; doc/emacs/misc.texi (Network Security): Fix typo.
[emacs.git] / src / xdisp.c
blobdcb002055b421393b7b7393eeeefd3fd81f2980f
1 /* Display generation from window structure and buffer text.
3 Copyright (C) 1985-1988, 1993-1995, 1997-2018 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 <https://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.
39 Under window systems like X, some portions of the redisplay code
40 are also called asynchronously, due to mouse movement or expose
41 events. "Asynchronously" in this context means that any C function
42 which calls maybe_quit or process_pending_signals could enter
43 redisplay via expose_frame and/or note_mouse_highlight, if X events
44 were recently reported to Emacs about mouse movements or frame(s)
45 that were exposed. And such redisplay could invoke the Lisp
46 interpreter, e.g. via the :eval forms in mode-line-format, and as
47 result the global state could change. It is therefore very
48 important that C functions which might cause such "asynchronous"
49 redisplay, but cannot tolerate the results, use
50 block_input/unblock_input around code fragments which assume that
51 global Lisp state doesn't change. If you don't follow this rule,
52 you will encounter bugs which are very hard to explain. One place
53 that needs to take such precautions is timer_check, some of whose
54 code cannot tolerate changes in timer alists while it processes
55 timers.
57 +--------------+ redisplay +----------------+
58 | Lisp machine |---------------->| Redisplay code |<--+
59 +--------------+ (xdisp.c) +----------------+ |
60 ^ | |
61 +----------------------------------+ |
62 Block input to prevent this when |
63 called asynchronously! |
65 note_mouse_highlight (asynchronous) |
67 X mouse events -----+
69 expose_frame (asynchronous) |
71 X expose events -----+
73 What does redisplay do? Obviously, it has to figure out somehow what
74 has been changed since the last time the display has been updated,
75 and to make these changes visible. Preferably it would do that in
76 a moderately intelligent way, i.e. fast.
78 Changes in buffer text can be deduced from window and buffer
79 structures, and from some global variables like `beg_unchanged' and
80 `end_unchanged'. The contents of the display are additionally
81 recorded in a `glyph matrix', a two-dimensional matrix of glyph
82 structures. Each row in such a matrix corresponds to a line on the
83 display, and each glyph in a row corresponds to a column displaying
84 a character, an image, or what else. This matrix is called the
85 `current glyph matrix' or `current matrix' in redisplay
86 terminology.
88 For buffer parts that have been changed since the last update, a
89 second glyph matrix is constructed, the so called `desired glyph
90 matrix' or short `desired matrix'. Current and desired matrix are
91 then compared to find a cheap way to update the display, e.g. by
92 reusing part of the display by scrolling lines.
94 You will find a lot of redisplay optimizations when you start
95 looking at the innards of redisplay. The overall goal of all these
96 optimizations is to make redisplay fast because it is done
97 frequently. Some of these optimizations are implemented by the
98 following functions:
100 . try_cursor_movement
102 This function tries to update the display if the text in the
103 window did not change and did not scroll, only point moved, and
104 it did not move off the displayed portion of the text.
106 . try_window_reusing_current_matrix
108 This function reuses the current matrix of a window when text
109 has not changed, but the window start changed (e.g., due to
110 scrolling).
112 . try_window_id
114 This function attempts to redisplay a window by reusing parts of
115 its existing display. It finds and reuses the part that was not
116 changed, and redraws the rest. (The "id" part in the function's
117 name stands for "insert/delete", not for "identification" or
118 somesuch.)
120 . try_window
122 This function performs the full redisplay of a single window
123 assuming that its fonts were not changed and that the cursor
124 will not end up in the scroll margins. (Loading fonts requires
125 re-adjustment of dimensions of glyph matrices, which makes this
126 method impossible to use.)
128 These optimizations are tried in sequence (some can be skipped if
129 it is known that they are not applicable). If none of the
130 optimizations were successful, redisplay calls redisplay_windows,
131 which performs a full redisplay of all windows.
133 Note that there's one more important optimization up Emacs's
134 sleeve, but it is related to actually redrawing the potentially
135 changed portions of the window/frame, not to reproducing the
136 desired matrices of those potentially changed portions. Namely,
137 the function update_frame and its subroutines, which you will find
138 in dispnew.c, compare the desired matrices with the current
139 matrices, and only redraw the portions that changed. So it could
140 happen that the functions in this file for some reason decide that
141 the entire desired matrix needs to be regenerated from scratch, and
142 still only parts of the Emacs display, or even nothing at all, will
143 be actually delivered to the glass, because update_frame has found
144 that the new and the old screen contents are similar or identical.
146 Desired matrices.
148 Desired matrices are always built per Emacs window. The function
149 `display_line' is the central function to look at if you are
150 interested. It constructs one row in a desired matrix given an
151 iterator structure containing both a buffer position and a
152 description of the environment in which the text is to be
153 displayed. But this is too early, read on.
155 Characters and pixmaps displayed for a range of buffer text depend
156 on various settings of buffers and windows, on overlays and text
157 properties, on display tables, on selective display. The good news
158 is that all this hairy stuff is hidden behind a small set of
159 interface functions taking an iterator structure (struct it)
160 argument.
162 Iteration over things to be displayed is then simple. It is
163 started by initializing an iterator with a call to init_iterator,
164 passing it the buffer position where to start iteration. For
165 iteration over strings, pass -1 as the position to init_iterator,
166 and call reseat_to_string when the string is ready, to initialize
167 the iterator for that string. Thereafter, calls to
168 get_next_display_element fill the iterator structure with relevant
169 information about the next thing to display. Calls to
170 set_iterator_to_next move the iterator to the next thing.
172 Besides this, an iterator also contains information about the
173 display environment in which glyphs for display elements are to be
174 produced. It has fields for the width and height of the display,
175 the information whether long lines are truncated or continued, a
176 current X and Y position, and lots of other stuff you can better
177 see in dispextern.h.
179 Glyphs in a desired matrix are normally constructed in a loop
180 calling get_next_display_element and then PRODUCE_GLYPHS. The call
181 to PRODUCE_GLYPHS will fill the iterator structure with pixel
182 information about the element being displayed and at the same time
183 produce glyphs for it. If the display element fits on the line
184 being displayed, set_iterator_to_next is called next, otherwise the
185 glyphs produced are discarded. The function display_line is the
186 workhorse of filling glyph rows in the desired matrix with glyphs.
187 In addition to producing glyphs, it also handles line truncation
188 and continuation, word wrap, and cursor positioning (for the
189 latter, see also set_cursor_from_row).
191 Frame matrices.
193 That just couldn't be all, could it? What about terminal types not
194 supporting operations on sub-windows of the screen? To update the
195 display on such a terminal, window-based glyph matrices are not
196 well suited. To be able to reuse part of the display (scrolling
197 lines up and down), we must instead have a view of the whole
198 screen. This is what `frame matrices' are for. They are a trick.
200 Frames on terminals like above have a glyph pool. Windows on such
201 a frame sub-allocate their glyph memory from their frame's glyph
202 pool. The frame itself is given its own glyph matrices. By
203 coincidence---or maybe something else---rows in window glyph
204 matrices are slices of corresponding rows in frame matrices. Thus
205 writing to window matrices implicitly updates a frame matrix which
206 provides us with the view of the whole screen that we originally
207 wanted to have without having to move many bytes around. To be
208 honest, there is a little bit more done, but not much more. If you
209 plan to extend that code, take a look at dispnew.c. The function
210 build_frame_matrix is a good starting point.
212 Bidirectional display.
214 Bidirectional display adds quite some hair to this already complex
215 design. The good news are that a large portion of that hairy stuff
216 is hidden in bidi.c behind only 3 interfaces. bidi.c implements a
217 reordering engine which is called by set_iterator_to_next and
218 returns the next character to display in the visual order. See
219 commentary on bidi.c for more details. As far as redisplay is
220 concerned, the effect of calling bidi_move_to_visually_next, the
221 main interface of the reordering engine, is that the iterator gets
222 magically placed on the buffer or string position that is to be
223 displayed next. In other words, a linear iteration through the
224 buffer/string is replaced with a non-linear one. All the rest of
225 the redisplay is oblivious to the bidi reordering.
227 Well, almost oblivious---there are still complications, most of
228 them due to the fact that buffer and string positions no longer
229 change monotonously with glyph indices in a glyph row. Moreover,
230 for continued lines, the buffer positions may not even be
231 monotonously changing with vertical positions. Also, accounting
232 for face changes, overlays, etc. becomes more complex because
233 non-linear iteration could potentially skip many positions with
234 changes, and then cross them again on the way back...
236 One other prominent effect of bidirectional display is that some
237 paragraphs of text need to be displayed starting at the right
238 margin of the window---the so-called right-to-left, or R2L
239 paragraphs. R2L paragraphs are displayed with R2L glyph rows,
240 which have their reversed_p flag set. The bidi reordering engine
241 produces characters in such rows starting from the character which
242 should be the rightmost on display. PRODUCE_GLYPHS then reverses
243 the order, when it fills up the glyph row whose reversed_p flag is
244 set, by prepending each new glyph to what is already there, instead
245 of appending it. When the glyph row is complete, the function
246 extend_face_to_end_of_line fills the empty space to the left of the
247 leftmost character with special glyphs, which will display as,
248 well, empty. On text terminals, these special glyphs are simply
249 blank characters. On graphics terminals, there's a single stretch
250 glyph of a suitably computed width. Both the blanks and the
251 stretch glyph are given the face of the background of the line.
252 This way, the terminal-specific back-end can still draw the glyphs
253 left to right, even for R2L lines.
255 Bidirectional display and character compositions
257 Some scripts cannot be displayed by drawing each character
258 individually, because adjacent characters change each other's shape
259 on display. For example, Arabic and Indic scripts belong to this
260 category.
262 Emacs display supports this by providing "character compositions",
263 most of which is implemented in composite.c. During the buffer
264 scan that delivers characters to PRODUCE_GLYPHS, if the next
265 character to be delivered is a composed character, the iteration
266 calls composition_reseat_it and next_element_from_composition. If
267 they succeed to compose the character with one or more of the
268 following characters, the whole sequence of characters that where
269 composed is recorded in the `struct composition_it' object that is
270 part of the buffer iterator. The composed sequence could produce
271 one or more font glyphs (called "grapheme clusters") on the screen.
272 Each of these grapheme clusters is then delivered to PRODUCE_GLYPHS
273 in the direction corresponding to the current bidi scan direction
274 (recorded in the scan_dir member of the `struct bidi_it' object
275 that is part of the buffer iterator). In particular, if the bidi
276 iterator currently scans the buffer backwards, the grapheme
277 clusters are delivered back to front. This reorders the grapheme
278 clusters as appropriate for the current bidi context. Note that
279 this means that the grapheme clusters are always stored in the
280 LGSTRING object (see composite.c) in the logical order.
282 Moving an iterator in bidirectional text
283 without producing glyphs
285 Note one important detail mentioned above: that the bidi reordering
286 engine, driven by the iterator, produces characters in R2L rows
287 starting at the character that will be the rightmost on display.
288 As far as the iterator is concerned, the geometry of such rows is
289 still left to right, i.e. the iterator "thinks" the first character
290 is at the leftmost pixel position. The iterator does not know that
291 PRODUCE_GLYPHS reverses the order of the glyphs that the iterator
292 delivers. This is important when functions from the move_it_*
293 family are used to get to certain screen position or to match
294 screen coordinates with buffer coordinates: these functions use the
295 iterator geometry, which is left to right even in R2L paragraphs.
296 This works well with most callers of move_it_*, because they need
297 to get to a specific column, and columns are still numbered in the
298 reading order, i.e. the rightmost character in a R2L paragraph is
299 still column zero. But some callers do not get well with this; a
300 notable example is mouse clicks that need to find the character
301 that corresponds to certain pixel coordinates. See
302 buffer_posn_from_coords in dispnew.c for how this is handled. */
304 #include <config.h>
305 #include <stdio.h>
306 #include <stdlib.h>
307 #include <limits.h>
308 #include <math.h>
310 #include "lisp.h"
311 #include "atimer.h"
312 #include "composite.h"
313 #include "keyboard.h"
314 #include "systime.h"
315 #include "frame.h"
316 #include "window.h"
317 #include "termchar.h"
318 #include "dispextern.h"
319 #include "character.h"
320 #include "buffer.h"
321 #include "charset.h"
322 #include "indent.h"
323 #include "commands.h"
324 #include "keymap.h"
325 #include "disptab.h"
326 #include "termhooks.h"
327 #include "termopts.h"
328 #include "intervals.h"
329 #include "coding.h"
330 #include "region-cache.h"
331 #include "font.h"
332 #include "fontset.h"
333 #include "blockinput.h"
334 #include "xwidget.h"
335 #ifdef HAVE_WINDOW_SYSTEM
336 #include TERM_HEADER
337 #endif /* HAVE_WINDOW_SYSTEM */
339 #ifndef FRAME_X_OUTPUT
340 #define FRAME_X_OUTPUT(f) ((f)->output_data.x)
341 #endif
343 #define DISP_INFINITY 10000000
345 /* Holds the list (error). */
346 static Lisp_Object list_of_error;
348 #ifdef HAVE_WINDOW_SYSTEM
350 /* Test if overflow newline into fringe. Called with iterator IT
351 at or past right window margin, and with IT->current_x set. */
353 #define IT_OVERFLOW_NEWLINE_INTO_FRINGE(IT) \
354 (!NILP (Voverflow_newline_into_fringe) \
355 && FRAME_WINDOW_P ((IT)->f) \
356 && ((IT)->bidi_it.paragraph_dir == R2L \
357 ? (WINDOW_LEFT_FRINGE_WIDTH ((IT)->w) > 0) \
358 : (WINDOW_RIGHT_FRINGE_WIDTH ((IT)->w) > 0)) \
359 && (IT)->current_x == (IT)->last_visible_x)
361 #else /* !HAVE_WINDOW_SYSTEM */
362 #define IT_OVERFLOW_NEWLINE_INTO_FRINGE(it) false
363 #endif /* HAVE_WINDOW_SYSTEM */
365 /* Test if the display element loaded in IT, or the underlying buffer
366 or string character, is a space or a TAB character. This is used
367 to determine where word wrapping can occur. */
369 #define IT_DISPLAYING_WHITESPACE(it) \
370 ((it->what == IT_CHARACTER && (it->c == ' ' || it->c == '\t')) \
371 || ((STRINGP (it->string) \
372 && (SREF (it->string, IT_STRING_BYTEPOS (*it)) == ' ' \
373 || SREF (it->string, IT_STRING_BYTEPOS (*it)) == '\t')) \
374 || (it->s \
375 && (it->s[IT_BYTEPOS (*it)] == ' ' \
376 || it->s[IT_BYTEPOS (*it)] == '\t')) \
377 || (IT_BYTEPOS (*it) < ZV_BYTE \
378 && (*BYTE_POS_ADDR (IT_BYTEPOS (*it)) == ' ' \
379 || *BYTE_POS_ADDR (IT_BYTEPOS (*it)) == '\t')))) \
381 /* True means print newline to stdout before next mini-buffer message. */
383 bool noninteractive_need_newline;
385 /* True means print newline to message log before next message. */
387 static bool message_log_need_newline;
389 /* Three markers that message_dolog uses.
390 It could allocate them itself, but that causes trouble
391 in handling memory-full errors. */
392 static Lisp_Object message_dolog_marker1;
393 static Lisp_Object message_dolog_marker2;
394 static Lisp_Object message_dolog_marker3;
396 /* The buffer position of the first character appearing entirely or
397 partially on the line of the selected window which contains the
398 cursor; <= 0 if not known. Set by set_cursor_from_row, used for
399 redisplay optimization in redisplay_internal. */
401 static struct text_pos this_line_start_pos;
403 /* Number of characters past the end of the line above, including the
404 terminating newline. */
406 static struct text_pos this_line_end_pos;
408 /* The vertical positions and the height of this line. */
410 static int this_line_vpos;
411 static int this_line_y;
412 static int this_line_pixel_height;
414 /* X position at which this display line starts. Usually zero;
415 negative if first character is partially visible. */
417 static int this_line_start_x;
419 /* The smallest character position seen by move_it_* functions as they
420 move across display lines. Used to set MATRIX_ROW_START_CHARPOS of
421 hscrolled lines, see display_line. */
423 static struct text_pos this_line_min_pos;
425 /* Buffer that this_line_.* variables are referring to. */
427 static struct buffer *this_line_buffer;
429 /* True if an overlay arrow has been displayed in this window. */
431 static bool overlay_arrow_seen;
433 /* Vector containing glyphs for an ellipsis `...'. */
435 static Lisp_Object default_invis_vector[3];
437 /* This is the window where the echo area message was displayed. It
438 is always a mini-buffer window, but it may not be the same window
439 currently active as a mini-buffer. */
441 Lisp_Object echo_area_window;
443 /* Stack of messages, which are pushed by push_message and popped and
444 displayed by restore_message. */
446 static Lisp_Object Vmessage_stack;
448 /* True means multibyte characters were enabled when the echo area
449 message was specified. */
451 static bool message_enable_multibyte;
453 /* At each redisplay cycle, we should refresh everything there is to refresh.
454 To do that efficiently, we use many optimizations that try to make sure we
455 don't waste too much time updating things that haven't changed.
456 The coarsest such optimization is that, in the most common cases, we only
457 look at the selected-window.
459 To know whether other windows should be considered for redisplay, we use the
460 variable windows_or_buffers_changed: as long as it is 0, it means that we
461 have not noticed anything that should require updating anything else than
462 the selected-window. If it is set to REDISPLAY_SOME, it means that since
463 last redisplay, some changes have been made which could impact other
464 windows. To know which ones need redisplay, every buffer, window, and frame
465 has a `redisplay' bit, which (if true) means that this object needs to be
466 redisplayed. If windows_or_buffers_changed is 0, we know there's no point
467 looking for those `redisplay' bits (actually, there might be some such bits
468 set, but then only on objects which aren't displayed anyway).
470 OTOH if it's non-zero we wil have to loop through all windows and then check
471 the `redisplay' bit of the corresponding window, frame, and buffer, in order
472 to decide whether that window needs attention or not. Note that we can't
473 just look at the frame's redisplay bit to decide that the whole frame can be
474 skipped, since even if the frame's redisplay bit is unset, some of its
475 windows's redisplay bits may be set.
477 Mostly for historical reasons, windows_or_buffers_changed can also take
478 other non-zero values. In that case, the precise value doesn't matter (it
479 encodes the cause of the setting but is only used for debugging purposes),
480 and what it means is that we shouldn't pay attention to any `redisplay' bits
481 and we should simply try and redisplay every window out there. */
483 int windows_or_buffers_changed;
485 /* Nonzero if we should redraw the mode lines on the next redisplay.
486 Similarly to `windows_or_buffers_changed', If it has value REDISPLAY_SOME,
487 then only redisplay the mode lines in those buffers/windows/frames where the
488 `redisplay' bit has been set.
489 For any other value, redisplay all mode lines (the number used is then only
490 used to track down the cause for this full-redisplay).
492 Since the frame title uses the same %-constructs as the mode line
493 (except %c, %C, and %l), if this variable is non-zero, we also consider
494 redisplaying the title of each frame, see x_consider_frame_title.
496 The `redisplay' bits are the same as those used for
497 windows_or_buffers_changed, and setting windows_or_buffers_changed also
498 causes recomputation of the mode lines of all those windows. IOW this
499 variable only has an effect if windows_or_buffers_changed is zero, in which
500 case we should only need to redisplay the mode-line of those objects with
501 a `redisplay' bit set but not the window's text content (tho we may still
502 need to refresh the text content of the selected-window). */
504 int update_mode_lines;
506 /* True after display_mode_line if %l was used and it displayed a
507 line number. */
509 static bool line_number_displayed;
511 /* The name of the *Messages* buffer, a string. */
513 static Lisp_Object Vmessages_buffer_name;
515 /* Current, index 0, and last displayed echo area message. Either
516 buffers from echo_buffers, or nil to indicate no message. */
518 Lisp_Object echo_area_buffer[2];
520 /* The buffers referenced from echo_area_buffer. */
522 static Lisp_Object echo_buffer[2];
524 /* A vector saved used in with_area_buffer to reduce consing. */
526 static Lisp_Object Vwith_echo_area_save_vector;
528 /* True means display_echo_area should display the last echo area
529 message again. Set by redisplay_preserve_echo_area. */
531 static bool display_last_displayed_message_p;
533 /* True if echo area is being used by print; false if being used by
534 message. */
536 static bool message_buf_print;
538 /* Set to true in clear_message to make redisplay_internal aware
539 of an emptied echo area. */
541 static bool message_cleared_p;
543 /* A scratch glyph row with contents used for generating truncation
544 glyphs. Also used in direct_output_for_insert. */
546 #define MAX_SCRATCH_GLYPHS 100
547 static struct glyph_row scratch_glyph_row;
548 static struct glyph scratch_glyphs[MAX_SCRATCH_GLYPHS];
550 /* Ascent and height of the last line processed by move_it_to. */
552 static int last_height;
554 /* True if there's a help-echo in the echo area. */
556 bool help_echo_showing_p;
558 /* The maximum distance to look ahead for text properties. Values
559 that are too small let us call compute_char_face and similar
560 functions too often which is expensive. Values that are too large
561 let us call compute_char_face and alike too often because we
562 might not be interested in text properties that far away. */
564 #define TEXT_PROP_DISTANCE_LIMIT 100
566 /* SAVE_IT and RESTORE_IT are called when we save a snapshot of the
567 iterator state and later restore it. This is needed because the
568 bidi iterator on bidi.c keeps a stacked cache of its states, which
569 is really a singleton. When we use scratch iterator objects to
570 move around the buffer, we can cause the bidi cache to be pushed or
571 popped, and therefore we need to restore the cache state when we
572 return to the original iterator. */
573 #define SAVE_IT(ITCOPY, ITORIG, CACHE) \
574 do { \
575 if (CACHE) \
576 bidi_unshelve_cache (CACHE, true); \
577 ITCOPY = ITORIG; \
578 CACHE = bidi_shelve_cache (); \
579 } while (false)
581 #define RESTORE_IT(pITORIG, pITCOPY, CACHE) \
582 do { \
583 if (pITORIG != pITCOPY) \
584 *(pITORIG) = *(pITCOPY); \
585 bidi_unshelve_cache (CACHE, false); \
586 CACHE = NULL; \
587 } while (false)
589 /* Functions to mark elements as needing redisplay. */
590 enum { REDISPLAY_SOME = 2}; /* Arbitrary choice. */
592 void
593 redisplay_other_windows (void)
595 if (!windows_or_buffers_changed)
596 windows_or_buffers_changed = REDISPLAY_SOME;
599 void
600 wset_redisplay (struct window *w)
602 /* Beware: selected_window can be nil during early stages. */
603 if (!EQ (make_lisp_ptr (w, Lisp_Vectorlike), selected_window))
604 redisplay_other_windows ();
605 w->redisplay = true;
608 void
609 fset_redisplay (struct frame *f)
611 redisplay_other_windows ();
612 f->redisplay = true;
615 void
616 bset_redisplay (struct buffer *b)
618 int count = buffer_window_count (b);
619 if (count > 0)
621 /* ... it's visible in other window than selected, */
622 if (count > 1 || b != XBUFFER (XWINDOW (selected_window)->contents))
623 redisplay_other_windows ();
624 /* Even if we don't set windows_or_buffers_changed, do set `redisplay'
625 so that if we later set windows_or_buffers_changed, this buffer will
626 not be omitted. */
627 b->text->redisplay = true;
631 void
632 bset_update_mode_line (struct buffer *b)
634 if (!update_mode_lines)
635 update_mode_lines = REDISPLAY_SOME;
636 b->text->redisplay = true;
639 DEFUN ("set-buffer-redisplay", Fset_buffer_redisplay,
640 Sset_buffer_redisplay, 4, 4, 0,
641 doc: /* Mark the current buffer for redisplay.
642 This function may be passed to `add-variable-watcher'. */)
643 (Lisp_Object symbol, Lisp_Object newval, Lisp_Object op, Lisp_Object where)
645 bset_update_mode_line (current_buffer);
646 current_buffer->prevent_redisplay_optimizations_p = true;
647 return Qnil;
650 #ifdef GLYPH_DEBUG
652 /* True means print traces of redisplay if compiled with
653 GLYPH_DEBUG defined. */
655 bool trace_redisplay_p;
657 #endif /* GLYPH_DEBUG */
659 #ifdef DEBUG_TRACE_MOVE
660 /* True means trace with TRACE_MOVE to stderr. */
661 static bool trace_move;
663 #define TRACE_MOVE(x) if (trace_move) fprintf x; else (void) 0
664 #else
665 #define TRACE_MOVE(x) (void) 0
666 #endif
668 /* Buffer being redisplayed -- for redisplay_window_error. */
670 static struct buffer *displayed_buffer;
672 /* Value returned from text property handlers (see below). */
674 enum prop_handled
676 HANDLED_NORMALLY,
677 HANDLED_RECOMPUTE_PROPS,
678 HANDLED_OVERLAY_STRING_CONSUMED,
679 HANDLED_RETURN
682 /* A description of text properties that redisplay is interested
683 in. */
685 struct props
687 /* The symbol index of the name of the property. */
688 short name;
690 /* A unique index for the property. */
691 enum prop_idx idx;
693 /* A handler function called to set up iterator IT from the property
694 at IT's current position. Value is used to steer handle_stop. */
695 enum prop_handled (*handler) (struct it *it);
698 static enum prop_handled handle_face_prop (struct it *);
699 static enum prop_handled handle_invisible_prop (struct it *);
700 static enum prop_handled handle_display_prop (struct it *);
701 static enum prop_handled handle_composition_prop (struct it *);
702 static enum prop_handled handle_overlay_change (struct it *);
703 static enum prop_handled handle_fontified_prop (struct it *);
705 /* Properties handled by iterators. */
707 static struct props it_props[] =
709 {SYMBOL_INDEX (Qfontified), FONTIFIED_PROP_IDX, handle_fontified_prop},
710 /* Handle `face' before `display' because some sub-properties of
711 `display' need to know the face. */
712 {SYMBOL_INDEX (Qface), FACE_PROP_IDX, handle_face_prop},
713 {SYMBOL_INDEX (Qdisplay), DISPLAY_PROP_IDX, handle_display_prop},
714 {SYMBOL_INDEX (Qinvisible), INVISIBLE_PROP_IDX, handle_invisible_prop},
715 {SYMBOL_INDEX (Qcomposition), COMPOSITION_PROP_IDX, handle_composition_prop},
716 {0, 0, NULL}
719 /* Value is the position described by X. If X is a marker, value is
720 the marker_position of X. Otherwise, value is X. */
722 #define COERCE_MARKER(X) (MARKERP ((X)) ? Fmarker_position (X) : (X))
724 /* Enumeration returned by some move_it_.* functions internally. */
726 enum move_it_result
728 /* Not used. Undefined value. */
729 MOVE_UNDEFINED,
731 /* Move ended at the requested buffer position or ZV. */
732 MOVE_POS_MATCH_OR_ZV,
734 /* Move ended at the requested X pixel position. */
735 MOVE_X_REACHED,
737 /* Move within a line ended at the end of a line that must be
738 continued. */
739 MOVE_LINE_CONTINUED,
741 /* Move within a line ended at the end of a line that would
742 be displayed truncated. */
743 MOVE_LINE_TRUNCATED,
745 /* Move within a line ended at a line end. */
746 MOVE_NEWLINE_OR_CR
749 /* This counter is used to clear the face cache every once in a while
750 in redisplay_internal. It is incremented for each redisplay.
751 Every CLEAR_FACE_CACHE_COUNT full redisplays, the face cache is
752 cleared. */
754 #define CLEAR_FACE_CACHE_COUNT 500
755 static int clear_face_cache_count;
757 /* Similarly for the image cache. */
759 #ifdef HAVE_WINDOW_SYSTEM
760 #define CLEAR_IMAGE_CACHE_COUNT 101
761 static int clear_image_cache_count;
763 /* Null glyph slice */
764 static struct glyph_slice null_glyph_slice = { 0, 0, 0, 0 };
765 #endif
767 /* True while redisplay_internal is in progress. */
769 bool redisplaying_p;
771 /* If a string, XTread_socket generates an event to display that string.
772 (The display is done in read_char.) */
774 Lisp_Object help_echo_string;
775 Lisp_Object help_echo_window;
776 Lisp_Object help_echo_object;
777 ptrdiff_t help_echo_pos;
779 /* Temporary variable for XTread_socket. */
781 Lisp_Object previous_help_echo_string;
783 /* Platform-independent portion of hourglass implementation. */
785 #ifdef HAVE_WINDOW_SYSTEM
787 /* True means an hourglass cursor is currently shown. */
788 static bool hourglass_shown_p;
790 /* If non-null, an asynchronous timer that, when it expires, displays
791 an hourglass cursor on all frames. */
792 static struct atimer *hourglass_atimer;
794 #endif /* HAVE_WINDOW_SYSTEM */
796 /* Default number of seconds to wait before displaying an hourglass
797 cursor. */
798 #define DEFAULT_HOURGLASS_DELAY 1
800 #ifdef HAVE_WINDOW_SYSTEM
802 /* Default pixel width of `thin-space' display method. */
803 #define THIN_SPACE_WIDTH 1
805 #endif /* HAVE_WINDOW_SYSTEM */
807 /* Function prototypes. */
809 static void setup_for_ellipsis (struct it *, int);
810 static void set_iterator_to_next (struct it *, bool);
811 static void mark_window_display_accurate_1 (struct window *, bool);
812 static bool row_for_charpos_p (struct glyph_row *, ptrdiff_t);
813 static bool cursor_row_p (struct glyph_row *);
814 static int redisplay_mode_lines (Lisp_Object, bool);
816 static void handle_line_prefix (struct it *);
818 static void handle_stop_backwards (struct it *, ptrdiff_t);
819 static void unwind_with_echo_area_buffer (Lisp_Object);
820 static Lisp_Object with_echo_area_buffer_unwind_data (struct window *);
821 static bool current_message_1 (ptrdiff_t, Lisp_Object);
822 static bool truncate_message_1 (ptrdiff_t, Lisp_Object);
823 static void set_message (Lisp_Object);
824 static bool set_message_1 (ptrdiff_t, Lisp_Object);
825 static bool display_echo_area_1 (ptrdiff_t, Lisp_Object);
826 static bool resize_mini_window_1 (ptrdiff_t, Lisp_Object);
827 static void unwind_redisplay (void);
828 static void extend_face_to_end_of_line (struct it *);
829 static intmax_t message_log_check_duplicate (ptrdiff_t, ptrdiff_t);
830 static void push_it (struct it *, struct text_pos *);
831 static void iterate_out_of_display_property (struct it *);
832 static void pop_it (struct it *);
833 static void redisplay_internal (void);
834 static void echo_area_display (bool);
835 static void block_buffer_flips (void);
836 static void unblock_buffer_flips (void);
837 static void redisplay_windows (Lisp_Object);
838 static void redisplay_window (Lisp_Object, bool);
839 static Lisp_Object redisplay_window_error (Lisp_Object);
840 static Lisp_Object redisplay_window_0 (Lisp_Object);
841 static Lisp_Object redisplay_window_1 (Lisp_Object);
842 static bool set_cursor_from_row (struct window *, struct glyph_row *,
843 struct glyph_matrix *, ptrdiff_t, ptrdiff_t,
844 int, int);
845 static bool cursor_row_fully_visible_p (struct window *, bool, bool);
846 static bool update_menu_bar (struct frame *, bool, bool);
847 static bool try_window_reusing_current_matrix (struct window *);
848 static int try_window_id (struct window *);
849 static void maybe_produce_line_number (struct it *);
850 static bool should_produce_line_number (struct it *);
851 static bool display_line (struct it *, int);
852 static int display_mode_lines (struct window *);
853 static int display_mode_line (struct window *, enum face_id, Lisp_Object);
854 static int display_mode_element (struct it *, int, int, int, Lisp_Object,
855 Lisp_Object, bool);
856 static int store_mode_line_string (const char *, Lisp_Object, bool, int, int,
857 Lisp_Object);
858 static const char *decode_mode_spec (struct window *, int, int, Lisp_Object *);
859 static void display_menu_bar (struct window *);
860 static ptrdiff_t display_count_lines (ptrdiff_t, ptrdiff_t, ptrdiff_t,
861 ptrdiff_t *);
862 static void pint2str (register char *, register int, register ptrdiff_t);
864 static int display_string (const char *, Lisp_Object, Lisp_Object,
865 ptrdiff_t, ptrdiff_t, struct it *, int, int, int, int);
866 static void compute_line_metrics (struct it *);
867 static void run_redisplay_end_trigger_hook (struct it *);
868 static bool get_overlay_strings (struct it *, ptrdiff_t);
869 static bool get_overlay_strings_1 (struct it *, ptrdiff_t, bool);
870 static void next_overlay_string (struct it *);
871 static void reseat (struct it *, struct text_pos, bool);
872 static void reseat_1 (struct it *, struct text_pos, bool);
873 static bool next_element_from_display_vector (struct it *);
874 static bool next_element_from_string (struct it *);
875 static bool next_element_from_c_string (struct it *);
876 static bool next_element_from_buffer (struct it *);
877 static bool next_element_from_composition (struct it *);
878 static bool next_element_from_image (struct it *);
879 static bool next_element_from_stretch (struct it *);
880 static bool next_element_from_xwidget (struct it *);
881 static void load_overlay_strings (struct it *, ptrdiff_t);
882 static bool get_next_display_element (struct it *);
883 static enum move_it_result
884 move_it_in_display_line_to (struct it *, ptrdiff_t, int,
885 enum move_operation_enum);
886 static void get_visually_first_element (struct it *);
887 static void compute_stop_pos (struct it *);
888 static int face_before_or_after_it_pos (struct it *, bool);
889 static ptrdiff_t next_overlay_change (ptrdiff_t);
890 static int handle_display_spec (struct it *, Lisp_Object, Lisp_Object,
891 Lisp_Object, struct text_pos *, ptrdiff_t, bool);
892 static int handle_single_display_spec (struct it *, Lisp_Object, Lisp_Object,
893 Lisp_Object, struct text_pos *,
894 ptrdiff_t, int, bool, bool);
895 static int underlying_face_id (struct it *);
897 #define face_before_it_pos(IT) face_before_or_after_it_pos (IT, true)
898 #define face_after_it_pos(IT) face_before_or_after_it_pos (IT, false)
900 #ifdef HAVE_WINDOW_SYSTEM
902 static void update_tool_bar (struct frame *, bool);
903 static void x_draw_bottom_divider (struct window *w);
904 static void notice_overwritten_cursor (struct window *,
905 enum glyph_row_area,
906 int, int, int, int);
907 static int normal_char_height (struct font *, int);
908 static void normal_char_ascent_descent (struct font *, int, int *, int *);
910 static void append_stretch_glyph (struct it *, Lisp_Object,
911 int, int, int);
913 static Lisp_Object get_it_property (struct it *, Lisp_Object);
914 static Lisp_Object calc_line_height_property (struct it *, Lisp_Object,
915 struct font *, int, bool);
917 #endif /* HAVE_WINDOW_SYSTEM */
919 static void produce_special_glyphs (struct it *, enum display_element_type);
920 static void show_mouse_face (Mouse_HLInfo *, enum draw_glyphs_face);
921 static bool coords_in_mouse_face_p (struct window *, int, int);
925 /***********************************************************************
926 Window display dimensions
927 ***********************************************************************/
929 /* Return the bottom boundary y-position for text lines in window W.
930 This is the first y position at which a line cannot start.
931 It is relative to the top of the window.
933 This is the height of W minus the height of a mode line, if any. */
936 window_text_bottom_y (struct window *w)
938 int height = WINDOW_PIXEL_HEIGHT (w);
940 height -= WINDOW_BOTTOM_DIVIDER_WIDTH (w);
942 if (window_wants_mode_line (w))
943 height -= CURRENT_MODE_LINE_HEIGHT (w);
945 height -= WINDOW_SCROLL_BAR_AREA_HEIGHT (w);
947 return height;
950 /* Return the pixel width of display area AREA of window W.
951 ANY_AREA means return the total width of W, not including
952 fringes to the left and right of the window. */
955 window_box_width (struct window *w, enum glyph_row_area area)
957 int width = w->pixel_width;
959 if (!w->pseudo_window_p)
961 width -= WINDOW_SCROLL_BAR_AREA_WIDTH (w);
962 width -= WINDOW_RIGHT_DIVIDER_WIDTH (w);
964 if (area == TEXT_AREA)
965 width -= (WINDOW_MARGINS_WIDTH (w)
966 + WINDOW_FRINGES_WIDTH (w));
967 else if (area == LEFT_MARGIN_AREA)
968 width = WINDOW_LEFT_MARGIN_WIDTH (w);
969 else if (area == RIGHT_MARGIN_AREA)
970 width = WINDOW_RIGHT_MARGIN_WIDTH (w);
973 /* With wide margins, fringes, etc. we might end up with a negative
974 width, correct that here. */
975 return max (0, width);
979 /* Return the pixel height of the display area of window W, not
980 including mode lines of W, if any. */
983 window_box_height (struct window *w)
985 struct frame *f = XFRAME (w->frame);
986 int height = WINDOW_PIXEL_HEIGHT (w);
988 eassert (height >= 0);
990 height -= WINDOW_BOTTOM_DIVIDER_WIDTH (w);
991 height -= WINDOW_SCROLL_BAR_AREA_HEIGHT (w);
993 /* Note: the code below that determines the mode-line/header-line
994 height is essentially the same as that contained in the macro
995 CURRENT_{MODE,HEADER}_LINE_HEIGHT, except that it checks whether
996 the appropriate glyph row has its `mode_line_p' flag set,
997 and if it doesn't, uses estimate_mode_line_height instead. */
999 if (window_wants_mode_line (w))
1001 struct glyph_row *ml_row
1002 = (w->current_matrix && w->current_matrix->rows
1003 ? MATRIX_MODE_LINE_ROW (w->current_matrix)
1004 : 0);
1005 if (ml_row && ml_row->mode_line_p)
1006 height -= ml_row->height;
1007 else
1008 height -= estimate_mode_line_height (f, CURRENT_MODE_LINE_FACE_ID (w));
1011 if (window_wants_header_line (w))
1013 struct glyph_row *hl_row
1014 = (w->current_matrix && w->current_matrix->rows
1015 ? MATRIX_HEADER_LINE_ROW (w->current_matrix)
1016 : 0);
1017 if (hl_row && hl_row->mode_line_p)
1018 height -= hl_row->height;
1019 else
1020 height -= estimate_mode_line_height (f, HEADER_LINE_FACE_ID);
1023 /* With a very small font and a mode-line that's taller than
1024 default, we might end up with a negative height. */
1025 return max (0, height);
1028 /* Return the window-relative coordinate of the left edge of display
1029 area AREA of window W. ANY_AREA means return the left edge of the
1030 whole window, to the right of the left fringe of W. */
1033 window_box_left_offset (struct window *w, enum glyph_row_area area)
1035 int x;
1037 if (w->pseudo_window_p)
1038 return 0;
1040 x = WINDOW_LEFT_SCROLL_BAR_AREA_WIDTH (w);
1042 if (area == TEXT_AREA)
1043 x += (WINDOW_LEFT_FRINGE_WIDTH (w)
1044 + window_box_width (w, LEFT_MARGIN_AREA));
1045 else if (area == RIGHT_MARGIN_AREA)
1046 x += (WINDOW_LEFT_FRINGE_WIDTH (w)
1047 + window_box_width (w, LEFT_MARGIN_AREA)
1048 + window_box_width (w, TEXT_AREA)
1049 + (WINDOW_HAS_FRINGES_OUTSIDE_MARGINS (w)
1051 : WINDOW_RIGHT_FRINGE_WIDTH (w)));
1052 else if (area == LEFT_MARGIN_AREA
1053 && WINDOW_HAS_FRINGES_OUTSIDE_MARGINS (w))
1054 x += WINDOW_LEFT_FRINGE_WIDTH (w);
1056 /* Don't return more than the window's pixel width. */
1057 return min (x, w->pixel_width);
1061 /* Return the window-relative coordinate of the right edge of display
1062 area AREA of window W. ANY_AREA means return the right edge of the
1063 whole window, to the left of the right fringe of W. */
1065 static int
1066 window_box_right_offset (struct window *w, enum glyph_row_area area)
1068 /* Don't return more than the window's pixel width. */
1069 return min (window_box_left_offset (w, area) + window_box_width (w, area),
1070 w->pixel_width);
1073 /* Return the frame-relative coordinate of the left edge of display
1074 area AREA of window W. ANY_AREA means return the left edge of the
1075 whole window, to the right of the left fringe of W. */
1078 window_box_left (struct window *w, enum glyph_row_area area)
1080 struct frame *f = XFRAME (w->frame);
1081 int x;
1083 if (w->pseudo_window_p)
1084 return FRAME_INTERNAL_BORDER_WIDTH (f);
1086 x = (WINDOW_LEFT_EDGE_X (w)
1087 + window_box_left_offset (w, area));
1089 return x;
1093 /* Return the frame-relative coordinate of the right edge of display
1094 area AREA of window W. ANY_AREA means return the right edge of the
1095 whole window, to the left of the right fringe of W. */
1098 window_box_right (struct window *w, enum glyph_row_area area)
1100 return window_box_left (w, area) + window_box_width (w, area);
1103 /* Get the bounding box of the display area AREA of window W, without
1104 mode lines, in frame-relative coordinates. ANY_AREA means the
1105 whole window, not including the left and right fringes of
1106 the window. Return in *BOX_X and *BOX_Y the frame-relative pixel
1107 coordinates of the upper-left corner of the box. Return in
1108 *BOX_WIDTH, and *BOX_HEIGHT the pixel width and height of the box. */
1110 void
1111 window_box (struct window *w, enum glyph_row_area area, int *box_x,
1112 int *box_y, int *box_width, int *box_height)
1114 if (box_width)
1115 *box_width = window_box_width (w, area);
1116 if (box_height)
1117 *box_height = window_box_height (w);
1118 if (box_x)
1119 *box_x = window_box_left (w, area);
1120 if (box_y)
1122 *box_y = WINDOW_TOP_EDGE_Y (w);
1123 if (window_wants_header_line (w))
1124 *box_y += CURRENT_HEADER_LINE_HEIGHT (w);
1128 #ifdef HAVE_WINDOW_SYSTEM
1130 /* Get the bounding box of the display area AREA of window W, without
1131 mode lines and both fringes of the window. Return in *TOP_LEFT_X
1132 and TOP_LEFT_Y the frame-relative pixel coordinates of the
1133 upper-left corner of the box. Return in *BOTTOM_RIGHT_X, and
1134 *BOTTOM_RIGHT_Y the coordinates of the bottom-right corner of the
1135 box. */
1137 static void
1138 window_box_edges (struct window *w, int *top_left_x, int *top_left_y,
1139 int *bottom_right_x, int *bottom_right_y)
1141 window_box (w, ANY_AREA, top_left_x, top_left_y,
1142 bottom_right_x, bottom_right_y);
1143 *bottom_right_x += *top_left_x;
1144 *bottom_right_y += *top_left_y;
1147 #endif /* HAVE_WINDOW_SYSTEM */
1149 /***********************************************************************
1150 Utilities
1151 ***********************************************************************/
1153 /* Return the bottom y-position of the line the iterator IT is in.
1154 This can modify IT's settings. */
1157 line_bottom_y (struct it *it)
1159 int line_height = it->max_ascent + it->max_descent;
1160 int line_top_y = it->current_y;
1162 if (line_height == 0)
1164 if (last_height)
1165 line_height = last_height;
1166 else if (IT_CHARPOS (*it) < ZV)
1168 move_it_by_lines (it, 1);
1169 line_height = (it->max_ascent || it->max_descent
1170 ? it->max_ascent + it->max_descent
1171 : last_height);
1173 else
1175 struct glyph_row *row = it->glyph_row;
1177 /* Use the default character height. */
1178 it->glyph_row = NULL;
1179 it->what = IT_CHARACTER;
1180 it->c = ' ';
1181 it->len = 1;
1182 PRODUCE_GLYPHS (it);
1183 line_height = it->ascent + it->descent;
1184 it->glyph_row = row;
1188 return line_top_y + line_height;
1191 DEFUN ("line-pixel-height", Fline_pixel_height,
1192 Sline_pixel_height, 0, 0, 0,
1193 doc: /* Return height in pixels of text line in the selected window.
1195 Value is the height in pixels of the line at point. */)
1196 (void)
1198 struct it it;
1199 struct text_pos pt;
1200 struct window *w = XWINDOW (selected_window);
1201 struct buffer *old_buffer = NULL;
1202 Lisp_Object result;
1204 if (XBUFFER (w->contents) != current_buffer)
1206 old_buffer = current_buffer;
1207 set_buffer_internal_1 (XBUFFER (w->contents));
1209 SET_TEXT_POS (pt, PT, PT_BYTE);
1210 start_display (&it, w, pt);
1211 /* Start from the beginning of the screen line, to make sure we
1212 traverse all of its display elements, and thus capture the
1213 correct metrics. */
1214 move_it_by_lines (&it, 0);
1215 it.vpos = it.current_y = 0;
1216 last_height = 0;
1217 result = make_number (line_bottom_y (&it));
1218 if (old_buffer)
1219 set_buffer_internal_1 (old_buffer);
1221 return result;
1224 /* Return the default pixel height of text lines in window W. The
1225 value is the canonical height of the W frame's default font, plus
1226 any extra space required by the line-spacing variable or frame
1227 parameter.
1229 Implementation note: this ignores any line-spacing text properties
1230 put on the newline characters. This is because those properties
1231 only affect the _screen_ line ending in the newline (i.e., in a
1232 continued line, only the last screen line will be affected), which
1233 means only a small number of lines in a buffer can ever use this
1234 feature. Since this function is used to compute the default pixel
1235 equivalent of text lines in a window, we can safely ignore those
1236 few lines. For the same reasons, we ignore the line-height
1237 properties. */
1239 default_line_pixel_height (struct window *w)
1241 struct frame *f = WINDOW_XFRAME (w);
1242 int height = FRAME_LINE_HEIGHT (f);
1244 if (!FRAME_INITIAL_P (f) && BUFFERP (w->contents))
1246 struct buffer *b = XBUFFER (w->contents);
1247 Lisp_Object val = BVAR (b, extra_line_spacing);
1249 if (NILP (val))
1250 val = BVAR (&buffer_defaults, extra_line_spacing);
1251 if (!NILP (val))
1253 if (RANGED_INTEGERP (0, val, INT_MAX))
1254 height += XFASTINT (val);
1255 else if (FLOATP (val))
1257 int addon = XFLOAT_DATA (val) * height + 0.5;
1259 if (addon >= 0)
1260 height += addon;
1263 else
1264 height += f->extra_line_spacing;
1267 return height;
1270 /* Subroutine of pos_visible_p below. Extracts a display string, if
1271 any, from the display spec given as its argument. */
1272 static Lisp_Object
1273 string_from_display_spec (Lisp_Object spec)
1275 if (VECTORP (spec))
1277 for (ptrdiff_t i = 0; i < ASIZE (spec); i++)
1278 if (STRINGP (AREF (spec, i)))
1279 return AREF (spec, i);
1281 else
1283 for (; CONSP (spec); spec = XCDR (spec))
1284 if (STRINGP (XCAR (spec)))
1285 return XCAR (spec);
1287 return spec;
1291 /* Limit insanely large values of W->hscroll on frame F to the largest
1292 value that will still prevent first_visible_x and last_visible_x of
1293 'struct it' from overflowing an int. */
1294 static int
1295 window_hscroll_limited (struct window *w, struct frame *f)
1297 ptrdiff_t window_hscroll = w->hscroll;
1298 int window_text_width = window_box_width (w, TEXT_AREA);
1299 int colwidth = FRAME_COLUMN_WIDTH (f);
1301 if (window_hscroll > (INT_MAX - window_text_width) / colwidth - 1)
1302 window_hscroll = (INT_MAX - window_text_width) / colwidth - 1;
1304 return window_hscroll;
1307 /* Return true if position CHARPOS is visible in window W.
1308 CHARPOS < 0 means return info about WINDOW_END position.
1309 If visible, set *X and *Y to pixel coordinates of top left corner.
1310 Set *RTOP and *RBOT to pixel height of an invisible area of glyph at POS.
1311 Set *ROWH and *VPOS to row's visible height and VPOS (row number). */
1313 bool
1314 pos_visible_p (struct window *w, ptrdiff_t charpos, int *x, int *y,
1315 int *rtop, int *rbot, int *rowh, int *vpos)
1317 struct it it;
1318 void *itdata = bidi_shelve_cache ();
1319 struct text_pos top;
1320 bool visible_p = false;
1321 struct buffer *old_buffer = NULL;
1322 bool r2l = false;
1324 if (FRAME_INITIAL_P (XFRAME (WINDOW_FRAME (w))))
1325 return visible_p;
1327 if (XBUFFER (w->contents) != current_buffer)
1329 old_buffer = current_buffer;
1330 set_buffer_internal_1 (XBUFFER (w->contents));
1333 SET_TEXT_POS_FROM_MARKER (top, w->start);
1334 /* Scrolling a minibuffer window via scroll bar when the echo area
1335 shows long text sometimes resets the minibuffer contents behind
1336 our backs. Also, someone might narrow-to-region and immediately
1337 call a scroll function. */
1338 if (CHARPOS (top) > ZV || CHARPOS (top) < BEGV)
1339 SET_TEXT_POS (top, BEGV, BEGV_BYTE);
1341 /* If the top of the window is after CHARPOS, the latter is surely
1342 not visible. */
1343 if (charpos >= 0 && CHARPOS (top) > charpos)
1344 return visible_p;
1346 /* Some Lisp hook could call us in the middle of redisplaying this
1347 very window. If, by some bad luck, we are retrying redisplay
1348 because we found that the mode-line height and/or header-line
1349 height needs to be updated, the assignment of mode_line_height
1350 and header_line_height below could disrupt that, due to the
1351 selected/nonselected window dance during mode-line display, and
1352 we could infloop. Avoid that. */
1353 int prev_mode_line_height = w->mode_line_height;
1354 int prev_header_line_height = w->header_line_height;
1355 /* Compute exact mode line heights. */
1356 if (window_wants_mode_line (w))
1358 Lisp_Object window_mode_line_format
1359 = window_parameter (w, Qmode_line_format);
1361 w->mode_line_height
1362 = display_mode_line (w, CURRENT_MODE_LINE_FACE_ID (w),
1363 NILP (window_mode_line_format)
1364 ? BVAR (current_buffer, mode_line_format)
1365 : window_mode_line_format);
1368 if (window_wants_header_line (w))
1370 Lisp_Object window_header_line_format
1371 = window_parameter (w, Qheader_line_format);
1373 w->header_line_height
1374 = display_mode_line (w, HEADER_LINE_FACE_ID,
1375 NILP (window_header_line_format)
1376 ? BVAR (current_buffer, header_line_format)
1377 : window_header_line_format);
1380 start_display (&it, w, top);
1381 move_it_to (&it, charpos, -1, it.last_visible_y - 1, -1,
1382 (charpos >= 0 ? MOVE_TO_POS : 0) | MOVE_TO_Y);
1384 /* Adjust for line numbers, if CHARPOS is at or beyond first_visible_x,
1385 but we didn't yet produce the line-number glyphs. */
1386 if (!NILP (Vdisplay_line_numbers)
1387 && it.current_x >= it.first_visible_x
1388 && IT_CHARPOS (it) == charpos
1389 && !it.line_number_produced_p)
1391 /* If the pixel width of line numbers was not yet known, compute
1392 it now. This usually happens in the first display line of a
1393 window. */
1394 if (!it.lnum_pixel_width)
1396 struct it it2;
1397 void *it2data = NULL;
1399 SAVE_IT (it2, it, it2data);
1400 move_it_by_lines (&it, 1);
1401 it2.lnum_pixel_width = it.lnum_pixel_width;
1402 RESTORE_IT (&it, &it2, it2data);
1404 it.current_x += it.lnum_pixel_width;
1407 if (charpos >= 0
1408 && (((!it.bidi_p || it.bidi_it.scan_dir != -1)
1409 && IT_CHARPOS (it) >= charpos)
1410 /* When scanning backwards under bidi iteration, move_it_to
1411 stops at or _before_ CHARPOS, because it stops at or to
1412 the _right_ of the character at CHARPOS. */
1413 || (it.bidi_p && it.bidi_it.scan_dir == -1
1414 && IT_CHARPOS (it) <= charpos)))
1416 /* We have reached CHARPOS, or passed it. How the call to
1417 move_it_to can overshoot: (i) If CHARPOS is on invisible text
1418 or covered by a display property, move_it_to stops at the end
1419 of the invisible text, to the right of CHARPOS. (ii) If
1420 CHARPOS is in a display vector, move_it_to stops on its last
1421 glyph. */
1422 int top_x = it.current_x;
1423 int top_y = it.current_y;
1424 int window_top_y = WINDOW_HEADER_LINE_HEIGHT (w);
1425 int bottom_y;
1426 struct it save_it;
1427 void *save_it_data = NULL;
1429 /* Calling line_bottom_y may change it.method, it.position, etc. */
1430 SAVE_IT (save_it, it, save_it_data);
1431 last_height = 0;
1432 bottom_y = line_bottom_y (&it);
1433 if (top_y < window_top_y)
1434 visible_p = bottom_y > window_top_y;
1435 else if (top_y < it.last_visible_y)
1436 visible_p = true;
1437 if (bottom_y >= it.last_visible_y
1438 && it.bidi_p && it.bidi_it.scan_dir == -1
1439 && IT_CHARPOS (it) < charpos)
1441 /* When the last line of the window is scanned backwards
1442 under bidi iteration, we could be duped into thinking
1443 that we have passed CHARPOS, when in fact move_it_to
1444 simply stopped short of CHARPOS because it reached
1445 last_visible_y. To see if that's what happened, we call
1446 move_it_to again with a slightly larger vertical limit,
1447 and see if it actually moved vertically; if it did, we
1448 didn't really reach CHARPOS, which is beyond window end. */
1449 /* Why 10? because we don't know how many canonical lines
1450 will the height of the next line(s) be. So we guess. */
1451 int ten_more_lines = 10 * default_line_pixel_height (w);
1453 move_it_to (&it, charpos, -1, bottom_y + ten_more_lines, -1,
1454 MOVE_TO_POS | MOVE_TO_Y);
1455 if (it.current_y > top_y)
1456 visible_p = false;
1459 RESTORE_IT (&it, &save_it, save_it_data);
1460 if (visible_p)
1462 if (it.method == GET_FROM_DISPLAY_VECTOR)
1464 /* We stopped on the last glyph of a display vector.
1465 Try and recompute. Hack alert! */
1466 if (charpos < 2 || top.charpos >= charpos)
1467 top_x = it.glyph_row->x;
1468 else
1470 struct it it2, it2_prev;
1471 /* The idea is to get to the previous buffer
1472 position, consume the character there, and use
1473 the pixel coordinates we get after that. But if
1474 the previous buffer position is also displayed
1475 from a display vector, we need to consume all of
1476 the glyphs from that display vector. */
1477 start_display (&it2, w, top);
1478 move_it_to (&it2, charpos - 1, -1, -1, -1, MOVE_TO_POS);
1479 /* If we didn't get to CHARPOS - 1, there's some
1480 replacing display property at that position, and
1481 we stopped after it. That is exactly the place
1482 whose coordinates we want. */
1483 if (IT_CHARPOS (it2) != charpos - 1)
1484 it2_prev = it2;
1485 else
1487 /* Iterate until we get out of the display
1488 vector that displays the character at
1489 CHARPOS - 1. */
1490 do {
1491 get_next_display_element (&it2);
1492 PRODUCE_GLYPHS (&it2);
1493 it2_prev = it2;
1494 set_iterator_to_next (&it2, true);
1495 } while (it2.method == GET_FROM_DISPLAY_VECTOR
1496 && IT_CHARPOS (it2) < charpos);
1498 if (ITERATOR_AT_END_OF_LINE_P (&it2_prev)
1499 || it2_prev.current_x > it2_prev.last_visible_x)
1500 top_x = it.glyph_row->x;
1501 else
1503 top_x = it2_prev.current_x;
1504 top_y = it2_prev.current_y;
1508 else if (IT_CHARPOS (it) != charpos)
1510 Lisp_Object cpos = make_number (charpos);
1511 Lisp_Object spec = Fget_char_property (cpos, Qdisplay, Qnil);
1512 Lisp_Object string = string_from_display_spec (spec);
1513 struct text_pos tpos;
1514 bool newline_in_string
1515 = (STRINGP (string)
1516 && memchr (SDATA (string), '\n', SBYTES (string)));
1518 SET_TEXT_POS (tpos, charpos, CHAR_TO_BYTE (charpos));
1519 bool replacing_spec_p
1520 = (!NILP (spec)
1521 && handle_display_spec (NULL, spec, Qnil, Qnil, &tpos,
1522 charpos, FRAME_WINDOW_P (it.f)));
1523 /* The tricky code below is needed because there's a
1524 discrepancy between move_it_to and how we set cursor
1525 when PT is at the beginning of a portion of text
1526 covered by a display property or an overlay with a
1527 display property, or the display line ends in a
1528 newline from a display string. move_it_to will stop
1529 _after_ such display strings, whereas
1530 set_cursor_from_row conspires with cursor_row_p to
1531 place the cursor on the first glyph produced from the
1532 display string. */
1534 /* We have overshoot PT because it is covered by a
1535 display property that replaces the text it covers.
1536 If the string includes embedded newlines, we are also
1537 in the wrong display line. Backtrack to the correct
1538 line, where the display property begins. */
1539 if (replacing_spec_p)
1541 Lisp_Object startpos, endpos;
1542 EMACS_INT start, end;
1543 struct it it3;
1545 /* Find the first and the last buffer positions
1546 covered by the display string. */
1547 endpos =
1548 Fnext_single_char_property_change (cpos, Qdisplay,
1549 Qnil, Qnil);
1550 startpos =
1551 Fprevious_single_char_property_change (endpos, Qdisplay,
1552 Qnil, Qnil);
1553 start = XFASTINT (startpos);
1554 end = XFASTINT (endpos);
1555 /* Move to the last buffer position before the
1556 display property. */
1557 start_display (&it3, w, top);
1558 if (start > CHARPOS (top))
1559 move_it_to (&it3, start - 1, -1, -1, -1, MOVE_TO_POS);
1560 /* Move forward one more line if the position before
1561 the display string is a newline or if it is the
1562 rightmost character on a line that is
1563 continued or word-wrapped. */
1564 if (it3.method == GET_FROM_BUFFER
1565 && (it3.c == '\n'
1566 || FETCH_BYTE (IT_BYTEPOS (it3)) == '\n'))
1567 move_it_by_lines (&it3, 1);
1568 else if (move_it_in_display_line_to (&it3, -1,
1569 it3.current_x
1570 + it3.pixel_width,
1571 MOVE_TO_X)
1572 == MOVE_LINE_CONTINUED)
1574 move_it_by_lines (&it3, 1);
1575 /* When we are under word-wrap, the #$@%!
1576 move_it_by_lines moves 2 lines, so we need to
1577 fix that up. */
1578 if (it3.line_wrap == WORD_WRAP)
1579 move_it_by_lines (&it3, -1);
1582 /* Record the vertical coordinate of the display
1583 line where we wound up. */
1584 top_y = it3.current_y;
1585 if (it3.bidi_p)
1587 /* When characters are reordered for display,
1588 the character displayed to the left of the
1589 display string could be _after_ the display
1590 property in the logical order. Use the
1591 smallest vertical position of these two. */
1592 start_display (&it3, w, top);
1593 move_it_to (&it3, end + 1, -1, -1, -1, MOVE_TO_POS);
1594 if (it3.current_y < top_y)
1595 top_y = it3.current_y;
1597 /* Move from the top of the window to the beginning
1598 of the display line where the display string
1599 begins. */
1600 start_display (&it3, w, top);
1601 move_it_to (&it3, -1, 0, top_y, -1, MOVE_TO_X | MOVE_TO_Y);
1602 /* If it3_moved stays false after the 'while' loop
1603 below, that means we already were at a newline
1604 before the loop (e.g., the display string begins
1605 with a newline), so we don't need to (and cannot)
1606 inspect the glyphs of it3.glyph_row, because
1607 PRODUCE_GLYPHS will not produce anything for a
1608 newline, and thus it3.glyph_row stays at its
1609 stale content it got at top of the window. */
1610 bool it3_moved = false;
1611 /* Finally, advance the iterator until we hit the
1612 first display element whose character position is
1613 CHARPOS, or until the first newline from the
1614 display string, which signals the end of the
1615 display line. */
1616 while (get_next_display_element (&it3))
1618 PRODUCE_GLYPHS (&it3);
1619 if (IT_CHARPOS (it3) == charpos
1620 || ITERATOR_AT_END_OF_LINE_P (&it3))
1621 break;
1622 it3_moved = true;
1623 set_iterator_to_next (&it3, false);
1625 top_x = it3.current_x - it3.pixel_width;
1626 /* Normally, we would exit the above loop because we
1627 found the display element whose character
1628 position is CHARPOS. For the contingency that we
1629 didn't, and stopped at the first newline from the
1630 display string, move back over the glyphs
1631 produced from the string, until we find the
1632 rightmost glyph not from the string. */
1633 if (it3_moved
1634 && newline_in_string
1635 && IT_CHARPOS (it3) != charpos && EQ (it3.object, string))
1637 struct glyph *g = it3.glyph_row->glyphs[TEXT_AREA]
1638 + it3.glyph_row->used[TEXT_AREA];
1640 while (EQ ((g - 1)->object, string))
1642 --g;
1643 top_x -= g->pixel_width;
1645 eassert (g < it3.glyph_row->glyphs[TEXT_AREA]
1646 + it3.glyph_row->used[TEXT_AREA]);
1651 *x = top_x;
1652 *y = max (top_y + max (0, it.max_ascent - it.ascent), window_top_y);
1653 *rtop = max (0, window_top_y - top_y);
1654 *rbot = max (0, bottom_y - it.last_visible_y);
1655 *rowh = max (0, (min (bottom_y, it.last_visible_y)
1656 - max (top_y, window_top_y)));
1657 *vpos = it.vpos;
1658 if (it.bidi_it.paragraph_dir == R2L)
1659 r2l = true;
1662 else
1664 /* Either we were asked to provide info about WINDOW_END, or
1665 CHARPOS is in the partially visible glyph row at end of
1666 window. */
1667 struct it it2;
1668 void *it2data = NULL;
1670 SAVE_IT (it2, it, it2data);
1671 if (IT_CHARPOS (it) < ZV && FETCH_BYTE (IT_BYTEPOS (it)) != '\n')
1672 move_it_by_lines (&it, 1);
1673 if (charpos < IT_CHARPOS (it)
1674 || (it.what == IT_EOB && charpos == IT_CHARPOS (it)))
1676 visible_p = true;
1677 RESTORE_IT (&it2, &it2, it2data);
1678 move_it_to (&it2, charpos, -1, -1, -1, MOVE_TO_POS);
1679 *x = it2.current_x;
1680 *y = it2.current_y + it2.max_ascent - it2.ascent;
1681 *rtop = max (0, -it2.current_y);
1682 *rbot = max (0, ((it2.current_y + it2.max_ascent + it2.max_descent)
1683 - it.last_visible_y));
1684 *rowh = max (0, (min (it2.current_y + it2.max_ascent + it2.max_descent,
1685 it.last_visible_y)
1686 - max (it2.current_y,
1687 WINDOW_HEADER_LINE_HEIGHT (w))));
1688 *vpos = it2.vpos;
1689 if (it2.bidi_it.paragraph_dir == R2L)
1690 r2l = true;
1692 else
1693 bidi_unshelve_cache (it2data, true);
1695 bidi_unshelve_cache (itdata, false);
1697 if (old_buffer)
1698 set_buffer_internal_1 (old_buffer);
1700 if (visible_p)
1702 if (w->hscroll > 0)
1703 *x -=
1704 window_hscroll_limited (w, WINDOW_XFRAME (w))
1705 * WINDOW_FRAME_COLUMN_WIDTH (w);
1706 /* For lines in an R2L paragraph, we need to mirror the X pixel
1707 coordinate wrt the text area. For the reasons, see the
1708 commentary in buffer_posn_from_coords and the explanation of
1709 the geometry used by the move_it_* functions at the end of
1710 the large commentary near the beginning of this file. */
1711 if (r2l)
1712 *x = window_box_width (w, TEXT_AREA) - *x - 1;
1715 #if false
1716 /* Debugging code. */
1717 if (visible_p)
1718 fprintf (stderr, "+pv pt=%d vs=%d --> x=%d y=%d rt=%d rb=%d rh=%d vp=%d\n",
1719 charpos, w->vscroll, *x, *y, *rtop, *rbot, *rowh, *vpos);
1720 else
1721 fprintf (stderr, "-pv pt=%d vs=%d\n", charpos, w->vscroll);
1722 #endif
1724 /* Restore potentially overwritten values. */
1725 w->mode_line_height = prev_mode_line_height;
1726 w->header_line_height = prev_header_line_height;
1728 return visible_p;
1732 /* Return the next character from STR. Return in *LEN the length of
1733 the character. This is like STRING_CHAR_AND_LENGTH but never
1734 returns an invalid character. If we find one, we return a `?', but
1735 with the length of the invalid character. */
1737 static int
1738 string_char_and_length (const unsigned char *str, int *len)
1740 int c;
1742 c = STRING_CHAR_AND_LENGTH (str, *len);
1743 if (!CHAR_VALID_P (c))
1744 /* We may not change the length here because other places in Emacs
1745 don't use this function, i.e. they silently accept invalid
1746 characters. */
1747 c = '?';
1749 return c;
1754 /* Given a position POS containing a valid character and byte position
1755 in STRING, return the position NCHARS ahead (NCHARS >= 0). */
1757 static struct text_pos
1758 string_pos_nchars_ahead (struct text_pos pos, Lisp_Object string, ptrdiff_t nchars)
1760 eassert (STRINGP (string) && nchars >= 0);
1762 if (STRING_MULTIBYTE (string))
1764 const unsigned char *p = SDATA (string) + BYTEPOS (pos);
1765 int len;
1767 while (nchars--)
1769 string_char_and_length (p, &len);
1770 p += len;
1771 CHARPOS (pos) += 1;
1772 BYTEPOS (pos) += len;
1775 else
1776 SET_TEXT_POS (pos, CHARPOS (pos) + nchars, BYTEPOS (pos) + nchars);
1778 return pos;
1782 /* Value is the text position, i.e. character and byte position,
1783 for character position CHARPOS in STRING. */
1785 static struct text_pos
1786 string_pos (ptrdiff_t charpos, Lisp_Object string)
1788 struct text_pos pos;
1789 eassert (STRINGP (string));
1790 eassert (charpos >= 0);
1791 SET_TEXT_POS (pos, charpos, string_char_to_byte (string, charpos));
1792 return pos;
1796 /* Value is a text position, i.e. character and byte position, for
1797 character position CHARPOS in C string S. MULTIBYTE_P
1798 means recognize multibyte characters. */
1800 static struct text_pos
1801 c_string_pos (ptrdiff_t charpos, const char *s, bool multibyte_p)
1803 struct text_pos pos;
1805 eassert (s != NULL);
1806 eassert (charpos >= 0);
1808 if (multibyte_p)
1810 int len;
1812 SET_TEXT_POS (pos, 0, 0);
1813 while (charpos--)
1815 string_char_and_length ((const unsigned char *) s, &len);
1816 s += len;
1817 CHARPOS (pos) += 1;
1818 BYTEPOS (pos) += len;
1821 else
1822 SET_TEXT_POS (pos, charpos, charpos);
1824 return pos;
1828 /* Value is the number of characters in C string S. MULTIBYTE_P
1829 means recognize multibyte characters. */
1831 static ptrdiff_t
1832 number_of_chars (const char *s, bool multibyte_p)
1834 ptrdiff_t nchars;
1836 if (multibyte_p)
1838 ptrdiff_t rest = strlen (s);
1839 int len;
1840 const unsigned char *p = (const unsigned char *) s;
1842 for (nchars = 0; rest > 0; ++nchars)
1844 string_char_and_length (p, &len);
1845 rest -= len, p += len;
1848 else
1849 nchars = strlen (s);
1851 return nchars;
1855 /* Compute byte position NEWPOS->bytepos corresponding to
1856 NEWPOS->charpos. POS is a known position in string STRING.
1857 NEWPOS->charpos must be >= POS.charpos. */
1859 static void
1860 compute_string_pos (struct text_pos *newpos, struct text_pos pos, Lisp_Object string)
1862 eassert (STRINGP (string));
1863 eassert (CHARPOS (*newpos) >= CHARPOS (pos));
1865 if (STRING_MULTIBYTE (string))
1866 *newpos = string_pos_nchars_ahead (pos, string,
1867 CHARPOS (*newpos) - CHARPOS (pos));
1868 else
1869 BYTEPOS (*newpos) = CHARPOS (*newpos);
1872 /* EXPORT:
1873 Return an estimation of the pixel height of mode or header lines on
1874 frame F. FACE_ID specifies what line's height to estimate. */
1877 estimate_mode_line_height (struct frame *f, enum face_id face_id)
1879 #ifdef HAVE_WINDOW_SYSTEM
1880 if (FRAME_WINDOW_P (f))
1882 int height = FONT_HEIGHT (FRAME_FONT (f));
1884 /* This function is called so early when Emacs starts that the face
1885 cache and mode line face are not yet initialized. */
1886 if (FRAME_FACE_CACHE (f))
1888 struct face *face = FACE_FROM_ID_OR_NULL (f, face_id);
1889 if (face)
1891 if (face->font)
1892 height = normal_char_height (face->font, -1);
1893 if (face->box_line_width > 0)
1894 height += 2 * face->box_line_width;
1898 return height;
1900 #endif
1902 return 1;
1905 /* Given a pixel position (PIX_X, PIX_Y) on frame F, return glyph
1906 co-ordinates in (*X, *Y). Set *BOUNDS to the rectangle that the
1907 glyph at X, Y occupies, if BOUNDS != 0. If NOCLIP, do
1908 not force the value into range. */
1910 void
1911 pixel_to_glyph_coords (struct frame *f, int pix_x, int pix_y, int *x, int *y,
1912 NativeRectangle *bounds, bool noclip)
1915 #ifdef HAVE_WINDOW_SYSTEM
1916 if (FRAME_WINDOW_P (f))
1918 /* Arrange for the division in FRAME_PIXEL_X_TO_COL etc. to round down
1919 even for negative values. */
1920 if (pix_x < 0)
1921 pix_x -= FRAME_COLUMN_WIDTH (f) - 1;
1922 if (pix_y < 0)
1923 pix_y -= FRAME_LINE_HEIGHT (f) - 1;
1925 pix_x = FRAME_PIXEL_X_TO_COL (f, pix_x);
1926 pix_y = FRAME_PIXEL_Y_TO_LINE (f, pix_y);
1928 if (bounds)
1929 STORE_NATIVE_RECT (*bounds,
1930 FRAME_COL_TO_PIXEL_X (f, pix_x),
1931 FRAME_LINE_TO_PIXEL_Y (f, pix_y),
1932 FRAME_COLUMN_WIDTH (f) - 1,
1933 FRAME_LINE_HEIGHT (f) - 1);
1935 /* PXW: Should we clip pixels before converting to columns/lines? */
1936 if (!noclip)
1938 if (pix_x < 0)
1939 pix_x = 0;
1940 else if (pix_x > FRAME_TOTAL_COLS (f))
1941 pix_x = FRAME_TOTAL_COLS (f);
1943 if (pix_y < 0)
1944 pix_y = 0;
1945 else if (pix_y > FRAME_TOTAL_LINES (f))
1946 pix_y = FRAME_TOTAL_LINES (f);
1949 #endif
1951 *x = pix_x;
1952 *y = pix_y;
1956 /* Find the glyph under window-relative coordinates X/Y in window W.
1957 Consider only glyphs from buffer text, i.e. no glyphs from overlay
1958 strings. Return in *HPOS and *VPOS the row and column number of
1959 the glyph found. Return in *AREA the glyph area containing X.
1960 Value is a pointer to the glyph found or null if X/Y is not on
1961 text, or we can't tell because W's current matrix is not up to
1962 date. */
1964 static struct glyph *
1965 x_y_to_hpos_vpos (struct window *w, int x, int y, int *hpos, int *vpos,
1966 int *dx, int *dy, int *area)
1968 struct glyph *glyph, *end;
1969 struct glyph_row *row = NULL;
1970 int x0, i;
1972 /* Find row containing Y. Give up if some row is not enabled. */
1973 for (i = 0; i < w->current_matrix->nrows; ++i)
1975 row = MATRIX_ROW (w->current_matrix, i);
1976 if (!row->enabled_p)
1977 return NULL;
1978 if (y >= row->y && y < MATRIX_ROW_BOTTOM_Y (row))
1979 break;
1982 *vpos = i;
1983 *hpos = 0;
1985 /* Give up if Y is not in the window. */
1986 if (i == w->current_matrix->nrows)
1987 return NULL;
1989 /* Get the glyph area containing X. */
1990 if (w->pseudo_window_p)
1992 *area = TEXT_AREA;
1993 x0 = 0;
1995 else
1997 if (x < window_box_left_offset (w, TEXT_AREA))
1999 *area = LEFT_MARGIN_AREA;
2000 x0 = window_box_left_offset (w, LEFT_MARGIN_AREA);
2002 else if (x < window_box_right_offset (w, TEXT_AREA))
2004 *area = TEXT_AREA;
2005 x0 = window_box_left_offset (w, TEXT_AREA) + min (row->x, 0);
2007 else
2009 *area = RIGHT_MARGIN_AREA;
2010 x0 = window_box_left_offset (w, RIGHT_MARGIN_AREA);
2014 /* Find glyph containing X. */
2015 glyph = row->glyphs[*area];
2016 end = glyph + row->used[*area];
2017 x -= x0;
2018 while (glyph < end && x >= glyph->pixel_width)
2020 x -= glyph->pixel_width;
2021 ++glyph;
2024 if (glyph == end)
2025 return NULL;
2027 if (dx)
2029 *dx = x;
2030 *dy = y - (row->y + row->ascent - glyph->ascent);
2033 *hpos = glyph - row->glyphs[*area];
2034 return glyph;
2037 /* Convert frame-relative x/y to coordinates relative to window W.
2038 Takes pseudo-windows into account. */
2040 static void
2041 frame_to_window_pixel_xy (struct window *w, int *x, int *y)
2043 if (w->pseudo_window_p)
2045 /* A pseudo-window is always full-width, and starts at the
2046 left edge of the frame, plus a frame border. */
2047 struct frame *f = XFRAME (w->frame);
2048 *x -= FRAME_INTERNAL_BORDER_WIDTH (f);
2049 *y = FRAME_TO_WINDOW_PIXEL_Y (w, *y);
2051 else
2053 *x -= WINDOW_LEFT_EDGE_X (w);
2054 *y = FRAME_TO_WINDOW_PIXEL_Y (w, *y);
2058 #ifdef HAVE_WINDOW_SYSTEM
2060 /* EXPORT:
2061 Return in RECTS[] at most N clipping rectangles for glyph string S.
2062 Return the number of stored rectangles. */
2065 get_glyph_string_clip_rects (struct glyph_string *s, NativeRectangle *rects, int n)
2067 XRectangle r;
2069 if (n <= 0)
2070 return 0;
2072 if (s->row->full_width_p)
2074 /* Draw full-width. X coordinates are relative to S->w->left_col. */
2075 r.x = WINDOW_LEFT_EDGE_X (s->w);
2076 if (s->row->mode_line_p)
2077 r.width = WINDOW_PIXEL_WIDTH (s->w) - WINDOW_RIGHT_DIVIDER_WIDTH (s->w);
2078 else
2079 r.width = WINDOW_PIXEL_WIDTH (s->w);
2081 /* Unless displaying a mode or menu bar line, which are always
2082 fully visible, clip to the visible part of the row. */
2083 if (s->w->pseudo_window_p)
2084 r.height = s->row->visible_height;
2085 else
2086 r.height = s->height;
2088 else
2090 /* This is a text line that may be partially visible. */
2091 r.x = window_box_left (s->w, s->area);
2092 r.width = window_box_width (s->w, s->area);
2093 r.height = s->row->visible_height;
2096 if (s->clip_head)
2097 if (r.x < s->clip_head->x)
2099 if (r.width >= s->clip_head->x - r.x)
2100 r.width -= s->clip_head->x - r.x;
2101 else
2102 r.width = 0;
2103 r.x = s->clip_head->x;
2105 if (s->clip_tail)
2106 if (r.x + r.width > s->clip_tail->x + s->clip_tail->background_width)
2108 if (s->clip_tail->x + s->clip_tail->background_width >= r.x)
2109 r.width = s->clip_tail->x + s->clip_tail->background_width - r.x;
2110 else
2111 r.width = 0;
2114 /* If S draws overlapping rows, it's sufficient to use the top and
2115 bottom of the window for clipping because this glyph string
2116 intentionally draws over other lines. */
2117 if (s->for_overlaps)
2119 r.y = WINDOW_HEADER_LINE_HEIGHT (s->w);
2120 r.height = window_text_bottom_y (s->w) - r.y;
2122 /* Alas, the above simple strategy does not work for the
2123 environments with anti-aliased text: if the same text is
2124 drawn onto the same place multiple times, it gets thicker.
2125 If the overlap we are processing is for the erased cursor, we
2126 take the intersection with the rectangle of the cursor. */
2127 if (s->for_overlaps & OVERLAPS_ERASED_CURSOR)
2129 XRectangle rc, r_save = r;
2131 rc.x = WINDOW_TEXT_TO_FRAME_PIXEL_X (s->w, s->w->phys_cursor.x);
2132 rc.y = s->w->phys_cursor.y;
2133 rc.width = s->w->phys_cursor_width;
2134 rc.height = s->w->phys_cursor_height;
2136 x_intersect_rectangles (&r_save, &rc, &r);
2139 else
2141 /* Don't use S->y for clipping because it doesn't take partially
2142 visible lines into account. For example, it can be negative for
2143 partially visible lines at the top of a window. */
2144 if (!s->row->full_width_p
2145 && MATRIX_ROW_PARTIALLY_VISIBLE_AT_TOP_P (s->w, s->row))
2146 r.y = WINDOW_HEADER_LINE_HEIGHT (s->w);
2147 else
2148 r.y = max (0, s->row->y);
2151 r.y = WINDOW_TO_FRAME_PIXEL_Y (s->w, r.y);
2153 /* If drawing the cursor, don't let glyph draw outside its
2154 advertised boundaries. Cleartype does this under some circumstances. */
2155 if (s->hl == DRAW_CURSOR)
2157 struct glyph *glyph = s->first_glyph;
2158 int height, max_y;
2160 if (s->x > r.x)
2162 if (r.width >= s->x - r.x)
2163 r.width -= s->x - r.x;
2164 else /* R2L hscrolled row with cursor outside text area */
2165 r.width = 0;
2166 r.x = s->x;
2168 r.width = min (r.width, glyph->pixel_width);
2170 /* If r.y is below window bottom, ensure that we still see a cursor. */
2171 height = min (glyph->ascent + glyph->descent,
2172 min (FRAME_LINE_HEIGHT (s->f), s->row->visible_height));
2173 max_y = window_text_bottom_y (s->w) - height;
2174 max_y = WINDOW_TO_FRAME_PIXEL_Y (s->w, max_y);
2175 if (s->ybase - glyph->ascent > max_y)
2177 r.y = max_y;
2178 r.height = height;
2180 else
2182 /* Don't draw cursor glyph taller than our actual glyph. */
2183 height = max (FRAME_LINE_HEIGHT (s->f), glyph->ascent + glyph->descent);
2184 if (height < r.height)
2186 max_y = r.y + r.height;
2187 r.y = min (max_y, max (r.y, s->ybase + glyph->descent - height));
2188 r.height = min (max_y - r.y, height);
2193 if (s->row->clip)
2195 XRectangle r_save = r;
2197 if (! x_intersect_rectangles (&r_save, s->row->clip, &r))
2198 r.width = 0;
2201 if ((s->for_overlaps & OVERLAPS_BOTH) == 0
2202 || ((s->for_overlaps & OVERLAPS_BOTH) == OVERLAPS_BOTH && n == 1))
2204 #ifdef CONVERT_FROM_XRECT
2205 CONVERT_FROM_XRECT (r, *rects);
2206 #else
2207 *rects = r;
2208 #endif
2209 return 1;
2211 else
2213 /* If we are processing overlapping and allowed to return
2214 multiple clipping rectangles, we exclude the row of the glyph
2215 string from the clipping rectangle. This is to avoid drawing
2216 the same text on the environment with anti-aliasing. */
2217 #ifdef CONVERT_FROM_XRECT
2218 XRectangle rs[2];
2219 #else
2220 XRectangle *rs = rects;
2221 #endif
2222 int i = 0, row_y = WINDOW_TO_FRAME_PIXEL_Y (s->w, s->row->y);
2224 if (s->for_overlaps & OVERLAPS_PRED)
2226 rs[i] = r;
2227 if (r.y + r.height > row_y)
2229 if (r.y < row_y)
2230 rs[i].height = row_y - r.y;
2231 else
2232 rs[i].height = 0;
2234 i++;
2236 if (s->for_overlaps & OVERLAPS_SUCC)
2238 rs[i] = r;
2239 if (r.y < row_y + s->row->visible_height)
2241 if (r.y + r.height > row_y + s->row->visible_height)
2243 rs[i].y = row_y + s->row->visible_height;
2244 rs[i].height = r.y + r.height - rs[i].y;
2246 else
2247 rs[i].height = 0;
2249 i++;
2252 n = i;
2253 #ifdef CONVERT_FROM_XRECT
2254 for (i = 0; i < n; i++)
2255 CONVERT_FROM_XRECT (rs[i], rects[i]);
2256 #endif
2257 return n;
2261 /* EXPORT:
2262 Return in *NR the clipping rectangle for glyph string S. */
2264 void
2265 get_glyph_string_clip_rect (struct glyph_string *s, NativeRectangle *nr)
2267 get_glyph_string_clip_rects (s, nr, 1);
2271 /* EXPORT:
2272 Return the position and height of the phys cursor in window W.
2273 Set w->phys_cursor_width to width of phys cursor.
2276 void
2277 get_phys_cursor_geometry (struct window *w, struct glyph_row *row,
2278 struct glyph *glyph, int *xp, int *yp, int *heightp)
2280 struct frame *f = XFRAME (WINDOW_FRAME (w));
2281 int x, y, wd, h, h0, y0, ascent;
2283 /* Compute the width of the rectangle to draw. If on a stretch
2284 glyph, and `x-stretch-block-cursor' is nil, don't draw a
2285 rectangle as wide as the glyph, but use a canonical character
2286 width instead. */
2287 wd = glyph->pixel_width;
2289 x = w->phys_cursor.x;
2290 if (x < 0)
2292 wd += x;
2293 x = 0;
2296 if (glyph->type == STRETCH_GLYPH
2297 && !x_stretch_cursor_p)
2298 wd = min (FRAME_COLUMN_WIDTH (f), wd);
2299 w->phys_cursor_width = wd;
2301 /* Don't let the hollow cursor glyph descend below the glyph row's
2302 ascent value, lest the hollow cursor looks funny. */
2303 y = w->phys_cursor.y;
2304 ascent = row->ascent;
2305 if (row->ascent < glyph->ascent)
2307 y -= glyph->ascent - row->ascent;
2308 ascent = glyph->ascent;
2311 /* If y is below window bottom, ensure that we still see a cursor. */
2312 h0 = min (FRAME_LINE_HEIGHT (f), row->visible_height);
2314 h = max (h0, ascent + glyph->descent);
2315 h0 = min (h0, ascent + glyph->descent);
2317 y0 = WINDOW_HEADER_LINE_HEIGHT (w);
2318 if (y < y0)
2320 h = max (h - (y0 - y) + 1, h0);
2321 y = y0 - 1;
2323 else
2325 y0 = window_text_bottom_y (w) - h0;
2326 if (y > y0)
2328 h += y - y0;
2329 y = y0;
2333 *xp = WINDOW_TEXT_TO_FRAME_PIXEL_X (w, x);
2334 *yp = WINDOW_TO_FRAME_PIXEL_Y (w, y);
2335 *heightp = h;
2339 * Remember which glyph the mouse is over.
2342 void
2343 remember_mouse_glyph (struct frame *f, int gx, int gy, NativeRectangle *rect)
2345 Lisp_Object window;
2346 struct window *w;
2347 struct glyph_row *r, *gr, *end_row;
2348 enum window_part part;
2349 enum glyph_row_area area;
2350 int x, y, width, height;
2352 /* Try to determine frame pixel position and size of the glyph under
2353 frame pixel coordinates X/Y on frame F. */
2355 if (window_resize_pixelwise)
2357 width = height = 1;
2358 goto virtual_glyph;
2360 else if (!f->glyphs_initialized_p
2361 || (window = window_from_coordinates (f, gx, gy, &part, false),
2362 NILP (window)))
2364 width = FRAME_SMALLEST_CHAR_WIDTH (f);
2365 height = FRAME_SMALLEST_FONT_HEIGHT (f);
2366 goto virtual_glyph;
2369 w = XWINDOW (window);
2370 width = WINDOW_FRAME_COLUMN_WIDTH (w);
2371 height = WINDOW_FRAME_LINE_HEIGHT (w);
2373 x = window_relative_x_coord (w, part, gx);
2374 y = gy - WINDOW_TOP_EDGE_Y (w);
2376 r = MATRIX_FIRST_TEXT_ROW (w->current_matrix);
2377 end_row = MATRIX_BOTTOM_TEXT_ROW (w->current_matrix, w);
2379 if (w->pseudo_window_p)
2381 area = TEXT_AREA;
2382 part = ON_MODE_LINE; /* Don't adjust margin. */
2383 goto text_glyph;
2386 switch (part)
2388 case ON_LEFT_MARGIN:
2389 area = LEFT_MARGIN_AREA;
2390 goto text_glyph;
2392 case ON_RIGHT_MARGIN:
2393 area = RIGHT_MARGIN_AREA;
2394 goto text_glyph;
2396 case ON_HEADER_LINE:
2397 case ON_MODE_LINE:
2398 gr = (part == ON_HEADER_LINE
2399 ? MATRIX_HEADER_LINE_ROW (w->current_matrix)
2400 : MATRIX_MODE_LINE_ROW (w->current_matrix));
2401 gy = gr->y;
2402 area = TEXT_AREA;
2403 goto text_glyph_row_found;
2405 case ON_TEXT:
2406 area = TEXT_AREA;
2408 text_glyph:
2409 gr = 0; gy = 0;
2410 for (; r <= end_row && r->enabled_p; ++r)
2411 if (r->y + r->height > y)
2413 gr = r; gy = r->y;
2414 break;
2417 text_glyph_row_found:
2418 if (gr && gy <= y)
2420 struct glyph *g = gr->glyphs[area];
2421 struct glyph *end = g + gr->used[area];
2423 height = gr->height;
2424 for (gx = gr->x; g < end; gx += g->pixel_width, ++g)
2425 if (gx + g->pixel_width > x)
2426 break;
2428 if (g < end)
2430 if (g->type == IMAGE_GLYPH)
2432 /* Don't remember when mouse is over image, as
2433 image may have hot-spots. */
2434 STORE_NATIVE_RECT (*rect, 0, 0, 0, 0);
2435 return;
2437 width = g->pixel_width;
2439 else
2441 /* Use nominal char spacing at end of line. */
2442 x -= gx;
2443 gx += (x / width) * width;
2446 if (part != ON_MODE_LINE && part != ON_HEADER_LINE)
2448 gx += window_box_left_offset (w, area);
2449 /* Don't expand over the modeline to make sure the vertical
2450 drag cursor is shown early enough. */
2451 height = min (height,
2452 max (0, WINDOW_BOX_HEIGHT_NO_MODE_LINE (w) - gy));
2455 else
2457 /* Use nominal line height at end of window. */
2458 gx = (x / width) * width;
2459 y -= gy;
2460 gy += (y / height) * height;
2461 if (part != ON_MODE_LINE && part != ON_HEADER_LINE)
2462 /* See comment above. */
2463 height = min (height,
2464 max (0, WINDOW_BOX_HEIGHT_NO_MODE_LINE (w) - gy));
2466 break;
2468 case ON_LEFT_FRINGE:
2469 gx = (WINDOW_HAS_FRINGES_OUTSIDE_MARGINS (w)
2470 ? WINDOW_LEFT_SCROLL_BAR_AREA_WIDTH (w)
2471 : window_box_right_offset (w, LEFT_MARGIN_AREA));
2472 width = WINDOW_LEFT_FRINGE_WIDTH (w);
2473 goto row_glyph;
2475 case ON_RIGHT_FRINGE:
2476 gx = (WINDOW_HAS_FRINGES_OUTSIDE_MARGINS (w)
2477 ? window_box_right_offset (w, RIGHT_MARGIN_AREA)
2478 : window_box_right_offset (w, TEXT_AREA));
2479 if (WINDOW_RIGHT_DIVIDER_WIDTH (w) == 0
2480 && !WINDOW_HAS_VERTICAL_SCROLL_BAR (w)
2481 && !WINDOW_RIGHTMOST_P (w))
2482 if (gx < WINDOW_PIXEL_WIDTH (w) - width)
2483 /* Make sure the vertical border can get her own glyph to the
2484 right of the one we build here. */
2485 width = WINDOW_RIGHT_FRINGE_WIDTH (w) - width;
2486 else
2487 width = WINDOW_PIXEL_WIDTH (w) - gx;
2488 else
2489 width = WINDOW_RIGHT_FRINGE_WIDTH (w);
2491 goto row_glyph;
2493 case ON_VERTICAL_BORDER:
2494 gx = WINDOW_PIXEL_WIDTH (w) - width;
2495 goto row_glyph;
2497 case ON_VERTICAL_SCROLL_BAR:
2498 gx = (WINDOW_HAS_VERTICAL_SCROLL_BAR_ON_LEFT (w)
2500 : (window_box_right_offset (w, RIGHT_MARGIN_AREA)
2501 + (WINDOW_HAS_FRINGES_OUTSIDE_MARGINS (w)
2502 ? WINDOW_RIGHT_FRINGE_WIDTH (w)
2503 : 0)));
2504 width = WINDOW_SCROLL_BAR_AREA_WIDTH (w);
2506 row_glyph:
2507 gr = 0, gy = 0;
2508 for (; r <= end_row && r->enabled_p; ++r)
2509 if (r->y + r->height > y)
2511 gr = r; gy = r->y;
2512 break;
2515 if (gr && gy <= y)
2516 height = gr->height;
2517 else
2519 /* Use nominal line height at end of window. */
2520 y -= gy;
2521 gy += (y / height) * height;
2523 break;
2525 case ON_RIGHT_DIVIDER:
2526 gx = WINDOW_PIXEL_WIDTH (w) - WINDOW_RIGHT_DIVIDER_WIDTH (w);
2527 width = WINDOW_RIGHT_DIVIDER_WIDTH (w);
2528 gy = 0;
2529 /* The bottom divider prevails. */
2530 height = WINDOW_PIXEL_HEIGHT (w) - WINDOW_BOTTOM_DIVIDER_WIDTH (w);
2531 goto add_edge;
2533 case ON_BOTTOM_DIVIDER:
2534 gx = 0;
2535 width = WINDOW_PIXEL_WIDTH (w);
2536 gy = WINDOW_PIXEL_HEIGHT (w) - WINDOW_BOTTOM_DIVIDER_WIDTH (w);
2537 height = WINDOW_BOTTOM_DIVIDER_WIDTH (w);
2538 goto add_edge;
2540 default:
2542 virtual_glyph:
2543 /* If there is no glyph under the mouse, then we divide the screen
2544 into a grid of the smallest glyph in the frame, and use that
2545 as our "glyph". */
2547 /* Arrange for the division in FRAME_PIXEL_X_TO_COL etc. to
2548 round down even for negative values. */
2549 if (gx < 0)
2550 gx -= width - 1;
2551 if (gy < 0)
2552 gy -= height - 1;
2554 gx = (gx / width) * width;
2555 gy = (gy / height) * height;
2557 goto store_rect;
2560 add_edge:
2561 gx += WINDOW_LEFT_EDGE_X (w);
2562 gy += WINDOW_TOP_EDGE_Y (w);
2564 store_rect:
2565 STORE_NATIVE_RECT (*rect, gx, gy, width, height);
2567 /* Visible feedback for debugging. */
2568 #if false && defined HAVE_X_WINDOWS
2569 XDrawRectangle (FRAME_X_DISPLAY (f), FRAME_X_DRAWABLE (f),
2570 f->output_data.x->normal_gc,
2571 gx, gy, width, height);
2572 #endif
2576 #endif /* HAVE_WINDOW_SYSTEM */
2578 static void
2579 adjust_window_ends (struct window *w, struct glyph_row *row, bool current)
2581 eassert (w);
2582 w->window_end_pos = Z - MATRIX_ROW_END_CHARPOS (row);
2583 w->window_end_bytepos = Z_BYTE - MATRIX_ROW_END_BYTEPOS (row);
2584 w->window_end_vpos
2585 = MATRIX_ROW_VPOS (row, current ? w->current_matrix : w->desired_matrix);
2588 static bool
2589 hscrolling_current_line_p (struct window *w)
2591 return (!w->suspend_auto_hscroll
2592 && EQ (Fbuffer_local_value (Qauto_hscroll_mode, w->contents),
2593 Qcurrent_line));
2596 /***********************************************************************
2597 Lisp form evaluation
2598 ***********************************************************************/
2600 /* Error handler for safe_eval and safe_call. */
2602 static Lisp_Object
2603 safe_eval_handler (Lisp_Object arg, ptrdiff_t nargs, Lisp_Object *args)
2605 add_to_log ("Error during redisplay: %S signaled %S",
2606 Flist (nargs, args), arg);
2607 return Qnil;
2610 /* Call function FUNC with the rest of NARGS - 1 arguments
2611 following. Return the result, or nil if something went
2612 wrong. Prevent redisplay during the evaluation. */
2614 static Lisp_Object
2615 safe__call (bool inhibit_quit, ptrdiff_t nargs, Lisp_Object func, va_list ap)
2617 Lisp_Object val;
2619 if (inhibit_eval_during_redisplay)
2620 val = Qnil;
2621 else
2623 ptrdiff_t i;
2624 ptrdiff_t count = SPECPDL_INDEX ();
2625 Lisp_Object *args;
2626 USE_SAFE_ALLOCA;
2627 SAFE_ALLOCA_LISP (args, nargs);
2629 args[0] = func;
2630 for (i = 1; i < nargs; i++)
2631 args[i] = va_arg (ap, Lisp_Object);
2633 specbind (Qinhibit_redisplay, Qt);
2634 if (inhibit_quit)
2635 specbind (Qinhibit_quit, Qt);
2636 /* Use Qt to ensure debugger does not run,
2637 so there is no possibility of wanting to redisplay. */
2638 val = internal_condition_case_n (Ffuncall, nargs, args, Qt,
2639 safe_eval_handler);
2640 SAFE_FREE ();
2641 val = unbind_to (count, val);
2644 return val;
2647 Lisp_Object
2648 safe_call (ptrdiff_t nargs, Lisp_Object func, ...)
2650 Lisp_Object retval;
2651 va_list ap;
2653 va_start (ap, func);
2654 retval = safe__call (false, nargs, func, ap);
2655 va_end (ap);
2656 return retval;
2659 /* Call function FN with one argument ARG.
2660 Return the result, or nil if something went wrong. */
2662 Lisp_Object
2663 safe_call1 (Lisp_Object fn, Lisp_Object arg)
2665 return safe_call (2, fn, arg);
2668 static Lisp_Object
2669 safe__call1 (bool inhibit_quit, Lisp_Object fn, ...)
2671 Lisp_Object retval;
2672 va_list ap;
2674 va_start (ap, fn);
2675 retval = safe__call (inhibit_quit, 2, fn, ap);
2676 va_end (ap);
2677 return retval;
2680 Lisp_Object
2681 safe_eval (Lisp_Object sexpr)
2683 return safe__call1 (false, Qeval, sexpr);
2686 static Lisp_Object
2687 safe__eval (bool inhibit_quit, Lisp_Object sexpr)
2689 return safe__call1 (inhibit_quit, Qeval, sexpr);
2692 /* Call function FN with two arguments ARG1 and ARG2.
2693 Return the result, or nil if something went wrong. */
2695 Lisp_Object
2696 safe_call2 (Lisp_Object fn, Lisp_Object arg1, Lisp_Object arg2)
2698 return safe_call (3, fn, arg1, arg2);
2703 /***********************************************************************
2704 Debugging
2705 ***********************************************************************/
2707 /* Define CHECK_IT to perform sanity checks on iterators.
2708 This is for debugging. It is too slow to do unconditionally. */
2710 static void
2711 CHECK_IT (struct it *it)
2713 #if false
2714 if (it->method == GET_FROM_STRING)
2716 eassert (STRINGP (it->string));
2717 eassert (IT_STRING_CHARPOS (*it) >= 0);
2719 else
2721 eassert (IT_STRING_CHARPOS (*it) < 0);
2722 if (it->method == GET_FROM_BUFFER)
2724 /* Check that character and byte positions agree. */
2725 eassert (IT_CHARPOS (*it) == BYTE_TO_CHAR (IT_BYTEPOS (*it)));
2729 if (it->dpvec)
2730 eassert (it->current.dpvec_index >= 0);
2731 else
2732 eassert (it->current.dpvec_index < 0);
2733 #endif
2737 /* Check that the window end of window W is what we expect it
2738 to be---the last row in the current matrix displaying text. */
2740 static void
2741 CHECK_WINDOW_END (struct window *w)
2743 #if defined GLYPH_DEBUG && defined ENABLE_CHECKING
2744 if (!MINI_WINDOW_P (w) && w->window_end_valid)
2746 struct glyph_row *row;
2747 eassert ((row = MATRIX_ROW (w->current_matrix, w->window_end_vpos),
2748 !row->enabled_p
2749 || MATRIX_ROW_DISPLAYS_TEXT_P (row)
2750 || MATRIX_ROW_VPOS (row, w->current_matrix) == 0));
2752 #endif
2755 /***********************************************************************
2756 Iterator initialization
2757 ***********************************************************************/
2759 /* Initialize IT for displaying current_buffer in window W, starting
2760 at character position CHARPOS. CHARPOS < 0 means that no buffer
2761 position is specified which is useful when the iterator is assigned
2762 a position later. BYTEPOS is the byte position corresponding to
2763 CHARPOS.
2765 If ROW is not null, calls to produce_glyphs with IT as parameter
2766 will produce glyphs in that row.
2768 BASE_FACE_ID is the id of a base face to use. It must be one of
2769 DEFAULT_FACE_ID for normal text, MODE_LINE_FACE_ID,
2770 MODE_LINE_INACTIVE_FACE_ID, or HEADER_LINE_FACE_ID for displaying
2771 mode lines, or TOOL_BAR_FACE_ID for displaying the tool-bar.
2773 If ROW is null and BASE_FACE_ID is equal to MODE_LINE_FACE_ID,
2774 MODE_LINE_INACTIVE_FACE_ID, or HEADER_LINE_FACE_ID, the iterator
2775 will be initialized to use the corresponding mode line glyph row of
2776 the desired matrix of W. */
2778 void
2779 init_iterator (struct it *it, struct window *w,
2780 ptrdiff_t charpos, ptrdiff_t bytepos,
2781 struct glyph_row *row, enum face_id base_face_id)
2783 enum face_id remapped_base_face_id = base_face_id;
2785 /* Some precondition checks. */
2786 eassert (w != NULL && it != NULL);
2787 eassert (charpos < 0 || (charpos >= BUF_BEG (current_buffer)
2788 && charpos <= ZV));
2790 /* If face attributes have been changed since the last redisplay,
2791 free realized faces now because they depend on face definitions
2792 that might have changed. Don't free faces while there might be
2793 desired matrices pending which reference these faces. */
2794 if (!inhibit_free_realized_faces)
2796 if (face_change)
2798 face_change = false;
2799 XFRAME (w->frame)->face_change = 0;
2800 free_all_realized_faces (Qnil);
2802 else if (XFRAME (w->frame)->face_change)
2804 XFRAME (w->frame)->face_change = 0;
2805 free_all_realized_faces (w->frame);
2809 /* Perhaps remap BASE_FACE_ID to a user-specified alternative. */
2810 if (! NILP (Vface_remapping_alist))
2811 remapped_base_face_id
2812 = lookup_basic_face (w, XFRAME (w->frame), base_face_id);
2814 /* Use one of the mode line rows of W's desired matrix if
2815 appropriate. */
2816 if (row == NULL)
2818 if (base_face_id == MODE_LINE_FACE_ID
2819 || base_face_id == MODE_LINE_INACTIVE_FACE_ID)
2820 row = MATRIX_MODE_LINE_ROW (w->desired_matrix);
2821 else if (base_face_id == HEADER_LINE_FACE_ID)
2822 row = MATRIX_HEADER_LINE_ROW (w->desired_matrix);
2825 /* Clear IT, and set it->object and other IT's Lisp objects to Qnil.
2826 Other parts of redisplay rely on that. */
2827 memclear (it, sizeof *it);
2828 it->current.overlay_string_index = -1;
2829 it->current.dpvec_index = -1;
2830 it->base_face_id = remapped_base_face_id;
2831 IT_STRING_CHARPOS (*it) = IT_STRING_BYTEPOS (*it) = -1;
2832 it->paragraph_embedding = L2R;
2833 it->bidi_it.w = w;
2835 /* The window in which we iterate over current_buffer: */
2836 XSETWINDOW (it->window, w);
2837 it->w = w;
2838 it->f = XFRAME (w->frame);
2840 it->cmp_it.id = -1;
2842 /* Extra space between lines (on window systems only). */
2843 if (base_face_id == DEFAULT_FACE_ID
2844 && FRAME_WINDOW_P (it->f))
2846 if (NATNUMP (BVAR (current_buffer, extra_line_spacing)))
2847 it->extra_line_spacing = XFASTINT (BVAR (current_buffer, extra_line_spacing));
2848 else if (FLOATP (BVAR (current_buffer, extra_line_spacing)))
2849 it->extra_line_spacing = (XFLOAT_DATA (BVAR (current_buffer, extra_line_spacing))
2850 * FRAME_LINE_HEIGHT (it->f));
2851 else if (it->f->extra_line_spacing > 0)
2852 it->extra_line_spacing = it->f->extra_line_spacing;
2855 /* If realized faces have been removed, e.g. because of face
2856 attribute changes of named faces, recompute them. When running
2857 in batch mode, the face cache of the initial frame is null. If
2858 we happen to get called, make a dummy face cache. */
2859 if (FRAME_FACE_CACHE (it->f) == NULL)
2860 init_frame_faces (it->f);
2861 if (FRAME_FACE_CACHE (it->f)->used == 0)
2862 recompute_basic_faces (it->f);
2864 it->override_ascent = -1;
2866 /* Are control characters displayed as `^C'? */
2867 it->ctl_arrow_p = !NILP (BVAR (current_buffer, ctl_arrow));
2869 /* -1 means everything between a CR and the following line end
2870 is invisible. >0 means lines indented more than this value are
2871 invisible. */
2872 it->selective = (INTEGERP (BVAR (current_buffer, selective_display))
2873 ? (clip_to_bounds
2874 (-1, XINT (BVAR (current_buffer, selective_display)),
2875 PTRDIFF_MAX))
2876 : (!NILP (BVAR (current_buffer, selective_display))
2877 ? -1 : 0));
2878 it->selective_display_ellipsis_p
2879 = !NILP (BVAR (current_buffer, selective_display_ellipses));
2881 /* Display table to use. */
2882 it->dp = window_display_table (w);
2884 /* Are multibyte characters enabled in current_buffer? */
2885 it->multibyte_p = !NILP (BVAR (current_buffer, enable_multibyte_characters));
2887 /* Get the position at which the redisplay_end_trigger hook should
2888 be run, if it is to be run at all. */
2889 if (MARKERP (w->redisplay_end_trigger)
2890 && XMARKER (w->redisplay_end_trigger)->buffer != 0)
2891 it->redisplay_end_trigger_charpos
2892 = marker_position (w->redisplay_end_trigger);
2893 else if (INTEGERP (w->redisplay_end_trigger))
2894 it->redisplay_end_trigger_charpos
2895 = clip_to_bounds (PTRDIFF_MIN, XINT (w->redisplay_end_trigger),
2896 PTRDIFF_MAX);
2898 it->tab_width = SANE_TAB_WIDTH (current_buffer);
2900 /* Are lines in the display truncated? */
2901 if (TRUNCATE != 0)
2902 it->line_wrap = TRUNCATE;
2903 if (base_face_id == DEFAULT_FACE_ID
2904 && !it->w->hscroll
2905 && (WINDOW_FULL_WIDTH_P (it->w)
2906 || NILP (Vtruncate_partial_width_windows)
2907 || (INTEGERP (Vtruncate_partial_width_windows)
2908 /* PXW: Shall we do something about this? */
2909 && (XINT (Vtruncate_partial_width_windows)
2910 <= WINDOW_TOTAL_COLS (it->w))))
2911 && NILP (BVAR (current_buffer, truncate_lines)))
2912 it->line_wrap = NILP (BVAR (current_buffer, word_wrap))
2913 ? WINDOW_WRAP : WORD_WRAP;
2915 /* Get dimensions of truncation and continuation glyphs. These are
2916 displayed as fringe bitmaps under X, but we need them for such
2917 frames when the fringes are turned off. The no_special_glyphs slot
2918 of the iterator's frame, when set, suppresses their display - by
2919 default for tooltip frames and when set via the 'no-special-glyphs'
2920 frame parameter. */
2921 #ifdef HAVE_WINDOW_SYSTEM
2922 if (!(FRAME_WINDOW_P (it->f) && it->f->no_special_glyphs))
2923 #endif
2925 if (it->line_wrap == TRUNCATE)
2927 /* We will need the truncation glyph. */
2928 eassert (it->glyph_row == NULL);
2929 produce_special_glyphs (it, IT_TRUNCATION);
2930 it->truncation_pixel_width = it->pixel_width;
2932 else
2934 /* We will need the continuation glyph. */
2935 eassert (it->glyph_row == NULL);
2936 produce_special_glyphs (it, IT_CONTINUATION);
2937 it->continuation_pixel_width = it->pixel_width;
2941 /* Reset these values to zero because the produce_special_glyphs
2942 above has changed them. */
2943 it->pixel_width = it->ascent = it->descent = 0;
2944 it->phys_ascent = it->phys_descent = 0;
2946 /* Set this after getting the dimensions of truncation and
2947 continuation glyphs, so that we don't produce glyphs when calling
2948 produce_special_glyphs, above. */
2949 it->glyph_row = row;
2950 it->area = TEXT_AREA;
2952 /* Get the dimensions of the display area. The display area
2953 consists of the visible window area plus a horizontally scrolled
2954 part to the left of the window. All x-values are relative to the
2955 start of this total display area. */
2956 if (base_face_id != DEFAULT_FACE_ID)
2958 /* Mode lines, menu bar in terminal frames. */
2959 it->first_visible_x = 0;
2960 it->last_visible_x = WINDOW_PIXEL_WIDTH (w);
2962 else
2964 /* When hscrolling only the current line, don't apply the
2965 hscroll here, it will be applied by display_line when it gets
2966 to laying out the line showing point. However, if the
2967 window's min_hscroll is positive, the user specified a lower
2968 bound for automatic hscrolling, so they expect the
2969 non-current lines to obey that hscroll amount. */
2970 if (hscrolling_current_line_p (w))
2972 if (w->min_hscroll > 0)
2973 it->first_visible_x = w->min_hscroll * FRAME_COLUMN_WIDTH (it->f);
2974 else
2975 it->first_visible_x = 0;
2977 else
2978 it->first_visible_x =
2979 window_hscroll_limited (w, it->f) * FRAME_COLUMN_WIDTH (it->f);
2980 it->last_visible_x = (it->first_visible_x
2981 + window_box_width (w, TEXT_AREA));
2983 /* If we truncate lines, leave room for the truncation glyph(s) at
2984 the right margin. Otherwise, leave room for the continuation
2985 glyph(s). Done only if the window has no right fringe. */
2986 if (WINDOW_RIGHT_FRINGE_WIDTH (it->w) == 0)
2988 if (it->line_wrap == TRUNCATE)
2989 it->last_visible_x -= it->truncation_pixel_width;
2990 else
2991 it->last_visible_x -= it->continuation_pixel_width;
2994 it->header_line_p = window_wants_header_line (w);
2995 it->current_y = WINDOW_HEADER_LINE_HEIGHT (w) + w->vscroll;
2998 /* Leave room for a border glyph. */
2999 if (!FRAME_WINDOW_P (it->f)
3000 && !WINDOW_RIGHTMOST_P (it->w))
3001 it->last_visible_x -= 1;
3003 it->last_visible_y = window_text_bottom_y (w);
3005 /* For mode lines and alike, arrange for the first glyph having a
3006 left box line if the face specifies a box. */
3007 if (base_face_id != DEFAULT_FACE_ID)
3009 struct face *face;
3011 it->face_id = remapped_base_face_id;
3013 /* If we have a boxed mode line, make the first character appear
3014 with a left box line. */
3015 face = FACE_FROM_ID_OR_NULL (it->f, remapped_base_face_id);
3016 if (face && face->box != FACE_NO_BOX)
3017 it->start_of_box_run_p = true;
3020 /* If a buffer position was specified, set the iterator there,
3021 getting overlays and face properties from that position. */
3022 if (charpos >= BUF_BEG (current_buffer))
3024 it->stop_charpos = charpos;
3025 it->end_charpos = ZV;
3026 eassert (charpos == BYTE_TO_CHAR (bytepos));
3027 IT_CHARPOS (*it) = charpos;
3028 IT_BYTEPOS (*it) = bytepos;
3030 /* We will rely on `reseat' to set this up properly, via
3031 handle_face_prop. */
3032 it->face_id = it->base_face_id;
3034 it->start = it->current;
3035 /* Do we need to reorder bidirectional text? Not if this is a
3036 unibyte buffer: by definition, none of the single-byte
3037 characters are strong R2L, so no reordering is needed. And
3038 bidi.c doesn't support unibyte buffers anyway. Also, don't
3039 reorder while we are loading loadup.el, since the tables of
3040 character properties needed for reordering are not yet
3041 available. */
3042 it->bidi_p =
3043 !redisplay__inhibit_bidi
3044 && !NILP (BVAR (current_buffer, bidi_display_reordering))
3045 && it->multibyte_p;
3047 /* If we are to reorder bidirectional text, init the bidi
3048 iterator. */
3049 if (it->bidi_p)
3051 /* Since we don't know at this point whether there will be
3052 any R2L lines in the window, we reserve space for
3053 truncation/continuation glyphs even if only the left
3054 fringe is absent. */
3055 if (base_face_id == DEFAULT_FACE_ID
3056 && WINDOW_LEFT_FRINGE_WIDTH (it->w) == 0
3057 && WINDOW_RIGHT_FRINGE_WIDTH (it->w) != 0)
3059 if (it->line_wrap == TRUNCATE)
3060 it->last_visible_x -= it->truncation_pixel_width;
3061 else
3062 it->last_visible_x -= it->continuation_pixel_width;
3064 /* Note the paragraph direction that this buffer wants to
3065 use. */
3066 if (EQ (BVAR (current_buffer, bidi_paragraph_direction),
3067 Qleft_to_right))
3068 it->paragraph_embedding = L2R;
3069 else if (EQ (BVAR (current_buffer, bidi_paragraph_direction),
3070 Qright_to_left))
3071 it->paragraph_embedding = R2L;
3072 else
3073 it->paragraph_embedding = NEUTRAL_DIR;
3074 bidi_unshelve_cache (NULL, false);
3075 bidi_init_it (charpos, IT_BYTEPOS (*it), FRAME_WINDOW_P (it->f),
3076 &it->bidi_it);
3079 /* Compute faces etc. */
3080 reseat (it, it->current.pos, true);
3083 CHECK_IT (it);
3087 /* Initialize IT for the display of window W with window start POS. */
3089 void
3090 start_display (struct it *it, struct window *w, struct text_pos pos)
3092 struct glyph_row *row;
3093 bool first_vpos = window_wants_header_line (w);
3095 row = w->desired_matrix->rows + first_vpos;
3096 init_iterator (it, w, CHARPOS (pos), BYTEPOS (pos), row, DEFAULT_FACE_ID);
3097 it->first_vpos = first_vpos;
3099 /* Don't reseat to previous visible line start if current start
3100 position is in a string or image. */
3101 if (it->method == GET_FROM_BUFFER && it->line_wrap != TRUNCATE)
3103 int first_y = it->current_y;
3105 /* If window start is not at a line start, skip forward to POS to
3106 get the correct continuation lines width. */
3107 bool start_at_line_beg_p = (CHARPOS (pos) == BEGV
3108 || FETCH_BYTE (BYTEPOS (pos) - 1) == '\n');
3109 if (!start_at_line_beg_p)
3111 int new_x;
3113 reseat_at_previous_visible_line_start (it);
3114 move_it_to (it, CHARPOS (pos), -1, -1, -1, MOVE_TO_POS);
3116 new_x = it->current_x + it->pixel_width;
3118 /* If lines are continued, this line may end in the middle
3119 of a multi-glyph character (e.g. a control character
3120 displayed as \003, or in the middle of an overlay
3121 string). In this case move_it_to above will not have
3122 taken us to the start of the continuation line but to the
3123 end of the continued line. */
3124 if (it->current_x > 0
3125 && it->line_wrap != TRUNCATE /* Lines are continued. */
3126 && (/* And glyph doesn't fit on the line. */
3127 new_x > it->last_visible_x
3128 /* Or it fits exactly and we're on a window
3129 system frame. */
3130 || (new_x == it->last_visible_x
3131 && FRAME_WINDOW_P (it->f)
3132 && ((it->bidi_p && it->bidi_it.paragraph_dir == R2L)
3133 ? WINDOW_LEFT_FRINGE_WIDTH (it->w)
3134 : WINDOW_RIGHT_FRINGE_WIDTH (it->w)))))
3136 if ((it->current.dpvec_index >= 0
3137 || it->current.overlay_string_index >= 0)
3138 /* If we are on a newline from a display vector or
3139 overlay string, then we are already at the end of
3140 a screen line; no need to go to the next line in
3141 that case, as this line is not really continued.
3142 (If we do go to the next line, C-e will not DTRT.) */
3143 && it->c != '\n')
3145 set_iterator_to_next (it, true);
3146 move_it_in_display_line_to (it, -1, -1, 0);
3149 it->continuation_lines_width += it->current_x;
3151 /* If the character at POS is displayed via a display
3152 vector, move_it_to above stops at the final glyph of
3153 IT->dpvec. To make the caller redisplay that character
3154 again (a.k.a. start at POS), we need to reset the
3155 dpvec_index to the beginning of IT->dpvec. */
3156 else if (it->current.dpvec_index >= 0)
3157 it->current.dpvec_index = 0;
3159 /* We're starting a new display line, not affected by the
3160 height of the continued line, so clear the appropriate
3161 fields in the iterator structure. */
3162 it->max_ascent = it->max_descent = 0;
3163 it->max_phys_ascent = it->max_phys_descent = 0;
3165 it->current_y = first_y;
3166 it->vpos = 0;
3167 it->current_x = it->hpos = 0;
3173 /* Return true if POS is a position in ellipses displayed for invisible
3174 text. W is the window we display, for text property lookup. */
3176 static bool
3177 in_ellipses_for_invisible_text_p (struct display_pos *pos, struct window *w)
3179 Lisp_Object prop, window;
3180 bool ellipses_p = false;
3181 ptrdiff_t charpos = CHARPOS (pos->pos);
3183 /* If POS specifies a position in a display vector, this might
3184 be for an ellipsis displayed for invisible text. We won't
3185 get the iterator set up for delivering that ellipsis unless
3186 we make sure that it gets aware of the invisible text. */
3187 if (pos->dpvec_index >= 0
3188 && pos->overlay_string_index < 0
3189 && CHARPOS (pos->string_pos) < 0
3190 && charpos > BEGV
3191 && (XSETWINDOW (window, w),
3192 prop = Fget_char_property (make_number (charpos),
3193 Qinvisible, window),
3194 TEXT_PROP_MEANS_INVISIBLE (prop) == 0))
3196 prop = Fget_char_property (make_number (charpos - 1), Qinvisible,
3197 window);
3198 ellipses_p = 2 == TEXT_PROP_MEANS_INVISIBLE (prop);
3201 return ellipses_p;
3205 /* Initialize IT for stepping through current_buffer in window W,
3206 starting at position POS that includes overlay string and display
3207 vector/ control character translation position information. Value
3208 is false if there are overlay strings with newlines at POS. */
3210 static bool
3211 init_from_display_pos (struct it *it, struct window *w, struct display_pos *pos)
3213 ptrdiff_t charpos = CHARPOS (pos->pos), bytepos = BYTEPOS (pos->pos);
3214 int i;
3215 bool overlay_strings_with_newlines = false;
3217 /* If POS specifies a position in a display vector, this might
3218 be for an ellipsis displayed for invisible text. We won't
3219 get the iterator set up for delivering that ellipsis unless
3220 we make sure that it gets aware of the invisible text. */
3221 if (in_ellipses_for_invisible_text_p (pos, w))
3223 --charpos;
3224 bytepos = 0;
3227 /* Keep in mind: the call to reseat in init_iterator skips invisible
3228 text, so we might end up at a position different from POS. This
3229 is only a problem when POS is a row start after a newline and an
3230 overlay starts there with an after-string, and the overlay has an
3231 invisible property. Since we don't skip invisible text in
3232 display_line and elsewhere immediately after consuming the
3233 newline before the row start, such a POS will not be in a string,
3234 but the call to init_iterator below will move us to the
3235 after-string. */
3236 init_iterator (it, w, charpos, bytepos, NULL, DEFAULT_FACE_ID);
3238 /* This only scans the current chunk -- it should scan all chunks.
3239 However, OVERLAY_STRING_CHUNK_SIZE has been increased from 3 in 21.1
3240 to 16 in 22.1 to make this a lesser problem. */
3241 for (i = 0; i < it->n_overlay_strings && i < OVERLAY_STRING_CHUNK_SIZE; ++i)
3243 const char *s = SSDATA (it->overlay_strings[i]);
3244 const char *e = s + SBYTES (it->overlay_strings[i]);
3246 while (s < e && *s != '\n')
3247 ++s;
3249 if (s < e)
3251 overlay_strings_with_newlines = true;
3252 break;
3256 /* If position is within an overlay string, set up IT to the right
3257 overlay string. */
3258 if (pos->overlay_string_index >= 0)
3260 int relative_index;
3262 /* If the first overlay string happens to have a `display'
3263 property for an image, the iterator will be set up for that
3264 image, and we have to undo that setup first before we can
3265 correct the overlay string index. */
3266 if (it->method == GET_FROM_IMAGE)
3267 pop_it (it);
3269 /* We already have the first chunk of overlay strings in
3270 IT->overlay_strings. Load more until the one for
3271 pos->overlay_string_index is in IT->overlay_strings. */
3272 if (pos->overlay_string_index >= OVERLAY_STRING_CHUNK_SIZE)
3274 ptrdiff_t n = pos->overlay_string_index / OVERLAY_STRING_CHUNK_SIZE;
3275 it->current.overlay_string_index = 0;
3276 while (n--)
3278 load_overlay_strings (it, 0);
3279 it->current.overlay_string_index += OVERLAY_STRING_CHUNK_SIZE;
3283 it->current.overlay_string_index = pos->overlay_string_index;
3284 relative_index = (it->current.overlay_string_index
3285 % OVERLAY_STRING_CHUNK_SIZE);
3286 it->string = it->overlay_strings[relative_index];
3287 eassert (STRINGP (it->string));
3288 it->current.string_pos = pos->string_pos;
3289 it->method = GET_FROM_STRING;
3290 it->end_charpos = SCHARS (it->string);
3291 /* Set up the bidi iterator for this overlay string. */
3292 if (it->bidi_p)
3294 it->bidi_it.string.lstring = it->string;
3295 it->bidi_it.string.s = NULL;
3296 it->bidi_it.string.schars = SCHARS (it->string);
3297 it->bidi_it.string.bufpos = it->overlay_strings_charpos;
3298 it->bidi_it.string.from_disp_str = it->string_from_display_prop_p;
3299 it->bidi_it.string.unibyte = !it->multibyte_p;
3300 it->bidi_it.w = it->w;
3301 bidi_init_it (IT_STRING_CHARPOS (*it), IT_STRING_BYTEPOS (*it),
3302 FRAME_WINDOW_P (it->f), &it->bidi_it);
3304 /* Synchronize the state of the bidi iterator with
3305 pos->string_pos. For any string position other than
3306 zero, this will be done automagically when we resume
3307 iteration over the string and get_visually_first_element
3308 is called. But if string_pos is zero, and the string is
3309 to be reordered for display, we need to resync manually,
3310 since it could be that the iteration state recorded in
3311 pos ended at string_pos of 0 moving backwards in string. */
3312 if (CHARPOS (pos->string_pos) == 0)
3314 get_visually_first_element (it);
3315 if (IT_STRING_CHARPOS (*it) != 0)
3316 do {
3317 /* Paranoia. */
3318 eassert (it->bidi_it.charpos < it->bidi_it.string.schars);
3319 bidi_move_to_visually_next (&it->bidi_it);
3320 } while (it->bidi_it.charpos != 0);
3322 eassert (IT_STRING_CHARPOS (*it) == it->bidi_it.charpos
3323 && IT_STRING_BYTEPOS (*it) == it->bidi_it.bytepos);
3327 if (CHARPOS (pos->string_pos) >= 0)
3329 /* Recorded position is not in an overlay string, but in another
3330 string. This can only be a string from a `display' property.
3331 IT should already be filled with that string. */
3332 it->current.string_pos = pos->string_pos;
3333 eassert (STRINGP (it->string));
3334 if (it->bidi_p)
3335 bidi_init_it (IT_STRING_CHARPOS (*it), IT_STRING_BYTEPOS (*it),
3336 FRAME_WINDOW_P (it->f), &it->bidi_it);
3339 /* Restore position in display vector translations, control
3340 character translations or ellipses. */
3341 if (pos->dpvec_index >= 0)
3343 if (it->dpvec == NULL)
3344 get_next_display_element (it);
3345 eassert (it->dpvec && it->current.dpvec_index == 0);
3346 it->current.dpvec_index = pos->dpvec_index;
3349 CHECK_IT (it);
3350 return !overlay_strings_with_newlines;
3354 /* Initialize IT for stepping through current_buffer in window W
3355 starting at ROW->start. */
3357 static void
3358 init_to_row_start (struct it *it, struct window *w, struct glyph_row *row)
3360 init_from_display_pos (it, w, &row->start);
3361 it->start = row->start;
3362 it->continuation_lines_width = row->continuation_lines_width;
3363 CHECK_IT (it);
3367 /* Initialize IT for stepping through current_buffer in window W
3368 starting in the line following ROW, i.e. starting at ROW->end.
3369 Value is false if there are overlay strings with newlines at ROW's
3370 end position. */
3372 static bool
3373 init_to_row_end (struct it *it, struct window *w, struct glyph_row *row)
3375 bool success = false;
3377 if (init_from_display_pos (it, w, &row->end))
3379 if (row->continued_p)
3380 it->continuation_lines_width
3381 = row->continuation_lines_width + row->pixel_width;
3382 CHECK_IT (it);
3383 success = true;
3386 return success;
3392 /***********************************************************************
3393 Text properties
3394 ***********************************************************************/
3396 /* Called when IT reaches IT->stop_charpos. Handle text property and
3397 overlay changes. Set IT->stop_charpos to the next position where
3398 to stop. */
3400 static void
3401 handle_stop (struct it *it)
3403 enum prop_handled handled;
3404 bool handle_overlay_change_p;
3405 struct props *p;
3407 it->dpvec = NULL;
3408 it->current.dpvec_index = -1;
3409 handle_overlay_change_p = !it->ignore_overlay_strings_at_pos_p;
3410 it->ellipsis_p = false;
3412 /* Use face of preceding text for ellipsis (if invisible) */
3413 if (it->selective_display_ellipsis_p)
3414 it->saved_face_id = it->face_id;
3416 /* Here's the description of the semantics of, and the logic behind,
3417 the various HANDLED_* statuses:
3419 HANDLED_NORMALLY means the handler did its job, and the loop
3420 should proceed to calling the next handler in order.
3422 HANDLED_RECOMPUTE_PROPS means the handler caused a significant
3423 change in the properties and overlays at current position, so the
3424 loop should be restarted, to re-invoke the handlers that were
3425 already called. This happens when fontification-functions were
3426 called by handle_fontified_prop, and actually fontified
3427 something. Another case where HANDLED_RECOMPUTE_PROPS is
3428 returned is when we discover overlay strings that need to be
3429 displayed right away. The loop below will continue for as long
3430 as the status is HANDLED_RECOMPUTE_PROPS.
3432 HANDLED_RETURN means return immediately to the caller, to
3433 continue iteration without calling any further handlers. This is
3434 used when we need to act on some property right away, for example
3435 when we need to display the ellipsis or a replacing display
3436 property, such as display string or image.
3438 HANDLED_OVERLAY_STRING_CONSUMED means an overlay string was just
3439 consumed, and the handler switched to the next overlay string.
3440 This signals the loop below to refrain from looking for more
3441 overlays before all the overlay strings of the current overlay
3442 are processed.
3444 Some of the handlers called by the loop push the iterator state
3445 onto the stack (see 'push_it'), and arrange for the iteration to
3446 continue with another object, such as an image, a display string,
3447 or an overlay string. In most such cases, it->stop_charpos is
3448 set to the first character of the string, so that when the
3449 iteration resumes, this function will immediately be called
3450 again, to examine the properties at the beginning of the string.
3452 When a display or overlay string is exhausted, the iterator state
3453 is popped (see 'pop_it'), and iteration continues with the
3454 previous object. Again, in many such cases this function is
3455 called again to find the next position where properties might
3456 change. */
3460 handled = HANDLED_NORMALLY;
3462 /* Call text property handlers. */
3463 for (p = it_props; p->handler; ++p)
3465 handled = p->handler (it);
3467 if (handled == HANDLED_RECOMPUTE_PROPS)
3468 break;
3469 else if (handled == HANDLED_RETURN)
3471 /* We still want to show before and after strings from
3472 overlays even if the actual buffer text is replaced. */
3473 if (!handle_overlay_change_p
3474 || it->sp > 1
3475 /* Don't call get_overlay_strings_1 if we already
3476 have overlay strings loaded, because doing so
3477 will load them again and push the iterator state
3478 onto the stack one more time, which is not
3479 expected by the rest of the code that processes
3480 overlay strings. */
3481 || (it->current.overlay_string_index < 0
3482 && !get_overlay_strings_1 (it, 0, false)))
3484 if (it->ellipsis_p)
3485 setup_for_ellipsis (it, 0);
3486 /* When handling a display spec, we might load an
3487 empty string. In that case, discard it here. We
3488 used to discard it in handle_single_display_spec,
3489 but that causes get_overlay_strings_1, above, to
3490 ignore overlay strings that we must check. */
3491 if (STRINGP (it->string) && !SCHARS (it->string))
3492 pop_it (it);
3493 return;
3495 else if (STRINGP (it->string) && !SCHARS (it->string))
3496 pop_it (it);
3497 else
3499 it->string_from_display_prop_p = false;
3500 it->from_disp_prop_p = false;
3501 handle_overlay_change_p = false;
3503 handled = HANDLED_RECOMPUTE_PROPS;
3504 break;
3506 else if (handled == HANDLED_OVERLAY_STRING_CONSUMED)
3507 handle_overlay_change_p = false;
3510 if (handled != HANDLED_RECOMPUTE_PROPS)
3512 /* Don't check for overlay strings below when set to deliver
3513 characters from a display vector. */
3514 if (it->method == GET_FROM_DISPLAY_VECTOR)
3515 handle_overlay_change_p = false;
3517 /* Handle overlay changes.
3518 This sets HANDLED to HANDLED_RECOMPUTE_PROPS
3519 if it finds overlays. */
3520 if (handle_overlay_change_p)
3521 handled = handle_overlay_change (it);
3524 if (it->ellipsis_p)
3526 setup_for_ellipsis (it, 0);
3527 break;
3530 while (handled == HANDLED_RECOMPUTE_PROPS);
3532 /* Determine where to stop next. */
3533 if (handled == HANDLED_NORMALLY)
3534 compute_stop_pos (it);
3538 /* Compute IT->stop_charpos from text property and overlay change
3539 information for IT's current position. */
3541 static void
3542 compute_stop_pos (struct it *it)
3544 register INTERVAL iv, next_iv;
3545 Lisp_Object object, limit, position;
3546 ptrdiff_t charpos, bytepos;
3548 if (STRINGP (it->string))
3550 /* Strings are usually short, so don't limit the search for
3551 properties. */
3552 it->stop_charpos = it->end_charpos;
3553 object = it->string;
3554 limit = Qnil;
3555 charpos = IT_STRING_CHARPOS (*it);
3556 bytepos = IT_STRING_BYTEPOS (*it);
3558 else
3560 ptrdiff_t pos;
3562 /* If end_charpos is out of range for some reason, such as a
3563 misbehaving display function, rationalize it (Bug#5984). */
3564 if (it->end_charpos > ZV)
3565 it->end_charpos = ZV;
3566 it->stop_charpos = it->end_charpos;
3568 /* If next overlay change is in front of the current stop pos
3569 (which is IT->end_charpos), stop there. Note: value of
3570 next_overlay_change is point-max if no overlay change
3571 follows. */
3572 charpos = IT_CHARPOS (*it);
3573 bytepos = IT_BYTEPOS (*it);
3574 pos = next_overlay_change (charpos);
3575 if (pos < it->stop_charpos)
3576 it->stop_charpos = pos;
3578 /* Set up variables for computing the stop position from text
3579 property changes. */
3580 XSETBUFFER (object, current_buffer);
3581 limit = make_number (IT_CHARPOS (*it) + TEXT_PROP_DISTANCE_LIMIT);
3584 /* Get the interval containing IT's position. Value is a null
3585 interval if there isn't such an interval. */
3586 position = make_number (charpos);
3587 iv = validate_interval_range (object, &position, &position, false);
3588 if (iv)
3590 Lisp_Object values_here[LAST_PROP_IDX];
3591 struct props *p;
3593 /* Get properties here. */
3594 for (p = it_props; p->handler; ++p)
3595 values_here[p->idx] = textget (iv->plist,
3596 builtin_lisp_symbol (p->name));
3598 /* Look for an interval following iv that has different
3599 properties. */
3600 for (next_iv = next_interval (iv);
3601 (next_iv
3602 && (NILP (limit)
3603 || XFASTINT (limit) > next_iv->position));
3604 next_iv = next_interval (next_iv))
3606 for (p = it_props; p->handler; ++p)
3608 Lisp_Object new_value = textget (next_iv->plist,
3609 builtin_lisp_symbol (p->name));
3610 if (!EQ (values_here[p->idx], new_value))
3611 break;
3614 if (p->handler)
3615 break;
3618 if (next_iv)
3620 if (INTEGERP (limit)
3621 && next_iv->position >= XFASTINT (limit))
3622 /* No text property change up to limit. */
3623 it->stop_charpos = min (XFASTINT (limit), it->stop_charpos);
3624 else
3625 /* Text properties change in next_iv. */
3626 it->stop_charpos = min (it->stop_charpos, next_iv->position);
3630 if (it->cmp_it.id < 0)
3632 ptrdiff_t stoppos = it->end_charpos;
3634 if (it->bidi_p && it->bidi_it.scan_dir < 0)
3635 stoppos = -1;
3636 composition_compute_stop_pos (&it->cmp_it, charpos, bytepos,
3637 stoppos, it->string);
3640 eassert (STRINGP (it->string)
3641 || (it->stop_charpos >= BEGV
3642 && it->stop_charpos >= IT_CHARPOS (*it)));
3646 /* Return the position of the next overlay change after POS in
3647 current_buffer. Value is point-max if no overlay change
3648 follows. This is like `next-overlay-change' but doesn't use
3649 xmalloc. */
3651 static ptrdiff_t
3652 next_overlay_change (ptrdiff_t pos)
3654 ptrdiff_t i, noverlays;
3655 ptrdiff_t endpos;
3656 Lisp_Object *overlays;
3657 USE_SAFE_ALLOCA;
3659 /* Get all overlays at the given position. */
3660 GET_OVERLAYS_AT (pos, overlays, noverlays, &endpos, true);
3662 /* If any of these overlays ends before endpos,
3663 use its ending point instead. */
3664 for (i = 0; i < noverlays; ++i)
3666 Lisp_Object oend;
3667 ptrdiff_t oendpos;
3669 oend = OVERLAY_END (overlays[i]);
3670 oendpos = OVERLAY_POSITION (oend);
3671 endpos = min (endpos, oendpos);
3674 SAFE_FREE ();
3675 return endpos;
3678 /* How many characters forward to search for a display property or
3679 display string. Searching too far forward makes the bidi display
3680 sluggish, especially in small windows. */
3681 #define MAX_DISP_SCAN 250
3683 /* Return the character position of a display string at or after
3684 position specified by POSITION. If no display string exists at or
3685 after POSITION, return ZV. A display string is either an overlay
3686 with `display' property whose value is a string, or a `display'
3687 text property whose value is a string. STRING is data about the
3688 string to iterate; if STRING->lstring is nil, we are iterating a
3689 buffer. FRAME_WINDOW_P is true when we are displaying a window
3690 on a GUI frame. DISP_PROP is set to zero if we searched
3691 MAX_DISP_SCAN characters forward without finding any display
3692 strings, non-zero otherwise. It is set to 2 if the display string
3693 uses any kind of `(space ...)' spec that will produce a stretch of
3694 white space in the text area. */
3695 ptrdiff_t
3696 compute_display_string_pos (struct text_pos *position,
3697 struct bidi_string_data *string,
3698 struct window *w,
3699 bool frame_window_p, int *disp_prop)
3701 /* OBJECT = nil means current buffer. */
3702 Lisp_Object object, object1;
3703 Lisp_Object pos, spec, limpos;
3704 bool string_p = string && (STRINGP (string->lstring) || string->s);
3705 ptrdiff_t eob = string_p ? string->schars : ZV;
3706 ptrdiff_t begb = string_p ? 0 : BEGV;
3707 ptrdiff_t bufpos, charpos = CHARPOS (*position);
3708 ptrdiff_t lim =
3709 (charpos < eob - MAX_DISP_SCAN) ? charpos + MAX_DISP_SCAN : eob;
3710 struct text_pos tpos;
3711 int rv = 0;
3713 if (string && STRINGP (string->lstring))
3714 object1 = object = string->lstring;
3715 else if (w && !string_p)
3717 XSETWINDOW (object, w);
3718 object1 = Qnil;
3720 else
3721 object1 = object = Qnil;
3723 *disp_prop = 1;
3725 if (charpos >= eob
3726 /* We don't support display properties whose values are strings
3727 that have display string properties. */
3728 || string->from_disp_str
3729 /* C strings cannot have display properties. */
3730 || (string->s && !STRINGP (object)))
3732 *disp_prop = 0;
3733 return eob;
3736 /* If the character at CHARPOS is where the display string begins,
3737 return CHARPOS. */
3738 pos = make_number (charpos);
3739 if (STRINGP (object))
3740 bufpos = string->bufpos;
3741 else
3742 bufpos = charpos;
3743 tpos = *position;
3744 if (!NILP (spec = Fget_char_property (pos, Qdisplay, object))
3745 && (charpos <= begb
3746 || !EQ (Fget_char_property (make_number (charpos - 1), Qdisplay,
3747 object),
3748 spec))
3749 && (rv = handle_display_spec (NULL, spec, object, Qnil, &tpos, bufpos,
3750 frame_window_p)))
3752 if (rv == 2)
3753 *disp_prop = 2;
3754 return charpos;
3757 /* Look forward for the first character with a `display' property
3758 that will replace the underlying text when displayed. */
3759 limpos = make_number (lim);
3760 do {
3761 pos = Fnext_single_char_property_change (pos, Qdisplay, object1, limpos);
3762 CHARPOS (tpos) = XFASTINT (pos);
3763 if (CHARPOS (tpos) >= lim)
3765 *disp_prop = 0;
3766 break;
3768 if (STRINGP (object))
3769 BYTEPOS (tpos) = string_char_to_byte (object, CHARPOS (tpos));
3770 else
3771 BYTEPOS (tpos) = CHAR_TO_BYTE (CHARPOS (tpos));
3772 spec = Fget_char_property (pos, Qdisplay, object);
3773 if (!STRINGP (object))
3774 bufpos = CHARPOS (tpos);
3775 } while (NILP (spec)
3776 || !(rv = handle_display_spec (NULL, spec, object, Qnil, &tpos,
3777 bufpos, frame_window_p)));
3778 if (rv == 2)
3779 *disp_prop = 2;
3781 return CHARPOS (tpos);
3784 /* Return the character position of the end of the display string that
3785 started at CHARPOS. If there's no display string at CHARPOS,
3786 return -1. A display string is either an overlay with `display'
3787 property whose value is a string or a `display' text property whose
3788 value is a string. */
3789 ptrdiff_t
3790 compute_display_string_end (ptrdiff_t charpos, struct bidi_string_data *string)
3792 /* OBJECT = nil means current buffer. */
3793 Lisp_Object object =
3794 (string && STRINGP (string->lstring)) ? string->lstring : Qnil;
3795 Lisp_Object pos = make_number (charpos);
3796 ptrdiff_t eob =
3797 (STRINGP (object) || (string && string->s)) ? string->schars : ZV;
3799 if (charpos >= eob || (string->s && !STRINGP (object)))
3800 return eob;
3802 /* It could happen that the display property or overlay was removed
3803 since we found it in compute_display_string_pos above. One way
3804 this can happen is if JIT font-lock was called (through
3805 handle_fontified_prop), and jit-lock-functions remove text
3806 properties or overlays from the portion of buffer that includes
3807 CHARPOS. Muse mode is known to do that, for example. In this
3808 case, we return -1 to the caller, to signal that no display
3809 string is actually present at CHARPOS. See bidi_fetch_char for
3810 how this is handled.
3812 An alternative would be to never look for display properties past
3813 it->stop_charpos. But neither compute_display_string_pos nor
3814 bidi_fetch_char that calls it know or care where the next
3815 stop_charpos is. */
3816 if (NILP (Fget_char_property (pos, Qdisplay, object)))
3817 return -1;
3819 /* Look forward for the first character where the `display' property
3820 changes. */
3821 pos = Fnext_single_char_property_change (pos, Qdisplay, object, Qnil);
3823 return XFASTINT (pos);
3828 /***********************************************************************
3829 Fontification
3830 ***********************************************************************/
3832 /* Handle changes in the `fontified' property of the current buffer by
3833 calling hook functions from Qfontification_functions to fontify
3834 regions of text. */
3836 static enum prop_handled
3837 handle_fontified_prop (struct it *it)
3839 Lisp_Object prop, pos;
3840 enum prop_handled handled = HANDLED_NORMALLY;
3842 if (!NILP (Vmemory_full))
3843 return handled;
3845 /* Get the value of the `fontified' property at IT's current buffer
3846 position. (The `fontified' property doesn't have a special
3847 meaning in strings.) If the value is nil, call functions from
3848 Qfontification_functions. */
3849 if (!STRINGP (it->string)
3850 && it->s == NULL
3851 && !NILP (Vfontification_functions)
3852 && !NILP (Vrun_hooks)
3853 && (pos = make_number (IT_CHARPOS (*it)),
3854 prop = Fget_char_property (pos, Qfontified, Qnil),
3855 /* Ignore the special cased nil value always present at EOB since
3856 no amount of fontifying will be able to change it. */
3857 NILP (prop) && IT_CHARPOS (*it) < Z))
3859 ptrdiff_t count = SPECPDL_INDEX ();
3860 Lisp_Object val;
3861 struct buffer *obuf = current_buffer;
3862 ptrdiff_t begv = BEGV, zv = ZV;
3863 bool old_clip_changed = current_buffer->clip_changed;
3865 val = Vfontification_functions;
3866 specbind (Qfontification_functions, Qnil);
3868 eassert (it->end_charpos == ZV);
3870 if (!CONSP (val) || EQ (XCAR (val), Qlambda))
3871 safe_call1 (val, pos);
3872 else
3874 Lisp_Object fns, fn;
3876 fns = Qnil;
3878 for (; CONSP (val); val = XCDR (val))
3880 fn = XCAR (val);
3882 if (EQ (fn, Qt))
3884 /* A value of t indicates this hook has a local
3885 binding; it means to run the global binding too.
3886 In a global value, t should not occur. If it
3887 does, we must ignore it to avoid an endless
3888 loop. */
3889 for (fns = Fdefault_value (Qfontification_functions);
3890 CONSP (fns);
3891 fns = XCDR (fns))
3893 fn = XCAR (fns);
3894 if (!EQ (fn, Qt))
3895 safe_call1 (fn, pos);
3898 else
3899 safe_call1 (fn, pos);
3903 unbind_to (count, Qnil);
3905 /* Fontification functions routinely call `save-restriction'.
3906 Normally, this tags clip_changed, which can confuse redisplay
3907 (see discussion in Bug#6671). Since we don't perform any
3908 special handling of fontification changes in the case where
3909 `save-restriction' isn't called, there's no point doing so in
3910 this case either. So, if the buffer's restrictions are
3911 actually left unchanged, reset clip_changed. */
3912 if (obuf == current_buffer)
3914 if (begv == BEGV && zv == ZV)
3915 current_buffer->clip_changed = old_clip_changed;
3917 /* There isn't much we can reasonably do to protect against
3918 misbehaving fontification, but here's a fig leaf. */
3919 else if (BUFFER_LIVE_P (obuf))
3920 set_buffer_internal_1 (obuf);
3922 /* The fontification code may have added/removed text.
3923 It could do even a lot worse, but let's at least protect against
3924 the most obvious case where only the text past `pos' gets changed',
3925 as is/was done in grep.el where some escapes sequences are turned
3926 into face properties (bug#7876). */
3927 it->end_charpos = ZV;
3929 /* Return HANDLED_RECOMPUTE_PROPS only if function fontified
3930 something. This avoids an endless loop if they failed to
3931 fontify the text for which reason ever. */
3932 if (!NILP (Fget_char_property (pos, Qfontified, Qnil)))
3933 handled = HANDLED_RECOMPUTE_PROPS;
3936 return handled;
3941 /***********************************************************************
3942 Faces
3943 ***********************************************************************/
3945 /* Set up iterator IT from face properties at its current position.
3946 Called from handle_stop. */
3948 static enum prop_handled
3949 handle_face_prop (struct it *it)
3951 int new_face_id;
3952 ptrdiff_t next_stop;
3954 if (!STRINGP (it->string))
3956 new_face_id
3957 = face_at_buffer_position (it->w,
3958 IT_CHARPOS (*it),
3959 &next_stop,
3960 (IT_CHARPOS (*it)
3961 + TEXT_PROP_DISTANCE_LIMIT),
3962 false, it->base_face_id);
3964 /* Is this a start of a run of characters with box face?
3965 Caveat: this can be called for a freshly initialized
3966 iterator; face_id is -1 in this case. We know that the new
3967 face will not change until limit, i.e. if the new face has a
3968 box, all characters up to limit will have one. But, as
3969 usual, we don't know whether limit is really the end. */
3970 if (new_face_id != it->face_id)
3972 struct face *new_face = FACE_FROM_ID (it->f, new_face_id);
3973 /* If it->face_id is -1, old_face below will be NULL, see
3974 the definition of FACE_FROM_ID_OR_NULL. This will happen
3975 if this is the initial call that gets the face. */
3976 struct face *old_face = FACE_FROM_ID_OR_NULL (it->f, it->face_id);
3978 /* If the value of face_id of the iterator is -1, we have to
3979 look in front of IT's position and see whether there is a
3980 face there that's different from new_face_id. */
3981 if (!old_face && IT_CHARPOS (*it) > BEG)
3983 int prev_face_id = face_before_it_pos (it);
3985 old_face = FACE_FROM_ID_OR_NULL (it->f, prev_face_id);
3988 /* If the new face has a box, but the old face does not,
3989 this is the start of a run of characters with box face,
3990 i.e. this character has a shadow on the left side. */
3991 it->start_of_box_run_p = (new_face->box != FACE_NO_BOX
3992 && (old_face == NULL || !old_face->box));
3993 it->face_box_p = new_face->box != FACE_NO_BOX;
3996 else
3998 int base_face_id;
3999 ptrdiff_t bufpos;
4000 int i;
4001 Lisp_Object from_overlay
4002 = (it->current.overlay_string_index >= 0
4003 ? it->string_overlays[it->current.overlay_string_index
4004 % OVERLAY_STRING_CHUNK_SIZE]
4005 : Qnil);
4007 /* See if we got to this string directly or indirectly from
4008 an overlay property. That includes the before-string or
4009 after-string of an overlay, strings in display properties
4010 provided by an overlay, their text properties, etc.
4012 FROM_OVERLAY is the overlay that brought us here, or nil if none. */
4013 if (! NILP (from_overlay))
4014 for (i = it->sp - 1; i >= 0; i--)
4016 if (it->stack[i].current.overlay_string_index >= 0)
4017 from_overlay
4018 = it->string_overlays[it->stack[i].current.overlay_string_index
4019 % OVERLAY_STRING_CHUNK_SIZE];
4020 else if (! NILP (it->stack[i].from_overlay))
4021 from_overlay = it->stack[i].from_overlay;
4023 if (!NILP (from_overlay))
4024 break;
4027 if (! NILP (from_overlay))
4029 bufpos = IT_CHARPOS (*it);
4030 /* For a string from an overlay, the base face depends
4031 only on text properties and ignores overlays. */
4032 base_face_id
4033 = face_for_overlay_string (it->w,
4034 IT_CHARPOS (*it),
4035 &next_stop,
4036 (IT_CHARPOS (*it)
4037 + TEXT_PROP_DISTANCE_LIMIT),
4038 false,
4039 from_overlay);
4041 else
4043 bufpos = 0;
4045 /* For strings from a `display' property, use the face at
4046 IT's current buffer position as the base face to merge
4047 with, so that overlay strings appear in the same face as
4048 surrounding text, unless they specify their own faces.
4049 For strings from wrap-prefix and line-prefix properties,
4050 use the default face, possibly remapped via
4051 Vface_remapping_alist. */
4052 /* Note that the fact that we use the face at _buffer_
4053 position means that a 'display' property on an overlay
4054 string will not inherit the face of that overlay string,
4055 but will instead revert to the face of buffer text
4056 covered by the overlay. This is visible, e.g., when the
4057 overlay specifies a box face, but neither the buffer nor
4058 the display string do. This sounds like a design bug,
4059 but Emacs always did that since v21.1, so changing that
4060 might be a big deal. */
4061 base_face_id = it->string_from_prefix_prop_p
4062 ? (!NILP (Vface_remapping_alist)
4063 ? lookup_basic_face (it->w, it->f, DEFAULT_FACE_ID)
4064 : DEFAULT_FACE_ID)
4065 : underlying_face_id (it);
4068 new_face_id = face_at_string_position (it->w,
4069 it->string,
4070 IT_STRING_CHARPOS (*it),
4071 bufpos,
4072 &next_stop,
4073 base_face_id, false);
4075 /* Is this a start of a run of characters with box? Caveat:
4076 this can be called for a freshly allocated iterator; face_id
4077 is -1 is this case. We know that the new face will not
4078 change until the next check pos, i.e. if the new face has a
4079 box, all characters up to that position will have a
4080 box. But, as usual, we don't know whether that position
4081 is really the end. */
4082 if (new_face_id != it->face_id)
4084 struct face *new_face = FACE_FROM_ID (it->f, new_face_id);
4085 struct face *old_face = FACE_FROM_ID_OR_NULL (it->f, it->face_id);
4087 /* If new face has a box but old face hasn't, this is the
4088 start of a run of characters with box, i.e. it has a
4089 shadow on the left side. */
4090 it->start_of_box_run_p
4091 = new_face->box && (old_face == NULL || !old_face->box);
4092 it->face_box_p = new_face->box != FACE_NO_BOX;
4096 it->face_id = new_face_id;
4097 return HANDLED_NORMALLY;
4101 /* Return the ID of the face ``underlying'' IT's current position,
4102 which is in a string. If the iterator is associated with a
4103 buffer, return the face at IT's current buffer position.
4104 Otherwise, use the iterator's base_face_id. */
4106 static int
4107 underlying_face_id (struct it *it)
4109 int face_id = it->base_face_id, i;
4111 eassert (STRINGP (it->string));
4113 for (i = it->sp - 1; i >= 0; --i)
4114 if (NILP (it->stack[i].string))
4115 face_id = it->stack[i].face_id;
4117 return face_id;
4121 /* Compute the face one character before or after the current position
4122 of IT, in the visual order. BEFORE_P means get the face
4123 in front (to the left in L2R paragraphs, to the right in R2L
4124 paragraphs) of IT's screen position. Value is the ID of the face. */
4126 static int
4127 face_before_or_after_it_pos (struct it *it, bool before_p)
4129 int face_id, limit;
4130 ptrdiff_t next_check_charpos;
4131 struct it it_copy;
4132 void *it_copy_data = NULL;
4134 eassert (it->s == NULL);
4136 if (STRINGP (it->string))
4138 ptrdiff_t bufpos, charpos;
4139 int base_face_id;
4141 /* No face change past the end of the string (for the case
4142 we are padding with spaces). No face change before the
4143 string start. */
4144 if (IT_STRING_CHARPOS (*it) >= SCHARS (it->string)
4145 || (IT_STRING_CHARPOS (*it) == 0 && before_p))
4146 return it->face_id;
4148 if (!it->bidi_p)
4150 /* Set charpos to the position before or after IT's current
4151 position, in the logical order, which in the non-bidi
4152 case is the same as the visual order. */
4153 if (before_p)
4154 charpos = IT_STRING_CHARPOS (*it) - 1;
4155 else if (it->what == IT_COMPOSITION)
4156 /* For composition, we must check the character after the
4157 composition. */
4158 charpos = IT_STRING_CHARPOS (*it) + it->cmp_it.nchars;
4159 else
4160 charpos = IT_STRING_CHARPOS (*it) + 1;
4162 else
4164 if (before_p)
4166 /* With bidi iteration, the character before the current
4167 in the visual order cannot be found by simple
4168 iteration, because "reverse" reordering is not
4169 supported. Instead, we need to start from the string
4170 beginning and go all the way to the current string
4171 position, remembering the previous position. */
4172 /* Ignore face changes before the first visible
4173 character on this display line. */
4174 if (it->current_x <= it->first_visible_x)
4175 return it->face_id;
4176 SAVE_IT (it_copy, *it, it_copy_data);
4177 IT_STRING_CHARPOS (it_copy) = 0;
4178 bidi_init_it (0, 0, FRAME_WINDOW_P (it_copy.f), &it_copy.bidi_it);
4182 charpos = IT_STRING_CHARPOS (it_copy);
4183 if (charpos >= SCHARS (it->string))
4184 break;
4185 bidi_move_to_visually_next (&it_copy.bidi_it);
4187 while (IT_STRING_CHARPOS (it_copy) != IT_STRING_CHARPOS (*it));
4189 RESTORE_IT (it, it, it_copy_data);
4191 else
4193 /* Set charpos to the string position of the character
4194 that comes after IT's current position in the visual
4195 order. */
4196 int n = (it->what == IT_COMPOSITION ? it->cmp_it.nchars : 1);
4198 it_copy = *it;
4199 while (n--)
4200 bidi_move_to_visually_next (&it_copy.bidi_it);
4202 charpos = it_copy.bidi_it.charpos;
4205 eassert (0 <= charpos && charpos <= SCHARS (it->string));
4207 if (it->current.overlay_string_index >= 0)
4208 bufpos = IT_CHARPOS (*it);
4209 else
4210 bufpos = 0;
4212 base_face_id = underlying_face_id (it);
4214 /* Get the face for ASCII, or unibyte. */
4215 face_id = face_at_string_position (it->w,
4216 it->string,
4217 charpos,
4218 bufpos,
4219 &next_check_charpos,
4220 base_face_id, false);
4222 /* Correct the face for charsets different from ASCII. Do it
4223 for the multibyte case only. The face returned above is
4224 suitable for unibyte text if IT->string is unibyte. */
4225 if (STRING_MULTIBYTE (it->string))
4227 struct text_pos pos1 = string_pos (charpos, it->string);
4228 const unsigned char *p = SDATA (it->string) + BYTEPOS (pos1);
4229 int c, len;
4230 struct face *face = FACE_FROM_ID (it->f, face_id);
4232 c = string_char_and_length (p, &len);
4233 face_id = FACE_FOR_CHAR (it->f, face, c, charpos, it->string);
4236 else
4238 struct text_pos pos;
4240 if ((IT_CHARPOS (*it) >= ZV && !before_p)
4241 || (IT_CHARPOS (*it) <= BEGV && before_p))
4242 return it->face_id;
4244 limit = IT_CHARPOS (*it) + TEXT_PROP_DISTANCE_LIMIT;
4245 pos = it->current.pos;
4247 if (!it->bidi_p)
4249 if (before_p)
4250 DEC_TEXT_POS (pos, it->multibyte_p);
4251 else
4253 if (it->what == IT_COMPOSITION)
4255 /* For composition, we must check the position after
4256 the composition. */
4257 pos.charpos += it->cmp_it.nchars;
4258 pos.bytepos += it->len;
4260 else
4261 INC_TEXT_POS (pos, it->multibyte_p);
4264 else
4266 if (before_p)
4268 int current_x;
4270 /* With bidi iteration, the character before the current
4271 in the visual order cannot be found by simple
4272 iteration, because "reverse" reordering is not
4273 supported. Instead, we need to use the move_it_*
4274 family of functions, and move to the previous
4275 character starting from the beginning of the visual
4276 line. */
4277 /* Ignore face changes before the first visible
4278 character on this display line. */
4279 if (it->current_x <= it->first_visible_x)
4280 return it->face_id;
4281 SAVE_IT (it_copy, *it, it_copy_data);
4282 /* Implementation note: Since move_it_in_display_line
4283 works in the iterator geometry, and thinks the first
4284 character is always the leftmost, even in R2L lines,
4285 we don't need to distinguish between the R2L and L2R
4286 cases here. */
4287 current_x = it_copy.current_x;
4288 move_it_vertically_backward (&it_copy, 0);
4289 move_it_in_display_line (&it_copy, ZV, current_x - 1, MOVE_TO_X);
4290 pos = it_copy.current.pos;
4291 RESTORE_IT (it, it, it_copy_data);
4293 else
4295 /* Set charpos to the buffer position of the character
4296 that comes after IT's current position in the visual
4297 order. */
4298 int n = (it->what == IT_COMPOSITION ? it->cmp_it.nchars : 1);
4300 it_copy = *it;
4301 while (n--)
4302 bidi_move_to_visually_next (&it_copy.bidi_it);
4304 SET_TEXT_POS (pos,
4305 it_copy.bidi_it.charpos, it_copy.bidi_it.bytepos);
4308 eassert (BEGV <= CHARPOS (pos) && CHARPOS (pos) <= ZV);
4310 /* Determine face for CHARSET_ASCII, or unibyte. */
4311 face_id = face_at_buffer_position (it->w,
4312 CHARPOS (pos),
4313 &next_check_charpos,
4314 limit, false, -1);
4316 /* Correct the face for charsets different from ASCII. Do it
4317 for the multibyte case only. The face returned above is
4318 suitable for unibyte text if current_buffer is unibyte. */
4319 if (it->multibyte_p)
4321 int c = FETCH_MULTIBYTE_CHAR (BYTEPOS (pos));
4322 struct face *face = FACE_FROM_ID (it->f, face_id);
4323 face_id = FACE_FOR_CHAR (it->f, face, c, CHARPOS (pos), Qnil);
4327 return face_id;
4332 /***********************************************************************
4333 Invisible text
4334 ***********************************************************************/
4336 /* Set up iterator IT from invisible properties at its current
4337 position. Called from handle_stop. */
4339 static enum prop_handled
4340 handle_invisible_prop (struct it *it)
4342 enum prop_handled handled = HANDLED_NORMALLY;
4343 int invis;
4344 Lisp_Object prop;
4346 if (STRINGP (it->string))
4348 Lisp_Object end_charpos, limit;
4350 /* Get the value of the invisible text property at the
4351 current position. Value will be nil if there is no such
4352 property. */
4353 end_charpos = make_number (IT_STRING_CHARPOS (*it));
4354 prop = Fget_text_property (end_charpos, Qinvisible, it->string);
4355 invis = TEXT_PROP_MEANS_INVISIBLE (prop);
4357 if (invis != 0 && IT_STRING_CHARPOS (*it) < it->end_charpos)
4359 /* Record whether we have to display an ellipsis for the
4360 invisible text. */
4361 bool display_ellipsis_p = (invis == 2);
4362 ptrdiff_t len, endpos;
4364 handled = HANDLED_RECOMPUTE_PROPS;
4366 /* Get the position at which the next visible text can be
4367 found in IT->string, if any. */
4368 endpos = len = SCHARS (it->string);
4369 XSETINT (limit, len);
4372 end_charpos
4373 = Fnext_single_property_change (end_charpos, Qinvisible,
4374 it->string, limit);
4375 /* Since LIMIT is always an integer, so should be the
4376 value returned by Fnext_single_property_change. */
4377 eassert (INTEGERP (end_charpos));
4378 if (INTEGERP (end_charpos))
4380 endpos = XFASTINT (end_charpos);
4381 prop = Fget_text_property (end_charpos, Qinvisible, it->string);
4382 invis = TEXT_PROP_MEANS_INVISIBLE (prop);
4383 if (invis == 2)
4384 display_ellipsis_p = true;
4386 else /* Should never happen; but if it does, exit the loop. */
4387 endpos = len;
4389 while (invis != 0 && endpos < len);
4391 if (display_ellipsis_p)
4392 it->ellipsis_p = true;
4394 if (endpos < len)
4396 /* Text at END_CHARPOS is visible. Move IT there. */
4397 struct text_pos old;
4398 ptrdiff_t oldpos;
4400 old = it->current.string_pos;
4401 oldpos = CHARPOS (old);
4402 if (it->bidi_p)
4404 if (it->bidi_it.first_elt
4405 && it->bidi_it.charpos < SCHARS (it->string))
4406 bidi_paragraph_init (it->paragraph_embedding,
4407 &it->bidi_it, true);
4408 /* Bidi-iterate out of the invisible text. */
4411 bidi_move_to_visually_next (&it->bidi_it);
4413 while (oldpos <= it->bidi_it.charpos
4414 && it->bidi_it.charpos < endpos
4415 && it->bidi_it.charpos < it->bidi_it.string.schars);
4417 IT_STRING_CHARPOS (*it) = it->bidi_it.charpos;
4418 IT_STRING_BYTEPOS (*it) = it->bidi_it.bytepos;
4419 if (IT_CHARPOS (*it) >= endpos)
4420 it->prev_stop = endpos;
4422 else
4424 IT_STRING_CHARPOS (*it) = endpos;
4425 compute_string_pos (&it->current.string_pos, old, it->string);
4428 else
4430 /* The rest of the string is invisible. If this is an
4431 overlay string, proceed with the next overlay string
4432 or whatever comes and return a character from there. */
4433 if (it->current.overlay_string_index >= 0
4434 && !display_ellipsis_p)
4436 next_overlay_string (it);
4437 /* Don't check for overlay strings when we just
4438 finished processing them. */
4439 handled = HANDLED_OVERLAY_STRING_CONSUMED;
4441 else
4443 IT_STRING_CHARPOS (*it) = SCHARS (it->string);
4444 IT_STRING_BYTEPOS (*it) = SBYTES (it->string);
4449 else
4451 ptrdiff_t newpos, next_stop, start_charpos, tem;
4452 Lisp_Object pos, overlay;
4454 /* First of all, is there invisible text at this position? */
4455 tem = start_charpos = IT_CHARPOS (*it);
4456 pos = make_number (tem);
4457 prop = get_char_property_and_overlay (pos, Qinvisible, it->window,
4458 &overlay);
4459 invis = TEXT_PROP_MEANS_INVISIBLE (prop);
4461 /* If we are on invisible text, skip over it. */
4462 if (invis != 0 && start_charpos < it->end_charpos)
4464 /* Record whether we have to display an ellipsis for the
4465 invisible text. */
4466 bool display_ellipsis_p = invis == 2;
4468 handled = HANDLED_RECOMPUTE_PROPS;
4470 /* Loop skipping over invisible text. The loop is left at
4471 ZV or with IT on the first char being visible again. */
4474 /* Try to skip some invisible text. Return value is the
4475 position reached which can be equal to where we start
4476 if there is nothing invisible there. This skips both
4477 over invisible text properties and overlays with
4478 invisible property. */
4479 newpos = skip_invisible (tem, &next_stop, ZV, it->window);
4481 /* If we skipped nothing at all we weren't at invisible
4482 text in the first place. If everything to the end of
4483 the buffer was skipped, end the loop. */
4484 if (newpos == tem || newpos >= ZV)
4485 invis = 0;
4486 else
4488 /* We skipped some characters but not necessarily
4489 all there are. Check if we ended up on visible
4490 text. Fget_char_property returns the property of
4491 the char before the given position, i.e. if we
4492 get invis = 0, this means that the char at
4493 newpos is visible. */
4494 pos = make_number (newpos);
4495 prop = Fget_char_property (pos, Qinvisible, it->window);
4496 invis = TEXT_PROP_MEANS_INVISIBLE (prop);
4499 /* If we ended up on invisible text, proceed to
4500 skip starting with next_stop. */
4501 if (invis != 0)
4502 tem = next_stop;
4504 /* If there are adjacent invisible texts, don't lose the
4505 second one's ellipsis. */
4506 if (invis == 2)
4507 display_ellipsis_p = true;
4509 while (invis != 0);
4511 /* The position newpos is now either ZV or on visible text. */
4512 if (it->bidi_p)
4514 ptrdiff_t bpos = CHAR_TO_BYTE (newpos);
4515 bool on_newline
4516 = bpos == ZV_BYTE || FETCH_BYTE (bpos) == '\n';
4517 bool after_newline
4518 = newpos <= BEGV || FETCH_BYTE (bpos - 1) == '\n';
4520 /* If the invisible text ends on a newline or on a
4521 character after a newline, we can avoid the costly,
4522 character by character, bidi iteration to NEWPOS, and
4523 instead simply reseat the iterator there. That's
4524 because all bidi reordering information is tossed at
4525 the newline. This is a big win for modes that hide
4526 complete lines, like Outline, Org, etc. */
4527 if (on_newline || after_newline)
4529 struct text_pos tpos;
4530 bidi_dir_t pdir = it->bidi_it.paragraph_dir;
4532 SET_TEXT_POS (tpos, newpos, bpos);
4533 reseat_1 (it, tpos, false);
4534 /* If we reseat on a newline/ZV, we need to prep the
4535 bidi iterator for advancing to the next character
4536 after the newline/EOB, keeping the current paragraph
4537 direction (so that PRODUCE_GLYPHS does TRT wrt
4538 prepending/appending glyphs to a glyph row). */
4539 if (on_newline)
4541 it->bidi_it.first_elt = false;
4542 it->bidi_it.paragraph_dir = pdir;
4543 it->bidi_it.ch = (bpos == ZV_BYTE) ? -1 : '\n';
4544 it->bidi_it.nchars = 1;
4545 it->bidi_it.ch_len = 1;
4548 else /* Must use the slow method. */
4550 /* With bidi iteration, the region of invisible text
4551 could start and/or end in the middle of a
4552 non-base embedding level. Therefore, we need to
4553 skip invisible text using the bidi iterator,
4554 starting at IT's current position, until we find
4555 ourselves outside of the invisible text.
4556 Skipping invisible text _after_ bidi iteration
4557 avoids affecting the visual order of the
4558 displayed text when invisible properties are
4559 added or removed. */
4560 if (it->bidi_it.first_elt && it->bidi_it.charpos < ZV)
4562 /* If we were `reseat'ed to a new paragraph,
4563 determine the paragraph base direction. We
4564 need to do it now because
4565 next_element_from_buffer may not have a
4566 chance to do it, if we are going to skip any
4567 text at the beginning, which resets the
4568 FIRST_ELT flag. */
4569 bidi_paragraph_init (it->paragraph_embedding,
4570 &it->bidi_it, true);
4574 bidi_move_to_visually_next (&it->bidi_it);
4576 while (it->stop_charpos <= it->bidi_it.charpos
4577 && it->bidi_it.charpos < newpos);
4578 IT_CHARPOS (*it) = it->bidi_it.charpos;
4579 IT_BYTEPOS (*it) = it->bidi_it.bytepos;
4580 /* If we overstepped NEWPOS, record its position in
4581 the iterator, so that we skip invisible text if
4582 later the bidi iteration lands us in the
4583 invisible region again. */
4584 if (IT_CHARPOS (*it) >= newpos)
4585 it->prev_stop = newpos;
4588 else
4590 IT_CHARPOS (*it) = newpos;
4591 IT_BYTEPOS (*it) = CHAR_TO_BYTE (newpos);
4594 if (display_ellipsis_p)
4596 /* Make sure that the glyphs of the ellipsis will get
4597 correct `charpos' values. If we would not update
4598 it->position here, the glyphs would belong to the
4599 last visible character _before_ the invisible
4600 text, which confuses `set_cursor_from_row'.
4602 We use the last invisible position instead of the
4603 first because this way the cursor is always drawn on
4604 the first "." of the ellipsis, whenever PT is inside
4605 the invisible text. Otherwise the cursor would be
4606 placed _after_ the ellipsis when the point is after the
4607 first invisible character. */
4608 if (!STRINGP (it->object))
4610 it->position.charpos = newpos - 1;
4611 it->position.bytepos = CHAR_TO_BYTE (it->position.charpos);
4615 /* If there are before-strings at the start of invisible
4616 text, and the text is invisible because of a text
4617 property, arrange to show before-strings because 20.x did
4618 it that way. (If the text is invisible because of an
4619 overlay property instead of a text property, this is
4620 already handled in the overlay code.) */
4621 if (NILP (overlay)
4622 && get_overlay_strings (it, it->stop_charpos))
4624 handled = HANDLED_RECOMPUTE_PROPS;
4625 if (it->sp > 0)
4627 it->stack[it->sp - 1].display_ellipsis_p = display_ellipsis_p;
4628 /* The call to get_overlay_strings above recomputes
4629 it->stop_charpos, but it only considers changes
4630 in properties and overlays beyond iterator's
4631 current position. This causes us to miss changes
4632 that happen exactly where the invisible property
4633 ended. So we play it safe here and force the
4634 iterator to check for potential stop positions
4635 immediately after the invisible text. Note that
4636 if get_overlay_strings returns true, it
4637 normally also pushed the iterator stack, so we
4638 need to update the stop position in the slot
4639 below the current one. */
4640 it->stack[it->sp - 1].stop_charpos
4641 = CHARPOS (it->stack[it->sp - 1].current.pos);
4644 else if (display_ellipsis_p)
4646 it->ellipsis_p = true;
4647 /* Let the ellipsis display before
4648 considering any properties of the following char.
4649 Fixes jasonr@gnu.org 01 Oct 07 bug. */
4650 handled = HANDLED_RETURN;
4655 return handled;
4659 /* Make iterator IT return `...' next.
4660 Replaces LEN characters from buffer. */
4662 static void
4663 setup_for_ellipsis (struct it *it, int len)
4665 /* Use the display table definition for `...'. Invalid glyphs
4666 will be handled by the method returning elements from dpvec. */
4667 if (it->dp && VECTORP (DISP_INVIS_VECTOR (it->dp)))
4669 struct Lisp_Vector *v = XVECTOR (DISP_INVIS_VECTOR (it->dp));
4670 it->dpvec = v->contents;
4671 it->dpend = v->contents + v->header.size;
4673 else
4675 /* Default `...'. */
4676 it->dpvec = default_invis_vector;
4677 it->dpend = default_invis_vector + 3;
4680 it->dpvec_char_len = len;
4681 it->current.dpvec_index = 0;
4682 it->dpvec_face_id = -1;
4684 /* Use IT->saved_face_id for the ellipsis, so that it has the same
4685 face as the preceding text. IT->saved_face_id was set in
4686 handle_stop to the face of the preceding character, and will be
4687 different from IT->face_id only if the invisible text skipped in
4688 handle_invisible_prop has some non-default face on its first
4689 character. We thus ignore the face of the invisible text when we
4690 display the ellipsis. IT's face is restored in set_iterator_to_next. */
4691 if (it->saved_face_id >= 0)
4692 it->face_id = it->saved_face_id;
4694 /* If the ellipsis represents buffer text, it means we advanced in
4695 the buffer, so we should no longer ignore overlay strings. */
4696 if (it->method == GET_FROM_BUFFER)
4697 it->ignore_overlay_strings_at_pos_p = false;
4699 it->method = GET_FROM_DISPLAY_VECTOR;
4700 it->ellipsis_p = true;
4705 /***********************************************************************
4706 'display' property
4707 ***********************************************************************/
4709 /* Set up iterator IT from `display' property at its current position.
4710 Called from handle_stop.
4711 We return HANDLED_RETURN if some part of the display property
4712 overrides the display of the buffer text itself.
4713 Otherwise we return HANDLED_NORMALLY. */
4715 static enum prop_handled
4716 handle_display_prop (struct it *it)
4718 Lisp_Object propval, object, overlay;
4719 struct text_pos *position;
4720 ptrdiff_t bufpos;
4721 /* Nonzero if some property replaces the display of the text itself. */
4722 int display_replaced = 0;
4724 if (STRINGP (it->string))
4726 object = it->string;
4727 position = &it->current.string_pos;
4728 bufpos = CHARPOS (it->current.pos);
4730 else
4732 XSETWINDOW (object, it->w);
4733 position = &it->current.pos;
4734 bufpos = CHARPOS (*position);
4737 /* Reset those iterator values set from display property values. */
4738 it->slice.x = it->slice.y = it->slice.width = it->slice.height = Qnil;
4739 it->space_width = Qnil;
4740 it->font_height = Qnil;
4741 it->voffset = 0;
4743 /* We don't support recursive `display' properties, i.e. string
4744 values that have a string `display' property, that have a string
4745 `display' property etc. */
4746 if (!it->string_from_display_prop_p)
4747 it->area = TEXT_AREA;
4749 propval = get_char_property_and_overlay (make_number (position->charpos),
4750 Qdisplay, object, &overlay);
4751 if (NILP (propval))
4752 return HANDLED_NORMALLY;
4753 /* Now OVERLAY is the overlay that gave us this property, or nil
4754 if it was a text property. */
4756 if (!STRINGP (it->string))
4757 object = it->w->contents;
4759 display_replaced = handle_display_spec (it, propval, object, overlay,
4760 position, bufpos,
4761 FRAME_WINDOW_P (it->f));
4762 return display_replaced != 0 ? HANDLED_RETURN : HANDLED_NORMALLY;
4765 /* Subroutine of handle_display_prop. Returns non-zero if the display
4766 specification in SPEC is a replacing specification, i.e. it would
4767 replace the text covered by `display' property with something else,
4768 such as an image or a display string. If SPEC includes any kind or
4769 `(space ...) specification, the value is 2; this is used by
4770 compute_display_string_pos, which see.
4772 See handle_single_display_spec for documentation of arguments.
4773 FRAME_WINDOW_P is true if the window being redisplayed is on a
4774 GUI frame; this argument is used only if IT is NULL, see below.
4776 IT can be NULL, if this is called by the bidi reordering code
4777 through compute_display_string_pos, which see. In that case, this
4778 function only examines SPEC, but does not otherwise "handle" it, in
4779 the sense that it doesn't set up members of IT from the display
4780 spec. */
4781 static int
4782 handle_display_spec (struct it *it, Lisp_Object spec, Lisp_Object object,
4783 Lisp_Object overlay, struct text_pos *position,
4784 ptrdiff_t bufpos, bool frame_window_p)
4786 int replacing = 0;
4787 bool enable_eval = true;
4789 /* Support (disable-eval PROP) which is used by enriched.el. */
4790 if (CONSP (spec) && EQ (XCAR (spec), Qdisable_eval))
4792 enable_eval = false;
4793 spec = XCAR (XCDR (spec));
4796 if (CONSP (spec)
4797 /* Simple specifications. */
4798 && !EQ (XCAR (spec), Qimage)
4799 #ifdef HAVE_XWIDGETS
4800 && !EQ (XCAR (spec), Qxwidget)
4801 #endif
4802 && !EQ (XCAR (spec), Qspace)
4803 && !EQ (XCAR (spec), Qwhen)
4804 && !EQ (XCAR (spec), Qslice)
4805 && !EQ (XCAR (spec), Qspace_width)
4806 && !EQ (XCAR (spec), Qheight)
4807 && !EQ (XCAR (spec), Qraise)
4808 /* Marginal area specifications. */
4809 && !(CONSP (XCAR (spec)) && EQ (XCAR (XCAR (spec)), Qmargin))
4810 && !EQ (XCAR (spec), Qleft_fringe)
4811 && !EQ (XCAR (spec), Qright_fringe)
4812 && !NILP (XCAR (spec)))
4814 for (; CONSP (spec); spec = XCDR (spec))
4816 int rv = handle_single_display_spec (it, XCAR (spec), object,
4817 overlay, position, bufpos,
4818 replacing, frame_window_p,
4819 enable_eval);
4820 if (rv != 0)
4822 replacing = rv;
4823 /* If some text in a string is replaced, `position' no
4824 longer points to the position of `object'. */
4825 if (!it || STRINGP (object))
4826 break;
4830 else if (VECTORP (spec))
4832 ptrdiff_t i;
4833 for (i = 0; i < ASIZE (spec); ++i)
4835 int rv = handle_single_display_spec (it, AREF (spec, i), object,
4836 overlay, position, bufpos,
4837 replacing, frame_window_p,
4838 enable_eval);
4839 if (rv != 0)
4841 replacing = rv;
4842 /* If some text in a string is replaced, `position' no
4843 longer points to the position of `object'. */
4844 if (!it || STRINGP (object))
4845 break;
4849 else
4850 replacing = handle_single_display_spec (it, spec, object, overlay, position,
4851 bufpos, 0, frame_window_p,
4852 enable_eval);
4853 return replacing;
4856 /* Value is the position of the end of the `display' property starting
4857 at START_POS in OBJECT. */
4859 static struct text_pos
4860 display_prop_end (struct it *it, Lisp_Object object, struct text_pos start_pos)
4862 Lisp_Object end;
4863 struct text_pos end_pos;
4865 end = Fnext_single_char_property_change (make_number (CHARPOS (start_pos)),
4866 Qdisplay, object, Qnil);
4867 CHARPOS (end_pos) = XFASTINT (end);
4868 if (STRINGP (object))
4869 compute_string_pos (&end_pos, start_pos, it->string);
4870 else
4871 BYTEPOS (end_pos) = CHAR_TO_BYTE (XFASTINT (end));
4873 return end_pos;
4877 /* Set up IT from a single `display' property specification SPEC. OBJECT
4878 is the object in which the `display' property was found. *POSITION
4879 is the position in OBJECT at which the `display' property was found.
4880 BUFPOS is the buffer position of OBJECT (different from POSITION if
4881 OBJECT is not a buffer). DISPLAY_REPLACED non-zero means that we
4882 previously saw a display specification which already replaced text
4883 display with something else, for example an image; we ignore such
4884 properties after the first one has been processed.
4886 OVERLAY is the overlay this `display' property came from,
4887 or nil if it was a text property.
4889 If SPEC is a `space' or `image' specification, and in some other
4890 cases too, set *POSITION to the position where the `display'
4891 property ends.
4893 If IT is NULL, only examine the property specification in SPEC, but
4894 don't set up IT. In that case, FRAME_WINDOW_P means SPEC
4895 is intended to be displayed in a window on a GUI frame.
4897 Enable evaluation of Lisp forms only if ENABLE_EVAL_P is true.
4899 Value is non-zero if something was found which replaces the display
4900 of buffer or string text. */
4902 static int
4903 handle_single_display_spec (struct it *it, Lisp_Object spec, Lisp_Object object,
4904 Lisp_Object overlay, struct text_pos *position,
4905 ptrdiff_t bufpos, int display_replaced,
4906 bool frame_window_p, bool enable_eval_p)
4908 Lisp_Object form;
4909 Lisp_Object location, value;
4910 struct text_pos start_pos = *position;
4912 /* If SPEC is a list of the form `(when FORM . VALUE)', evaluate FORM.
4913 If the result is non-nil, use VALUE instead of SPEC. */
4914 form = Qt;
4915 if (CONSP (spec) && EQ (XCAR (spec), Qwhen))
4917 spec = XCDR (spec);
4918 if (!CONSP (spec))
4919 return 0;
4920 form = XCAR (spec);
4921 spec = XCDR (spec);
4924 if (!NILP (form) && !EQ (form, Qt) && !enable_eval_p)
4925 form = Qnil;
4926 if (!NILP (form) && !EQ (form, Qt))
4928 ptrdiff_t count = SPECPDL_INDEX ();
4930 /* Bind `object' to the object having the `display' property, a
4931 buffer or string. Bind `position' to the position in the
4932 object where the property was found, and `buffer-position'
4933 to the current position in the buffer. */
4935 if (NILP (object))
4936 XSETBUFFER (object, current_buffer);
4937 specbind (Qobject, object);
4938 specbind (Qposition, make_number (CHARPOS (*position)));
4939 specbind (Qbuffer_position, make_number (bufpos));
4940 form = safe_eval (form);
4941 unbind_to (count, Qnil);
4944 if (NILP (form))
4945 return 0;
4947 /* Handle `(height HEIGHT)' specifications. */
4948 if (CONSP (spec)
4949 && EQ (XCAR (spec), Qheight)
4950 && CONSP (XCDR (spec)))
4952 if (it)
4954 if (!FRAME_WINDOW_P (it->f))
4955 return 0;
4957 it->font_height = XCAR (XCDR (spec));
4958 if (!NILP (it->font_height))
4960 int new_height = -1;
4962 if (CONSP (it->font_height)
4963 && (EQ (XCAR (it->font_height), Qplus)
4964 || EQ (XCAR (it->font_height), Qminus))
4965 && CONSP (XCDR (it->font_height))
4966 && RANGED_INTEGERP (0, XCAR (XCDR (it->font_height)), INT_MAX))
4968 /* `(+ N)' or `(- N)' where N is an integer. */
4969 int steps = XINT (XCAR (XCDR (it->font_height)));
4970 if (EQ (XCAR (it->font_height), Qplus))
4971 steps = - steps;
4972 it->face_id = smaller_face (it->f, it->face_id, steps);
4974 else if (FUNCTIONP (it->font_height) && enable_eval_p)
4976 /* Call function with current height as argument.
4977 Value is the new height. */
4978 struct face *face = FACE_FROM_ID (it->f, it->face_id);
4979 Lisp_Object height;
4980 height = safe_call1 (it->font_height,
4981 face->lface[LFACE_HEIGHT_INDEX]);
4982 if (NUMBERP (height))
4983 new_height = XFLOATINT (height);
4985 else if (NUMBERP (it->font_height))
4987 /* Value is a multiple of the canonical char height. */
4988 struct face *f;
4990 f = FACE_FROM_ID (it->f,
4991 lookup_basic_face (it->w, it->f, DEFAULT_FACE_ID));
4992 new_height = (XFLOATINT (it->font_height)
4993 * XINT (f->lface[LFACE_HEIGHT_INDEX]));
4995 else if (enable_eval_p)
4997 /* Evaluate IT->font_height with `height' bound to the
4998 current specified height to get the new height. */
4999 ptrdiff_t count = SPECPDL_INDEX ();
5000 struct face *face = FACE_FROM_ID (it->f, it->face_id);
5002 specbind (Qheight, face->lface[LFACE_HEIGHT_INDEX]);
5003 value = safe_eval (it->font_height);
5004 unbind_to (count, Qnil);
5006 if (NUMBERP (value))
5007 new_height = XFLOATINT (value);
5010 if (new_height > 0)
5011 it->face_id = face_with_height (it->f, it->face_id, new_height);
5015 return 0;
5018 /* Handle `(space-width WIDTH)'. */
5019 if (CONSP (spec)
5020 && EQ (XCAR (spec), Qspace_width)
5021 && CONSP (XCDR (spec)))
5023 if (it)
5025 if (!FRAME_WINDOW_P (it->f))
5026 return 0;
5028 value = XCAR (XCDR (spec));
5029 if (NUMBERP (value) && XFLOATINT (value) > 0)
5030 it->space_width = value;
5033 return 0;
5036 /* Handle `(slice X Y WIDTH HEIGHT)'. */
5037 if (CONSP (spec)
5038 && EQ (XCAR (spec), Qslice))
5040 Lisp_Object tem;
5042 if (it)
5044 if (!FRAME_WINDOW_P (it->f))
5045 return 0;
5047 if (tem = XCDR (spec), CONSP (tem))
5049 it->slice.x = XCAR (tem);
5050 if (tem = XCDR (tem), CONSP (tem))
5052 it->slice.y = XCAR (tem);
5053 if (tem = XCDR (tem), CONSP (tem))
5055 it->slice.width = XCAR (tem);
5056 if (tem = XCDR (tem), CONSP (tem))
5057 it->slice.height = XCAR (tem);
5063 return 0;
5066 /* Handle `(raise FACTOR)'. */
5067 if (CONSP (spec)
5068 && EQ (XCAR (spec), Qraise)
5069 && CONSP (XCDR (spec)))
5071 if (it)
5073 if (!FRAME_WINDOW_P (it->f))
5074 return 0;
5076 #ifdef HAVE_WINDOW_SYSTEM
5077 value = XCAR (XCDR (spec));
5078 if (NUMBERP (value))
5080 struct face *face = FACE_FROM_ID (it->f, it->face_id);
5081 it->voffset = - (XFLOATINT (value)
5082 * (normal_char_height (face->font, -1)));
5084 #endif /* HAVE_WINDOW_SYSTEM */
5087 return 0;
5090 /* Don't handle the other kinds of display specifications
5091 inside a string that we got from a `display' property. */
5092 if (it && it->string_from_display_prop_p)
5093 return 0;
5095 /* Characters having this form of property are not displayed, so
5096 we have to find the end of the property. */
5097 if (it)
5099 start_pos = *position;
5100 *position = display_prop_end (it, object, start_pos);
5101 /* If the display property comes from an overlay, don't consider
5102 any potential stop_charpos values before the end of that
5103 overlay. Since display_prop_end will happily find another
5104 'display' property coming from some other overlay or text
5105 property on buffer positions before this overlay's end, we
5106 need to ignore them, or else we risk displaying this
5107 overlay's display string/image twice. */
5108 if (!NILP (overlay))
5110 ptrdiff_t ovendpos = OVERLAY_POSITION (OVERLAY_END (overlay));
5112 /* Some borderline-sane Lisp might call us with the current
5113 buffer narrowed so that overlay-end is outside the
5114 POINT_MIN..POINT_MAX region, which will then cause
5115 various assertion violations and crashes down the road,
5116 starting with pop_it when it will attempt to use POSITION
5117 set below. Prevent that. */
5118 ovendpos = clip_to_bounds (BEGV, ovendpos, ZV);
5120 if (ovendpos > CHARPOS (*position))
5121 SET_TEXT_POS (*position, ovendpos, CHAR_TO_BYTE (ovendpos));
5124 value = Qnil;
5126 /* Stop the scan at that end position--we assume that all
5127 text properties change there. */
5128 if (it)
5129 it->stop_charpos = position->charpos;
5131 /* Handle `(left-fringe BITMAP [FACE])'
5132 and `(right-fringe BITMAP [FACE])'. */
5133 if (CONSP (spec)
5134 && (EQ (XCAR (spec), Qleft_fringe)
5135 || EQ (XCAR (spec), Qright_fringe))
5136 && CONSP (XCDR (spec)))
5138 if (it)
5140 if (!FRAME_WINDOW_P (it->f))
5141 /* If we return here, POSITION has been advanced
5142 across the text with this property. */
5144 /* Synchronize the bidi iterator with POSITION. This is
5145 needed because we are not going to push the iterator
5146 on behalf of this display property, so there will be
5147 no pop_it call to do this synchronization for us. */
5148 if (it->bidi_p)
5150 it->position = *position;
5151 iterate_out_of_display_property (it);
5152 *position = it->position;
5154 return 1;
5157 else if (!frame_window_p)
5158 return 1;
5160 #ifdef HAVE_WINDOW_SYSTEM
5161 value = XCAR (XCDR (spec));
5162 int fringe_bitmap = SYMBOLP (value) ? lookup_fringe_bitmap (value) : 0;
5163 if (! fringe_bitmap)
5164 /* If we return here, POSITION has been advanced
5165 across the text with this property. */
5167 if (it && it->bidi_p)
5169 it->position = *position;
5170 iterate_out_of_display_property (it);
5171 *position = it->position;
5173 return 1;
5176 if (it)
5178 int face_id = lookup_basic_face (it->w, it->f, DEFAULT_FACE_ID);
5180 if (CONSP (XCDR (XCDR (spec))))
5182 Lisp_Object face_name = XCAR (XCDR (XCDR (spec)));
5183 int face_id2 = lookup_derived_face (it->w, it->f, face_name,
5184 FRINGE_FACE_ID, false);
5185 if (face_id2 >= 0)
5186 face_id = face_id2;
5189 /* Save current settings of IT so that we can restore them
5190 when we are finished with the glyph property value. */
5191 push_it (it, position);
5193 it->area = TEXT_AREA;
5194 it->what = IT_IMAGE;
5195 it->image_id = -1; /* no image */
5196 it->position = start_pos;
5197 it->object = NILP (object) ? it->w->contents : object;
5198 it->method = GET_FROM_IMAGE;
5199 it->from_overlay = Qnil;
5200 it->face_id = face_id;
5201 it->from_disp_prop_p = true;
5203 /* Say that we haven't consumed the characters with
5204 `display' property yet. The call to pop_it in
5205 set_iterator_to_next will clean this up. */
5206 *position = start_pos;
5208 if (EQ (XCAR (spec), Qleft_fringe))
5210 it->left_user_fringe_bitmap = fringe_bitmap;
5211 it->left_user_fringe_face_id = face_id;
5213 else
5215 it->right_user_fringe_bitmap = fringe_bitmap;
5216 it->right_user_fringe_face_id = face_id;
5219 #endif /* HAVE_WINDOW_SYSTEM */
5220 return 1;
5223 /* Prepare to handle `((margin left-margin) ...)',
5224 `((margin right-margin) ...)' and `((margin nil) ...)'
5225 prefixes for display specifications. */
5226 location = Qunbound;
5227 if (CONSP (spec) && CONSP (XCAR (spec)))
5229 Lisp_Object tem;
5231 value = XCDR (spec);
5232 if (CONSP (value))
5233 value = XCAR (value);
5235 tem = XCAR (spec);
5236 if (EQ (XCAR (tem), Qmargin)
5237 && (tem = XCDR (tem),
5238 tem = CONSP (tem) ? XCAR (tem) : Qnil,
5239 (NILP (tem)
5240 || EQ (tem, Qleft_margin)
5241 || EQ (tem, Qright_margin))))
5242 location = tem;
5245 if (EQ (location, Qunbound))
5247 location = Qnil;
5248 value = spec;
5251 /* After this point, VALUE is the property after any
5252 margin prefix has been stripped. It must be a string,
5253 an image specification, or `(space ...)'.
5255 LOCATION specifies where to display: `left-margin',
5256 `right-margin' or nil. */
5258 bool valid_p = (STRINGP (value)
5259 #ifdef HAVE_WINDOW_SYSTEM
5260 || ((it ? FRAME_WINDOW_P (it->f) : frame_window_p)
5261 && valid_image_p (value))
5262 #endif /* not HAVE_WINDOW_SYSTEM */
5263 || (CONSP (value) && EQ (XCAR (value), Qspace))
5264 || ((it ? FRAME_WINDOW_P (it->f) : frame_window_p)
5265 && valid_xwidget_spec_p (value)));
5267 if (valid_p && display_replaced == 0)
5269 int retval = 1;
5271 if (!it)
5273 /* Callers need to know whether the display spec is any kind
5274 of `(space ...)' spec that is about to affect text-area
5275 display. */
5276 if (CONSP (value) && EQ (XCAR (value), Qspace) && NILP (location))
5277 retval = 2;
5278 return retval;
5281 /* Save current settings of IT so that we can restore them
5282 when we are finished with the glyph property value. */
5283 push_it (it, position);
5284 it->from_overlay = overlay;
5285 it->from_disp_prop_p = true;
5287 if (NILP (location))
5288 it->area = TEXT_AREA;
5289 else if (EQ (location, Qleft_margin))
5290 it->area = LEFT_MARGIN_AREA;
5291 else
5292 it->area = RIGHT_MARGIN_AREA;
5294 if (STRINGP (value))
5296 it->string = value;
5297 it->multibyte_p = STRING_MULTIBYTE (it->string);
5298 it->current.overlay_string_index = -1;
5299 IT_STRING_CHARPOS (*it) = IT_STRING_BYTEPOS (*it) = 0;
5300 it->end_charpos = it->string_nchars = SCHARS (it->string);
5301 it->method = GET_FROM_STRING;
5302 it->stop_charpos = 0;
5303 it->prev_stop = 0;
5304 it->base_level_stop = 0;
5305 it->string_from_display_prop_p = true;
5306 it->cmp_it.id = -1;
5307 /* Say that we haven't consumed the characters with
5308 `display' property yet. The call to pop_it in
5309 set_iterator_to_next will clean this up. */
5310 if (BUFFERP (object))
5311 *position = start_pos;
5313 /* Force paragraph direction to be that of the parent
5314 object. If the parent object's paragraph direction is
5315 not yet determined, default to L2R. */
5316 if (it->bidi_p && it->bidi_it.paragraph_dir == R2L)
5317 it->paragraph_embedding = it->bidi_it.paragraph_dir;
5318 else
5319 it->paragraph_embedding = L2R;
5321 /* Set up the bidi iterator for this display string. */
5322 if (it->bidi_p)
5324 it->bidi_it.string.lstring = it->string;
5325 it->bidi_it.string.s = NULL;
5326 it->bidi_it.string.schars = it->end_charpos;
5327 it->bidi_it.string.bufpos = bufpos;
5328 it->bidi_it.string.from_disp_str = true;
5329 it->bidi_it.string.unibyte = !it->multibyte_p;
5330 it->bidi_it.w = it->w;
5331 bidi_init_it (0, 0, FRAME_WINDOW_P (it->f), &it->bidi_it);
5334 else if (CONSP (value) && EQ (XCAR (value), Qspace))
5336 it->method = GET_FROM_STRETCH;
5337 it->object = value;
5338 *position = it->position = start_pos;
5339 retval = 1 + (it->area == TEXT_AREA);
5341 else if (valid_xwidget_spec_p (value))
5343 it->what = IT_XWIDGET;
5344 it->method = GET_FROM_XWIDGET;
5345 it->position = start_pos;
5346 it->object = NILP (object) ? it->w->contents : object;
5347 *position = start_pos;
5348 it->xwidget = lookup_xwidget (value);
5350 #ifdef HAVE_WINDOW_SYSTEM
5351 else
5353 it->what = IT_IMAGE;
5354 it->image_id = lookup_image (it->f, value);
5355 it->position = start_pos;
5356 it->object = NILP (object) ? it->w->contents : object;
5357 it->method = GET_FROM_IMAGE;
5359 /* Say that we haven't consumed the characters with
5360 `display' property yet. The call to pop_it in
5361 set_iterator_to_next will clean this up. */
5362 *position = start_pos;
5364 #endif /* HAVE_WINDOW_SYSTEM */
5366 return retval;
5369 /* Invalid property or property not supported. Restore
5370 POSITION to what it was before. */
5371 *position = start_pos;
5372 return 0;
5375 /* Check if PROP is a display property value whose text should be
5376 treated as intangible. OVERLAY is the overlay from which PROP
5377 came, or nil if it came from a text property. CHARPOS and BYTEPOS
5378 specify the buffer position covered by PROP. */
5380 bool
5381 display_prop_intangible_p (Lisp_Object prop, Lisp_Object overlay,
5382 ptrdiff_t charpos, ptrdiff_t bytepos)
5384 bool frame_window_p = FRAME_WINDOW_P (XFRAME (selected_frame));
5385 struct text_pos position;
5387 SET_TEXT_POS (position, charpos, bytepos);
5388 return (handle_display_spec (NULL, prop, Qnil, overlay,
5389 &position, charpos, frame_window_p)
5390 != 0);
5394 /* Return true if PROP is a display sub-property value containing STRING.
5396 Implementation note: this and the following function are really
5397 special cases of handle_display_spec and
5398 handle_single_display_spec, and should ideally use the same code.
5399 Until they do, these two pairs must be consistent and must be
5400 modified in sync. */
5402 static bool
5403 single_display_spec_string_p (Lisp_Object prop, Lisp_Object string)
5405 if (EQ (string, prop))
5406 return true;
5408 /* Skip over `when FORM'. */
5409 if (CONSP (prop) && EQ (XCAR (prop), Qwhen))
5411 prop = XCDR (prop);
5412 if (!CONSP (prop))
5413 return false;
5414 /* Actually, the condition following `when' should be eval'ed,
5415 like handle_single_display_spec does, and we should return
5416 false if it evaluates to nil. However, this function is
5417 called only when the buffer was already displayed and some
5418 glyph in the glyph matrix was found to come from a display
5419 string. Therefore, the condition was already evaluated, and
5420 the result was non-nil, otherwise the display string wouldn't
5421 have been displayed and we would have never been called for
5422 this property. Thus, we can skip the evaluation and assume
5423 its result is non-nil. */
5424 prop = XCDR (prop);
5427 if (CONSP (prop))
5428 /* Skip over `margin LOCATION'. */
5429 if (EQ (XCAR (prop), Qmargin))
5431 prop = XCDR (prop);
5432 if (!CONSP (prop))
5433 return false;
5435 prop = XCDR (prop);
5436 if (!CONSP (prop))
5437 return false;
5440 return EQ (prop, string) || (CONSP (prop) && EQ (XCAR (prop), string));
5444 /* Return true if STRING appears in the `display' property PROP. */
5446 static bool
5447 display_prop_string_p (Lisp_Object prop, Lisp_Object string)
5449 if (CONSP (prop)
5450 && !EQ (XCAR (prop), Qwhen)
5451 && !(CONSP (XCAR (prop)) && EQ (Qmargin, XCAR (XCAR (prop)))))
5453 /* A list of sub-properties. */
5454 while (CONSP (prop))
5456 if (single_display_spec_string_p (XCAR (prop), string))
5457 return true;
5458 prop = XCDR (prop);
5461 else if (VECTORP (prop))
5463 /* A vector of sub-properties. */
5464 ptrdiff_t i;
5465 for (i = 0; i < ASIZE (prop); ++i)
5466 if (single_display_spec_string_p (AREF (prop, i), string))
5467 return true;
5469 else
5470 return single_display_spec_string_p (prop, string);
5472 return false;
5475 /* Look for STRING in overlays and text properties in the current
5476 buffer, between character positions FROM and TO (excluding TO).
5477 BACK_P means look back (in this case, TO is supposed to be
5478 less than FROM).
5479 Value is the first character position where STRING was found, or
5480 zero if it wasn't found before hitting TO.
5482 This function may only use code that doesn't eval because it is
5483 called asynchronously from note_mouse_highlight. */
5485 static ptrdiff_t
5486 string_buffer_position_lim (Lisp_Object string,
5487 ptrdiff_t from, ptrdiff_t to, bool back_p)
5489 Lisp_Object limit, prop, pos;
5490 bool found = false;
5492 pos = make_number (max (from, BEGV));
5494 if (!back_p) /* looking forward */
5496 limit = make_number (min (to, ZV));
5497 while (!found && !EQ (pos, limit))
5499 prop = Fget_char_property (pos, Qdisplay, Qnil);
5500 if (!NILP (prop) && display_prop_string_p (prop, string))
5501 found = true;
5502 else
5503 pos = Fnext_single_char_property_change (pos, Qdisplay, Qnil,
5504 limit);
5507 else /* looking back */
5509 limit = make_number (max (to, BEGV));
5510 while (!found && !EQ (pos, limit))
5512 prop = Fget_char_property (pos, Qdisplay, Qnil);
5513 if (!NILP (prop) && display_prop_string_p (prop, string))
5514 found = true;
5515 else
5516 pos = Fprevious_single_char_property_change (pos, Qdisplay, Qnil,
5517 limit);
5521 return found ? XINT (pos) : 0;
5524 /* Determine which buffer position in current buffer STRING comes from.
5525 AROUND_CHARPOS is an approximate position where it could come from.
5526 Value is the buffer position or 0 if it couldn't be determined.
5528 This function is necessary because we don't record buffer positions
5529 in glyphs generated from strings (to keep struct glyph small).
5530 This function may only use code that doesn't eval because it is
5531 called asynchronously from note_mouse_highlight. */
5533 static ptrdiff_t
5534 string_buffer_position (Lisp_Object string, ptrdiff_t around_charpos)
5536 const int MAX_DISTANCE = 1000;
5537 ptrdiff_t found = string_buffer_position_lim (string, around_charpos,
5538 around_charpos + MAX_DISTANCE,
5539 false);
5541 if (!found)
5542 found = string_buffer_position_lim (string, around_charpos,
5543 around_charpos - MAX_DISTANCE, true);
5544 return found;
5549 /***********************************************************************
5550 `composition' property
5551 ***********************************************************************/
5553 /* Set up iterator IT from `composition' property at its current
5554 position. Called from handle_stop. */
5556 static enum prop_handled
5557 handle_composition_prop (struct it *it)
5559 Lisp_Object prop, string;
5560 ptrdiff_t pos, pos_byte, start, end;
5562 if (STRINGP (it->string))
5564 unsigned char *s;
5566 pos = IT_STRING_CHARPOS (*it);
5567 pos_byte = IT_STRING_BYTEPOS (*it);
5568 string = it->string;
5569 s = SDATA (string) + pos_byte;
5570 it->c = STRING_CHAR (s);
5572 else
5574 pos = IT_CHARPOS (*it);
5575 pos_byte = IT_BYTEPOS (*it);
5576 string = Qnil;
5577 it->c = FETCH_CHAR (pos_byte);
5580 /* If there's a valid composition and point is not inside of the
5581 composition (in the case that the composition is from the current
5582 buffer), draw a glyph composed from the composition components. */
5583 if (find_composition (pos, -1, &start, &end, &prop, string)
5584 && composition_valid_p (start, end, prop)
5585 && (STRINGP (it->string) || (PT <= start || PT >= end)))
5587 if (start < pos)
5588 /* As we can't handle this situation (perhaps font-lock added
5589 a new composition), we just return here hoping that next
5590 redisplay will detect this composition much earlier. */
5591 return HANDLED_NORMALLY;
5592 if (start != pos)
5594 if (STRINGP (it->string))
5595 pos_byte = string_char_to_byte (it->string, start);
5596 else
5597 pos_byte = CHAR_TO_BYTE (start);
5599 it->cmp_it.id = get_composition_id (start, pos_byte, end - start,
5600 prop, string);
5602 if (it->cmp_it.id >= 0)
5604 it->cmp_it.ch = -1;
5605 it->cmp_it.nchars = COMPOSITION_LENGTH (prop);
5606 it->cmp_it.nglyphs = -1;
5610 return HANDLED_NORMALLY;
5615 /***********************************************************************
5616 Overlay strings
5617 ***********************************************************************/
5619 /* The following structure is used to record overlay strings for
5620 later sorting in load_overlay_strings. */
5622 struct overlay_entry
5624 Lisp_Object overlay;
5625 Lisp_Object string;
5626 EMACS_INT priority;
5627 bool after_string_p;
5631 /* Set up iterator IT from overlay strings at its current position.
5632 Called from handle_stop. */
5634 static enum prop_handled
5635 handle_overlay_change (struct it *it)
5637 if (!STRINGP (it->string) && get_overlay_strings (it, 0))
5638 return HANDLED_RECOMPUTE_PROPS;
5639 else
5640 return HANDLED_NORMALLY;
5644 /* Set up the next overlay string for delivery by IT, if there is an
5645 overlay string to deliver. Called by set_iterator_to_next when the
5646 end of the current overlay string is reached. If there are more
5647 overlay strings to display, IT->string and
5648 IT->current.overlay_string_index are set appropriately here.
5649 Otherwise IT->string is set to nil. */
5651 static void
5652 next_overlay_string (struct it *it)
5654 ++it->current.overlay_string_index;
5655 if (it->current.overlay_string_index == it->n_overlay_strings)
5657 /* No more overlay strings. Restore IT's settings to what
5658 they were before overlay strings were processed, and
5659 continue to deliver from current_buffer. */
5661 it->ellipsis_p = it->stack[it->sp - 1].display_ellipsis_p;
5662 pop_it (it);
5663 eassert (it->sp > 0
5664 || (NILP (it->string)
5665 && it->method == GET_FROM_BUFFER
5666 && it->stop_charpos >= BEGV
5667 && it->stop_charpos <= it->end_charpos));
5668 it->current.overlay_string_index = -1;
5669 it->n_overlay_strings = 0;
5670 /* If there's an empty display string on the stack, pop the
5671 stack, to resync the bidi iterator with IT's position. Such
5672 empty strings are pushed onto the stack in
5673 get_overlay_strings_1. */
5674 if (it->sp > 0 && STRINGP (it->string) && !SCHARS (it->string))
5675 pop_it (it);
5677 /* Since we've exhausted overlay strings at this buffer
5678 position, set the flag to ignore overlays until we move to
5679 another position. (The flag will be reset in
5680 next_element_from_buffer.) But don't do that if the overlay
5681 strings were loaded at position other than the current one,
5682 which could happen if we called pop_it above, or if the
5683 overlay strings were loaded by handle_invisible_prop at the
5684 beginning of invisible text. */
5685 if (it->overlay_strings_charpos == IT_CHARPOS (*it))
5686 it->ignore_overlay_strings_at_pos_p = true;
5688 /* If we're at the end of the buffer, record that we have
5689 processed the overlay strings there already, so that
5690 next_element_from_buffer doesn't try it again. */
5691 if (NILP (it->string)
5692 && IT_CHARPOS (*it) >= it->end_charpos
5693 && it->overlay_strings_charpos >= it->end_charpos)
5694 it->overlay_strings_at_end_processed_p = true;
5695 /* Note: we reset overlay_strings_charpos only here, to make
5696 sure the just-processed overlays were indeed at EOB.
5697 Otherwise, overlays on text with invisible text property,
5698 which are processed with IT's position past the invisible
5699 text, might fool us into thinking the overlays at EOB were
5700 already processed (linum-mode can cause this, for
5701 example). */
5702 it->overlay_strings_charpos = -1;
5704 else
5706 /* There are more overlay strings to process. If
5707 IT->current.overlay_string_index has advanced to a position
5708 where we must load IT->overlay_strings with more strings, do
5709 it. We must load at the IT->overlay_strings_charpos where
5710 IT->n_overlay_strings was originally computed; when invisible
5711 text is present, this might not be IT_CHARPOS (Bug#7016). */
5712 int i = it->current.overlay_string_index % OVERLAY_STRING_CHUNK_SIZE;
5714 if (it->current.overlay_string_index && i == 0)
5715 load_overlay_strings (it, it->overlay_strings_charpos);
5717 /* Initialize IT to deliver display elements from the overlay
5718 string. */
5719 it->string = it->overlay_strings[i];
5720 it->multibyte_p = STRING_MULTIBYTE (it->string);
5721 SET_TEXT_POS (it->current.string_pos, 0, 0);
5722 it->method = GET_FROM_STRING;
5723 it->stop_charpos = 0;
5724 it->end_charpos = SCHARS (it->string);
5725 if (it->cmp_it.stop_pos >= 0)
5726 it->cmp_it.stop_pos = 0;
5727 it->prev_stop = 0;
5728 it->base_level_stop = 0;
5730 /* Set up the bidi iterator for this overlay string. */
5731 if (it->bidi_p)
5733 it->bidi_it.string.lstring = it->string;
5734 it->bidi_it.string.s = NULL;
5735 it->bidi_it.string.schars = SCHARS (it->string);
5736 it->bidi_it.string.bufpos = it->overlay_strings_charpos;
5737 it->bidi_it.string.from_disp_str = it->string_from_display_prop_p;
5738 it->bidi_it.string.unibyte = !it->multibyte_p;
5739 it->bidi_it.w = it->w;
5740 bidi_init_it (0, 0, FRAME_WINDOW_P (it->f), &it->bidi_it);
5744 CHECK_IT (it);
5748 /* Compare two overlay_entry structures E1 and E2. Used as a
5749 comparison function for qsort in load_overlay_strings. Overlay
5750 strings for the same position are sorted so that
5752 1. All after-strings come in front of before-strings, except
5753 when they come from the same overlay.
5755 2. Within after-strings, strings are sorted so that overlay strings
5756 from overlays with higher priorities come first.
5758 2. Within before-strings, strings are sorted so that overlay
5759 strings from overlays with higher priorities come last.
5761 Value is analogous to strcmp. */
5764 static int
5765 compare_overlay_entries (const void *e1, const void *e2)
5767 struct overlay_entry const *entry1 = e1;
5768 struct overlay_entry const *entry2 = e2;
5769 int result;
5771 if (entry1->after_string_p != entry2->after_string_p)
5773 /* Let after-strings appear in front of before-strings if
5774 they come from different overlays. */
5775 if (EQ (entry1->overlay, entry2->overlay))
5776 result = entry1->after_string_p ? 1 : -1;
5777 else
5778 result = entry1->after_string_p ? -1 : 1;
5780 else if (entry1->priority != entry2->priority)
5782 if (entry1->after_string_p)
5783 /* After-strings sorted in order of decreasing priority. */
5784 result = entry2->priority < entry1->priority ? -1 : 1;
5785 else
5786 /* Before-strings sorted in order of increasing priority. */
5787 result = entry1->priority < entry2->priority ? -1 : 1;
5789 else
5790 result = 0;
5792 return result;
5796 /* Load the vector IT->overlay_strings with overlay strings from IT's
5797 current buffer position, or from CHARPOS if that is > 0. Set
5798 IT->n_overlays to the total number of overlay strings found.
5800 Overlay strings are processed OVERLAY_STRING_CHUNK_SIZE strings at
5801 a time. On entry into load_overlay_strings,
5802 IT->current.overlay_string_index gives the number of overlay
5803 strings that have already been loaded by previous calls to this
5804 function.
5806 IT->add_overlay_start contains an additional overlay start
5807 position to consider for taking overlay strings from, if non-zero.
5808 This position comes into play when the overlay has an `invisible'
5809 property, and both before and after-strings. When we've skipped to
5810 the end of the overlay, because of its `invisible' property, we
5811 nevertheless want its before-string to appear.
5812 IT->add_overlay_start will contain the overlay start position
5813 in this case.
5815 Overlay strings are sorted so that after-string strings come in
5816 front of before-string strings. Within before and after-strings,
5817 strings are sorted by overlay priority. See also function
5818 compare_overlay_entries. */
5820 static void
5821 load_overlay_strings (struct it *it, ptrdiff_t charpos)
5823 Lisp_Object overlay, window, str, invisible;
5824 struct Lisp_Overlay *ov;
5825 ptrdiff_t start, end;
5826 ptrdiff_t n = 0, i, j;
5827 int invis;
5828 struct overlay_entry entriesbuf[20];
5829 ptrdiff_t size = ARRAYELTS (entriesbuf);
5830 struct overlay_entry *entries = entriesbuf;
5831 USE_SAFE_ALLOCA;
5833 if (charpos <= 0)
5834 charpos = IT_CHARPOS (*it);
5836 /* Append the overlay string STRING of overlay OVERLAY to vector
5837 `entries' which has size `size' and currently contains `n'
5838 elements. AFTER_P means STRING is an after-string of
5839 OVERLAY. */
5840 #define RECORD_OVERLAY_STRING(OVERLAY, STRING, AFTER_P) \
5841 do \
5843 Lisp_Object priority; \
5845 if (n == size) \
5847 struct overlay_entry *old = entries; \
5848 SAFE_NALLOCA (entries, 2, size); \
5849 memcpy (entries, old, size * sizeof *entries); \
5850 size *= 2; \
5853 entries[n].string = (STRING); \
5854 entries[n].overlay = (OVERLAY); \
5855 priority = Foverlay_get ((OVERLAY), Qpriority); \
5856 entries[n].priority = INTEGERP (priority) ? XINT (priority) : 0; \
5857 entries[n].after_string_p = (AFTER_P); \
5858 ++n; \
5860 while (false)
5862 /* Process overlay before the overlay center. */
5863 for (ov = current_buffer->overlays_before; ov; ov = ov->next)
5865 XSETMISC (overlay, ov);
5866 eassert (OVERLAYP (overlay));
5867 start = OVERLAY_POSITION (OVERLAY_START (overlay));
5868 end = OVERLAY_POSITION (OVERLAY_END (overlay));
5870 if (end < charpos)
5871 break;
5873 /* Skip this overlay if it doesn't start or end at IT's current
5874 position. */
5875 if (end != charpos && start != charpos)
5876 continue;
5878 /* Skip this overlay if it doesn't apply to IT->w. */
5879 window = Foverlay_get (overlay, Qwindow);
5880 if (WINDOWP (window) && XWINDOW (window) != it->w)
5881 continue;
5883 /* If the text ``under'' the overlay is invisible, both before-
5884 and after-strings from this overlay are visible; start and
5885 end position are indistinguishable. */
5886 invisible = Foverlay_get (overlay, Qinvisible);
5887 invis = TEXT_PROP_MEANS_INVISIBLE (invisible);
5889 /* If overlay has a non-empty before-string, record it. */
5890 if ((start == charpos || (end == charpos && invis != 0))
5891 && (str = Foverlay_get (overlay, Qbefore_string), STRINGP (str))
5892 && SCHARS (str))
5893 RECORD_OVERLAY_STRING (overlay, str, false);
5895 /* If overlay has a non-empty after-string, record it. */
5896 if ((end == charpos || (start == charpos && invis != 0))
5897 && (str = Foverlay_get (overlay, Qafter_string), STRINGP (str))
5898 && SCHARS (str))
5899 RECORD_OVERLAY_STRING (overlay, str, true);
5902 /* Process overlays after the overlay center. */
5903 for (ov = current_buffer->overlays_after; ov; ov = ov->next)
5905 XSETMISC (overlay, ov);
5906 eassert (OVERLAYP (overlay));
5907 start = OVERLAY_POSITION (OVERLAY_START (overlay));
5908 end = OVERLAY_POSITION (OVERLAY_END (overlay));
5910 if (start > charpos)
5911 break;
5913 /* Skip this overlay if it doesn't start or end at IT's current
5914 position. */
5915 if (end != charpos && start != charpos)
5916 continue;
5918 /* Skip this overlay if it doesn't apply to IT->w. */
5919 window = Foverlay_get (overlay, Qwindow);
5920 if (WINDOWP (window) && XWINDOW (window) != it->w)
5921 continue;
5923 /* If the text ``under'' the overlay is invisible, it has a zero
5924 dimension, and both before- and after-strings apply. */
5925 invisible = Foverlay_get (overlay, Qinvisible);
5926 invis = TEXT_PROP_MEANS_INVISIBLE (invisible);
5928 /* If overlay has a non-empty before-string, record it. */
5929 if ((start == charpos || (end == charpos && invis != 0))
5930 && (str = Foverlay_get (overlay, Qbefore_string), STRINGP (str))
5931 && SCHARS (str))
5932 RECORD_OVERLAY_STRING (overlay, str, false);
5934 /* If overlay has a non-empty after-string, record it. */
5935 if ((end == charpos || (start == charpos && invis != 0))
5936 && (str = Foverlay_get (overlay, Qafter_string), STRINGP (str))
5937 && SCHARS (str))
5938 RECORD_OVERLAY_STRING (overlay, str, true);
5941 #undef RECORD_OVERLAY_STRING
5943 /* Sort entries. */
5944 if (n > 1)
5945 qsort (entries, n, sizeof *entries, compare_overlay_entries);
5947 /* Record number of overlay strings, and where we computed it. */
5948 it->n_overlay_strings = n;
5949 it->overlay_strings_charpos = charpos;
5951 /* IT->current.overlay_string_index is the number of overlay strings
5952 that have already been consumed by IT. Copy some of the
5953 remaining overlay strings to IT->overlay_strings. */
5954 i = 0;
5955 j = it->current.overlay_string_index;
5956 while (i < OVERLAY_STRING_CHUNK_SIZE && j < n)
5958 it->overlay_strings[i] = entries[j].string;
5959 it->string_overlays[i++] = entries[j++].overlay;
5962 CHECK_IT (it);
5963 SAFE_FREE ();
5967 /* Get the first chunk of overlay strings at IT's current buffer
5968 position, or at CHARPOS if that is > 0. Value is true if at
5969 least one overlay string was found. */
5971 static bool
5972 get_overlay_strings_1 (struct it *it, ptrdiff_t charpos, bool compute_stop_p)
5974 /* Get the first OVERLAY_STRING_CHUNK_SIZE overlay strings to
5975 process. This fills IT->overlay_strings with strings, and sets
5976 IT->n_overlay_strings to the total number of strings to process.
5977 IT->pos.overlay_string_index has to be set temporarily to zero
5978 because load_overlay_strings needs this; it must be set to -1
5979 when no overlay strings are found because a zero value would
5980 indicate a position in the first overlay string. */
5981 it->current.overlay_string_index = 0;
5982 load_overlay_strings (it, charpos);
5984 /* If we found overlay strings, set up IT to deliver display
5985 elements from the first one. Otherwise set up IT to deliver
5986 from current_buffer. */
5987 if (it->n_overlay_strings)
5989 /* Make sure we know settings in current_buffer, so that we can
5990 restore meaningful values when we're done with the overlay
5991 strings. */
5992 if (compute_stop_p)
5993 compute_stop_pos (it);
5994 eassert (it->face_id >= 0);
5996 /* Save IT's settings. They are restored after all overlay
5997 strings have been processed. */
5998 eassert (!compute_stop_p || it->sp == 0);
6000 /* When called from handle_stop, there might be an empty display
6001 string loaded. In that case, don't bother saving it. But
6002 don't use this optimization with the bidi iterator, since we
6003 need the corresponding pop_it call to resync the bidi
6004 iterator's position with IT's position, after we are done
6005 with the overlay strings. (The corresponding call to pop_it
6006 in case of an empty display string is in
6007 next_overlay_string.) */
6008 if (!(!it->bidi_p
6009 && STRINGP (it->string) && !SCHARS (it->string)))
6010 push_it (it, NULL);
6012 /* Set up IT to deliver display elements from the first overlay
6013 string. */
6014 IT_STRING_CHARPOS (*it) = IT_STRING_BYTEPOS (*it) = 0;
6015 it->string = it->overlay_strings[0];
6016 it->from_overlay = Qnil;
6017 it->stop_charpos = 0;
6018 eassert (STRINGP (it->string));
6019 it->end_charpos = SCHARS (it->string);
6020 it->prev_stop = 0;
6021 it->base_level_stop = 0;
6022 it->multibyte_p = STRING_MULTIBYTE (it->string);
6023 it->method = GET_FROM_STRING;
6024 it->from_disp_prop_p = 0;
6025 it->cmp_it.id = -1;
6027 /* Force paragraph direction to be that of the parent
6028 buffer. */
6029 if (it->bidi_p && it->bidi_it.paragraph_dir == R2L)
6030 it->paragraph_embedding = it->bidi_it.paragraph_dir;
6031 else
6032 it->paragraph_embedding = L2R;
6034 /* Set up the bidi iterator for this overlay string. */
6035 if (it->bidi_p)
6037 ptrdiff_t pos = (charpos > 0 ? charpos : IT_CHARPOS (*it));
6039 it->bidi_it.string.lstring = it->string;
6040 it->bidi_it.string.s = NULL;
6041 it->bidi_it.string.schars = SCHARS (it->string);
6042 it->bidi_it.string.bufpos = pos;
6043 it->bidi_it.string.from_disp_str = it->string_from_display_prop_p;
6044 it->bidi_it.string.unibyte = !it->multibyte_p;
6045 it->bidi_it.w = it->w;
6046 bidi_init_it (0, 0, FRAME_WINDOW_P (it->f), &it->bidi_it);
6048 return true;
6051 it->current.overlay_string_index = -1;
6052 return false;
6055 static bool
6056 get_overlay_strings (struct it *it, ptrdiff_t charpos)
6058 it->string = Qnil;
6059 it->method = GET_FROM_BUFFER;
6061 get_overlay_strings_1 (it, charpos, true);
6063 CHECK_IT (it);
6065 /* Value is true if we found at least one overlay string. */
6066 return STRINGP (it->string);
6071 /***********************************************************************
6072 Saving and restoring state
6073 ***********************************************************************/
6075 /* Save current settings of IT on IT->stack. Called, for example,
6076 before setting up IT for an overlay string, to be able to restore
6077 IT's settings to what they were after the overlay string has been
6078 processed. If POSITION is non-NULL, it is the position to save on
6079 the stack instead of IT->position. */
6081 static void
6082 push_it (struct it *it, struct text_pos *position)
6084 struct iterator_stack_entry *p;
6086 eassert (it->sp < IT_STACK_SIZE);
6087 p = it->stack + it->sp;
6089 p->stop_charpos = it->stop_charpos;
6090 p->prev_stop = it->prev_stop;
6091 p->base_level_stop = it->base_level_stop;
6092 p->cmp_it = it->cmp_it;
6093 eassert (it->face_id >= 0);
6094 p->face_id = it->face_id;
6095 p->string = it->string;
6096 p->method = it->method;
6097 p->from_overlay = it->from_overlay;
6098 switch (p->method)
6100 case GET_FROM_IMAGE:
6101 p->u.image.object = it->object;
6102 p->u.image.image_id = it->image_id;
6103 p->u.image.slice = it->slice;
6104 break;
6105 case GET_FROM_STRETCH:
6106 p->u.stretch.object = it->object;
6107 break;
6108 case GET_FROM_XWIDGET:
6109 p->u.xwidget.object = it->object;
6110 break;
6111 case GET_FROM_BUFFER:
6112 case GET_FROM_DISPLAY_VECTOR:
6113 case GET_FROM_STRING:
6114 case GET_FROM_C_STRING:
6115 break;
6116 default:
6117 emacs_abort ();
6119 p->position = position ? *position : it->position;
6120 p->current = it->current;
6121 p->end_charpos = it->end_charpos;
6122 p->string_nchars = it->string_nchars;
6123 p->area = it->area;
6124 p->multibyte_p = it->multibyte_p;
6125 p->avoid_cursor_p = it->avoid_cursor_p;
6126 p->space_width = it->space_width;
6127 p->font_height = it->font_height;
6128 p->voffset = it->voffset;
6129 p->string_from_display_prop_p = it->string_from_display_prop_p;
6130 p->string_from_prefix_prop_p = it->string_from_prefix_prop_p;
6131 p->display_ellipsis_p = false;
6132 p->line_wrap = it->line_wrap;
6133 p->bidi_p = it->bidi_p;
6134 p->paragraph_embedding = it->paragraph_embedding;
6135 p->from_disp_prop_p = it->from_disp_prop_p;
6136 ++it->sp;
6138 /* Save the state of the bidi iterator as well. */
6139 if (it->bidi_p)
6140 bidi_push_it (&it->bidi_it);
6143 static void
6144 iterate_out_of_display_property (struct it *it)
6146 bool buffer_p = !STRINGP (it->string);
6147 ptrdiff_t eob = (buffer_p ? ZV : it->end_charpos);
6148 ptrdiff_t bob = (buffer_p ? BEGV : 0);
6150 eassert (eob >= CHARPOS (it->position) && CHARPOS (it->position) >= bob);
6152 /* Maybe initialize paragraph direction. If we are at the beginning
6153 of a new paragraph, next_element_from_buffer may not have a
6154 chance to do that. */
6155 if (it->bidi_it.first_elt && it->bidi_it.charpos < eob)
6156 bidi_paragraph_init (it->paragraph_embedding, &it->bidi_it, true);
6157 /* prev_stop can be zero, so check against BEGV as well. */
6158 while (it->bidi_it.charpos >= bob
6159 && it->prev_stop <= it->bidi_it.charpos
6160 && it->bidi_it.charpos < CHARPOS (it->position)
6161 && it->bidi_it.charpos < eob)
6162 bidi_move_to_visually_next (&it->bidi_it);
6163 /* Record the stop_pos we just crossed, for when we cross it
6164 back, maybe. */
6165 if (it->bidi_it.charpos > CHARPOS (it->position))
6166 it->prev_stop = CHARPOS (it->position);
6167 /* If we ended up not where pop_it put us, resync IT's
6168 positional members with the bidi iterator. */
6169 if (it->bidi_it.charpos != CHARPOS (it->position))
6170 SET_TEXT_POS (it->position, it->bidi_it.charpos, it->bidi_it.bytepos);
6171 if (buffer_p)
6172 it->current.pos = it->position;
6173 else
6174 it->current.string_pos = it->position;
6177 /* Restore IT's settings from IT->stack. Called, for example, when no
6178 more overlay strings must be processed, and we return to delivering
6179 display elements from a buffer, or when the end of a string from a
6180 `display' property is reached and we return to delivering display
6181 elements from an overlay string, or from a buffer. */
6183 static void
6184 pop_it (struct it *it)
6186 struct iterator_stack_entry *p;
6187 bool from_display_prop = it->from_disp_prop_p;
6188 ptrdiff_t prev_pos = IT_CHARPOS (*it);
6190 eassert (it->sp > 0);
6191 --it->sp;
6192 p = it->stack + it->sp;
6193 it->stop_charpos = p->stop_charpos;
6194 it->prev_stop = p->prev_stop;
6195 it->base_level_stop = p->base_level_stop;
6196 it->cmp_it = p->cmp_it;
6197 it->face_id = p->face_id;
6198 it->current = p->current;
6199 it->position = p->position;
6200 it->string = p->string;
6201 it->from_overlay = p->from_overlay;
6202 if (NILP (it->string))
6203 SET_TEXT_POS (it->current.string_pos, -1, -1);
6204 it->method = p->method;
6205 switch (it->method)
6207 case GET_FROM_IMAGE:
6208 it->image_id = p->u.image.image_id;
6209 it->object = p->u.image.object;
6210 it->slice = p->u.image.slice;
6211 break;
6212 case GET_FROM_XWIDGET:
6213 it->object = p->u.xwidget.object;
6214 break;
6215 case GET_FROM_STRETCH:
6216 it->object = p->u.stretch.object;
6217 break;
6218 case GET_FROM_BUFFER:
6219 it->object = it->w->contents;
6220 break;
6221 case GET_FROM_STRING:
6223 struct face *face = FACE_FROM_ID_OR_NULL (it->f, it->face_id);
6225 /* Restore the face_box_p flag, since it could have been
6226 overwritten by the face of the object that we just finished
6227 displaying. */
6228 if (face)
6229 it->face_box_p = face->box != FACE_NO_BOX;
6230 it->object = it->string;
6232 break;
6233 case GET_FROM_DISPLAY_VECTOR:
6234 if (it->s)
6235 it->method = GET_FROM_C_STRING;
6236 else if (STRINGP (it->string))
6237 it->method = GET_FROM_STRING;
6238 else
6240 it->method = GET_FROM_BUFFER;
6241 it->object = it->w->contents;
6243 break;
6244 case GET_FROM_C_STRING:
6245 break;
6246 default:
6247 emacs_abort ();
6249 it->end_charpos = p->end_charpos;
6250 it->string_nchars = p->string_nchars;
6251 it->area = p->area;
6252 it->multibyte_p = p->multibyte_p;
6253 it->avoid_cursor_p = p->avoid_cursor_p;
6254 it->space_width = p->space_width;
6255 it->font_height = p->font_height;
6256 it->voffset = p->voffset;
6257 it->string_from_display_prop_p = p->string_from_display_prop_p;
6258 it->string_from_prefix_prop_p = p->string_from_prefix_prop_p;
6259 it->line_wrap = p->line_wrap;
6260 it->bidi_p = p->bidi_p;
6261 it->paragraph_embedding = p->paragraph_embedding;
6262 it->from_disp_prop_p = p->from_disp_prop_p;
6263 if (it->bidi_p)
6265 bidi_pop_it (&it->bidi_it);
6266 /* Bidi-iterate until we get out of the portion of text, if any,
6267 covered by a `display' text property or by an overlay with
6268 `display' property. (We cannot just jump there, because the
6269 internal coherency of the bidi iterator state can not be
6270 preserved across such jumps.) We also must determine the
6271 paragraph base direction if the overlay we just processed is
6272 at the beginning of a new paragraph. */
6273 if (from_display_prop
6274 && (it->method == GET_FROM_BUFFER || it->method == GET_FROM_STRING))
6275 iterate_out_of_display_property (it);
6277 eassert ((BUFFERP (it->object)
6278 && IT_CHARPOS (*it) == it->bidi_it.charpos
6279 && IT_BYTEPOS (*it) == it->bidi_it.bytepos)
6280 || (STRINGP (it->object)
6281 && IT_STRING_CHARPOS (*it) == it->bidi_it.charpos
6282 && IT_STRING_BYTEPOS (*it) == it->bidi_it.bytepos)
6283 || (CONSP (it->object) && it->method == GET_FROM_STRETCH));
6285 /* If we move the iterator over text covered by a display property
6286 to a new buffer position, any info about previously seen overlays
6287 is no longer valid. */
6288 if (from_display_prop && it->sp == 0 && CHARPOS (it->position) != prev_pos)
6289 it->ignore_overlay_strings_at_pos_p = false;
6294 /***********************************************************************
6295 Moving over lines
6296 ***********************************************************************/
6298 /* Set IT's current position to the previous line start. */
6300 static void
6301 back_to_previous_line_start (struct it *it)
6303 ptrdiff_t cp = IT_CHARPOS (*it), bp = IT_BYTEPOS (*it);
6305 DEC_BOTH (cp, bp);
6306 IT_CHARPOS (*it) = find_newline_no_quit (cp, bp, -1, &IT_BYTEPOS (*it));
6310 /* Move IT to the next line start.
6312 Value is true if a newline was found. Set *SKIPPED_P to true if
6313 we skipped over part of the text (as opposed to moving the iterator
6314 continuously over the text). Otherwise, don't change the value
6315 of *SKIPPED_P.
6317 If BIDI_IT_PREV is non-NULL, store into it the state of the bidi
6318 iterator on the newline, if it was found.
6320 Newlines may come from buffer text, overlay strings, or strings
6321 displayed via the `display' property. That's the reason we can't
6322 simply use find_newline_no_quit.
6324 Note that this function may not skip over invisible text that is so
6325 because of text properties and immediately follows a newline. If
6326 it would, function reseat_at_next_visible_line_start, when called
6327 from set_iterator_to_next, would effectively make invisible
6328 characters following a newline part of the wrong glyph row, which
6329 leads to wrong cursor motion. */
6331 static bool
6332 forward_to_next_line_start (struct it *it, bool *skipped_p,
6333 struct bidi_it *bidi_it_prev)
6335 ptrdiff_t old_selective;
6336 bool newline_found_p = false;
6337 int n;
6338 const int MAX_NEWLINE_DISTANCE = 500;
6340 /* If already on a newline, just consume it to avoid unintended
6341 skipping over invisible text below. */
6342 if (it->what == IT_CHARACTER
6343 && it->c == '\n'
6344 && CHARPOS (it->position) == IT_CHARPOS (*it))
6346 if (it->bidi_p && bidi_it_prev)
6347 *bidi_it_prev = it->bidi_it;
6348 set_iterator_to_next (it, false);
6349 it->c = 0;
6350 return true;
6353 /* Don't handle selective display in the following. It's (a)
6354 unnecessary because it's done by the caller, and (b) leads to an
6355 infinite recursion because next_element_from_ellipsis indirectly
6356 calls this function. */
6357 old_selective = it->selective;
6358 it->selective = 0;
6360 /* Scan for a newline within MAX_NEWLINE_DISTANCE display elements
6361 from buffer text. */
6362 for (n = 0;
6363 !newline_found_p && n < MAX_NEWLINE_DISTANCE;
6364 n += !STRINGP (it->string))
6366 if (!get_next_display_element (it))
6367 return false;
6368 newline_found_p = it->what == IT_CHARACTER && it->c == '\n';
6369 if (newline_found_p && it->bidi_p && bidi_it_prev)
6370 *bidi_it_prev = it->bidi_it;
6371 set_iterator_to_next (it, false);
6374 /* If we didn't find a newline near enough, see if we can use a
6375 short-cut. */
6376 if (!newline_found_p)
6378 ptrdiff_t bytepos, start = IT_CHARPOS (*it);
6379 ptrdiff_t limit = find_newline_no_quit (start, IT_BYTEPOS (*it),
6380 1, &bytepos);
6381 Lisp_Object pos;
6383 eassert (!STRINGP (it->string));
6385 /* If there isn't any `display' property in sight, and no
6386 overlays, we can just use the position of the newline in
6387 buffer text. */
6388 if (it->stop_charpos >= limit
6389 || ((pos = Fnext_single_property_change (make_number (start),
6390 Qdisplay, Qnil,
6391 make_number (limit)),
6392 NILP (pos))
6393 && next_overlay_change (start) == ZV))
6395 if (!it->bidi_p)
6397 IT_CHARPOS (*it) = limit;
6398 IT_BYTEPOS (*it) = bytepos;
6400 else
6402 struct bidi_it bprev;
6404 /* Help bidi.c avoid expensive searches for display
6405 properties and overlays, by telling it that there are
6406 none up to `limit'. */
6407 if (it->bidi_it.disp_pos < limit)
6409 it->bidi_it.disp_pos = limit;
6410 it->bidi_it.disp_prop = 0;
6412 do {
6413 bprev = it->bidi_it;
6414 bidi_move_to_visually_next (&it->bidi_it);
6415 } while (it->bidi_it.charpos != limit);
6416 IT_CHARPOS (*it) = limit;
6417 IT_BYTEPOS (*it) = it->bidi_it.bytepos;
6418 if (bidi_it_prev)
6419 *bidi_it_prev = bprev;
6421 *skipped_p = newline_found_p = true;
6423 else
6425 while (!newline_found_p)
6427 if (!get_next_display_element (it))
6428 break;
6429 newline_found_p = ITERATOR_AT_END_OF_LINE_P (it);
6430 if (newline_found_p && it->bidi_p && bidi_it_prev)
6431 *bidi_it_prev = it->bidi_it;
6432 set_iterator_to_next (it, false);
6437 it->selective = old_selective;
6438 return newline_found_p;
6442 /* Set IT's current position to the previous visible line start. Skip
6443 invisible text that is so either due to text properties or due to
6444 selective display. Caution: this does not change IT->current_x and
6445 IT->hpos. */
6447 static void
6448 back_to_previous_visible_line_start (struct it *it)
6450 while (IT_CHARPOS (*it) > BEGV)
6452 back_to_previous_line_start (it);
6454 if (IT_CHARPOS (*it) <= BEGV)
6455 break;
6457 /* If selective > 0, then lines indented more than its value are
6458 invisible. */
6459 if (it->selective > 0
6460 && indented_beyond_p (IT_CHARPOS (*it), IT_BYTEPOS (*it),
6461 it->selective))
6462 continue;
6464 /* Check the newline before point for invisibility. */
6466 Lisp_Object prop;
6467 prop = Fget_char_property (make_number (IT_CHARPOS (*it) - 1),
6468 Qinvisible, it->window);
6469 if (TEXT_PROP_MEANS_INVISIBLE (prop) != 0)
6470 continue;
6473 if (IT_CHARPOS (*it) <= BEGV)
6474 break;
6477 struct it it2;
6478 void *it2data = NULL;
6479 ptrdiff_t pos;
6480 ptrdiff_t beg, end;
6481 Lisp_Object val, overlay;
6483 SAVE_IT (it2, *it, it2data);
6485 /* If newline is part of a composition, continue from start of composition */
6486 if (find_composition (IT_CHARPOS (*it), -1, &beg, &end, &val, Qnil)
6487 && beg < IT_CHARPOS (*it))
6488 goto replaced;
6490 /* If newline is replaced by a display property, find start of overlay
6491 or interval and continue search from that point. */
6492 pos = --IT_CHARPOS (it2);
6493 --IT_BYTEPOS (it2);
6494 it2.sp = 0;
6495 bidi_unshelve_cache (NULL, false);
6496 it2.string_from_display_prop_p = false;
6497 it2.from_disp_prop_p = false;
6498 if (handle_display_prop (&it2) == HANDLED_RETURN
6499 && !NILP (val = get_char_property_and_overlay
6500 (make_number (pos), Qdisplay, Qnil, &overlay))
6501 && (OVERLAYP (overlay)
6502 ? (beg = OVERLAY_POSITION (OVERLAY_START (overlay)))
6503 : get_property_and_range (pos, Qdisplay, &val, &beg, &end, Qnil)))
6505 RESTORE_IT (it, it, it2data);
6506 goto replaced;
6509 /* Newline is not replaced by anything -- so we are done. */
6510 RESTORE_IT (it, it, it2data);
6511 break;
6513 replaced:
6514 if (beg < BEGV)
6515 beg = BEGV;
6516 IT_CHARPOS (*it) = beg;
6517 IT_BYTEPOS (*it) = buf_charpos_to_bytepos (current_buffer, beg);
6521 it->continuation_lines_width = 0;
6523 eassert (IT_CHARPOS (*it) >= BEGV);
6524 eassert (IT_CHARPOS (*it) == BEGV
6525 || FETCH_BYTE (IT_BYTEPOS (*it) - 1) == '\n');
6526 CHECK_IT (it);
6530 /* Reseat iterator IT at the previous visible line start. Skip
6531 invisible text that is so either due to text properties or due to
6532 selective display. At the end, update IT's overlay information,
6533 face information etc. */
6535 void
6536 reseat_at_previous_visible_line_start (struct it *it)
6538 back_to_previous_visible_line_start (it);
6539 reseat (it, it->current.pos, true);
6540 CHECK_IT (it);
6544 /* Reseat iterator IT on the next visible line start in the current
6545 buffer. ON_NEWLINE_P means position IT on the newline
6546 preceding the line start. Skip over invisible text that is so
6547 because of selective display. Compute faces, overlays etc at the
6548 new position. Note that this function does not skip over text that
6549 is invisible because of text properties. */
6551 static void
6552 reseat_at_next_visible_line_start (struct it *it, bool on_newline_p)
6554 bool skipped_p = false;
6555 struct bidi_it bidi_it_prev;
6556 bool newline_found_p
6557 = forward_to_next_line_start (it, &skipped_p, &bidi_it_prev);
6559 /* Skip over lines that are invisible because they are indented
6560 more than the value of IT->selective. */
6561 if (it->selective > 0)
6562 while (IT_CHARPOS (*it) < ZV
6563 && indented_beyond_p (IT_CHARPOS (*it), IT_BYTEPOS (*it),
6564 it->selective))
6566 eassert (IT_BYTEPOS (*it) == BEGV
6567 || FETCH_BYTE (IT_BYTEPOS (*it) - 1) == '\n');
6568 newline_found_p =
6569 forward_to_next_line_start (it, &skipped_p, &bidi_it_prev);
6572 /* Position on the newline if that's what's requested. */
6573 if (on_newline_p && newline_found_p)
6575 if (STRINGP (it->string))
6577 if (IT_STRING_CHARPOS (*it) > 0)
6579 if (!it->bidi_p)
6581 --IT_STRING_CHARPOS (*it);
6582 --IT_STRING_BYTEPOS (*it);
6584 else
6586 /* We need to restore the bidi iterator to the state
6587 it had on the newline, and resync the IT's
6588 position with that. */
6589 it->bidi_it = bidi_it_prev;
6590 IT_STRING_CHARPOS (*it) = it->bidi_it.charpos;
6591 IT_STRING_BYTEPOS (*it) = it->bidi_it.bytepos;
6595 else if (IT_CHARPOS (*it) > BEGV)
6597 if (!it->bidi_p)
6599 --IT_CHARPOS (*it);
6600 --IT_BYTEPOS (*it);
6602 else
6604 /* We need to restore the bidi iterator to the state it
6605 had on the newline and resync IT with that. */
6606 it->bidi_it = bidi_it_prev;
6607 IT_CHARPOS (*it) = it->bidi_it.charpos;
6608 IT_BYTEPOS (*it) = it->bidi_it.bytepos;
6610 reseat (it, it->current.pos, false);
6613 else if (skipped_p)
6614 reseat (it, it->current.pos, false);
6616 CHECK_IT (it);
6621 /***********************************************************************
6622 Changing an iterator's position
6623 ***********************************************************************/
6625 /* Change IT's current position to POS in current_buffer.
6626 If FORCE_P, always check for text properties at the new position.
6627 Otherwise, text properties are only looked up if POS >=
6628 IT->check_charpos of a property. */
6630 static void
6631 reseat (struct it *it, struct text_pos pos, bool force_p)
6633 ptrdiff_t original_pos = IT_CHARPOS (*it);
6635 reseat_1 (it, pos, false);
6637 /* Determine where to check text properties. Avoid doing it
6638 where possible because text property lookup is very expensive. */
6639 if (force_p
6640 || CHARPOS (pos) > it->stop_charpos
6641 || CHARPOS (pos) < original_pos)
6643 if (it->bidi_p)
6645 /* For bidi iteration, we need to prime prev_stop and
6646 base_level_stop with our best estimations. */
6647 /* Implementation note: Of course, POS is not necessarily a
6648 stop position, so assigning prev_pos to it is a lie; we
6649 should have called compute_stop_backwards. However, if
6650 the current buffer does not include any R2L characters,
6651 that call would be a waste of cycles, because the
6652 iterator will never move back, and thus never cross this
6653 "fake" stop position. So we delay that backward search
6654 until the time we really need it, in next_element_from_buffer. */
6655 if (CHARPOS (pos) != it->prev_stop)
6656 it->prev_stop = CHARPOS (pos);
6657 if (CHARPOS (pos) < it->base_level_stop)
6658 it->base_level_stop = 0; /* meaning it's unknown */
6659 handle_stop (it);
6661 else
6663 handle_stop (it);
6664 it->prev_stop = it->base_level_stop = 0;
6669 CHECK_IT (it);
6673 /* Change IT's buffer position to POS. SET_STOP_P means set
6674 IT->stop_pos to POS, also. */
6676 static void
6677 reseat_1 (struct it *it, struct text_pos pos, bool set_stop_p)
6679 /* Don't call this function when scanning a C string. */
6680 eassert (it->s == NULL);
6682 /* POS must be a reasonable value. */
6683 eassert (CHARPOS (pos) >= BEGV && CHARPOS (pos) <= ZV);
6685 it->current.pos = it->position = pos;
6686 it->end_charpos = ZV;
6687 it->dpvec = NULL;
6688 it->current.dpvec_index = -1;
6689 it->current.overlay_string_index = -1;
6690 IT_STRING_CHARPOS (*it) = -1;
6691 IT_STRING_BYTEPOS (*it) = -1;
6692 it->string = Qnil;
6693 it->method = GET_FROM_BUFFER;
6694 it->object = it->w->contents;
6695 it->area = TEXT_AREA;
6696 it->multibyte_p = !NILP (BVAR (current_buffer, enable_multibyte_characters));
6697 it->sp = 0;
6698 it->string_from_display_prop_p = false;
6699 it->string_from_prefix_prop_p = false;
6701 it->from_disp_prop_p = false;
6702 it->face_before_selective_p = false;
6703 if (it->bidi_p)
6705 bidi_init_it (IT_CHARPOS (*it), IT_BYTEPOS (*it), FRAME_WINDOW_P (it->f),
6706 &it->bidi_it);
6707 bidi_unshelve_cache (NULL, false);
6708 it->bidi_it.paragraph_dir = NEUTRAL_DIR;
6709 it->bidi_it.string.s = NULL;
6710 it->bidi_it.string.lstring = Qnil;
6711 it->bidi_it.string.bufpos = 0;
6712 it->bidi_it.string.from_disp_str = false;
6713 it->bidi_it.string.unibyte = false;
6714 it->bidi_it.w = it->w;
6717 if (set_stop_p)
6719 it->stop_charpos = CHARPOS (pos);
6720 it->base_level_stop = CHARPOS (pos);
6722 /* This make the information stored in it->cmp_it invalidate. */
6723 it->cmp_it.id = -1;
6727 /* Set up IT for displaying a string, starting at CHARPOS in window W.
6728 If S is non-null, it is a C string to iterate over. Otherwise,
6729 STRING gives a Lisp string to iterate over.
6731 If PRECISION > 0, don't return more then PRECISION number of
6732 characters from the string.
6734 If FIELD_WIDTH > 0, return padding spaces until FIELD_WIDTH
6735 characters have been returned. FIELD_WIDTH < 0 means an infinite
6736 field width.
6738 MULTIBYTE = 0 means disable processing of multibyte characters,
6739 MULTIBYTE > 0 means enable it,
6740 MULTIBYTE < 0 means use IT->multibyte_p.
6742 IT must be initialized via a prior call to init_iterator before
6743 calling this function. */
6745 static void
6746 reseat_to_string (struct it *it, const char *s, Lisp_Object string,
6747 ptrdiff_t charpos, ptrdiff_t precision, int field_width,
6748 int multibyte)
6750 /* No text property checks performed by default, but see below. */
6751 it->stop_charpos = -1;
6753 /* Set iterator position and end position. */
6754 memset (&it->current, 0, sizeof it->current);
6755 it->current.overlay_string_index = -1;
6756 it->current.dpvec_index = -1;
6757 eassert (charpos >= 0);
6759 /* If STRING is specified, use its multibyteness, otherwise use the
6760 setting of MULTIBYTE, if specified. */
6761 if (multibyte >= 0)
6762 it->multibyte_p = multibyte > 0;
6764 /* Bidirectional reordering of strings is controlled by the default
6765 value of bidi-display-reordering. Don't try to reorder while
6766 loading loadup.el, as the necessary character property tables are
6767 not yet available. */
6768 it->bidi_p =
6769 !redisplay__inhibit_bidi
6770 && !NILP (BVAR (&buffer_defaults, bidi_display_reordering));
6772 if (s == NULL)
6774 eassert (STRINGP (string));
6775 it->string = string;
6776 it->s = NULL;
6777 it->end_charpos = it->string_nchars = SCHARS (string);
6778 it->method = GET_FROM_STRING;
6779 it->current.string_pos = string_pos (charpos, string);
6781 if (it->bidi_p)
6783 it->bidi_it.string.lstring = string;
6784 it->bidi_it.string.s = NULL;
6785 it->bidi_it.string.schars = it->end_charpos;
6786 it->bidi_it.string.bufpos = 0;
6787 it->bidi_it.string.from_disp_str = false;
6788 it->bidi_it.string.unibyte = !it->multibyte_p;
6789 it->bidi_it.w = it->w;
6790 bidi_init_it (charpos, IT_STRING_BYTEPOS (*it),
6791 FRAME_WINDOW_P (it->f), &it->bidi_it);
6794 else
6796 it->s = (const unsigned char *) s;
6797 it->string = Qnil;
6799 /* Note that we use IT->current.pos, not it->current.string_pos,
6800 for displaying C strings. */
6801 IT_STRING_CHARPOS (*it) = IT_STRING_BYTEPOS (*it) = -1;
6802 if (it->multibyte_p)
6804 it->current.pos = c_string_pos (charpos, s, true);
6805 it->end_charpos = it->string_nchars = number_of_chars (s, true);
6807 else
6809 IT_CHARPOS (*it) = IT_BYTEPOS (*it) = charpos;
6810 it->end_charpos = it->string_nchars = strlen (s);
6813 if (it->bidi_p)
6815 it->bidi_it.string.lstring = Qnil;
6816 it->bidi_it.string.s = (const unsigned char *) s;
6817 it->bidi_it.string.schars = it->end_charpos;
6818 it->bidi_it.string.bufpos = 0;
6819 it->bidi_it.string.from_disp_str = false;
6820 it->bidi_it.string.unibyte = !it->multibyte_p;
6821 it->bidi_it.w = it->w;
6822 bidi_init_it (charpos, IT_BYTEPOS (*it), FRAME_WINDOW_P (it->f),
6823 &it->bidi_it);
6825 it->method = GET_FROM_C_STRING;
6828 /* PRECISION > 0 means don't return more than PRECISION characters
6829 from the string. */
6830 if (precision > 0 && it->end_charpos - charpos > precision)
6832 it->end_charpos = it->string_nchars = charpos + precision;
6833 if (it->bidi_p)
6834 it->bidi_it.string.schars = it->end_charpos;
6837 /* FIELD_WIDTH > 0 means pad with spaces until FIELD_WIDTH
6838 characters have been returned. FIELD_WIDTH == 0 means don't pad,
6839 FIELD_WIDTH < 0 means infinite field width. This is useful for
6840 padding with `-' at the end of a mode line. */
6841 if (field_width < 0)
6842 field_width = DISP_INFINITY;
6843 /* Implementation note: We deliberately don't enlarge
6844 it->bidi_it.string.schars here to fit it->end_charpos, because
6845 the bidi iterator cannot produce characters out of thin air. */
6846 if (field_width > it->end_charpos - charpos)
6847 it->end_charpos = charpos + field_width;
6849 /* Use the standard display table for displaying strings. */
6850 if (DISP_TABLE_P (Vstandard_display_table))
6851 it->dp = XCHAR_TABLE (Vstandard_display_table);
6853 it->stop_charpos = charpos;
6854 it->prev_stop = charpos;
6855 it->base_level_stop = 0;
6856 if (it->bidi_p)
6858 it->bidi_it.first_elt = true;
6859 it->bidi_it.paragraph_dir = NEUTRAL_DIR;
6860 it->bidi_it.disp_pos = -1;
6862 if (s == NULL && it->multibyte_p)
6864 ptrdiff_t endpos = SCHARS (it->string);
6865 if (endpos > it->end_charpos)
6866 endpos = it->end_charpos;
6867 composition_compute_stop_pos (&it->cmp_it, charpos, -1, endpos,
6868 it->string);
6870 CHECK_IT (it);
6875 /***********************************************************************
6876 Iteration
6877 ***********************************************************************/
6879 /* Map enum it_method value to corresponding next_element_from_* function. */
6881 typedef bool (*next_element_function) (struct it *);
6883 static next_element_function const get_next_element[NUM_IT_METHODS] =
6885 next_element_from_buffer,
6886 next_element_from_display_vector,
6887 next_element_from_string,
6888 next_element_from_c_string,
6889 next_element_from_image,
6890 next_element_from_stretch,
6891 next_element_from_xwidget,
6894 #define GET_NEXT_DISPLAY_ELEMENT(it) (*get_next_element[(it)->method]) (it)
6897 /* Return true iff a character at CHARPOS (and BYTEPOS) is composed
6898 (possibly with the following characters). */
6900 #define CHAR_COMPOSED_P(IT,CHARPOS,BYTEPOS,END_CHARPOS) \
6901 ((IT)->cmp_it.id >= 0 \
6902 || ((IT)->cmp_it.stop_pos == (CHARPOS) \
6903 && composition_reseat_it (&(IT)->cmp_it, CHARPOS, BYTEPOS, \
6904 END_CHARPOS, (IT)->w, \
6905 FACE_FROM_ID_OR_NULL ((IT)->f, \
6906 (IT)->face_id), \
6907 (IT)->string)))
6910 /* Lookup the char-table Vglyphless_char_display for character C (-1
6911 if we want information for no-font case), and return the display
6912 method symbol. By side-effect, update it->what and
6913 it->glyphless_method. This function is called from
6914 get_next_display_element for each character element, and from
6915 x_produce_glyphs when no suitable font was found. */
6917 Lisp_Object
6918 lookup_glyphless_char_display (int c, struct it *it)
6920 Lisp_Object glyphless_method = Qnil;
6922 if (CHAR_TABLE_P (Vglyphless_char_display)
6923 && CHAR_TABLE_EXTRA_SLOTS (XCHAR_TABLE (Vglyphless_char_display)) >= 1)
6925 if (c >= 0)
6927 glyphless_method = CHAR_TABLE_REF (Vglyphless_char_display, c);
6928 if (CONSP (glyphless_method))
6929 glyphless_method = FRAME_WINDOW_P (it->f)
6930 ? XCAR (glyphless_method)
6931 : XCDR (glyphless_method);
6933 else
6934 glyphless_method = XCHAR_TABLE (Vglyphless_char_display)->extras[0];
6937 retry:
6938 if (NILP (glyphless_method))
6940 if (c >= 0)
6941 /* The default is to display the character by a proper font. */
6942 return Qnil;
6943 /* The default for the no-font case is to display an empty box. */
6944 glyphless_method = Qempty_box;
6946 if (EQ (glyphless_method, Qzero_width))
6948 if (c >= 0)
6949 return glyphless_method;
6950 /* This method can't be used for the no-font case. */
6951 glyphless_method = Qempty_box;
6953 if (EQ (glyphless_method, Qthin_space))
6954 it->glyphless_method = GLYPHLESS_DISPLAY_THIN_SPACE;
6955 else if (EQ (glyphless_method, Qempty_box))
6956 it->glyphless_method = GLYPHLESS_DISPLAY_EMPTY_BOX;
6957 else if (EQ (glyphless_method, Qhex_code))
6958 it->glyphless_method = GLYPHLESS_DISPLAY_HEX_CODE;
6959 else if (STRINGP (glyphless_method))
6960 it->glyphless_method = GLYPHLESS_DISPLAY_ACRONYM;
6961 else
6963 /* Invalid value. We use the default method. */
6964 glyphless_method = Qnil;
6965 goto retry;
6967 it->what = IT_GLYPHLESS;
6968 return glyphless_method;
6971 /* Merge escape glyph face and cache the result. */
6973 static struct frame *last_escape_glyph_frame = NULL;
6974 static int last_escape_glyph_face_id = (1 << FACE_ID_BITS);
6975 static int last_escape_glyph_merged_face_id = 0;
6977 static int
6978 merge_escape_glyph_face (struct it *it)
6980 int face_id;
6982 if (it->f == last_escape_glyph_frame
6983 && it->face_id == last_escape_glyph_face_id)
6984 face_id = last_escape_glyph_merged_face_id;
6985 else
6987 /* Merge the `escape-glyph' face into the current face. */
6988 face_id = merge_faces (it->w, Qescape_glyph, 0, it->face_id);
6989 last_escape_glyph_frame = it->f;
6990 last_escape_glyph_face_id = it->face_id;
6991 last_escape_glyph_merged_face_id = face_id;
6993 return face_id;
6996 /* Likewise for glyphless glyph face. */
6998 static struct frame *last_glyphless_glyph_frame = NULL;
6999 static int last_glyphless_glyph_face_id = (1 << FACE_ID_BITS);
7000 static int last_glyphless_glyph_merged_face_id = 0;
7003 merge_glyphless_glyph_face (struct it *it)
7005 int face_id;
7007 if (it->f == last_glyphless_glyph_frame
7008 && it->face_id == last_glyphless_glyph_face_id)
7009 face_id = last_glyphless_glyph_merged_face_id;
7010 else
7012 /* Merge the `glyphless-char' face into the current face. */
7013 face_id = merge_faces (it->w, Qglyphless_char, 0, it->face_id);
7014 last_glyphless_glyph_frame = it->f;
7015 last_glyphless_glyph_face_id = it->face_id;
7016 last_glyphless_glyph_merged_face_id = face_id;
7018 return face_id;
7021 /* Forget the `escape-glyph' and `glyphless-char' faces. This should
7022 be called before redisplaying windows, and when the frame's face
7023 cache is freed. */
7024 void
7025 forget_escape_and_glyphless_faces (void)
7027 last_escape_glyph_frame = NULL;
7028 last_escape_glyph_face_id = (1 << FACE_ID_BITS);
7029 last_glyphless_glyph_frame = NULL;
7030 last_glyphless_glyph_face_id = (1 << FACE_ID_BITS);
7033 /* Load IT's display element fields with information about the next
7034 display element from the current position of IT. Value is false if
7035 end of buffer (or C string) is reached. */
7037 static bool
7038 get_next_display_element (struct it *it)
7040 /* True means that we found a display element. False means that
7041 we hit the end of what we iterate over. Performance note: the
7042 function pointer `method' used here turns out to be faster than
7043 using a sequence of if-statements. */
7044 bool success_p;
7046 get_next:
7047 success_p = GET_NEXT_DISPLAY_ELEMENT (it);
7049 if (it->what == IT_CHARACTER)
7051 /* UAX#9, L4: "A character is depicted by a mirrored glyph if
7052 and only if (a) the resolved directionality of that character
7053 is R..." */
7054 /* FIXME: Do we need an exception for characters from display
7055 tables? */
7056 if (it->bidi_p && it->bidi_it.type == STRONG_R
7057 && !inhibit_bidi_mirroring)
7058 it->c = bidi_mirror_char (it->c);
7059 /* Map via display table or translate control characters.
7060 IT->c, IT->len etc. have been set to the next character by
7061 the function call above. If we have a display table, and it
7062 contains an entry for IT->c, translate it. Don't do this if
7063 IT->c itself comes from a display table, otherwise we could
7064 end up in an infinite recursion. (An alternative could be to
7065 count the recursion depth of this function and signal an
7066 error when a certain maximum depth is reached.) Is it worth
7067 it? */
7068 if (success_p && it->dpvec == NULL)
7070 Lisp_Object dv;
7071 struct charset *unibyte = CHARSET_FROM_ID (charset_unibyte);
7072 bool nonascii_space_p = false;
7073 bool nonascii_hyphen_p = false;
7074 int c = it->c; /* This is the character to display. */
7076 if (! it->multibyte_p && ! ASCII_CHAR_P (c))
7078 eassert (SINGLE_BYTE_CHAR_P (c));
7079 if (unibyte_display_via_language_environment)
7081 c = DECODE_CHAR (unibyte, c);
7082 if (c < 0)
7083 c = BYTE8_TO_CHAR (it->c);
7085 else
7086 c = BYTE8_TO_CHAR (it->c);
7089 if (it->dp
7090 && (dv = DISP_CHAR_VECTOR (it->dp, c),
7091 VECTORP (dv)))
7093 struct Lisp_Vector *v = XVECTOR (dv);
7095 /* Return the first character from the display table
7096 entry, if not empty. If empty, don't display the
7097 current character. */
7098 if (v->header.size)
7100 it->dpvec_char_len = it->len;
7101 it->dpvec = v->contents;
7102 it->dpend = v->contents + v->header.size;
7103 it->current.dpvec_index = 0;
7104 it->dpvec_face_id = -1;
7105 it->saved_face_id = it->face_id;
7106 it->method = GET_FROM_DISPLAY_VECTOR;
7107 it->ellipsis_p = false;
7109 else
7111 set_iterator_to_next (it, false);
7113 goto get_next;
7116 if (! NILP (lookup_glyphless_char_display (c, it)))
7118 if (it->what == IT_GLYPHLESS)
7119 goto done;
7120 /* Don't display this character. */
7121 set_iterator_to_next (it, false);
7122 goto get_next;
7125 /* If `nobreak-char-display' is non-nil, we display
7126 non-ASCII spaces and hyphens specially. */
7127 if (! ASCII_CHAR_P (c) && ! NILP (Vnobreak_char_display))
7129 if (c == NO_BREAK_SPACE)
7130 nonascii_space_p = true;
7131 else if (c == SOFT_HYPHEN || c == HYPHEN
7132 || c == NON_BREAKING_HYPHEN)
7133 nonascii_hyphen_p = true;
7136 /* Translate control characters into `\003' or `^C' form.
7137 Control characters coming from a display table entry are
7138 currently not translated because we use IT->dpvec to hold
7139 the translation. This could easily be changed but I
7140 don't believe that it is worth doing.
7142 The characters handled by `nobreak-char-display' must be
7143 translated too.
7145 Non-printable characters and raw-byte characters are also
7146 translated to octal or hexadecimal form. */
7147 if (((c < ' ' || c == 127) /* ASCII control chars. */
7148 ? (it->area != TEXT_AREA
7149 /* In mode line, treat \n, \t like other crl chars. */
7150 || (c != '\t'
7151 && it->glyph_row
7152 && (it->glyph_row->mode_line_p || it->avoid_cursor_p))
7153 || (c != '\n' && c != '\t'))
7154 : (nonascii_space_p
7155 || nonascii_hyphen_p
7156 || CHAR_BYTE8_P (c)
7157 || ! CHAR_PRINTABLE_P (c))))
7159 /* C is a control character, non-ASCII space/hyphen,
7160 raw-byte, or a non-printable character which must be
7161 displayed either as '\003' or as `^C' where the '\\'
7162 and '^' can be defined in the display table. Fill
7163 IT->ctl_chars with glyphs for what we have to
7164 display. Then, set IT->dpvec to these glyphs. */
7165 Lisp_Object gc;
7166 int ctl_len;
7167 int face_id;
7168 int lface_id = 0;
7169 int escape_glyph;
7171 /* Handle control characters with ^. */
7173 if (ASCII_CHAR_P (c) && it->ctl_arrow_p)
7175 int g;
7177 g = '^'; /* default glyph for Control */
7178 /* Set IT->ctl_chars[0] to the glyph for `^'. */
7179 if (it->dp
7180 && (gc = DISP_CTRL_GLYPH (it->dp), GLYPH_CODE_P (gc)))
7182 g = GLYPH_CODE_CHAR (gc);
7183 lface_id = GLYPH_CODE_FACE (gc);
7186 face_id = (lface_id
7187 ? merge_faces (it->w, Qt, lface_id, it->face_id)
7188 : merge_escape_glyph_face (it));
7190 XSETINT (it->ctl_chars[0], g);
7191 XSETINT (it->ctl_chars[1], c ^ 0100);
7192 ctl_len = 2;
7193 goto display_control;
7196 /* Handle non-ascii space in the mode where it only gets
7197 highlighting. */
7199 if (nonascii_space_p && EQ (Vnobreak_char_display, Qt))
7201 /* Merge `nobreak-space' into the current face. */
7202 face_id = merge_faces (it->w, Qnobreak_space, 0,
7203 it->face_id);
7204 XSETINT (it->ctl_chars[0], ' ');
7205 ctl_len = 1;
7206 goto display_control;
7209 /* Handle non-ascii hyphens in the mode where it only
7210 gets highlighting. */
7212 if (nonascii_hyphen_p && EQ (Vnobreak_char_display, Qt))
7214 /* Merge `nobreak-space' into the current face. */
7215 face_id = merge_faces (it->w, Qnobreak_hyphen, 0,
7216 it->face_id);
7217 XSETINT (it->ctl_chars[0], '-');
7218 ctl_len = 1;
7219 goto display_control;
7222 /* Handle sequences that start with the "escape glyph". */
7224 /* the default escape glyph is \. */
7225 escape_glyph = '\\';
7227 if (it->dp
7228 && (gc = DISP_ESCAPE_GLYPH (it->dp), GLYPH_CODE_P (gc)))
7230 escape_glyph = GLYPH_CODE_CHAR (gc);
7231 lface_id = GLYPH_CODE_FACE (gc);
7234 face_id = (lface_id
7235 ? merge_faces (it->w, Qt, lface_id, it->face_id)
7236 : merge_escape_glyph_face (it));
7238 /* Draw non-ASCII space/hyphen with escape glyph: */
7240 if (nonascii_space_p || nonascii_hyphen_p)
7242 XSETINT (it->ctl_chars[0], escape_glyph);
7243 XSETINT (it->ctl_chars[1], nonascii_space_p ? ' ' : '-');
7244 ctl_len = 2;
7245 goto display_control;
7249 char str[10];
7250 int len, i;
7252 if (CHAR_BYTE8_P (c))
7253 /* Display \200 or \x80 instead of \17777600. */
7254 c = CHAR_TO_BYTE8 (c);
7255 const char *format_string = display_raw_bytes_as_hex
7256 ? "x%02x"
7257 : "%03o";
7258 len = sprintf (str, format_string, c + 0u);
7260 XSETINT (it->ctl_chars[0], escape_glyph);
7261 for (i = 0; i < len; i++)
7262 XSETINT (it->ctl_chars[i + 1], str[i]);
7263 ctl_len = len + 1;
7266 display_control:
7267 /* Set up IT->dpvec and return first character from it. */
7268 it->dpvec_char_len = it->len;
7269 it->dpvec = it->ctl_chars;
7270 it->dpend = it->dpvec + ctl_len;
7271 it->current.dpvec_index = 0;
7272 it->dpvec_face_id = face_id;
7273 it->saved_face_id = it->face_id;
7274 it->method = GET_FROM_DISPLAY_VECTOR;
7275 it->ellipsis_p = false;
7276 goto get_next;
7278 it->char_to_display = c;
7280 else if (success_p)
7282 it->char_to_display = it->c;
7286 #ifdef HAVE_WINDOW_SYSTEM
7287 /* Adjust face id for a multibyte character. There are no multibyte
7288 character in unibyte text. */
7289 if ((it->what == IT_CHARACTER || it->what == IT_COMPOSITION)
7290 && it->multibyte_p
7291 && success_p
7292 && FRAME_WINDOW_P (it->f))
7294 struct face *face = FACE_FROM_ID (it->f, it->face_id);
7296 if (it->what == IT_COMPOSITION && it->cmp_it.ch >= 0)
7298 /* Automatic composition with glyph-string. */
7299 Lisp_Object gstring = composition_gstring_from_id (it->cmp_it.id);
7301 it->face_id = face_for_font (it->f, LGSTRING_FONT (gstring), face);
7303 else
7305 ptrdiff_t pos = (it->s ? -1
7306 : STRINGP (it->string) ? IT_STRING_CHARPOS (*it)
7307 : IT_CHARPOS (*it));
7308 int c;
7310 if (it->what == IT_CHARACTER)
7311 c = it->char_to_display;
7312 else
7314 struct composition *cmp = composition_table[it->cmp_it.id];
7315 int i;
7317 c = ' ';
7318 for (i = 0; i < cmp->glyph_len; i++)
7319 /* TAB in a composition means display glyphs with
7320 padding space on the left or right. */
7321 if ((c = COMPOSITION_GLYPH (cmp, i)) != '\t')
7322 break;
7324 it->face_id = FACE_FOR_CHAR (it->f, face, c, pos, it->string);
7327 #endif /* HAVE_WINDOW_SYSTEM */
7329 done:
7330 /* Is this character the last one of a run of characters with
7331 box? If yes, set IT->end_of_box_run_p to true. */
7332 if (it->face_box_p
7333 && it->s == NULL)
7335 if (it->method == GET_FROM_STRING && it->sp)
7337 int face_id = underlying_face_id (it);
7338 struct face *face = FACE_FROM_ID_OR_NULL (it->f, face_id);
7340 if (face)
7342 if (face->box == FACE_NO_BOX)
7344 /* If the box comes from face properties in a
7345 display string, check faces in that string. */
7346 int string_face_id = face_after_it_pos (it);
7347 it->end_of_box_run_p
7348 = (FACE_FROM_ID (it->f, string_face_id)->box
7349 == FACE_NO_BOX);
7351 /* Otherwise, the box comes from the underlying face.
7352 If this is the last string character displayed, check
7353 the next buffer location. */
7354 else if ((IT_STRING_CHARPOS (*it) >= SCHARS (it->string) - 1)
7355 /* n_overlay_strings is unreliable unless
7356 overlay_string_index is non-negative. */
7357 && ((it->current.overlay_string_index >= 0
7358 && (it->current.overlay_string_index
7359 == it->n_overlay_strings - 1))
7360 /* A string from display property. */
7361 || it->from_disp_prop_p))
7363 ptrdiff_t ignore;
7364 int next_face_id;
7365 bool text_from_string = false;
7366 /* Normally, the next buffer location is stored in
7367 IT->current.pos... */
7368 struct text_pos pos = it->current.pos;
7370 /* ...but for a string from a display property, the
7371 next buffer position is stored in the 'position'
7372 member of the iteration stack slot below the
7373 current one, see handle_single_display_spec. By
7374 contrast, it->current.pos was not yet updated to
7375 point to that buffer position; that will happen
7376 in pop_it, after we finish displaying the current
7377 string. Note that we already checked above that
7378 it->sp is positive, so subtracting one from it is
7379 safe. */
7380 if (it->from_disp_prop_p)
7382 int stackp = it->sp - 1;
7384 /* Find the stack level with data from buffer. */
7385 while (stackp >= 0
7386 && STRINGP ((it->stack + stackp)->string))
7387 stackp--;
7388 if (stackp < 0)
7390 /* If no stack slot was found for iterating
7391 a buffer, we are displaying text from a
7392 string, most probably the mode line or
7393 the header line, and that string has a
7394 display string on some of its
7395 characters. */
7396 text_from_string = true;
7397 pos = it->stack[it->sp - 1].position;
7399 else
7400 pos = (it->stack + stackp)->position;
7402 else
7403 INC_TEXT_POS (pos, it->multibyte_p);
7405 if (text_from_string)
7407 Lisp_Object base_string = it->stack[it->sp - 1].string;
7409 if (CHARPOS (pos) >= SCHARS (base_string) - 1)
7410 it->end_of_box_run_p = true;
7411 else
7413 next_face_id
7414 = face_at_string_position (it->w, base_string,
7415 CHARPOS (pos), 0,
7416 &ignore, face_id, false);
7417 it->end_of_box_run_p
7418 = (FACE_FROM_ID (it->f, next_face_id)->box
7419 == FACE_NO_BOX);
7422 else if (CHARPOS (pos) >= ZV)
7423 it->end_of_box_run_p = true;
7424 else
7426 next_face_id =
7427 face_at_buffer_position (it->w, CHARPOS (pos), &ignore,
7428 CHARPOS (pos)
7429 + TEXT_PROP_DISTANCE_LIMIT,
7430 false, -1);
7431 it->end_of_box_run_p
7432 = (FACE_FROM_ID (it->f, next_face_id)->box
7433 == FACE_NO_BOX);
7438 /* next_element_from_display_vector sets this flag according to
7439 faces of the display vector glyphs, see there. */
7440 else if (it->method != GET_FROM_DISPLAY_VECTOR)
7442 int face_id = face_after_it_pos (it);
7443 it->end_of_box_run_p
7444 = (face_id != it->face_id
7445 && FACE_FROM_ID (it->f, face_id)->box == FACE_NO_BOX);
7448 /* If we reached the end of the object we've been iterating (e.g., a
7449 display string or an overlay string), and there's something on
7450 IT->stack, proceed with what's on the stack. It doesn't make
7451 sense to return false if there's unprocessed stuff on the stack,
7452 because otherwise that stuff will never be displayed. */
7453 if (!success_p && it->sp > 0)
7455 set_iterator_to_next (it, false);
7456 success_p = get_next_display_element (it);
7459 /* Value is false if end of buffer or string reached. */
7460 return success_p;
7464 /* Move IT to the next display element.
7466 RESEAT_P means if called on a newline in buffer text,
7467 skip to the next visible line start.
7469 Functions get_next_display_element and set_iterator_to_next are
7470 separate because I find this arrangement easier to handle than a
7471 get_next_display_element function that also increments IT's
7472 position. The way it is we can first look at an iterator's current
7473 display element, decide whether it fits on a line, and if it does,
7474 increment the iterator position. The other way around we probably
7475 would either need a flag indicating whether the iterator has to be
7476 incremented the next time, or we would have to implement a
7477 decrement position function which would not be easy to write. */
7479 void
7480 set_iterator_to_next (struct it *it, bool reseat_p)
7482 /* Reset flags indicating start and end of a sequence of characters
7483 with box. Reset them at the start of this function because
7484 moving the iterator to a new position might set them. */
7485 it->start_of_box_run_p = it->end_of_box_run_p = false;
7487 switch (it->method)
7489 case GET_FROM_BUFFER:
7490 /* The current display element of IT is a character from
7491 current_buffer. Advance in the buffer, and maybe skip over
7492 invisible lines that are so because of selective display. */
7493 if (ITERATOR_AT_END_OF_LINE_P (it) && reseat_p)
7494 reseat_at_next_visible_line_start (it, false);
7495 else if (it->cmp_it.id >= 0)
7497 /* We are currently getting glyphs from a composition. */
7498 if (! it->bidi_p)
7500 IT_CHARPOS (*it) += it->cmp_it.nchars;
7501 IT_BYTEPOS (*it) += it->cmp_it.nbytes;
7503 else
7505 int i;
7507 /* Update IT's char/byte positions to point to the first
7508 character of the next grapheme cluster, or to the
7509 character visually after the current composition. */
7510 for (i = 0; i < it->cmp_it.nchars; i++)
7511 bidi_move_to_visually_next (&it->bidi_it);
7512 IT_BYTEPOS (*it) = it->bidi_it.bytepos;
7513 IT_CHARPOS (*it) = it->bidi_it.charpos;
7516 if ((! it->bidi_p || ! it->cmp_it.reversed_p)
7517 && it->cmp_it.to < it->cmp_it.nglyphs)
7519 /* Composition created while scanning forward. Proceed
7520 to the next grapheme cluster. */
7521 it->cmp_it.from = it->cmp_it.to;
7523 else if ((it->bidi_p && it->cmp_it.reversed_p)
7524 && it->cmp_it.from > 0)
7526 /* Composition created while scanning backward. Proceed
7527 to the previous grapheme cluster. */
7528 it->cmp_it.to = it->cmp_it.from;
7530 else
7532 /* No more grapheme clusters in this composition.
7533 Find the next stop position. */
7534 ptrdiff_t stop = it->end_charpos;
7536 if (it->bidi_it.scan_dir < 0)
7537 /* Now we are scanning backward and don't know
7538 where to stop. */
7539 stop = -1;
7540 composition_compute_stop_pos (&it->cmp_it, IT_CHARPOS (*it),
7541 IT_BYTEPOS (*it), stop, Qnil);
7544 else
7546 eassert (it->len != 0);
7548 if (!it->bidi_p)
7550 IT_BYTEPOS (*it) += it->len;
7551 IT_CHARPOS (*it) += 1;
7553 else
7555 int prev_scan_dir = it->bidi_it.scan_dir;
7556 /* If this is a new paragraph, determine its base
7557 direction (a.k.a. its base embedding level). */
7558 if (it->bidi_it.new_paragraph)
7559 bidi_paragraph_init (it->paragraph_embedding, &it->bidi_it,
7560 false);
7561 bidi_move_to_visually_next (&it->bidi_it);
7562 IT_BYTEPOS (*it) = it->bidi_it.bytepos;
7563 IT_CHARPOS (*it) = it->bidi_it.charpos;
7564 if (prev_scan_dir != it->bidi_it.scan_dir)
7566 /* As the scan direction was changed, we must
7567 re-compute the stop position for composition. */
7568 ptrdiff_t stop = it->end_charpos;
7569 if (it->bidi_it.scan_dir < 0)
7570 stop = -1;
7571 composition_compute_stop_pos (&it->cmp_it, IT_CHARPOS (*it),
7572 IT_BYTEPOS (*it), stop, Qnil);
7575 eassert (IT_BYTEPOS (*it) == CHAR_TO_BYTE (IT_CHARPOS (*it)));
7577 break;
7579 case GET_FROM_C_STRING:
7580 /* Current display element of IT is from a C string. */
7581 if (!it->bidi_p
7582 /* If the string position is beyond string's end, it means
7583 next_element_from_c_string is padding the string with
7584 blanks, in which case we bypass the bidi iterator,
7585 because it cannot deal with such virtual characters. */
7586 || IT_CHARPOS (*it) >= it->bidi_it.string.schars)
7588 IT_BYTEPOS (*it) += it->len;
7589 IT_CHARPOS (*it) += 1;
7591 else
7593 bidi_move_to_visually_next (&it->bidi_it);
7594 IT_BYTEPOS (*it) = it->bidi_it.bytepos;
7595 IT_CHARPOS (*it) = it->bidi_it.charpos;
7597 break;
7599 case GET_FROM_DISPLAY_VECTOR:
7600 /* Current display element of IT is from a display table entry.
7601 Advance in the display table definition. Reset it to null if
7602 end reached, and continue with characters from buffers/
7603 strings. */
7604 ++it->current.dpvec_index;
7606 /* Restore face of the iterator to what they were before the
7607 display vector entry (these entries may contain faces). */
7608 it->face_id = it->saved_face_id;
7610 if (it->dpvec + it->current.dpvec_index >= it->dpend)
7612 bool recheck_faces = it->ellipsis_p;
7614 if (it->s)
7615 it->method = GET_FROM_C_STRING;
7616 else if (STRINGP (it->string))
7617 it->method = GET_FROM_STRING;
7618 else
7620 it->method = GET_FROM_BUFFER;
7621 it->object = it->w->contents;
7624 it->dpvec = NULL;
7625 it->current.dpvec_index = -1;
7627 /* Skip over characters which were displayed via IT->dpvec. */
7628 if (it->dpvec_char_len < 0)
7629 reseat_at_next_visible_line_start (it, true);
7630 else if (it->dpvec_char_len > 0)
7632 it->len = it->dpvec_char_len;
7633 set_iterator_to_next (it, reseat_p);
7636 /* Maybe recheck faces after display vector. */
7637 if (recheck_faces)
7639 if (it->method == GET_FROM_STRING)
7640 it->stop_charpos = IT_STRING_CHARPOS (*it);
7641 else
7642 it->stop_charpos = IT_CHARPOS (*it);
7645 break;
7647 case GET_FROM_STRING:
7648 /* Current display element is a character from a Lisp string. */
7649 eassert (it->s == NULL && STRINGP (it->string));
7650 /* Don't advance past string end. These conditions are true
7651 when set_iterator_to_next is called at the end of
7652 get_next_display_element, in which case the Lisp string is
7653 already exhausted, and all we want is pop the iterator
7654 stack. */
7655 if (it->current.overlay_string_index >= 0)
7657 /* This is an overlay string, so there's no padding with
7658 spaces, and the number of characters in the string is
7659 where the string ends. */
7660 if (IT_STRING_CHARPOS (*it) >= SCHARS (it->string))
7661 goto consider_string_end;
7663 else
7665 /* Not an overlay string. There could be padding, so test
7666 against it->end_charpos. */
7667 if (IT_STRING_CHARPOS (*it) >= it->end_charpos)
7668 goto consider_string_end;
7670 if (it->cmp_it.id >= 0)
7672 /* We are delivering display elements from a composition.
7673 Update the string position past the grapheme cluster
7674 we've just processed. */
7675 if (! it->bidi_p)
7677 IT_STRING_CHARPOS (*it) += it->cmp_it.nchars;
7678 IT_STRING_BYTEPOS (*it) += it->cmp_it.nbytes;
7680 else
7682 int i;
7684 for (i = 0; i < it->cmp_it.nchars; i++)
7685 bidi_move_to_visually_next (&it->bidi_it);
7686 IT_STRING_BYTEPOS (*it) = it->bidi_it.bytepos;
7687 IT_STRING_CHARPOS (*it) = it->bidi_it.charpos;
7690 /* Did we exhaust all the grapheme clusters of this
7691 composition? */
7692 if ((! it->bidi_p || ! it->cmp_it.reversed_p)
7693 && (it->cmp_it.to < it->cmp_it.nglyphs))
7695 /* Not all the grapheme clusters were processed yet;
7696 advance to the next cluster. */
7697 it->cmp_it.from = it->cmp_it.to;
7699 else if ((it->bidi_p && it->cmp_it.reversed_p)
7700 && it->cmp_it.from > 0)
7702 /* Likewise: advance to the next cluster, but going in
7703 the reverse direction. */
7704 it->cmp_it.to = it->cmp_it.from;
7706 else
7708 /* This composition was fully processed; find the next
7709 candidate place for checking for composed
7710 characters. */
7711 /* Always limit string searches to the string length;
7712 any padding spaces are not part of the string, and
7713 there cannot be any compositions in that padding. */
7714 ptrdiff_t stop = SCHARS (it->string);
7716 if (it->bidi_p && it->bidi_it.scan_dir < 0)
7717 stop = -1;
7718 else if (it->end_charpos < stop)
7720 /* Cf. PRECISION in reseat_to_string: we might be
7721 limited in how many of the string characters we
7722 need to deliver. */
7723 stop = it->end_charpos;
7725 composition_compute_stop_pos (&it->cmp_it,
7726 IT_STRING_CHARPOS (*it),
7727 IT_STRING_BYTEPOS (*it), stop,
7728 it->string);
7731 else
7733 if (!it->bidi_p
7734 /* If the string position is beyond string's end, it
7735 means next_element_from_string is padding the string
7736 with blanks, in which case we bypass the bidi
7737 iterator, because it cannot deal with such virtual
7738 characters. */
7739 || IT_STRING_CHARPOS (*it) >= it->bidi_it.string.schars)
7741 IT_STRING_BYTEPOS (*it) += it->len;
7742 IT_STRING_CHARPOS (*it) += 1;
7744 else
7746 int prev_scan_dir = it->bidi_it.scan_dir;
7748 bidi_move_to_visually_next (&it->bidi_it);
7749 IT_STRING_BYTEPOS (*it) = it->bidi_it.bytepos;
7750 IT_STRING_CHARPOS (*it) = it->bidi_it.charpos;
7751 /* If the scan direction changes, we may need to update
7752 the place where to check for composed characters. */
7753 if (prev_scan_dir != it->bidi_it.scan_dir)
7755 ptrdiff_t stop = SCHARS (it->string);
7757 if (it->bidi_it.scan_dir < 0)
7758 stop = -1;
7759 else if (it->end_charpos < stop)
7760 stop = it->end_charpos;
7762 composition_compute_stop_pos (&it->cmp_it,
7763 IT_STRING_CHARPOS (*it),
7764 IT_STRING_BYTEPOS (*it), stop,
7765 it->string);
7770 consider_string_end:
7772 if (it->current.overlay_string_index >= 0)
7774 /* IT->string is an overlay string. Advance to the
7775 next, if there is one. */
7776 if (IT_STRING_CHARPOS (*it) >= SCHARS (it->string))
7778 it->ellipsis_p = false;
7779 next_overlay_string (it);
7780 if (it->ellipsis_p)
7781 setup_for_ellipsis (it, 0);
7784 else
7786 /* IT->string is not an overlay string. If we reached
7787 its end, and there is something on IT->stack, proceed
7788 with what is on the stack. This can be either another
7789 string, this time an overlay string, or a buffer. */
7790 if (IT_STRING_CHARPOS (*it) == SCHARS (it->string)
7791 && it->sp > 0)
7793 pop_it (it);
7794 if (it->method == GET_FROM_STRING)
7795 goto consider_string_end;
7798 break;
7800 case GET_FROM_IMAGE:
7801 case GET_FROM_STRETCH:
7802 case GET_FROM_XWIDGET:
7804 /* The position etc with which we have to proceed are on
7805 the stack. The position may be at the end of a string,
7806 if the `display' property takes up the whole string. */
7807 eassert (it->sp > 0);
7808 pop_it (it);
7809 if (it->method == GET_FROM_STRING)
7810 goto consider_string_end;
7811 break;
7813 default:
7814 /* There are no other methods defined, so this should be a bug. */
7815 emacs_abort ();
7818 eassert (it->method != GET_FROM_STRING
7819 || (STRINGP (it->string)
7820 && IT_STRING_CHARPOS (*it) >= 0));
7823 /* Load IT's display element fields with information about the next
7824 display element which comes from a display table entry or from the
7825 result of translating a control character to one of the forms `^C'
7826 or `\003'.
7828 IT->dpvec holds the glyphs to return as characters.
7829 IT->saved_face_id holds the face id before the display vector--it
7830 is restored into IT->face_id in set_iterator_to_next. */
7832 static bool
7833 next_element_from_display_vector (struct it *it)
7835 Lisp_Object gc;
7836 int prev_face_id = it->face_id;
7837 int next_face_id;
7839 /* Precondition. */
7840 eassert (it->dpvec && it->current.dpvec_index >= 0);
7842 it->face_id = it->saved_face_id;
7844 /* KFS: This code used to check ip->dpvec[0] instead of the current element.
7845 That seemed totally bogus - so I changed it... */
7846 if (it->dpend - it->dpvec > 0 /* empty dpvec[] is invalid */
7847 && (gc = it->dpvec[it->current.dpvec_index], GLYPH_CODE_P (gc)))
7849 struct face *this_face, *prev_face, *next_face;
7851 it->c = GLYPH_CODE_CHAR (gc);
7852 it->len = CHAR_BYTES (it->c);
7854 /* The entry may contain a face id to use. Such a face id is
7855 the id of a Lisp face, not a realized face. A face id of
7856 zero means no face is specified. */
7857 if (it->dpvec_face_id >= 0)
7858 it->face_id = it->dpvec_face_id;
7859 else
7861 int lface_id = GLYPH_CODE_FACE (gc);
7862 if (lface_id > 0)
7863 it->face_id = merge_faces (it->w, Qt, lface_id,
7864 it->saved_face_id);
7867 /* Glyphs in the display vector could have the box face, so we
7868 need to set the related flags in the iterator, as
7869 appropriate. */
7870 this_face = FACE_FROM_ID_OR_NULL (it->f, it->face_id);
7871 prev_face = FACE_FROM_ID_OR_NULL (it->f, prev_face_id);
7873 /* Is this character the first character of a box-face run? */
7874 it->start_of_box_run_p = (this_face && this_face->box != FACE_NO_BOX
7875 && (!prev_face
7876 || prev_face->box == FACE_NO_BOX));
7878 /* For the last character of the box-face run, we need to look
7879 either at the next glyph from the display vector, or at the
7880 face we saw before the display vector. */
7881 next_face_id = it->saved_face_id;
7882 if (it->current.dpvec_index < it->dpend - it->dpvec - 1)
7884 if (it->dpvec_face_id >= 0)
7885 next_face_id = it->dpvec_face_id;
7886 else
7888 int lface_id =
7889 GLYPH_CODE_FACE (it->dpvec[it->current.dpvec_index + 1]);
7891 if (lface_id > 0)
7892 next_face_id = merge_faces (it->w, Qt, lface_id,
7893 it->saved_face_id);
7896 next_face = FACE_FROM_ID_OR_NULL (it->f, next_face_id);
7897 it->end_of_box_run_p = (this_face && this_face->box != FACE_NO_BOX
7898 && (!next_face
7899 || next_face->box == FACE_NO_BOX));
7900 it->face_box_p = this_face && this_face->box != FACE_NO_BOX;
7902 else
7903 /* Display table entry is invalid. Return a space. */
7904 it->c = ' ', it->len = 1;
7906 /* Don't change position and object of the iterator here. They are
7907 still the values of the character that had this display table
7908 entry or was translated, and that's what we want. */
7909 it->what = IT_CHARACTER;
7910 return true;
7913 /* Get the first element of string/buffer in the visual order, after
7914 being reseated to a new position in a string or a buffer. */
7915 static void
7916 get_visually_first_element (struct it *it)
7918 bool string_p = STRINGP (it->string) || it->s;
7919 ptrdiff_t eob = (string_p ? it->bidi_it.string.schars : ZV);
7920 ptrdiff_t bob = (string_p ? 0 : BEGV);
7922 if (STRINGP (it->string))
7924 it->bidi_it.charpos = IT_STRING_CHARPOS (*it);
7925 it->bidi_it.bytepos = IT_STRING_BYTEPOS (*it);
7927 else
7929 it->bidi_it.charpos = IT_CHARPOS (*it);
7930 it->bidi_it.bytepos = IT_BYTEPOS (*it);
7933 if (it->bidi_it.charpos == eob)
7935 /* Nothing to do, but reset the FIRST_ELT flag, like
7936 bidi_paragraph_init does, because we are not going to
7937 call it. */
7938 it->bidi_it.first_elt = false;
7940 else if (it->bidi_it.charpos == bob
7941 || (!string_p
7942 && (FETCH_CHAR (it->bidi_it.bytepos - 1) == '\n'
7943 || FETCH_CHAR (it->bidi_it.bytepos) == '\n')))
7945 /* If we are at the beginning of a line/string, we can produce
7946 the next element right away. */
7947 bidi_paragraph_init (it->paragraph_embedding, &it->bidi_it, true);
7948 bidi_move_to_visually_next (&it->bidi_it);
7950 else
7952 ptrdiff_t orig_bytepos = it->bidi_it.bytepos;
7954 /* We need to prime the bidi iterator starting at the line's or
7955 string's beginning, before we will be able to produce the
7956 next element. */
7957 if (string_p)
7958 it->bidi_it.charpos = it->bidi_it.bytepos = 0;
7959 else
7960 it->bidi_it.charpos = find_newline_no_quit (IT_CHARPOS (*it),
7961 IT_BYTEPOS (*it), -1,
7962 &it->bidi_it.bytepos);
7963 bidi_paragraph_init (it->paragraph_embedding, &it->bidi_it, true);
7966 /* Now return to buffer/string position where we were asked
7967 to get the next display element, and produce that. */
7968 bidi_move_to_visually_next (&it->bidi_it);
7970 while (it->bidi_it.bytepos != orig_bytepos
7971 && it->bidi_it.charpos < eob);
7974 /* Adjust IT's position information to where we ended up. */
7975 if (STRINGP (it->string))
7977 IT_STRING_CHARPOS (*it) = it->bidi_it.charpos;
7978 IT_STRING_BYTEPOS (*it) = it->bidi_it.bytepos;
7980 else
7982 IT_CHARPOS (*it) = it->bidi_it.charpos;
7983 IT_BYTEPOS (*it) = it->bidi_it.bytepos;
7986 if (STRINGP (it->string) || !it->s)
7988 ptrdiff_t stop, charpos, bytepos;
7990 if (STRINGP (it->string))
7992 eassert (!it->s);
7993 stop = SCHARS (it->string);
7994 if (stop > it->end_charpos)
7995 stop = it->end_charpos;
7996 charpos = IT_STRING_CHARPOS (*it);
7997 bytepos = IT_STRING_BYTEPOS (*it);
7999 else
8001 stop = it->end_charpos;
8002 charpos = IT_CHARPOS (*it);
8003 bytepos = IT_BYTEPOS (*it);
8005 if (it->bidi_it.scan_dir < 0)
8006 stop = -1;
8007 composition_compute_stop_pos (&it->cmp_it, charpos, bytepos, stop,
8008 it->string);
8012 /* Load IT with the next display element from Lisp string IT->string.
8013 IT->current.string_pos is the current position within the string.
8014 If IT->current.overlay_string_index >= 0, the Lisp string is an
8015 overlay string. */
8017 static bool
8018 next_element_from_string (struct it *it)
8020 struct text_pos position;
8022 eassert (STRINGP (it->string));
8023 eassert (!it->bidi_p || EQ (it->string, it->bidi_it.string.lstring));
8024 eassert (IT_STRING_CHARPOS (*it) >= 0);
8025 position = it->current.string_pos;
8027 /* With bidi reordering, the character to display might not be the
8028 character at IT_STRING_CHARPOS. BIDI_IT.FIRST_ELT means
8029 that we were reseat()ed to a new string, whose paragraph
8030 direction is not known. */
8031 if (it->bidi_p && it->bidi_it.first_elt)
8033 get_visually_first_element (it);
8034 SET_TEXT_POS (position, IT_STRING_CHARPOS (*it), IT_STRING_BYTEPOS (*it));
8037 /* Time to check for invisible text? */
8038 if (IT_STRING_CHARPOS (*it) < it->end_charpos)
8040 if (IT_STRING_CHARPOS (*it) >= it->stop_charpos)
8042 if (!(!it->bidi_p
8043 || BIDI_AT_BASE_LEVEL (it->bidi_it)
8044 || IT_STRING_CHARPOS (*it) == it->stop_charpos))
8046 /* With bidi non-linear iteration, we could find
8047 ourselves far beyond the last computed stop_charpos,
8048 with several other stop positions in between that we
8049 missed. Scan them all now, in buffer's logical
8050 order, until we find and handle the last stop_charpos
8051 that precedes our current position. */
8052 handle_stop_backwards (it, it->stop_charpos);
8053 return GET_NEXT_DISPLAY_ELEMENT (it);
8055 else
8057 if (it->bidi_p)
8059 /* Take note of the stop position we just moved
8060 across, for when we will move back across it. */
8061 it->prev_stop = it->stop_charpos;
8062 /* If we are at base paragraph embedding level, take
8063 note of the last stop position seen at this
8064 level. */
8065 if (BIDI_AT_BASE_LEVEL (it->bidi_it))
8066 it->base_level_stop = it->stop_charpos;
8068 handle_stop (it);
8070 /* Since a handler may have changed IT->method, we must
8071 recurse here. */
8072 return GET_NEXT_DISPLAY_ELEMENT (it);
8075 else if (it->bidi_p
8076 /* If we are before prev_stop, we may have overstepped
8077 on our way backwards a stop_pos, and if so, we need
8078 to handle that stop_pos. */
8079 && IT_STRING_CHARPOS (*it) < it->prev_stop
8080 /* We can sometimes back up for reasons that have nothing
8081 to do with bidi reordering. E.g., compositions. The
8082 code below is only needed when we are above the base
8083 embedding level, so test for that explicitly. */
8084 && !BIDI_AT_BASE_LEVEL (it->bidi_it))
8086 /* If we lost track of base_level_stop, we have no better
8087 place for handle_stop_backwards to start from than string
8088 beginning. This happens, e.g., when we were reseated to
8089 the previous screenful of text by vertical-motion. */
8090 if (it->base_level_stop <= 0
8091 || IT_STRING_CHARPOS (*it) < it->base_level_stop)
8092 it->base_level_stop = 0;
8093 handle_stop_backwards (it, it->base_level_stop);
8094 return GET_NEXT_DISPLAY_ELEMENT (it);
8098 if (it->current.overlay_string_index >= 0)
8100 /* Get the next character from an overlay string. In overlay
8101 strings, there is no field width or padding with spaces to
8102 do. */
8103 if (IT_STRING_CHARPOS (*it) >= SCHARS (it->string))
8105 it->what = IT_EOB;
8106 return false;
8108 else if (CHAR_COMPOSED_P (it, IT_STRING_CHARPOS (*it),
8109 IT_STRING_BYTEPOS (*it),
8110 it->bidi_it.scan_dir < 0
8111 ? -1
8112 : SCHARS (it->string))
8113 && next_element_from_composition (it))
8115 return true;
8117 else if (STRING_MULTIBYTE (it->string))
8119 const unsigned char *s = (SDATA (it->string)
8120 + IT_STRING_BYTEPOS (*it));
8121 it->c = string_char_and_length (s, &it->len);
8123 else
8125 it->c = SREF (it->string, IT_STRING_BYTEPOS (*it));
8126 it->len = 1;
8129 else
8131 /* Get the next character from a Lisp string that is not an
8132 overlay string. Such strings come from the mode line, for
8133 example. We may have to pad with spaces, or truncate the
8134 string. See also next_element_from_c_string. */
8135 if (IT_STRING_CHARPOS (*it) >= it->end_charpos)
8137 it->what = IT_EOB;
8138 return false;
8140 else if (IT_STRING_CHARPOS (*it) >= it->string_nchars)
8142 /* Pad with spaces. */
8143 it->c = ' ', it->len = 1;
8144 CHARPOS (position) = BYTEPOS (position) = -1;
8146 else if (CHAR_COMPOSED_P (it, IT_STRING_CHARPOS (*it),
8147 IT_STRING_BYTEPOS (*it),
8148 it->bidi_it.scan_dir < 0
8149 ? -1
8150 : it->string_nchars)
8151 && next_element_from_composition (it))
8153 return true;
8155 else if (STRING_MULTIBYTE (it->string))
8157 const unsigned char *s = (SDATA (it->string)
8158 + IT_STRING_BYTEPOS (*it));
8159 it->c = string_char_and_length (s, &it->len);
8161 else
8163 it->c = SREF (it->string, IT_STRING_BYTEPOS (*it));
8164 it->len = 1;
8168 /* Record what we have and where it came from. */
8169 it->what = IT_CHARACTER;
8170 it->object = it->string;
8171 it->position = position;
8172 return true;
8176 /* Load IT with next display element from C string IT->s.
8177 IT->string_nchars is the maximum number of characters to return
8178 from the string. IT->end_charpos may be greater than
8179 IT->string_nchars when this function is called, in which case we
8180 may have to return padding spaces. Value is false if end of string
8181 reached, including padding spaces. */
8183 static bool
8184 next_element_from_c_string (struct it *it)
8186 bool success_p = true;
8188 eassert (it->s);
8189 eassert (!it->bidi_p || it->s == it->bidi_it.string.s);
8190 it->what = IT_CHARACTER;
8191 BYTEPOS (it->position) = CHARPOS (it->position) = 0;
8192 it->object = make_number (0);
8194 /* With bidi reordering, the character to display might not be the
8195 character at IT_CHARPOS. BIDI_IT.FIRST_ELT means that
8196 we were reseated to a new string, whose paragraph direction is
8197 not known. */
8198 if (it->bidi_p && it->bidi_it.first_elt)
8199 get_visually_first_element (it);
8201 /* IT's position can be greater than IT->string_nchars in case a
8202 field width or precision has been specified when the iterator was
8203 initialized. */
8204 if (IT_CHARPOS (*it) >= it->end_charpos)
8206 /* End of the game. */
8207 it->what = IT_EOB;
8208 success_p = false;
8210 else if (IT_CHARPOS (*it) >= it->string_nchars)
8212 /* Pad with spaces. */
8213 it->c = ' ', it->len = 1;
8214 BYTEPOS (it->position) = CHARPOS (it->position) = -1;
8216 else if (it->multibyte_p)
8217 it->c = string_char_and_length (it->s + IT_BYTEPOS (*it), &it->len);
8218 else
8219 it->c = it->s[IT_BYTEPOS (*it)], it->len = 1;
8221 return success_p;
8225 /* Set up IT to return characters from an ellipsis, if appropriate.
8226 The definition of the ellipsis glyphs may come from a display table
8227 entry. This function fills IT with the first glyph from the
8228 ellipsis if an ellipsis is to be displayed. */
8230 static bool
8231 next_element_from_ellipsis (struct it *it)
8233 if (it->selective_display_ellipsis_p)
8234 setup_for_ellipsis (it, it->len);
8235 else
8237 /* The face at the current position may be different from the
8238 face we find after the invisible text. Remember what it
8239 was in IT->saved_face_id, and signal that it's there by
8240 setting face_before_selective_p. */
8241 it->saved_face_id = it->face_id;
8242 it->method = GET_FROM_BUFFER;
8243 it->object = it->w->contents;
8244 reseat_at_next_visible_line_start (it, true);
8245 it->face_before_selective_p = true;
8248 return GET_NEXT_DISPLAY_ELEMENT (it);
8252 /* Deliver an image display element. The iterator IT is already
8253 filled with image information (done in handle_display_prop). Value
8254 is always true. */
8257 static bool
8258 next_element_from_image (struct it *it)
8260 it->what = IT_IMAGE;
8261 return true;
8264 static bool
8265 next_element_from_xwidget (struct it *it)
8267 it->what = IT_XWIDGET;
8268 return true;
8272 /* Fill iterator IT with next display element from a stretch glyph
8273 property. IT->object is the value of the text property. Value is
8274 always true. */
8276 static bool
8277 next_element_from_stretch (struct it *it)
8279 it->what = IT_STRETCH;
8280 return true;
8283 /* Scan backwards from IT's current position until we find a stop
8284 position, or until BEGV. This is called when we find ourself
8285 before both the last known prev_stop and base_level_stop while
8286 reordering bidirectional text. */
8288 static void
8289 compute_stop_pos_backwards (struct it *it)
8291 const int SCAN_BACK_LIMIT = 1000;
8292 struct text_pos pos;
8293 struct display_pos save_current = it->current;
8294 struct text_pos save_position = it->position;
8295 ptrdiff_t charpos = IT_CHARPOS (*it);
8296 ptrdiff_t where_we_are = charpos;
8297 ptrdiff_t save_stop_pos = it->stop_charpos;
8298 ptrdiff_t save_end_pos = it->end_charpos;
8300 eassert (NILP (it->string) && !it->s);
8301 eassert (it->bidi_p);
8302 it->bidi_p = false;
8305 it->end_charpos = min (charpos + 1, ZV);
8306 charpos = max (charpos - SCAN_BACK_LIMIT, BEGV);
8307 SET_TEXT_POS (pos, charpos, CHAR_TO_BYTE (charpos));
8308 reseat_1 (it, pos, false);
8309 compute_stop_pos (it);
8310 /* We must advance forward, right? */
8311 if (it->stop_charpos <= charpos)
8312 emacs_abort ();
8314 while (charpos > BEGV && it->stop_charpos >= it->end_charpos);
8316 if (it->stop_charpos <= where_we_are)
8317 it->prev_stop = it->stop_charpos;
8318 else
8319 it->prev_stop = BEGV;
8320 it->bidi_p = true;
8321 it->current = save_current;
8322 it->position = save_position;
8323 it->stop_charpos = save_stop_pos;
8324 it->end_charpos = save_end_pos;
8327 /* Scan forward from CHARPOS in the current buffer/string, until we
8328 find a stop position > current IT's position. Then handle the stop
8329 position before that. This is called when we bump into a stop
8330 position while reordering bidirectional text. CHARPOS should be
8331 the last previously processed stop_pos (or BEGV/0, if none were
8332 processed yet) whose position is less that IT's current
8333 position. */
8335 static void
8336 handle_stop_backwards (struct it *it, ptrdiff_t charpos)
8338 bool bufp = !STRINGP (it->string);
8339 ptrdiff_t where_we_are = (bufp ? IT_CHARPOS (*it) : IT_STRING_CHARPOS (*it));
8340 struct display_pos save_current = it->current;
8341 struct text_pos save_position = it->position;
8342 struct text_pos pos1;
8343 ptrdiff_t next_stop;
8345 /* Scan in strict logical order. */
8346 eassert (it->bidi_p);
8347 it->bidi_p = false;
8350 it->prev_stop = charpos;
8351 if (bufp)
8353 SET_TEXT_POS (pos1, charpos, CHAR_TO_BYTE (charpos));
8354 reseat_1 (it, pos1, false);
8356 else
8357 it->current.string_pos = string_pos (charpos, it->string);
8358 compute_stop_pos (it);
8359 /* We must advance forward, right? */
8360 if (it->stop_charpos <= it->prev_stop)
8361 emacs_abort ();
8362 charpos = it->stop_charpos;
8364 while (charpos <= where_we_are);
8366 it->bidi_p = true;
8367 it->current = save_current;
8368 it->position = save_position;
8369 next_stop = it->stop_charpos;
8370 it->stop_charpos = it->prev_stop;
8371 handle_stop (it);
8372 it->stop_charpos = next_stop;
8375 /* Load IT with the next display element from current_buffer. Value
8376 is false if end of buffer reached. IT->stop_charpos is the next
8377 position at which to stop and check for text properties or buffer
8378 end. */
8380 static bool
8381 next_element_from_buffer (struct it *it)
8383 bool success_p = true;
8385 eassert (IT_CHARPOS (*it) >= BEGV);
8386 eassert (NILP (it->string) && !it->s);
8387 eassert (!it->bidi_p
8388 || (EQ (it->bidi_it.string.lstring, Qnil)
8389 && it->bidi_it.string.s == NULL));
8391 /* With bidi reordering, the character to display might not be the
8392 character at IT_CHARPOS. BIDI_IT.FIRST_ELT means that
8393 we were reseat()ed to a new buffer position, which is potentially
8394 a different paragraph. */
8395 if (it->bidi_p && it->bidi_it.first_elt)
8397 get_visually_first_element (it);
8398 SET_TEXT_POS (it->position, IT_CHARPOS (*it), IT_BYTEPOS (*it));
8401 if (IT_CHARPOS (*it) >= it->stop_charpos)
8403 if (IT_CHARPOS (*it) >= it->end_charpos)
8405 bool overlay_strings_follow_p;
8407 /* End of the game, except when overlay strings follow that
8408 haven't been returned yet. */
8409 if (it->overlay_strings_at_end_processed_p)
8410 overlay_strings_follow_p = false;
8411 else
8413 it->overlay_strings_at_end_processed_p = true;
8414 overlay_strings_follow_p = get_overlay_strings (it, 0);
8417 if (overlay_strings_follow_p)
8418 success_p = GET_NEXT_DISPLAY_ELEMENT (it);
8419 else
8421 it->what = IT_EOB;
8422 it->position = it->current.pos;
8423 success_p = false;
8426 else if (!(!it->bidi_p
8427 || BIDI_AT_BASE_LEVEL (it->bidi_it)
8428 || IT_CHARPOS (*it) == it->stop_charpos))
8430 /* With bidi non-linear iteration, we could find ourselves
8431 far beyond the last computed stop_charpos, with several
8432 other stop positions in between that we missed. Scan
8433 them all now, in buffer's logical order, until we find
8434 and handle the last stop_charpos that precedes our
8435 current position. */
8436 handle_stop_backwards (it, it->stop_charpos);
8437 it->ignore_overlay_strings_at_pos_p = false;
8438 return GET_NEXT_DISPLAY_ELEMENT (it);
8440 else
8442 if (it->bidi_p)
8444 /* Take note of the stop position we just moved across,
8445 for when we will move back across it. */
8446 it->prev_stop = it->stop_charpos;
8447 /* If we are at base paragraph embedding level, take
8448 note of the last stop position seen at this
8449 level. */
8450 if (BIDI_AT_BASE_LEVEL (it->bidi_it))
8451 it->base_level_stop = it->stop_charpos;
8453 handle_stop (it);
8454 it->ignore_overlay_strings_at_pos_p = false;
8455 return GET_NEXT_DISPLAY_ELEMENT (it);
8458 else if (it->bidi_p
8459 /* If we are before prev_stop, we may have overstepped on
8460 our way backwards a stop_pos, and if so, we need to
8461 handle that stop_pos. */
8462 && IT_CHARPOS (*it) < it->prev_stop
8463 /* We can sometimes back up for reasons that have nothing
8464 to do with bidi reordering. E.g., compositions. The
8465 code below is only needed when we are above the base
8466 embedding level, so test for that explicitly. */
8467 && !BIDI_AT_BASE_LEVEL (it->bidi_it))
8469 if (it->base_level_stop <= 0
8470 || IT_CHARPOS (*it) < it->base_level_stop)
8472 /* If we lost track of base_level_stop, we need to find
8473 prev_stop by looking backwards. This happens, e.g., when
8474 we were reseated to the previous screenful of text by
8475 vertical-motion. */
8476 it->base_level_stop = BEGV;
8477 compute_stop_pos_backwards (it);
8478 handle_stop_backwards (it, it->prev_stop);
8480 else
8481 handle_stop_backwards (it, it->base_level_stop);
8482 it->ignore_overlay_strings_at_pos_p = false;
8483 return GET_NEXT_DISPLAY_ELEMENT (it);
8485 else
8487 /* No face changes, overlays etc. in sight, so just return a
8488 character from current_buffer. */
8489 unsigned char *p;
8490 ptrdiff_t stop;
8492 /* We moved to the next buffer position, so any info about
8493 previously seen overlays is no longer valid. */
8494 it->ignore_overlay_strings_at_pos_p = false;
8496 /* Maybe run the redisplay end trigger hook. Performance note:
8497 This doesn't seem to cost measurable time. */
8498 if (it->redisplay_end_trigger_charpos
8499 && it->glyph_row
8500 && IT_CHARPOS (*it) >= it->redisplay_end_trigger_charpos)
8501 run_redisplay_end_trigger_hook (it);
8503 stop = it->bidi_it.scan_dir < 0 ? -1 : it->end_charpos;
8504 if (CHAR_COMPOSED_P (it, IT_CHARPOS (*it), IT_BYTEPOS (*it),
8505 stop)
8506 && next_element_from_composition (it))
8508 return true;
8511 /* Get the next character, maybe multibyte. */
8512 p = BYTE_POS_ADDR (IT_BYTEPOS (*it));
8513 if (it->multibyte_p && !ASCII_CHAR_P (*p))
8514 it->c = STRING_CHAR_AND_LENGTH (p, it->len);
8515 else
8516 it->c = *p, it->len = 1;
8518 /* Record what we have and where it came from. */
8519 it->what = IT_CHARACTER;
8520 it->object = it->w->contents;
8521 it->position = it->current.pos;
8523 /* Normally we return the character found above, except when we
8524 really want to return an ellipsis for selective display. */
8525 if (it->selective)
8527 if (it->c == '\n')
8529 /* A value of selective > 0 means hide lines indented more
8530 than that number of columns. */
8531 if (it->selective > 0
8532 && IT_CHARPOS (*it) + 1 < ZV
8533 && indented_beyond_p (IT_CHARPOS (*it) + 1,
8534 IT_BYTEPOS (*it) + 1,
8535 it->selective))
8537 success_p = next_element_from_ellipsis (it);
8538 it->dpvec_char_len = -1;
8541 else if (it->c == '\r' && it->selective == -1)
8543 /* A value of selective == -1 means that everything from the
8544 CR to the end of the line is invisible, with maybe an
8545 ellipsis displayed for it. */
8546 success_p = next_element_from_ellipsis (it);
8547 it->dpvec_char_len = -1;
8552 /* Value is false if end of buffer reached. */
8553 eassert (!success_p || it->what != IT_CHARACTER || it->len > 0);
8554 return success_p;
8558 /* Run the redisplay end trigger hook for IT. */
8560 static void
8561 run_redisplay_end_trigger_hook (struct it *it)
8563 /* IT->glyph_row should be non-null, i.e. we should be actually
8564 displaying something, or otherwise we should not run the hook. */
8565 eassert (it->glyph_row);
8567 ptrdiff_t charpos = it->redisplay_end_trigger_charpos;
8568 it->redisplay_end_trigger_charpos = 0;
8570 /* Since we are *trying* to run these functions, don't try to run
8571 them again, even if they get an error. */
8572 wset_redisplay_end_trigger (it->w, Qnil);
8573 CALLN (Frun_hook_with_args, Qredisplay_end_trigger_functions, it->window,
8574 make_number (charpos));
8576 /* Notice if it changed the face of the character we are on. */
8577 handle_face_prop (it);
8581 /* Deliver a composition display element. Unlike the other
8582 next_element_from_XXX, this function is not registered in the array
8583 get_next_element[]. It is called from next_element_from_buffer and
8584 next_element_from_string when necessary. */
8586 static bool
8587 next_element_from_composition (struct it *it)
8589 it->what = IT_COMPOSITION;
8590 it->len = it->cmp_it.nbytes;
8591 if (STRINGP (it->string))
8593 if (it->c < 0)
8595 IT_STRING_CHARPOS (*it) += it->cmp_it.nchars;
8596 IT_STRING_BYTEPOS (*it) += it->cmp_it.nbytes;
8597 return false;
8599 it->position = it->current.string_pos;
8600 it->object = it->string;
8601 it->c = composition_update_it (&it->cmp_it, IT_STRING_CHARPOS (*it),
8602 IT_STRING_BYTEPOS (*it), it->string);
8604 else
8606 if (it->c < 0)
8608 IT_CHARPOS (*it) += it->cmp_it.nchars;
8609 IT_BYTEPOS (*it) += it->cmp_it.nbytes;
8610 if (it->bidi_p)
8612 if (it->bidi_it.new_paragraph)
8613 bidi_paragraph_init (it->paragraph_embedding, &it->bidi_it,
8614 false);
8615 /* Resync the bidi iterator with IT's new position.
8616 FIXME: this doesn't support bidirectional text. */
8617 while (it->bidi_it.charpos < IT_CHARPOS (*it))
8618 bidi_move_to_visually_next (&it->bidi_it);
8620 return false;
8622 it->position = it->current.pos;
8623 it->object = it->w->contents;
8624 it->c = composition_update_it (&it->cmp_it, IT_CHARPOS (*it),
8625 IT_BYTEPOS (*it), Qnil);
8627 return true;
8632 /***********************************************************************
8633 Moving an iterator without producing glyphs
8634 ***********************************************************************/
8636 /* Check if iterator is at a position corresponding to a valid buffer
8637 position after some move_it_ call. */
8639 #define IT_POS_VALID_AFTER_MOVE_P(it) \
8640 ((it)->method != GET_FROM_STRING || IT_STRING_CHARPOS (*it) == 0)
8643 /* Move iterator IT to a specified buffer or X position within one
8644 line on the display without producing glyphs.
8646 OP should be a bit mask including some or all of these bits:
8647 MOVE_TO_X: Stop upon reaching x-position TO_X.
8648 MOVE_TO_POS: Stop upon reaching buffer or string position TO_CHARPOS.
8649 Regardless of OP's value, stop upon reaching the end of the display line.
8651 TO_X is normally a value 0 <= TO_X <= IT->last_visible_x.
8652 This means, in particular, that TO_X includes window's horizontal
8653 scroll amount.
8655 The return value has several possible values that
8656 say what condition caused the scan to stop:
8658 MOVE_POS_MATCH_OR_ZV
8659 - when TO_POS or ZV was reached.
8661 MOVE_X_REACHED
8662 -when TO_X was reached before TO_POS or ZV were reached.
8664 MOVE_LINE_CONTINUED
8665 - when we reached the end of the display area and the line must
8666 be continued.
8668 MOVE_LINE_TRUNCATED
8669 - when we reached the end of the display area and the line is
8670 truncated.
8672 MOVE_NEWLINE_OR_CR
8673 - when we stopped at a line end, i.e. a newline or a CR and selective
8674 display is on. */
8676 static enum move_it_result
8677 move_it_in_display_line_to (struct it *it,
8678 ptrdiff_t to_charpos, int to_x,
8679 enum move_operation_enum op)
8681 enum move_it_result result = MOVE_UNDEFINED;
8682 struct glyph_row *saved_glyph_row;
8683 struct it wrap_it, atpos_it, atx_it, ppos_it;
8684 void *wrap_data = NULL, *atpos_data = NULL, *atx_data = NULL;
8685 void *ppos_data = NULL;
8686 bool may_wrap = false;
8687 enum it_method prev_method = it->method;
8688 ptrdiff_t closest_pos UNINIT;
8689 ptrdiff_t prev_pos = IT_CHARPOS (*it);
8690 bool saw_smaller_pos = prev_pos < to_charpos;
8691 bool line_number_pending = false;
8693 /* Don't produce glyphs in produce_glyphs. */
8694 saved_glyph_row = it->glyph_row;
8695 it->glyph_row = NULL;
8697 /* Use wrap_it to save a copy of IT wherever a word wrap could
8698 occur. Use atpos_it to save a copy of IT at the desired buffer
8699 position, if found, so that we can scan ahead and check if the
8700 word later overshoots the window edge. Use atx_it similarly, for
8701 pixel positions. */
8702 wrap_it.sp = -1;
8703 atpos_it.sp = -1;
8704 atx_it.sp = -1;
8706 /* Use ppos_it under bidi reordering to save a copy of IT for the
8707 initial position. We restore that position in IT when we have
8708 scanned the entire display line without finding a match for
8709 TO_CHARPOS and all the character positions are greater than
8710 TO_CHARPOS. We then restart the scan from the initial position,
8711 and stop at CLOSEST_POS, which is a position > TO_CHARPOS that is
8712 the closest to TO_CHARPOS. */
8713 if (it->bidi_p)
8715 if ((op & MOVE_TO_POS) && IT_CHARPOS (*it) >= to_charpos)
8717 SAVE_IT (ppos_it, *it, ppos_data);
8718 closest_pos = IT_CHARPOS (*it);
8720 else
8721 closest_pos = ZV;
8724 #define BUFFER_POS_REACHED_P() \
8725 ((op & MOVE_TO_POS) != 0 \
8726 && BUFFERP (it->object) \
8727 && (IT_CHARPOS (*it) == to_charpos \
8728 || ((!it->bidi_p \
8729 || BIDI_AT_BASE_LEVEL (it->bidi_it)) \
8730 && IT_CHARPOS (*it) > to_charpos) \
8731 || (it->what == IT_COMPOSITION \
8732 && ((IT_CHARPOS (*it) > to_charpos \
8733 && to_charpos >= it->cmp_it.charpos) \
8734 || (IT_CHARPOS (*it) < to_charpos \
8735 && to_charpos <= it->cmp_it.charpos)))) \
8736 && (it->method == GET_FROM_BUFFER \
8737 || (it->method == GET_FROM_DISPLAY_VECTOR \
8738 && it->dpvec + it->current.dpvec_index + 1 >= it->dpend)))
8740 if (it->hpos == 0)
8742 /* If line numbers are being displayed, produce a line number.
8743 But don't do that if we are to reach first_visible_x, because
8744 line numbers are not relevant to stuff that is not visible on
8745 display. */
8746 if (!((op && MOVE_TO_X) && to_x == it->first_visible_x)
8747 && should_produce_line_number (it))
8749 if (it->current_x == it->first_visible_x)
8750 maybe_produce_line_number (it);
8751 else
8752 line_number_pending = true;
8754 /* If there's a line-/wrap-prefix, handle it. */
8755 if (it->method == GET_FROM_BUFFER)
8756 handle_line_prefix (it);
8759 if (IT_CHARPOS (*it) < CHARPOS (this_line_min_pos))
8760 SET_TEXT_POS (this_line_min_pos, IT_CHARPOS (*it), IT_BYTEPOS (*it));
8762 while (true)
8764 int x, i, ascent = 0, descent = 0;
8766 /* Utility macro to reset an iterator with x, ascent, and descent. */
8767 #define IT_RESET_X_ASCENT_DESCENT(IT) \
8768 ((IT)->current_x = x, (IT)->max_ascent = ascent, \
8769 (IT)->max_descent = descent)
8771 /* Stop if we move beyond TO_CHARPOS (after an image or a
8772 display string or stretch glyph). */
8773 if ((op & MOVE_TO_POS) != 0
8774 && BUFFERP (it->object)
8775 && it->method == GET_FROM_BUFFER
8776 && (((!it->bidi_p
8777 /* When the iterator is at base embedding level, we
8778 are guaranteed that characters are delivered for
8779 display in strictly increasing order of their
8780 buffer positions. */
8781 || BIDI_AT_BASE_LEVEL (it->bidi_it))
8782 && IT_CHARPOS (*it) > to_charpos)
8783 || (it->bidi_p
8784 && (prev_method == GET_FROM_IMAGE
8785 || prev_method == GET_FROM_STRETCH
8786 || prev_method == GET_FROM_STRING)
8787 /* Passed TO_CHARPOS from left to right. */
8788 && ((prev_pos < to_charpos
8789 && IT_CHARPOS (*it) > to_charpos)
8790 /* Passed TO_CHARPOS from right to left. */
8791 || (prev_pos > to_charpos
8792 && IT_CHARPOS (*it) < to_charpos)))))
8794 if (it->line_wrap != WORD_WRAP || wrap_it.sp < 0)
8796 result = MOVE_POS_MATCH_OR_ZV;
8797 break;
8799 else if (it->line_wrap == WORD_WRAP && atpos_it.sp < 0)
8800 /* If wrap_it is valid, the current position might be in a
8801 word that is wrapped. So, save the iterator in
8802 atpos_it and continue to see if wrapping happens. */
8803 SAVE_IT (atpos_it, *it, atpos_data);
8806 /* Stop when ZV reached.
8807 We used to stop here when TO_CHARPOS reached as well, but that is
8808 too soon if this glyph does not fit on this line. So we handle it
8809 explicitly below. */
8810 if (!get_next_display_element (it))
8812 result = MOVE_POS_MATCH_OR_ZV;
8813 break;
8816 if (it->line_wrap == TRUNCATE)
8818 /* If it->pixel_width is zero, the last PRODUCE_GLYPHS call
8819 produced something that doesn't consume any screen estate
8820 in the text area, so we don't want to exit the loop at
8821 TO_CHARPOS, before we produce the glyph for that buffer
8822 position. This happens, e.g., when there's an overlay at
8823 TO_CHARPOS that draws a fringe bitmap. */
8824 if (BUFFER_POS_REACHED_P ()
8825 && (it->pixel_width > 0
8826 || IT_CHARPOS (*it) > to_charpos
8827 || it->area != TEXT_AREA))
8829 result = MOVE_POS_MATCH_OR_ZV;
8830 break;
8833 else
8835 if (it->line_wrap == WORD_WRAP && it->area == TEXT_AREA)
8837 if (IT_DISPLAYING_WHITESPACE (it))
8838 may_wrap = true;
8839 else if (may_wrap)
8841 /* We have reached a glyph that follows one or more
8842 whitespace characters. If the position is
8843 already found, we are done. */
8844 if (atpos_it.sp >= 0)
8846 RESTORE_IT (it, &atpos_it, atpos_data);
8847 result = MOVE_POS_MATCH_OR_ZV;
8848 goto done;
8850 if (atx_it.sp >= 0)
8852 RESTORE_IT (it, &atx_it, atx_data);
8853 result = MOVE_X_REACHED;
8854 goto done;
8856 /* Otherwise, we can wrap here. */
8857 SAVE_IT (wrap_it, *it, wrap_data);
8858 may_wrap = false;
8863 /* Remember the line height for the current line, in case
8864 the next element doesn't fit on the line. */
8865 ascent = it->max_ascent;
8866 descent = it->max_descent;
8868 /* The call to produce_glyphs will get the metrics of the
8869 display element IT is loaded with. Record the x-position
8870 before this display element, in case it doesn't fit on the
8871 line. */
8872 x = it->current_x;
8874 PRODUCE_GLYPHS (it);
8876 if (it->area != TEXT_AREA)
8878 prev_method = it->method;
8879 if (it->method == GET_FROM_BUFFER)
8880 prev_pos = IT_CHARPOS (*it);
8881 set_iterator_to_next (it, true);
8882 if (IT_CHARPOS (*it) < CHARPOS (this_line_min_pos))
8883 SET_TEXT_POS (this_line_min_pos,
8884 IT_CHARPOS (*it), IT_BYTEPOS (*it));
8885 if (it->bidi_p
8886 && (op & MOVE_TO_POS)
8887 && IT_CHARPOS (*it) > to_charpos
8888 && IT_CHARPOS (*it) < closest_pos)
8889 closest_pos = IT_CHARPOS (*it);
8890 continue;
8893 /* The number of glyphs we get back in IT->nglyphs will normally
8894 be 1 except when IT->c is (i) a TAB, or (ii) a multi-glyph
8895 character on a terminal frame, or (iii) a line end. For the
8896 second case, IT->nglyphs - 1 padding glyphs will be present.
8897 (On X frames, there is only one glyph produced for a
8898 composite character.)
8900 The behavior implemented below means, for continuation lines,
8901 that as many spaces of a TAB as fit on the current line are
8902 displayed there. For terminal frames, as many glyphs of a
8903 multi-glyph character are displayed in the current line, too.
8904 This is what the old redisplay code did, and we keep it that
8905 way. Under X, the whole shape of a complex character must
8906 fit on the line or it will be completely displayed in the
8907 next line.
8909 Note that both for tabs and padding glyphs, all glyphs have
8910 the same width. */
8911 if (it->nglyphs)
8913 /* More than one glyph or glyph doesn't fit on line. All
8914 glyphs have the same width. */
8915 int single_glyph_width = it->pixel_width / it->nglyphs;
8916 int new_x;
8917 int x_before_this_char = x;
8918 int hpos_before_this_char = it->hpos;
8920 for (i = 0; i < it->nglyphs; ++i, x = new_x)
8922 new_x = x + single_glyph_width;
8924 /* We want to leave anything reaching TO_X to the caller. */
8925 if ((op & MOVE_TO_X) && new_x > to_x)
8927 if (BUFFER_POS_REACHED_P ())
8929 if (it->line_wrap != WORD_WRAP || wrap_it.sp < 0)
8930 goto buffer_pos_reached;
8931 if (atpos_it.sp < 0)
8933 SAVE_IT (atpos_it, *it, atpos_data);
8934 IT_RESET_X_ASCENT_DESCENT (&atpos_it);
8937 else
8939 if (it->line_wrap != WORD_WRAP || wrap_it.sp < 0)
8941 it->current_x = x;
8942 result = MOVE_X_REACHED;
8943 break;
8945 if (atx_it.sp < 0)
8947 SAVE_IT (atx_it, *it, atx_data);
8948 IT_RESET_X_ASCENT_DESCENT (&atx_it);
8953 if (/* Lines are continued. */
8954 it->line_wrap != TRUNCATE
8955 && (/* And glyph doesn't fit on the line. */
8956 new_x > it->last_visible_x
8957 /* Or it fits exactly and we're on a window
8958 system frame. */
8959 || (new_x == it->last_visible_x
8960 && FRAME_WINDOW_P (it->f)
8961 && ((it->bidi_p && it->bidi_it.paragraph_dir == R2L)
8962 ? WINDOW_LEFT_FRINGE_WIDTH (it->w)
8963 : WINDOW_RIGHT_FRINGE_WIDTH (it->w)))))
8965 bool moved_forward = false;
8967 if (/* IT->hpos == 0 means the very first glyph
8968 doesn't fit on the line, e.g. a wide image. */
8969 it->hpos == 0
8970 || (new_x == it->last_visible_x
8971 && FRAME_WINDOW_P (it->f)))
8973 ++it->hpos;
8974 it->current_x = new_x;
8976 /* The character's last glyph just barely fits
8977 in this row. */
8978 if (i == it->nglyphs - 1)
8980 /* If this is the destination position,
8981 return a position *before* it in this row,
8982 now that we know it fits in this row. */
8983 if (BUFFER_POS_REACHED_P ())
8985 bool can_wrap = true;
8987 /* If we are at a whitespace character
8988 that barely fits on this screen line,
8989 but the next character is also
8990 whitespace, we cannot wrap here. */
8991 if (it->line_wrap == WORD_WRAP
8992 && wrap_it.sp >= 0
8993 && may_wrap
8994 && IT_OVERFLOW_NEWLINE_INTO_FRINGE (it))
8996 struct it tem_it;
8997 void *tem_data = NULL;
8999 SAVE_IT (tem_it, *it, tem_data);
9000 set_iterator_to_next (it, true);
9001 if (get_next_display_element (it)
9002 && IT_DISPLAYING_WHITESPACE (it))
9003 can_wrap = false;
9004 RESTORE_IT (it, &tem_it, tem_data);
9006 if (it->line_wrap != WORD_WRAP
9007 || wrap_it.sp < 0
9008 /* If we've just found whitespace
9009 where we can wrap, effectively
9010 ignore the previous wrap point --
9011 it is no longer relevant, but we
9012 won't have an opportunity to
9013 update it, since we've reached
9014 the edge of this screen line. */
9015 || (may_wrap && can_wrap
9016 && IT_OVERFLOW_NEWLINE_INTO_FRINGE (it)))
9018 it->hpos = hpos_before_this_char;
9019 it->current_x = x_before_this_char;
9020 result = MOVE_POS_MATCH_OR_ZV;
9021 break;
9023 if (it->line_wrap == WORD_WRAP
9024 && atpos_it.sp < 0)
9026 SAVE_IT (atpos_it, *it, atpos_data);
9027 atpos_it.current_x = x_before_this_char;
9028 atpos_it.hpos = hpos_before_this_char;
9032 prev_method = it->method;
9033 if (it->method == GET_FROM_BUFFER)
9034 prev_pos = IT_CHARPOS (*it);
9035 set_iterator_to_next (it, true);
9036 if (IT_CHARPOS (*it) < CHARPOS (this_line_min_pos))
9037 SET_TEXT_POS (this_line_min_pos,
9038 IT_CHARPOS (*it), IT_BYTEPOS (*it));
9039 /* On graphical terminals, newlines may
9040 "overflow" into the fringe if
9041 overflow-newline-into-fringe is non-nil.
9042 On text terminals, and on graphical
9043 terminals with no right margin, newlines
9044 may overflow into the last glyph on the
9045 display line.*/
9046 if (!FRAME_WINDOW_P (it->f)
9047 || ((it->bidi_p
9048 && it->bidi_it.paragraph_dir == R2L)
9049 ? WINDOW_LEFT_FRINGE_WIDTH (it->w)
9050 : WINDOW_RIGHT_FRINGE_WIDTH (it->w)) == 0
9051 || IT_OVERFLOW_NEWLINE_INTO_FRINGE (it))
9053 if (!get_next_display_element (it))
9055 result = MOVE_POS_MATCH_OR_ZV;
9056 break;
9058 moved_forward = true;
9059 if (BUFFER_POS_REACHED_P ())
9061 if (ITERATOR_AT_END_OF_LINE_P (it))
9062 result = MOVE_POS_MATCH_OR_ZV;
9063 else
9064 result = MOVE_LINE_CONTINUED;
9065 break;
9067 if (ITERATOR_AT_END_OF_LINE_P (it)
9068 && (it->line_wrap != WORD_WRAP
9069 || wrap_it.sp < 0
9070 || IT_OVERFLOW_NEWLINE_INTO_FRINGE (it)))
9072 result = MOVE_NEWLINE_OR_CR;
9073 break;
9078 else
9079 IT_RESET_X_ASCENT_DESCENT (it);
9081 /* If the screen line ends with whitespace, and we
9082 are under word-wrap, don't use wrap_it: it is no
9083 longer relevant, but we won't have an opportunity
9084 to update it, since we are done with this screen
9085 line. */
9086 if (may_wrap && IT_OVERFLOW_NEWLINE_INTO_FRINGE (it)
9087 /* If the character after the one which set the
9088 may_wrap flag is also whitespace, we can't
9089 wrap here, since the screen line cannot be
9090 wrapped in the middle of whitespace.
9091 Therefore, wrap_it _is_ relevant in that
9092 case. */
9093 && !(moved_forward && IT_DISPLAYING_WHITESPACE (it)))
9095 /* If we've found TO_X, go back there, as we now
9096 know the last word fits on this screen line. */
9097 if ((op & MOVE_TO_X) && new_x == it->last_visible_x
9098 && atx_it.sp >= 0)
9100 RESTORE_IT (it, &atx_it, atx_data);
9101 atpos_it.sp = -1;
9102 atx_it.sp = -1;
9103 result = MOVE_X_REACHED;
9104 break;
9107 else if (wrap_it.sp >= 0)
9109 RESTORE_IT (it, &wrap_it, wrap_data);
9110 atpos_it.sp = -1;
9111 atx_it.sp = -1;
9114 TRACE_MOVE ((stderr, "move_it_in: continued at %d\n",
9115 IT_CHARPOS (*it)));
9116 result = MOVE_LINE_CONTINUED;
9117 break;
9120 if (BUFFER_POS_REACHED_P ())
9122 if (it->line_wrap != WORD_WRAP || wrap_it.sp < 0)
9123 goto buffer_pos_reached;
9124 if (it->line_wrap == WORD_WRAP && atpos_it.sp < 0)
9126 SAVE_IT (atpos_it, *it, atpos_data);
9127 IT_RESET_X_ASCENT_DESCENT (&atpos_it);
9131 if (new_x > it->first_visible_x)
9133 /* If we have reached the visible portion of the
9134 screen line, produce the line number if needed. */
9135 if (line_number_pending)
9137 line_number_pending = false;
9138 it->current_x = it->first_visible_x;
9139 maybe_produce_line_number (it);
9140 it->current_x += new_x - it->first_visible_x;
9142 /* Glyph is visible. Increment number of glyphs that
9143 would be displayed. */
9144 ++it->hpos;
9148 if (result != MOVE_UNDEFINED)
9149 break;
9151 else if (BUFFER_POS_REACHED_P ())
9153 buffer_pos_reached:
9154 IT_RESET_X_ASCENT_DESCENT (it);
9155 result = MOVE_POS_MATCH_OR_ZV;
9156 break;
9158 else if ((op & MOVE_TO_X) && it->current_x >= to_x)
9160 /* Stop when TO_X specified and reached. This check is
9161 necessary here because of lines consisting of a line end,
9162 only. The line end will not produce any glyphs and we
9163 would never get MOVE_X_REACHED. */
9164 eassert (it->nglyphs == 0);
9165 result = MOVE_X_REACHED;
9166 break;
9169 /* Is this a line end? If yes, we're done. */
9170 if (ITERATOR_AT_END_OF_LINE_P (it))
9172 /* If we are past TO_CHARPOS, but never saw any character
9173 positions smaller than TO_CHARPOS, return
9174 MOVE_POS_MATCH_OR_ZV, like the unidirectional display
9175 did. */
9176 if (it->bidi_p && (op & MOVE_TO_POS) != 0)
9178 if (!saw_smaller_pos && IT_CHARPOS (*it) > to_charpos)
9180 if (closest_pos < ZV)
9182 RESTORE_IT (it, &ppos_it, ppos_data);
9183 /* Don't recurse if closest_pos is equal to
9184 to_charpos, since we have just tried that. */
9185 if (closest_pos != to_charpos)
9186 move_it_in_display_line_to (it, closest_pos, -1,
9187 MOVE_TO_POS);
9188 result = MOVE_POS_MATCH_OR_ZV;
9190 else
9191 goto buffer_pos_reached;
9193 else if (it->line_wrap == WORD_WRAP && atpos_it.sp >= 0
9194 && IT_CHARPOS (*it) > to_charpos)
9195 goto buffer_pos_reached;
9196 else
9197 result = MOVE_NEWLINE_OR_CR;
9199 else
9200 result = MOVE_NEWLINE_OR_CR;
9201 /* If we've processed the newline, make sure this flag is
9202 reset, as it must only be set when the newline itself is
9203 processed. */
9204 if (result == MOVE_NEWLINE_OR_CR)
9205 it->constrain_row_ascent_descent_p = false;
9206 break;
9209 prev_method = it->method;
9210 if (it->method == GET_FROM_BUFFER)
9211 prev_pos = IT_CHARPOS (*it);
9213 /* Detect overly-wide wrap-prefixes made of (space ...) display
9214 properties. When such a wrap prefix reaches past the right
9215 margin of the window, we need to avoid the call to
9216 set_iterator_to_next below, so that it->line_wrap is left at
9217 its TRUNCATE value wisely set by handle_line_prefix.
9218 Otherwise, set_iterator_to_next will pop the iterator stack,
9219 restore it->line_wrap, and we might miss the opportunity to
9220 exit the loop and return. */
9221 bool overwide_wrap_prefix =
9222 CONSP (it->object) && EQ (XCAR (it->object), Qspace)
9223 && it->sp > 0 && it->method == GET_FROM_STRETCH
9224 && it->current_x >= it->last_visible_x
9225 && it->continuation_lines_width > 0
9226 && it->line_wrap == TRUNCATE && it->stack[0].line_wrap != TRUNCATE;
9227 /* The current display element has been consumed. Advance
9228 to the next. */
9229 if (!overwide_wrap_prefix)
9230 set_iterator_to_next (it, true);
9231 if (IT_CHARPOS (*it) < CHARPOS (this_line_min_pos))
9232 SET_TEXT_POS (this_line_min_pos, IT_CHARPOS (*it), IT_BYTEPOS (*it));
9233 if (IT_CHARPOS (*it) < to_charpos)
9234 saw_smaller_pos = true;
9235 if (it->bidi_p
9236 && (op & MOVE_TO_POS)
9237 && IT_CHARPOS (*it) >= to_charpos
9238 && IT_CHARPOS (*it) < closest_pos)
9239 closest_pos = IT_CHARPOS (*it);
9241 /* Stop if lines are truncated and IT's current x-position is
9242 past the right edge of the window now. */
9243 if (it->line_wrap == TRUNCATE
9244 && it->current_x >= it->last_visible_x)
9246 if (!FRAME_WINDOW_P (it->f)
9247 || ((it->bidi_p && it->bidi_it.paragraph_dir == R2L)
9248 ? WINDOW_LEFT_FRINGE_WIDTH (it->w)
9249 : WINDOW_RIGHT_FRINGE_WIDTH (it->w)) == 0
9250 || IT_OVERFLOW_NEWLINE_INTO_FRINGE (it))
9252 bool at_eob_p = false;
9254 if ((at_eob_p = !get_next_display_element (it))
9255 || BUFFER_POS_REACHED_P ()
9256 /* If we are past TO_CHARPOS, but never saw any
9257 character positions smaller than TO_CHARPOS,
9258 return MOVE_POS_MATCH_OR_ZV, like the
9259 unidirectional display did. */
9260 || (it->bidi_p && (op & MOVE_TO_POS) != 0
9261 && !saw_smaller_pos
9262 && IT_CHARPOS (*it) > to_charpos))
9264 if (it->bidi_p
9265 && !BUFFER_POS_REACHED_P ()
9266 && !at_eob_p && closest_pos < ZV)
9268 RESTORE_IT (it, &ppos_it, ppos_data);
9269 if (closest_pos != to_charpos)
9270 move_it_in_display_line_to (it, closest_pos, -1,
9271 MOVE_TO_POS);
9273 result = MOVE_POS_MATCH_OR_ZV;
9274 break;
9276 if (ITERATOR_AT_END_OF_LINE_P (it))
9278 result = MOVE_NEWLINE_OR_CR;
9279 break;
9282 else if (it->bidi_p && (op & MOVE_TO_POS) != 0
9283 && !saw_smaller_pos
9284 && IT_CHARPOS (*it) > to_charpos)
9286 if (closest_pos < ZV)
9288 RESTORE_IT (it, &ppos_it, ppos_data);
9289 if (closest_pos != to_charpos)
9290 move_it_in_display_line_to (it, closest_pos, -1,
9291 MOVE_TO_POS);
9293 result = MOVE_POS_MATCH_OR_ZV;
9294 break;
9296 result = MOVE_LINE_TRUNCATED;
9297 break;
9299 #undef IT_RESET_X_ASCENT_DESCENT
9302 #undef BUFFER_POS_REACHED_P
9304 /* If we scanned beyond TO_POS, restore the saved iterator either to
9305 the wrap point (if found), or to atpos/atx location. We decide which
9306 data to use to restore the saved iterator state by their X coordinates,
9307 since buffer positions might increase non-monotonically with screen
9308 coordinates due to bidi reordering. */
9309 if (result == MOVE_LINE_CONTINUED
9310 && it->line_wrap == WORD_WRAP
9311 && wrap_it.sp >= 0
9312 && ((atpos_it.sp >= 0 && wrap_it.current_x < atpos_it.current_x)
9313 || (atx_it.sp >= 0 && wrap_it.current_x < atx_it.current_x)))
9314 RESTORE_IT (it, &wrap_it, wrap_data);
9315 else if (atpos_it.sp >= 0)
9316 RESTORE_IT (it, &atpos_it, atpos_data);
9317 else if (atx_it.sp >= 0)
9318 RESTORE_IT (it, &atx_it, atx_data);
9320 done:
9322 if (atpos_data)
9323 bidi_unshelve_cache (atpos_data, true);
9324 if (atx_data)
9325 bidi_unshelve_cache (atx_data, true);
9326 if (wrap_data)
9327 bidi_unshelve_cache (wrap_data, true);
9328 if (ppos_data)
9329 bidi_unshelve_cache (ppos_data, true);
9331 /* Restore the iterator settings altered at the beginning of this
9332 function. */
9333 it->glyph_row = saved_glyph_row;
9334 return result;
9337 /* For external use. */
9338 void
9339 move_it_in_display_line (struct it *it,
9340 ptrdiff_t to_charpos, int to_x,
9341 enum move_operation_enum op)
9343 if (it->line_wrap == WORD_WRAP
9344 && (op & MOVE_TO_X))
9346 struct it save_it;
9347 void *save_data = NULL;
9348 int skip;
9350 SAVE_IT (save_it, *it, save_data);
9351 skip = move_it_in_display_line_to (it, to_charpos, to_x, op);
9352 /* When word-wrap is on, TO_X may lie past the end
9353 of a wrapped line. Then it->current is the
9354 character on the next line, so backtrack to the
9355 space before the wrap point. */
9356 if (skip == MOVE_LINE_CONTINUED)
9358 int prev_x = max (it->current_x - 1, 0);
9359 RESTORE_IT (it, &save_it, save_data);
9360 move_it_in_display_line_to
9361 (it, -1, prev_x, MOVE_TO_X);
9363 else
9364 bidi_unshelve_cache (save_data, true);
9366 else
9367 move_it_in_display_line_to (it, to_charpos, to_x, op);
9371 /* Move IT forward until it satisfies one or more of the criteria in
9372 TO_CHARPOS, TO_X, TO_Y, and TO_VPOS.
9374 OP is a bit-mask that specifies where to stop, and in particular,
9375 which of those four position arguments makes a difference. See the
9376 description of enum move_operation_enum.
9378 If TO_CHARPOS is in invisible text, e.g. a truncated part of a
9379 screen line, this function will set IT to the next position that is
9380 displayed to the right of TO_CHARPOS on the screen.
9382 Return the maximum pixel length of any line scanned but never more
9383 than it.last_visible_x. */
9386 move_it_to (struct it *it, ptrdiff_t to_charpos, int to_x, int to_y, int to_vpos, int op)
9388 enum move_it_result skip, skip2 = MOVE_X_REACHED;
9389 int line_height, line_start_x = 0, reached = 0;
9390 int max_current_x = 0;
9391 void *backup_data = NULL;
9393 for (;;)
9395 if (op & MOVE_TO_VPOS)
9397 /* If no TO_CHARPOS and no TO_X specified, stop at the
9398 start of the line TO_VPOS. */
9399 if ((op & (MOVE_TO_X | MOVE_TO_POS)) == 0)
9401 if (it->vpos == to_vpos)
9403 reached = 1;
9404 break;
9406 else
9407 skip = move_it_in_display_line_to (it, -1, -1, 0);
9409 else
9411 /* TO_VPOS >= 0 means stop at TO_X in the line at
9412 TO_VPOS, or at TO_POS, whichever comes first. */
9413 if (it->vpos == to_vpos)
9415 reached = 2;
9416 break;
9419 skip = move_it_in_display_line_to (it, to_charpos, to_x, op);
9421 if (skip == MOVE_POS_MATCH_OR_ZV || it->vpos == to_vpos)
9423 reached = 3;
9424 break;
9426 else if (skip == MOVE_X_REACHED && it->vpos != to_vpos)
9428 /* We have reached TO_X but not in the line we want. */
9429 skip = move_it_in_display_line_to (it, to_charpos,
9430 -1, MOVE_TO_POS);
9431 if (skip == MOVE_POS_MATCH_OR_ZV)
9433 reached = 4;
9434 break;
9439 else if (op & MOVE_TO_Y)
9441 struct it it_backup;
9443 if (it->line_wrap == WORD_WRAP)
9444 SAVE_IT (it_backup, *it, backup_data);
9446 /* TO_Y specified means stop at TO_X in the line containing
9447 TO_Y---or at TO_CHARPOS if this is reached first. The
9448 problem is that we can't really tell whether the line
9449 contains TO_Y before we have completely scanned it, and
9450 this may skip past TO_X. What we do is to first scan to
9451 TO_X.
9453 If TO_X is not specified, use a TO_X of zero. The reason
9454 is to make the outcome of this function more predictable.
9455 If we didn't use TO_X == 0, we would stop at the end of
9456 the line which is probably not what a caller would expect
9457 to happen. */
9458 skip = move_it_in_display_line_to
9459 (it, to_charpos, ((op & MOVE_TO_X) ? to_x : 0),
9460 (MOVE_TO_X | (op & MOVE_TO_POS)));
9462 /* If TO_CHARPOS is reached or ZV, we don't have to do more. */
9463 if (skip == MOVE_POS_MATCH_OR_ZV)
9464 reached = 5;
9465 else if (skip == MOVE_X_REACHED)
9467 /* If TO_X was reached, we want to know whether TO_Y is
9468 in the line. We know this is the case if the already
9469 scanned glyphs make the line tall enough. Otherwise,
9470 we must check by scanning the rest of the line. */
9471 line_height = it->max_ascent + it->max_descent;
9472 if (to_y >= it->current_y
9473 && to_y < it->current_y + line_height)
9475 reached = 6;
9476 break;
9478 SAVE_IT (it_backup, *it, backup_data);
9479 TRACE_MOVE ((stderr, "move_it: from %d\n", IT_CHARPOS (*it)));
9480 skip2 = move_it_in_display_line_to (it, to_charpos, -1,
9481 op & MOVE_TO_POS);
9482 TRACE_MOVE ((stderr, "move_it: to %d\n", IT_CHARPOS (*it)));
9483 line_height = it->max_ascent + it->max_descent;
9484 TRACE_MOVE ((stderr, "move_it: line_height = %d\n", line_height));
9486 if (to_y >= it->current_y
9487 && to_y < it->current_y + line_height)
9489 /* If TO_Y is in this line and TO_X was reached
9490 above, we scanned too far. We have to restore
9491 IT's settings to the ones before skipping. But
9492 keep the more accurate values of max_ascent and
9493 max_descent we've found while skipping the rest
9494 of the line, for the sake of callers, such as
9495 pos_visible_p, that need to know the line
9496 height. */
9497 int max_ascent = it->max_ascent;
9498 int max_descent = it->max_descent;
9500 RESTORE_IT (it, &it_backup, backup_data);
9501 it->max_ascent = max_ascent;
9502 it->max_descent = max_descent;
9503 reached = 6;
9505 else
9507 skip = skip2;
9508 if (skip == MOVE_POS_MATCH_OR_ZV)
9509 reached = 7;
9512 else
9514 /* Check whether TO_Y is in this line. */
9515 line_height = it->max_ascent + it->max_descent;
9516 TRACE_MOVE ((stderr, "move_it: line_height = %d\n", line_height));
9518 if (to_y >= it->current_y
9519 && to_y < it->current_y + line_height)
9521 if (to_y > it->current_y)
9522 max_current_x = max (it->current_x, max_current_x);
9524 /* When word-wrap is on, TO_X may lie past the end
9525 of a wrapped line. Then it->current is the
9526 character on the next line, so backtrack to the
9527 space before the wrap point. */
9528 if (skip == MOVE_LINE_CONTINUED
9529 && it->line_wrap == WORD_WRAP)
9531 int prev_x = max (it->current_x - 1, 0);
9532 RESTORE_IT (it, &it_backup, backup_data);
9533 skip = move_it_in_display_line_to
9534 (it, -1, prev_x, MOVE_TO_X);
9537 reached = 6;
9541 if (reached)
9543 max_current_x = max (it->current_x, max_current_x);
9544 break;
9547 else if (BUFFERP (it->object)
9548 && (it->method == GET_FROM_BUFFER
9549 || it->method == GET_FROM_STRETCH)
9550 && IT_CHARPOS (*it) >= to_charpos
9551 /* Under bidi iteration, a call to set_iterator_to_next
9552 can scan far beyond to_charpos if the initial
9553 portion of the next line needs to be reordered. In
9554 that case, give move_it_in_display_line_to another
9555 chance below. */
9556 && !(it->bidi_p
9557 && it->bidi_it.scan_dir == -1))
9558 skip = MOVE_POS_MATCH_OR_ZV;
9559 else
9560 skip = move_it_in_display_line_to (it, to_charpos, -1, MOVE_TO_POS);
9562 switch (skip)
9564 case MOVE_POS_MATCH_OR_ZV:
9565 max_current_x = max (it->current_x, max_current_x);
9566 reached = 8;
9567 goto out;
9569 case MOVE_NEWLINE_OR_CR:
9570 max_current_x = max (it->current_x, max_current_x);
9571 set_iterator_to_next (it, true);
9572 it->continuation_lines_width = 0;
9573 break;
9575 case MOVE_LINE_TRUNCATED:
9576 max_current_x = it->last_visible_x;
9577 it->continuation_lines_width = 0;
9578 reseat_at_next_visible_line_start (it, false);
9579 if ((op & MOVE_TO_POS) != 0
9580 && IT_CHARPOS (*it) > to_charpos)
9582 reached = 9;
9583 goto out;
9585 break;
9587 case MOVE_LINE_CONTINUED:
9588 max_current_x = it->last_visible_x;
9589 /* For continued lines ending in a tab, some of the glyphs
9590 associated with the tab are displayed on the current
9591 line. Since it->current_x does not include these glyphs,
9592 we use it->last_visible_x instead. */
9593 if (it->c == '\t')
9595 it->continuation_lines_width += it->last_visible_x;
9596 /* When moving by vpos, ensure that the iterator really
9597 advances to the next line (bug#847, bug#969). Fixme:
9598 do we need to do this in other circumstances? */
9599 if (it->current_x != it->last_visible_x
9600 && (op & MOVE_TO_VPOS)
9601 && !(op & (MOVE_TO_X | MOVE_TO_POS)))
9603 line_start_x = it->current_x + it->pixel_width
9604 - it->last_visible_x;
9605 if (FRAME_WINDOW_P (it->f))
9607 struct face *face = FACE_FROM_ID (it->f, it->face_id);
9608 struct font *face_font = face->font;
9610 /* When display_line produces a continued line
9611 that ends in a TAB, it skips a tab stop that
9612 is closer than the font's space character
9613 width (see x_produce_glyphs where it produces
9614 the stretch glyph which represents a TAB).
9615 We need to reproduce the same logic here. */
9616 eassert (face_font);
9617 if (face_font)
9619 if (line_start_x < face_font->space_width)
9620 line_start_x
9621 += it->tab_width * face_font->space_width;
9624 set_iterator_to_next (it, false);
9627 else
9628 it->continuation_lines_width += it->current_x;
9629 break;
9631 default:
9632 emacs_abort ();
9635 /* Reset/increment for the next run. */
9636 recenter_overlay_lists (current_buffer, IT_CHARPOS (*it));
9637 it->current_x = line_start_x;
9638 line_start_x = 0;
9639 it->hpos = 0;
9640 it->line_number_produced_p = false;
9641 it->current_y += it->max_ascent + it->max_descent;
9642 ++it->vpos;
9643 last_height = it->max_ascent + it->max_descent;
9644 it->max_ascent = it->max_descent = 0;
9647 out:
9649 /* On text terminals, we may stop at the end of a line in the middle
9650 of a multi-character glyph. If the glyph itself is continued,
9651 i.e. it is actually displayed on the next line, don't treat this
9652 stopping point as valid; move to the next line instead (unless
9653 that brings us offscreen). */
9654 if (!FRAME_WINDOW_P (it->f)
9655 && op & MOVE_TO_POS
9656 && IT_CHARPOS (*it) == to_charpos
9657 && it->what == IT_CHARACTER
9658 && it->nglyphs > 1
9659 && it->line_wrap == WINDOW_WRAP
9660 && it->current_x == it->last_visible_x - 1
9661 && it->c != '\n'
9662 && it->c != '\t'
9663 && it->w->window_end_valid
9664 && it->vpos < it->w->window_end_vpos)
9666 it->continuation_lines_width += it->current_x;
9667 it->current_x = it->hpos = it->max_ascent = it->max_descent = 0;
9668 it->current_y += it->max_ascent + it->max_descent;
9669 ++it->vpos;
9670 last_height = it->max_ascent + it->max_descent;
9673 if (backup_data)
9674 bidi_unshelve_cache (backup_data, true);
9676 TRACE_MOVE ((stderr, "move_it_to: reached %d\n", reached));
9678 return max_current_x;
9682 /* Move iterator IT backward by a specified y-distance DY, DY >= 0.
9684 If DY > 0, move IT backward at least that many pixels. DY = 0
9685 means move IT backward to the preceding line start or BEGV. This
9686 function may move over more than DY pixels if IT->current_y - DY
9687 ends up in the middle of a line; in this case IT->current_y will be
9688 set to the top of the line moved to. */
9690 void
9691 move_it_vertically_backward (struct it *it, int dy)
9693 int nlines, h;
9694 struct it it2, it3;
9695 void *it2data = NULL, *it3data = NULL;
9696 ptrdiff_t start_pos;
9697 int nchars_per_row
9698 = (it->last_visible_x - it->first_visible_x) / FRAME_COLUMN_WIDTH (it->f);
9699 ptrdiff_t pos_limit;
9701 move_further_back:
9702 eassert (dy >= 0);
9704 start_pos = IT_CHARPOS (*it);
9706 /* Estimate how many newlines we must move back. */
9707 nlines = max (1, dy / default_line_pixel_height (it->w));
9708 if (it->line_wrap == TRUNCATE || nchars_per_row == 0)
9709 pos_limit = BEGV;
9710 else
9711 pos_limit = max (start_pos - nlines * nchars_per_row, BEGV);
9713 /* Set the iterator's position that many lines back. But don't go
9714 back more than NLINES full screen lines -- this wins a day with
9715 buffers which have very long lines. */
9716 while (nlines-- && IT_CHARPOS (*it) > pos_limit)
9717 back_to_previous_visible_line_start (it);
9719 /* Reseat the iterator here. When moving backward, we don't want
9720 reseat to skip forward over invisible text, set up the iterator
9721 to deliver from overlay strings at the new position etc. So,
9722 use reseat_1 here. */
9723 reseat_1 (it, it->current.pos, true);
9725 /* We are now surely at a line start. */
9726 it->current_x = it->hpos = 0; /* FIXME: this is incorrect when bidi
9727 reordering is in effect. */
9728 it->continuation_lines_width = 0;
9730 /* Move forward and see what y-distance we moved. First move to the
9731 start of the next line so that we get its height. We need this
9732 height to be able to tell whether we reached the specified
9733 y-distance. */
9734 SAVE_IT (it2, *it, it2data);
9735 it2.max_ascent = it2.max_descent = 0;
9738 move_it_to (&it2, start_pos, -1, -1, it2.vpos + 1,
9739 MOVE_TO_POS | MOVE_TO_VPOS);
9741 while (!(IT_POS_VALID_AFTER_MOVE_P (&it2)
9742 /* If we are in a display string which starts at START_POS,
9743 and that display string includes a newline, and we are
9744 right after that newline (i.e. at the beginning of a
9745 display line), exit the loop, because otherwise we will
9746 infloop, since move_it_to will see that it is already at
9747 START_POS and will not move. */
9748 || (it2.method == GET_FROM_STRING
9749 && IT_CHARPOS (it2) == start_pos
9750 && SREF (it2.string, IT_STRING_BYTEPOS (it2) - 1) == '\n')));
9751 eassert (IT_CHARPOS (*it) >= BEGV);
9752 SAVE_IT (it3, it2, it3data);
9754 move_it_to (&it2, start_pos, -1, -1, -1, MOVE_TO_POS);
9755 eassert (IT_CHARPOS (*it) >= BEGV);
9756 /* H is the actual vertical distance from the position in *IT
9757 and the starting position. */
9758 h = it2.current_y - it->current_y;
9759 /* NLINES is the distance in number of lines. */
9760 nlines = it2.vpos - it->vpos;
9762 /* Correct IT's y and vpos position
9763 so that they are relative to the starting point. */
9764 it->vpos -= nlines;
9765 it->current_y -= h;
9767 if (dy == 0)
9769 /* DY == 0 means move to the start of the screen line. The
9770 value of nlines is > 0 if continuation lines were involved,
9771 or if the original IT position was at start of a line. */
9772 RESTORE_IT (it, it, it2data);
9773 if (nlines > 0)
9774 move_it_by_lines (it, nlines);
9775 /* The above code moves us to some position NLINES down,
9776 usually to its first glyph (leftmost in an L2R line), but
9777 that's not necessarily the start of the line, under bidi
9778 reordering. We want to get to the character position
9779 that is immediately after the newline of the previous
9780 line. */
9781 if (it->bidi_p
9782 && !it->continuation_lines_width
9783 && !STRINGP (it->string)
9784 && IT_CHARPOS (*it) > BEGV
9785 && FETCH_BYTE (IT_BYTEPOS (*it) - 1) != '\n')
9787 ptrdiff_t cp = IT_CHARPOS (*it), bp = IT_BYTEPOS (*it);
9789 DEC_BOTH (cp, bp);
9790 cp = find_newline_no_quit (cp, bp, -1, NULL);
9791 move_it_to (it, cp, -1, -1, -1, MOVE_TO_POS);
9793 bidi_unshelve_cache (it3data, true);
9795 else
9797 /* The y-position we try to reach, relative to *IT.
9798 Note that H has been subtracted in front of the if-statement. */
9799 int target_y = it->current_y + h - dy;
9800 int y0 = it3.current_y;
9801 int y1;
9802 int line_height;
9804 RESTORE_IT (&it3, &it3, it3data);
9805 y1 = line_bottom_y (&it3);
9806 line_height = y1 - y0;
9807 RESTORE_IT (it, it, it2data);
9808 /* If we did not reach target_y, try to move further backward if
9809 we can. If we moved too far backward, try to move forward. */
9810 if (target_y < it->current_y
9811 /* This is heuristic. In a window that's 3 lines high, with
9812 a line height of 13 pixels each, recentering with point
9813 on the bottom line will try to move -39/2 = 19 pixels
9814 backward. Try to avoid moving into the first line. */
9815 && (it->current_y - target_y
9816 > min (window_box_height (it->w), line_height * 2 / 3))
9817 && IT_CHARPOS (*it) > BEGV)
9819 TRACE_MOVE ((stderr, " not far enough -> move_vert %d\n",
9820 target_y - it->current_y));
9821 dy = it->current_y - target_y;
9822 goto move_further_back;
9824 else if (target_y >= it->current_y + line_height
9825 && IT_CHARPOS (*it) < ZV)
9827 /* Should move forward by at least one line, maybe more.
9829 Note: Calling move_it_by_lines can be expensive on
9830 terminal frames, where compute_motion is used (via
9831 vmotion) to do the job, when there are very long lines
9832 and truncate-lines is nil. That's the reason for
9833 treating terminal frames specially here. */
9835 if (!FRAME_WINDOW_P (it->f))
9836 move_it_vertically (it, target_y - it->current_y);
9837 else
9841 move_it_by_lines (it, 1);
9843 while (target_y >= line_bottom_y (it) && IT_CHARPOS (*it) < ZV);
9850 /* Move IT by a specified amount of pixel lines DY. DY negative means
9851 move backwards. DY = 0 means move to start of screen line. At the
9852 end, IT will be on the start of a screen line. */
9854 void
9855 move_it_vertically (struct it *it, int dy)
9857 if (dy <= 0)
9858 move_it_vertically_backward (it, -dy);
9859 else
9861 TRACE_MOVE ((stderr, "move_it_v: from %d, %d\n", IT_CHARPOS (*it), dy));
9862 move_it_to (it, ZV, -1, it->current_y + dy, -1,
9863 MOVE_TO_POS | MOVE_TO_Y);
9864 TRACE_MOVE ((stderr, "move_it_v: to %d\n", IT_CHARPOS (*it)));
9866 /* If buffer ends in ZV without a newline, move to the start of
9867 the line to satisfy the post-condition. */
9868 if (IT_CHARPOS (*it) == ZV
9869 && ZV > BEGV
9870 && FETCH_BYTE (IT_BYTEPOS (*it) - 1) != '\n')
9871 move_it_by_lines (it, 0);
9876 /* Move iterator IT past the end of the text line it is in. */
9878 void
9879 move_it_past_eol (struct it *it)
9881 enum move_it_result rc;
9883 rc = move_it_in_display_line_to (it, Z, 0, MOVE_TO_POS);
9884 if (rc == MOVE_NEWLINE_OR_CR)
9885 set_iterator_to_next (it, false);
9889 /* Move IT by a specified number DVPOS of screen lines down. DVPOS
9890 negative means move up. DVPOS == 0 means move to the start of the
9891 screen line.
9893 Optimization idea: If we would know that IT->f doesn't use
9894 a face with proportional font, we could be faster for
9895 truncate-lines nil. */
9897 void
9898 move_it_by_lines (struct it *it, ptrdiff_t dvpos)
9901 /* The commented-out optimization uses vmotion on terminals. This
9902 gives bad results, because elements like it->what, on which
9903 callers such as pos_visible_p rely, aren't updated. */
9904 /* struct position pos;
9905 if (!FRAME_WINDOW_P (it->f))
9907 struct text_pos textpos;
9909 pos = *vmotion (IT_CHARPOS (*it), dvpos, it->w);
9910 SET_TEXT_POS (textpos, pos.bufpos, pos.bytepos);
9911 reseat (it, textpos, true);
9912 it->vpos += pos.vpos;
9913 it->current_y += pos.vpos;
9915 else */
9917 if (dvpos == 0)
9919 /* DVPOS == 0 means move to the start of the screen line. */
9920 move_it_vertically_backward (it, 0);
9921 /* Let next call to line_bottom_y calculate real line height. */
9922 last_height = 0;
9924 else if (dvpos > 0)
9926 move_it_to (it, -1, -1, -1, it->vpos + dvpos, MOVE_TO_VPOS);
9927 if (!IT_POS_VALID_AFTER_MOVE_P (it))
9929 /* Only move to the next buffer position if we ended up in a
9930 string from display property, not in an overlay string
9931 (before-string or after-string). That is because the
9932 latter don't conceal the underlying buffer position, so
9933 we can ask to move the iterator to the exact position we
9934 are interested in. Note that, even if we are already at
9935 IT_CHARPOS (*it), the call below is not a no-op, as it
9936 will detect that we are at the end of the string, pop the
9937 iterator, and compute it->current_x and it->hpos
9938 correctly. */
9939 move_it_to (it, IT_CHARPOS (*it) + it->string_from_display_prop_p,
9940 -1, -1, -1, MOVE_TO_POS);
9943 else
9945 struct it it2;
9946 void *it2data = NULL;
9947 ptrdiff_t start_charpos, i;
9948 int nchars_per_row
9949 = (it->last_visible_x - it->first_visible_x) / FRAME_COLUMN_WIDTH (it->f);
9950 bool hit_pos_limit = false;
9951 ptrdiff_t pos_limit;
9953 /* Start at the beginning of the screen line containing IT's
9954 position. This may actually move vertically backwards,
9955 in case of overlays, so adjust dvpos accordingly. */
9956 dvpos += it->vpos;
9957 move_it_vertically_backward (it, 0);
9958 dvpos -= it->vpos;
9960 /* Go back -DVPOS buffer lines, but no farther than -DVPOS full
9961 screen lines, and reseat the iterator there. */
9962 start_charpos = IT_CHARPOS (*it);
9963 if (it->line_wrap == TRUNCATE || nchars_per_row == 0)
9964 pos_limit = BEGV;
9965 else
9966 pos_limit = max (start_charpos + dvpos * nchars_per_row, BEGV);
9968 for (i = -dvpos; i > 0 && IT_CHARPOS (*it) > pos_limit; --i)
9969 back_to_previous_visible_line_start (it);
9970 if (i > 0 && IT_CHARPOS (*it) <= pos_limit)
9971 hit_pos_limit = true;
9972 reseat (it, it->current.pos, true);
9974 /* Move further back if we end up in a string or an image. */
9975 while (!IT_POS_VALID_AFTER_MOVE_P (it))
9977 /* First try to move to start of display line. */
9978 dvpos += it->vpos;
9979 move_it_vertically_backward (it, 0);
9980 dvpos -= it->vpos;
9981 if (IT_POS_VALID_AFTER_MOVE_P (it))
9982 break;
9983 /* If start of line is still in string or image,
9984 move further back. */
9985 back_to_previous_visible_line_start (it);
9986 reseat (it, it->current.pos, true);
9987 dvpos--;
9990 it->current_x = it->hpos = 0;
9992 /* Above call may have moved too far if continuation lines
9993 are involved. Scan forward and see if it did. */
9994 SAVE_IT (it2, *it, it2data);
9995 it2.vpos = it2.current_y = 0;
9996 move_it_to (&it2, start_charpos, -1, -1, -1, MOVE_TO_POS);
9997 it->vpos -= it2.vpos;
9998 it->current_y -= it2.current_y;
9999 it->current_x = it->hpos = 0;
10001 /* If we moved too far back, move IT some lines forward. */
10002 if (it2.vpos > -dvpos)
10004 int delta = it2.vpos + dvpos;
10006 RESTORE_IT (&it2, &it2, it2data);
10007 SAVE_IT (it2, *it, it2data);
10008 move_it_to (it, -1, -1, -1, it->vpos + delta, MOVE_TO_VPOS);
10009 /* Move back again if we got too far ahead. */
10010 if (IT_CHARPOS (*it) >= start_charpos)
10011 RESTORE_IT (it, &it2, it2data);
10012 else
10013 bidi_unshelve_cache (it2data, true);
10015 else if (hit_pos_limit && pos_limit > BEGV
10016 && dvpos < 0 && it2.vpos < -dvpos)
10018 /* If we hit the limit, but still didn't make it far enough
10019 back, that means there's a display string with a newline
10020 covering a large chunk of text, and that caused
10021 back_to_previous_visible_line_start try to go too far.
10022 Punish those who commit such atrocities by going back
10023 until we've reached DVPOS, after lifting the limit, which
10024 could make it slow for very long lines. "If it hurts,
10025 don't do that!" */
10026 dvpos += it2.vpos;
10027 RESTORE_IT (it, it, it2data);
10028 for (i = -dvpos; i > 0; --i)
10030 back_to_previous_visible_line_start (it);
10031 it->vpos--;
10033 reseat_1 (it, it->current.pos, true);
10035 else
10036 RESTORE_IT (it, it, it2data);
10041 partial_line_height (struct it *it_origin)
10043 int partial_height;
10044 void *it_data = NULL;
10045 struct it it;
10046 SAVE_IT (it, *it_origin, it_data);
10047 move_it_to (&it, ZV, -1, it.last_visible_y, -1,
10048 MOVE_TO_POS | MOVE_TO_Y);
10049 if (it.what == IT_EOB)
10051 int vis_height = it.last_visible_y - it.current_y;
10052 int height = it.ascent + it.descent;
10053 partial_height = (vis_height < height) ? vis_height : 0;
10055 else
10057 int last_line_y = it.current_y;
10058 move_it_by_lines (&it, 1);
10059 partial_height = (it.current_y > it.last_visible_y)
10060 ? it.last_visible_y - last_line_y : 0;
10062 RESTORE_IT (&it, &it, it_data);
10063 return partial_height;
10066 /* Return true if IT points into the middle of a display vector. */
10068 bool
10069 in_display_vector_p (struct it *it)
10071 return (it->method == GET_FROM_DISPLAY_VECTOR
10072 && it->current.dpvec_index > 0
10073 && it->dpvec + it->current.dpvec_index != it->dpend);
10076 DEFUN ("window-text-pixel-size", Fwindow_text_pixel_size, Swindow_text_pixel_size, 0, 6, 0,
10077 doc: /* Return the size of the text of WINDOW's buffer in pixels.
10078 WINDOW must be a live window and defaults to the selected one. The
10079 return value is a cons of the maximum pixel-width of any text line and
10080 the maximum pixel-height of all text lines.
10082 The optional argument FROM, if non-nil, specifies the first text
10083 position and defaults to the minimum accessible position of the buffer.
10084 If FROM is t, use the minimum accessible position that starts a
10085 non-empty line. TO, if non-nil, specifies the last text position and
10086 defaults to the maximum accessible position of the buffer. If TO is t,
10087 use the maximum accessible position that ends a non-empty line.
10089 The optional argument X-LIMIT, if non-nil, specifies the maximum text
10090 width that can be returned. X-LIMIT nil or omitted, means to use the
10091 pixel-width of WINDOW's body; use this if you want to know how high
10092 WINDOW should be become in order to fit all of its buffer's text with
10093 the width of WINDOW unaltered. Use the maximum width WINDOW may assume
10094 if you intend to change WINDOW's width. In any case, text whose
10095 x-coordinate is beyond X-LIMIT is ignored. Since calculating the width
10096 of long lines can take some time, it's always a good idea to make this
10097 argument as small as possible; in particular, if the buffer contains
10098 long lines that shall be truncated anyway.
10100 The optional argument Y-LIMIT, if non-nil, specifies the maximum text
10101 height (excluding the height of the mode- or header-line, if any) that
10102 can be returned. Text lines whose y-coordinate is beyond Y-LIMIT are
10103 ignored. Since calculating the text height of a large buffer can take
10104 some time, it makes sense to specify this argument if the size of the
10105 buffer is large or unknown.
10107 Optional argument MODE-AND-HEADER-LINE nil or omitted means do not
10108 include the height of the mode- or header-line of WINDOW in the return
10109 value. If it is either the symbol `mode-line' or `header-line', include
10110 only the height of that line, if present, in the return value. If t,
10111 include the height of both, if present, in the return value. */)
10112 (Lisp_Object window, Lisp_Object from, Lisp_Object to, Lisp_Object x_limit,
10113 Lisp_Object y_limit, Lisp_Object mode_and_header_line)
10115 struct window *w = decode_live_window (window);
10116 Lisp_Object buffer = w->contents;
10117 struct buffer *b;
10118 struct it it;
10119 struct buffer *old_b = NULL;
10120 ptrdiff_t start, end, pos;
10121 struct text_pos startp;
10122 void *itdata = NULL;
10123 int c, max_x = 0, max_y = 0, x = 0, y = 0;
10125 CHECK_BUFFER (buffer);
10126 b = XBUFFER (buffer);
10128 if (b != current_buffer)
10130 old_b = current_buffer;
10131 set_buffer_internal (b);
10134 if (NILP (from))
10135 start = BEGV;
10136 else if (EQ (from, Qt))
10138 start = pos = BEGV;
10139 while ((pos++ < ZV) && (c = FETCH_CHAR (pos))
10140 && (c == ' ' || c == '\t' || c == '\n' || c == '\r'))
10141 start = pos;
10142 while ((pos-- > BEGV) && (c = FETCH_CHAR (pos)) && (c == ' ' || c == '\t'))
10143 start = pos;
10145 else
10147 CHECK_NUMBER_COERCE_MARKER (from);
10148 start = min (max (XINT (from), BEGV), ZV);
10151 if (NILP (to))
10152 end = ZV;
10153 else if (EQ (to, Qt))
10155 end = pos = ZV;
10156 while ((pos-- > BEGV) && (c = FETCH_CHAR (pos))
10157 && (c == ' ' || c == '\t' || c == '\n' || c == '\r'))
10158 end = pos;
10159 while ((pos++ < ZV) && (c = FETCH_CHAR (pos)) && (c == ' ' || c == '\t'))
10160 end = pos;
10162 else
10164 CHECK_NUMBER_COERCE_MARKER (to);
10165 end = max (start, min (XINT (to), ZV));
10168 if (!NILP (x_limit) && RANGED_INTEGERP (0, x_limit, INT_MAX))
10169 max_x = XINT (x_limit);
10171 if (NILP (y_limit))
10172 max_y = INT_MAX;
10173 else if (RANGED_INTEGERP (0, y_limit, INT_MAX))
10174 max_y = XINT (y_limit);
10176 itdata = bidi_shelve_cache ();
10177 SET_TEXT_POS (startp, start, CHAR_TO_BYTE (start));
10178 start_display (&it, w, startp);
10179 /* It makes no sense to measure dimensions of region of text that
10180 crosses the point where bidi reordering changes scan direction.
10181 By using unidirectional movement here we at least support the use
10182 case of measuring regions of text that have a uniformly R2L
10183 directionality, and regions that begin and end in text of the
10184 same directionality. */
10185 it.bidi_p = false;
10187 int move_op = MOVE_TO_POS | MOVE_TO_Y;
10188 int to_x = -1;
10189 if (!NILP (x_limit))
10191 it.last_visible_x = max_x;
10192 /* Actually, we never want move_it_to stop at to_x. But to make
10193 sure that move_it_in_display_line_to always moves far enough,
10194 we set to_x to INT_MAX and specify MOVE_TO_X. */
10195 move_op |= MOVE_TO_X;
10196 to_x = INT_MAX;
10199 void *it2data = NULL;
10200 struct it it2;
10201 SAVE_IT (it2, it, it2data);
10203 x = move_it_to (&it, end, to_x, max_y, -1, move_op);
10205 /* We could have a display property at END, in which case asking
10206 move_it_to to stop at END will overshoot and stop at position
10207 after END. So we try again, stopping before END, and account for
10208 the width of the last buffer position manually. */
10209 if (IT_CHARPOS (it) > end)
10211 end--;
10212 RESTORE_IT (&it, &it2, it2data);
10213 x = move_it_to (&it, end, to_x, max_y, -1, move_op);
10214 /* Add the width of the thing at TO, but only if we didn't
10215 overshoot it; if we did, it is already accounted for. Also,
10216 account for the height of the thing at TO. */
10217 if (IT_CHARPOS (it) == end)
10219 x += it.pixel_width;
10220 it.max_ascent = max (it.max_ascent, it.ascent);
10221 it.max_descent = max (it.max_descent, it.descent);
10224 if (!NILP (x_limit))
10226 /* Don't return more than X-LIMIT. */
10227 if (x > max_x)
10228 x = max_x;
10231 /* Subtract height of header-line which was counted automatically by
10232 start_display. */
10233 y = it.current_y + it.max_ascent + it.max_descent
10234 - WINDOW_HEADER_LINE_HEIGHT (w);
10235 /* Don't return more than Y-LIMIT. */
10236 if (y > max_y)
10237 y = max_y;
10239 if (EQ (mode_and_header_line, Qheader_line)
10240 || EQ (mode_and_header_line, Qt))
10241 /* Re-add height of header-line as requested. */
10242 y = y + WINDOW_HEADER_LINE_HEIGHT (w);
10244 if (EQ (mode_and_header_line, Qmode_line)
10245 || EQ (mode_and_header_line, Qt))
10246 /* Add height of mode-line as requested. */
10247 y = y + WINDOW_MODE_LINE_HEIGHT (w);
10249 bidi_unshelve_cache (itdata, false);
10251 if (old_b)
10252 set_buffer_internal (old_b);
10254 return Fcons (make_number (x), make_number (y));
10257 /***********************************************************************
10258 Messages
10259 ***********************************************************************/
10261 /* Return the number of arguments the format string FORMAT needs. */
10263 static ptrdiff_t
10264 format_nargs (char const *format)
10266 ptrdiff_t nargs = 0;
10267 for (char const *p = format; (p = strchr (p, '%')); p++)
10268 if (p[1] == '%')
10269 p++;
10270 else
10271 nargs++;
10272 return nargs;
10275 /* Add a message with format string FORMAT and formatted arguments
10276 to *Messages*. */
10278 void
10279 add_to_log (const char *format, ...)
10281 va_list ap;
10282 va_start (ap, format);
10283 vadd_to_log (format, ap);
10284 va_end (ap);
10287 void
10288 vadd_to_log (char const *format, va_list ap)
10290 ptrdiff_t form_nargs = format_nargs (format);
10291 ptrdiff_t nargs = 1 + form_nargs;
10292 Lisp_Object args[10];
10293 eassert (nargs <= ARRAYELTS (args));
10294 AUTO_STRING (args0, format);
10295 args[0] = args0;
10296 for (ptrdiff_t i = 1; i <= nargs; i++)
10297 args[i] = va_arg (ap, Lisp_Object);
10298 Lisp_Object msg = Qnil;
10299 msg = Fformat_message (nargs, args);
10301 ptrdiff_t len = SBYTES (msg) + 1;
10302 USE_SAFE_ALLOCA;
10303 char *buffer = SAFE_ALLOCA (len);
10304 memcpy (buffer, SDATA (msg), len);
10306 message_dolog (buffer, len - 1, true, STRING_MULTIBYTE (msg));
10307 SAFE_FREE ();
10311 /* Output a newline in the *Messages* buffer if "needs" one. */
10313 void
10314 message_log_maybe_newline (void)
10316 if (message_log_need_newline)
10317 message_dolog ("", 0, true, false);
10321 /* Add a string M of length NBYTES to the message log, optionally
10322 terminated with a newline when NLFLAG is true. MULTIBYTE, if
10323 true, means interpret the contents of M as multibyte. This
10324 function calls low-level routines in order to bypass text property
10325 hooks, etc. which might not be safe to run.
10327 This may GC (insert may run before/after change hooks),
10328 so the buffer M must NOT point to a Lisp string. */
10330 void
10331 message_dolog (const char *m, ptrdiff_t nbytes, bool nlflag, bool multibyte)
10333 const unsigned char *msg = (const unsigned char *) m;
10335 if (!NILP (Vmemory_full))
10336 return;
10338 if (!NILP (Vmessage_log_max))
10340 struct buffer *oldbuf;
10341 Lisp_Object oldpoint, oldbegv, oldzv;
10342 int old_windows_or_buffers_changed = windows_or_buffers_changed;
10343 ptrdiff_t point_at_end = 0;
10344 ptrdiff_t zv_at_end = 0;
10345 Lisp_Object old_deactivate_mark;
10347 old_deactivate_mark = Vdeactivate_mark;
10348 oldbuf = current_buffer;
10350 /* Ensure the Messages buffer exists, and switch to it.
10351 If we created it, set the major-mode. */
10352 bool newbuffer = NILP (Fget_buffer (Vmessages_buffer_name));
10353 Fset_buffer (Fget_buffer_create (Vmessages_buffer_name));
10354 if (newbuffer
10355 && !NILP (Ffboundp (intern ("messages-buffer-mode"))))
10356 call0 (intern ("messages-buffer-mode"));
10358 bset_undo_list (current_buffer, Qt);
10359 bset_cache_long_scans (current_buffer, Qnil);
10361 oldpoint = message_dolog_marker1;
10362 set_marker_restricted_both (oldpoint, Qnil, PT, PT_BYTE);
10363 oldbegv = message_dolog_marker2;
10364 set_marker_restricted_both (oldbegv, Qnil, BEGV, BEGV_BYTE);
10365 oldzv = message_dolog_marker3;
10366 set_marker_restricted_both (oldzv, Qnil, ZV, ZV_BYTE);
10368 if (PT == Z)
10369 point_at_end = 1;
10370 if (ZV == Z)
10371 zv_at_end = 1;
10373 BEGV = BEG;
10374 BEGV_BYTE = BEG_BYTE;
10375 ZV = Z;
10376 ZV_BYTE = Z_BYTE;
10377 TEMP_SET_PT_BOTH (Z, Z_BYTE);
10379 /* Insert the string--maybe converting multibyte to single byte
10380 or vice versa, so that all the text fits the buffer. */
10381 if (multibyte
10382 && NILP (BVAR (current_buffer, enable_multibyte_characters)))
10384 ptrdiff_t i;
10385 int c, char_bytes;
10386 char work[1];
10388 /* Convert a multibyte string to single-byte
10389 for the *Message* buffer. */
10390 for (i = 0; i < nbytes; i += char_bytes)
10392 c = string_char_and_length (msg + i, &char_bytes);
10393 work[0] = CHAR_TO_BYTE8 (c);
10394 insert_1_both (work, 1, 1, true, false, false);
10397 else if (! multibyte
10398 && ! NILP (BVAR (current_buffer, enable_multibyte_characters)))
10400 ptrdiff_t i;
10401 int c, char_bytes;
10402 unsigned char str[MAX_MULTIBYTE_LENGTH];
10403 /* Convert a single-byte string to multibyte
10404 for the *Message* buffer. */
10405 for (i = 0; i < nbytes; i++)
10407 c = msg[i];
10408 MAKE_CHAR_MULTIBYTE (c);
10409 char_bytes = CHAR_STRING (c, str);
10410 insert_1_both ((char *) str, 1, char_bytes, true, false, false);
10413 else if (nbytes)
10414 insert_1_both (m, chars_in_text (msg, nbytes), nbytes,
10415 true, false, false);
10417 if (nlflag)
10419 ptrdiff_t this_bol, this_bol_byte, prev_bol, prev_bol_byte;
10420 printmax_t dups;
10422 insert_1_both ("\n", 1, 1, true, false, false);
10424 scan_newline (Z, Z_BYTE, BEG, BEG_BYTE, -2, false);
10425 this_bol = PT;
10426 this_bol_byte = PT_BYTE;
10428 /* See if this line duplicates the previous one.
10429 If so, combine duplicates. */
10430 if (this_bol > BEG)
10432 scan_newline (PT, PT_BYTE, BEG, BEG_BYTE, -2, false);
10433 prev_bol = PT;
10434 prev_bol_byte = PT_BYTE;
10436 dups = message_log_check_duplicate (prev_bol_byte,
10437 this_bol_byte);
10438 if (dups)
10440 del_range_both (prev_bol, prev_bol_byte,
10441 this_bol, this_bol_byte, false);
10442 if (dups > 1)
10444 char dupstr[sizeof " [ times]"
10445 + INT_STRLEN_BOUND (printmax_t)];
10447 /* If you change this format, don't forget to also
10448 change message_log_check_duplicate. */
10449 int duplen = sprintf (dupstr, " [%"pMd" times]", dups);
10450 TEMP_SET_PT_BOTH (Z - 1, Z_BYTE - 1);
10451 insert_1_both (dupstr, duplen, duplen,
10452 true, false, true);
10457 /* If we have more than the desired maximum number of lines
10458 in the *Messages* buffer now, delete the oldest ones.
10459 This is safe because we don't have undo in this buffer. */
10461 if (NATNUMP (Vmessage_log_max))
10463 scan_newline (Z, Z_BYTE, BEG, BEG_BYTE,
10464 -XFASTINT (Vmessage_log_max) - 1, false);
10465 del_range_both (BEG, BEG_BYTE, PT, PT_BYTE, false);
10468 BEGV = marker_position (oldbegv);
10469 BEGV_BYTE = marker_byte_position (oldbegv);
10471 if (zv_at_end)
10473 ZV = Z;
10474 ZV_BYTE = Z_BYTE;
10476 else
10478 ZV = marker_position (oldzv);
10479 ZV_BYTE = marker_byte_position (oldzv);
10482 if (point_at_end)
10483 TEMP_SET_PT_BOTH (Z, Z_BYTE);
10484 else
10485 /* We can't do Fgoto_char (oldpoint) because it will run some
10486 Lisp code. */
10487 TEMP_SET_PT_BOTH (marker_position (oldpoint),
10488 marker_byte_position (oldpoint));
10490 unchain_marker (XMARKER (oldpoint));
10491 unchain_marker (XMARKER (oldbegv));
10492 unchain_marker (XMARKER (oldzv));
10494 /* We called insert_1_both above with its 5th argument (PREPARE)
10495 false, which prevents insert_1_both from calling
10496 prepare_to_modify_buffer, which in turns prevents us from
10497 incrementing windows_or_buffers_changed even if *Messages* is
10498 shown in some window. So we must manually set
10499 windows_or_buffers_changed here to make up for that. */
10500 windows_or_buffers_changed = old_windows_or_buffers_changed;
10501 bset_redisplay (current_buffer);
10503 set_buffer_internal (oldbuf);
10505 message_log_need_newline = !nlflag;
10506 Vdeactivate_mark = old_deactivate_mark;
10511 /* We are at the end of the buffer after just having inserted a newline.
10512 (Note: We depend on the fact we won't be crossing the gap.)
10513 Check to see if the most recent message looks a lot like the previous one.
10514 Return 0 if different, 1 if the new one should just replace it, or a
10515 value N > 1 if we should also append " [N times]". */
10517 static intmax_t
10518 message_log_check_duplicate (ptrdiff_t prev_bol_byte, ptrdiff_t this_bol_byte)
10520 ptrdiff_t i;
10521 ptrdiff_t len = Z_BYTE - 1 - this_bol_byte;
10522 bool seen_dots = false;
10523 unsigned char *p1 = BUF_BYTE_ADDRESS (current_buffer, prev_bol_byte);
10524 unsigned char *p2 = BUF_BYTE_ADDRESS (current_buffer, this_bol_byte);
10526 for (i = 0; i < len; i++)
10528 if (i >= 3 && p1[i - 3] == '.' && p1[i - 2] == '.' && p1[i - 1] == '.')
10529 seen_dots = true;
10530 if (p1[i] != p2[i])
10531 return seen_dots;
10533 p1 += len;
10534 if (*p1 == '\n')
10535 return 2;
10536 if (*p1++ == ' ' && *p1++ == '[')
10538 char *pend;
10539 intmax_t n = strtoimax ((char *) p1, &pend, 10);
10540 if (0 < n && n < INTMAX_MAX && strncmp (pend, " times]\n", 8) == 0)
10541 return n + 1;
10543 return 0;
10547 /* Display an echo area message M with a specified length of NBYTES
10548 bytes. The string may include null characters. If M is not a
10549 string, clear out any existing message, and let the mini-buffer
10550 text show through.
10552 This function cancels echoing. */
10554 void
10555 message3 (Lisp_Object m)
10557 clear_message (true, true);
10558 cancel_echoing ();
10560 /* First flush out any partial line written with print. */
10561 message_log_maybe_newline ();
10562 if (STRINGP (m))
10564 ptrdiff_t nbytes = SBYTES (m);
10565 bool multibyte = STRING_MULTIBYTE (m);
10566 char *buffer;
10567 USE_SAFE_ALLOCA;
10568 SAFE_ALLOCA_STRING (buffer, m);
10569 message_dolog (buffer, nbytes, true, multibyte);
10570 SAFE_FREE ();
10572 if (! inhibit_message)
10573 message3_nolog (m);
10576 /* Log the message M to stderr. Log an empty line if M is not a string. */
10578 static void
10579 message_to_stderr (Lisp_Object m)
10581 if (noninteractive_need_newline)
10583 noninteractive_need_newline = false;
10584 fputc ('\n', stderr);
10586 if (STRINGP (m))
10588 Lisp_Object coding_system = Vlocale_coding_system;
10589 Lisp_Object s;
10591 if (!NILP (Vcoding_system_for_write))
10592 coding_system = Vcoding_system_for_write;
10593 if (!NILP (coding_system))
10594 s = code_convert_string_norecord (m, coding_system, true);
10595 else
10596 s = m;
10598 fwrite (SDATA (s), SBYTES (s), 1, stderr);
10600 if (!cursor_in_echo_area)
10601 fputc ('\n', stderr);
10602 fflush (stderr);
10605 /* The non-logging version of message3.
10606 This does not cancel echoing, because it is used for echoing.
10607 Perhaps we need to make a separate function for echoing
10608 and make this cancel echoing. */
10610 void
10611 message3_nolog (Lisp_Object m)
10613 struct frame *sf = SELECTED_FRAME ();
10615 if (FRAME_INITIAL_P (sf))
10616 message_to_stderr (m);
10617 /* Error messages get reported properly by cmd_error, so this must be just an
10618 informative message; if the frame hasn't really been initialized yet, just
10619 toss it. */
10620 else if (INTERACTIVE && sf->glyphs_initialized_p)
10622 /* Get the frame containing the mini-buffer
10623 that the selected frame is using. */
10624 Lisp_Object mini_window = FRAME_MINIBUF_WINDOW (sf);
10625 Lisp_Object frame = XWINDOW (mini_window)->frame;
10626 struct frame *f = XFRAME (frame);
10628 if (FRAME_VISIBLE_P (sf) && !FRAME_VISIBLE_P (f))
10629 Fmake_frame_visible (frame);
10631 if (STRINGP (m) && SCHARS (m) > 0)
10633 set_message (m);
10634 if (minibuffer_auto_raise)
10635 Fraise_frame (frame);
10636 /* Assume we are not echoing.
10637 (If we are, echo_now will override this.) */
10638 echo_message_buffer = Qnil;
10640 else
10641 clear_message (true, true);
10643 do_pending_window_change (false);
10644 echo_area_display (true);
10645 do_pending_window_change (false);
10646 if (FRAME_TERMINAL (f)->frame_up_to_date_hook)
10647 (*FRAME_TERMINAL (f)->frame_up_to_date_hook) (f);
10652 /* Display a null-terminated echo area message M. If M is 0, clear
10653 out any existing message, and let the mini-buffer text show through.
10655 The buffer M must continue to exist until after the echo area gets
10656 cleared or some other message gets displayed there. Do not pass
10657 text that is stored in a Lisp string. Do not pass text in a buffer
10658 that was alloca'd. */
10660 void
10661 message1 (const char *m)
10663 message3 (m ? build_unibyte_string (m) : Qnil);
10667 /* The non-logging counterpart of message1. */
10669 void
10670 message1_nolog (const char *m)
10672 message3_nolog (m ? build_unibyte_string (m) : Qnil);
10675 /* Display a message M which contains a single %s
10676 which gets replaced with STRING. */
10678 void
10679 message_with_string (const char *m, Lisp_Object string, bool log)
10681 CHECK_STRING (string);
10683 bool need_message;
10684 if (noninteractive)
10685 need_message = !!m;
10686 else if (!INTERACTIVE)
10687 need_message = false;
10688 else
10690 /* The frame whose minibuffer we're going to display the message on.
10691 It may be larger than the selected frame, so we need
10692 to use its buffer, not the selected frame's buffer. */
10693 Lisp_Object mini_window;
10694 struct frame *f, *sf = SELECTED_FRAME ();
10696 /* Get the frame containing the minibuffer
10697 that the selected frame is using. */
10698 mini_window = FRAME_MINIBUF_WINDOW (sf);
10699 f = XFRAME (WINDOW_FRAME (XWINDOW (mini_window)));
10701 /* Error messages get reported properly by cmd_error, so this must be
10702 just an informative message; if the frame hasn't really been
10703 initialized yet, just toss it. */
10704 need_message = f->glyphs_initialized_p;
10707 if (need_message)
10709 AUTO_STRING (fmt, m);
10710 Lisp_Object msg = CALLN (Fformat_message, fmt, string);
10712 if (noninteractive)
10713 message_to_stderr (msg);
10714 else
10716 if (log)
10717 message3 (msg);
10718 else
10719 message3_nolog (msg);
10721 /* Print should start at the beginning of the message
10722 buffer next time. */
10723 message_buf_print = false;
10729 /* Dump an informative message to the minibuf. If M is 0, clear out
10730 any existing message, and let the mini-buffer text show through.
10732 The message must be safe ASCII (because when Emacs is
10733 non-interactive the message is sent straight to stderr without
10734 encoding first) and the format must not contain ` or ' (because
10735 this function does not account for `text-quoting-style'). If your
10736 message and format do not fit into this category, convert your
10737 arguments to Lisp objects and use Fmessage instead. */
10739 static void ATTRIBUTE_FORMAT_PRINTF (1, 0)
10740 vmessage (const char *m, va_list ap)
10742 if (noninteractive)
10744 if (m)
10746 if (noninteractive_need_newline)
10747 putc ('\n', stderr);
10748 noninteractive_need_newline = false;
10749 vfprintf (stderr, m, ap);
10750 if (!cursor_in_echo_area)
10751 fprintf (stderr, "\n");
10752 fflush (stderr);
10755 else if (INTERACTIVE)
10757 /* The frame whose mini-buffer we're going to display the message
10758 on. It may be larger than the selected frame, so we need to
10759 use its buffer, not the selected frame's buffer. */
10760 Lisp_Object mini_window;
10761 struct frame *f, *sf = SELECTED_FRAME ();
10763 /* Get the frame containing the mini-buffer
10764 that the selected frame is using. */
10765 mini_window = FRAME_MINIBUF_WINDOW (sf);
10766 f = XFRAME (WINDOW_FRAME (XWINDOW (mini_window)));
10768 /* Error messages get reported properly by cmd_error, so this must be
10769 just an informative message; if the frame hasn't really been
10770 initialized yet, just toss it. */
10771 if (f->glyphs_initialized_p)
10773 if (m)
10775 ptrdiff_t len;
10776 ptrdiff_t maxsize = FRAME_MESSAGE_BUF_SIZE (f);
10777 USE_SAFE_ALLOCA;
10778 char *message_buf = SAFE_ALLOCA (maxsize + 1);
10780 len = doprnt (message_buf, maxsize, m, 0, ap);
10782 message3 (make_string (message_buf, len));
10783 SAFE_FREE ();
10785 else
10786 message1 (0);
10788 /* Print should start at the beginning of the message
10789 buffer next time. */
10790 message_buf_print = false;
10795 /* See vmessage for restrictions on the text of the message. */
10796 void
10797 message (const char *m, ...)
10799 va_list ap;
10800 va_start (ap, m);
10801 vmessage (m, ap);
10802 va_end (ap);
10806 /* Display the current message in the current mini-buffer. This is
10807 only called from error handlers in process.c, and is not time
10808 critical. */
10810 void
10811 update_echo_area (void)
10813 if (!NILP (echo_area_buffer[0]))
10815 Lisp_Object string;
10816 string = Fcurrent_message ();
10817 message3 (string);
10822 /* Make sure echo area buffers in `echo_buffers' are live.
10823 If they aren't, make new ones. */
10825 static void
10826 ensure_echo_area_buffers (void)
10828 for (int i = 0; i < 2; i++)
10829 if (!BUFFERP (echo_buffer[i])
10830 || !BUFFER_LIVE_P (XBUFFER (echo_buffer[i])))
10832 Lisp_Object old_buffer = echo_buffer[i];
10833 static char const name_fmt[] = " *Echo Area %d*";
10834 char name[sizeof name_fmt + INT_STRLEN_BOUND (int)];
10835 AUTO_STRING_WITH_LEN (lname, name, sprintf (name, name_fmt, i));
10836 echo_buffer[i] = Fget_buffer_create (lname);
10837 bset_truncate_lines (XBUFFER (echo_buffer[i]), Qnil);
10838 /* to force word wrap in echo area -
10839 it was decided to postpone this*/
10840 /* XBUFFER (echo_buffer[i])->word_wrap = Qt; */
10842 for (int j = 0; j < 2; j++)
10843 if (EQ (old_buffer, echo_area_buffer[j]))
10844 echo_area_buffer[j] = echo_buffer[i];
10849 /* Call FN with args A1..A2 with either the current or last displayed
10850 echo_area_buffer as current buffer.
10852 WHICH zero means use the current message buffer
10853 echo_area_buffer[0]. If that is nil, choose a suitable buffer
10854 from echo_buffer[] and clear it.
10856 WHICH > 0 means use echo_area_buffer[1]. If that is nil, choose a
10857 suitable buffer from echo_buffer[] and clear it.
10859 If WHICH < 0, set echo_area_buffer[1] to echo_area_buffer[0], so
10860 that the current message becomes the last displayed one, choose a
10861 suitable buffer for echo_area_buffer[0], and clear it.
10863 Value is what FN returns. */
10865 static bool
10866 with_echo_area_buffer (struct window *w, int which,
10867 bool (*fn) (ptrdiff_t, Lisp_Object),
10868 ptrdiff_t a1, Lisp_Object a2)
10870 Lisp_Object buffer;
10871 bool this_one, the_other, clear_buffer_p, rc;
10872 ptrdiff_t count = SPECPDL_INDEX ();
10874 /* If buffers aren't live, make new ones. */
10875 ensure_echo_area_buffers ();
10877 clear_buffer_p = false;
10879 if (which == 0)
10880 this_one = false, the_other = true;
10881 else if (which > 0)
10882 this_one = true, the_other = false;
10883 else
10885 this_one = false, the_other = true;
10886 clear_buffer_p = true;
10888 /* We need a fresh one in case the current echo buffer equals
10889 the one containing the last displayed echo area message. */
10890 if (!NILP (echo_area_buffer[this_one])
10891 && EQ (echo_area_buffer[this_one], echo_area_buffer[the_other]))
10892 echo_area_buffer[this_one] = Qnil;
10895 /* Choose a suitable buffer from echo_buffer[] if we don't
10896 have one. */
10897 if (NILP (echo_area_buffer[this_one]))
10899 echo_area_buffer[this_one]
10900 = (EQ (echo_area_buffer[the_other], echo_buffer[this_one])
10901 ? echo_buffer[the_other]
10902 : echo_buffer[this_one]);
10903 clear_buffer_p = true;
10906 buffer = echo_area_buffer[this_one];
10908 /* Don't get confused by reusing the buffer used for echoing
10909 for a different purpose. */
10910 if (echo_kboard == NULL && EQ (buffer, echo_message_buffer))
10911 cancel_echoing ();
10913 record_unwind_protect (unwind_with_echo_area_buffer,
10914 with_echo_area_buffer_unwind_data (w));
10916 /* Make the echo area buffer current. Note that for display
10917 purposes, it is not necessary that the displayed window's buffer
10918 == current_buffer, except for text property lookup. So, let's
10919 only set that buffer temporarily here without doing a full
10920 Fset_window_buffer. We must also change w->pointm, though,
10921 because otherwise an assertions in unshow_buffer fails, and Emacs
10922 aborts. */
10923 set_buffer_internal_1 (XBUFFER (buffer));
10924 if (w)
10926 wset_buffer (w, buffer);
10927 set_marker_both (w->pointm, buffer, BEG, BEG_BYTE);
10928 set_marker_both (w->old_pointm, buffer, BEG, BEG_BYTE);
10931 bset_undo_list (current_buffer, Qt);
10932 bset_read_only (current_buffer, Qnil);
10933 specbind (Qinhibit_read_only, Qt);
10934 specbind (Qinhibit_modification_hooks, Qt);
10936 if (clear_buffer_p && Z > BEG)
10937 del_range (BEG, Z);
10939 eassert (BEGV >= BEG);
10940 eassert (ZV <= Z && ZV >= BEGV);
10942 rc = fn (a1, a2);
10944 eassert (BEGV >= BEG);
10945 eassert (ZV <= Z && ZV >= BEGV);
10947 unbind_to (count, Qnil);
10948 return rc;
10952 /* Save state that should be preserved around the call to the function
10953 FN called in with_echo_area_buffer. */
10955 static Lisp_Object
10956 with_echo_area_buffer_unwind_data (struct window *w)
10958 int i = 0;
10959 Lisp_Object vector, tmp;
10961 /* Reduce consing by keeping one vector in
10962 Vwith_echo_area_save_vector. */
10963 vector = Vwith_echo_area_save_vector;
10964 Vwith_echo_area_save_vector = Qnil;
10966 if (NILP (vector))
10967 vector = Fmake_vector (make_number (11), Qnil);
10969 XSETBUFFER (tmp, current_buffer); ASET (vector, i, tmp); ++i;
10970 ASET (vector, i, Vdeactivate_mark); ++i;
10971 ASET (vector, i, make_number (windows_or_buffers_changed)); ++i;
10973 if (w)
10975 XSETWINDOW (tmp, w); ASET (vector, i, tmp); ++i;
10976 ASET (vector, i, w->contents); ++i;
10977 ASET (vector, i, make_number (marker_position (w->pointm))); ++i;
10978 ASET (vector, i, make_number (marker_byte_position (w->pointm))); ++i;
10979 ASET (vector, i, make_number (marker_position (w->old_pointm))); ++i;
10980 ASET (vector, i, make_number (marker_byte_position (w->old_pointm))); ++i;
10981 ASET (vector, i, make_number (marker_position (w->start))); ++i;
10982 ASET (vector, i, make_number (marker_byte_position (w->start))); ++i;
10984 else
10986 int end = i + 8;
10987 for (; i < end; ++i)
10988 ASET (vector, i, Qnil);
10991 eassert (i == ASIZE (vector));
10992 return vector;
10996 /* Restore global state from VECTOR which was created by
10997 with_echo_area_buffer_unwind_data. */
10999 static void
11000 unwind_with_echo_area_buffer (Lisp_Object vector)
11002 set_buffer_internal_1 (XBUFFER (AREF (vector, 0)));
11003 Vdeactivate_mark = AREF (vector, 1);
11004 windows_or_buffers_changed = XFASTINT (AREF (vector, 2));
11006 if (WINDOWP (AREF (vector, 3)))
11008 struct window *w;
11009 Lisp_Object buffer;
11011 w = XWINDOW (AREF (vector, 3));
11012 buffer = AREF (vector, 4);
11014 wset_buffer (w, buffer);
11015 set_marker_both (w->pointm, buffer,
11016 XFASTINT (AREF (vector, 5)),
11017 XFASTINT (AREF (vector, 6)));
11018 set_marker_both (w->old_pointm, buffer,
11019 XFASTINT (AREF (vector, 7)),
11020 XFASTINT (AREF (vector, 8)));
11021 set_marker_both (w->start, buffer,
11022 XFASTINT (AREF (vector, 9)),
11023 XFASTINT (AREF (vector, 10)));
11026 Vwith_echo_area_save_vector = vector;
11030 /* Set up the echo area for use by print functions. MULTIBYTE_P
11031 means we will print multibyte. */
11033 void
11034 setup_echo_area_for_printing (bool multibyte_p)
11036 /* If we can't find an echo area any more, exit. */
11037 if (! FRAME_LIVE_P (XFRAME (selected_frame)))
11038 Fkill_emacs (Qnil);
11040 ensure_echo_area_buffers ();
11042 if (!message_buf_print)
11044 /* A message has been output since the last time we printed.
11045 Choose a fresh echo area buffer. */
11046 if (EQ (echo_area_buffer[1], echo_buffer[0]))
11047 echo_area_buffer[0] = echo_buffer[1];
11048 else
11049 echo_area_buffer[0] = echo_buffer[0];
11051 /* Switch to that buffer and clear it. */
11052 set_buffer_internal (XBUFFER (echo_area_buffer[0]));
11053 bset_truncate_lines (current_buffer, Qnil);
11055 if (Z > BEG)
11057 ptrdiff_t count = SPECPDL_INDEX ();
11058 specbind (Qinhibit_read_only, Qt);
11059 /* Note that undo recording is always disabled. */
11060 del_range (BEG, Z);
11061 unbind_to (count, Qnil);
11063 TEMP_SET_PT_BOTH (BEG, BEG_BYTE);
11065 /* Set up the buffer for the multibyteness we need. We always
11066 set it to be multibyte, except when
11067 unibyte-display-via-language-environment is non-nil and the
11068 buffer from which we are called is unibyte, because in that
11069 case unibyte characters should not be displayed as octal
11070 escapes. */
11071 if (unibyte_display_via_language_environment
11072 && !multibyte_p
11073 && !NILP (BVAR (current_buffer, enable_multibyte_characters)))
11074 Fset_buffer_multibyte (Qnil);
11075 else if (NILP (BVAR (current_buffer, enable_multibyte_characters)))
11076 Fset_buffer_multibyte (Qt);
11078 /* Raise the frame containing the echo area. */
11079 if (minibuffer_auto_raise)
11081 struct frame *sf = SELECTED_FRAME ();
11082 Lisp_Object mini_window;
11083 mini_window = FRAME_MINIBUF_WINDOW (sf);
11084 Fraise_frame (WINDOW_FRAME (XWINDOW (mini_window)));
11087 message_log_maybe_newline ();
11088 message_buf_print = true;
11090 else
11092 if (NILP (echo_area_buffer[0]))
11094 if (EQ (echo_area_buffer[1], echo_buffer[0]))
11095 echo_area_buffer[0] = echo_buffer[1];
11096 else
11097 echo_area_buffer[0] = echo_buffer[0];
11100 if (current_buffer != XBUFFER (echo_area_buffer[0]))
11102 /* Someone switched buffers between print requests. */
11103 set_buffer_internal (XBUFFER (echo_area_buffer[0]));
11104 bset_truncate_lines (current_buffer, Qnil);
11110 /* Display an echo area message in window W. Value is true if W's
11111 height is changed. If display_last_displayed_message_p,
11112 display the message that was last displayed, otherwise
11113 display the current message. */
11115 static bool
11116 display_echo_area (struct window *w)
11118 bool no_message_p, window_height_changed_p;
11120 /* Temporarily disable garbage collections while displaying the echo
11121 area. This is done because a GC can print a message itself.
11122 That message would modify the echo area buffer's contents while a
11123 redisplay of the buffer is going on, and seriously confuse
11124 redisplay. */
11125 ptrdiff_t count = inhibit_garbage_collection ();
11127 /* If there is no message, we must call display_echo_area_1
11128 nevertheless because it resizes the window. But we will have to
11129 reset the echo_area_buffer in question to nil at the end because
11130 with_echo_area_buffer will sets it to an empty buffer. */
11131 bool i = display_last_displayed_message_p;
11132 /* According to the C99, C11 and C++11 standards, the integral value
11133 of a "bool" is always 0 or 1, so this array access is safe here,
11134 if oddly typed. */
11135 no_message_p = NILP (echo_area_buffer[i]);
11137 window_height_changed_p
11138 = with_echo_area_buffer (w, display_last_displayed_message_p,
11139 display_echo_area_1,
11140 (intptr_t) w, Qnil);
11142 if (no_message_p)
11143 echo_area_buffer[i] = Qnil;
11145 unbind_to (count, Qnil);
11146 return window_height_changed_p;
11150 /* Helper for display_echo_area. Display the current buffer which
11151 contains the current echo area message in window W, a mini-window,
11152 a pointer to which is passed in A1. A2..A4 are currently not used.
11153 Change the height of W so that all of the message is displayed.
11154 Value is true if height of W was changed. */
11156 static bool
11157 display_echo_area_1 (ptrdiff_t a1, Lisp_Object a2)
11159 intptr_t i1 = a1;
11160 struct window *w = (struct window *) i1;
11161 Lisp_Object window;
11162 struct text_pos start;
11164 /* We are about to enter redisplay without going through
11165 redisplay_internal, so we need to forget these faces by hand
11166 here. */
11167 forget_escape_and_glyphless_faces ();
11169 /* Do this before displaying, so that we have a large enough glyph
11170 matrix for the display. If we can't get enough space for the
11171 whole text, display the last N lines. That works by setting w->start. */
11172 bool window_height_changed_p = resize_mini_window (w, false);
11174 /* Use the starting position chosen by resize_mini_window. */
11175 SET_TEXT_POS_FROM_MARKER (start, w->start);
11177 /* Display. */
11178 clear_glyph_matrix (w->desired_matrix);
11179 XSETWINDOW (window, w);
11180 try_window (window, start, 0);
11182 return window_height_changed_p;
11186 /* Resize the echo area window to exactly the size needed for the
11187 currently displayed message, if there is one. If a mini-buffer
11188 is active, don't shrink it. */
11190 void
11191 resize_echo_area_exactly (void)
11193 if (BUFFERP (echo_area_buffer[0])
11194 && WINDOWP (echo_area_window))
11196 struct window *w = XWINDOW (echo_area_window);
11197 Lisp_Object resize_exactly = (minibuf_level == 0 ? Qt : Qnil);
11198 bool resized_p = with_echo_area_buffer (w, 0, resize_mini_window_1,
11199 (intptr_t) w, resize_exactly);
11200 if (resized_p)
11202 windows_or_buffers_changed = 42;
11203 update_mode_lines = 30;
11204 redisplay_internal ();
11210 /* Callback function for with_echo_area_buffer, when used from
11211 resize_echo_area_exactly. A1 contains a pointer to the window to
11212 resize, EXACTLY non-nil means resize the mini-window exactly to the
11213 size of the text displayed. A3 and A4 are not used. Value is what
11214 resize_mini_window returns. */
11216 static bool
11217 resize_mini_window_1 (ptrdiff_t a1, Lisp_Object exactly)
11219 intptr_t i1 = a1;
11220 return resize_mini_window ((struct window *) i1, !NILP (exactly));
11224 /* Resize mini-window W to fit the size of its contents. EXACT_P
11225 means size the window exactly to the size needed. Otherwise, it's
11226 only enlarged until W's buffer is empty.
11228 Set W->start to the right place to begin display. If the whole
11229 contents fit, start at the beginning. Otherwise, start so as
11230 to make the end of the contents appear. This is particularly
11231 important for y-or-n-p, but seems desirable generally.
11233 Value is true if the window height has been changed. */
11235 bool
11236 resize_mini_window (struct window *w, bool exact_p)
11238 struct frame *f = XFRAME (w->frame);
11239 bool window_height_changed_p = false;
11241 eassert (MINI_WINDOW_P (w));
11243 /* By default, start display at the beginning. */
11244 set_marker_both (w->start, w->contents,
11245 BUF_BEGV (XBUFFER (w->contents)),
11246 BUF_BEGV_BYTE (XBUFFER (w->contents)));
11248 /* Don't resize windows while redisplaying a window; it would
11249 confuse redisplay functions when the size of the window they are
11250 displaying changes from under them. Such a resizing can happen,
11251 for instance, when which-func prints a long message while
11252 we are running fontification-functions. We're running these
11253 functions with safe_call which binds inhibit-redisplay to t. */
11254 if (!NILP (Vinhibit_redisplay))
11255 return false;
11257 /* Nil means don't try to resize. */
11258 if (NILP (Vresize_mini_windows)
11259 || (FRAME_X_P (f) && FRAME_X_OUTPUT (f) == NULL))
11260 return false;
11262 if (!FRAME_MINIBUF_ONLY_P (f))
11264 struct it it;
11265 int total_height = (WINDOW_PIXEL_HEIGHT (XWINDOW (FRAME_ROOT_WINDOW (f)))
11266 + WINDOW_PIXEL_HEIGHT (w));
11267 int unit = FRAME_LINE_HEIGHT (f);
11268 int height, max_height;
11269 struct text_pos start;
11270 struct buffer *old_current_buffer = NULL;
11272 if (current_buffer != XBUFFER (w->contents))
11274 old_current_buffer = current_buffer;
11275 set_buffer_internal (XBUFFER (w->contents));
11278 init_iterator (&it, w, BEGV, BEGV_BYTE, NULL, DEFAULT_FACE_ID);
11280 /* Compute the max. number of lines specified by the user. */
11281 if (FLOATP (Vmax_mini_window_height))
11282 max_height = XFLOAT_DATA (Vmax_mini_window_height) * total_height;
11283 else if (INTEGERP (Vmax_mini_window_height))
11284 max_height = XINT (Vmax_mini_window_height) * unit;
11285 else
11286 max_height = total_height / 4;
11288 /* Correct that max. height if it's bogus. */
11289 max_height = clip_to_bounds (unit, max_height, total_height);
11291 /* Find out the height of the text in the window. */
11292 if (it.line_wrap == TRUNCATE)
11293 height = unit;
11294 else
11296 last_height = 0;
11297 move_it_to (&it, ZV, -1, -1, -1, MOVE_TO_POS);
11298 if (it.max_ascent == 0 && it.max_descent == 0)
11299 height = it.current_y + last_height;
11300 else
11301 height = it.current_y + it.max_ascent + it.max_descent;
11302 height -= min (it.extra_line_spacing, it.max_extra_line_spacing);
11305 /* Compute a suitable window start. */
11306 if (height > max_height)
11308 height = (max_height / unit) * unit;
11309 init_iterator (&it, w, ZV, ZV_BYTE, NULL, DEFAULT_FACE_ID);
11310 move_it_vertically_backward (&it, height - unit);
11311 start = it.current.pos;
11313 else
11314 SET_TEXT_POS (start, BEGV, BEGV_BYTE);
11315 SET_MARKER_FROM_TEXT_POS (w->start, start);
11317 if (EQ (Vresize_mini_windows, Qgrow_only))
11319 /* Let it grow only, until we display an empty message, in which
11320 case the window shrinks again. */
11321 if (height > WINDOW_PIXEL_HEIGHT (w))
11323 int old_height = WINDOW_PIXEL_HEIGHT (w);
11325 FRAME_WINDOWS_FROZEN (f) = true;
11326 grow_mini_window (w, height - WINDOW_PIXEL_HEIGHT (w), true);
11327 window_height_changed_p = WINDOW_PIXEL_HEIGHT (w) != old_height;
11329 else if (height < WINDOW_PIXEL_HEIGHT (w)
11330 && (exact_p || BEGV == ZV))
11332 int old_height = WINDOW_PIXEL_HEIGHT (w);
11334 FRAME_WINDOWS_FROZEN (f) = false;
11335 shrink_mini_window (w, true);
11336 window_height_changed_p = WINDOW_PIXEL_HEIGHT (w) != old_height;
11339 else
11341 /* Always resize to exact size needed. */
11342 if (height > WINDOW_PIXEL_HEIGHT (w))
11344 int old_height = WINDOW_PIXEL_HEIGHT (w);
11346 FRAME_WINDOWS_FROZEN (f) = true;
11347 grow_mini_window (w, height - WINDOW_PIXEL_HEIGHT (w), true);
11348 window_height_changed_p = WINDOW_PIXEL_HEIGHT (w) != old_height;
11350 else if (height < WINDOW_PIXEL_HEIGHT (w))
11352 int old_height = WINDOW_PIXEL_HEIGHT (w);
11354 FRAME_WINDOWS_FROZEN (f) = false;
11355 shrink_mini_window (w, true);
11357 if (height)
11359 FRAME_WINDOWS_FROZEN (f) = true;
11360 grow_mini_window (w, height - WINDOW_PIXEL_HEIGHT (w), true);
11363 window_height_changed_p = WINDOW_PIXEL_HEIGHT (w) != old_height;
11367 if (old_current_buffer)
11368 set_buffer_internal (old_current_buffer);
11371 return window_height_changed_p;
11375 /* Value is the current message, a string, or nil if there is no
11376 current message. */
11378 Lisp_Object
11379 current_message (void)
11381 Lisp_Object msg;
11383 if (!BUFFERP (echo_area_buffer[0]))
11384 msg = Qnil;
11385 else
11387 with_echo_area_buffer (0, 0, current_message_1,
11388 (intptr_t) &msg, Qnil);
11389 if (NILP (msg))
11390 echo_area_buffer[0] = Qnil;
11393 return msg;
11397 static bool
11398 current_message_1 (ptrdiff_t a1, Lisp_Object a2)
11400 intptr_t i1 = a1;
11401 Lisp_Object *msg = (Lisp_Object *) i1;
11403 if (Z > BEG)
11404 *msg = make_buffer_string (BEG, Z, true);
11405 else
11406 *msg = Qnil;
11407 return false;
11411 /* Push the current message on Vmessage_stack for later restoration
11412 by restore_message. Value is true if the current message isn't
11413 empty. This is a relatively infrequent operation, so it's not
11414 worth optimizing. */
11416 bool
11417 push_message (void)
11419 Lisp_Object msg = current_message ();
11420 Vmessage_stack = Fcons (msg, Vmessage_stack);
11421 return STRINGP (msg);
11425 /* Restore message display from the top of Vmessage_stack. */
11427 void
11428 restore_message (void)
11430 eassert (CONSP (Vmessage_stack));
11431 message3_nolog (XCAR (Vmessage_stack));
11435 /* Handler for unwind-protect calling pop_message. */
11437 void
11438 pop_message_unwind (void)
11440 /* Pop the top-most entry off Vmessage_stack. */
11441 eassert (CONSP (Vmessage_stack));
11442 Vmessage_stack = XCDR (Vmessage_stack);
11446 /* Check that Vmessage_stack is nil. Called from emacs.c when Emacs
11447 exits. If the stack is not empty, we have a missing pop_message
11448 somewhere. */
11450 void
11451 check_message_stack (void)
11453 if (!NILP (Vmessage_stack))
11454 emacs_abort ();
11458 /* Truncate to NCHARS what will be displayed in the echo area the next
11459 time we display it---but don't redisplay it now. */
11461 void
11462 truncate_echo_area (ptrdiff_t nchars)
11464 if (nchars == 0)
11465 echo_area_buffer[0] = Qnil;
11466 else if (!noninteractive
11467 && INTERACTIVE
11468 && !NILP (echo_area_buffer[0]))
11470 struct frame *sf = SELECTED_FRAME ();
11471 /* Error messages get reported properly by cmd_error, so this must be
11472 just an informative message; if the frame hasn't really been
11473 initialized yet, just toss it. */
11474 if (sf->glyphs_initialized_p)
11475 with_echo_area_buffer (0, 0, truncate_message_1, nchars, Qnil);
11480 /* Helper function for truncate_echo_area. Truncate the current
11481 message to at most NCHARS characters. */
11483 static bool
11484 truncate_message_1 (ptrdiff_t nchars, Lisp_Object a2)
11486 if (BEG + nchars < Z)
11487 del_range (BEG + nchars, Z);
11488 if (Z == BEG)
11489 echo_area_buffer[0] = Qnil;
11490 return false;
11493 /* Set the current message to STRING. */
11495 static void
11496 set_message (Lisp_Object string)
11498 eassert (STRINGP (string));
11500 message_enable_multibyte = STRING_MULTIBYTE (string);
11502 with_echo_area_buffer (0, -1, set_message_1, 0, string);
11503 message_buf_print = false;
11504 help_echo_showing_p = false;
11506 if (STRINGP (Vdebug_on_message)
11507 && STRINGP (string)
11508 && fast_string_match (Vdebug_on_message, string) >= 0)
11509 call_debugger (list2 (Qerror, string));
11513 /* Helper function for set_message. First argument is ignored and second
11514 argument has the same meaning as for set_message.
11515 This function is called with the echo area buffer being current. */
11517 static bool
11518 set_message_1 (ptrdiff_t a1, Lisp_Object string)
11520 eassert (STRINGP (string));
11522 /* Change multibyteness of the echo buffer appropriately. We always
11523 set it to be multibyte, except when
11524 unibyte-display-via-language-environment is non-nil and the
11525 string to display is unibyte, because in that case unibyte
11526 characters should not be displayed as octal escapes. */
11527 if (!message_enable_multibyte
11528 && unibyte_display_via_language_environment
11529 && !NILP (BVAR (current_buffer, enable_multibyte_characters)))
11530 Fset_buffer_multibyte (Qnil);
11531 else if (NILP (BVAR (current_buffer, enable_multibyte_characters)))
11532 Fset_buffer_multibyte (Qt);
11534 bset_truncate_lines (current_buffer, message_truncate_lines ? Qt : Qnil);
11535 if (!NILP (BVAR (current_buffer, bidi_display_reordering)))
11536 bset_bidi_paragraph_direction (current_buffer, Qleft_to_right);
11538 /* Insert new message at BEG. */
11539 TEMP_SET_PT_BOTH (BEG, BEG_BYTE);
11541 /* This function takes care of single/multibyte conversion.
11542 We just have to ensure that the echo area buffer has the right
11543 setting of enable_multibyte_characters. */
11544 insert_from_string (string, 0, 0, SCHARS (string), SBYTES (string), true);
11546 return false;
11550 /* Clear messages. CURRENT_P means clear the current message.
11551 LAST_DISPLAYED_P means clear the message last displayed. */
11553 void
11554 clear_message (bool current_p, bool last_displayed_p)
11556 if (current_p)
11558 echo_area_buffer[0] = Qnil;
11559 message_cleared_p = true;
11562 if (last_displayed_p)
11563 echo_area_buffer[1] = Qnil;
11565 message_buf_print = false;
11568 /* Clear garbaged frames.
11570 This function is used where the old redisplay called
11571 redraw_garbaged_frames which in turn called redraw_frame which in
11572 turn called clear_frame. The call to clear_frame was a source of
11573 flickering. I believe a clear_frame is not necessary. It should
11574 suffice in the new redisplay to invalidate all current matrices,
11575 and ensure a complete redisplay of all windows. */
11577 static void
11578 clear_garbaged_frames (void)
11580 if (frame_garbaged)
11582 Lisp_Object tail, frame;
11583 struct frame *sf = SELECTED_FRAME ();
11585 FOR_EACH_FRAME (tail, frame)
11587 struct frame *f = XFRAME (frame);
11589 if (FRAME_VISIBLE_P (f) && FRAME_GARBAGED_P (f))
11591 if (f->resized_p
11592 /* It makes no sense to redraw a non-selected TTY
11593 frame, since that will actually clear the
11594 selected frame, and might leave the selected
11595 frame with corrupted display, if it happens not
11596 to be marked garbaged. */
11597 && !(f != sf && (FRAME_TERMCAP_P (f) || FRAME_MSDOS_P (f))))
11598 redraw_frame (f);
11599 else
11600 clear_current_matrices (f);
11602 #if defined (HAVE_WINDOW_SYSTEM) && !defined (HAVE_NS)
11603 x_clear_under_internal_border (f);
11604 #endif /* HAVE_WINDOW_SYSTEM && !HAVE_NS */
11606 fset_redisplay (f);
11607 f->garbaged = false;
11608 f->resized_p = false;
11612 frame_garbaged = false;
11617 /* Redisplay the echo area of the selected frame. If UPDATE_FRAME_P, update
11618 selected_frame. */
11620 static void
11621 echo_area_display (bool update_frame_p)
11623 Lisp_Object mini_window;
11624 struct window *w;
11625 struct frame *f;
11626 bool window_height_changed_p = false;
11627 struct frame *sf = SELECTED_FRAME ();
11629 mini_window = FRAME_MINIBUF_WINDOW (sf);
11630 if (NILP (mini_window))
11631 return;
11633 w = XWINDOW (mini_window);
11634 f = XFRAME (WINDOW_FRAME (w));
11636 /* Don't display if frame is invisible or not yet initialized. */
11637 if (!FRAME_VISIBLE_P (f) || !f->glyphs_initialized_p)
11638 return;
11640 #ifdef HAVE_WINDOW_SYSTEM
11641 /* When Emacs starts, selected_frame may be the initial terminal
11642 frame. If we let this through, a message would be displayed on
11643 the terminal. */
11644 if (FRAME_INITIAL_P (XFRAME (selected_frame)))
11645 return;
11646 #endif /* HAVE_WINDOW_SYSTEM */
11648 /* Redraw garbaged frames. */
11649 clear_garbaged_frames ();
11651 if (!NILP (echo_area_buffer[0]) || minibuf_level == 0)
11653 echo_area_window = mini_window;
11654 window_height_changed_p = display_echo_area (w);
11655 w->must_be_updated_p = true;
11657 /* Update the display, unless called from redisplay_internal.
11658 Also don't update the screen during redisplay itself. The
11659 update will happen at the end of redisplay, and an update
11660 here could cause confusion. */
11661 if (update_frame_p && !redisplaying_p)
11663 int n = 0;
11665 /* If the display update has been interrupted by pending
11666 input, update mode lines in the frame. Due to the
11667 pending input, it might have been that redisplay hasn't
11668 been called, so that mode lines above the echo area are
11669 garbaged. This looks odd, so we prevent it here. */
11670 if (!display_completed)
11672 n = redisplay_mode_lines (FRAME_ROOT_WINDOW (f), false);
11674 #if defined (HAVE_WINDOW_SYSTEM) && !defined (HAVE_NS)
11675 x_clear_under_internal_border (f);
11676 #endif /* HAVE_WINDOW_SYSTEM && !HAVE_NS */
11680 if (window_height_changed_p
11681 /* Don't do this if Emacs is shutting down. Redisplay
11682 needs to run hooks. */
11683 && !NILP (Vrun_hooks))
11685 /* Must update other windows. Likewise as in other
11686 cases, don't let this update be interrupted by
11687 pending input. */
11688 ptrdiff_t count = SPECPDL_INDEX ();
11689 specbind (Qredisplay_dont_pause, Qt);
11690 fset_redisplay (f);
11691 redisplay_internal ();
11692 unbind_to (count, Qnil);
11694 else if (FRAME_WINDOW_P (f) && n == 0)
11696 /* Window configuration is the same as before.
11697 Can do with a display update of the echo area,
11698 unless we displayed some mode lines. */
11699 update_single_window (w);
11700 flush_frame (f);
11702 else
11703 update_frame (f, true, true);
11705 /* If cursor is in the echo area, make sure that the next
11706 redisplay displays the minibuffer, so that the cursor will
11707 be replaced with what the minibuffer wants. */
11708 if (cursor_in_echo_area)
11709 wset_redisplay (XWINDOW (mini_window));
11712 else if (!EQ (mini_window, selected_window))
11713 wset_redisplay (XWINDOW (mini_window));
11715 /* Last displayed message is now the current message. */
11716 echo_area_buffer[1] = echo_area_buffer[0];
11717 /* Inform read_char that we're not echoing. */
11718 echo_message_buffer = Qnil;
11720 /* Prevent redisplay optimization in redisplay_internal by resetting
11721 this_line_start_pos. This is done because the mini-buffer now
11722 displays the message instead of its buffer text. */
11723 if (EQ (mini_window, selected_window))
11724 CHARPOS (this_line_start_pos) = 0;
11726 if (window_height_changed_p)
11728 fset_redisplay (f);
11730 /* If window configuration was changed, frames may have been
11731 marked garbaged. Clear them or we will experience
11732 surprises wrt scrolling.
11733 FIXME: How/why/when? */
11734 clear_garbaged_frames ();
11738 /* True if W's buffer was changed but not saved. */
11740 static bool
11741 window_buffer_changed (struct window *w)
11743 struct buffer *b = XBUFFER (w->contents);
11745 eassert (BUFFER_LIVE_P (b));
11747 return (BUF_SAVE_MODIFF (b) < BUF_MODIFF (b)) != w->last_had_star;
11750 /* True if W has %c or %C in its mode line and mode line should be updated. */
11752 static bool
11753 mode_line_update_needed (struct window *w)
11755 return (w->column_number_displayed != -1
11756 && !(PT == w->last_point && !window_outdated (w))
11757 && (w->column_number_displayed != current_column ()));
11760 /* True if window start of W is frozen and may not be changed during
11761 redisplay. */
11763 static bool
11764 window_frozen_p (struct window *w)
11766 if (FRAME_WINDOWS_FROZEN (XFRAME (WINDOW_FRAME (w))))
11768 Lisp_Object window;
11770 XSETWINDOW (window, w);
11771 if (MINI_WINDOW_P (w))
11772 return false;
11773 else if (EQ (window, selected_window))
11774 return false;
11775 else if (MINI_WINDOW_P (XWINDOW (selected_window))
11776 && EQ (window, Vminibuf_scroll_window))
11777 /* This special window can't be frozen too. */
11778 return false;
11779 else
11780 return true;
11782 return false;
11785 /***********************************************************************
11786 Mode Lines and Frame Titles
11787 ***********************************************************************/
11789 /* A buffer for constructing non-propertized mode-line strings and
11790 frame titles in it; allocated from the heap in init_xdisp and
11791 resized as needed in store_mode_line_noprop_char. */
11793 static char *mode_line_noprop_buf;
11795 /* The buffer's end, and a current output position in it. */
11797 static char *mode_line_noprop_buf_end;
11798 static char *mode_line_noprop_ptr;
11800 #define MODE_LINE_NOPROP_LEN(start) \
11801 ((mode_line_noprop_ptr - mode_line_noprop_buf) - start)
11803 static enum {
11804 MODE_LINE_DISPLAY = 0,
11805 MODE_LINE_TITLE,
11806 MODE_LINE_NOPROP,
11807 MODE_LINE_STRING
11808 } mode_line_target;
11810 /* Alist that caches the results of :propertize.
11811 Each element is (PROPERTIZED-STRING . PROPERTY-LIST). */
11812 static Lisp_Object mode_line_proptrans_alist;
11814 /* List of strings making up the mode-line. */
11815 static Lisp_Object mode_line_string_list;
11817 /* Base face property when building propertized mode line string. */
11818 static Lisp_Object mode_line_string_face;
11819 static Lisp_Object mode_line_string_face_prop;
11822 /* Unwind data for mode line strings */
11824 static Lisp_Object Vmode_line_unwind_vector;
11826 static Lisp_Object
11827 format_mode_line_unwind_data (struct frame *target_frame,
11828 struct buffer *obuf,
11829 Lisp_Object owin,
11830 bool save_proptrans)
11832 Lisp_Object vector, tmp;
11834 /* Reduce consing by keeping one vector in
11835 Vwith_echo_area_save_vector. */
11836 vector = Vmode_line_unwind_vector;
11837 Vmode_line_unwind_vector = Qnil;
11839 if (NILP (vector))
11840 vector = Fmake_vector (make_number (10), Qnil);
11842 ASET (vector, 0, make_number (mode_line_target));
11843 ASET (vector, 1, make_number (MODE_LINE_NOPROP_LEN (0)));
11844 ASET (vector, 2, mode_line_string_list);
11845 ASET (vector, 3, save_proptrans ? mode_line_proptrans_alist : Qt);
11846 ASET (vector, 4, mode_line_string_face);
11847 ASET (vector, 5, mode_line_string_face_prop);
11849 if (obuf)
11850 XSETBUFFER (tmp, obuf);
11851 else
11852 tmp = Qnil;
11853 ASET (vector, 6, tmp);
11854 ASET (vector, 7, owin);
11855 if (target_frame)
11857 /* Similarly to `with-selected-window', if the operation selects
11858 a window on another frame, we must restore that frame's
11859 selected window, and (for a tty) the top-frame. */
11860 ASET (vector, 8, target_frame->selected_window);
11861 if (FRAME_TERMCAP_P (target_frame))
11862 ASET (vector, 9, FRAME_TTY (target_frame)->top_frame);
11865 return vector;
11868 static void
11869 unwind_format_mode_line (Lisp_Object vector)
11871 Lisp_Object old_window = AREF (vector, 7);
11872 Lisp_Object target_frame_window = AREF (vector, 8);
11873 Lisp_Object old_top_frame = AREF (vector, 9);
11875 mode_line_target = XINT (AREF (vector, 0));
11876 mode_line_noprop_ptr = mode_line_noprop_buf + XINT (AREF (vector, 1));
11877 mode_line_string_list = AREF (vector, 2);
11878 if (! EQ (AREF (vector, 3), Qt))
11879 mode_line_proptrans_alist = AREF (vector, 3);
11880 mode_line_string_face = AREF (vector, 4);
11881 mode_line_string_face_prop = AREF (vector, 5);
11883 /* Select window before buffer, since it may change the buffer. */
11884 if (!NILP (old_window))
11886 /* If the operation that we are unwinding had selected a window
11887 on a different frame, reset its frame-selected-window. For a
11888 text terminal, reset its top-frame if necessary. */
11889 if (!NILP (target_frame_window))
11891 Lisp_Object frame
11892 = WINDOW_FRAME (XWINDOW (target_frame_window));
11894 if (!EQ (frame, WINDOW_FRAME (XWINDOW (old_window))))
11895 Fselect_window (target_frame_window, Qt);
11897 if (!NILP (old_top_frame) && !EQ (old_top_frame, frame))
11898 Fselect_frame (old_top_frame, Qt);
11901 Fselect_window (old_window, Qt);
11904 if (!NILP (AREF (vector, 6)))
11906 set_buffer_internal_1 (XBUFFER (AREF (vector, 6)));
11907 ASET (vector, 6, Qnil);
11910 Vmode_line_unwind_vector = vector;
11914 /* Store a single character C for the frame title in mode_line_noprop_buf.
11915 Re-allocate mode_line_noprop_buf if necessary. */
11917 static void
11918 store_mode_line_noprop_char (char c)
11920 /* If output position has reached the end of the allocated buffer,
11921 increase the buffer's size. */
11922 if (mode_line_noprop_ptr == mode_line_noprop_buf_end)
11924 ptrdiff_t len = MODE_LINE_NOPROP_LEN (0);
11925 ptrdiff_t size = len;
11926 mode_line_noprop_buf =
11927 xpalloc (mode_line_noprop_buf, &size, 1, STRING_BYTES_BOUND, 1);
11928 mode_line_noprop_buf_end = mode_line_noprop_buf + size;
11929 mode_line_noprop_ptr = mode_line_noprop_buf + len;
11932 *mode_line_noprop_ptr++ = c;
11936 /* Store part of a frame title in mode_line_noprop_buf, beginning at
11937 mode_line_noprop_ptr. STRING is the string to store. Do not copy
11938 characters that yield more columns than PRECISION; PRECISION <= 0
11939 means copy the whole string. Pad with spaces until FIELD_WIDTH
11940 number of characters have been copied; FIELD_WIDTH <= 0 means don't
11941 pad. Called from display_mode_element when it is used to build a
11942 frame title. */
11944 static int
11945 store_mode_line_noprop (const char *string, int field_width, int precision)
11947 const unsigned char *str = (const unsigned char *) string;
11948 int n = 0;
11949 ptrdiff_t dummy, nbytes;
11951 /* Copy at most PRECISION chars from STR. */
11952 nbytes = strlen (string);
11953 n += c_string_width (str, nbytes, precision, &dummy, &nbytes);
11954 while (nbytes--)
11955 store_mode_line_noprop_char (*str++);
11957 /* Fill up with spaces until FIELD_WIDTH reached. */
11958 while (field_width > 0
11959 && n < field_width)
11961 store_mode_line_noprop_char (' ');
11962 ++n;
11965 return n;
11968 /***********************************************************************
11969 Frame Titles
11970 ***********************************************************************/
11972 #ifdef HAVE_WINDOW_SYSTEM
11974 /* Set the title of FRAME, if it has changed. The title format is
11975 Vicon_title_format if FRAME is iconified, otherwise it is
11976 frame_title_format. */
11978 static void
11979 x_consider_frame_title (Lisp_Object frame)
11981 struct frame *f = XFRAME (frame);
11983 if ((FRAME_WINDOW_P (f)
11984 || FRAME_MINIBUF_ONLY_P (f)
11985 || f->explicit_name)
11986 && !FRAME_TOOLTIP_P (f))
11988 /* Do we have more than one visible frame on this X display? */
11989 Lisp_Object tail, other_frame, fmt;
11990 ptrdiff_t title_start;
11991 char *title;
11992 ptrdiff_t len;
11993 struct it it;
11994 ptrdiff_t count = SPECPDL_INDEX ();
11996 FOR_EACH_FRAME (tail, other_frame)
11998 struct frame *tf = XFRAME (other_frame);
12000 if (tf != f
12001 && FRAME_KBOARD (tf) == FRAME_KBOARD (f)
12002 && !FRAME_MINIBUF_ONLY_P (tf)
12003 && !FRAME_PARENT_FRAME (tf)
12004 && !FRAME_TOOLTIP_P (tf)
12005 && (FRAME_VISIBLE_P (tf) || FRAME_ICONIFIED_P (tf)))
12006 break;
12009 /* Set global variable indicating that multiple frames exist. */
12010 multiple_frames = CONSP (tail);
12012 /* Switch to the buffer of selected window of the frame. Set up
12013 mode_line_target so that display_mode_element will output into
12014 mode_line_noprop_buf; then display the title. */
12015 record_unwind_protect (unwind_format_mode_line,
12016 format_mode_line_unwind_data
12017 (f, current_buffer, selected_window, false));
12018 /* select-frame calls resize_mini_window, which could resize the
12019 mini-window and by that undo the effect of this redisplay
12020 cycle wrt minibuffer and echo-area display. Binding
12021 inhibit-redisplay to t makes the call to resize_mini_window a
12022 no-op, thus avoiding the adverse side effects. */
12023 specbind (Qinhibit_redisplay, Qt);
12025 Fselect_window (f->selected_window, Qt);
12026 set_buffer_internal_1
12027 (XBUFFER (XWINDOW (f->selected_window)->contents));
12028 fmt = FRAME_ICONIFIED_P (f) ? Vicon_title_format : Vframe_title_format;
12030 mode_line_target = MODE_LINE_TITLE;
12031 title_start = MODE_LINE_NOPROP_LEN (0);
12032 init_iterator (&it, XWINDOW (f->selected_window), -1, -1,
12033 NULL, DEFAULT_FACE_ID);
12034 display_mode_element (&it, 0, -1, -1, fmt, Qnil, false);
12035 len = MODE_LINE_NOPROP_LEN (title_start);
12036 title = mode_line_noprop_buf + title_start;
12037 unbind_to (count, Qnil);
12039 /* Set the title only if it's changed. This avoids consing in
12040 the common case where it hasn't. (If it turns out that we've
12041 already wasted too much time by walking through the list with
12042 display_mode_element, then we might need to optimize at a
12043 higher level than this.) */
12044 if (! STRINGP (f->name)
12045 || SBYTES (f->name) != len
12046 || memcmp (title, SDATA (f->name), len) != 0)
12047 x_implicitly_set_name (f, make_string (title, len), Qnil);
12051 #endif /* not HAVE_WINDOW_SYSTEM */
12054 /***********************************************************************
12055 Menu Bars
12056 ***********************************************************************/
12058 /* True if we will not redisplay all visible windows. */
12059 #define REDISPLAY_SOME_P() \
12060 ((windows_or_buffers_changed == 0 \
12061 || windows_or_buffers_changed == REDISPLAY_SOME) \
12062 && (update_mode_lines == 0 \
12063 || update_mode_lines == REDISPLAY_SOME))
12065 /* Prepare for redisplay by updating menu-bar item lists when
12066 appropriate. This can call eval. */
12068 static void
12069 prepare_menu_bars (void)
12071 bool all_windows = windows_or_buffers_changed || update_mode_lines;
12072 bool some_windows = REDISPLAY_SOME_P ();
12074 if (FUNCTIONP (Vpre_redisplay_function))
12076 Lisp_Object windows = all_windows ? Qt : Qnil;
12077 if (all_windows && some_windows)
12079 Lisp_Object ws = window_list ();
12080 for (windows = Qnil; CONSP (ws); ws = XCDR (ws))
12082 Lisp_Object this = XCAR (ws);
12083 struct window *w = XWINDOW (this);
12084 if (w->redisplay
12085 || XFRAME (w->frame)->redisplay
12086 || XBUFFER (w->contents)->text->redisplay)
12088 windows = Fcons (this, windows);
12092 safe__call1 (true, Vpre_redisplay_function, windows);
12095 /* Update all frame titles based on their buffer names, etc. We do
12096 this before the menu bars so that the buffer-menu will show the
12097 up-to-date frame titles. */
12098 #ifdef HAVE_WINDOW_SYSTEM
12099 if (all_windows)
12101 Lisp_Object tail, frame;
12103 FOR_EACH_FRAME (tail, frame)
12105 struct frame *f = XFRAME (frame);
12106 struct window *w = XWINDOW (FRAME_SELECTED_WINDOW (f));
12107 if (some_windows
12108 && !f->redisplay
12109 && !w->redisplay
12110 && !XBUFFER (w->contents)->text->redisplay)
12111 continue;
12113 if (!FRAME_TOOLTIP_P (f)
12114 && !FRAME_PARENT_FRAME (f)
12115 && (FRAME_ICONIFIED_P (f)
12116 || FRAME_VISIBLE_P (f) == 1
12117 /* Exclude TTY frames that are obscured because they
12118 are not the top frame on their console. This is
12119 because x_consider_frame_title actually switches
12120 to the frame, which for TTY frames means it is
12121 marked as garbaged, and will be completely
12122 redrawn on the next redisplay cycle. This causes
12123 TTY frames to be completely redrawn, when there
12124 are more than one of them, even though nothing
12125 should be changed on display. */
12126 || (FRAME_VISIBLE_P (f) == 2 && FRAME_WINDOW_P (f))))
12127 x_consider_frame_title (frame);
12130 #endif /* HAVE_WINDOW_SYSTEM */
12132 /* Update the menu bar item lists, if appropriate. This has to be
12133 done before any actual redisplay or generation of display lines. */
12135 if (all_windows)
12137 Lisp_Object tail, frame;
12138 ptrdiff_t count = SPECPDL_INDEX ();
12139 /* True means that update_menu_bar has run its hooks
12140 so any further calls to update_menu_bar shouldn't do so again. */
12141 bool menu_bar_hooks_run = false;
12143 record_unwind_save_match_data ();
12145 FOR_EACH_FRAME (tail, frame)
12147 struct frame *f = XFRAME (frame);
12148 struct window *w = XWINDOW (FRAME_SELECTED_WINDOW (f));
12150 /* Ignore tooltip frame. */
12151 if (FRAME_TOOLTIP_P (f))
12152 continue;
12154 if (some_windows
12155 && !f->redisplay
12156 && !w->redisplay
12157 && !XBUFFER (w->contents)->text->redisplay)
12158 continue;
12160 run_window_size_change_functions (frame);
12162 if (FRAME_PARENT_FRAME (f))
12163 continue;
12165 menu_bar_hooks_run = update_menu_bar (f, false, menu_bar_hooks_run);
12166 #ifdef HAVE_WINDOW_SYSTEM
12167 update_tool_bar (f, false);
12168 #endif
12171 unbind_to (count, Qnil);
12173 else
12175 struct frame *sf = SELECTED_FRAME ();
12176 update_menu_bar (sf, true, false);
12177 #ifdef HAVE_WINDOW_SYSTEM
12178 update_tool_bar (sf, true);
12179 #endif
12184 /* Update the menu bar item list for frame F. This has to be done
12185 before we start to fill in any display lines, because it can call
12186 eval.
12188 If SAVE_MATCH_DATA, we must save and restore it here.
12190 If HOOKS_RUN, a previous call to update_menu_bar
12191 already ran the menu bar hooks for this redisplay, so there
12192 is no need to run them again. The return value is the
12193 updated value of this flag, to pass to the next call. */
12195 static bool
12196 update_menu_bar (struct frame *f, bool save_match_data, bool hooks_run)
12198 Lisp_Object window;
12199 struct window *w;
12201 /* If called recursively during a menu update, do nothing. This can
12202 happen when, for instance, an activate-menubar-hook causes a
12203 redisplay. */
12204 if (inhibit_menubar_update)
12205 return hooks_run;
12207 window = FRAME_SELECTED_WINDOW (f);
12208 w = XWINDOW (window);
12210 if (FRAME_WINDOW_P (f)
12212 #if defined (USE_X_TOOLKIT) || defined (HAVE_NTGUI) \
12213 || defined (HAVE_NS) || defined (USE_GTK)
12214 FRAME_EXTERNAL_MENU_BAR (f)
12215 #else
12216 FRAME_MENU_BAR_LINES (f) > 0
12217 #endif
12218 : FRAME_MENU_BAR_LINES (f) > 0)
12220 /* If the user has switched buffers or windows, we need to
12221 recompute to reflect the new bindings. But we'll
12222 recompute when update_mode_lines is set too; that means
12223 that people can use force-mode-line-update to request
12224 that the menu bar be recomputed. The adverse effect on
12225 the rest of the redisplay algorithm is about the same as
12226 windows_or_buffers_changed anyway. */
12227 if (windows_or_buffers_changed
12228 /* This used to test w->update_mode_line, but we believe
12229 there is no need to recompute the menu in that case. */
12230 || update_mode_lines
12231 || window_buffer_changed (w))
12233 struct buffer *prev = current_buffer;
12234 ptrdiff_t count = SPECPDL_INDEX ();
12236 specbind (Qinhibit_menubar_update, Qt);
12238 set_buffer_internal_1 (XBUFFER (w->contents));
12239 if (save_match_data)
12240 record_unwind_save_match_data ();
12241 if (NILP (Voverriding_local_map_menu_flag))
12243 specbind (Qoverriding_terminal_local_map, Qnil);
12244 specbind (Qoverriding_local_map, Qnil);
12247 if (!hooks_run)
12249 /* Run the Lucid hook. */
12250 safe_run_hooks (Qactivate_menubar_hook);
12252 /* If it has changed current-menubar from previous value,
12253 really recompute the menu-bar from the value. */
12254 if (! NILP (Vlucid_menu_bar_dirty_flag))
12255 call0 (Qrecompute_lucid_menubar);
12257 safe_run_hooks (Qmenu_bar_update_hook);
12259 hooks_run = true;
12262 XSETFRAME (Vmenu_updating_frame, f);
12263 fset_menu_bar_items (f, menu_bar_items (FRAME_MENU_BAR_ITEMS (f)));
12265 /* Redisplay the menu bar in case we changed it. */
12266 #if defined (USE_X_TOOLKIT) || defined (HAVE_NTGUI) \
12267 || defined (HAVE_NS) || defined (USE_GTK)
12268 if (FRAME_WINDOW_P (f))
12270 #if defined (HAVE_NS)
12271 /* All frames on Mac OS share the same menubar. So only
12272 the selected frame should be allowed to set it. */
12273 if (f == SELECTED_FRAME ())
12274 #endif
12275 set_frame_menubar (f, false, false);
12277 else
12278 /* On a terminal screen, the menu bar is an ordinary screen
12279 line, and this makes it get updated. */
12280 w->update_mode_line = true;
12281 #else /* ! (USE_X_TOOLKIT || HAVE_NTGUI || HAVE_NS || USE_GTK) */
12282 /* In the non-toolkit version, the menu bar is an ordinary screen
12283 line, and this makes it get updated. */
12284 w->update_mode_line = true;
12285 #endif /* ! (USE_X_TOOLKIT || HAVE_NTGUI || HAVE_NS || USE_GTK) */
12287 unbind_to (count, Qnil);
12288 set_buffer_internal_1 (prev);
12292 return hooks_run;
12295 /***********************************************************************
12296 Tool-bars
12297 ***********************************************************************/
12299 #ifdef HAVE_WINDOW_SYSTEM
12301 /* Select `frame' temporarily without running all the code in
12302 do_switch_frame.
12303 FIXME: Maybe do_switch_frame should be trimmed down similarly
12304 when `norecord' is set. */
12305 static void
12306 fast_set_selected_frame (Lisp_Object frame)
12308 if (!EQ (selected_frame, frame))
12310 selected_frame = frame;
12311 selected_window = XFRAME (frame)->selected_window;
12315 /* Update the tool-bar item list for frame F. This has to be done
12316 before we start to fill in any display lines. Called from
12317 prepare_menu_bars. If SAVE_MATCH_DATA, we must save
12318 and restore it here. */
12320 static void
12321 update_tool_bar (struct frame *f, bool save_match_data)
12323 #if defined (USE_GTK) || defined (HAVE_NS)
12324 bool do_update = FRAME_EXTERNAL_TOOL_BAR (f);
12325 #else
12326 bool do_update = (WINDOWP (f->tool_bar_window)
12327 && WINDOW_TOTAL_LINES (XWINDOW (f->tool_bar_window)) > 0);
12328 #endif
12330 if (do_update)
12332 Lisp_Object window;
12333 struct window *w;
12335 window = FRAME_SELECTED_WINDOW (f);
12336 w = XWINDOW (window);
12338 /* If the user has switched buffers or windows, we need to
12339 recompute to reflect the new bindings. But we'll
12340 recompute when update_mode_lines is set too; that means
12341 that people can use force-mode-line-update to request
12342 that the menu bar be recomputed. The adverse effect on
12343 the rest of the redisplay algorithm is about the same as
12344 windows_or_buffers_changed anyway. */
12345 if (windows_or_buffers_changed
12346 || w->update_mode_line
12347 || update_mode_lines
12348 || window_buffer_changed (w))
12350 struct buffer *prev = current_buffer;
12351 ptrdiff_t count = SPECPDL_INDEX ();
12352 Lisp_Object frame, new_tool_bar;
12353 int new_n_tool_bar;
12355 /* Set current_buffer to the buffer of the selected
12356 window of the frame, so that we get the right local
12357 keymaps. */
12358 set_buffer_internal_1 (XBUFFER (w->contents));
12360 /* Save match data, if we must. */
12361 if (save_match_data)
12362 record_unwind_save_match_data ();
12364 /* Make sure that we don't accidentally use bogus keymaps. */
12365 if (NILP (Voverriding_local_map_menu_flag))
12367 specbind (Qoverriding_terminal_local_map, Qnil);
12368 specbind (Qoverriding_local_map, Qnil);
12371 /* We must temporarily set the selected frame to this frame
12372 before calling tool_bar_items, because the calculation of
12373 the tool-bar keymap uses the selected frame (see
12374 `tool-bar-make-keymap' in tool-bar.el). */
12375 eassert (EQ (selected_window,
12376 /* Since we only explicitly preserve selected_frame,
12377 check that selected_window would be redundant. */
12378 XFRAME (selected_frame)->selected_window));
12379 record_unwind_protect (fast_set_selected_frame, selected_frame);
12380 XSETFRAME (frame, f);
12381 fast_set_selected_frame (frame);
12383 /* Build desired tool-bar items from keymaps. */
12384 new_tool_bar
12385 = tool_bar_items (Fcopy_sequence (f->tool_bar_items),
12386 &new_n_tool_bar);
12388 /* Redisplay the tool-bar if we changed it. */
12389 if (new_n_tool_bar != f->n_tool_bar_items
12390 || NILP (Fequal (new_tool_bar, f->tool_bar_items)))
12392 /* Redisplay that happens asynchronously due to an expose event
12393 may access f->tool_bar_items. Make sure we update both
12394 variables within BLOCK_INPUT so no such event interrupts. */
12395 block_input ();
12396 fset_tool_bar_items (f, new_tool_bar);
12397 f->n_tool_bar_items = new_n_tool_bar;
12398 w->update_mode_line = true;
12399 unblock_input ();
12402 unbind_to (count, Qnil);
12403 set_buffer_internal_1 (prev);
12408 #if ! defined (USE_GTK) && ! defined (HAVE_NS)
12410 /* Set F->desired_tool_bar_string to a Lisp string representing frame
12411 F's desired tool-bar contents. F->tool_bar_items must have
12412 been set up previously by calling prepare_menu_bars. */
12414 static void
12415 build_desired_tool_bar_string (struct frame *f)
12417 int i, size, size_needed;
12418 Lisp_Object image, plist;
12420 image = plist = Qnil;
12422 /* Prepare F->desired_tool_bar_string. If we can reuse it, do so.
12423 Otherwise, make a new string. */
12425 /* The size of the string we might be able to reuse. */
12426 size = (STRINGP (f->desired_tool_bar_string)
12427 ? SCHARS (f->desired_tool_bar_string)
12428 : 0);
12430 /* We need one space in the string for each image. */
12431 size_needed = f->n_tool_bar_items;
12433 /* Reuse f->desired_tool_bar_string, if possible. */
12434 if (size < size_needed || NILP (f->desired_tool_bar_string))
12435 fset_desired_tool_bar_string
12436 (f, Fmake_string (make_number (size_needed), make_number (' '), Qnil));
12437 else
12439 AUTO_LIST4 (props, Qdisplay, Qnil, Qmenu_item, Qnil);
12440 Fremove_text_properties (make_number (0), make_number (size),
12441 props, f->desired_tool_bar_string);
12444 /* Put a `display' property on the string for the images to display,
12445 put a `menu_item' property on tool-bar items with a value that
12446 is the index of the item in F's tool-bar item vector. */
12447 for (i = 0; i < f->n_tool_bar_items; ++i)
12449 #define PROP(IDX) \
12450 AREF (f->tool_bar_items, i * TOOL_BAR_ITEM_NSLOTS + (IDX))
12452 bool enabled_p = !NILP (PROP (TOOL_BAR_ITEM_ENABLED_P));
12453 bool selected_p = !NILP (PROP (TOOL_BAR_ITEM_SELECTED_P));
12454 int hmargin, vmargin, relief, idx, end;
12456 /* If image is a vector, choose the image according to the
12457 button state. */
12458 image = PROP (TOOL_BAR_ITEM_IMAGES);
12459 if (VECTORP (image))
12461 if (enabled_p)
12462 idx = (selected_p
12463 ? TOOL_BAR_IMAGE_ENABLED_SELECTED
12464 : TOOL_BAR_IMAGE_ENABLED_DESELECTED);
12465 else
12466 idx = (selected_p
12467 ? TOOL_BAR_IMAGE_DISABLED_SELECTED
12468 : TOOL_BAR_IMAGE_DISABLED_DESELECTED);
12470 eassert (ASIZE (image) >= idx);
12471 image = AREF (image, idx);
12473 else
12474 idx = -1;
12476 /* Ignore invalid image specifications. */
12477 if (!valid_image_p (image))
12478 continue;
12480 /* Display the tool-bar button pressed, or depressed. */
12481 plist = Fcopy_sequence (XCDR (image));
12483 /* Compute margin and relief to draw. */
12484 relief = (tool_bar_button_relief >= 0
12485 ? tool_bar_button_relief
12486 : DEFAULT_TOOL_BAR_BUTTON_RELIEF);
12487 hmargin = vmargin = relief;
12489 if (RANGED_INTEGERP (1, Vtool_bar_button_margin,
12490 INT_MAX - max (hmargin, vmargin)))
12492 hmargin += XFASTINT (Vtool_bar_button_margin);
12493 vmargin += XFASTINT (Vtool_bar_button_margin);
12495 else if (CONSP (Vtool_bar_button_margin))
12497 if (RANGED_INTEGERP (1, XCAR (Vtool_bar_button_margin),
12498 INT_MAX - hmargin))
12499 hmargin += XFASTINT (XCAR (Vtool_bar_button_margin));
12501 if (RANGED_INTEGERP (1, XCDR (Vtool_bar_button_margin),
12502 INT_MAX - vmargin))
12503 vmargin += XFASTINT (XCDR (Vtool_bar_button_margin));
12506 if (auto_raise_tool_bar_buttons_p)
12508 /* Add a `:relief' property to the image spec if the item is
12509 selected. */
12510 if (selected_p)
12512 plist = Fplist_put (plist, QCrelief, make_number (-relief));
12513 hmargin -= relief;
12514 vmargin -= relief;
12517 else
12519 /* If image is selected, display it pressed, i.e. with a
12520 negative relief. If it's not selected, display it with a
12521 raised relief. */
12522 plist = Fplist_put (plist, QCrelief,
12523 (selected_p
12524 ? make_number (-relief)
12525 : make_number (relief)));
12526 hmargin -= relief;
12527 vmargin -= relief;
12530 /* Put a margin around the image. */
12531 if (hmargin || vmargin)
12533 if (hmargin == vmargin)
12534 plist = Fplist_put (plist, QCmargin, make_number (hmargin));
12535 else
12536 plist = Fplist_put (plist, QCmargin,
12537 Fcons (make_number (hmargin),
12538 make_number (vmargin)));
12541 /* If button is not enabled, and we don't have special images
12542 for the disabled state, make the image appear disabled by
12543 applying an appropriate algorithm to it. */
12544 if (!enabled_p && idx < 0)
12545 plist = Fplist_put (plist, QCconversion, Qdisabled);
12547 /* Put a `display' text property on the string for the image to
12548 display. Put a `menu-item' property on the string that gives
12549 the start of this item's properties in the tool-bar items
12550 vector. */
12551 image = Fcons (Qimage, plist);
12552 AUTO_LIST4 (props, Qdisplay, image, Qmenu_item,
12553 make_number (i * TOOL_BAR_ITEM_NSLOTS));
12555 /* Let the last image hide all remaining spaces in the tool bar
12556 string. The string can be longer than needed when we reuse a
12557 previous string. */
12558 if (i + 1 == f->n_tool_bar_items)
12559 end = SCHARS (f->desired_tool_bar_string);
12560 else
12561 end = i + 1;
12562 Fadd_text_properties (make_number (i), make_number (end),
12563 props, f->desired_tool_bar_string);
12564 #undef PROP
12569 /* Display one line of the tool-bar of frame IT->f.
12571 HEIGHT specifies the desired height of the tool-bar line.
12572 If the actual height of the glyph row is less than HEIGHT, the
12573 row's height is increased to HEIGHT, and the icons are centered
12574 vertically in the new height.
12576 If HEIGHT is -1, we are counting needed tool-bar lines, so don't
12577 count a final empty row in case the tool-bar width exactly matches
12578 the window width.
12581 static void
12582 display_tool_bar_line (struct it *it, int height)
12584 struct glyph_row *row = it->glyph_row;
12585 int max_x = it->last_visible_x;
12586 struct glyph *last;
12588 /* Don't extend on a previously drawn tool bar items (Bug#16058). */
12589 clear_glyph_row (row);
12590 row->enabled_p = true;
12591 row->y = it->current_y;
12593 /* Note that this isn't made use of if the face hasn't a box,
12594 so there's no need to check the face here. */
12595 it->start_of_box_run_p = true;
12597 while (it->current_x < max_x)
12599 int x, n_glyphs_before, i, nglyphs;
12600 struct it it_before;
12602 /* Get the next display element. */
12603 if (!get_next_display_element (it))
12605 /* Don't count empty row if we are counting needed tool-bar lines. */
12606 if (height < 0 && !it->hpos)
12607 return;
12608 break;
12611 /* Produce glyphs. */
12612 n_glyphs_before = row->used[TEXT_AREA];
12613 it_before = *it;
12615 PRODUCE_GLYPHS (it);
12617 nglyphs = row->used[TEXT_AREA] - n_glyphs_before;
12618 i = 0;
12619 x = it_before.current_x;
12620 while (i < nglyphs)
12622 struct glyph *glyph = row->glyphs[TEXT_AREA] + n_glyphs_before + i;
12624 if (x + glyph->pixel_width > max_x)
12626 /* Glyph doesn't fit on line. Backtrack. */
12627 row->used[TEXT_AREA] = n_glyphs_before;
12628 *it = it_before;
12629 /* If this is the only glyph on this line, it will never fit on the
12630 tool-bar, so skip it. But ensure there is at least one glyph,
12631 so we don't accidentally disable the tool-bar. */
12632 if (n_glyphs_before == 0
12633 && (it->vpos > 0 || IT_STRING_CHARPOS (*it) < it->end_charpos-1))
12634 break;
12635 goto out;
12638 ++it->hpos;
12639 x += glyph->pixel_width;
12640 ++i;
12643 /* Stop at line end. */
12644 if (ITERATOR_AT_END_OF_LINE_P (it))
12645 break;
12647 set_iterator_to_next (it, true);
12650 out:;
12652 row->displays_text_p = row->used[TEXT_AREA] != 0;
12654 /* Use default face for the border below the tool bar.
12656 FIXME: When auto-resize-tool-bars is grow-only, there is
12657 no additional border below the possibly empty tool-bar lines.
12658 So to make the extra empty lines look "normal", we have to
12659 use the tool-bar face for the border too. */
12660 if (!MATRIX_ROW_DISPLAYS_TEXT_P (row)
12661 && !EQ (Vauto_resize_tool_bars, Qgrow_only))
12662 it->face_id = DEFAULT_FACE_ID;
12664 extend_face_to_end_of_line (it);
12665 last = row->glyphs[TEXT_AREA] + row->used[TEXT_AREA] - 1;
12666 last->right_box_line_p = true;
12667 if (last == row->glyphs[TEXT_AREA])
12668 last->left_box_line_p = true;
12670 /* Make line the desired height and center it vertically. */
12671 if ((height -= it->max_ascent + it->max_descent) > 0)
12673 /* Don't add more than one line height. */
12674 height %= FRAME_LINE_HEIGHT (it->f);
12675 it->max_ascent += height / 2;
12676 it->max_descent += (height + 1) / 2;
12679 compute_line_metrics (it);
12681 /* If line is empty, make it occupy the rest of the tool-bar. */
12682 if (!MATRIX_ROW_DISPLAYS_TEXT_P (row))
12684 row->height = row->phys_height = it->last_visible_y - row->y;
12685 row->visible_height = row->height;
12686 row->ascent = row->phys_ascent = 0;
12687 row->extra_line_spacing = 0;
12690 row->full_width_p = true;
12691 row->continued_p = false;
12692 row->truncated_on_left_p = false;
12693 row->truncated_on_right_p = false;
12695 it->current_x = it->hpos = 0;
12696 it->current_y += row->height;
12697 ++it->vpos;
12698 ++it->glyph_row;
12702 /* Value is the number of pixels needed to make all tool-bar items of
12703 frame F visible. The actual number of glyph rows needed is
12704 returned in *N_ROWS if non-NULL. */
12705 static int
12706 tool_bar_height (struct frame *f, int *n_rows, bool pixelwise)
12708 struct window *w = XWINDOW (f->tool_bar_window);
12709 struct it it;
12710 /* tool_bar_height is called from redisplay_tool_bar after building
12711 the desired matrix, so use (unused) mode-line row as temporary row to
12712 avoid destroying the first tool-bar row. */
12713 struct glyph_row *temp_row = MATRIX_MODE_LINE_ROW (w->desired_matrix);
12715 /* Initialize an iterator for iteration over
12716 F->desired_tool_bar_string in the tool-bar window of frame F. */
12717 init_iterator (&it, w, -1, -1, temp_row, TOOL_BAR_FACE_ID);
12718 temp_row->reversed_p = false;
12719 it.first_visible_x = 0;
12720 it.last_visible_x = WINDOW_PIXEL_WIDTH (w);
12721 reseat_to_string (&it, NULL, f->desired_tool_bar_string, 0, 0, 0, -1);
12722 it.paragraph_embedding = L2R;
12724 while (!ITERATOR_AT_END_P (&it))
12726 clear_glyph_row (temp_row);
12727 it.glyph_row = temp_row;
12728 display_tool_bar_line (&it, -1);
12730 clear_glyph_row (temp_row);
12732 /* f->n_tool_bar_rows == 0 means "unknown"; -1 means no tool-bar. */
12733 if (n_rows)
12734 *n_rows = it.vpos > 0 ? it.vpos : -1;
12736 if (pixelwise)
12737 return it.current_y;
12738 else
12739 return (it.current_y + FRAME_LINE_HEIGHT (f) - 1) / FRAME_LINE_HEIGHT (f);
12742 #endif /* !USE_GTK && !HAVE_NS */
12744 DEFUN ("tool-bar-height", Ftool_bar_height, Stool_bar_height,
12745 0, 2, 0,
12746 doc: /* Return the number of lines occupied by the tool bar of FRAME.
12747 If FRAME is nil or omitted, use the selected frame. Optional argument
12748 PIXELWISE non-nil means return the height of the tool bar in pixels. */)
12749 (Lisp_Object frame, Lisp_Object pixelwise)
12751 int height = 0;
12753 #if ! defined (USE_GTK) && ! defined (HAVE_NS)
12754 struct frame *f = decode_any_frame (frame);
12756 if (WINDOWP (f->tool_bar_window)
12757 && WINDOW_PIXEL_HEIGHT (XWINDOW (f->tool_bar_window)) > 0)
12759 update_tool_bar (f, true);
12760 if (f->n_tool_bar_items)
12762 build_desired_tool_bar_string (f);
12763 height = tool_bar_height (f, NULL, !NILP (pixelwise));
12766 #endif
12768 return make_number (height);
12772 /* Display the tool-bar of frame F. Value is true if tool-bar's
12773 height should be changed. */
12774 static bool
12775 redisplay_tool_bar (struct frame *f)
12777 f->tool_bar_redisplayed = true;
12778 #if defined (USE_GTK) || defined (HAVE_NS)
12780 if (FRAME_EXTERNAL_TOOL_BAR (f))
12781 update_frame_tool_bar (f);
12782 return false;
12784 #else /* !USE_GTK && !HAVE_NS */
12786 struct window *w;
12787 struct it it;
12788 struct glyph_row *row;
12790 /* If frame hasn't a tool-bar window or if it is zero-height, don't
12791 do anything. This means you must start with tool-bar-lines
12792 non-zero to get the auto-sizing effect. Or in other words, you
12793 can turn off tool-bars by specifying tool-bar-lines zero. */
12794 if (!WINDOWP (f->tool_bar_window)
12795 || (w = XWINDOW (f->tool_bar_window),
12796 WINDOW_TOTAL_LINES (w) == 0))
12797 return false;
12799 /* Set up an iterator for the tool-bar window. */
12800 init_iterator (&it, w, -1, -1, w->desired_matrix->rows, TOOL_BAR_FACE_ID);
12801 it.first_visible_x = 0;
12802 it.last_visible_x = WINDOW_PIXEL_WIDTH (w);
12803 row = it.glyph_row;
12804 row->reversed_p = false;
12806 /* Build a string that represents the contents of the tool-bar. */
12807 build_desired_tool_bar_string (f);
12808 reseat_to_string (&it, NULL, f->desired_tool_bar_string, 0, 0, 0, -1);
12809 /* FIXME: This should be controlled by a user option. But it
12810 doesn't make sense to have an R2L tool bar if the menu bar cannot
12811 be drawn also R2L, and making the menu bar R2L is tricky due
12812 toolkit-specific code that implements it. If an R2L tool bar is
12813 ever supported, display_tool_bar_line should also be augmented to
12814 call unproduce_glyphs like display_line and display_string
12815 do. */
12816 it.paragraph_embedding = L2R;
12818 if (f->n_tool_bar_rows == 0)
12820 int new_height = tool_bar_height (f, &f->n_tool_bar_rows, true);
12822 if (new_height != WINDOW_PIXEL_HEIGHT (w))
12824 x_change_tool_bar_height (f, new_height);
12825 frame_default_tool_bar_height = new_height;
12826 /* Always do that now. */
12827 clear_glyph_matrix (w->desired_matrix);
12828 f->fonts_changed = true;
12829 return true;
12833 /* Display as many lines as needed to display all tool-bar items. */
12835 if (f->n_tool_bar_rows > 0)
12837 int border, rows, height, extra;
12839 if (TYPE_RANGED_INTEGERP (int, Vtool_bar_border))
12840 border = XINT (Vtool_bar_border);
12841 else if (EQ (Vtool_bar_border, Qinternal_border_width))
12842 border = FRAME_INTERNAL_BORDER_WIDTH (f);
12843 else if (EQ (Vtool_bar_border, Qborder_width))
12844 border = f->border_width;
12845 else
12846 border = 0;
12847 if (border < 0)
12848 border = 0;
12850 rows = f->n_tool_bar_rows;
12851 height = max (1, (it.last_visible_y - border) / rows);
12852 extra = it.last_visible_y - border - height * rows;
12854 while (it.current_y < it.last_visible_y)
12856 int h = 0;
12857 if (extra > 0 && rows-- > 0)
12859 h = (extra + rows - 1) / rows;
12860 extra -= h;
12862 display_tool_bar_line (&it, height + h);
12865 else
12867 while (it.current_y < it.last_visible_y)
12868 display_tool_bar_line (&it, 0);
12871 /* It doesn't make much sense to try scrolling in the tool-bar
12872 window, so don't do it. */
12873 w->desired_matrix->no_scrolling_p = true;
12874 w->must_be_updated_p = true;
12876 if (!NILP (Vauto_resize_tool_bars))
12878 bool change_height_p = true;
12880 /* If we couldn't display everything, change the tool-bar's
12881 height if there is room for more. */
12882 if (IT_STRING_CHARPOS (it) < it.end_charpos)
12883 change_height_p = true;
12885 /* We subtract 1 because display_tool_bar_line advances the
12886 glyph_row pointer before returning to its caller. We want to
12887 examine the last glyph row produced by
12888 display_tool_bar_line. */
12889 row = it.glyph_row - 1;
12891 /* If there are blank lines at the end, except for a partially
12892 visible blank line at the end that is smaller than
12893 FRAME_LINE_HEIGHT, change the tool-bar's height. */
12894 if (!MATRIX_ROW_DISPLAYS_TEXT_P (row)
12895 && row->height >= FRAME_LINE_HEIGHT (f))
12896 change_height_p = true;
12898 /* If row displays tool-bar items, but is partially visible,
12899 change the tool-bar's height. */
12900 if (MATRIX_ROW_DISPLAYS_TEXT_P (row)
12901 && MATRIX_ROW_BOTTOM_Y (row) > it.last_visible_y)
12902 change_height_p = true;
12904 /* Resize windows as needed by changing the `tool-bar-lines'
12905 frame parameter. */
12906 if (change_height_p)
12908 int nrows;
12909 int new_height = tool_bar_height (f, &nrows, true);
12911 change_height_p = ((EQ (Vauto_resize_tool_bars, Qgrow_only)
12912 && !f->minimize_tool_bar_window_p)
12913 ? (new_height > WINDOW_PIXEL_HEIGHT (w))
12914 : (new_height != WINDOW_PIXEL_HEIGHT (w)));
12915 f->minimize_tool_bar_window_p = false;
12917 if (change_height_p)
12919 x_change_tool_bar_height (f, new_height);
12920 frame_default_tool_bar_height = new_height;
12921 clear_glyph_matrix (w->desired_matrix);
12922 f->n_tool_bar_rows = nrows;
12923 f->fonts_changed = true;
12925 return true;
12930 f->minimize_tool_bar_window_p = false;
12931 return false;
12933 #endif /* USE_GTK || HAVE_NS */
12936 #if ! defined (USE_GTK) && ! defined (HAVE_NS)
12938 /* Get information about the tool-bar item which is displayed in GLYPH
12939 on frame F. Return in *PROP_IDX the index where tool-bar item
12940 properties start in F->tool_bar_items. Value is false if
12941 GLYPH doesn't display a tool-bar item. */
12943 static bool
12944 tool_bar_item_info (struct frame *f, struct glyph *glyph, int *prop_idx)
12946 Lisp_Object prop;
12947 int charpos;
12949 /* This function can be called asynchronously, which means we must
12950 exclude any possibility that Fget_text_property signals an
12951 error. */
12952 charpos = min (SCHARS (f->current_tool_bar_string), glyph->charpos);
12953 charpos = max (0, charpos);
12955 /* Get the text property `menu-item' at pos. The value of that
12956 property is the start index of this item's properties in
12957 F->tool_bar_items. */
12958 prop = Fget_text_property (make_number (charpos),
12959 Qmenu_item, f->current_tool_bar_string);
12960 if (! INTEGERP (prop))
12961 return false;
12962 *prop_idx = XINT (prop);
12963 return true;
12967 /* Get information about the tool-bar item at position X/Y on frame F.
12968 Return in *GLYPH a pointer to the glyph of the tool-bar item in
12969 the current matrix of the tool-bar window of F, or NULL if not
12970 on a tool-bar item. Return in *PROP_IDX the index of the tool-bar
12971 item in F->tool_bar_items. Value is
12973 -1 if X/Y is not on a tool-bar item
12974 0 if X/Y is on the same item that was highlighted before.
12975 1 otherwise. */
12977 static int
12978 get_tool_bar_item (struct frame *f, int x, int y, struct glyph **glyph,
12979 int *hpos, int *vpos, int *prop_idx)
12981 Mouse_HLInfo *hlinfo = MOUSE_HL_INFO (f);
12982 struct window *w = XWINDOW (f->tool_bar_window);
12983 int area;
12985 /* Find the glyph under X/Y. */
12986 *glyph = x_y_to_hpos_vpos (w, x, y, hpos, vpos, 0, 0, &area);
12987 if (*glyph == NULL)
12988 return -1;
12990 /* Get the start of this tool-bar item's properties in
12991 f->tool_bar_items. */
12992 if (!tool_bar_item_info (f, *glyph, prop_idx))
12993 return -1;
12995 /* Is mouse on the highlighted item? */
12996 if (EQ (f->tool_bar_window, hlinfo->mouse_face_window)
12997 && *vpos >= hlinfo->mouse_face_beg_row
12998 && *vpos <= hlinfo->mouse_face_end_row
12999 && (*vpos > hlinfo->mouse_face_beg_row
13000 || *hpos >= hlinfo->mouse_face_beg_col)
13001 && (*vpos < hlinfo->mouse_face_end_row
13002 || *hpos < hlinfo->mouse_face_end_col
13003 || hlinfo->mouse_face_past_end))
13004 return 0;
13006 return 1;
13010 /* EXPORT:
13011 Handle mouse button event on the tool-bar of frame F, at
13012 frame-relative coordinates X/Y. DOWN_P is true for a button press,
13013 false for button release. MODIFIERS is event modifiers for button
13014 release. */
13016 void
13017 handle_tool_bar_click (struct frame *f, int x, int y, bool down_p,
13018 int modifiers)
13020 Mouse_HLInfo *hlinfo = MOUSE_HL_INFO (f);
13021 struct window *w = XWINDOW (f->tool_bar_window);
13022 int hpos, vpos, prop_idx;
13023 struct glyph *glyph;
13024 Lisp_Object enabled_p;
13025 int ts;
13027 /* If not on the highlighted tool-bar item, and mouse-highlight is
13028 non-nil, return. This is so we generate the tool-bar button
13029 click only when the mouse button is released on the same item as
13030 where it was pressed. However, when mouse-highlight is disabled,
13031 generate the click when the button is released regardless of the
13032 highlight, since tool-bar items are not highlighted in that
13033 case. */
13034 frame_to_window_pixel_xy (w, &x, &y);
13035 ts = get_tool_bar_item (f, x, y, &glyph, &hpos, &vpos, &prop_idx);
13036 if (ts == -1
13037 || (ts != 0 && !NILP (Vmouse_highlight)))
13038 return;
13040 /* When mouse-highlight is off, generate the click for the item
13041 where the button was pressed, disregarding where it was
13042 released. */
13043 if (NILP (Vmouse_highlight) && !down_p)
13044 prop_idx = f->last_tool_bar_item;
13046 /* If item is disabled, do nothing. */
13047 enabled_p = AREF (f->tool_bar_items, prop_idx + TOOL_BAR_ITEM_ENABLED_P);
13048 if (NILP (enabled_p))
13049 return;
13051 if (down_p)
13053 /* Show item in pressed state. */
13054 if (!NILP (Vmouse_highlight))
13055 show_mouse_face (hlinfo, DRAW_IMAGE_SUNKEN);
13056 f->last_tool_bar_item = prop_idx;
13058 else
13060 Lisp_Object key, frame;
13061 struct input_event event;
13062 EVENT_INIT (event);
13064 /* Show item in released state. */
13065 if (!NILP (Vmouse_highlight))
13066 show_mouse_face (hlinfo, DRAW_IMAGE_RAISED);
13068 key = AREF (f->tool_bar_items, prop_idx + TOOL_BAR_ITEM_KEY);
13070 XSETFRAME (frame, f);
13071 event.kind = TOOL_BAR_EVENT;
13072 event.frame_or_window = frame;
13073 event.arg = frame;
13074 kbd_buffer_store_event (&event);
13076 event.kind = TOOL_BAR_EVENT;
13077 event.frame_or_window = frame;
13078 event.arg = key;
13079 event.modifiers = modifiers;
13080 kbd_buffer_store_event (&event);
13081 f->last_tool_bar_item = -1;
13086 /* Possibly highlight a tool-bar item on frame F when mouse moves to
13087 tool-bar window-relative coordinates X/Y. Called from
13088 note_mouse_highlight. */
13090 static void
13091 note_tool_bar_highlight (struct frame *f, int x, int y)
13093 Lisp_Object window = f->tool_bar_window;
13094 struct window *w = XWINDOW (window);
13095 Display_Info *dpyinfo = FRAME_DISPLAY_INFO (f);
13096 Mouse_HLInfo *hlinfo = MOUSE_HL_INFO (f);
13097 int hpos, vpos;
13098 struct glyph *glyph;
13099 struct glyph_row *row;
13100 int i;
13101 Lisp_Object enabled_p;
13102 int prop_idx;
13103 enum draw_glyphs_face draw = DRAW_IMAGE_RAISED;
13104 bool mouse_down_p;
13105 int rc;
13107 /* Function note_mouse_highlight is called with negative X/Y
13108 values when mouse moves outside of the frame. */
13109 if (x <= 0 || y <= 0)
13111 clear_mouse_face (hlinfo);
13112 return;
13115 rc = get_tool_bar_item (f, x, y, &glyph, &hpos, &vpos, &prop_idx);
13116 if (rc < 0)
13118 /* Not on tool-bar item. */
13119 clear_mouse_face (hlinfo);
13120 return;
13122 else if (rc == 0)
13123 /* On same tool-bar item as before. */
13124 goto set_help_echo;
13126 clear_mouse_face (hlinfo);
13128 /* Mouse is down, but on different tool-bar item? */
13129 mouse_down_p = (x_mouse_grabbed (dpyinfo)
13130 && f == dpyinfo->last_mouse_frame);
13132 if (mouse_down_p && f->last_tool_bar_item != prop_idx)
13133 return;
13135 draw = mouse_down_p ? DRAW_IMAGE_SUNKEN : DRAW_IMAGE_RAISED;
13137 /* If tool-bar item is not enabled, don't highlight it. */
13138 enabled_p = AREF (f->tool_bar_items, prop_idx + TOOL_BAR_ITEM_ENABLED_P);
13139 if (!NILP (enabled_p) && !NILP (Vmouse_highlight))
13141 /* Compute the x-position of the glyph. In front and past the
13142 image is a space. We include this in the highlighted area. */
13143 row = MATRIX_ROW (w->current_matrix, vpos);
13144 for (i = x = 0; i < hpos; ++i)
13145 x += row->glyphs[TEXT_AREA][i].pixel_width;
13147 /* Record this as the current active region. */
13148 hlinfo->mouse_face_beg_col = hpos;
13149 hlinfo->mouse_face_beg_row = vpos;
13150 hlinfo->mouse_face_beg_x = x;
13151 hlinfo->mouse_face_past_end = false;
13153 hlinfo->mouse_face_end_col = hpos + 1;
13154 hlinfo->mouse_face_end_row = vpos;
13155 hlinfo->mouse_face_end_x = x + glyph->pixel_width;
13156 hlinfo->mouse_face_window = window;
13157 hlinfo->mouse_face_face_id = TOOL_BAR_FACE_ID;
13159 /* Display it as active. */
13160 show_mouse_face (hlinfo, draw);
13163 set_help_echo:
13165 /* Set help_echo_string to a help string to display for this tool-bar item.
13166 XTread_socket does the rest. */
13167 help_echo_object = help_echo_window = Qnil;
13168 help_echo_pos = -1;
13169 help_echo_string = AREF (f->tool_bar_items, prop_idx + TOOL_BAR_ITEM_HELP);
13170 if (NILP (help_echo_string))
13171 help_echo_string = AREF (f->tool_bar_items, prop_idx + TOOL_BAR_ITEM_CAPTION);
13174 #endif /* !USE_GTK && !HAVE_NS */
13176 #endif /* HAVE_WINDOW_SYSTEM */
13180 /************************************************************************
13181 Horizontal scrolling
13182 ************************************************************************/
13184 /* For all leaf windows in the window tree rooted at WINDOW, set their
13185 hscroll value so that PT is (i) visible in the window, and (ii) so
13186 that it is not within a certain margin at the window's left and
13187 right border. Value is true if any window's hscroll has been
13188 changed. */
13190 static bool
13191 hscroll_window_tree (Lisp_Object window)
13193 bool hscrolled_p = false;
13194 bool hscroll_relative_p = FLOATP (Vhscroll_step);
13195 int hscroll_step_abs = 0;
13196 double hscroll_step_rel = 0;
13198 if (hscroll_relative_p)
13200 hscroll_step_rel = XFLOAT_DATA (Vhscroll_step);
13201 if (hscroll_step_rel < 0)
13203 hscroll_relative_p = false;
13204 hscroll_step_abs = 0;
13207 else if (TYPE_RANGED_INTEGERP (int, Vhscroll_step))
13209 hscroll_step_abs = XINT (Vhscroll_step);
13210 if (hscroll_step_abs < 0)
13211 hscroll_step_abs = 0;
13213 else
13214 hscroll_step_abs = 0;
13216 while (WINDOWP (window))
13218 struct window *w = XWINDOW (window);
13220 if (WINDOWP (w->contents))
13221 hscrolled_p |= hscroll_window_tree (w->contents);
13222 else if (w->cursor.vpos >= 0)
13224 int h_margin;
13225 int text_area_width;
13226 struct glyph_row *cursor_row;
13227 struct glyph_row *bottom_row;
13229 bottom_row = MATRIX_BOTTOM_TEXT_ROW (w->desired_matrix, w);
13230 if (w->cursor.vpos < bottom_row - w->desired_matrix->rows)
13231 cursor_row = MATRIX_ROW (w->desired_matrix, w->cursor.vpos);
13232 else
13233 cursor_row = bottom_row - 1;
13235 if (!cursor_row->enabled_p)
13237 bottom_row = MATRIX_BOTTOM_TEXT_ROW (w->current_matrix, w);
13238 if (w->cursor.vpos < bottom_row - w->current_matrix->rows)
13239 cursor_row = MATRIX_ROW (w->current_matrix, w->cursor.vpos);
13240 else
13241 cursor_row = bottom_row - 1;
13243 bool row_r2l_p = cursor_row->reversed_p;
13244 bool hscl = hscrolling_current_line_p (w);
13245 int x_offset = 0;
13246 /* When line numbers are displayed, we need to account for
13247 the horizontal space they consume. */
13248 if (!NILP (Vdisplay_line_numbers))
13250 struct glyph *g;
13251 if (!row_r2l_p)
13253 for (g = cursor_row->glyphs[TEXT_AREA];
13254 g < cursor_row->glyphs[TEXT_AREA]
13255 + cursor_row->used[TEXT_AREA];
13256 g++)
13258 if (!(NILP (g->object) && g->charpos < 0))
13259 break;
13260 x_offset += g->pixel_width;
13263 else
13265 for (g = cursor_row->glyphs[TEXT_AREA]
13266 + cursor_row->used[TEXT_AREA];
13267 g > cursor_row->glyphs[TEXT_AREA];
13268 g--)
13270 if (!(NILP ((g - 1)->object) && (g - 1)->charpos < 0))
13271 break;
13272 x_offset += (g - 1)->pixel_width;
13276 if (cursor_row->truncated_on_left_p)
13278 /* On TTY frames, don't count the left truncation glyph. */
13279 struct frame *f = XFRAME (WINDOW_FRAME (w));
13280 x_offset -= (FRAME_TERMCAP_P (f) || FRAME_MSDOS_P (f));
13283 text_area_width = window_box_width (w, TEXT_AREA);
13285 /* Scroll when cursor is inside this scroll margin. */
13286 h_margin = hscroll_margin * WINDOW_FRAME_COLUMN_WIDTH (w);
13288 /* If the position of this window's point has explicitly
13289 changed, no more suspend auto hscrolling. */
13290 if (w->suspend_auto_hscroll
13291 && NILP (Fequal (Fwindow_point (window),
13292 Fwindow_old_point (window))))
13294 w->suspend_auto_hscroll = false;
13295 /* When hscrolling just the current line, and the rest
13296 of lines were temporarily hscrolled, but no longer
13297 are, force thorough redisplay of this window, to show
13298 the effect of disabling hscroll suspension immediately. */
13299 if (w->min_hscroll == 0 && w->hscroll > 0
13300 && EQ (Fbuffer_local_value (Qauto_hscroll_mode, w->contents),
13301 Qcurrent_line))
13302 SET_FRAME_GARBAGED (XFRAME (w->frame));
13305 /* Remember window point. */
13306 Fset_marker (w->old_pointm,
13307 ((w == XWINDOW (selected_window))
13308 ? make_number (BUF_PT (XBUFFER (w->contents)))
13309 : Fmarker_position (w->pointm)),
13310 w->contents);
13312 if (!NILP (Fbuffer_local_value (Qauto_hscroll_mode, w->contents))
13313 && !w->suspend_auto_hscroll
13314 /* In some pathological cases, like restoring a window
13315 configuration into a frame that is much smaller than
13316 the one from which the configuration was saved, we
13317 get glyph rows whose start and end have zero buffer
13318 positions, which we cannot handle below. Just skip
13319 such windows. */
13320 && CHARPOS (cursor_row->start.pos) >= BUF_BEG (w->contents)
13321 /* For left-to-right rows, hscroll when cursor is either
13322 (i) inside the right hscroll margin, or (ii) if it is
13323 inside the left margin and the window is already
13324 hscrolled. */
13325 && ((!row_r2l_p
13326 && ((w->hscroll && w->cursor.x <= h_margin + x_offset)
13327 || (cursor_row->enabled_p
13328 && cursor_row->truncated_on_right_p
13329 && (w->cursor.x >= text_area_width - h_margin))))
13330 /* For right-to-left rows, the logic is similar,
13331 except that rules for scrolling to left and right
13332 are reversed. E.g., if cursor.x <= h_margin, we
13333 need to hscroll "to the right" unconditionally,
13334 and that will scroll the screen to the left so as
13335 to reveal the next portion of the row. */
13336 || (row_r2l_p
13337 && ((cursor_row->enabled_p
13338 /* FIXME: It is confusing to set the
13339 truncated_on_right_p flag when R2L rows
13340 are actually truncated on the left. */
13341 && cursor_row->truncated_on_right_p
13342 && w->cursor.x <= h_margin)
13343 || (w->hscroll
13344 && (w->cursor.x >= (text_area_width - h_margin
13345 - x_offset)))))
13346 /* This last condition is needed when moving
13347 vertically from an hscrolled line to a short line
13348 that doesn't need to be hscrolled. If we omit
13349 this condition, the line from which we move will
13350 remain hscrolled. */
13351 || (hscl
13352 && w->hscroll != w->min_hscroll
13353 && !cursor_row->truncated_on_left_p)))
13355 struct it it;
13356 ptrdiff_t hscroll;
13357 struct buffer *saved_current_buffer;
13358 ptrdiff_t pt;
13359 int wanted_x;
13361 /* Find point in a display of infinite width. */
13362 saved_current_buffer = current_buffer;
13363 current_buffer = XBUFFER (w->contents);
13365 if (w == XWINDOW (selected_window))
13366 pt = PT;
13367 else
13368 pt = clip_to_bounds (BEGV, marker_position (w->pointm), ZV);
13370 /* Move iterator to pt starting at cursor_row->start in
13371 a line with infinite width. */
13372 init_to_row_start (&it, w, cursor_row);
13373 if (hscl)
13374 it.first_visible_x = window_hscroll_limited (w, it.f)
13375 * FRAME_COLUMN_WIDTH (it.f);
13376 it.last_visible_x = DISP_INFINITY;
13377 move_it_in_display_line_to (&it, pt, -1, MOVE_TO_POS);
13378 /* If the line ends in an overlay string with a newline,
13379 we might infloop, because displaying the window will
13380 want to put the cursor after the overlay, i.e. at X
13381 coordinate of zero on the next screen line. So we
13382 use the buffer position prior to the overlay string
13383 instead. */
13384 if (it.method == GET_FROM_STRING && pt > 1)
13386 init_to_row_start (&it, w, cursor_row);
13387 if (hscl)
13388 it.first_visible_x = (window_hscroll_limited (w, it.f)
13389 * FRAME_COLUMN_WIDTH (it.f));
13390 move_it_in_display_line_to (&it, pt - 1, -1, MOVE_TO_POS);
13392 current_buffer = saved_current_buffer;
13394 /* Position cursor in window. */
13395 if (!hscroll_relative_p && hscroll_step_abs == 0)
13396 hscroll = max (0, (it.current_x
13397 - (ITERATOR_AT_END_OF_LINE_P (&it)
13398 ? (text_area_width - 4 * FRAME_COLUMN_WIDTH (it.f))
13399 : (text_area_width / 2))))
13400 / FRAME_COLUMN_WIDTH (it.f);
13401 else if ((!row_r2l_p
13402 && w->cursor.x >= text_area_width - h_margin)
13403 || (row_r2l_p && w->cursor.x <= h_margin))
13405 if (hscroll_relative_p)
13406 wanted_x = text_area_width * (1 - hscroll_step_rel)
13407 - h_margin;
13408 else
13409 wanted_x = text_area_width
13410 - hscroll_step_abs * FRAME_COLUMN_WIDTH (it.f)
13411 - h_margin;
13412 hscroll
13413 = max (0, it.current_x - wanted_x) / FRAME_COLUMN_WIDTH (it.f);
13415 else
13417 if (hscroll_relative_p)
13418 wanted_x = text_area_width * hscroll_step_rel
13419 + h_margin;
13420 else
13421 wanted_x = hscroll_step_abs * FRAME_COLUMN_WIDTH (it.f)
13422 + h_margin;
13423 hscroll
13424 = max (0, it.current_x - wanted_x) / FRAME_COLUMN_WIDTH (it.f);
13426 hscroll = max (hscroll, w->min_hscroll);
13428 /* Don't prevent redisplay optimizations if hscroll
13429 hasn't changed, as it will unnecessarily slow down
13430 redisplay. */
13431 if (w->hscroll != hscroll
13432 /* When hscrolling only the current line, we need to
13433 report hscroll even if its value is equal to the
13434 previous one, because the new line might need a
13435 different value. */
13436 || (hscl && w->last_cursor_vpos != w->cursor.vpos))
13438 struct buffer *b = XBUFFER (w->contents);
13439 b->prevent_redisplay_optimizations_p = true;
13440 w->hscroll = hscroll;
13441 hscrolled_p = true;
13446 window = w->next;
13449 /* Value is true if hscroll of any leaf window has been changed. */
13450 return hscrolled_p;
13454 /* Set hscroll so that cursor is visible and not inside horizontal
13455 scroll margins for all windows in the tree rooted at WINDOW. See
13456 also hscroll_window_tree above. Value is true if any window's
13457 hscroll has been changed. If it has, desired matrices on the frame
13458 of WINDOW are cleared. */
13460 static bool
13461 hscroll_windows (Lisp_Object window)
13463 bool hscrolled_p = hscroll_window_tree (window);
13464 if (hscrolled_p)
13465 clear_desired_matrices (XFRAME (WINDOW_FRAME (XWINDOW (window))));
13466 return hscrolled_p;
13471 /************************************************************************
13472 Redisplay
13473 ************************************************************************/
13475 /* Variables holding some state of redisplay if GLYPH_DEBUG is defined.
13476 This is sometimes handy to have in a debugger session. */
13478 #ifdef GLYPH_DEBUG
13480 /* First and last unchanged row for try_window_id. */
13482 static int debug_first_unchanged_at_end_vpos;
13483 static int debug_last_unchanged_at_beg_vpos;
13485 /* Delta vpos and y. */
13487 static int debug_dvpos, debug_dy;
13489 /* Delta in characters and bytes for try_window_id. */
13491 static ptrdiff_t debug_delta, debug_delta_bytes;
13493 /* Values of window_end_pos and window_end_vpos at the end of
13494 try_window_id. */
13496 static ptrdiff_t debug_end_vpos;
13498 /* Append a string to W->desired_matrix->method. FMT is a printf
13499 format string. If trace_redisplay_p is true also printf the
13500 resulting string to stderr. */
13502 static void debug_method_add (struct window *, char const *, ...)
13503 ATTRIBUTE_FORMAT_PRINTF (2, 3);
13505 static void
13506 debug_method_add (struct window *w, char const *fmt, ...)
13508 void *ptr = w;
13509 char *method = w->desired_matrix->method;
13510 int len = strlen (method);
13511 int size = sizeof w->desired_matrix->method;
13512 int remaining = size - len - 1;
13513 va_list ap;
13515 if (len && remaining)
13517 method[len] = '|';
13518 --remaining, ++len;
13521 va_start (ap, fmt);
13522 vsnprintf (method + len, remaining + 1, fmt, ap);
13523 va_end (ap);
13525 if (trace_redisplay_p)
13526 fprintf (stderr, "%p (%s): %s\n",
13527 ptr,
13528 ((BUFFERP (w->contents)
13529 && STRINGP (BVAR (XBUFFER (w->contents), name)))
13530 ? SSDATA (BVAR (XBUFFER (w->contents), name))
13531 : "no buffer"),
13532 method + len);
13535 #endif /* GLYPH_DEBUG */
13538 /* Value is true if all changes in window W, which displays
13539 current_buffer, are in the text between START and END. START is a
13540 buffer position, END is given as a distance from Z. Used in
13541 redisplay_internal for display optimization. */
13543 static bool
13544 text_outside_line_unchanged_p (struct window *w,
13545 ptrdiff_t start, ptrdiff_t end)
13547 bool unchanged_p = true;
13549 /* If text or overlays have changed, see where. */
13550 if (window_outdated (w))
13552 /* Gap in the line? */
13553 if (GPT < start || Z - GPT < end)
13554 unchanged_p = false;
13556 /* Changes start in front of the line, or end after it? */
13557 if (unchanged_p
13558 && (BEG_UNCHANGED < start - 1
13559 || END_UNCHANGED < end))
13560 unchanged_p = false;
13562 /* If selective display, can't optimize if changes start at the
13563 beginning of the line. */
13564 if (unchanged_p
13565 && INTEGERP (BVAR (current_buffer, selective_display))
13566 && XINT (BVAR (current_buffer, selective_display)) > 0
13567 && (BEG_UNCHANGED < start || GPT <= start))
13568 unchanged_p = false;
13570 /* If there are overlays at the start or end of the line, these
13571 may have overlay strings with newlines in them. A change at
13572 START, for instance, may actually concern the display of such
13573 overlay strings as well, and they are displayed on different
13574 lines. So, quickly rule out this case. (For the future, it
13575 might be desirable to implement something more telling than
13576 just BEG/END_UNCHANGED.) */
13577 if (unchanged_p)
13579 if (BEG + BEG_UNCHANGED == start
13580 && overlay_touches_p (start))
13581 unchanged_p = false;
13582 if (END_UNCHANGED == end
13583 && overlay_touches_p (Z - end))
13584 unchanged_p = false;
13587 /* Under bidi reordering, adding or deleting a character in the
13588 beginning of a paragraph, before the first strong directional
13589 character, can change the base direction of the paragraph (unless
13590 the buffer specifies a fixed paragraph direction), which will
13591 require redisplaying the whole paragraph. It might be worthwhile
13592 to find the paragraph limits and widen the range of redisplayed
13593 lines to that, but for now just give up this optimization. */
13594 if (!NILP (BVAR (XBUFFER (w->contents), bidi_display_reordering))
13595 && NILP (BVAR (XBUFFER (w->contents), bidi_paragraph_direction)))
13596 unchanged_p = false;
13599 return unchanged_p;
13603 /* Do a frame update, taking possible shortcuts into account. This is
13604 the main external entry point for redisplay.
13606 If the last redisplay displayed an echo area message and that message
13607 is no longer requested, we clear the echo area or bring back the
13608 mini-buffer if that is in use. */
13610 void
13611 redisplay (void)
13613 redisplay_internal ();
13617 static Lisp_Object
13618 overlay_arrow_string_or_property (Lisp_Object var)
13620 Lisp_Object val;
13622 if (val = Fget (var, Qoverlay_arrow_string), STRINGP (val))
13623 return val;
13625 return Voverlay_arrow_string;
13628 /* Return true if there are any overlay-arrows in current_buffer. */
13629 static bool
13630 overlay_arrow_in_current_buffer_p (void)
13632 Lisp_Object vlist;
13634 for (vlist = Voverlay_arrow_variable_list;
13635 CONSP (vlist);
13636 vlist = XCDR (vlist))
13638 Lisp_Object var = XCAR (vlist);
13639 Lisp_Object val;
13641 if (!SYMBOLP (var))
13642 continue;
13643 val = find_symbol_value (var);
13644 if (MARKERP (val)
13645 && current_buffer == XMARKER (val)->buffer)
13646 return true;
13648 return false;
13652 /* Return true if any overlay_arrows have moved or overlay-arrow-string
13653 has changed.
13654 If SET_REDISPLAY is true, additionally, set the `redisplay' bit in those
13655 buffers that are affected. */
13657 static bool
13658 overlay_arrows_changed_p (bool set_redisplay)
13660 Lisp_Object vlist;
13661 bool changed = false;
13663 for (vlist = Voverlay_arrow_variable_list;
13664 CONSP (vlist);
13665 vlist = XCDR (vlist))
13667 Lisp_Object var = XCAR (vlist);
13668 Lisp_Object val, pstr;
13670 if (!SYMBOLP (var))
13671 continue;
13672 val = find_symbol_value (var);
13673 if (!MARKERP (val))
13674 continue;
13675 if (! EQ (COERCE_MARKER (val),
13676 /* FIXME: Don't we have a problem, using such a global
13677 * "last-position" if the variable is buffer-local? */
13678 Fget (var, Qlast_arrow_position))
13679 || ! (pstr = overlay_arrow_string_or_property (var),
13680 EQ (pstr, Fget (var, Qlast_arrow_string))))
13682 struct buffer *buf = XMARKER (val)->buffer;
13684 if (set_redisplay)
13686 if (buf)
13687 bset_redisplay (buf);
13688 changed = true;
13690 else
13691 return true;
13694 return changed;
13697 /* Mark overlay arrows to be updated on next redisplay. */
13699 static void
13700 update_overlay_arrows (int up_to_date)
13702 Lisp_Object vlist;
13704 for (vlist = Voverlay_arrow_variable_list;
13705 CONSP (vlist);
13706 vlist = XCDR (vlist))
13708 Lisp_Object var = XCAR (vlist);
13710 if (!SYMBOLP (var))
13711 continue;
13713 if (up_to_date > 0)
13715 Lisp_Object val = find_symbol_value (var);
13716 if (!MARKERP (val))
13717 continue;
13718 Fput (var, Qlast_arrow_position,
13719 COERCE_MARKER (val));
13720 Fput (var, Qlast_arrow_string,
13721 overlay_arrow_string_or_property (var));
13723 else if (up_to_date < 0
13724 || !NILP (Fget (var, Qlast_arrow_position)))
13726 Fput (var, Qlast_arrow_position, Qt);
13727 Fput (var, Qlast_arrow_string, Qt);
13733 /* Return overlay arrow string to display at row.
13734 Return integer (bitmap number) for arrow bitmap in left fringe.
13735 Return nil if no overlay arrow. */
13737 static Lisp_Object
13738 overlay_arrow_at_row (struct it *it, struct glyph_row *row)
13740 Lisp_Object vlist;
13742 for (vlist = Voverlay_arrow_variable_list;
13743 CONSP (vlist);
13744 vlist = XCDR (vlist))
13746 Lisp_Object var = XCAR (vlist);
13747 Lisp_Object val;
13749 if (!SYMBOLP (var))
13750 continue;
13752 val = find_symbol_value (var);
13754 if (MARKERP (val)
13755 && current_buffer == XMARKER (val)->buffer
13756 && (MATRIX_ROW_START_CHARPOS (row) == marker_position (val)))
13758 if (FRAME_WINDOW_P (it->f)
13759 /* FIXME: if ROW->reversed_p is set, this should test
13760 the right fringe, not the left one. */
13761 && WINDOW_LEFT_FRINGE_WIDTH (it->w) > 0)
13763 #ifdef HAVE_WINDOW_SYSTEM
13764 if (val = Fget (var, Qoverlay_arrow_bitmap), SYMBOLP (val))
13766 int fringe_bitmap = lookup_fringe_bitmap (val);
13767 if (fringe_bitmap != 0)
13768 return make_number (fringe_bitmap);
13770 #endif
13771 return make_number (-1); /* Use default arrow bitmap. */
13773 return overlay_arrow_string_or_property (var);
13777 return Qnil;
13780 /* Return true if point moved out of or into a composition. Otherwise
13781 return false. PREV_BUF and PREV_PT are the last point buffer and
13782 position. BUF and PT are the current point buffer and position. */
13784 static bool
13785 check_point_in_composition (struct buffer *prev_buf, ptrdiff_t prev_pt,
13786 struct buffer *buf, ptrdiff_t pt)
13788 ptrdiff_t start, end;
13789 Lisp_Object prop;
13790 Lisp_Object buffer;
13792 XSETBUFFER (buffer, buf);
13793 /* Check a composition at the last point if point moved within the
13794 same buffer. */
13795 if (prev_buf == buf)
13797 if (prev_pt == pt)
13798 /* Point didn't move. */
13799 return false;
13801 if (prev_pt > BUF_BEGV (buf) && prev_pt < BUF_ZV (buf)
13802 && find_composition (prev_pt, -1, &start, &end, &prop, buffer)
13803 && composition_valid_p (start, end, prop)
13804 && start < prev_pt && end > prev_pt)
13805 /* The last point was within the composition. Return true iff
13806 point moved out of the composition. */
13807 return (pt <= start || pt >= end);
13810 /* Check a composition at the current point. */
13811 return (pt > BUF_BEGV (buf) && pt < BUF_ZV (buf)
13812 && find_composition (pt, -1, &start, &end, &prop, buffer)
13813 && composition_valid_p (start, end, prop)
13814 && start < pt && end > pt);
13817 /* Reconsider the clip changes of buffer which is displayed in W. */
13819 static void
13820 reconsider_clip_changes (struct window *w)
13822 struct buffer *b = XBUFFER (w->contents);
13824 if (b->clip_changed
13825 && w->window_end_valid
13826 && w->current_matrix->buffer == b
13827 && w->current_matrix->zv == BUF_ZV (b)
13828 && w->current_matrix->begv == BUF_BEGV (b))
13829 b->clip_changed = false;
13831 /* If display wasn't paused, and W is not a tool bar window, see if
13832 point has been moved into or out of a composition. In that case,
13833 set b->clip_changed to force updating the screen. If
13834 b->clip_changed has already been set, skip this check. */
13835 if (!b->clip_changed && w->window_end_valid)
13837 ptrdiff_t pt = (w == XWINDOW (selected_window)
13838 ? PT : marker_position (w->pointm));
13840 if ((w->current_matrix->buffer != b || pt != w->last_point)
13841 && check_point_in_composition (w->current_matrix->buffer,
13842 w->last_point, b, pt))
13843 b->clip_changed = true;
13847 static void
13848 propagate_buffer_redisplay (void)
13849 { /* Resetting b->text->redisplay is problematic!
13850 We can't just reset it in the case that some window that displays
13851 it has not been redisplayed; and such a window can stay
13852 unredisplayed for a long time if it's currently invisible.
13853 But we do want to reset it at the end of redisplay otherwise
13854 its displayed windows will keep being redisplayed over and over
13855 again.
13856 So we copy all b->text->redisplay flags up to their windows here,
13857 such that mark_window_display_accurate can safely reset
13858 b->text->redisplay. */
13859 Lisp_Object ws = window_list ();
13860 for (; CONSP (ws); ws = XCDR (ws))
13862 struct window *thisw = XWINDOW (XCAR (ws));
13863 struct buffer *thisb = XBUFFER (thisw->contents);
13864 if (thisb->text->redisplay)
13865 thisw->redisplay = true;
13869 #define STOP_POLLING \
13870 do { if (! polling_stopped_here) stop_polling (); \
13871 polling_stopped_here = true; } while (false)
13873 #define RESUME_POLLING \
13874 do { if (polling_stopped_here) start_polling (); \
13875 polling_stopped_here = false; } while (false)
13878 /* Perhaps in the future avoid recentering windows if it
13879 is not necessary; currently that causes some problems. */
13881 static void
13882 redisplay_internal (void)
13884 struct window *w = XWINDOW (selected_window);
13885 struct window *sw;
13886 struct frame *fr;
13887 bool pending;
13888 bool must_finish = false, match_p;
13889 struct text_pos tlbufpos, tlendpos;
13890 int number_of_visible_frames;
13891 ptrdiff_t count;
13892 struct frame *sf;
13893 bool polling_stopped_here = false;
13894 Lisp_Object tail, frame;
13896 /* Set a limit to the number of retries we perform due to horizontal
13897 scrolling, this avoids getting stuck in an uninterruptible
13898 infinite loop (Bug #24633). */
13899 enum { MAX_HSCROLL_RETRIES = 16 };
13900 int hscroll_retries = 0;
13902 /* Limit the number of retries for when frame(s) become garbaged as
13903 result of redisplaying them. Some packages set various redisplay
13904 hooks, such as window-scroll-functions, to run Lisp that always
13905 calls APIs which cause the frame's garbaged flag to become set,
13906 so we loop indefinitely. */
13907 enum {MAX_GARBAGED_FRAME_RETRIES = 2 };
13908 int garbaged_frame_retries = 0;
13910 /* True means redisplay has to consider all windows on all
13911 frames. False, only selected_window is considered. */
13912 bool consider_all_windows_p;
13914 /* True means redisplay has to redisplay the miniwindow. */
13915 bool update_miniwindow_p = false;
13917 TRACE ((stderr, "redisplay_internal %d\n", redisplaying_p));
13919 /* No redisplay if running in batch mode or frame is not yet fully
13920 initialized, or redisplay is explicitly turned off by setting
13921 Vinhibit_redisplay. */
13922 if (FRAME_INITIAL_P (SELECTED_FRAME ())
13923 || !NILP (Vinhibit_redisplay))
13924 return;
13926 /* Don't examine these until after testing Vinhibit_redisplay.
13927 When Emacs is shutting down, perhaps because its connection to
13928 X has dropped, we should not look at them at all. */
13929 fr = XFRAME (w->frame);
13930 sf = SELECTED_FRAME ();
13932 if (!fr->glyphs_initialized_p)
13933 return;
13935 #if defined (USE_X_TOOLKIT) || defined (USE_GTK) || defined (HAVE_NS)
13936 if (popup_activated ())
13938 #ifdef NS_IMPL_COCOA
13939 /* On macOS we may have disabled screen updates due to window
13940 resizing. We should re-enable them so the popup can be
13941 displayed. */
13942 ns_enable_screen_updates ();
13943 #endif
13944 return;
13946 #endif
13948 /* I don't think this happens but let's be paranoid. */
13949 if (redisplaying_p)
13950 return;
13952 /* Record a function that clears redisplaying_p
13953 when we leave this function. */
13954 count = SPECPDL_INDEX ();
13955 record_unwind_protect_void (unwind_redisplay);
13956 redisplaying_p = true;
13957 block_buffer_flips ();
13958 specbind (Qinhibit_free_realized_faces, Qnil);
13960 /* Record this function, so it appears on the profiler's backtraces. */
13961 record_in_backtrace (Qredisplay_internal_xC_functionx, 0, 0);
13963 FOR_EACH_FRAME (tail, frame)
13964 XFRAME (frame)->already_hscrolled_p = false;
13966 retry:
13967 /* Remember the currently selected window. */
13968 sw = w;
13970 pending = false;
13971 forget_escape_and_glyphless_faces ();
13973 inhibit_free_realized_faces = false;
13975 /* If face_change, init_iterator will free all realized faces, which
13976 includes the faces referenced from current matrices. So, we
13977 can't reuse current matrices in this case. */
13978 if (face_change)
13979 windows_or_buffers_changed = 47;
13981 if ((FRAME_TERMCAP_P (sf) || FRAME_MSDOS_P (sf))
13982 && FRAME_TTY (sf)->previous_frame != sf)
13984 /* Since frames on a single ASCII terminal share the same
13985 display area, displaying a different frame means redisplay
13986 the whole thing. */
13987 SET_FRAME_GARBAGED (sf);
13988 #ifndef DOS_NT
13989 set_tty_color_mode (FRAME_TTY (sf), sf);
13990 #endif
13991 FRAME_TTY (sf)->previous_frame = sf;
13994 /* Set the visible flags for all frames. Do this before checking for
13995 resized or garbaged frames; they want to know if their frames are
13996 visible. See the comment in frame.h for FRAME_SAMPLE_VISIBILITY. */
13997 number_of_visible_frames = 0;
13999 FOR_EACH_FRAME (tail, frame)
14001 struct frame *f = XFRAME (frame);
14003 if (FRAME_VISIBLE_P (f))
14005 ++number_of_visible_frames;
14006 /* Adjust matrices for visible frames only. */
14007 if (f->fonts_changed)
14009 adjust_frame_glyphs (f);
14010 /* Disable all redisplay optimizations for this frame.
14011 This is because adjust_frame_glyphs resets the
14012 enabled_p flag for all glyph rows of all windows, so
14013 many optimizations will fail anyway, and some might
14014 fail to test that flag and do bogus things as
14015 result. */
14016 SET_FRAME_GARBAGED (f);
14017 f->fonts_changed = false;
14019 /* If cursor type has been changed on the frame
14020 other than selected, consider all frames. */
14021 if (f != sf && f->cursor_type_changed)
14022 fset_redisplay (f);
14024 clear_desired_matrices (f);
14027 /* Notice any pending interrupt request to change frame size. */
14028 do_pending_window_change (true);
14030 /* Clear frames marked as garbaged. */
14031 clear_garbaged_frames ();
14033 /* Build menubar and tool-bar items. */
14034 if (NILP (Vmemory_full))
14035 prepare_menu_bars ();
14037 /* do_pending_window_change could change the selected_window due to
14038 frame resizing which makes the selected window too small.
14039 prepare_menu_bars may call lisp hooks and hence also change the
14040 selected_window. */
14041 if (WINDOWP (selected_window) && (w = XWINDOW (selected_window)) != sw)
14042 sw = w;
14044 reconsider_clip_changes (w);
14046 /* In most cases selected window displays current buffer. */
14047 match_p = XBUFFER (w->contents) == current_buffer;
14048 if (match_p)
14050 /* Detect case that we need to write or remove a star in the mode line. */
14051 if ((SAVE_MODIFF < MODIFF) != w->last_had_star)
14052 w->update_mode_line = true;
14054 if (mode_line_update_needed (w))
14055 w->update_mode_line = true;
14057 /* If reconsider_clip_changes above decided that the narrowing
14058 in the current buffer changed, make sure all other windows
14059 showing that buffer will be redisplayed. */
14060 if (current_buffer->clip_changed)
14061 bset_update_mode_line (current_buffer);
14064 /* Normally the message* functions will have already displayed and
14065 updated the echo area, but the frame may have been trashed, or
14066 the update may have been preempted, so display the echo area
14067 again here. Checking message_cleared_p captures the case that
14068 the echo area should be cleared. */
14069 if ((!NILP (echo_area_buffer[0]) && !display_last_displayed_message_p)
14070 || (!NILP (echo_area_buffer[1]) && display_last_displayed_message_p)
14071 || (message_cleared_p
14072 && minibuf_level == 0
14073 /* If the mini-window is currently selected, this means the
14074 echo-area doesn't show through. */
14075 && !MINI_WINDOW_P (XWINDOW (selected_window))))
14077 echo_area_display (false);
14079 /* If echo_area_display resizes the mini-window, the redisplay and
14080 window_sizes_changed flags of the selected frame are set, but
14081 it's too late for the hooks in window-size-change-functions,
14082 which have been examined already in prepare_menu_bars. So in
14083 that case we call the hooks here only for the selected frame. */
14084 if (sf->redisplay)
14086 ptrdiff_t count1 = SPECPDL_INDEX ();
14088 record_unwind_save_match_data ();
14089 run_window_size_change_functions (selected_frame);
14090 unbind_to (count1, Qnil);
14093 if (message_cleared_p)
14094 update_miniwindow_p = true;
14096 must_finish = true;
14098 /* If we don't display the current message, don't clear the
14099 message_cleared_p flag, because, if we did, we wouldn't clear
14100 the echo area in the next redisplay which doesn't preserve
14101 the echo area. */
14102 if (!display_last_displayed_message_p)
14103 message_cleared_p = false;
14105 else if (EQ (selected_window, minibuf_window)
14106 && (current_buffer->clip_changed || window_outdated (w))
14107 && resize_mini_window (w, false))
14109 if (sf->redisplay)
14111 ptrdiff_t count1 = SPECPDL_INDEX ();
14113 record_unwind_save_match_data ();
14114 run_window_size_change_functions (selected_frame);
14115 unbind_to (count1, Qnil);
14118 /* Resized active mini-window to fit the size of what it is
14119 showing if its contents might have changed. */
14120 must_finish = true;
14122 /* If window configuration was changed, frames may have been
14123 marked garbaged. Clear them or we will experience
14124 surprises wrt scrolling. */
14125 clear_garbaged_frames ();
14128 if (windows_or_buffers_changed && !update_mode_lines)
14129 /* Code that sets windows_or_buffers_changed doesn't distinguish whether
14130 only the windows's contents needs to be refreshed, or whether the
14131 mode-lines also need a refresh. */
14132 update_mode_lines = (windows_or_buffers_changed == REDISPLAY_SOME
14133 ? REDISPLAY_SOME : 32);
14135 /* If specs for an arrow have changed, do thorough redisplay
14136 to ensure we remove any arrow that should no longer exist. */
14137 /* Apparently, this is the only case where we update other windows,
14138 without updating other mode-lines. */
14139 overlay_arrows_changed_p (true);
14141 consider_all_windows_p = (update_mode_lines
14142 || windows_or_buffers_changed);
14144 #define AINC(a,i) \
14146 Lisp_Object entry = Fgethash (make_number (i), a, make_number (0)); \
14147 if (INTEGERP (entry)) \
14148 Fputhash (make_number (i), make_number (1 + XINT (entry)), a); \
14151 AINC (Vredisplay__all_windows_cause, windows_or_buffers_changed);
14152 AINC (Vredisplay__mode_lines_cause, update_mode_lines);
14154 /* Optimize the case that only the line containing the cursor in the
14155 selected window has changed. Variables starting with this_ are
14156 set in display_line and record information about the line
14157 containing the cursor. */
14158 tlbufpos = this_line_start_pos;
14159 tlendpos = this_line_end_pos;
14160 if (!consider_all_windows_p
14161 && CHARPOS (tlbufpos) > 0
14162 && !w->update_mode_line
14163 && !current_buffer->clip_changed
14164 && !current_buffer->prevent_redisplay_optimizations_p
14165 && FRAME_VISIBLE_P (XFRAME (w->frame))
14166 && !FRAME_OBSCURED_P (XFRAME (w->frame))
14167 && !XFRAME (w->frame)->cursor_type_changed
14168 && !XFRAME (w->frame)->face_change
14169 /* Make sure recorded data applies to current buffer, etc. */
14170 && this_line_buffer == current_buffer
14171 && match_p
14172 && !w->force_start
14173 && !w->optional_new_start
14174 /* Point must be on the line that we have info recorded about. */
14175 && PT >= CHARPOS (tlbufpos)
14176 && PT <= Z - CHARPOS (tlendpos)
14177 /* All text outside that line, including its final newline,
14178 must be unchanged. */
14179 && text_outside_line_unchanged_p (w, CHARPOS (tlbufpos),
14180 CHARPOS (tlendpos)))
14182 if (CHARPOS (tlbufpos) > BEGV
14183 && FETCH_BYTE (BYTEPOS (tlbufpos) - 1) != '\n'
14184 && (CHARPOS (tlbufpos) == ZV
14185 || FETCH_BYTE (BYTEPOS (tlbufpos)) == '\n'))
14186 /* Former continuation line has disappeared by becoming empty. */
14187 goto cancel;
14188 else if (window_outdated (w) || MINI_WINDOW_P (w))
14190 /* We have to handle the case of continuation around a
14191 wide-column character (see the comment in indent.c around
14192 line 1340).
14194 For instance, in the following case:
14196 -------- Insert --------
14197 K_A_N_\\ `a' K_A_N_a\ `X_' are wide-column chars.
14198 J_I_ ==> J_I_ `^^' are cursors.
14199 ^^ ^^
14200 -------- --------
14202 As we have to redraw the line above, we cannot use this
14203 optimization. */
14205 struct it it;
14206 int line_height_before = this_line_pixel_height;
14208 /* Note that start_display will handle the case that the
14209 line starting at tlbufpos is a continuation line. */
14210 start_display (&it, w, tlbufpos);
14212 /* Implementation note: It this still necessary? */
14213 if (it.current_x != this_line_start_x)
14214 goto cancel;
14216 TRACE ((stderr, "trying display optimization 1\n"));
14217 w->cursor.vpos = -1;
14218 overlay_arrow_seen = false;
14219 it.vpos = this_line_vpos;
14220 it.current_y = this_line_y;
14221 it.glyph_row = MATRIX_ROW (w->desired_matrix, this_line_vpos);
14222 display_line (&it, -1);
14224 /* If line contains point, is not continued,
14225 and ends at same distance from eob as before, we win. */
14226 if (w->cursor.vpos >= 0
14227 /* Line is not continued, otherwise this_line_start_pos
14228 would have been set to 0 in display_line. */
14229 && CHARPOS (this_line_start_pos)
14230 /* Line ends as before. */
14231 && CHARPOS (this_line_end_pos) == CHARPOS (tlendpos)
14232 /* Line has same height as before. Otherwise other lines
14233 would have to be shifted up or down. */
14234 && this_line_pixel_height == line_height_before)
14236 /* If this is not the window's last line, we must adjust
14237 the charstarts of the lines below. */
14238 if (it.current_y < it.last_visible_y)
14240 struct glyph_row *row
14241 = MATRIX_ROW (w->current_matrix, this_line_vpos + 1);
14242 ptrdiff_t delta, delta_bytes;
14244 /* We used to distinguish between two cases here,
14245 conditioned by Z - CHARPOS (tlendpos) == ZV, for
14246 when the line ends in a newline or the end of the
14247 buffer's accessible portion. But both cases did
14248 the same, so they were collapsed. */
14249 delta = (Z
14250 - CHARPOS (tlendpos)
14251 - MATRIX_ROW_START_CHARPOS (row));
14252 delta_bytes = (Z_BYTE
14253 - BYTEPOS (tlendpos)
14254 - MATRIX_ROW_START_BYTEPOS (row));
14256 increment_matrix_positions (w->current_matrix,
14257 this_line_vpos + 1,
14258 w->current_matrix->nrows,
14259 delta, delta_bytes);
14262 /* If this row displays text now but previously didn't,
14263 or vice versa, w->window_end_vpos may have to be
14264 adjusted. */
14265 if (MATRIX_ROW_DISPLAYS_TEXT_P (it.glyph_row - 1))
14267 if (w->window_end_vpos < this_line_vpos)
14268 w->window_end_vpos = this_line_vpos;
14270 else if (w->window_end_vpos == this_line_vpos
14271 && this_line_vpos > 0)
14272 w->window_end_vpos = this_line_vpos - 1;
14273 w->window_end_valid = false;
14275 /* Update hint: No need to try to scroll in update_window. */
14276 w->desired_matrix->no_scrolling_p = true;
14278 #ifdef GLYPH_DEBUG
14279 *w->desired_matrix->method = 0;
14280 debug_method_add (w, "optimization 1");
14281 #endif
14282 #ifdef HAVE_WINDOW_SYSTEM
14283 update_window_fringes (w, false);
14284 #endif
14285 goto update;
14287 else
14288 goto cancel;
14290 else if (/* Cursor position hasn't changed. */
14291 PT == w->last_point
14292 /* Make sure the cursor was last displayed
14293 in this window. Otherwise we have to reposition it. */
14295 /* PXW: Must be converted to pixels, probably. */
14296 && 0 <= w->cursor.vpos
14297 && w->cursor.vpos < WINDOW_TOTAL_LINES (w))
14299 if (!must_finish)
14301 do_pending_window_change (true);
14302 /* If selected_window changed, redisplay again. */
14303 if (WINDOWP (selected_window)
14304 && (w = XWINDOW (selected_window)) != sw)
14305 goto retry;
14307 /* We used to always goto end_of_redisplay here, but this
14308 isn't enough if we have a blinking cursor. */
14309 if (w->cursor_off_p == w->last_cursor_off_p)
14310 goto end_of_redisplay;
14312 goto update;
14314 /* If highlighting the region, or if the cursor is in the echo area,
14315 then we can't just move the cursor. */
14316 else if (NILP (Vshow_trailing_whitespace)
14317 && !cursor_in_echo_area)
14319 struct it it;
14320 struct glyph_row *row;
14322 /* Skip from tlbufpos to PT and see where it is. Note that
14323 PT may be in invisible text. If so, we will end at the
14324 next visible position. */
14325 init_iterator (&it, w, CHARPOS (tlbufpos), BYTEPOS (tlbufpos),
14326 NULL, DEFAULT_FACE_ID);
14327 it.current_x = this_line_start_x;
14328 it.current_y = this_line_y;
14329 it.vpos = this_line_vpos;
14331 /* The call to move_it_to stops in front of PT, but
14332 moves over before-strings. */
14333 move_it_to (&it, PT, -1, -1, -1, MOVE_TO_POS);
14335 if (it.vpos == this_line_vpos
14336 && (row = MATRIX_ROW (w->current_matrix, this_line_vpos),
14337 row->enabled_p))
14339 eassert (this_line_vpos == it.vpos);
14340 eassert (this_line_y == it.current_y);
14341 set_cursor_from_row (w, row, w->current_matrix, 0, 0, 0, 0);
14342 if (cursor_row_fully_visible_p (w, false, true))
14344 #ifdef GLYPH_DEBUG
14345 *w->desired_matrix->method = 0;
14346 debug_method_add (w, "optimization 3");
14347 #endif
14348 goto update;
14350 else
14351 goto cancel;
14353 else
14354 goto cancel;
14357 cancel:
14358 /* Text changed drastically or point moved off of line. */
14359 SET_MATRIX_ROW_ENABLED_P (w->desired_matrix, this_line_vpos, false);
14362 CHARPOS (this_line_start_pos) = 0;
14363 ++clear_face_cache_count;
14364 #ifdef HAVE_WINDOW_SYSTEM
14365 ++clear_image_cache_count;
14366 #endif
14368 /* Build desired matrices, and update the display. If
14369 consider_all_windows_p, do it for all windows on all frames that
14370 require redisplay, as specified by their 'redisplay' flag.
14371 Otherwise do it for selected_window, only. */
14373 if (consider_all_windows_p)
14375 FOR_EACH_FRAME (tail, frame)
14376 XFRAME (frame)->updated_p = false;
14378 propagate_buffer_redisplay ();
14380 FOR_EACH_FRAME (tail, frame)
14382 struct frame *f = XFRAME (frame);
14384 /* We don't have to do anything for unselected terminal
14385 frames. */
14386 if ((FRAME_TERMCAP_P (f) || FRAME_MSDOS_P (f))
14387 && !EQ (FRAME_TTY (f)->top_frame, frame))
14388 continue;
14390 retry_frame:
14391 if (FRAME_WINDOW_P (f) || FRAME_TERMCAP_P (f) || f == sf)
14393 bool gcscrollbars
14394 /* Only GC scrollbars when we redisplay the whole frame. */
14395 = f->redisplay || !REDISPLAY_SOME_P ();
14396 bool f_redisplay_flag = f->redisplay;
14397 /* Mark all the scroll bars to be removed; we'll redeem
14398 the ones we want when we redisplay their windows. */
14399 if (gcscrollbars && FRAME_TERMINAL (f)->condemn_scroll_bars_hook)
14400 FRAME_TERMINAL (f)->condemn_scroll_bars_hook (f);
14402 if (FRAME_VISIBLE_P (f) && !FRAME_OBSCURED_P (f))
14403 redisplay_windows (FRAME_ROOT_WINDOW (f));
14404 /* Remember that the invisible frames need to be redisplayed next
14405 time they're visible. */
14406 else if (!REDISPLAY_SOME_P ())
14407 f->redisplay = true;
14409 /* The X error handler may have deleted that frame. */
14410 if (!FRAME_LIVE_P (f))
14411 continue;
14413 /* Any scroll bars which redisplay_windows should have
14414 nuked should now go away. */
14415 if (gcscrollbars && FRAME_TERMINAL (f)->judge_scroll_bars_hook)
14416 FRAME_TERMINAL (f)->judge_scroll_bars_hook (f);
14418 if (FRAME_VISIBLE_P (f) && !FRAME_OBSCURED_P (f))
14420 /* If fonts changed on visible frame, display again. */
14421 if (f->fonts_changed)
14423 adjust_frame_glyphs (f);
14424 /* Disable all redisplay optimizations for this
14425 frame. For the reasons, see the comment near
14426 the previous call to adjust_frame_glyphs above. */
14427 SET_FRAME_GARBAGED (f);
14428 f->fonts_changed = false;
14429 goto retry_frame;
14432 /* See if we have to hscroll. */
14433 if (!f->already_hscrolled_p)
14435 f->already_hscrolled_p = true;
14436 if (hscroll_retries <= MAX_HSCROLL_RETRIES
14437 && hscroll_windows (f->root_window))
14439 hscroll_retries++;
14440 goto retry_frame;
14444 /* If the frame's redisplay flag was not set before
14445 we went about redisplaying its windows, but it is
14446 set now, that means we employed some redisplay
14447 optimizations inside redisplay_windows, and
14448 bypassed producing some screen lines. But if
14449 f->redisplay is now set, it might mean the old
14450 faces are no longer valid (e.g., if redisplaying
14451 some window called some Lisp which defined a new
14452 face or redefined an existing face), so trying to
14453 use them in update_frame will segfault.
14454 Therefore, we must redisplay this frame. */
14455 if (!f_redisplay_flag && f->redisplay)
14456 goto retry_frame;
14457 /* In some case (e.g., window resize), we notice
14458 only during window updating that the window
14459 content changed unpredictably (e.g., a GTK
14460 scrollbar moved, or some Lisp hook that winds up
14461 calling adjust_frame_glyphs) and that our
14462 previous estimation of the frame content was
14463 garbage. We have to start over. These cases
14464 should be rare, so going all the way back to the
14465 top of redisplay should be good enough. */
14466 if (FRAME_GARBAGED_P (f)
14467 && garbaged_frame_retries++ < MAX_GARBAGED_FRAME_RETRIES)
14468 goto retry;
14470 #if defined (HAVE_WINDOW_SYSTEM) && !defined (HAVE_NS)
14471 x_clear_under_internal_border (f);
14472 #endif /* HAVE_WINDOW_SYSTEM && !HAVE_NS */
14474 /* Prevent various kinds of signals during display
14475 update. stdio is not robust about handling
14476 signals, which can cause an apparent I/O error. */
14477 if (interrupt_input)
14478 unrequest_sigio ();
14479 STOP_POLLING;
14481 pending |= update_frame (f, false, false);
14482 f->cursor_type_changed = false;
14483 f->updated_p = true;
14488 eassert (EQ (XFRAME (selected_frame)->selected_window, selected_window));
14490 if (!pending)
14492 /* Do the mark_window_display_accurate after all windows have
14493 been redisplayed because this call resets flags in buffers
14494 which are needed for proper redisplay. */
14495 FOR_EACH_FRAME (tail, frame)
14497 struct frame *f = XFRAME (frame);
14498 if (f->updated_p)
14500 f->redisplay = false;
14501 f->garbaged = false;
14502 mark_window_display_accurate (f->root_window, true);
14503 if (FRAME_TERMINAL (f)->frame_up_to_date_hook)
14504 FRAME_TERMINAL (f)->frame_up_to_date_hook (f);
14509 else if (FRAME_VISIBLE_P (sf) && !FRAME_OBSCURED_P (sf))
14511 displayed_buffer = XBUFFER (XWINDOW (selected_window)->contents);
14512 /* Use list_of_error, not Qerror, so that
14513 we catch only errors and don't run the debugger. */
14514 internal_condition_case_1 (redisplay_window_1, selected_window,
14515 list_of_error,
14516 redisplay_window_error);
14517 if (update_miniwindow_p)
14518 internal_condition_case_1 (redisplay_window_1,
14519 FRAME_MINIBUF_WINDOW (sf), list_of_error,
14520 redisplay_window_error);
14522 /* Compare desired and current matrices, perform output. */
14524 update:
14525 /* If fonts changed, display again. Likewise if redisplay_window_1
14526 above caused some change (e.g., a change in faces) that requires
14527 considering the entire frame again. */
14528 if (sf->fonts_changed || sf->redisplay)
14530 if (sf->redisplay)
14532 /* Set this to force a more thorough redisplay.
14533 Otherwise, we might immediately loop back to the
14534 above "else-if" clause (since all the conditions that
14535 led here might still be true), and we will then
14536 infloop, because the selected-frame's redisplay flag
14537 is not (and cannot be) reset. */
14538 windows_or_buffers_changed = 50;
14540 goto retry;
14543 /* Prevent freeing of realized faces, since desired matrices are
14544 pending that reference the faces we computed and cached. */
14545 inhibit_free_realized_faces = true;
14547 /* Prevent various kinds of signals during display update.
14548 stdio is not robust about handling signals,
14549 which can cause an apparent I/O error. */
14550 if (interrupt_input)
14551 unrequest_sigio ();
14552 STOP_POLLING;
14554 if (FRAME_VISIBLE_P (sf) && !FRAME_OBSCURED_P (sf))
14556 if (hscroll_retries <= MAX_HSCROLL_RETRIES
14557 && hscroll_windows (selected_window))
14559 hscroll_retries++;
14560 goto retry;
14563 XWINDOW (selected_window)->must_be_updated_p = true;
14564 pending = update_frame (sf, false, false);
14565 sf->cursor_type_changed = false;
14568 /* We may have called echo_area_display at the top of this
14569 function. If the echo area is on another frame, that may
14570 have put text on a frame other than the selected one, so the
14571 above call to update_frame would not have caught it. Catch
14572 it here. */
14573 Lisp_Object mini_window = FRAME_MINIBUF_WINDOW (sf);
14574 struct frame *mini_frame = XFRAME (WINDOW_FRAME (XWINDOW (mini_window)));
14576 if (mini_frame != sf && FRAME_WINDOW_P (mini_frame))
14578 XWINDOW (mini_window)->must_be_updated_p = true;
14579 pending |= update_frame (mini_frame, false, false);
14580 mini_frame->cursor_type_changed = false;
14581 if (!pending && hscroll_retries <= MAX_HSCROLL_RETRIES
14582 && hscroll_windows (mini_window))
14584 hscroll_retries++;
14585 goto retry;
14590 /* If display was paused because of pending input, make sure we do a
14591 thorough update the next time. */
14592 if (pending)
14594 /* Prevent the optimization at the beginning of
14595 redisplay_internal that tries a single-line update of the
14596 line containing the cursor in the selected window. */
14597 CHARPOS (this_line_start_pos) = 0;
14599 /* Let the overlay arrow be updated the next time. */
14600 update_overlay_arrows (0);
14602 /* If we pause after scrolling, some rows in the current
14603 matrices of some windows are not valid. */
14604 if (!WINDOW_FULL_WIDTH_P (w)
14605 && !FRAME_WINDOW_P (XFRAME (w->frame)))
14606 update_mode_lines = 36;
14608 else
14610 if (!consider_all_windows_p)
14612 /* This has already been done above if
14613 consider_all_windows_p is set. */
14614 if (XBUFFER (w->contents)->text->redisplay
14615 && buffer_window_count (XBUFFER (w->contents)) > 1)
14616 /* This can happen if b->text->redisplay was set during
14617 jit-lock. */
14618 propagate_buffer_redisplay ();
14619 mark_window_display_accurate_1 (w, true);
14621 /* Say overlay arrows are up to date. */
14622 update_overlay_arrows (1);
14624 if (FRAME_TERMINAL (sf)->frame_up_to_date_hook != 0)
14625 FRAME_TERMINAL (sf)->frame_up_to_date_hook (sf);
14628 update_mode_lines = 0;
14629 windows_or_buffers_changed = 0;
14632 /* Start SIGIO interrupts coming again. Having them off during the
14633 code above makes it less likely one will discard output, but not
14634 impossible, since there might be stuff in the system buffer here.
14635 But it is much hairier to try to do anything about that. */
14636 if (interrupt_input)
14637 request_sigio ();
14638 RESUME_POLLING;
14640 /* If a frame has become visible which was not before, redisplay
14641 again, so that we display it. Expose events for such a frame
14642 (which it gets when becoming visible) don't call the parts of
14643 redisplay constructing glyphs, so simply exposing a frame won't
14644 display anything in this case. So, we have to display these
14645 frames here explicitly. */
14646 if (!pending)
14648 int new_count = 0;
14650 FOR_EACH_FRAME (tail, frame)
14652 if (XFRAME (frame)->visible)
14653 new_count++;
14656 if (new_count != number_of_visible_frames)
14657 windows_or_buffers_changed = 52;
14660 /* Change frame size now if a change is pending. */
14661 do_pending_window_change (true);
14663 /* If we just did a pending size change, or have additional
14664 visible frames, or selected_window changed, redisplay again. */
14665 if ((windows_or_buffers_changed && !pending)
14666 || (WINDOWP (selected_window) && (w = XWINDOW (selected_window)) != sw))
14667 goto retry;
14669 /* Clear the face and image caches.
14671 We used to do this only if consider_all_windows_p. But the cache
14672 needs to be cleared if a timer creates images in the current
14673 buffer (e.g. the test case in Bug#6230). */
14675 if (clear_face_cache_count > CLEAR_FACE_CACHE_COUNT)
14677 clear_face_cache (false);
14678 clear_face_cache_count = 0;
14681 #ifdef HAVE_WINDOW_SYSTEM
14682 if (clear_image_cache_count > CLEAR_IMAGE_CACHE_COUNT)
14684 clear_image_caches (Qnil);
14685 clear_image_cache_count = 0;
14687 #endif /* HAVE_WINDOW_SYSTEM */
14689 end_of_redisplay:
14690 #ifdef HAVE_NS
14691 ns_set_doc_edited ();
14692 #endif
14693 if (interrupt_input && interrupts_deferred)
14694 request_sigio ();
14696 unbind_to (count, Qnil);
14697 RESUME_POLLING;
14700 static void
14701 unwind_redisplay_preserve_echo_area (void)
14703 unblock_buffer_flips ();
14706 /* Redisplay, but leave alone any recent echo area message unless
14707 another message has been requested in its place.
14709 This is useful in situations where you need to redisplay but no
14710 user action has occurred, making it inappropriate for the message
14711 area to be cleared. See tracking_off and
14712 wait_reading_process_output for examples of these situations.
14714 FROM_WHERE is an integer saying from where this function was
14715 called. This is useful for debugging. */
14717 void
14718 redisplay_preserve_echo_area (int from_where)
14720 TRACE ((stderr, "redisplay_preserve_echo_area (%d)\n", from_where));
14722 block_input ();
14723 ptrdiff_t count = SPECPDL_INDEX ();
14724 record_unwind_protect_void (unwind_redisplay_preserve_echo_area);
14725 block_buffer_flips ();
14726 unblock_input ();
14728 if (!NILP (echo_area_buffer[1]))
14730 /* We have a previously displayed message, but no current
14731 message. Redisplay the previous message. */
14732 display_last_displayed_message_p = true;
14733 redisplay_internal ();
14734 display_last_displayed_message_p = false;
14736 else
14737 redisplay_internal ();
14739 flush_frame (SELECTED_FRAME ());
14740 unbind_to (count, Qnil);
14744 /* Function registered with record_unwind_protect in redisplay_internal. */
14746 static void
14747 unwind_redisplay (void)
14749 redisplaying_p = false;
14750 unblock_buffer_flips ();
14751 #ifdef NS_IMPL_COCOA
14752 /* On macOS we may have disabled screen updates due to window
14753 resizing. When redisplay completes we want to re-enable
14754 them. */
14755 ns_enable_screen_updates ();
14756 #endif
14760 /* Mark the display of leaf window W as accurate or inaccurate.
14761 If ACCURATE_P, mark display of W as accurate.
14762 If !ACCURATE_P, arrange for W to be redisplayed the next
14763 time redisplay_internal is called. */
14765 static void
14766 mark_window_display_accurate_1 (struct window *w, bool accurate_p)
14768 struct buffer *b = XBUFFER (w->contents);
14770 w->last_modified = accurate_p ? BUF_MODIFF (b) : 0;
14771 w->last_overlay_modified = accurate_p ? BUF_OVERLAY_MODIFF (b) : 0;
14772 w->last_had_star = BUF_MODIFF (b) > BUF_SAVE_MODIFF (b);
14774 if (accurate_p)
14776 b->clip_changed = false;
14777 b->prevent_redisplay_optimizations_p = false;
14778 eassert (buffer_window_count (b) > 0);
14779 /* Resetting b->text->redisplay is problematic!
14780 In order to make it safer to do it here, redisplay_internal must
14781 have copied all b->text->redisplay to their respective windows. */
14782 b->text->redisplay = false;
14784 BUF_UNCHANGED_MODIFIED (b) = BUF_MODIFF (b);
14785 BUF_OVERLAY_UNCHANGED_MODIFIED (b) = BUF_OVERLAY_MODIFF (b);
14786 BUF_BEG_UNCHANGED (b) = BUF_GPT (b) - BUF_BEG (b);
14787 BUF_END_UNCHANGED (b) = BUF_Z (b) - BUF_GPT (b);
14789 w->current_matrix->buffer = b;
14790 w->current_matrix->begv = BUF_BEGV (b);
14791 w->current_matrix->zv = BUF_ZV (b);
14793 w->last_cursor_vpos = w->cursor.vpos;
14794 w->last_cursor_off_p = w->cursor_off_p;
14796 if (w == XWINDOW (selected_window))
14797 w->last_point = BUF_PT (b);
14798 else
14799 w->last_point = marker_position (w->pointm);
14801 w->window_end_valid = true;
14802 w->update_mode_line = false;
14805 w->redisplay = !accurate_p;
14809 /* Mark the display of windows in the window tree rooted at WINDOW as
14810 accurate or inaccurate. If ACCURATE_P, mark display of
14811 windows as accurate. If !ACCURATE_P, arrange for windows to
14812 be redisplayed the next time redisplay_internal is called. */
14814 void
14815 mark_window_display_accurate (Lisp_Object window, bool accurate_p)
14817 struct window *w;
14819 for (; !NILP (window); window = w->next)
14821 w = XWINDOW (window);
14822 if (WINDOWP (w->contents))
14823 mark_window_display_accurate (w->contents, accurate_p);
14824 else
14825 mark_window_display_accurate_1 (w, accurate_p);
14828 if (accurate_p)
14829 update_overlay_arrows (1);
14830 else
14831 /* Force a thorough redisplay the next time by setting
14832 last_arrow_position and last_arrow_string to t, which is
14833 unequal to any useful value of Voverlay_arrow_... */
14834 update_overlay_arrows (-1);
14838 /* Return value in display table DP (Lisp_Char_Table *) for character
14839 C. Since a display table doesn't have any parent, we don't have to
14840 follow parent. Do not call this function directly but use the
14841 macro DISP_CHAR_VECTOR. */
14843 Lisp_Object
14844 disp_char_vector (struct Lisp_Char_Table *dp, int c)
14846 Lisp_Object val;
14848 if (ASCII_CHAR_P (c))
14850 val = dp->ascii;
14851 if (SUB_CHAR_TABLE_P (val))
14852 val = XSUB_CHAR_TABLE (val)->contents[c];
14854 else
14856 Lisp_Object table;
14858 XSETCHAR_TABLE (table, dp);
14859 val = char_table_ref (table, c);
14861 if (NILP (val))
14862 val = dp->defalt;
14863 return val;
14866 static int buffer_flip_blocked_depth;
14868 static void
14869 block_buffer_flips (void)
14871 eassert (buffer_flip_blocked_depth >= 0);
14872 buffer_flip_blocked_depth++;
14875 static void
14876 unblock_buffer_flips (void)
14878 eassert (buffer_flip_blocked_depth > 0);
14879 if (--buffer_flip_blocked_depth == 0)
14881 Lisp_Object tail, frame;
14882 block_input ();
14883 FOR_EACH_FRAME (tail, frame)
14885 struct frame *f = XFRAME (frame);
14886 if (FRAME_TERMINAL (f)->buffer_flipping_unblocked_hook)
14887 (*FRAME_TERMINAL (f)->buffer_flipping_unblocked_hook) (f);
14889 unblock_input ();
14893 bool
14894 buffer_flipping_blocked_p (void)
14896 return buffer_flip_blocked_depth > 0;
14900 /***********************************************************************
14901 Window Redisplay
14902 ***********************************************************************/
14904 /* Redisplay all leaf windows in the window tree rooted at WINDOW. */
14906 static void
14907 redisplay_windows (Lisp_Object window)
14909 while (!NILP (window))
14911 struct window *w = XWINDOW (window);
14913 if (WINDOWP (w->contents))
14914 redisplay_windows (w->contents);
14915 else if (BUFFERP (w->contents))
14917 displayed_buffer = XBUFFER (w->contents);
14918 /* Use list_of_error, not Qerror, so that
14919 we catch only errors and don't run the debugger. */
14920 internal_condition_case_1 (redisplay_window_0, window,
14921 list_of_error,
14922 redisplay_window_error);
14925 window = w->next;
14929 static Lisp_Object
14930 redisplay_window_error (Lisp_Object ignore)
14932 displayed_buffer->display_error_modiff = BUF_MODIFF (displayed_buffer);
14933 return Qnil;
14936 static Lisp_Object
14937 redisplay_window_0 (Lisp_Object window)
14939 if (displayed_buffer->display_error_modiff < BUF_MODIFF (displayed_buffer))
14940 redisplay_window (window, false);
14941 return Qnil;
14944 static Lisp_Object
14945 redisplay_window_1 (Lisp_Object window)
14947 if (displayed_buffer->display_error_modiff < BUF_MODIFF (displayed_buffer))
14948 redisplay_window (window, true);
14949 return Qnil;
14953 /* Set cursor position of W. PT is assumed to be displayed in ROW.
14954 DELTA and DELTA_BYTES are the numbers of characters and bytes by
14955 which positions recorded in ROW differ from current buffer
14956 positions.
14958 Return true iff cursor is on this row. */
14960 static bool
14961 set_cursor_from_row (struct window *w, struct glyph_row *row,
14962 struct glyph_matrix *matrix,
14963 ptrdiff_t delta, ptrdiff_t delta_bytes,
14964 int dy, int dvpos)
14966 struct glyph *glyph = row->glyphs[TEXT_AREA];
14967 struct glyph *end = glyph + row->used[TEXT_AREA];
14968 struct glyph *cursor = NULL;
14969 /* The last known character position in row. */
14970 ptrdiff_t last_pos = MATRIX_ROW_START_CHARPOS (row) + delta;
14971 int x = row->x;
14972 ptrdiff_t pt_old = PT - delta;
14973 ptrdiff_t pos_before = MATRIX_ROW_START_CHARPOS (row) + delta;
14974 ptrdiff_t pos_after = MATRIX_ROW_END_CHARPOS (row) + delta;
14975 struct glyph *glyph_before = glyph - 1, *glyph_after = end;
14976 /* A glyph beyond the edge of TEXT_AREA which we should never
14977 touch. */
14978 struct glyph *glyphs_end = end;
14979 /* True means we've found a match for cursor position, but that
14980 glyph has the avoid_cursor_p flag set. */
14981 bool match_with_avoid_cursor = false;
14982 /* True means we've seen at least one glyph that came from a
14983 display string. */
14984 bool string_seen = false;
14985 /* Largest and smallest buffer positions seen so far during scan of
14986 glyph row. */
14987 ptrdiff_t bpos_max = pos_before;
14988 ptrdiff_t bpos_min = pos_after;
14989 /* Last buffer position covered by an overlay string with an integer
14990 `cursor' property. */
14991 ptrdiff_t bpos_covered = 0;
14992 /* True means the display string on which to display the cursor
14993 comes from a text property, not from an overlay. */
14994 bool string_from_text_prop = false;
14996 /* Don't even try doing anything if called for a mode-line or
14997 header-line row, since the rest of the code isn't prepared to
14998 deal with such calamities. */
14999 eassert (!row->mode_line_p);
15000 if (row->mode_line_p)
15001 return false;
15003 /* Skip over glyphs not having an object at the start and the end of
15004 the row. These are special glyphs like truncation marks on
15005 terminal frames. */
15006 if (MATRIX_ROW_DISPLAYS_TEXT_P (row))
15008 if (!row->reversed_p)
15010 while (glyph < end
15011 && NILP (glyph->object)
15012 && glyph->charpos < 0)
15014 x += glyph->pixel_width;
15015 ++glyph;
15017 while (end > glyph
15018 && NILP ((end - 1)->object)
15019 /* CHARPOS is zero for blanks and stretch glyphs
15020 inserted by extend_face_to_end_of_line. */
15021 && (end - 1)->charpos <= 0)
15022 --end;
15023 glyph_before = glyph - 1;
15024 glyph_after = end;
15026 else
15028 struct glyph *g;
15030 /* If the glyph row is reversed, we need to process it from back
15031 to front, so swap the edge pointers. */
15032 glyphs_end = end = glyph - 1;
15033 glyph += row->used[TEXT_AREA] - 1;
15035 while (glyph > end + 1
15036 && NILP (glyph->object)
15037 && glyph->charpos < 0)
15038 --glyph;
15039 if (NILP (glyph->object) && glyph->charpos < 0)
15040 --glyph;
15041 /* By default, in reversed rows we put the cursor on the
15042 rightmost (first in the reading order) glyph. */
15043 for (x = 0, g = end + 1; g < glyph; g++)
15044 x += g->pixel_width;
15045 while (end < glyph
15046 && NILP ((end + 1)->object)
15047 && (end + 1)->charpos <= 0)
15048 ++end;
15049 glyph_before = glyph + 1;
15050 glyph_after = end;
15053 else if (row->reversed_p)
15055 /* In R2L rows that don't display text, put the cursor on the
15056 rightmost glyph. Case in point: an empty last line that is
15057 part of an R2L paragraph. */
15058 cursor = end - 1;
15059 /* Avoid placing the cursor on the last glyph of the row, where
15060 on terminal frames we hold the vertical border between
15061 adjacent windows. */
15062 if (!FRAME_WINDOW_P (WINDOW_XFRAME (w))
15063 && !WINDOW_RIGHTMOST_P (w)
15064 && cursor == row->glyphs[LAST_AREA] - 1)
15065 cursor--;
15066 x = -1; /* will be computed below, at label compute_x */
15069 /* Step 1: Try to find the glyph whose character position
15070 corresponds to point. If that's not possible, find 2 glyphs
15071 whose character positions are the closest to point, one before
15072 point, the other after it. */
15073 if (!row->reversed_p)
15074 while (/* not marched to end of glyph row */
15075 glyph < end
15076 /* glyph was not inserted by redisplay for internal purposes */
15077 && !NILP (glyph->object))
15079 if (BUFFERP (glyph->object))
15081 ptrdiff_t dpos = glyph->charpos - pt_old;
15083 if (glyph->charpos > bpos_max)
15084 bpos_max = glyph->charpos;
15085 if (glyph->charpos < bpos_min)
15086 bpos_min = glyph->charpos;
15087 if (!glyph->avoid_cursor_p)
15089 /* If we hit point, we've found the glyph on which to
15090 display the cursor. */
15091 if (dpos == 0)
15093 match_with_avoid_cursor = false;
15094 break;
15096 /* See if we've found a better approximation to
15097 POS_BEFORE or to POS_AFTER. */
15098 if (0 > dpos && dpos > pos_before - pt_old)
15100 pos_before = glyph->charpos;
15101 glyph_before = glyph;
15103 else if (0 < dpos && dpos < pos_after - pt_old)
15105 pos_after = glyph->charpos;
15106 glyph_after = glyph;
15109 else if (dpos == 0)
15110 match_with_avoid_cursor = true;
15112 else if (STRINGP (glyph->object))
15114 Lisp_Object chprop;
15115 ptrdiff_t glyph_pos = glyph->charpos;
15117 chprop = Fget_char_property (make_number (glyph_pos), Qcursor,
15118 glyph->object);
15119 if (!NILP (chprop))
15121 /* If the string came from a `display' text property,
15122 look up the buffer position of that property and
15123 use that position to update bpos_max, as if we
15124 actually saw such a position in one of the row's
15125 glyphs. This helps with supporting integer values
15126 of `cursor' property on the display string in
15127 situations where most or all of the row's buffer
15128 text is completely covered by display properties,
15129 so that no glyph with valid buffer positions is
15130 ever seen in the row. */
15131 ptrdiff_t prop_pos =
15132 string_buffer_position_lim (glyph->object, pos_before,
15133 pos_after, false);
15135 if (prop_pos >= pos_before)
15136 bpos_max = prop_pos;
15138 if (INTEGERP (chprop))
15140 bpos_covered = bpos_max + XINT (chprop);
15141 /* If the `cursor' property covers buffer positions up
15142 to and including point, we should display cursor on
15143 this glyph. Note that, if a `cursor' property on one
15144 of the string's characters has an integer value, we
15145 will break out of the loop below _before_ we get to
15146 the position match above. IOW, integer values of
15147 the `cursor' property override the "exact match for
15148 point" strategy of positioning the cursor. */
15149 /* Implementation note: bpos_max == pt_old when, e.g.,
15150 we are in an empty line, where bpos_max is set to
15151 MATRIX_ROW_START_CHARPOS, see above. */
15152 if (bpos_max <= pt_old && bpos_covered >= pt_old)
15154 cursor = glyph;
15155 break;
15159 string_seen = true;
15161 x += glyph->pixel_width;
15162 ++glyph;
15164 else if (glyph > end) /* row is reversed */
15165 while (!NILP (glyph->object))
15167 if (BUFFERP (glyph->object))
15169 ptrdiff_t dpos = glyph->charpos - pt_old;
15171 if (glyph->charpos > bpos_max)
15172 bpos_max = glyph->charpos;
15173 if (glyph->charpos < bpos_min)
15174 bpos_min = glyph->charpos;
15175 if (!glyph->avoid_cursor_p)
15177 if (dpos == 0)
15179 match_with_avoid_cursor = false;
15180 break;
15182 if (0 > dpos && dpos > pos_before - pt_old)
15184 pos_before = glyph->charpos;
15185 glyph_before = glyph;
15187 else if (0 < dpos && dpos < pos_after - pt_old)
15189 pos_after = glyph->charpos;
15190 glyph_after = glyph;
15193 else if (dpos == 0)
15194 match_with_avoid_cursor = true;
15196 else if (STRINGP (glyph->object))
15198 Lisp_Object chprop;
15199 ptrdiff_t glyph_pos = glyph->charpos;
15201 chprop = Fget_char_property (make_number (glyph_pos), Qcursor,
15202 glyph->object);
15203 if (!NILP (chprop))
15205 ptrdiff_t prop_pos =
15206 string_buffer_position_lim (glyph->object, pos_before,
15207 pos_after, false);
15209 if (prop_pos >= pos_before)
15210 bpos_max = prop_pos;
15212 if (INTEGERP (chprop))
15214 bpos_covered = bpos_max + XINT (chprop);
15215 /* If the `cursor' property covers buffer positions up
15216 to and including point, we should display cursor on
15217 this glyph. */
15218 if (bpos_max <= pt_old && bpos_covered >= pt_old)
15220 cursor = glyph;
15221 break;
15224 string_seen = true;
15226 --glyph;
15227 if (glyph == glyphs_end) /* don't dereference outside TEXT_AREA */
15229 x--; /* can't use any pixel_width */
15230 break;
15232 x -= glyph->pixel_width;
15235 /* Step 2: If we didn't find an exact match for point, we need to
15236 look for a proper place to put the cursor among glyphs between
15237 GLYPH_BEFORE and GLYPH_AFTER. */
15238 if (!((row->reversed_p ? glyph > glyphs_end : glyph < glyphs_end)
15239 && BUFFERP (glyph->object) && glyph->charpos == pt_old)
15240 && !(bpos_max <= pt_old && pt_old <= bpos_covered))
15242 /* An empty line has a single glyph whose OBJECT is nil and
15243 whose CHARPOS is the position of a newline on that line.
15244 Note that on a TTY, there are more glyphs after that, which
15245 were produced by extend_face_to_end_of_line, but their
15246 CHARPOS is zero or negative. */
15247 bool empty_line_p =
15248 ((row->reversed_p ? glyph > glyphs_end : glyph < glyphs_end)
15249 && NILP (glyph->object) && glyph->charpos > 0
15250 /* On a TTY, continued and truncated rows also have a glyph at
15251 their end whose OBJECT is nil and whose CHARPOS is
15252 positive (the continuation and truncation glyphs), but such
15253 rows are obviously not "empty". */
15254 && !(row->continued_p || row->truncated_on_right_p));
15256 if (row->ends_in_ellipsis_p && pos_after == last_pos)
15258 ptrdiff_t ellipsis_pos;
15260 /* Scan back over the ellipsis glyphs. */
15261 if (!row->reversed_p)
15263 ellipsis_pos = (glyph - 1)->charpos;
15264 while (glyph > row->glyphs[TEXT_AREA]
15265 && (glyph - 1)->charpos == ellipsis_pos)
15266 glyph--, x -= glyph->pixel_width;
15267 /* That loop always goes one position too far, including
15268 the glyph before the ellipsis. So scan forward over
15269 that one. */
15270 x += glyph->pixel_width;
15271 glyph++;
15273 else /* row is reversed */
15275 ellipsis_pos = (glyph + 1)->charpos;
15276 while (glyph < row->glyphs[TEXT_AREA] + row->used[TEXT_AREA] - 1
15277 && (glyph + 1)->charpos == ellipsis_pos)
15278 glyph++, x += glyph->pixel_width;
15279 x -= glyph->pixel_width;
15280 glyph--;
15283 else if (match_with_avoid_cursor)
15285 cursor = glyph_after;
15286 x = -1;
15288 else if (string_seen)
15290 int incr = row->reversed_p ? -1 : +1;
15292 /* Need to find the glyph that came out of a string which is
15293 present at point. That glyph is somewhere between
15294 GLYPH_BEFORE and GLYPH_AFTER, and it came from a string
15295 positioned between POS_BEFORE and POS_AFTER in the
15296 buffer. */
15297 struct glyph *start, *stop;
15298 ptrdiff_t pos = pos_before;
15300 x = -1;
15302 /* If the row ends in a newline from a display string,
15303 reordering could have moved the glyphs belonging to the
15304 string out of the [GLYPH_BEFORE..GLYPH_AFTER] range. So
15305 in this case we extend the search to the last glyph in
15306 the row that was not inserted by redisplay. */
15307 if (row->ends_in_newline_from_string_p)
15309 glyph_after = end;
15310 pos_after = MATRIX_ROW_END_CHARPOS (row) + delta;
15313 /* GLYPH_BEFORE and GLYPH_AFTER are the glyphs that
15314 correspond to POS_BEFORE and POS_AFTER, respectively. We
15315 need START and STOP in the order that corresponds to the
15316 row's direction as given by its reversed_p flag. If the
15317 directionality of characters between POS_BEFORE and
15318 POS_AFTER is the opposite of the row's base direction,
15319 these characters will have been reordered for display,
15320 and we need to reverse START and STOP. */
15321 if (!row->reversed_p)
15323 start = min (glyph_before, glyph_after);
15324 stop = max (glyph_before, glyph_after);
15326 else
15328 start = max (glyph_before, glyph_after);
15329 stop = min (glyph_before, glyph_after);
15331 for (glyph = start + incr;
15332 row->reversed_p ? glyph > stop : glyph < stop; )
15335 /* Any glyphs that come from the buffer are here because
15336 of bidi reordering. Skip them, and only pay
15337 attention to glyphs that came from some string. */
15338 if (STRINGP (glyph->object))
15340 Lisp_Object str;
15341 ptrdiff_t tem;
15342 /* If the display property covers the newline, we
15343 need to search for it one position farther. */
15344 ptrdiff_t lim = pos_after
15345 + (pos_after == MATRIX_ROW_END_CHARPOS (row) + delta);
15347 string_from_text_prop = false;
15348 str = glyph->object;
15349 tem = string_buffer_position_lim (str, pos, lim, false);
15350 if (tem == 0 /* from overlay */
15351 || pos <= tem)
15353 /* If the string from which this glyph came is
15354 found in the buffer at point, or at position
15355 that is closer to point than pos_after, then
15356 we've found the glyph we've been looking for.
15357 If it comes from an overlay (tem == 0), and
15358 it has the `cursor' property on one of its
15359 glyphs, record that glyph as a candidate for
15360 displaying the cursor. (As in the
15361 unidirectional version, we will display the
15362 cursor on the last candidate we find.) */
15363 if (tem == 0
15364 || tem == pt_old
15365 || (tem - pt_old > 0 && tem < pos_after))
15367 /* The glyphs from this string could have
15368 been reordered. Find the one with the
15369 smallest string position. Or there could
15370 be a character in the string with the
15371 `cursor' property, which means display
15372 cursor on that character's glyph. */
15373 ptrdiff_t strpos = glyph->charpos;
15375 if (tem)
15377 cursor = glyph;
15378 string_from_text_prop = true;
15380 for ( ;
15381 (row->reversed_p ? glyph > stop : glyph < stop)
15382 && EQ (glyph->object, str);
15383 glyph += incr)
15385 Lisp_Object cprop;
15386 ptrdiff_t gpos = glyph->charpos;
15388 cprop = Fget_char_property (make_number (gpos),
15389 Qcursor,
15390 glyph->object);
15391 if (!NILP (cprop))
15393 cursor = glyph;
15394 break;
15396 if (tem && glyph->charpos < strpos)
15398 strpos = glyph->charpos;
15399 cursor = glyph;
15403 if (tem == pt_old
15404 || (tem - pt_old > 0 && tem < pos_after))
15405 goto compute_x;
15407 if (tem)
15408 pos = tem + 1; /* don't find previous instances */
15410 /* This string is not what we want; skip all of the
15411 glyphs that came from it. */
15412 while ((row->reversed_p ? glyph > stop : glyph < stop)
15413 && EQ (glyph->object, str))
15414 glyph += incr;
15416 else
15417 glyph += incr;
15420 /* If we reached the end of the line, and END was from a string,
15421 the cursor is not on this line. */
15422 if (cursor == NULL
15423 && (row->reversed_p ? glyph <= end : glyph >= end)
15424 && (row->reversed_p ? end > glyphs_end : end < glyphs_end)
15425 && STRINGP (end->object)
15426 && row->continued_p)
15427 return false;
15429 /* A truncated row may not include PT among its character positions.
15430 Setting the cursor inside the scroll margin will trigger
15431 recalculation of hscroll in hscroll_window_tree. But if a
15432 display string covers point, defer to the string-handling
15433 code below to figure this out. */
15434 else if (row->truncated_on_left_p && pt_old < bpos_min)
15436 cursor = glyph_before;
15437 x = -1;
15439 else if ((row->truncated_on_right_p && pt_old > bpos_max)
15440 /* Zero-width characters produce no glyphs. */
15441 || (!empty_line_p
15442 && (row->reversed_p
15443 ? glyph_after > glyphs_end
15444 : glyph_after < glyphs_end)))
15446 cursor = glyph_after;
15447 x = -1;
15451 compute_x:
15452 if (cursor != NULL)
15453 glyph = cursor;
15454 else if (glyph == glyphs_end
15455 && pos_before == pos_after
15456 && STRINGP ((row->reversed_p
15457 ? row->glyphs[TEXT_AREA] + row->used[TEXT_AREA] - 1
15458 : row->glyphs[TEXT_AREA])->object))
15460 /* If all the glyphs of this row came from strings, put the
15461 cursor on the first glyph of the row. This avoids having the
15462 cursor outside of the text area in this very rare and hard
15463 use case. */
15464 glyph =
15465 row->reversed_p
15466 ? row->glyphs[TEXT_AREA] + row->used[TEXT_AREA] - 1
15467 : row->glyphs[TEXT_AREA];
15469 if (x < 0)
15471 struct glyph *g;
15473 /* Need to compute x that corresponds to GLYPH. */
15474 for (g = row->glyphs[TEXT_AREA], x = row->x; g < glyph; g++)
15476 if (g >= row->glyphs[TEXT_AREA] + row->used[TEXT_AREA])
15477 emacs_abort ();
15478 x += g->pixel_width;
15482 /* ROW could be part of a continued line, which, under bidi
15483 reordering, might have other rows whose start and end charpos
15484 occlude point. Only set w->cursor if we found a better
15485 approximation to the cursor position than we have from previously
15486 examined candidate rows belonging to the same continued line. */
15487 if (/* We already have a candidate row. */
15488 w->cursor.vpos >= 0
15489 /* That candidate is not the row we are processing. */
15490 && MATRIX_ROW (matrix, w->cursor.vpos) != row
15491 /* Make sure cursor.vpos specifies a row whose start and end
15492 charpos occlude point, and it is valid candidate for being a
15493 cursor-row. This is because some callers of this function
15494 leave cursor.vpos at the row where the cursor was displayed
15495 during the last redisplay cycle. */
15496 && MATRIX_ROW_START_CHARPOS (MATRIX_ROW (matrix, w->cursor.vpos)) <= pt_old
15497 && pt_old <= MATRIX_ROW_END_CHARPOS (MATRIX_ROW (matrix, w->cursor.vpos))
15498 && cursor_row_p (MATRIX_ROW (matrix, w->cursor.vpos)))
15500 struct glyph *g1
15501 = MATRIX_ROW_GLYPH_START (matrix, w->cursor.vpos) + w->cursor.hpos;
15503 /* Don't consider glyphs that are outside TEXT_AREA. */
15504 if (!(row->reversed_p ? glyph > glyphs_end : glyph < glyphs_end))
15505 return false;
15506 /* Keep the candidate whose buffer position is the closest to
15507 point or has the `cursor' property. */
15508 if (/* Previous candidate is a glyph in TEXT_AREA of that row. */
15509 w->cursor.hpos >= 0
15510 && w->cursor.hpos < MATRIX_ROW_USED (matrix, w->cursor.vpos)
15511 && ((BUFFERP (g1->object)
15512 && (g1->charpos == pt_old /* An exact match always wins. */
15513 || (BUFFERP (glyph->object)
15514 && eabs (g1->charpos - pt_old)
15515 < eabs (glyph->charpos - pt_old))))
15516 /* Previous candidate is a glyph from a string that has
15517 a non-nil `cursor' property. */
15518 || (STRINGP (g1->object)
15519 && (!NILP (Fget_char_property (make_number (g1->charpos),
15520 Qcursor, g1->object))
15521 /* Previous candidate is from the same display
15522 string as this one, and the display string
15523 came from a text property. */
15524 || (EQ (g1->object, glyph->object)
15525 && string_from_text_prop)
15526 /* this candidate is from newline and its
15527 position is not an exact match */
15528 || (NILP (glyph->object)
15529 && glyph->charpos != pt_old)))))
15530 return false;
15531 /* If this candidate gives an exact match, use that. */
15532 if (!((BUFFERP (glyph->object) && glyph->charpos == pt_old)
15533 /* If this candidate is a glyph created for the
15534 terminating newline of a line, and point is on that
15535 newline, it wins because it's an exact match. */
15536 || (!row->continued_p
15537 && NILP (glyph->object)
15538 && glyph->charpos == 0
15539 && pt_old == MATRIX_ROW_END_CHARPOS (row) - 1))
15540 /* Otherwise, keep the candidate that comes from a row
15541 spanning less buffer positions. This may win when one or
15542 both candidate positions are on glyphs that came from
15543 display strings, for which we cannot compare buffer
15544 positions. */
15545 && MATRIX_ROW_END_CHARPOS (MATRIX_ROW (matrix, w->cursor.vpos))
15546 - MATRIX_ROW_START_CHARPOS (MATRIX_ROW (matrix, w->cursor.vpos))
15547 < MATRIX_ROW_END_CHARPOS (row) - MATRIX_ROW_START_CHARPOS (row))
15548 return false;
15550 w->cursor.hpos = glyph - row->glyphs[TEXT_AREA];
15551 w->cursor.x = x;
15552 w->cursor.vpos = MATRIX_ROW_VPOS (row, matrix) + dvpos;
15553 w->cursor.y = row->y + dy;
15555 if (w == XWINDOW (selected_window))
15557 if (!row->continued_p
15558 && !MATRIX_ROW_CONTINUATION_LINE_P (row)
15559 && row->x == 0)
15561 this_line_buffer = XBUFFER (w->contents);
15563 CHARPOS (this_line_start_pos)
15564 = MATRIX_ROW_START_CHARPOS (row) + delta;
15565 BYTEPOS (this_line_start_pos)
15566 = MATRIX_ROW_START_BYTEPOS (row) + delta_bytes;
15568 CHARPOS (this_line_end_pos)
15569 = Z - (MATRIX_ROW_END_CHARPOS (row) + delta);
15570 BYTEPOS (this_line_end_pos)
15571 = Z_BYTE - (MATRIX_ROW_END_BYTEPOS (row) + delta_bytes);
15573 this_line_y = w->cursor.y;
15574 this_line_pixel_height = row->height;
15575 this_line_vpos = w->cursor.vpos;
15576 this_line_start_x = row->x;
15578 else
15579 CHARPOS (this_line_start_pos) = 0;
15582 return true;
15586 /* Run window scroll functions, if any, for WINDOW with new window
15587 start STARTP. Sets the window start of WINDOW to that position.
15589 We assume that the window's buffer is really current. */
15591 static struct text_pos
15592 run_window_scroll_functions (Lisp_Object window, struct text_pos startp)
15594 struct window *w = XWINDOW (window);
15595 SET_MARKER_FROM_TEXT_POS (w->start, startp);
15597 eassert (current_buffer == XBUFFER (w->contents));
15599 if (!NILP (Vwindow_scroll_functions))
15601 run_hook_with_args_2 (Qwindow_scroll_functions, window,
15602 make_number (CHARPOS (startp)));
15603 SET_TEXT_POS_FROM_MARKER (startp, w->start);
15604 /* In case the hook functions switch buffers. */
15605 set_buffer_internal (XBUFFER (w->contents));
15608 return startp;
15612 /* Make sure the line containing the cursor is fully visible.
15613 A value of true means there is nothing to be done.
15614 (Either the line is fully visible, or it cannot be made so,
15615 or we cannot tell.)
15617 If FORCE_P, return false even if partial visible cursor row
15618 is higher than window.
15620 If CURRENT_MATRIX_P, use the information from the
15621 window's current glyph matrix; otherwise use the desired glyph
15622 matrix.
15624 A value of false means the caller should do scrolling
15625 as if point had gone off the screen. */
15627 static bool
15628 cursor_row_fully_visible_p (struct window *w, bool force_p,
15629 bool current_matrix_p)
15631 struct glyph_matrix *matrix;
15632 struct glyph_row *row;
15633 int window_height;
15635 if (!make_cursor_line_fully_visible_p)
15636 return true;
15638 /* It's not always possible to find the cursor, e.g, when a window
15639 is full of overlay strings. Don't do anything in that case. */
15640 if (w->cursor.vpos < 0)
15641 return true;
15643 matrix = current_matrix_p ? w->current_matrix : w->desired_matrix;
15644 row = MATRIX_ROW (matrix, w->cursor.vpos);
15646 /* If the cursor row is not partially visible, there's nothing to do. */
15647 if (!MATRIX_ROW_PARTIALLY_VISIBLE_P (w, row))
15648 return true;
15650 /* If the row the cursor is in is taller than the window's height,
15651 it's not clear what to do, so do nothing. */
15652 window_height = window_box_height (w);
15653 if (row->height >= window_height)
15655 if (!force_p || MINI_WINDOW_P (w)
15656 || w->vscroll || w->cursor.vpos == 0)
15657 return true;
15659 return false;
15663 /* Try scrolling PT into view in window WINDOW. JUST_THIS_ONE_P
15664 means only WINDOW is redisplayed in redisplay_internal.
15665 TEMP_SCROLL_STEP has the same meaning as emacs_scroll_step, and is used
15666 in redisplay_window to bring a partially visible line into view in
15667 the case that only the cursor has moved.
15669 LAST_LINE_MISFIT should be true if we're scrolling because the
15670 last screen line's vertical height extends past the end of the screen.
15672 Value is
15674 1 if scrolling succeeded
15676 0 if scrolling didn't find point.
15678 -1 if new fonts have been loaded so that we must interrupt
15679 redisplay, adjust glyph matrices, and try again. */
15681 enum
15683 SCROLLING_SUCCESS,
15684 SCROLLING_FAILED,
15685 SCROLLING_NEED_LARGER_MATRICES
15688 /* If scroll-conservatively is more than this, never recenter.
15690 If you change this, don't forget to update the doc string of
15691 `scroll-conservatively' and the Emacs manual. */
15692 #define SCROLL_LIMIT 100
15694 static int
15695 try_scrolling (Lisp_Object window, bool just_this_one_p,
15696 ptrdiff_t arg_scroll_conservatively, ptrdiff_t scroll_step,
15697 bool temp_scroll_step, bool last_line_misfit)
15699 struct window *w = XWINDOW (window);
15700 struct text_pos pos, startp;
15701 struct it it;
15702 int this_scroll_margin, scroll_max, rc, height;
15703 int dy = 0, amount_to_scroll = 0;
15704 bool scroll_down_p = false;
15705 int extra_scroll_margin_lines = last_line_misfit;
15706 Lisp_Object aggressive;
15707 /* We will never try scrolling more than this number of lines. */
15708 int scroll_limit = SCROLL_LIMIT;
15709 int frame_line_height = default_line_pixel_height (w);
15711 #ifdef GLYPH_DEBUG
15712 debug_method_add (w, "try_scrolling");
15713 #endif
15715 SET_TEXT_POS_FROM_MARKER (startp, w->start);
15717 this_scroll_margin = window_scroll_margin (w, MARGIN_IN_PIXELS);
15719 /* Force arg_scroll_conservatively to have a reasonable value, to
15720 avoid scrolling too far away with slow move_it_* functions. Note
15721 that the user can supply scroll-conservatively equal to
15722 `most-positive-fixnum', which can be larger than INT_MAX. */
15723 if (arg_scroll_conservatively > scroll_limit)
15725 arg_scroll_conservatively = scroll_limit + 1;
15726 scroll_max = scroll_limit * frame_line_height;
15728 else if (scroll_step || arg_scroll_conservatively || temp_scroll_step)
15729 /* Compute how much we should try to scroll maximally to bring
15730 point into view. */
15731 scroll_max = (max (scroll_step,
15732 max (arg_scroll_conservatively, temp_scroll_step))
15733 * frame_line_height);
15734 else if (NUMBERP (BVAR (current_buffer, scroll_down_aggressively))
15735 || NUMBERP (BVAR (current_buffer, scroll_up_aggressively)))
15736 /* We're trying to scroll because of aggressive scrolling but no
15737 scroll_step is set. Choose an arbitrary one. */
15738 scroll_max = 10 * frame_line_height;
15739 else
15740 scroll_max = 0;
15742 too_near_end:
15744 /* Decide whether to scroll down. */
15745 if (PT > CHARPOS (startp))
15747 int scroll_margin_y;
15749 /* Compute the pixel ypos of the scroll margin, then move IT to
15750 either that ypos or PT, whichever comes first. */
15751 start_display (&it, w, startp);
15752 scroll_margin_y = it.last_visible_y - partial_line_height (&it)
15753 - this_scroll_margin
15754 - frame_line_height * extra_scroll_margin_lines;
15755 move_it_to (&it, PT, -1, scroll_margin_y - 1, -1,
15756 (MOVE_TO_POS | MOVE_TO_Y));
15758 if (PT > CHARPOS (it.current.pos))
15760 int y0 = line_bottom_y (&it);
15761 /* Compute how many pixels below window bottom to stop searching
15762 for PT. This avoids costly search for PT that is far away if
15763 the user limited scrolling by a small number of lines, but
15764 always finds PT if scroll_conservatively is set to a large
15765 number, such as most-positive-fixnum. */
15766 int slack = max (scroll_max, 10 * frame_line_height);
15767 int y_to_move = it.last_visible_y + slack;
15769 /* Compute the distance from the scroll margin to PT or to
15770 the scroll limit, whichever comes first. This should
15771 include the height of the cursor line, to make that line
15772 fully visible. */
15773 move_it_to (&it, PT, -1, y_to_move,
15774 -1, MOVE_TO_POS | MOVE_TO_Y);
15775 dy = line_bottom_y (&it) - y0;
15777 if (dy > scroll_max)
15778 return SCROLLING_FAILED;
15780 if (dy > 0)
15781 scroll_down_p = true;
15783 else if (PT == IT_CHARPOS (it)
15784 && IT_CHARPOS (it) < ZV
15785 && it.method == GET_FROM_STRING
15786 && arg_scroll_conservatively > scroll_limit
15787 && it.current_x == 0)
15789 enum move_it_result skip;
15790 int y1 = it.current_y;
15791 int vpos;
15793 /* A before-string that includes newlines and is displayed
15794 on the last visible screen line could fail us under
15795 scroll-conservatively > 100, because we will be unable to
15796 position the cursor on that last visible line. Try to
15797 recover by finding the first screen line that has some
15798 glyphs coming from the buffer text. */
15799 do {
15800 skip = move_it_in_display_line_to (&it, ZV, -1, MOVE_TO_POS);
15801 if (skip != MOVE_NEWLINE_OR_CR
15802 || IT_CHARPOS (it) != PT
15803 || it.method == GET_FROM_BUFFER)
15804 break;
15805 vpos = it.vpos;
15806 move_it_to (&it, -1, -1, -1, vpos + 1, MOVE_TO_VPOS);
15807 } while (it.vpos > vpos);
15809 dy = it.current_y - y1;
15811 if (dy > scroll_max)
15812 return SCROLLING_FAILED;
15814 if (dy > 0)
15815 scroll_down_p = true;
15819 if (scroll_down_p)
15821 /* Point is in or below the bottom scroll margin, so move the
15822 window start down. If scrolling conservatively, move it just
15823 enough down to make point visible. If scroll_step is set,
15824 move it down by scroll_step. */
15825 if (arg_scroll_conservatively)
15826 amount_to_scroll
15827 = min (max (dy, frame_line_height),
15828 frame_line_height * arg_scroll_conservatively);
15829 else if (scroll_step || temp_scroll_step)
15830 amount_to_scroll = scroll_max;
15831 else
15833 aggressive = BVAR (current_buffer, scroll_up_aggressively);
15834 height = WINDOW_BOX_TEXT_HEIGHT (w);
15835 if (NUMBERP (aggressive))
15837 double float_amount = XFLOATINT (aggressive) * height;
15838 int aggressive_scroll = float_amount;
15839 if (aggressive_scroll == 0 && float_amount > 0)
15840 aggressive_scroll = 1;
15841 /* Don't let point enter the scroll margin near top of
15842 the window. This could happen if the value of
15843 scroll_up_aggressively is too large and there are
15844 non-zero margins, because scroll_up_aggressively
15845 means put point that fraction of window height
15846 _from_the_bottom_margin_. */
15847 if (aggressive_scroll + 2 * this_scroll_margin > height)
15848 aggressive_scroll = height - 2 * this_scroll_margin;
15849 amount_to_scroll = dy + aggressive_scroll;
15853 if (amount_to_scroll <= 0)
15854 return SCROLLING_FAILED;
15856 start_display (&it, w, startp);
15857 if (arg_scroll_conservatively <= scroll_limit)
15858 move_it_vertically (&it, amount_to_scroll);
15859 else
15861 /* Extra precision for users who set scroll-conservatively
15862 to a large number: make sure the amount we scroll
15863 the window start is never less than amount_to_scroll,
15864 which was computed as distance from window bottom to
15865 point. This matters when lines at window top and lines
15866 below window bottom have different height. */
15867 struct it it1;
15868 void *it1data = NULL;
15869 /* We use a temporary it1 because line_bottom_y can modify
15870 its argument, if it moves one line down; see there. */
15871 int start_y;
15873 SAVE_IT (it1, it, it1data);
15874 start_y = line_bottom_y (&it1);
15875 do {
15876 RESTORE_IT (&it, &it, it1data);
15877 move_it_by_lines (&it, 1);
15878 SAVE_IT (it1, it, it1data);
15879 } while (IT_CHARPOS (it) < ZV
15880 && line_bottom_y (&it1) - start_y < amount_to_scroll);
15881 bidi_unshelve_cache (it1data, true);
15884 /* If STARTP is unchanged, move it down another screen line. */
15885 if (IT_CHARPOS (it) == CHARPOS (startp))
15886 move_it_by_lines (&it, 1);
15887 startp = it.current.pos;
15889 else
15891 struct text_pos scroll_margin_pos = startp;
15892 int y_offset = 0;
15894 /* See if point is inside the scroll margin at the top of the
15895 window. */
15896 if (this_scroll_margin)
15898 int y_start;
15900 start_display (&it, w, startp);
15901 y_start = it.current_y;
15902 move_it_vertically (&it, this_scroll_margin);
15903 scroll_margin_pos = it.current.pos;
15904 /* If we didn't move enough before hitting ZV, request
15905 additional amount of scroll, to move point out of the
15906 scroll margin. */
15907 if (IT_CHARPOS (it) == ZV
15908 && it.current_y - y_start < this_scroll_margin)
15909 y_offset = this_scroll_margin - (it.current_y - y_start);
15912 if (PT < CHARPOS (scroll_margin_pos))
15914 /* Point is in the scroll margin at the top of the window or
15915 above what is displayed in the window. */
15916 int y0, y_to_move;
15918 /* Compute the vertical distance from PT to the scroll
15919 margin position. Move as far as scroll_max allows, or
15920 one screenful, or 10 screen lines, whichever is largest.
15921 Give up if distance is greater than scroll_max or if we
15922 didn't reach the scroll margin position. */
15923 SET_TEXT_POS (pos, PT, PT_BYTE);
15924 start_display (&it, w, pos);
15925 y0 = it.current_y;
15926 y_to_move = max (it.last_visible_y,
15927 max (scroll_max, 10 * frame_line_height));
15928 move_it_to (&it, CHARPOS (scroll_margin_pos), 0,
15929 y_to_move, -1,
15930 MOVE_TO_POS | MOVE_TO_X | MOVE_TO_Y);
15931 dy = it.current_y - y0;
15932 if (dy > scroll_max
15933 || IT_CHARPOS (it) < CHARPOS (scroll_margin_pos))
15934 return SCROLLING_FAILED;
15936 /* Additional scroll for when ZV was too close to point. */
15937 dy += y_offset;
15939 /* Compute new window start. */
15940 start_display (&it, w, startp);
15942 if (arg_scroll_conservatively)
15943 amount_to_scroll = max (dy, frame_line_height
15944 * max (scroll_step, temp_scroll_step));
15945 else if (scroll_step || temp_scroll_step)
15946 amount_to_scroll = scroll_max;
15947 else
15949 aggressive = BVAR (current_buffer, scroll_down_aggressively);
15950 height = WINDOW_BOX_TEXT_HEIGHT (w);
15951 if (NUMBERP (aggressive))
15953 double float_amount = XFLOATINT (aggressive) * height;
15954 int aggressive_scroll = float_amount;
15955 if (aggressive_scroll == 0 && float_amount > 0)
15956 aggressive_scroll = 1;
15957 /* Don't let point enter the scroll margin near
15958 bottom of the window, if the value of
15959 scroll_down_aggressively happens to be too
15960 large. */
15961 if (aggressive_scroll + 2 * this_scroll_margin > height)
15962 aggressive_scroll = height - 2 * this_scroll_margin;
15963 amount_to_scroll = dy + aggressive_scroll;
15967 if (amount_to_scroll <= 0)
15968 return SCROLLING_FAILED;
15970 move_it_vertically_backward (&it, amount_to_scroll);
15971 startp = it.current.pos;
15975 /* Run window scroll functions. */
15976 startp = run_window_scroll_functions (window, startp);
15978 /* Display the window. Give up if new fonts are loaded, or if point
15979 doesn't appear. */
15980 if (!try_window (window, startp, 0))
15981 rc = SCROLLING_NEED_LARGER_MATRICES;
15982 else if (w->cursor.vpos < 0)
15984 clear_glyph_matrix (w->desired_matrix);
15985 rc = SCROLLING_FAILED;
15987 else
15989 /* Maybe forget recorded base line for line number display. */
15990 if (!just_this_one_p
15991 || current_buffer->clip_changed
15992 || BEG_UNCHANGED < CHARPOS (startp))
15993 w->base_line_number = 0;
15995 /* If cursor ends up on a partially visible line,
15996 treat that as being off the bottom of the screen. */
15997 if (! cursor_row_fully_visible_p (w, extra_scroll_margin_lines <= 1,
15998 false)
15999 /* It's possible that the cursor is on the first line of the
16000 buffer, which is partially obscured due to a vscroll
16001 (Bug#7537). In that case, avoid looping forever. */
16002 && extra_scroll_margin_lines < w->desired_matrix->nrows - 1)
16004 clear_glyph_matrix (w->desired_matrix);
16005 ++extra_scroll_margin_lines;
16006 goto too_near_end;
16008 rc = SCROLLING_SUCCESS;
16011 return rc;
16015 /* Compute a suitable window start for window W if display of W starts
16016 on a continuation line. Value is true if a new window start
16017 was computed.
16019 The new window start will be computed, based on W's width, starting
16020 from the start of the continued line. It is the start of the
16021 screen line with the minimum distance from the old start W->start,
16022 which is still before point (otherwise point will definitely not
16023 be visible in the window). */
16025 static bool
16026 compute_window_start_on_continuation_line (struct window *w)
16028 struct text_pos pos, start_pos, pos_before_pt;
16029 bool window_start_changed_p = false;
16031 SET_TEXT_POS_FROM_MARKER (start_pos, w->start);
16033 /* If window start is on a continuation line... Window start may be
16034 < BEGV in case there's invisible text at the start of the
16035 buffer (M-x rmail, for example). */
16036 if (CHARPOS (start_pos) > BEGV
16037 && FETCH_BYTE (BYTEPOS (start_pos) - 1) != '\n')
16039 struct it it;
16040 struct glyph_row *row;
16042 /* Handle the case that the window start is out of range. */
16043 if (CHARPOS (start_pos) < BEGV)
16044 SET_TEXT_POS (start_pos, BEGV, BEGV_BYTE);
16045 else if (CHARPOS (start_pos) > ZV)
16046 SET_TEXT_POS (start_pos, ZV, ZV_BYTE);
16048 /* Find the start of the continued line. This should be fast
16049 because find_newline is fast (newline cache). */
16050 row = w->desired_matrix->rows + window_wants_header_line (w);
16051 init_iterator (&it, w, CHARPOS (start_pos), BYTEPOS (start_pos),
16052 row, DEFAULT_FACE_ID);
16053 reseat_at_previous_visible_line_start (&it);
16055 /* If the line start is "too far" away from the window start,
16056 say it takes too much time to compute a new window start.
16057 Also, give up if the line start is after point, as in that
16058 case point will not be visible with any window start we
16059 compute. */
16060 if (IT_CHARPOS (it) <= PT
16061 || (CHARPOS (start_pos) - IT_CHARPOS (it)
16062 /* PXW: Do we need upper bounds here? */
16063 < WINDOW_TOTAL_LINES (w) * WINDOW_TOTAL_COLS (w)))
16065 int min_distance, distance;
16067 /* Move forward by display lines to find the new window
16068 start. If window width was enlarged, the new start can
16069 be expected to be > the old start. If window width was
16070 decreased, the new window start will be < the old start.
16071 So, we're looking for the display line start with the
16072 minimum distance from the old window start. */
16073 pos_before_pt = pos = it.current.pos;
16074 min_distance = DISP_INFINITY;
16075 while ((distance = eabs (CHARPOS (start_pos) - IT_CHARPOS (it))),
16076 distance < min_distance)
16078 min_distance = distance;
16079 if (CHARPOS (pos) <= PT)
16080 pos_before_pt = pos;
16081 pos = it.current.pos;
16082 if (it.line_wrap == WORD_WRAP)
16084 /* Under WORD_WRAP, move_it_by_lines is likely to
16085 overshoot and stop not at the first, but the
16086 second character from the left margin. So in
16087 that case, we need a more tight control on the X
16088 coordinate of the iterator than move_it_by_lines
16089 promises in its contract. The method is to first
16090 go to the last (rightmost) visible character of a
16091 line, then move to the leftmost character on the
16092 next line in a separate call. */
16093 move_it_to (&it, ZV, it.last_visible_x, it.current_y, -1,
16094 MOVE_TO_POS | MOVE_TO_X | MOVE_TO_Y);
16095 move_it_to (&it, ZV, 0,
16096 it.current_y + it.max_ascent + it.max_descent, -1,
16097 MOVE_TO_POS | MOVE_TO_X | MOVE_TO_Y);
16099 else
16100 move_it_by_lines (&it, 1);
16103 /* It makes very little sense to make the new window start
16104 after point, as point won't be visible. If that's what
16105 the loop above finds, fall back on the candidate before
16106 or at point that is closest to the old window start. */
16107 if (CHARPOS (pos) > PT)
16108 pos = pos_before_pt;
16110 /* Set the window start there. */
16111 SET_MARKER_FROM_TEXT_POS (w->start, pos);
16112 window_start_changed_p = true;
16116 return window_start_changed_p;
16120 /* Try cursor movement in case text has not changed in window WINDOW,
16121 with window start STARTP. Value is
16123 CURSOR_MOVEMENT_SUCCESS if successful
16125 CURSOR_MOVEMENT_CANNOT_BE_USED if this method cannot be used
16127 CURSOR_MOVEMENT_MUST_SCROLL if we know we have to scroll the
16128 display. *SCROLL_STEP is set to true, under certain circumstances, if
16129 we want to scroll as if scroll-step were set to 1. See the code.
16131 CURSOR_MOVEMENT_NEED_LARGER_MATRICES if we need larger matrices, in
16132 which case we have to abort this redisplay, and adjust matrices
16133 first. */
16135 enum
16137 CURSOR_MOVEMENT_SUCCESS,
16138 CURSOR_MOVEMENT_CANNOT_BE_USED,
16139 CURSOR_MOVEMENT_MUST_SCROLL,
16140 CURSOR_MOVEMENT_NEED_LARGER_MATRICES
16143 static int
16144 try_cursor_movement (Lisp_Object window, struct text_pos startp,
16145 bool *scroll_step)
16147 struct window *w = XWINDOW (window);
16148 struct frame *f = XFRAME (w->frame);
16149 int rc = CURSOR_MOVEMENT_CANNOT_BE_USED;
16151 #ifdef GLYPH_DEBUG
16152 if (inhibit_try_cursor_movement)
16153 return rc;
16154 #endif
16156 /* Previously, there was a check for Lisp integer in the
16157 if-statement below. Now, this field is converted to
16158 ptrdiff_t, thus zero means invalid position in a buffer. */
16159 eassert (w->last_point > 0);
16160 /* Likewise there was a check whether window_end_vpos is nil or larger
16161 than the window. Now window_end_vpos is int and so never nil, but
16162 let's leave eassert to check whether it fits in the window. */
16163 eassert (!w->window_end_valid
16164 || w->window_end_vpos < w->current_matrix->nrows);
16166 /* Handle case where text has not changed, only point, and it has
16167 not moved off the frame. */
16168 if (/* Point may be in this window. */
16169 PT >= CHARPOS (startp)
16170 /* Selective display hasn't changed. */
16171 && !current_buffer->clip_changed
16172 /* Function force-mode-line-update is used to force a thorough
16173 redisplay. It sets either windows_or_buffers_changed or
16174 update_mode_lines. So don't take a shortcut here for these
16175 cases. */
16176 && !update_mode_lines
16177 && !windows_or_buffers_changed
16178 && !f->cursor_type_changed
16179 && NILP (Vshow_trailing_whitespace)
16180 /* When display-line-numbers is in relative mode, moving point
16181 requires to redraw the entire window. */
16182 && !EQ (Vdisplay_line_numbers, Qrelative)
16183 && !EQ (Vdisplay_line_numbers, Qvisual)
16184 /* When the current line number should be displayed in a
16185 distinct face, moving point cannot be handled in optimized
16186 way as below. */
16187 && !(!NILP (Vdisplay_line_numbers)
16188 && NILP (Finternal_lisp_face_equal_p (Qline_number,
16189 Qline_number_current_line,
16190 w->frame)))
16191 /* This code is not used for mini-buffer for the sake of the case
16192 of redisplaying to replace an echo area message; since in
16193 that case the mini-buffer contents per se are usually
16194 unchanged. This code is of no real use in the mini-buffer
16195 since the handling of this_line_start_pos, etc., in redisplay
16196 handles the same cases. */
16197 && !EQ (window, minibuf_window)
16198 /* When overlay arrow is shown in current buffer, point movement
16199 is no longer "simple", as it typically causes the overlay
16200 arrow to move as well. */
16201 && !overlay_arrow_in_current_buffer_p ())
16203 int this_scroll_margin, top_scroll_margin;
16204 struct glyph_row *row = NULL;
16206 #ifdef GLYPH_DEBUG
16207 debug_method_add (w, "cursor movement");
16208 #endif
16210 this_scroll_margin = window_scroll_margin (w, MARGIN_IN_PIXELS);
16212 top_scroll_margin = this_scroll_margin;
16213 if (window_wants_header_line (w))
16214 top_scroll_margin += CURRENT_HEADER_LINE_HEIGHT (w);
16216 /* Start with the row the cursor was displayed during the last
16217 not paused redisplay. Give up if that row is not valid. */
16218 if (w->last_cursor_vpos < 0
16219 || w->last_cursor_vpos >= w->current_matrix->nrows)
16220 rc = CURSOR_MOVEMENT_MUST_SCROLL;
16221 else
16223 row = MATRIX_ROW (w->current_matrix, w->last_cursor_vpos);
16224 if (row->mode_line_p)
16225 ++row;
16226 if (!row->enabled_p)
16227 rc = CURSOR_MOVEMENT_MUST_SCROLL;
16230 if (rc == CURSOR_MOVEMENT_CANNOT_BE_USED)
16232 bool scroll_p = false, must_scroll = false;
16233 int last_y = window_text_bottom_y (w) - this_scroll_margin;
16235 if (PT > w->last_point)
16237 /* Point has moved forward. */
16238 while (MATRIX_ROW_END_CHARPOS (row) < PT
16239 && MATRIX_ROW_BOTTOM_Y (row) < last_y)
16241 eassert (row->enabled_p);
16242 ++row;
16245 /* If the end position of a row equals the start
16246 position of the next row, and PT is at that position,
16247 we would rather display cursor in the next line. */
16248 while (MATRIX_ROW_BOTTOM_Y (row) < last_y
16249 && MATRIX_ROW_END_CHARPOS (row) == PT
16250 && row < MATRIX_MODE_LINE_ROW (w->current_matrix)
16251 && MATRIX_ROW_START_CHARPOS (row+1) == PT
16252 && !cursor_row_p (row))
16253 ++row;
16255 /* If within the scroll margin, scroll. Note that
16256 MATRIX_ROW_BOTTOM_Y gives the pixel position at which
16257 the next line would be drawn, and that
16258 this_scroll_margin can be zero. */
16259 if (MATRIX_ROW_BOTTOM_Y (row) > last_y
16260 || PT > MATRIX_ROW_END_CHARPOS (row)
16261 /* Line is completely visible last line in window
16262 and PT is to be set in the next line. */
16263 || (MATRIX_ROW_BOTTOM_Y (row) == last_y
16264 && PT == MATRIX_ROW_END_CHARPOS (row)
16265 && !row->ends_at_zv_p
16266 && !MATRIX_ROW_ENDS_IN_MIDDLE_OF_CHAR_P (row)))
16267 scroll_p = true;
16269 else if (PT < w->last_point)
16271 /* Cursor has to be moved backward. Note that PT >=
16272 CHARPOS (startp) because of the outer if-statement. */
16273 while (!row->mode_line_p
16274 && (MATRIX_ROW_START_CHARPOS (row) > PT
16275 || (MATRIX_ROW_START_CHARPOS (row) == PT
16276 && (MATRIX_ROW_STARTS_IN_MIDDLE_OF_CHAR_P (row)
16277 || (/* STARTS_IN_MIDDLE_OF_STRING_P (row) */
16278 row > w->current_matrix->rows
16279 && (row-1)->ends_in_newline_from_string_p))))
16280 && (row->y > top_scroll_margin
16281 || CHARPOS (startp) == BEGV))
16283 eassert (row->enabled_p);
16284 --row;
16287 /* Consider the following case: Window starts at BEGV,
16288 there is invisible, intangible text at BEGV, so that
16289 display starts at some point START > BEGV. It can
16290 happen that we are called with PT somewhere between
16291 BEGV and START. Try to handle that case. */
16292 if (row < w->current_matrix->rows
16293 || row->mode_line_p)
16295 row = w->current_matrix->rows;
16296 if (row->mode_line_p)
16297 ++row;
16300 /* Due to newlines in overlay strings, we may have to
16301 skip forward over overlay strings. */
16302 while (MATRIX_ROW_BOTTOM_Y (row) < last_y
16303 && MATRIX_ROW_END_CHARPOS (row) == PT
16304 && !cursor_row_p (row))
16305 ++row;
16307 /* If within the scroll margin, scroll. */
16308 if (row->y < top_scroll_margin
16309 && CHARPOS (startp) != BEGV)
16310 scroll_p = true;
16312 else
16314 /* Cursor did not move. So don't scroll even if cursor line
16315 is partially visible, as it was so before. */
16316 rc = CURSOR_MOVEMENT_SUCCESS;
16319 if (PT < MATRIX_ROW_START_CHARPOS (row)
16320 || PT > MATRIX_ROW_END_CHARPOS (row))
16322 /* if PT is not in the glyph row, give up. */
16323 rc = CURSOR_MOVEMENT_MUST_SCROLL;
16324 must_scroll = true;
16326 else if (rc != CURSOR_MOVEMENT_SUCCESS
16327 && !NILP (BVAR (XBUFFER (w->contents), bidi_display_reordering)))
16329 struct glyph_row *row1;
16331 /* If rows are bidi-reordered and point moved, back up
16332 until we find a row that does not belong to a
16333 continuation line. This is because we must consider
16334 all rows of a continued line as candidates for the
16335 new cursor positioning, since row start and end
16336 positions change non-linearly with vertical position
16337 in such rows. */
16338 /* FIXME: Revisit this when glyph ``spilling'' in
16339 continuation lines' rows is implemented for
16340 bidi-reordered rows. */
16341 for (row1 = MATRIX_FIRST_TEXT_ROW (w->current_matrix);
16342 MATRIX_ROW_CONTINUATION_LINE_P (row);
16343 --row)
16345 /* If we hit the beginning of the displayed portion
16346 without finding the first row of a continued
16347 line, give up. */
16348 if (row <= row1)
16350 rc = CURSOR_MOVEMENT_MUST_SCROLL;
16351 break;
16353 eassert (row->enabled_p);
16356 if (must_scroll)
16358 else if (rc != CURSOR_MOVEMENT_SUCCESS
16359 && MATRIX_ROW_PARTIALLY_VISIBLE_P (w, row)
16360 /* Make sure this isn't a header line by any chance, since
16361 then MATRIX_ROW_PARTIALLY_VISIBLE_P might yield true. */
16362 && !row->mode_line_p
16363 && make_cursor_line_fully_visible_p)
16365 if (PT == MATRIX_ROW_END_CHARPOS (row)
16366 && !row->ends_at_zv_p
16367 && !MATRIX_ROW_ENDS_IN_MIDDLE_OF_CHAR_P (row))
16368 rc = CURSOR_MOVEMENT_MUST_SCROLL;
16369 else if (row->height > window_box_height (w))
16371 /* If we end up in a partially visible line, let's
16372 make it fully visible, except when it's taller
16373 than the window, in which case we can't do much
16374 about it. */
16375 *scroll_step = true;
16376 rc = CURSOR_MOVEMENT_MUST_SCROLL;
16378 else
16380 set_cursor_from_row (w, row, w->current_matrix, 0, 0, 0, 0);
16381 if (!cursor_row_fully_visible_p (w, false, true))
16382 rc = CURSOR_MOVEMENT_MUST_SCROLL;
16383 else
16384 rc = CURSOR_MOVEMENT_SUCCESS;
16387 else if (scroll_p)
16388 rc = CURSOR_MOVEMENT_MUST_SCROLL;
16389 else if (rc != CURSOR_MOVEMENT_SUCCESS
16390 && !NILP (BVAR (XBUFFER (w->contents), bidi_display_reordering)))
16392 /* With bidi-reordered rows, there could be more than
16393 one candidate row whose start and end positions
16394 occlude point. We need to let set_cursor_from_row
16395 find the best candidate. */
16396 /* FIXME: Revisit this when glyph ``spilling'' in
16397 continuation lines' rows is implemented for
16398 bidi-reordered rows. */
16399 bool rv = false;
16403 bool at_zv_p = false, exact_match_p = false;
16405 if (MATRIX_ROW_START_CHARPOS (row) <= PT
16406 && PT <= MATRIX_ROW_END_CHARPOS (row)
16407 && cursor_row_p (row))
16408 rv |= set_cursor_from_row (w, row, w->current_matrix,
16409 0, 0, 0, 0);
16410 /* As soon as we've found the exact match for point,
16411 or the first suitable row whose ends_at_zv_p flag
16412 is set, we are done. */
16413 if (rv)
16415 at_zv_p = MATRIX_ROW (w->current_matrix,
16416 w->cursor.vpos)->ends_at_zv_p;
16417 if (!at_zv_p
16418 && w->cursor.hpos >= 0
16419 && w->cursor.hpos < MATRIX_ROW_USED (w->current_matrix,
16420 w->cursor.vpos))
16422 struct glyph_row *candidate =
16423 MATRIX_ROW (w->current_matrix, w->cursor.vpos);
16424 struct glyph *g =
16425 candidate->glyphs[TEXT_AREA] + w->cursor.hpos;
16426 ptrdiff_t endpos = MATRIX_ROW_END_CHARPOS (candidate);
16428 exact_match_p =
16429 (BUFFERP (g->object) && g->charpos == PT)
16430 || (NILP (g->object)
16431 && (g->charpos == PT
16432 || (g->charpos == 0 && endpos - 1 == PT)));
16434 if (at_zv_p || exact_match_p)
16436 rc = CURSOR_MOVEMENT_SUCCESS;
16437 break;
16440 if (MATRIX_ROW_BOTTOM_Y (row) == last_y)
16441 break;
16442 ++row;
16444 while (((MATRIX_ROW_CONTINUATION_LINE_P (row)
16445 || row->continued_p)
16446 && MATRIX_ROW_BOTTOM_Y (row) <= last_y)
16447 || (MATRIX_ROW_START_CHARPOS (row) == PT
16448 && MATRIX_ROW_BOTTOM_Y (row) < last_y));
16449 /* If we didn't find any candidate rows, or exited the
16450 loop before all the candidates were examined, signal
16451 to the caller that this method failed. */
16452 if (rc != CURSOR_MOVEMENT_SUCCESS
16453 && !(rv
16454 && !MATRIX_ROW_CONTINUATION_LINE_P (row)
16455 && !row->continued_p))
16456 rc = CURSOR_MOVEMENT_MUST_SCROLL;
16457 else if (rv)
16458 rc = CURSOR_MOVEMENT_SUCCESS;
16460 else
16464 if (set_cursor_from_row (w, row, w->current_matrix, 0, 0, 0, 0))
16466 rc = CURSOR_MOVEMENT_SUCCESS;
16467 break;
16469 ++row;
16471 while (MATRIX_ROW_BOTTOM_Y (row) < last_y
16472 && MATRIX_ROW_START_CHARPOS (row) == PT
16473 && cursor_row_p (row));
16478 return rc;
16482 void
16483 set_vertical_scroll_bar (struct window *w)
16485 ptrdiff_t start, end, whole;
16487 /* Calculate the start and end positions for the current window.
16488 At some point, it would be nice to choose between scrollbars
16489 which reflect the whole buffer size, with special markers
16490 indicating narrowing, and scrollbars which reflect only the
16491 visible region.
16493 Note that mini-buffers sometimes aren't displaying any text. */
16494 if (!MINI_WINDOW_P (w)
16495 || (w == XWINDOW (minibuf_window)
16496 && NILP (echo_area_buffer[0])))
16498 struct buffer *buf = XBUFFER (w->contents);
16499 whole = BUF_ZV (buf) - BUF_BEGV (buf);
16500 start = marker_position (w->start) - BUF_BEGV (buf);
16501 /* I don't think this is guaranteed to be right. For the
16502 moment, we'll pretend it is. */
16503 end = BUF_Z (buf) - w->window_end_pos - BUF_BEGV (buf);
16505 if (end < start)
16506 end = start;
16507 if (whole < (end - start))
16508 whole = end - start;
16510 else
16511 start = end = whole = 0;
16513 /* Indicate what this scroll bar ought to be displaying now. */
16514 if (FRAME_TERMINAL (XFRAME (w->frame))->set_vertical_scroll_bar_hook)
16515 (*FRAME_TERMINAL (XFRAME (w->frame))->set_vertical_scroll_bar_hook)
16516 (w, end - start, whole, start);
16520 void
16521 set_horizontal_scroll_bar (struct window *w)
16523 int start, end, whole, portion;
16525 if (!MINI_WINDOW_P (w)
16526 || (w == XWINDOW (minibuf_window)
16527 && NILP (echo_area_buffer[0])))
16529 struct buffer *b = XBUFFER (w->contents);
16530 struct buffer *old_buffer = NULL;
16531 struct it it;
16532 struct text_pos startp;
16534 if (b != current_buffer)
16536 old_buffer = current_buffer;
16537 set_buffer_internal (b);
16540 SET_TEXT_POS_FROM_MARKER (startp, w->start);
16541 start_display (&it, w, startp);
16542 it.last_visible_x = INT_MAX;
16543 whole = move_it_to (&it, -1, INT_MAX, window_box_height (w), -1,
16544 MOVE_TO_X | MOVE_TO_Y);
16545 /* whole = move_it_to (&it, w->window_end_pos, INT_MAX,
16546 window_box_height (w), -1,
16547 MOVE_TO_POS | MOVE_TO_X | MOVE_TO_Y); */
16549 start = w->hscroll * FRAME_COLUMN_WIDTH (WINDOW_XFRAME (w));
16550 end = start + window_box_width (w, TEXT_AREA);
16551 portion = end - start;
16552 /* After enlarging a horizontally scrolled window such that it
16553 gets at least as wide as the text it contains, make sure that
16554 the thumb doesn't fill the entire scroll bar so we can still
16555 drag it back to see the entire text. */
16556 whole = max (whole, end);
16558 if (it.bidi_p)
16560 Lisp_Object pdir;
16562 pdir = Fcurrent_bidi_paragraph_direction (Qnil);
16563 if (EQ (pdir, Qright_to_left))
16565 start = whole - end;
16566 end = start + portion;
16570 if (old_buffer)
16571 set_buffer_internal (old_buffer);
16573 else
16574 start = end = whole = portion = 0;
16576 w->hscroll_whole = whole;
16578 /* Indicate what this scroll bar ought to be displaying now. */
16579 if (FRAME_TERMINAL (XFRAME (w->frame))->set_horizontal_scroll_bar_hook)
16580 (*FRAME_TERMINAL (XFRAME (w->frame))->set_horizontal_scroll_bar_hook)
16581 (w, portion, whole, start);
16585 /* Redisplay leaf window WINDOW. JUST_THIS_ONE_P means only
16586 selected_window is redisplayed.
16588 We can return without actually redisplaying the window if fonts has been
16589 changed on window's frame. In that case, redisplay_internal will retry.
16591 As one of the important parts of redisplaying a window, we need to
16592 decide whether the previous window-start position (stored in the
16593 window's w->start marker position) is still valid, and if it isn't,
16594 recompute it. Some details about that:
16596 . The previous window-start could be in a continuation line, in
16597 which case we need to recompute it when the window width
16598 changes. See compute_window_start_on_continuation_line and its
16599 call below.
16601 . The text that changed since last redisplay could include the
16602 previous window-start position. In that case, we try to salvage
16603 what we can from the current glyph matrix by calling
16604 try_scrolling, which see.
16606 . Some Emacs command could force us to use a specific window-start
16607 position by setting the window's force_start flag, or gently
16608 propose doing that by setting the window's optional_new_start
16609 flag. In these cases, we try using the specified start point if
16610 that succeeds (i.e. the window desired matrix is successfully
16611 recomputed, and point location is within the window). In case
16612 of optional_new_start, we first check if the specified start
16613 position is feasible, i.e. if it will allow point to be
16614 displayed in the window. If using the specified start point
16615 fails, e.g., if new fonts are needed to be loaded, we abort the
16616 redisplay cycle and leave it up to the next cycle to figure out
16617 things.
16619 . Note that the window's force_start flag is sometimes set by
16620 redisplay itself, when it decides that the previous window start
16621 point is fine and should be kept. Search for "goto force_start"
16622 below to see the details. Like the values of window-start
16623 specified outside of redisplay, these internally-deduced values
16624 are tested for feasibility, and ignored if found to be
16625 unfeasible.
16627 . Note that the function try_window, used to completely redisplay
16628 a window, accepts the window's start point as its argument.
16629 This is used several times in the redisplay code to control
16630 where the window start will be, according to user options such
16631 as scroll-conservatively, and also to ensure the screen line
16632 showing point will be fully (as opposed to partially) visible on
16633 display. */
16635 static void
16636 redisplay_window (Lisp_Object window, bool just_this_one_p)
16638 struct window *w = XWINDOW (window);
16639 struct frame *f = XFRAME (w->frame);
16640 struct buffer *buffer = XBUFFER (w->contents);
16641 struct buffer *old = current_buffer;
16642 struct text_pos lpoint, opoint, startp;
16643 bool update_mode_line;
16644 int tem;
16645 struct it it;
16646 /* Record it now because it's overwritten. */
16647 bool current_matrix_up_to_date_p = false;
16648 bool used_current_matrix_p = false;
16649 /* This is less strict than current_matrix_up_to_date_p.
16650 It indicates that the buffer contents and narrowing are unchanged. */
16651 bool buffer_unchanged_p = false;
16652 bool temp_scroll_step = false;
16653 ptrdiff_t count = SPECPDL_INDEX ();
16654 int rc;
16655 int centering_position = -1;
16656 bool last_line_misfit = false;
16657 ptrdiff_t beg_unchanged, end_unchanged;
16658 int frame_line_height, margin;
16659 bool use_desired_matrix;
16660 void *itdata = NULL;
16662 SET_TEXT_POS (lpoint, PT, PT_BYTE);
16663 opoint = lpoint;
16665 #ifdef GLYPH_DEBUG
16666 *w->desired_matrix->method = 0;
16667 #endif
16669 if (!just_this_one_p
16670 && REDISPLAY_SOME_P ()
16671 && !w->redisplay
16672 && !w->update_mode_line
16673 && !f->face_change
16674 && !f->redisplay
16675 && !buffer->text->redisplay
16676 && BUF_PT (buffer) == w->last_point)
16677 return;
16679 /* Make sure that both W's markers are valid. */
16680 eassert (XMARKER (w->start)->buffer == buffer);
16681 eassert (XMARKER (w->pointm)->buffer == buffer);
16683 reconsider_clip_changes (w);
16684 frame_line_height = default_line_pixel_height (w);
16685 margin = window_scroll_margin (w, MARGIN_IN_LINES);
16688 /* Has the mode line to be updated? */
16689 update_mode_line = (w->update_mode_line
16690 || update_mode_lines
16691 || buffer->clip_changed
16692 || buffer->prevent_redisplay_optimizations_p);
16694 if (!just_this_one_p)
16695 /* If `just_this_one_p' is set, we apparently set must_be_updated_p more
16696 cleverly elsewhere. */
16697 w->must_be_updated_p = true;
16699 if (MINI_WINDOW_P (w))
16701 if (w == XWINDOW (echo_area_window)
16702 && !NILP (echo_area_buffer[0]))
16704 if (update_mode_line)
16705 /* We may have to update a tty frame's menu bar or a
16706 tool-bar. Example `M-x C-h C-h C-g'. */
16707 goto finish_menu_bars;
16708 else
16709 /* We've already displayed the echo area glyphs in this window. */
16710 goto finish_scroll_bars;
16712 else if ((w != XWINDOW (minibuf_window)
16713 || minibuf_level == 0)
16714 /* When buffer is nonempty, redisplay window normally. */
16715 && BUF_Z (XBUFFER (w->contents)) == BUF_BEG (XBUFFER (w->contents))
16716 /* Quail displays non-mini buffers in minibuffer window.
16717 In that case, redisplay the window normally. */
16718 && !NILP (Fmemq (w->contents, Vminibuffer_list)))
16720 /* W is a mini-buffer window, but it's not active, so clear
16721 it. */
16722 int yb = window_text_bottom_y (w);
16723 struct glyph_row *row;
16724 int y;
16726 for (y = 0, row = w->desired_matrix->rows;
16727 y < yb;
16728 y += row->height, ++row)
16729 blank_row (w, row, y);
16730 goto finish_scroll_bars;
16733 clear_glyph_matrix (w->desired_matrix);
16736 /* Otherwise set up data on this window; select its buffer and point
16737 value. */
16738 /* Really select the buffer, for the sake of buffer-local
16739 variables. */
16740 set_buffer_internal_1 (XBUFFER (w->contents));
16742 current_matrix_up_to_date_p
16743 = (w->window_end_valid
16744 && !current_buffer->clip_changed
16745 && !current_buffer->prevent_redisplay_optimizations_p
16746 && !window_outdated (w)
16747 && !hscrolling_current_line_p (w));
16749 beg_unchanged = BEG_UNCHANGED;
16750 end_unchanged = END_UNCHANGED;
16752 SET_TEXT_POS (opoint, PT, PT_BYTE);
16754 specbind (Qinhibit_point_motion_hooks, Qt);
16756 buffer_unchanged_p
16757 = (w->window_end_valid
16758 && !current_buffer->clip_changed
16759 && !window_outdated (w));
16761 /* When windows_or_buffers_changed is non-zero, we can't rely
16762 on the window end being valid, so set it to zero there. */
16763 if (windows_or_buffers_changed)
16765 /* If window starts on a continuation line, maybe adjust the
16766 window start in case the window's width changed. */
16767 if (XMARKER (w->start)->buffer == current_buffer)
16768 compute_window_start_on_continuation_line (w);
16770 w->window_end_valid = false;
16771 /* If so, we also can't rely on current matrix
16772 and should not fool try_cursor_movement below. */
16773 current_matrix_up_to_date_p = false;
16776 /* Some sanity checks. */
16777 CHECK_WINDOW_END (w);
16778 if (Z == Z_BYTE && CHARPOS (opoint) != BYTEPOS (opoint))
16779 emacs_abort ();
16780 if (BYTEPOS (opoint) < CHARPOS (opoint))
16781 emacs_abort ();
16783 if (mode_line_update_needed (w))
16784 update_mode_line = true;
16786 /* Point refers normally to the selected window. For any other
16787 window, set up appropriate value. */
16788 if (!EQ (window, selected_window))
16790 ptrdiff_t new_pt = marker_position (w->pointm);
16791 ptrdiff_t new_pt_byte = marker_byte_position (w->pointm);
16793 if (new_pt < BEGV)
16795 new_pt = BEGV;
16796 new_pt_byte = BEGV_BYTE;
16797 set_marker_both (w->pointm, Qnil, BEGV, BEGV_BYTE);
16799 else if (new_pt > (ZV - 1))
16801 new_pt = ZV;
16802 new_pt_byte = ZV_BYTE;
16803 set_marker_both (w->pointm, Qnil, ZV, ZV_BYTE);
16806 /* We don't use SET_PT so that the point-motion hooks don't run. */
16807 TEMP_SET_PT_BOTH (new_pt, new_pt_byte);
16810 /* If any of the character widths specified in the display table
16811 have changed, invalidate the width run cache. It's true that
16812 this may be a bit late to catch such changes, but the rest of
16813 redisplay goes (non-fatally) haywire when the display table is
16814 changed, so why should we worry about doing any better? */
16815 if (current_buffer->width_run_cache
16816 || (current_buffer->base_buffer
16817 && current_buffer->base_buffer->width_run_cache))
16819 struct Lisp_Char_Table *disptab = buffer_display_table ();
16821 if (! disptab_matches_widthtab
16822 (disptab, XVECTOR (BVAR (current_buffer, width_table))))
16824 struct buffer *buf = current_buffer;
16826 if (buf->base_buffer)
16827 buf = buf->base_buffer;
16828 invalidate_region_cache (buf, buf->width_run_cache, BEG, Z);
16829 recompute_width_table (current_buffer, disptab);
16833 /* If window-start is screwed up, choose a new one. */
16834 if (XMARKER (w->start)->buffer != current_buffer)
16835 goto recenter;
16837 SET_TEXT_POS_FROM_MARKER (startp, w->start);
16839 /* If someone specified a new starting point but did not insist,
16840 check whether it can be used. */
16841 if ((w->optional_new_start || window_frozen_p (w))
16842 && CHARPOS (startp) >= BEGV
16843 && CHARPOS (startp) <= ZV)
16845 ptrdiff_t it_charpos;
16847 w->optional_new_start = false;
16848 start_display (&it, w, startp);
16849 move_it_to (&it, PT, 0, it.last_visible_y, -1,
16850 MOVE_TO_POS | MOVE_TO_X | MOVE_TO_Y);
16851 /* Record IT's position now, since line_bottom_y might change
16852 that. */
16853 it_charpos = IT_CHARPOS (it);
16854 /* Make sure we set the force_start flag only if the cursor row
16855 will be fully visible. Otherwise, the code under force_start
16856 label below will try to move point back into view, which is
16857 not what the code which sets optional_new_start wants. */
16858 if ((it.current_y == 0 || line_bottom_y (&it) < it.last_visible_y)
16859 && !w->force_start)
16861 if (it_charpos == PT)
16862 w->force_start = true;
16863 /* IT may overshoot PT if text at PT is invisible. */
16864 else if (it_charpos > PT && CHARPOS (startp) <= PT)
16865 w->force_start = true;
16866 #ifdef GLYPH_DEBUG
16867 if (w->force_start)
16869 if (window_frozen_p (w))
16870 debug_method_add (w, "set force_start from frozen window start");
16871 else
16872 debug_method_add (w, "set force_start from optional_new_start");
16874 #endif
16878 force_start:
16880 /* Handle case where place to start displaying has been specified,
16881 unless the specified location is outside the accessible range. */
16882 if (w->force_start)
16884 /* We set this later on if we have to adjust point. */
16885 int new_vpos = -1;
16887 w->force_start = false;
16888 w->vscroll = 0;
16889 w->window_end_valid = false;
16891 /* Forget any recorded base line for line number display. */
16892 if (!buffer_unchanged_p)
16893 w->base_line_number = 0;
16895 /* Redisplay the mode line. Select the buffer properly for that.
16896 Also, run the hook window-scroll-functions
16897 because we have scrolled. */
16898 /* Note, we do this after clearing force_start because
16899 if there's an error, it is better to forget about force_start
16900 than to get into an infinite loop calling the hook functions
16901 and having them get more errors. */
16902 if (!update_mode_line
16903 || ! NILP (Vwindow_scroll_functions))
16905 update_mode_line = true;
16906 w->update_mode_line = true;
16907 startp = run_window_scroll_functions (window, startp);
16910 if (CHARPOS (startp) < BEGV)
16911 SET_TEXT_POS (startp, BEGV, BEGV_BYTE);
16912 else if (CHARPOS (startp) > ZV)
16913 SET_TEXT_POS (startp, ZV, ZV_BYTE);
16915 /* Redisplay, then check if cursor has been set during the
16916 redisplay. Give up if new fonts were loaded. */
16917 /* We used to issue a CHECK_MARGINS argument to try_window here,
16918 but this causes scrolling to fail when point begins inside
16919 the scroll margin (bug#148) -- cyd */
16920 if (!try_window (window, startp, 0))
16922 w->force_start = true;
16923 clear_glyph_matrix (w->desired_matrix);
16924 goto need_larger_matrices;
16927 if (w->cursor.vpos < 0)
16929 /* If point does not appear, try to move point so it does
16930 appear. The desired matrix has been built above, so we
16931 can use it here. First see if point is in invisible
16932 text, and if so, move it to the first visible buffer
16933 position past that. */
16934 struct glyph_row *r = NULL;
16935 Lisp_Object invprop =
16936 get_char_property_and_overlay (make_number (PT), Qinvisible,
16937 Qnil, NULL);
16939 if (TEXT_PROP_MEANS_INVISIBLE (invprop) != 0)
16941 ptrdiff_t alt_pt;
16942 Lisp_Object invprop_end =
16943 Fnext_single_char_property_change (make_number (PT), Qinvisible,
16944 Qnil, Qnil);
16946 if (NATNUMP (invprop_end))
16947 alt_pt = XFASTINT (invprop_end);
16948 else
16949 alt_pt = ZV;
16950 r = row_containing_pos (w, alt_pt, w->desired_matrix->rows,
16951 NULL, 0);
16953 if (r)
16954 new_vpos = MATRIX_ROW_BOTTOM_Y (r);
16955 else /* Give up and just move to the middle of the window. */
16956 new_vpos = window_box_height (w) / 2;
16959 if (!cursor_row_fully_visible_p (w, false, false))
16961 /* Point does appear, but on a line partly visible at end of window.
16962 Move it back to a fully-visible line. */
16963 new_vpos = window_box_height (w);
16964 /* But if window_box_height suggests a Y coordinate that is
16965 not less than we already have, that line will clearly not
16966 be fully visible, so give up and scroll the display.
16967 This can happen when the default face uses a font whose
16968 dimensions are different from the frame's default
16969 font. */
16970 if (new_vpos >= w->cursor.y)
16972 w->cursor.vpos = -1;
16973 clear_glyph_matrix (w->desired_matrix);
16974 goto try_to_scroll;
16977 else if (w->cursor.vpos >= 0)
16979 /* Some people insist on not letting point enter the scroll
16980 margin, even though this part handles windows that didn't
16981 scroll at all. */
16982 int pixel_margin = margin * frame_line_height;
16983 bool header_line = window_wants_header_line (w);
16985 /* Note: We add an extra FRAME_LINE_HEIGHT, because the loop
16986 below, which finds the row to move point to, advances by
16987 the Y coordinate of the _next_ row, see the definition of
16988 MATRIX_ROW_BOTTOM_Y. */
16989 if (w->cursor.vpos < margin + header_line)
16991 w->cursor.vpos = -1;
16992 clear_glyph_matrix (w->desired_matrix);
16993 goto try_to_scroll;
16995 else
16997 int window_height = window_box_height (w);
16999 if (header_line)
17000 window_height += CURRENT_HEADER_LINE_HEIGHT (w);
17001 if (w->cursor.y >= window_height - pixel_margin)
17003 w->cursor.vpos = -1;
17004 clear_glyph_matrix (w->desired_matrix);
17005 goto try_to_scroll;
17010 /* If we need to move point for either of the above reasons,
17011 now actually do it. */
17012 if (new_vpos >= 0)
17014 struct glyph_row *row;
17016 row = MATRIX_FIRST_TEXT_ROW (w->desired_matrix);
17017 while (MATRIX_ROW_BOTTOM_Y (row) < new_vpos)
17018 ++row;
17020 TEMP_SET_PT_BOTH (MATRIX_ROW_START_CHARPOS (row),
17021 MATRIX_ROW_START_BYTEPOS (row));
17023 if (w != XWINDOW (selected_window))
17024 set_marker_both (w->pointm, Qnil, PT, PT_BYTE);
17025 else if (current_buffer == old)
17026 SET_TEXT_POS (lpoint, PT, PT_BYTE);
17028 set_cursor_from_row (w, row, w->desired_matrix, 0, 0, 0, 0);
17030 /* Re-run pre-redisplay-function so it can update the region
17031 according to the new position of point. */
17032 /* Other than the cursor, w's redisplay is done so we can set its
17033 redisplay to false. Also the buffer's redisplay can be set to
17034 false, since propagate_buffer_redisplay should have already
17035 propagated its info to `w' anyway. */
17036 w->redisplay = false;
17037 XBUFFER (w->contents)->text->redisplay = false;
17038 safe__call1 (true, Vpre_redisplay_function, Fcons (window, Qnil));
17040 if (w->redisplay || XBUFFER (w->contents)->text->redisplay
17041 || ((EQ (Vdisplay_line_numbers, Qrelative)
17042 || EQ (Vdisplay_line_numbers, Qvisual))
17043 && row != MATRIX_FIRST_TEXT_ROW (w->desired_matrix)))
17045 /* Either pre-redisplay-function made changes (e.g. move
17046 the region), or we moved point in a window that is
17047 under display-line-numbers = relative mode. We need
17048 another round of redisplay. */
17049 clear_glyph_matrix (w->desired_matrix);
17050 if (!try_window (window, startp, 0))
17051 goto need_larger_matrices;
17054 if (w->cursor.vpos < 0 || !cursor_row_fully_visible_p (w, false, false))
17056 clear_glyph_matrix (w->desired_matrix);
17057 goto try_to_scroll;
17060 #ifdef GLYPH_DEBUG
17061 debug_method_add (w, "forced window start");
17062 #endif
17063 goto done;
17066 /* Handle case where text has not changed, only point, and it has
17067 not moved off the frame, and we are not retrying after hscroll.
17068 (current_matrix_up_to_date_p is true when retrying.) */
17069 if (current_matrix_up_to_date_p
17070 && (rc = try_cursor_movement (window, startp, &temp_scroll_step),
17071 rc != CURSOR_MOVEMENT_CANNOT_BE_USED))
17073 switch (rc)
17075 case CURSOR_MOVEMENT_SUCCESS:
17076 used_current_matrix_p = true;
17077 goto done;
17079 case CURSOR_MOVEMENT_MUST_SCROLL:
17080 goto try_to_scroll;
17082 default:
17083 emacs_abort ();
17086 /* If current starting point was originally the beginning of a line
17087 but no longer is, find a new starting point. */
17088 else if (w->start_at_line_beg
17089 && !(CHARPOS (startp) <= BEGV
17090 || FETCH_BYTE (BYTEPOS (startp) - 1) == '\n'))
17092 #ifdef GLYPH_DEBUG
17093 debug_method_add (w, "recenter 1");
17094 #endif
17095 goto recenter;
17098 /* Try scrolling with try_window_id. Value is > 0 if update has
17099 been done, it is -1 if we know that the same window start will
17100 not work. It is 0 if unsuccessful for some other reason. */
17101 else if ((tem = try_window_id (w)) != 0)
17103 #ifdef GLYPH_DEBUG
17104 debug_method_add (w, "try_window_id %d", tem);
17105 #endif
17107 if (f->fonts_changed)
17108 goto need_larger_matrices;
17109 if (tem > 0)
17110 goto done;
17112 /* Otherwise try_window_id has returned -1 which means that we
17113 don't want the alternative below this comment to execute. */
17115 else if (CHARPOS (startp) >= BEGV
17116 && CHARPOS (startp) <= ZV
17117 && PT >= CHARPOS (startp)
17118 && (CHARPOS (startp) < ZV
17119 /* Avoid starting at end of buffer. */
17120 || CHARPOS (startp) == BEGV
17121 || !window_outdated (w)))
17123 int d1, d2, d5, d6;
17124 int rtop, rbot;
17126 /* If first window line is a continuation line, and window start
17127 is inside the modified region, but the first change is before
17128 current window start, we must select a new window start.
17130 However, if this is the result of a down-mouse event (e.g. by
17131 extending the mouse-drag-overlay), we don't want to select a
17132 new window start, since that would change the position under
17133 the mouse, resulting in an unwanted mouse-movement rather
17134 than a simple mouse-click. */
17135 if (!w->start_at_line_beg
17136 && NILP (do_mouse_tracking)
17137 && CHARPOS (startp) > BEGV
17138 && CHARPOS (startp) > BEG + beg_unchanged
17139 && CHARPOS (startp) <= Z - end_unchanged
17140 /* Even if w->start_at_line_beg is nil, a new window may
17141 start at a line_beg, since that's how set_buffer_window
17142 sets it. So, we need to check the return value of
17143 compute_window_start_on_continuation_line. (See also
17144 bug#197). */
17145 && XMARKER (w->start)->buffer == current_buffer
17146 && compute_window_start_on_continuation_line (w)
17147 /* It doesn't make sense to force the window start like we
17148 do at label force_start if it is already known that point
17149 will not be fully visible in the resulting window, because
17150 doing so will move point from its correct position
17151 instead of scrolling the window to bring point into view.
17152 See bug#9324. */
17153 && pos_visible_p (w, PT, &d1, &d2, &rtop, &rbot, &d5, &d6)
17154 /* A very tall row could need more than the window height,
17155 in which case we accept that it is partially visible. */
17156 && (rtop != 0) == (rbot != 0))
17158 w->force_start = true;
17159 SET_TEXT_POS_FROM_MARKER (startp, w->start);
17160 #ifdef GLYPH_DEBUG
17161 debug_method_add (w, "recomputed window start in continuation line");
17162 #endif
17163 goto force_start;
17166 #ifdef GLYPH_DEBUG
17167 debug_method_add (w, "same window start");
17168 #endif
17170 /* Try to redisplay starting at same place as before.
17171 If point has not moved off frame, accept the results. */
17172 if (!current_matrix_up_to_date_p
17173 /* Don't use try_window_reusing_current_matrix in this case
17174 because a window scroll function can have changed the
17175 buffer. */
17176 || !NILP (Vwindow_scroll_functions)
17177 || MINI_WINDOW_P (w)
17178 || !(used_current_matrix_p
17179 = try_window_reusing_current_matrix (w)))
17181 IF_DEBUG (debug_method_add (w, "1"));
17182 clear_glyph_matrix (w->desired_matrix);
17183 if (try_window (window, startp, TRY_WINDOW_CHECK_MARGINS) < 0)
17184 /* -1 means we need to scroll.
17185 0 means we need new matrices, but fonts_changed
17186 is set in that case, so we will detect it below. */
17187 goto try_to_scroll;
17190 if (f->fonts_changed)
17191 goto need_larger_matrices;
17193 if (w->cursor.vpos >= 0)
17195 if (!just_this_one_p
17196 || current_buffer->clip_changed
17197 || BEG_UNCHANGED < CHARPOS (startp))
17198 /* Forget any recorded base line for line number display. */
17199 w->base_line_number = 0;
17201 if (!cursor_row_fully_visible_p (w, true, false))
17203 clear_glyph_matrix (w->desired_matrix);
17204 last_line_misfit = true;
17206 /* Drop through and scroll. */
17207 else
17208 goto done;
17210 else
17211 clear_glyph_matrix (w->desired_matrix);
17214 try_to_scroll:
17216 /* Redisplay the mode line. Select the buffer properly for that. */
17217 if (!update_mode_line)
17219 update_mode_line = true;
17220 w->update_mode_line = true;
17223 /* Try to scroll by specified few lines. */
17224 if ((scroll_conservatively
17225 || emacs_scroll_step
17226 || temp_scroll_step
17227 || NUMBERP (BVAR (current_buffer, scroll_up_aggressively))
17228 || NUMBERP (BVAR (current_buffer, scroll_down_aggressively)))
17229 && CHARPOS (startp) >= BEGV
17230 && CHARPOS (startp) <= ZV)
17232 /* The function returns -1 if new fonts were loaded, 1 if
17233 successful, 0 if not successful. */
17234 int ss = try_scrolling (window, just_this_one_p,
17235 scroll_conservatively,
17236 emacs_scroll_step,
17237 temp_scroll_step, last_line_misfit);
17238 switch (ss)
17240 case SCROLLING_SUCCESS:
17241 goto done;
17243 case SCROLLING_NEED_LARGER_MATRICES:
17244 goto need_larger_matrices;
17246 case SCROLLING_FAILED:
17247 break;
17249 default:
17250 emacs_abort ();
17254 /* Finally, just choose a place to start which positions point
17255 according to user preferences. */
17257 recenter:
17259 #ifdef GLYPH_DEBUG
17260 debug_method_add (w, "recenter");
17261 #endif
17263 /* Forget any previously recorded base line for line number display. */
17264 if (!buffer_unchanged_p)
17265 w->base_line_number = 0;
17267 /* Determine the window start relative to point. */
17268 init_iterator (&it, w, PT, PT_BYTE, NULL, DEFAULT_FACE_ID);
17269 it.current_y = it.last_visible_y;
17270 if (centering_position < 0)
17272 ptrdiff_t margin_pos = CHARPOS (startp);
17273 Lisp_Object aggressive;
17274 bool scrolling_up;
17276 /* If there is a scroll margin at the top of the window, find
17277 its character position. */
17278 if (margin
17279 /* Cannot call start_display if startp is not in the
17280 accessible region of the buffer. This can happen when we
17281 have just switched to a different buffer and/or changed
17282 its restriction. In that case, startp is initialized to
17283 the character position 1 (BEGV) because we did not yet
17284 have chance to display the buffer even once. */
17285 && BEGV <= CHARPOS (startp) && CHARPOS (startp) <= ZV)
17287 struct it it1;
17288 void *it1data = NULL;
17290 SAVE_IT (it1, it, it1data);
17291 start_display (&it1, w, startp);
17292 move_it_vertically (&it1, margin * frame_line_height);
17293 margin_pos = IT_CHARPOS (it1);
17294 RESTORE_IT (&it, &it, it1data);
17296 scrolling_up = PT > margin_pos;
17297 aggressive =
17298 scrolling_up
17299 ? BVAR (current_buffer, scroll_up_aggressively)
17300 : BVAR (current_buffer, scroll_down_aggressively);
17302 if (!MINI_WINDOW_P (w)
17303 && (scroll_conservatively > SCROLL_LIMIT || NUMBERP (aggressive)))
17305 int pt_offset = 0;
17307 /* Setting scroll-conservatively overrides
17308 scroll-*-aggressively. */
17309 if (!scroll_conservatively && NUMBERP (aggressive))
17311 double float_amount = XFLOATINT (aggressive);
17313 pt_offset = float_amount * WINDOW_BOX_TEXT_HEIGHT (w);
17314 if (pt_offset == 0 && float_amount > 0)
17315 pt_offset = 1;
17316 if (pt_offset && margin > 0)
17317 margin -= 1;
17319 /* Compute how much to move the window start backward from
17320 point so that point will be displayed where the user
17321 wants it. */
17322 if (scrolling_up)
17324 centering_position = it.last_visible_y;
17325 if (pt_offset)
17326 centering_position -= pt_offset;
17327 centering_position -=
17328 (frame_line_height * (1 + margin + last_line_misfit)
17329 + WINDOW_HEADER_LINE_HEIGHT (w));
17330 /* Don't let point enter the scroll margin near top of
17331 the window. */
17332 if (centering_position < margin * frame_line_height)
17333 centering_position = margin * frame_line_height;
17335 else
17336 centering_position = margin * frame_line_height + pt_offset;
17338 else
17339 /* Set the window start half the height of the window backward
17340 from point. */
17341 centering_position = window_box_height (w) / 2;
17343 move_it_vertically_backward (&it, centering_position);
17345 eassert (IT_CHARPOS (it) >= BEGV);
17347 /* The function move_it_vertically_backward may move over more
17348 than the specified y-distance. If it->w is small, e.g. a
17349 mini-buffer window, we may end up in front of the window's
17350 display area. Start displaying at the start of the line
17351 containing PT in this case. */
17352 if (it.current_y <= 0)
17354 init_iterator (&it, w, PT, PT_BYTE, NULL, DEFAULT_FACE_ID);
17355 move_it_vertically_backward (&it, 0);
17356 it.current_y = 0;
17359 it.current_x = it.hpos = 0;
17361 /* Set the window start position here explicitly, to avoid an
17362 infinite loop in case the functions in window-scroll-functions
17363 get errors. */
17364 set_marker_both (w->start, Qnil, IT_CHARPOS (it), IT_BYTEPOS (it));
17366 /* Run scroll hooks. */
17367 startp = run_window_scroll_functions (window, it.current.pos);
17369 /* We invoke try_window and try_window_reusing_current_matrix below,
17370 and they manipulate the bidi cache. Save and restore the cache
17371 state of our iterator, so we could continue using it after that. */
17372 itdata = bidi_shelve_cache ();
17374 /* Redisplay the window. */
17375 use_desired_matrix = false;
17376 if (!current_matrix_up_to_date_p
17377 || windows_or_buffers_changed
17378 || f->cursor_type_changed
17379 /* Don't use try_window_reusing_current_matrix in this case
17380 because it can have changed the buffer. */
17381 || !NILP (Vwindow_scroll_functions)
17382 || !just_this_one_p
17383 || MINI_WINDOW_P (w)
17384 || !(used_current_matrix_p
17385 = try_window_reusing_current_matrix (w)))
17386 use_desired_matrix = (try_window (window, startp, 0) == 1);
17388 bidi_unshelve_cache (itdata, false);
17390 /* If new fonts have been loaded (due to fontsets), give up. We
17391 have to start a new redisplay since we need to re-adjust glyph
17392 matrices. */
17393 if (f->fonts_changed)
17394 goto need_larger_matrices;
17396 /* If cursor did not appear assume that the middle of the window is
17397 in the first line of the window. Do it again with the next line.
17398 (Imagine a window of height 100, displaying two lines of height
17399 60. Moving back 50 from it->last_visible_y will end in the first
17400 line.) */
17401 if (w->cursor.vpos < 0)
17403 if (w->window_end_valid && PT >= Z - w->window_end_pos)
17405 clear_glyph_matrix (w->desired_matrix);
17406 move_it_by_lines (&it, 1);
17407 try_window (window, it.current.pos, 0);
17409 else if (PT < IT_CHARPOS (it))
17411 clear_glyph_matrix (w->desired_matrix);
17412 move_it_by_lines (&it, -1);
17413 try_window (window, it.current.pos, 0);
17415 else if (scroll_conservatively > SCROLL_LIMIT
17416 && (it.method == GET_FROM_STRING
17417 || overlay_touches_p (IT_CHARPOS (it)))
17418 && IT_CHARPOS (it) < ZV)
17420 /* If the window starts with a before-string that spans more
17421 than one screen line, using that position to display the
17422 window might fail to bring point into the view, because
17423 start_display will always start by displaying the string,
17424 whereas the code above determines where to set w->start
17425 by the buffer position of the place where it takes screen
17426 coordinates. Try to recover by finding the next screen
17427 line that displays buffer text. */
17428 ptrdiff_t pos0 = IT_CHARPOS (it);
17430 clear_glyph_matrix (w->desired_matrix);
17431 do {
17432 move_it_by_lines (&it, 1);
17433 } while (IT_CHARPOS (it) == pos0);
17434 try_window (window, it.current.pos, 0);
17436 else
17438 /* Not much we can do about it. */
17442 /* Consider the following case: Window starts at BEGV, there is
17443 invisible, intangible text at BEGV, so that display starts at
17444 some point START > BEGV. It can happen that we are called with
17445 PT somewhere between BEGV and START. Try to handle that case,
17446 and similar ones. */
17447 if (w->cursor.vpos < 0)
17449 /* Prefer the desired matrix to the current matrix, if possible,
17450 in the fallback calculations below. This is because using
17451 the current matrix might completely goof, e.g. if its first
17452 row is after point. */
17453 struct glyph_matrix *matrix =
17454 use_desired_matrix ? w->desired_matrix : w->current_matrix;
17455 /* First, try locating the proper glyph row for PT. */
17456 struct glyph_row *row =
17457 row_containing_pos (w, PT, matrix->rows, NULL, 0);
17459 /* Sometimes point is at the beginning of invisible text that is
17460 before the 1st character displayed in the row. In that case,
17461 row_containing_pos fails to find the row, because no glyphs
17462 with appropriate buffer positions are present in the row.
17463 Therefore, we next try to find the row which shows the 1st
17464 position after the invisible text. */
17465 if (!row)
17467 Lisp_Object val =
17468 get_char_property_and_overlay (make_number (PT), Qinvisible,
17469 Qnil, NULL);
17471 if (TEXT_PROP_MEANS_INVISIBLE (val) != 0)
17473 ptrdiff_t alt_pos;
17474 Lisp_Object invis_end =
17475 Fnext_single_char_property_change (make_number (PT), Qinvisible,
17476 Qnil, Qnil);
17478 if (NATNUMP (invis_end))
17479 alt_pos = XFASTINT (invis_end);
17480 else
17481 alt_pos = ZV;
17482 row = row_containing_pos (w, alt_pos, matrix->rows, NULL, 0);
17485 /* Finally, fall back on the first row of the window after the
17486 header line (if any). This is slightly better than not
17487 displaying the cursor at all. */
17488 if (!row)
17490 row = matrix->rows;
17491 if (row->mode_line_p)
17492 ++row;
17494 set_cursor_from_row (w, row, matrix, 0, 0, 0, 0);
17497 if (!cursor_row_fully_visible_p (w, false, false))
17499 /* If vscroll is enabled, disable it and try again. */
17500 if (w->vscroll)
17502 w->vscroll = 0;
17503 clear_glyph_matrix (w->desired_matrix);
17504 goto recenter;
17507 /* Users who set scroll-conservatively to a large number want
17508 point just above/below the scroll margin. If we ended up
17509 with point's row partially visible, move the window start to
17510 make that row fully visible and out of the margin. */
17511 if (scroll_conservatively > SCROLL_LIMIT)
17513 int window_total_lines
17514 = WINDOW_TOTAL_LINES (w) * FRAME_LINE_HEIGHT (f) / frame_line_height;
17515 bool move_down = w->cursor.vpos >= window_total_lines / 2;
17517 move_it_by_lines (&it, move_down ? margin + 1 : -(margin + 1));
17518 clear_glyph_matrix (w->desired_matrix);
17519 if (1 == try_window (window, it.current.pos,
17520 TRY_WINDOW_CHECK_MARGINS))
17521 goto done;
17524 /* If centering point failed to make the whole line visible,
17525 put point at the top instead. That has to make the whole line
17526 visible, if it can be done. */
17527 if (centering_position == 0)
17528 goto done;
17530 clear_glyph_matrix (w->desired_matrix);
17531 centering_position = 0;
17532 goto recenter;
17535 done:
17537 SET_TEXT_POS_FROM_MARKER (startp, w->start);
17538 w->start_at_line_beg = (CHARPOS (startp) == BEGV
17539 || FETCH_BYTE (BYTEPOS (startp) - 1) == '\n');
17541 /* Display the mode line, if we must. */
17542 if ((update_mode_line
17543 /* If window not full width, must redo its mode line
17544 if (a) the window to its side is being redone and
17545 (b) we do a frame-based redisplay. This is a consequence
17546 of how inverted lines are drawn in frame-based redisplay. */
17547 || (!just_this_one_p
17548 && !FRAME_WINDOW_P (f)
17549 && !WINDOW_FULL_WIDTH_P (w))
17550 /* Line number to display. */
17551 || w->base_line_pos > 0
17552 /* Column number is displayed and different from the one displayed. */
17553 || (w->column_number_displayed != -1
17554 && (w->column_number_displayed != current_column ())))
17555 /* This means that the window has a mode line. */
17556 && (window_wants_mode_line (w)
17557 || window_wants_header_line (w)))
17560 display_mode_lines (w);
17562 /* If mode line height has changed, arrange for a thorough
17563 immediate redisplay using the correct mode line height. */
17564 if (window_wants_mode_line (w)
17565 && CURRENT_MODE_LINE_HEIGHT (w) != DESIRED_MODE_LINE_HEIGHT (w))
17567 f->fonts_changed = true;
17568 w->mode_line_height = -1;
17569 MATRIX_MODE_LINE_ROW (w->current_matrix)->height
17570 = DESIRED_MODE_LINE_HEIGHT (w);
17573 /* If header line height has changed, arrange for a thorough
17574 immediate redisplay using the correct header line height. */
17575 if (window_wants_header_line (w)
17576 && CURRENT_HEADER_LINE_HEIGHT (w) != DESIRED_HEADER_LINE_HEIGHT (w))
17578 f->fonts_changed = true;
17579 w->header_line_height = -1;
17580 MATRIX_HEADER_LINE_ROW (w->current_matrix)->height
17581 = DESIRED_HEADER_LINE_HEIGHT (w);
17584 if (f->fonts_changed)
17585 goto need_larger_matrices;
17588 if (!line_number_displayed && w->base_line_pos != -1)
17590 w->base_line_pos = 0;
17591 w->base_line_number = 0;
17594 finish_menu_bars:
17596 /* When we reach a frame's selected window, redo the frame's menu
17597 bar and the frame's title. */
17598 if (update_mode_line
17599 && EQ (FRAME_SELECTED_WINDOW (f), window))
17601 bool redisplay_menu_p;
17603 if (FRAME_WINDOW_P (f))
17605 #if defined (USE_X_TOOLKIT) || defined (HAVE_NTGUI) \
17606 || defined (HAVE_NS) || defined (USE_GTK)
17607 redisplay_menu_p = FRAME_EXTERNAL_MENU_BAR (f);
17608 #else
17609 redisplay_menu_p = FRAME_MENU_BAR_LINES (f) > 0;
17610 #endif
17612 else
17613 redisplay_menu_p = FRAME_MENU_BAR_LINES (f) > 0;
17615 if (redisplay_menu_p)
17616 display_menu_bar (w);
17618 #ifdef HAVE_WINDOW_SYSTEM
17619 if (FRAME_WINDOW_P (f))
17621 #if defined (USE_GTK) || defined (HAVE_NS)
17622 if (FRAME_EXTERNAL_TOOL_BAR (f))
17623 redisplay_tool_bar (f);
17624 #else
17625 if (WINDOWP (f->tool_bar_window)
17626 && (FRAME_TOOL_BAR_LINES (f) > 0
17627 || !NILP (Vauto_resize_tool_bars))
17628 && redisplay_tool_bar (f))
17629 ignore_mouse_drag_p = true;
17630 #endif
17632 x_consider_frame_title (w->frame);
17633 #endif
17636 #ifdef HAVE_WINDOW_SYSTEM
17637 if (FRAME_WINDOW_P (f)
17638 && update_window_fringes (w, (just_this_one_p
17639 || (!used_current_matrix_p && !overlay_arrow_seen)
17640 || w->pseudo_window_p)))
17642 update_begin (f);
17643 block_input ();
17644 if (draw_window_fringes (w, true))
17646 if (WINDOW_RIGHT_DIVIDER_WIDTH (w))
17647 x_draw_right_divider (w);
17648 else
17649 x_draw_vertical_border (w);
17651 unblock_input ();
17652 update_end (f);
17655 if (WINDOW_BOTTOM_DIVIDER_WIDTH (w))
17656 x_draw_bottom_divider (w);
17657 #endif /* HAVE_WINDOW_SYSTEM */
17659 /* We go to this label, with fonts_changed set, if it is
17660 necessary to try again using larger glyph matrices.
17661 We have to redeem the scroll bar even in this case,
17662 because the loop in redisplay_internal expects that. */
17663 need_larger_matrices:
17665 finish_scroll_bars:
17667 if (WINDOW_HAS_VERTICAL_SCROLL_BAR (w) || WINDOW_HAS_HORIZONTAL_SCROLL_BAR (w))
17669 if (WINDOW_HAS_VERTICAL_SCROLL_BAR (w))
17670 /* Set the thumb's position and size. */
17671 set_vertical_scroll_bar (w);
17673 if (WINDOW_HAS_HORIZONTAL_SCROLL_BAR (w))
17674 /* Set the thumb's position and size. */
17675 set_horizontal_scroll_bar (w);
17677 /* Note that we actually used the scroll bar attached to this
17678 window, so it shouldn't be deleted at the end of redisplay. */
17679 if (FRAME_TERMINAL (f)->redeem_scroll_bar_hook)
17680 (*FRAME_TERMINAL (f)->redeem_scroll_bar_hook) (w);
17683 /* Restore current_buffer and value of point in it. The window
17684 update may have changed the buffer, so first make sure `opoint'
17685 is still valid (Bug#6177). */
17686 if (CHARPOS (opoint) < BEGV)
17687 TEMP_SET_PT_BOTH (BEGV, BEGV_BYTE);
17688 else if (CHARPOS (opoint) > ZV)
17689 TEMP_SET_PT_BOTH (Z, Z_BYTE);
17690 else
17691 TEMP_SET_PT_BOTH (CHARPOS (opoint), BYTEPOS (opoint));
17693 set_buffer_internal_1 (old);
17694 /* Avoid an abort in TEMP_SET_PT_BOTH if the buffer has become
17695 shorter. This can be caused by log truncation in *Messages*. */
17696 if (CHARPOS (lpoint) <= ZV)
17697 TEMP_SET_PT_BOTH (CHARPOS (lpoint), BYTEPOS (lpoint));
17699 unbind_to (count, Qnil);
17703 /* Build the complete desired matrix of WINDOW with a window start
17704 buffer position POS.
17706 Value is 1 if successful. It is zero if fonts were loaded during
17707 redisplay which makes re-adjusting glyph matrices necessary, and -1
17708 if point would appear in the scroll margins.
17709 (We check the former only if TRY_WINDOW_IGNORE_FONTS_CHANGE is
17710 unset in FLAGS, and the latter only if TRY_WINDOW_CHECK_MARGINS is
17711 set in FLAGS.) */
17714 try_window (Lisp_Object window, struct text_pos pos, int flags)
17716 struct window *w = XWINDOW (window);
17717 struct it it;
17718 struct glyph_row *last_text_row = NULL;
17719 struct frame *f = XFRAME (w->frame);
17720 int cursor_vpos = w->cursor.vpos;
17722 /* Make POS the new window start. */
17723 set_marker_both (w->start, Qnil, CHARPOS (pos), BYTEPOS (pos));
17725 /* Mark cursor position as unknown. No overlay arrow seen. */
17726 w->cursor.vpos = -1;
17727 overlay_arrow_seen = false;
17729 /* Initialize iterator and info to start at POS. */
17730 start_display (&it, w, pos);
17731 it.glyph_row->reversed_p = false;
17733 /* Display all lines of W. */
17734 while (it.current_y < it.last_visible_y)
17736 if (display_line (&it, cursor_vpos))
17737 last_text_row = it.glyph_row - 1;
17738 if (f->fonts_changed && !(flags & TRY_WINDOW_IGNORE_FONTS_CHANGE))
17739 return 0;
17742 /* Save the character position of 'it' before we call
17743 'start_display' again. */
17744 ptrdiff_t it_charpos = IT_CHARPOS (it);
17746 /* Don't let the cursor end in the scroll margins. */
17747 if ((flags & TRY_WINDOW_CHECK_MARGINS)
17748 && !MINI_WINDOW_P (w))
17750 int this_scroll_margin = window_scroll_margin (w, MARGIN_IN_PIXELS);
17751 start_display (&it, w, pos);
17753 if ((w->cursor.y >= 0 /* not vscrolled */
17754 && w->cursor.y < this_scroll_margin
17755 && CHARPOS (pos) > BEGV
17756 && it_charpos < ZV)
17757 /* rms: considering make_cursor_line_fully_visible_p here
17758 seems to give wrong results. We don't want to recenter
17759 when the last line is partly visible, we want to allow
17760 that case to be handled in the usual way. */
17761 || w->cursor.y > (it.last_visible_y - partial_line_height (&it)
17762 - this_scroll_margin - 1))
17764 w->cursor.vpos = -1;
17765 clear_glyph_matrix (w->desired_matrix);
17766 return -1;
17770 /* If bottom moved off end of frame, change mode line percentage. */
17771 if (w->window_end_pos <= 0 && Z != it_charpos)
17772 w->update_mode_line = true;
17774 /* Set window_end_pos to the offset of the last character displayed
17775 on the window from the end of current_buffer. Set
17776 window_end_vpos to its row number. */
17777 if (last_text_row)
17779 eassert (MATRIX_ROW_DISPLAYS_TEXT_P (last_text_row));
17780 adjust_window_ends (w, last_text_row, false);
17781 eassert
17782 (MATRIX_ROW_DISPLAYS_TEXT_P (MATRIX_ROW (w->desired_matrix,
17783 w->window_end_vpos)));
17785 else
17787 w->window_end_bytepos = Z_BYTE - ZV_BYTE;
17788 w->window_end_pos = Z - ZV;
17789 w->window_end_vpos = 0;
17792 /* But that is not valid info until redisplay finishes. */
17793 w->window_end_valid = false;
17794 return 1;
17799 /************************************************************************
17800 Window redisplay reusing current matrix when buffer has not changed
17801 ************************************************************************/
17803 /* Try redisplay of window W showing an unchanged buffer with a
17804 different window start than the last time it was displayed by
17805 reusing its current matrix. Value is true if successful.
17806 W->start is the new window start. */
17808 static bool
17809 try_window_reusing_current_matrix (struct window *w)
17811 struct frame *f = XFRAME (w->frame);
17812 struct glyph_row *bottom_row;
17813 struct it it;
17814 struct run run;
17815 struct text_pos start, new_start;
17816 int nrows_scrolled, i;
17817 struct glyph_row *last_text_row;
17818 struct glyph_row *last_reused_text_row;
17819 struct glyph_row *start_row;
17820 int start_vpos, min_y, max_y;
17822 #ifdef GLYPH_DEBUG
17823 if (inhibit_try_window_reusing)
17824 return false;
17825 #endif
17827 if (/* This function doesn't handle terminal frames. */
17828 !FRAME_WINDOW_P (f)
17829 /* Don't try to reuse the display if windows have been split
17830 or such. */
17831 || windows_or_buffers_changed
17832 || f->cursor_type_changed
17833 /* This function cannot handle buffers where the overlay arrow
17834 is shown on the fringes, because if the arrow position
17835 changes, we cannot just reuse the current matrix. */
17836 || overlay_arrow_in_current_buffer_p ())
17837 return false;
17839 /* Can't do this if showing trailing whitespace. */
17840 if (!NILP (Vshow_trailing_whitespace))
17841 return false;
17843 /* If top-line visibility has changed, give up. */
17844 if (window_wants_header_line (w)
17845 != MATRIX_HEADER_LINE_ROW (w->current_matrix)->mode_line_p)
17846 return false;
17848 /* Give up if old or new display is scrolled vertically. We could
17849 make this function handle this, but right now it doesn't. */
17850 start_row = MATRIX_FIRST_TEXT_ROW (w->current_matrix);
17851 if (w->vscroll || MATRIX_ROW_PARTIALLY_VISIBLE_P (w, start_row))
17852 return false;
17854 /* Clear the desired matrix for the display below. */
17855 clear_glyph_matrix (w->desired_matrix);
17857 /* Give up if line numbers are being displayed, because reusing the
17858 current matrix might use the wrong width for line-number
17859 display. */
17860 if (!NILP (Vdisplay_line_numbers))
17861 return false;
17863 /* The variable new_start now holds the new window start. The old
17864 start `start' can be determined from the current matrix. */
17865 SET_TEXT_POS_FROM_MARKER (new_start, w->start);
17866 start = start_row->minpos;
17867 start_vpos = MATRIX_ROW_VPOS (start_row, w->current_matrix);
17869 if (CHARPOS (new_start) <= CHARPOS (start))
17871 /* Don't use this method if the display starts with an ellipsis
17872 displayed for invisible text. It's not easy to handle that case
17873 below, and it's certainly not worth the effort since this is
17874 not a frequent case. */
17875 if (in_ellipses_for_invisible_text_p (&start_row->start, w))
17876 return false;
17878 IF_DEBUG (debug_method_add (w, "twu1"));
17880 /* Display up to a row that can be reused. The variable
17881 last_text_row is set to the last row displayed that displays
17882 text. Note that it.vpos == 0 if or if not there is a
17883 header-line; it's not the same as the MATRIX_ROW_VPOS! */
17884 start_display (&it, w, new_start);
17885 w->cursor.vpos = -1;
17886 last_text_row = last_reused_text_row = NULL;
17888 while (it.current_y < it.last_visible_y && !f->fonts_changed)
17890 /* If we have reached into the characters in the START row,
17891 that means the line boundaries have changed. So we
17892 can't start copying with the row START. Maybe it will
17893 work to start copying with the following row. */
17894 while (IT_CHARPOS (it) > CHARPOS (start))
17896 /* Advance to the next row as the "start". */
17897 start_row++;
17898 start = start_row->minpos;
17899 /* If there are no more rows to try, or just one, give up. */
17900 if (start_row == MATRIX_MODE_LINE_ROW (w->current_matrix) - 1
17901 || w->vscroll || MATRIX_ROW_PARTIALLY_VISIBLE_P (w, start_row)
17902 || CHARPOS (start) == ZV)
17904 clear_glyph_matrix (w->desired_matrix);
17905 return false;
17908 start_vpos = MATRIX_ROW_VPOS (start_row, w->current_matrix);
17910 /* If we have reached alignment, we can copy the rest of the
17911 rows. */
17912 if (IT_CHARPOS (it) == CHARPOS (start)
17913 /* Don't accept "alignment" inside a display vector,
17914 since start_row could have started in the middle of
17915 that same display vector (thus their character
17916 positions match), and we have no way of telling if
17917 that is the case. */
17918 && it.current.dpvec_index < 0)
17919 break;
17921 it.glyph_row->reversed_p = false;
17922 if (display_line (&it, -1))
17923 last_text_row = it.glyph_row - 1;
17927 /* A value of current_y < last_visible_y means that we stopped
17928 at the previous window start, which in turn means that we
17929 have at least one reusable row. */
17930 if (it.current_y < it.last_visible_y)
17932 struct glyph_row *row;
17934 /* IT.vpos always starts from 0; it counts text lines. */
17935 nrows_scrolled = it.vpos - (start_row - MATRIX_FIRST_TEXT_ROW (w->current_matrix));
17937 /* Find PT if not already found in the lines displayed. */
17938 if (w->cursor.vpos < 0)
17940 int dy = it.current_y - start_row->y;
17942 row = MATRIX_FIRST_TEXT_ROW (w->current_matrix);
17943 row = row_containing_pos (w, PT, row, NULL, dy);
17944 if (row)
17945 set_cursor_from_row (w, row, w->current_matrix, 0, 0,
17946 dy, nrows_scrolled);
17947 else
17949 clear_glyph_matrix (w->desired_matrix);
17950 return false;
17954 /* Scroll the display. Do it before the current matrix is
17955 changed. The problem here is that update has not yet
17956 run, i.e. part of the current matrix is not up to date.
17957 scroll_run_hook will clear the cursor, and use the
17958 current matrix to get the height of the row the cursor is
17959 in. */
17960 run.current_y = start_row->y;
17961 run.desired_y = it.current_y;
17962 run.height = it.last_visible_y - it.current_y;
17964 if (run.height > 0 && run.current_y != run.desired_y)
17966 update_begin (f);
17967 FRAME_RIF (f)->update_window_begin_hook (w);
17968 FRAME_RIF (f)->clear_window_mouse_face (w);
17969 FRAME_RIF (f)->scroll_run_hook (w, &run);
17970 FRAME_RIF (f)->update_window_end_hook (w, false, false);
17971 update_end (f);
17974 /* Shift current matrix down by nrows_scrolled lines. */
17975 bottom_row = MATRIX_BOTTOM_TEXT_ROW (w->current_matrix, w);
17976 rotate_matrix (w->current_matrix,
17977 start_vpos,
17978 MATRIX_ROW_VPOS (bottom_row, w->current_matrix),
17979 nrows_scrolled);
17981 /* Disable lines that must be updated. */
17982 for (i = 0; i < nrows_scrolled; ++i)
17983 (start_row + i)->enabled_p = false;
17985 /* Re-compute Y positions. */
17986 min_y = WINDOW_HEADER_LINE_HEIGHT (w);
17987 max_y = it.last_visible_y;
17988 for (row = start_row + nrows_scrolled;
17989 row < bottom_row;
17990 ++row)
17992 row->y = it.current_y;
17993 row->visible_height = row->height;
17995 if (row->y < min_y)
17996 row->visible_height -= min_y - row->y;
17997 if (row->y + row->height > max_y)
17998 row->visible_height -= row->y + row->height - max_y;
17999 if (row->fringe_bitmap_periodic_p)
18000 row->redraw_fringe_bitmaps_p = true;
18002 it.current_y += row->height;
18004 if (MATRIX_ROW_DISPLAYS_TEXT_P (row))
18005 last_reused_text_row = row;
18006 if (MATRIX_ROW_BOTTOM_Y (row) >= it.last_visible_y)
18007 break;
18010 /* Disable lines in the current matrix which are now
18011 below the window. */
18012 for (++row; row < bottom_row; ++row)
18013 row->enabled_p = row->mode_line_p = false;
18016 /* Update window_end_pos etc.; last_reused_text_row is the last
18017 reused row from the current matrix containing text, if any.
18018 The value of last_text_row is the last displayed line
18019 containing text. */
18020 if (last_reused_text_row)
18021 adjust_window_ends (w, last_reused_text_row, true);
18022 else if (last_text_row)
18023 adjust_window_ends (w, last_text_row, false);
18024 else
18026 /* This window must be completely empty. */
18027 w->window_end_bytepos = Z_BYTE - ZV_BYTE;
18028 w->window_end_pos = Z - ZV;
18029 w->window_end_vpos = 0;
18031 w->window_end_valid = false;
18033 /* Update hint: don't try scrolling again in update_window. */
18034 w->desired_matrix->no_scrolling_p = true;
18036 #ifdef GLYPH_DEBUG
18037 debug_method_add (w, "try_window_reusing_current_matrix 1");
18038 #endif
18039 return true;
18041 else if (CHARPOS (new_start) > CHARPOS (start))
18043 struct glyph_row *pt_row, *row;
18044 struct glyph_row *first_reusable_row;
18045 struct glyph_row *first_row_to_display;
18046 int dy;
18047 int yb = window_text_bottom_y (w);
18049 /* Find the row starting at new_start, if there is one. Don't
18050 reuse a partially visible line at the end. */
18051 first_reusable_row = start_row;
18052 while (first_reusable_row->enabled_p
18053 && MATRIX_ROW_BOTTOM_Y (first_reusable_row) < yb
18054 && (MATRIX_ROW_START_CHARPOS (first_reusable_row)
18055 < CHARPOS (new_start)))
18056 ++first_reusable_row;
18058 /* Give up if there is no row to reuse. */
18059 if (MATRIX_ROW_BOTTOM_Y (first_reusable_row) >= yb
18060 || !first_reusable_row->enabled_p
18061 || (MATRIX_ROW_START_CHARPOS (first_reusable_row)
18062 != CHARPOS (new_start)))
18063 return false;
18065 /* We can reuse fully visible rows beginning with
18066 first_reusable_row to the end of the window. Set
18067 first_row_to_display to the first row that cannot be reused.
18068 Set pt_row to the row containing point, if there is any. */
18069 pt_row = NULL;
18070 for (first_row_to_display = first_reusable_row;
18071 MATRIX_ROW_BOTTOM_Y (first_row_to_display) < yb;
18072 ++first_row_to_display)
18074 if (PT >= MATRIX_ROW_START_CHARPOS (first_row_to_display)
18075 && (PT < MATRIX_ROW_END_CHARPOS (first_row_to_display)
18076 || (PT == MATRIX_ROW_END_CHARPOS (first_row_to_display)
18077 && first_row_to_display->ends_at_zv_p
18078 && pt_row == NULL)))
18079 pt_row = first_row_to_display;
18082 /* Start displaying at the start of first_row_to_display. */
18083 eassert (first_row_to_display->y < yb);
18084 init_to_row_start (&it, w, first_row_to_display);
18086 nrows_scrolled = (MATRIX_ROW_VPOS (first_reusable_row, w->current_matrix)
18087 - start_vpos);
18088 it.vpos = (MATRIX_ROW_VPOS (first_row_to_display, w->current_matrix)
18089 - nrows_scrolled);
18090 it.current_y = (first_row_to_display->y - first_reusable_row->y
18091 + WINDOW_HEADER_LINE_HEIGHT (w));
18093 /* Display lines beginning with first_row_to_display in the
18094 desired matrix. Set last_text_row to the last row displayed
18095 that displays text. */
18096 it.glyph_row = MATRIX_ROW (w->desired_matrix, it.vpos);
18097 if (pt_row == NULL)
18098 w->cursor.vpos = -1;
18099 last_text_row = NULL;
18100 while (it.current_y < it.last_visible_y && !f->fonts_changed)
18101 if (display_line (&it, w->cursor.vpos))
18102 last_text_row = it.glyph_row - 1;
18104 /* If point is in a reused row, adjust y and vpos of the cursor
18105 position. */
18106 if (pt_row)
18108 w->cursor.vpos -= nrows_scrolled;
18109 w->cursor.y -= first_reusable_row->y - start_row->y;
18112 /* Give up if point isn't in a row displayed or reused. (This
18113 also handles the case where w->cursor.vpos < nrows_scrolled
18114 after the calls to display_line, which can happen with scroll
18115 margins. See bug#1295.) */
18116 if (w->cursor.vpos < 0)
18118 clear_glyph_matrix (w->desired_matrix);
18119 return false;
18122 /* Scroll the display. */
18123 run.current_y = first_reusable_row->y;
18124 run.desired_y = WINDOW_HEADER_LINE_HEIGHT (w);
18125 run.height = it.last_visible_y - run.current_y;
18126 dy = run.current_y - run.desired_y;
18128 if (run.height)
18130 update_begin (f);
18131 FRAME_RIF (f)->update_window_begin_hook (w);
18132 FRAME_RIF (f)->clear_window_mouse_face (w);
18133 FRAME_RIF (f)->scroll_run_hook (w, &run);
18134 FRAME_RIF (f)->update_window_end_hook (w, false, false);
18135 update_end (f);
18138 /* Adjust Y positions of reused rows. */
18139 bottom_row = MATRIX_BOTTOM_TEXT_ROW (w->current_matrix, w);
18140 min_y = WINDOW_HEADER_LINE_HEIGHT (w);
18141 max_y = it.last_visible_y;
18142 for (row = first_reusable_row; row < first_row_to_display; ++row)
18144 row->y -= dy;
18145 row->visible_height = row->height;
18146 if (row->y < min_y)
18147 row->visible_height -= min_y - row->y;
18148 if (row->y + row->height > max_y)
18149 row->visible_height -= row->y + row->height - max_y;
18150 if (row->fringe_bitmap_periodic_p)
18151 row->redraw_fringe_bitmaps_p = true;
18154 /* Scroll the current matrix. */
18155 eassert (nrows_scrolled > 0);
18156 rotate_matrix (w->current_matrix,
18157 start_vpos,
18158 MATRIX_ROW_VPOS (bottom_row, w->current_matrix),
18159 -nrows_scrolled);
18161 /* Disable rows not reused. */
18162 for (row -= nrows_scrolled; row < bottom_row; ++row)
18163 row->enabled_p = false;
18165 /* Point may have moved to a different line, so we cannot assume that
18166 the previous cursor position is valid; locate the correct row. */
18167 if (pt_row)
18169 for (row = MATRIX_ROW (w->current_matrix, w->cursor.vpos);
18170 row < bottom_row
18171 && PT >= MATRIX_ROW_END_CHARPOS (row)
18172 && !row->ends_at_zv_p;
18173 row++)
18175 w->cursor.vpos++;
18176 w->cursor.y = row->y;
18178 if (row < bottom_row)
18180 /* Can't simply scan the row for point with
18181 bidi-reordered glyph rows. Let set_cursor_from_row
18182 figure out where to put the cursor, and if it fails,
18183 give up. */
18184 if (!NILP (BVAR (XBUFFER (w->contents), bidi_display_reordering)))
18186 if (!set_cursor_from_row (w, row, w->current_matrix,
18187 0, 0, 0, 0))
18189 clear_glyph_matrix (w->desired_matrix);
18190 return false;
18193 else
18195 struct glyph *glyph = row->glyphs[TEXT_AREA] + w->cursor.hpos;
18196 struct glyph *end = row->glyphs[TEXT_AREA] + row->used[TEXT_AREA];
18198 for (; glyph < end
18199 && (!BUFFERP (glyph->object)
18200 || glyph->charpos < PT);
18201 glyph++)
18203 w->cursor.hpos++;
18204 w->cursor.x += glyph->pixel_width;
18210 /* Adjust window end. A null value of last_text_row means that
18211 the window end is in reused rows which in turn means that
18212 only its vpos can have changed. */
18213 if (last_text_row)
18214 adjust_window_ends (w, last_text_row, false);
18215 else
18216 w->window_end_vpos -= nrows_scrolled;
18218 w->window_end_valid = false;
18219 w->desired_matrix->no_scrolling_p = true;
18221 #ifdef GLYPH_DEBUG
18222 debug_method_add (w, "try_window_reusing_current_matrix 2");
18223 #endif
18224 return true;
18227 return false;
18232 /************************************************************************
18233 Window redisplay reusing current matrix when buffer has changed
18234 ************************************************************************/
18236 static struct glyph_row *find_last_unchanged_at_beg_row (struct window *);
18237 static struct glyph_row *find_first_unchanged_at_end_row (struct window *,
18238 ptrdiff_t *, ptrdiff_t *);
18239 static struct glyph_row *
18240 find_last_row_displaying_text (struct glyph_matrix *, struct it *,
18241 struct glyph_row *);
18244 /* Return the last row in MATRIX displaying text. If row START is
18245 non-null, start searching with that row. IT gives the dimensions
18246 of the display. Value is null if matrix is empty; otherwise it is
18247 a pointer to the row found. */
18249 static struct glyph_row *
18250 find_last_row_displaying_text (struct glyph_matrix *matrix, struct it *it,
18251 struct glyph_row *start)
18253 struct glyph_row *row, *row_found;
18255 /* Set row_found to the last row in IT->w's current matrix
18256 displaying text. The loop looks funny but think of partially
18257 visible lines. */
18258 row_found = NULL;
18259 row = start ? start : MATRIX_FIRST_TEXT_ROW (matrix);
18260 while (MATRIX_ROW_DISPLAYS_TEXT_P (row))
18262 eassert (row->enabled_p);
18263 row_found = row;
18264 if (MATRIX_ROW_BOTTOM_Y (row) >= it->last_visible_y)
18265 break;
18266 ++row;
18269 return row_found;
18273 /* Return the last row in the current matrix of W that is not affected
18274 by changes at the start of current_buffer that occurred since W's
18275 current matrix was built. Value is null if no such row exists.
18277 BEG_UNCHANGED us the number of characters unchanged at the start of
18278 current_buffer. BEG + BEG_UNCHANGED is the buffer position of the
18279 first changed character in current_buffer. Characters at positions <
18280 BEG + BEG_UNCHANGED are at the same buffer positions as they were
18281 when the current matrix was built. */
18283 static struct glyph_row *
18284 find_last_unchanged_at_beg_row (struct window *w)
18286 ptrdiff_t first_changed_pos = BEG + BEG_UNCHANGED;
18287 struct glyph_row *row;
18288 struct glyph_row *row_found = NULL;
18289 int yb = window_text_bottom_y (w);
18291 /* Find the last row displaying unchanged text. */
18292 for (row = MATRIX_FIRST_TEXT_ROW (w->current_matrix);
18293 MATRIX_ROW_DISPLAYS_TEXT_P (row)
18294 && MATRIX_ROW_START_CHARPOS (row) < first_changed_pos;
18295 ++row)
18297 if (/* If row ends before first_changed_pos, it is unchanged,
18298 except in some case. */
18299 MATRIX_ROW_END_CHARPOS (row) <= first_changed_pos
18300 /* When row ends in ZV and we write at ZV it is not
18301 unchanged. */
18302 && !row->ends_at_zv_p
18303 /* When first_changed_pos is the end of a continued line,
18304 row is not unchanged because it may be no longer
18305 continued. */
18306 && !(MATRIX_ROW_END_CHARPOS (row) == first_changed_pos
18307 && (row->continued_p
18308 || row->exact_window_width_line_p))
18309 /* If ROW->end is beyond ZV, then ROW->end is outdated and
18310 needs to be recomputed, so don't consider this row as
18311 unchanged. This happens when the last line was
18312 bidi-reordered and was killed immediately before this
18313 redisplay cycle. In that case, ROW->end stores the
18314 buffer position of the first visual-order character of
18315 the killed text, which is now beyond ZV. */
18316 && CHARPOS (row->end.pos) <= ZV)
18317 row_found = row;
18319 /* Stop if last visible row. */
18320 if (MATRIX_ROW_BOTTOM_Y (row) >= yb)
18321 break;
18324 return row_found;
18328 /* Find the first glyph row in the current matrix of W that is not
18329 affected by changes at the end of current_buffer since the
18330 time W's current matrix was built.
18332 Return in *DELTA the number of chars by which buffer positions in
18333 unchanged text at the end of current_buffer must be adjusted.
18335 Return in *DELTA_BYTES the corresponding number of bytes.
18337 Value is null if no such row exists, i.e. all rows are affected by
18338 changes. */
18340 static struct glyph_row *
18341 find_first_unchanged_at_end_row (struct window *w,
18342 ptrdiff_t *delta, ptrdiff_t *delta_bytes)
18344 struct glyph_row *row;
18345 struct glyph_row *row_found = NULL;
18347 *delta = *delta_bytes = 0;
18349 /* Display must not have been paused, otherwise the current matrix
18350 is not up to date. */
18351 eassert (w->window_end_valid);
18353 /* A value of window_end_pos >= END_UNCHANGED means that the window
18354 end is in the range of changed text. If so, there is no
18355 unchanged row at the end of W's current matrix. */
18356 if (w->window_end_pos >= END_UNCHANGED)
18357 return NULL;
18359 /* Set row to the last row in W's current matrix displaying text. */
18360 row = MATRIX_ROW (w->current_matrix, w->window_end_vpos);
18362 /* If matrix is entirely empty, no unchanged row exists. */
18363 if (MATRIX_ROW_DISPLAYS_TEXT_P (row))
18365 /* The value of row is the last glyph row in the matrix having a
18366 meaningful buffer position in it. The end position of row
18367 corresponds to window_end_pos. This allows us to translate
18368 buffer positions in the current matrix to current buffer
18369 positions for characters not in changed text. */
18370 ptrdiff_t Z_old =
18371 MATRIX_ROW_END_CHARPOS (row) + w->window_end_pos;
18372 ptrdiff_t Z_BYTE_old =
18373 MATRIX_ROW_END_BYTEPOS (row) + w->window_end_bytepos;
18374 ptrdiff_t last_unchanged_pos, last_unchanged_pos_old;
18375 struct glyph_row *first_text_row
18376 = MATRIX_FIRST_TEXT_ROW (w->current_matrix);
18378 *delta = Z - Z_old;
18379 *delta_bytes = Z_BYTE - Z_BYTE_old;
18381 /* Set last_unchanged_pos to the buffer position of the last
18382 character in the buffer that has not been changed. Z is the
18383 index + 1 of the last character in current_buffer, i.e. by
18384 subtracting END_UNCHANGED we get the index of the last
18385 unchanged character, and we have to add BEG to get its buffer
18386 position. */
18387 last_unchanged_pos = Z - END_UNCHANGED + BEG;
18388 last_unchanged_pos_old = last_unchanged_pos - *delta;
18390 /* Search backward from ROW for a row displaying a line that
18391 starts at a minimum position >= last_unchanged_pos_old. */
18392 for (; row > first_text_row; --row)
18394 /* This used to abort, but it can happen.
18395 It is ok to just stop the search instead here. KFS. */
18396 if (!row->enabled_p || !MATRIX_ROW_DISPLAYS_TEXT_P (row))
18397 break;
18399 if (MATRIX_ROW_START_CHARPOS (row) >= last_unchanged_pos_old)
18400 row_found = row;
18404 eassert (!row_found || MATRIX_ROW_DISPLAYS_TEXT_P (row_found));
18406 return row_found;
18410 /* Make sure that glyph rows in the current matrix of window W
18411 reference the same glyph memory as corresponding rows in the
18412 frame's frame matrix. This function is called after scrolling W's
18413 current matrix on a terminal frame in try_window_id and
18414 try_window_reusing_current_matrix. */
18416 static void
18417 sync_frame_with_window_matrix_rows (struct window *w)
18419 struct frame *f = XFRAME (w->frame);
18420 struct glyph_row *window_row, *window_row_end, *frame_row;
18422 /* Preconditions: W must be a leaf window and full-width. Its frame
18423 must have a frame matrix. */
18424 eassert (BUFFERP (w->contents));
18425 eassert (WINDOW_FULL_WIDTH_P (w));
18426 eassert (!FRAME_WINDOW_P (f));
18428 /* If W is a full-width window, glyph pointers in W's current matrix
18429 have, by definition, to be the same as glyph pointers in the
18430 corresponding frame matrix. Note that frame matrices have no
18431 marginal areas (see build_frame_matrix). */
18432 window_row = w->current_matrix->rows;
18433 window_row_end = window_row + w->current_matrix->nrows;
18434 frame_row = f->current_matrix->rows + WINDOW_TOP_EDGE_LINE (w);
18435 while (window_row < window_row_end)
18437 struct glyph *start = window_row->glyphs[LEFT_MARGIN_AREA];
18438 struct glyph *end = window_row->glyphs[LAST_AREA];
18440 frame_row->glyphs[LEFT_MARGIN_AREA] = start;
18441 frame_row->glyphs[TEXT_AREA] = start;
18442 frame_row->glyphs[RIGHT_MARGIN_AREA] = end;
18443 frame_row->glyphs[LAST_AREA] = end;
18445 /* Disable frame rows whose corresponding window rows have
18446 been disabled in try_window_id. */
18447 if (!window_row->enabled_p)
18448 frame_row->enabled_p = false;
18450 ++window_row, ++frame_row;
18455 /* Find the glyph row in window W containing CHARPOS. Consider all
18456 rows between START and END (not inclusive). END null means search
18457 all rows to the end of the display area of W. Value is the row
18458 containing CHARPOS or null. */
18460 struct glyph_row *
18461 row_containing_pos (struct window *w, ptrdiff_t charpos,
18462 struct glyph_row *start, struct glyph_row *end, int dy)
18464 struct glyph_row *row = start;
18465 struct glyph_row *best_row = NULL;
18466 ptrdiff_t mindif = BUF_ZV (XBUFFER (w->contents)) + 1;
18467 int last_y;
18469 /* If we happen to start on a header-line, skip that. */
18470 if (row->mode_line_p)
18471 ++row;
18473 if ((end && row >= end) || !row->enabled_p)
18474 return NULL;
18476 last_y = window_text_bottom_y (w) - dy;
18478 while (true)
18480 /* Give up if we have gone too far. */
18481 if ((end && row >= end) || !row->enabled_p)
18482 return NULL;
18483 /* This formerly returned if they were equal.
18484 I think that both quantities are of a "last plus one" type;
18485 if so, when they are equal, the row is within the screen. -- rms. */
18486 if (MATRIX_ROW_BOTTOM_Y (row) > last_y)
18487 return NULL;
18489 /* If it is in this row, return this row. */
18490 if (! (MATRIX_ROW_END_CHARPOS (row) < charpos
18491 || (MATRIX_ROW_END_CHARPOS (row) == charpos
18492 /* The end position of a row equals the start
18493 position of the next row. If CHARPOS is there, we
18494 would rather consider it displayed in the next
18495 line, except when this line ends in ZV. */
18496 && !row_for_charpos_p (row, charpos)))
18497 && charpos >= MATRIX_ROW_START_CHARPOS (row))
18499 struct glyph *g;
18501 if (NILP (BVAR (XBUFFER (w->contents), bidi_display_reordering))
18502 || (!best_row && !row->continued_p))
18503 return row;
18504 /* In bidi-reordered rows, there could be several rows whose
18505 edges surround CHARPOS, all of these rows belonging to
18506 the same continued line. We need to find the row which
18507 fits CHARPOS the best. */
18508 for (g = row->glyphs[TEXT_AREA];
18509 g < row->glyphs[TEXT_AREA] + row->used[TEXT_AREA];
18510 g++)
18512 if (!STRINGP (g->object))
18514 if (g->charpos > 0 && eabs (g->charpos - charpos) < mindif)
18516 mindif = eabs (g->charpos - charpos);
18517 best_row = row;
18518 /* Exact match always wins. */
18519 if (mindif == 0)
18520 return best_row;
18525 else if (best_row && !row->continued_p)
18526 return best_row;
18527 ++row;
18532 /* Try to redisplay window W by reusing its existing display. W's
18533 current matrix must be up to date when this function is called,
18534 i.e., window_end_valid must be true.
18536 Value is
18538 >= 1 if successful, i.e. display has been updated
18539 specifically:
18540 1 means the changes were in front of a newline that precedes
18541 the window start, and the whole current matrix was reused
18542 2 means the changes were after the last position displayed
18543 in the window, and the whole current matrix was reused
18544 3 means portions of the current matrix were reused, while
18545 some of the screen lines were redrawn
18546 -1 if redisplay with same window start is known not to succeed
18547 0 if otherwise unsuccessful
18549 The following steps are performed:
18551 1. Find the last row in the current matrix of W that is not
18552 affected by changes at the start of current_buffer. If no such row
18553 is found, give up.
18555 2. Find the first row in W's current matrix that is not affected by
18556 changes at the end of current_buffer. Maybe there is no such row.
18558 3. Display lines beginning with the row + 1 found in step 1 to the
18559 row found in step 2 or, if step 2 didn't find a row, to the end of
18560 the window.
18562 4. If cursor is not known to appear on the window, give up.
18564 5. If display stopped at the row found in step 2, scroll the
18565 display and current matrix as needed.
18567 6. Maybe display some lines at the end of W, if we must. This can
18568 happen under various circumstances, like a partially visible line
18569 becoming fully visible, or because newly displayed lines are displayed
18570 in smaller font sizes.
18572 7. Update W's window end information. */
18574 static int
18575 try_window_id (struct window *w)
18577 struct frame *f = XFRAME (w->frame);
18578 struct glyph_matrix *current_matrix = w->current_matrix;
18579 struct glyph_matrix *desired_matrix = w->desired_matrix;
18580 struct glyph_row *last_unchanged_at_beg_row;
18581 struct glyph_row *first_unchanged_at_end_row;
18582 struct glyph_row *row;
18583 struct glyph_row *bottom_row;
18584 int bottom_vpos;
18585 struct it it;
18586 ptrdiff_t delta = 0, delta_bytes = 0, stop_pos;
18587 int dvpos, dy;
18588 struct text_pos start_pos;
18589 struct run run;
18590 int first_unchanged_at_end_vpos = 0;
18591 struct glyph_row *last_text_row, *last_text_row_at_end;
18592 struct text_pos start;
18593 ptrdiff_t first_changed_charpos, last_changed_charpos;
18595 #ifdef GLYPH_DEBUG
18596 if (inhibit_try_window_id)
18597 return 0;
18598 #endif
18600 /* This is handy for debugging. */
18601 #if false
18602 #define GIVE_UP(X) \
18603 do { \
18604 TRACE ((stderr, "try_window_id give up %d\n", (X))); \
18605 return 0; \
18606 } while (false)
18607 #else
18608 #define GIVE_UP(X) return 0
18609 #endif
18611 SET_TEXT_POS_FROM_MARKER (start, w->start);
18613 /* Don't use this for mini-windows because these can show
18614 messages and mini-buffers, and we don't handle that here. */
18615 if (MINI_WINDOW_P (w))
18616 GIVE_UP (1);
18618 /* This flag is used to prevent redisplay optimizations. */
18619 if (windows_or_buffers_changed || f->cursor_type_changed)
18620 GIVE_UP (2);
18622 /* This function's optimizations cannot be used if overlays have
18623 changed in the buffer displayed by the window, so give up if they
18624 have. */
18625 if (w->last_overlay_modified != OVERLAY_MODIFF)
18626 GIVE_UP (200);
18628 /* Verify that narrowing has not changed.
18629 Also verify that we were not told to prevent redisplay optimizations.
18630 It would be nice to further
18631 reduce the number of cases where this prevents try_window_id. */
18632 if (current_buffer->clip_changed
18633 || current_buffer->prevent_redisplay_optimizations_p)
18634 GIVE_UP (3);
18636 /* Window must either use window-based redisplay or be full width. */
18637 if (!FRAME_WINDOW_P (f)
18638 && (!FRAME_LINE_INS_DEL_OK (f)
18639 || !WINDOW_FULL_WIDTH_P (w)))
18640 GIVE_UP (4);
18642 /* Give up if point is known NOT to appear in W. */
18643 if (PT < CHARPOS (start))
18644 GIVE_UP (5);
18646 /* Another way to prevent redisplay optimizations. */
18647 if (w->last_modified == 0)
18648 GIVE_UP (6);
18650 /* Verify that window is not hscrolled. */
18651 if (w->hscroll != 0)
18652 GIVE_UP (7);
18654 /* Verify that display wasn't paused. */
18655 if (!w->window_end_valid)
18656 GIVE_UP (8);
18658 /* Likewise if highlighting trailing whitespace. */
18659 if (!NILP (Vshow_trailing_whitespace))
18660 GIVE_UP (11);
18662 /* Can't use this if overlay arrow position and/or string have
18663 changed. */
18664 if (overlay_arrows_changed_p (false))
18665 GIVE_UP (12);
18667 /* When word-wrap is on, adding a space to the first word of a
18668 wrapped line can change the wrap position, altering the line
18669 above it. It might be worthwhile to handle this more
18670 intelligently, but for now just redisplay from scratch. */
18671 if (!NILP (BVAR (XBUFFER (w->contents), word_wrap)))
18672 GIVE_UP (21);
18674 /* Under bidi reordering, adding or deleting a character in the
18675 beginning of a paragraph, before the first strong directional
18676 character, can change the base direction of the paragraph (unless
18677 the buffer specifies a fixed paragraph direction), which will
18678 require redisplaying the whole paragraph. It might be worthwhile
18679 to find the paragraph limits and widen the range of redisplayed
18680 lines to that, but for now just give up this optimization and
18681 redisplay from scratch. */
18682 if (!NILP (BVAR (XBUFFER (w->contents), bidi_display_reordering))
18683 && NILP (BVAR (XBUFFER (w->contents), bidi_paragraph_direction)))
18684 GIVE_UP (22);
18686 /* Give up if the buffer has line-spacing set, as Lisp-level changes
18687 to that variable require thorough redisplay. */
18688 if (!NILP (BVAR (XBUFFER (w->contents), extra_line_spacing)))
18689 GIVE_UP (23);
18691 /* Give up if display-line-numbers is in relative mode, or when the
18692 current line's number needs to be displayed in a distinct face. */
18693 if (EQ (Vdisplay_line_numbers, Qrelative)
18694 || EQ (Vdisplay_line_numbers, Qvisual)
18695 || (!NILP (Vdisplay_line_numbers)
18696 && NILP (Finternal_lisp_face_equal_p (Qline_number,
18697 Qline_number_current_line,
18698 w->frame))))
18699 GIVE_UP (24);
18701 /* Make sure beg_unchanged and end_unchanged are up to date. Do it
18702 only if buffer has really changed. The reason is that the gap is
18703 initially at Z for freshly visited files. The code below would
18704 set end_unchanged to 0 in that case. */
18705 if (MODIFF > SAVE_MODIFF
18706 /* This seems to happen sometimes after saving a buffer. */
18707 || BEG_UNCHANGED + END_UNCHANGED > Z_BYTE)
18709 if (GPT - BEG < BEG_UNCHANGED)
18710 BEG_UNCHANGED = GPT - BEG;
18711 if (Z - GPT < END_UNCHANGED)
18712 END_UNCHANGED = Z - GPT;
18715 /* The position of the first and last character that has been changed. */
18716 first_changed_charpos = BEG + BEG_UNCHANGED;
18717 last_changed_charpos = Z - END_UNCHANGED;
18719 /* If window starts after a line end, and the last change is in
18720 front of that newline, then changes don't affect the display.
18721 This case happens with stealth-fontification. Note that although
18722 the display is unchanged, glyph positions in the matrix have to
18723 be adjusted, of course. */
18724 row = MATRIX_ROW (w->current_matrix, w->window_end_vpos);
18725 if (MATRIX_ROW_DISPLAYS_TEXT_P (row)
18726 && ((last_changed_charpos < CHARPOS (start)
18727 && CHARPOS (start) == BEGV)
18728 || (last_changed_charpos < CHARPOS (start) - 1
18729 && FETCH_BYTE (BYTEPOS (start) - 1) == '\n')))
18731 ptrdiff_t Z_old, Z_delta, Z_BYTE_old, Z_delta_bytes;
18732 struct glyph_row *r0;
18734 /* Compute how many chars/bytes have been added to or removed
18735 from the buffer. */
18736 Z_old = MATRIX_ROW_END_CHARPOS (row) + w->window_end_pos;
18737 Z_BYTE_old = MATRIX_ROW_END_BYTEPOS (row) + w->window_end_bytepos;
18738 Z_delta = Z - Z_old;
18739 Z_delta_bytes = Z_BYTE - Z_BYTE_old;
18741 /* Give up if PT is not in the window. Note that it already has
18742 been checked at the start of try_window_id that PT is not in
18743 front of the window start. */
18744 if (PT >= MATRIX_ROW_END_CHARPOS (row) + Z_delta)
18745 GIVE_UP (13);
18747 /* If window start is unchanged, we can reuse the whole matrix
18748 as is, after adjusting glyph positions. No need to compute
18749 the window end again, since its offset from Z hasn't changed. */
18750 r0 = MATRIX_FIRST_TEXT_ROW (current_matrix);
18751 if (CHARPOS (start) == MATRIX_ROW_START_CHARPOS (r0) + Z_delta
18752 && BYTEPOS (start) == MATRIX_ROW_START_BYTEPOS (r0) + Z_delta_bytes
18753 /* PT must not be in a partially visible line. */
18754 && !(PT >= MATRIX_ROW_START_CHARPOS (row) + Z_delta
18755 && MATRIX_ROW_BOTTOM_Y (row) > window_text_bottom_y (w)))
18757 /* Adjust positions in the glyph matrix. */
18758 if (Z_delta || Z_delta_bytes)
18760 struct glyph_row *r1
18761 = MATRIX_BOTTOM_TEXT_ROW (current_matrix, w);
18762 increment_matrix_positions (w->current_matrix,
18763 MATRIX_ROW_VPOS (r0, current_matrix),
18764 MATRIX_ROW_VPOS (r1, current_matrix),
18765 Z_delta, Z_delta_bytes);
18768 /* Set the cursor. */
18769 row = row_containing_pos (w, PT, r0, NULL, 0);
18770 if (row)
18771 set_cursor_from_row (w, row, current_matrix, 0, 0, 0, 0);
18772 return 1;
18776 /* Handle the case that changes are all below what is displayed in
18777 the window, and that PT is in the window. This shortcut cannot
18778 be taken if ZV is visible in the window, and text has been added
18779 there that is visible in the window. */
18780 if (first_changed_charpos >= MATRIX_ROW_END_CHARPOS (row)
18781 /* ZV is not visible in the window, or there are no
18782 changes at ZV, actually. */
18783 && (current_matrix->zv > MATRIX_ROW_END_CHARPOS (row)
18784 || first_changed_charpos == last_changed_charpos))
18786 struct glyph_row *r0;
18788 /* Give up if PT is not in the window. Note that it already has
18789 been checked at the start of try_window_id that PT is not in
18790 front of the window start. */
18791 if (PT >= MATRIX_ROW_END_CHARPOS (row))
18792 GIVE_UP (14);
18794 /* If window start is unchanged, we can reuse the whole matrix
18795 as is, without changing glyph positions since no text has
18796 been added/removed in front of the window end. */
18797 r0 = MATRIX_FIRST_TEXT_ROW (current_matrix);
18798 if (TEXT_POS_EQUAL_P (start, r0->minpos)
18799 /* PT must not be in a partially visible line. */
18800 && !(PT >= MATRIX_ROW_START_CHARPOS (row)
18801 && MATRIX_ROW_BOTTOM_Y (row) > window_text_bottom_y (w)))
18803 /* We have to compute the window end anew since text
18804 could have been added/removed after it. */
18805 w->window_end_pos = Z - MATRIX_ROW_END_CHARPOS (row);
18806 w->window_end_bytepos = Z_BYTE - MATRIX_ROW_END_BYTEPOS (row);
18808 /* Set the cursor. */
18809 row = row_containing_pos (w, PT, r0, NULL, 0);
18810 if (row)
18811 set_cursor_from_row (w, row, current_matrix, 0, 0, 0, 0);
18812 return 2;
18816 /* Give up if window start is in the changed area.
18818 The condition used to read
18820 (BEG_UNCHANGED + END_UNCHANGED != Z - BEG && ...)
18822 but why that was tested escapes me at the moment. */
18823 if (CHARPOS (start) >= first_changed_charpos
18824 && CHARPOS (start) <= last_changed_charpos)
18825 GIVE_UP (15);
18827 /* Check that window start agrees with the start of the first glyph
18828 row in its current matrix. Check this after we know the window
18829 start is not in changed text, otherwise positions would not be
18830 comparable. */
18831 row = MATRIX_FIRST_TEXT_ROW (current_matrix);
18832 if (!TEXT_POS_EQUAL_P (start, row->minpos))
18833 GIVE_UP (16);
18835 /* Give up if the window ends in strings. Overlay strings
18836 at the end are difficult to handle, so don't try. */
18837 row = MATRIX_ROW (current_matrix, w->window_end_vpos);
18838 if (MATRIX_ROW_START_CHARPOS (row) == MATRIX_ROW_END_CHARPOS (row))
18839 GIVE_UP (20);
18841 /* Compute the position at which we have to start displaying new
18842 lines. Some of the lines at the top of the window might be
18843 reusable because they are not displaying changed text. Find the
18844 last row in W's current matrix not affected by changes at the
18845 start of current_buffer. Value is null if changes start in the
18846 first line of window. */
18847 last_unchanged_at_beg_row = find_last_unchanged_at_beg_row (w);
18848 if (last_unchanged_at_beg_row)
18850 /* Avoid starting to display in the middle of a character, a TAB
18851 for instance. This is easier than to set up the iterator
18852 exactly, and it's not a frequent case, so the additional
18853 effort wouldn't really pay off. */
18854 while ((MATRIX_ROW_ENDS_IN_MIDDLE_OF_CHAR_P (last_unchanged_at_beg_row)
18855 || last_unchanged_at_beg_row->ends_in_newline_from_string_p)
18856 && last_unchanged_at_beg_row > w->current_matrix->rows)
18857 --last_unchanged_at_beg_row;
18859 if (MATRIX_ROW_ENDS_IN_MIDDLE_OF_CHAR_P (last_unchanged_at_beg_row))
18860 GIVE_UP (17);
18862 if (! init_to_row_end (&it, w, last_unchanged_at_beg_row))
18863 GIVE_UP (18);
18864 start_pos = it.current.pos;
18866 /* Start displaying new lines in the desired matrix at the same
18867 vpos we would use in the current matrix, i.e. below
18868 last_unchanged_at_beg_row. */
18869 it.vpos = 1 + MATRIX_ROW_VPOS (last_unchanged_at_beg_row,
18870 current_matrix);
18871 it.glyph_row = MATRIX_ROW (desired_matrix, it.vpos);
18872 it.current_y = MATRIX_ROW_BOTTOM_Y (last_unchanged_at_beg_row);
18874 eassert (it.hpos == 0 && it.current_x == 0);
18876 else
18878 /* There are no reusable lines at the start of the window.
18879 Start displaying in the first text line. */
18880 start_display (&it, w, start);
18881 it.vpos = it.first_vpos;
18882 start_pos = it.current.pos;
18885 /* Find the first row that is not affected by changes at the end of
18886 the buffer. Value will be null if there is no unchanged row, in
18887 which case we must redisplay to the end of the window. delta
18888 will be set to the value by which buffer positions beginning with
18889 first_unchanged_at_end_row have to be adjusted due to text
18890 changes. */
18891 first_unchanged_at_end_row
18892 = find_first_unchanged_at_end_row (w, &delta, &delta_bytes);
18893 IF_DEBUG (debug_delta = delta);
18894 IF_DEBUG (debug_delta_bytes = delta_bytes);
18896 /* Set stop_pos to the buffer position up to which we will have to
18897 display new lines. If first_unchanged_at_end_row != NULL, this
18898 is the buffer position of the start of the line displayed in that
18899 row. For first_unchanged_at_end_row == NULL, use 0 to indicate
18900 that we don't stop at a buffer position. */
18901 stop_pos = 0;
18902 if (first_unchanged_at_end_row)
18904 eassert (last_unchanged_at_beg_row == NULL
18905 || first_unchanged_at_end_row >= last_unchanged_at_beg_row);
18907 /* If this is a continuation line, move forward to the next one
18908 that isn't. Changes in lines above affect this line.
18909 Caution: this may move first_unchanged_at_end_row to a row
18910 not displaying text. */
18911 while (MATRIX_ROW_CONTINUATION_LINE_P (first_unchanged_at_end_row)
18912 && MATRIX_ROW_DISPLAYS_TEXT_P (first_unchanged_at_end_row)
18913 && (MATRIX_ROW_BOTTOM_Y (first_unchanged_at_end_row)
18914 < it.last_visible_y))
18915 ++first_unchanged_at_end_row;
18917 if (!MATRIX_ROW_DISPLAYS_TEXT_P (first_unchanged_at_end_row)
18918 || (MATRIX_ROW_BOTTOM_Y (first_unchanged_at_end_row)
18919 >= it.last_visible_y))
18920 first_unchanged_at_end_row = NULL;
18921 else
18923 stop_pos = (MATRIX_ROW_START_CHARPOS (first_unchanged_at_end_row)
18924 + delta);
18925 first_unchanged_at_end_vpos
18926 = MATRIX_ROW_VPOS (first_unchanged_at_end_row, current_matrix);
18927 eassert (stop_pos >= Z - END_UNCHANGED);
18930 else if (last_unchanged_at_beg_row == NULL)
18931 GIVE_UP (19);
18934 #ifdef GLYPH_DEBUG
18936 /* Either there is no unchanged row at the end, or the one we have
18937 now displays text. This is a necessary condition for the window
18938 end pos calculation at the end of this function. */
18939 eassert (first_unchanged_at_end_row == NULL
18940 || MATRIX_ROW_DISPLAYS_TEXT_P (first_unchanged_at_end_row));
18942 debug_last_unchanged_at_beg_vpos
18943 = (last_unchanged_at_beg_row
18944 ? MATRIX_ROW_VPOS (last_unchanged_at_beg_row, current_matrix)
18945 : -1);
18946 debug_first_unchanged_at_end_vpos = first_unchanged_at_end_vpos;
18948 #endif /* GLYPH_DEBUG */
18951 /* Display new lines. Set last_text_row to the last new line
18952 displayed which has text on it, i.e. might end up as being the
18953 line where the window_end_vpos is. */
18954 w->cursor.vpos = -1;
18955 last_text_row = NULL;
18956 overlay_arrow_seen = false;
18957 if (it.current_y < it.last_visible_y
18958 && !f->fonts_changed
18959 && (first_unchanged_at_end_row == NULL
18960 || IT_CHARPOS (it) < stop_pos))
18961 it.glyph_row->reversed_p = false;
18962 while (it.current_y < it.last_visible_y
18963 && !f->fonts_changed
18964 && (first_unchanged_at_end_row == NULL
18965 || IT_CHARPOS (it) < stop_pos))
18967 if (display_line (&it, -1))
18968 last_text_row = it.glyph_row - 1;
18971 if (f->fonts_changed)
18972 return -1;
18974 /* The redisplay iterations in display_line above could have
18975 triggered font-lock, which could have done something that
18976 invalidates IT->w window's end-point information, on which we
18977 rely below. E.g., one package, which will remain unnamed, used
18978 to install a font-lock-fontify-region-function that called
18979 bury-buffer, whose side effect is to switch the buffer displayed
18980 by IT->w, and that predictably resets IT->w's window_end_valid
18981 flag, which we already tested at the entry to this function.
18982 Amply punish such packages/modes by giving up on this
18983 optimization in those cases. */
18984 if (!w->window_end_valid)
18986 clear_glyph_matrix (w->desired_matrix);
18987 return -1;
18990 /* Compute differences in buffer positions, y-positions etc. for
18991 lines reused at the bottom of the window. Compute what we can
18992 scroll. */
18993 if (first_unchanged_at_end_row
18994 /* No lines reused because we displayed everything up to the
18995 bottom of the window. */
18996 && it.current_y < it.last_visible_y)
18998 dvpos = (it.vpos
18999 - MATRIX_ROW_VPOS (first_unchanged_at_end_row,
19000 current_matrix));
19001 dy = it.current_y - first_unchanged_at_end_row->y;
19002 run.current_y = first_unchanged_at_end_row->y;
19003 run.desired_y = run.current_y + dy;
19004 run.height = it.last_visible_y - max (run.current_y, run.desired_y);
19006 else
19008 delta = delta_bytes = dvpos = dy
19009 = run.current_y = run.desired_y = run.height = 0;
19010 first_unchanged_at_end_row = NULL;
19012 IF_DEBUG ((debug_dvpos = dvpos, debug_dy = dy));
19015 /* Find the cursor if not already found. We have to decide whether
19016 PT will appear on this window (it sometimes doesn't, but this is
19017 not a very frequent case.) This decision has to be made before
19018 the current matrix is altered. A value of cursor.vpos < 0 means
19019 that PT is either in one of the lines beginning at
19020 first_unchanged_at_end_row or below the window. Don't care for
19021 lines that might be displayed later at the window end; as
19022 mentioned, this is not a frequent case. */
19023 if (w->cursor.vpos < 0)
19025 /* Cursor in unchanged rows at the top? */
19026 if (PT < CHARPOS (start_pos)
19027 && last_unchanged_at_beg_row)
19029 row = row_containing_pos (w, PT,
19030 MATRIX_FIRST_TEXT_ROW (w->current_matrix),
19031 last_unchanged_at_beg_row + 1, 0);
19032 if (row)
19033 set_cursor_from_row (w, row, w->current_matrix, 0, 0, 0, 0);
19036 /* Start from first_unchanged_at_end_row looking for PT. */
19037 else if (first_unchanged_at_end_row)
19039 row = row_containing_pos (w, PT - delta,
19040 first_unchanged_at_end_row, NULL, 0);
19041 if (row)
19042 set_cursor_from_row (w, row, w->current_matrix, delta,
19043 delta_bytes, dy, dvpos);
19046 /* Give up if cursor was not found. */
19047 if (w->cursor.vpos < 0)
19049 clear_glyph_matrix (w->desired_matrix);
19050 return -1;
19054 /* Don't let the cursor end in the scroll margins. */
19056 int this_scroll_margin = window_scroll_margin (w, MARGIN_IN_PIXELS);
19057 int cursor_height = MATRIX_ROW (w->desired_matrix, w->cursor.vpos)->height;
19059 if ((w->cursor.y < this_scroll_margin
19060 && CHARPOS (start) > BEGV)
19061 /* Old redisplay didn't take scroll margin into account at the bottom,
19062 but then global-hl-line-mode doesn't scroll. KFS 2004-06-14 */
19063 || (w->cursor.y + (make_cursor_line_fully_visible_p
19064 ? cursor_height + this_scroll_margin
19065 : 1)) > it.last_visible_y)
19067 w->cursor.vpos = -1;
19068 clear_glyph_matrix (w->desired_matrix);
19069 return -1;
19073 /* Scroll the display. Do it before changing the current matrix so
19074 that xterm.c doesn't get confused about where the cursor glyph is
19075 found. */
19076 if (dy && run.height)
19078 update_begin (f);
19080 if (FRAME_WINDOW_P (f))
19082 FRAME_RIF (f)->update_window_begin_hook (w);
19083 FRAME_RIF (f)->clear_window_mouse_face (w);
19084 FRAME_RIF (f)->scroll_run_hook (w, &run);
19085 FRAME_RIF (f)->update_window_end_hook (w, false, false);
19087 else
19089 /* Terminal frame. In this case, dvpos gives the number of
19090 lines to scroll by; dvpos < 0 means scroll up. */
19091 int from_vpos
19092 = MATRIX_ROW_VPOS (first_unchanged_at_end_row, w->current_matrix);
19093 int from = WINDOW_TOP_EDGE_LINE (w) + from_vpos;
19094 int end = (WINDOW_TOP_EDGE_LINE (w)
19095 + window_wants_header_line (w)
19096 + window_internal_height (w));
19098 #if defined (HAVE_GPM) || defined (MSDOS)
19099 x_clear_window_mouse_face (w);
19100 #endif
19101 /* Perform the operation on the screen. */
19102 if (dvpos > 0)
19104 /* Scroll last_unchanged_at_beg_row to the end of the
19105 window down dvpos lines. */
19106 set_terminal_window (f, end);
19108 /* On dumb terminals delete dvpos lines at the end
19109 before inserting dvpos empty lines. */
19110 if (!FRAME_SCROLL_REGION_OK (f))
19111 ins_del_lines (f, end - dvpos, -dvpos);
19113 /* Insert dvpos empty lines in front of
19114 last_unchanged_at_beg_row. */
19115 ins_del_lines (f, from, dvpos);
19117 else if (dvpos < 0)
19119 /* Scroll up last_unchanged_at_beg_vpos to the end of
19120 the window to last_unchanged_at_beg_vpos - |dvpos|. */
19121 set_terminal_window (f, end);
19123 /* Delete dvpos lines in front of
19124 last_unchanged_at_beg_vpos. ins_del_lines will set
19125 the cursor to the given vpos and emit |dvpos| delete
19126 line sequences. */
19127 ins_del_lines (f, from + dvpos, dvpos);
19129 /* On a dumb terminal insert dvpos empty lines at the
19130 end. */
19131 if (!FRAME_SCROLL_REGION_OK (f))
19132 ins_del_lines (f, end + dvpos, -dvpos);
19135 set_terminal_window (f, 0);
19138 update_end (f);
19141 /* Shift reused rows of the current matrix to the right position.
19142 BOTTOM_ROW is the last + 1 row in the current matrix reserved for
19143 text. */
19144 bottom_row = MATRIX_BOTTOM_TEXT_ROW (current_matrix, w);
19145 bottom_vpos = MATRIX_ROW_VPOS (bottom_row, current_matrix);
19146 if (dvpos < 0)
19148 rotate_matrix (current_matrix, first_unchanged_at_end_vpos + dvpos,
19149 bottom_vpos, dvpos);
19150 clear_glyph_matrix_rows (current_matrix, bottom_vpos + dvpos,
19151 bottom_vpos);
19153 else if (dvpos > 0)
19155 rotate_matrix (current_matrix, first_unchanged_at_end_vpos,
19156 bottom_vpos, dvpos);
19157 clear_glyph_matrix_rows (current_matrix, first_unchanged_at_end_vpos,
19158 first_unchanged_at_end_vpos + dvpos);
19161 /* For frame-based redisplay, make sure that current frame and window
19162 matrix are in sync with respect to glyph memory. */
19163 if (!FRAME_WINDOW_P (f))
19164 sync_frame_with_window_matrix_rows (w);
19166 /* Adjust buffer positions in reused rows. */
19167 if (delta || delta_bytes)
19168 increment_matrix_positions (current_matrix,
19169 first_unchanged_at_end_vpos + dvpos,
19170 bottom_vpos, delta, delta_bytes);
19172 /* Adjust Y positions. */
19173 if (dy)
19174 shift_glyph_matrix (w, current_matrix,
19175 first_unchanged_at_end_vpos + dvpos,
19176 bottom_vpos, dy);
19178 if (first_unchanged_at_end_row)
19180 first_unchanged_at_end_row += dvpos;
19181 if (first_unchanged_at_end_row->y >= it.last_visible_y
19182 || !MATRIX_ROW_DISPLAYS_TEXT_P (first_unchanged_at_end_row))
19183 first_unchanged_at_end_row = NULL;
19186 /* If scrolling up, there may be some lines to display at the end of
19187 the window. */
19188 last_text_row_at_end = NULL;
19189 if (dy < 0)
19191 /* Scrolling up can leave for example a partially visible line
19192 at the end of the window to be redisplayed. */
19193 /* Set last_row to the glyph row in the current matrix where the
19194 window end line is found. It has been moved up or down in
19195 the matrix by dvpos. */
19196 int last_vpos = w->window_end_vpos + dvpos;
19197 struct glyph_row *last_row = MATRIX_ROW (current_matrix, last_vpos);
19199 /* If last_row is the window end line, it should display text. */
19200 eassert (MATRIX_ROW_DISPLAYS_TEXT_P (last_row));
19202 /* If window end line was partially visible before, begin
19203 displaying at that line. Otherwise begin displaying with the
19204 line following it. */
19205 if (MATRIX_ROW_BOTTOM_Y (last_row) - dy >= it.last_visible_y)
19207 init_to_row_start (&it, w, last_row);
19208 it.vpos = last_vpos;
19209 it.current_y = last_row->y;
19211 else
19213 init_to_row_end (&it, w, last_row);
19214 it.vpos = 1 + last_vpos;
19215 it.current_y = MATRIX_ROW_BOTTOM_Y (last_row);
19216 ++last_row;
19219 /* We may start in a continuation line. If so, we have to
19220 get the right continuation_lines_width and current_x. */
19221 it.continuation_lines_width = last_row->continuation_lines_width;
19222 it.hpos = it.current_x = 0;
19224 /* Display the rest of the lines at the window end. */
19225 it.glyph_row = MATRIX_ROW (desired_matrix, it.vpos);
19226 while (it.current_y < it.last_visible_y && !f->fonts_changed)
19228 /* Is it always sure that the display agrees with lines in
19229 the current matrix? I don't think so, so we mark rows
19230 displayed invalid in the current matrix by setting their
19231 enabled_p flag to false. */
19232 SET_MATRIX_ROW_ENABLED_P (w->current_matrix, it.vpos, false);
19233 if (display_line (&it, w->cursor.vpos))
19234 last_text_row_at_end = it.glyph_row - 1;
19238 /* Update window_end_pos and window_end_vpos. */
19239 if (first_unchanged_at_end_row && !last_text_row_at_end)
19241 /* Window end line if one of the preserved rows from the current
19242 matrix. Set row to the last row displaying text in current
19243 matrix starting at first_unchanged_at_end_row, after
19244 scrolling. */
19245 eassert (MATRIX_ROW_DISPLAYS_TEXT_P (first_unchanged_at_end_row));
19246 row = find_last_row_displaying_text (w->current_matrix, &it,
19247 first_unchanged_at_end_row);
19248 eassume (row && MATRIX_ROW_DISPLAYS_TEXT_P (row));
19249 adjust_window_ends (w, row, true);
19250 eassert (w->window_end_bytepos >= 0);
19251 IF_DEBUG (debug_method_add (w, "A"));
19253 else if (last_text_row_at_end)
19255 adjust_window_ends (w, last_text_row_at_end, false);
19256 eassert (w->window_end_bytepos >= 0);
19257 IF_DEBUG (debug_method_add (w, "B"));
19259 else if (last_text_row)
19261 /* We have displayed either to the end of the window or at the
19262 end of the window, i.e. the last row with text is to be found
19263 in the desired matrix. */
19264 adjust_window_ends (w, last_text_row, false);
19265 eassert (w->window_end_bytepos >= 0);
19267 else if (first_unchanged_at_end_row == NULL
19268 && last_text_row == NULL
19269 && last_text_row_at_end == NULL)
19271 /* Displayed to end of window, but no line containing text was
19272 displayed. Lines were deleted at the end of the window. */
19273 bool first_vpos = window_wants_header_line (w);
19274 int vpos = w->window_end_vpos;
19275 struct glyph_row *current_row = current_matrix->rows + vpos;
19276 struct glyph_row *desired_row = desired_matrix->rows + vpos;
19278 for (row = NULL; !row; --vpos, --current_row, --desired_row)
19280 eassert (first_vpos <= vpos);
19281 if (desired_row->enabled_p)
19283 if (MATRIX_ROW_DISPLAYS_TEXT_P (desired_row))
19284 row = desired_row;
19286 else if (MATRIX_ROW_DISPLAYS_TEXT_P (current_row))
19287 row = current_row;
19290 w->window_end_vpos = vpos + 1;
19291 w->window_end_pos = Z - MATRIX_ROW_END_CHARPOS (row);
19292 w->window_end_bytepos = Z_BYTE - MATRIX_ROW_END_BYTEPOS (row);
19293 eassert (w->window_end_bytepos >= 0);
19294 IF_DEBUG (debug_method_add (w, "C"));
19296 else
19297 emacs_abort ();
19299 IF_DEBUG ((debug_end_pos = w->window_end_pos,
19300 debug_end_vpos = w->window_end_vpos));
19302 /* Record that display has not been completed. */
19303 w->window_end_valid = false;
19304 w->desired_matrix->no_scrolling_p = true;
19305 return 3;
19307 #undef GIVE_UP
19312 /***********************************************************************
19313 More debugging support
19314 ***********************************************************************/
19316 #ifdef GLYPH_DEBUG
19318 void dump_glyph_row (struct glyph_row *, int, int) EXTERNALLY_VISIBLE;
19319 void dump_glyph_matrix (struct glyph_matrix *, int) EXTERNALLY_VISIBLE;
19320 void dump_glyph (struct glyph_row *, struct glyph *, int) EXTERNALLY_VISIBLE;
19323 /* Dump the contents of glyph matrix MATRIX on stderr.
19325 GLYPHS 0 means don't show glyph contents.
19326 GLYPHS 1 means show glyphs in short form
19327 GLYPHS > 1 means show glyphs in long form. */
19329 void
19330 dump_glyph_matrix (struct glyph_matrix *matrix, int glyphs)
19332 int i;
19333 for (i = 0; i < matrix->nrows; ++i)
19334 dump_glyph_row (MATRIX_ROW (matrix, i), i, glyphs);
19338 /* Dump contents of glyph GLYPH to stderr. ROW and AREA are
19339 the glyph row and area where the glyph comes from. */
19341 void
19342 dump_glyph (struct glyph_row *row, struct glyph *glyph, int area)
19344 if (glyph->type == CHAR_GLYPH
19345 || glyph->type == GLYPHLESS_GLYPH)
19347 fprintf (stderr,
19348 " %5"pD"d %c %9"pD"d %c %3d 0x%06x %c %4d %1.1d%1.1d\n",
19349 glyph - row->glyphs[TEXT_AREA],
19350 (glyph->type == CHAR_GLYPH
19351 ? 'C'
19352 : 'G'),
19353 glyph->charpos,
19354 (BUFFERP (glyph->object)
19355 ? 'B'
19356 : (STRINGP (glyph->object)
19357 ? 'S'
19358 : (NILP (glyph->object)
19359 ? '0'
19360 : '-'))),
19361 glyph->pixel_width,
19362 glyph->u.ch,
19363 (glyph->u.ch < 0x80 && glyph->u.ch >= ' '
19364 ? (int) glyph->u.ch
19365 : '.'),
19366 glyph->face_id,
19367 glyph->left_box_line_p,
19368 glyph->right_box_line_p);
19370 else if (glyph->type == STRETCH_GLYPH)
19372 fprintf (stderr,
19373 " %5"pD"d %c %9"pD"d %c %3d 0x%06x %c %4d %1.1d%1.1d\n",
19374 glyph - row->glyphs[TEXT_AREA],
19375 'S',
19376 glyph->charpos,
19377 (BUFFERP (glyph->object)
19378 ? 'B'
19379 : (STRINGP (glyph->object)
19380 ? 'S'
19381 : (NILP (glyph->object)
19382 ? '0'
19383 : '-'))),
19384 glyph->pixel_width,
19386 ' ',
19387 glyph->face_id,
19388 glyph->left_box_line_p,
19389 glyph->right_box_line_p);
19391 else if (glyph->type == IMAGE_GLYPH)
19393 fprintf (stderr,
19394 " %5"pD"d %c %9"pD"d %c %3d 0x%06x %c %4d %1.1d%1.1d\n",
19395 glyph - row->glyphs[TEXT_AREA],
19396 'I',
19397 glyph->charpos,
19398 (BUFFERP (glyph->object)
19399 ? 'B'
19400 : (STRINGP (glyph->object)
19401 ? 'S'
19402 : (NILP (glyph->object)
19403 ? '0'
19404 : '-'))),
19405 glyph->pixel_width,
19406 (unsigned int) glyph->u.img_id,
19407 '.',
19408 glyph->face_id,
19409 glyph->left_box_line_p,
19410 glyph->right_box_line_p);
19412 else if (glyph->type == COMPOSITE_GLYPH)
19414 fprintf (stderr,
19415 " %5"pD"d %c %9"pD"d %c %3d 0x%06x",
19416 glyph - row->glyphs[TEXT_AREA],
19417 '+',
19418 glyph->charpos,
19419 (BUFFERP (glyph->object)
19420 ? 'B'
19421 : (STRINGP (glyph->object)
19422 ? 'S'
19423 : (NILP (glyph->object)
19424 ? '0'
19425 : '-'))),
19426 glyph->pixel_width,
19427 (unsigned int) glyph->u.cmp.id);
19428 if (glyph->u.cmp.automatic)
19429 fprintf (stderr,
19430 "[%d-%d]",
19431 glyph->slice.cmp.from, glyph->slice.cmp.to);
19432 fprintf (stderr, " . %4d %1.1d%1.1d\n",
19433 glyph->face_id,
19434 glyph->left_box_line_p,
19435 glyph->right_box_line_p);
19437 else if (glyph->type == XWIDGET_GLYPH)
19439 #ifndef HAVE_XWIDGETS
19440 eassume (false);
19441 #else
19442 fprintf (stderr,
19443 " %5d %4c %6d %c %3d 0x%05x %c %4d %1.1d%1.1d\n",
19444 glyph - row->glyphs[TEXT_AREA],
19445 'X',
19446 glyph->charpos,
19447 (BUFFERP (glyph->object)
19448 ? 'B'
19449 : (STRINGP (glyph->object)
19450 ? 'S'
19451 : '-')),
19452 glyph->pixel_width,
19453 glyph->u.xwidget,
19454 '.',
19455 glyph->face_id,
19456 glyph->left_box_line_p,
19457 glyph->right_box_line_p);
19458 #endif
19463 /* Dump the contents of glyph row at VPOS in MATRIX to stderr.
19464 GLYPHS 0 means don't show glyph contents.
19465 GLYPHS 1 means show glyphs in short form
19466 GLYPHS > 1 means show glyphs in long form. */
19468 void
19469 dump_glyph_row (struct glyph_row *row, int vpos, int glyphs)
19471 if (glyphs != 1)
19473 fprintf (stderr, "Row Start End Used oE><\\CTZFesm X Y W H V A P\n");
19474 fprintf (stderr, "==============================================================================\n");
19476 fprintf (stderr, "%3d %9"pD"d %9"pD"d %4d %1.1d%1.1d%1.1d%1.1d\
19477 %1.1d%1.1d%1.1d%1.1d%1.1d%1.1d%1.1d%1.1d %4d %4d %4d %4d %4d %4d %4d\n",
19478 vpos,
19479 MATRIX_ROW_START_CHARPOS (row),
19480 MATRIX_ROW_END_CHARPOS (row),
19481 row->used[TEXT_AREA],
19482 row->contains_overlapping_glyphs_p,
19483 row->enabled_p,
19484 row->truncated_on_left_p,
19485 row->truncated_on_right_p,
19486 row->continued_p,
19487 MATRIX_ROW_CONTINUATION_LINE_P (row),
19488 MATRIX_ROW_DISPLAYS_TEXT_P (row),
19489 row->ends_at_zv_p,
19490 row->fill_line_p,
19491 row->ends_in_middle_of_char_p,
19492 row->starts_in_middle_of_char_p,
19493 row->mouse_face_p,
19494 row->x,
19495 row->y,
19496 row->pixel_width,
19497 row->height,
19498 row->visible_height,
19499 row->ascent,
19500 row->phys_ascent);
19501 /* The next 3 lines should align to "Start" in the header. */
19502 fprintf (stderr, " %9"pD"d %9"pD"d\t%5d\n", row->start.overlay_string_index,
19503 row->end.overlay_string_index,
19504 row->continuation_lines_width);
19505 fprintf (stderr, " %9"pD"d %9"pD"d\n",
19506 CHARPOS (row->start.string_pos),
19507 CHARPOS (row->end.string_pos));
19508 fprintf (stderr, " %9d %9d\n", row->start.dpvec_index,
19509 row->end.dpvec_index);
19512 if (glyphs > 1)
19514 int area;
19516 for (area = LEFT_MARGIN_AREA; area < LAST_AREA; ++area)
19518 struct glyph *glyph = row->glyphs[area];
19519 struct glyph *glyph_end = glyph + row->used[area];
19521 /* Glyph for a line end in text. */
19522 if (area == TEXT_AREA && glyph == glyph_end && glyph->charpos > 0)
19523 ++glyph_end;
19525 if (glyph < glyph_end)
19526 fprintf (stderr, " Glyph# Type Pos O W Code C Face LR\n");
19528 for (; glyph < glyph_end; ++glyph)
19529 dump_glyph (row, glyph, area);
19532 else if (glyphs == 1)
19534 int area;
19535 char s[SHRT_MAX + 4];
19537 for (area = LEFT_MARGIN_AREA; area < LAST_AREA; ++area)
19539 int i;
19541 for (i = 0; i < row->used[area]; ++i)
19543 struct glyph *glyph = row->glyphs[area] + i;
19544 if (i == row->used[area] - 1
19545 && area == TEXT_AREA
19546 && NILP (glyph->object)
19547 && glyph->type == CHAR_GLYPH
19548 && glyph->u.ch == ' ')
19550 strcpy (&s[i], "[\\n]");
19551 i += 4;
19553 else if (glyph->type == CHAR_GLYPH
19554 && glyph->u.ch < 0x80
19555 && glyph->u.ch >= ' ')
19556 s[i] = glyph->u.ch;
19557 else
19558 s[i] = '.';
19561 s[i] = '\0';
19562 fprintf (stderr, "%3d: (%d) '%s'\n", vpos, row->enabled_p, s);
19568 DEFUN ("dump-glyph-matrix", Fdump_glyph_matrix,
19569 Sdump_glyph_matrix, 0, 1, "p",
19570 doc: /* Dump the current matrix of the selected window to stderr.
19571 Shows contents of glyph row structures. With non-nil
19572 parameter GLYPHS, dump glyphs as well. If GLYPHS is 1 show
19573 glyphs in short form, otherwise show glyphs in long form.
19575 Interactively, no argument means show glyphs in short form;
19576 with numeric argument, its value is passed as the GLYPHS flag. */)
19577 (Lisp_Object glyphs)
19579 struct window *w = XWINDOW (selected_window);
19580 struct buffer *buffer = XBUFFER (w->contents);
19582 fprintf (stderr, "PT = %"pD"d, BEGV = %"pD"d. ZV = %"pD"d\n",
19583 BUF_PT (buffer), BUF_BEGV (buffer), BUF_ZV (buffer));
19584 fprintf (stderr, "Cursor x = %d, y = %d, hpos = %d, vpos = %d\n",
19585 w->cursor.x, w->cursor.y, w->cursor.hpos, w->cursor.vpos);
19586 fprintf (stderr, "=============================================\n");
19587 dump_glyph_matrix (w->current_matrix,
19588 TYPE_RANGED_INTEGERP (int, glyphs) ? XINT (glyphs) : 0);
19589 return Qnil;
19593 DEFUN ("dump-frame-glyph-matrix", Fdump_frame_glyph_matrix,
19594 Sdump_frame_glyph_matrix, 0, 0, "", doc: /* Dump the current glyph matrix of the selected frame to stderr.
19595 Only text-mode frames have frame glyph matrices. */)
19596 (void)
19598 struct frame *f = XFRAME (selected_frame);
19600 if (f->current_matrix)
19601 dump_glyph_matrix (f->current_matrix, 1);
19602 else
19603 fprintf (stderr, "*** This frame doesn't have a frame glyph matrix ***\n");
19604 return Qnil;
19608 DEFUN ("dump-glyph-row", Fdump_glyph_row, Sdump_glyph_row, 1, 2, "P",
19609 doc: /* Dump glyph row ROW to stderr.
19610 Interactively, ROW is the prefix numeric argument and defaults to
19611 the row which displays point.
19612 Optional argument GLYPHS 0 means don't dump glyphs.
19613 GLYPHS 1 means dump glyphs in short form.
19614 GLYPHS > 1 or omitted means dump glyphs in long form. */)
19615 (Lisp_Object row, Lisp_Object glyphs)
19617 struct glyph_matrix *matrix;
19618 EMACS_INT vpos;
19620 if (NILP (row))
19622 int d1, d2, d3, d4, d5, ypos;
19623 bool visible_p = pos_visible_p (XWINDOW (selected_window), PT,
19624 &d1, &d2, &d3, &d4, &d5, &ypos);
19625 if (visible_p)
19626 vpos = ypos;
19627 else
19628 vpos = 0;
19630 else
19632 CHECK_NUMBER (row);
19633 vpos = XINT (row);
19635 matrix = XWINDOW (selected_window)->current_matrix;
19636 if (vpos >= 0 && vpos < matrix->nrows)
19637 dump_glyph_row (MATRIX_ROW (matrix, vpos),
19638 vpos,
19639 TYPE_RANGED_INTEGERP (int, glyphs) ? XINT (glyphs) : 2);
19640 return Qnil;
19644 DEFUN ("dump-tool-bar-row", Fdump_tool_bar_row, Sdump_tool_bar_row, 1, 2, "P",
19645 doc: /* Dump glyph row ROW of the tool-bar of the current frame to stderr.
19646 Interactively, ROW is the prefix numeric argument and defaults to zero.
19647 GLYPHS 0 means don't dump glyphs.
19648 GLYPHS 1 means dump glyphs in short form.
19649 GLYPHS > 1 or omitted means dump glyphs in long form.
19651 If there's no tool-bar, or if the tool-bar is not drawn by Emacs,
19652 do nothing. */)
19653 (Lisp_Object row, Lisp_Object glyphs)
19655 #if defined (HAVE_WINDOW_SYSTEM) && ! defined (USE_GTK) && ! defined (HAVE_NS)
19656 struct frame *sf = SELECTED_FRAME ();
19657 struct glyph_matrix *m = XWINDOW (sf->tool_bar_window)->current_matrix;
19658 EMACS_INT vpos;
19660 if (NILP (row))
19661 vpos = 0;
19662 else
19664 CHECK_NUMBER (row);
19665 vpos = XINT (row);
19667 if (vpos >= 0 && vpos < m->nrows)
19668 dump_glyph_row (MATRIX_ROW (m, vpos), vpos,
19669 TYPE_RANGED_INTEGERP (int, glyphs) ? XINT (glyphs) : 2);
19670 #endif
19671 return Qnil;
19675 DEFUN ("trace-redisplay", Ftrace_redisplay, Strace_redisplay, 0, 1, "P",
19676 doc: /* Toggle tracing of redisplay.
19677 With ARG, turn tracing on if and only if ARG is positive. */)
19678 (Lisp_Object arg)
19680 if (NILP (arg))
19681 trace_redisplay_p = !trace_redisplay_p;
19682 else
19684 arg = Fprefix_numeric_value (arg);
19685 trace_redisplay_p = XINT (arg) > 0;
19688 return Qnil;
19692 DEFUN ("trace-to-stderr", Ftrace_to_stderr, Strace_to_stderr, 1, MANY, "",
19693 doc: /* Like `format', but print result to stderr.
19694 usage: (trace-to-stderr STRING &rest OBJECTS) */)
19695 (ptrdiff_t nargs, Lisp_Object *args)
19697 Lisp_Object s = Fformat (nargs, args);
19698 fwrite (SDATA (s), 1, SBYTES (s), stderr);
19699 return Qnil;
19702 #endif /* GLYPH_DEBUG */
19706 /***********************************************************************
19707 Building Desired Matrix Rows
19708 ***********************************************************************/
19710 /* Return a temporary glyph row holding the glyphs of an overlay arrow.
19711 Used for non-window-redisplay windows, and for windows w/o left fringe. */
19713 static struct glyph_row *
19714 get_overlay_arrow_glyph_row (struct window *w, Lisp_Object overlay_arrow_string)
19716 struct frame *f = XFRAME (WINDOW_FRAME (w));
19717 struct buffer *buffer = XBUFFER (w->contents);
19718 struct buffer *old = current_buffer;
19719 const unsigned char *arrow_string = SDATA (overlay_arrow_string);
19720 ptrdiff_t arrow_len = SCHARS (overlay_arrow_string);
19721 const unsigned char *arrow_end = arrow_string + arrow_len;
19722 const unsigned char *p;
19723 struct it it;
19724 bool multibyte_p;
19725 int n_glyphs_before;
19727 set_buffer_temp (buffer);
19728 init_iterator (&it, w, -1, -1, &scratch_glyph_row, DEFAULT_FACE_ID);
19729 scratch_glyph_row.reversed_p = false;
19730 it.glyph_row->used[TEXT_AREA] = 0;
19731 SET_TEXT_POS (it.position, 0, 0);
19733 multibyte_p = !NILP (BVAR (buffer, enable_multibyte_characters));
19734 p = arrow_string;
19735 while (p < arrow_end)
19737 Lisp_Object face, ilisp;
19739 /* Get the next character. */
19740 if (multibyte_p)
19741 it.c = it.char_to_display = string_char_and_length (p, &it.len);
19742 else
19744 it.c = it.char_to_display = *p, it.len = 1;
19745 if (! ASCII_CHAR_P (it.c))
19746 it.char_to_display = BYTE8_TO_CHAR (it.c);
19748 p += it.len;
19750 /* Get its face. */
19751 ilisp = make_number (p - arrow_string);
19752 face = Fget_text_property (ilisp, Qface, overlay_arrow_string);
19753 it.face_id = compute_char_face (f, it.char_to_display, face);
19755 /* Compute its width, get its glyphs. */
19756 n_glyphs_before = it.glyph_row->used[TEXT_AREA];
19757 SET_TEXT_POS (it.position, -1, -1);
19758 PRODUCE_GLYPHS (&it);
19760 /* If this character doesn't fit any more in the line, we have
19761 to remove some glyphs. */
19762 if (it.current_x > it.last_visible_x)
19764 it.glyph_row->used[TEXT_AREA] = n_glyphs_before;
19765 break;
19769 set_buffer_temp (old);
19770 return it.glyph_row;
19774 /* Insert truncation glyphs at the start of IT->glyph_row. Which
19775 glyphs to insert is determined by produce_special_glyphs. */
19777 static void
19778 insert_left_trunc_glyphs (struct it *it)
19780 struct it truncate_it;
19781 struct glyph *from, *end, *to, *toend;
19783 eassert (!FRAME_WINDOW_P (it->f)
19784 || (!it->glyph_row->reversed_p
19785 && WINDOW_LEFT_FRINGE_WIDTH (it->w) == 0)
19786 || (it->glyph_row->reversed_p
19787 && WINDOW_RIGHT_FRINGE_WIDTH (it->w) == 0));
19789 /* Get the truncation glyphs. */
19790 truncate_it = *it;
19791 truncate_it.current_x = 0;
19792 truncate_it.face_id = DEFAULT_FACE_ID;
19793 truncate_it.glyph_row = &scratch_glyph_row;
19794 truncate_it.area = TEXT_AREA;
19795 truncate_it.glyph_row->used[TEXT_AREA] = 0;
19796 CHARPOS (truncate_it.position) = BYTEPOS (truncate_it.position) = -1;
19797 truncate_it.object = Qnil;
19798 produce_special_glyphs (&truncate_it, IT_TRUNCATION);
19800 /* Overwrite glyphs from IT with truncation glyphs. */
19801 if (!it->glyph_row->reversed_p)
19803 short tused = truncate_it.glyph_row->used[TEXT_AREA];
19805 from = truncate_it.glyph_row->glyphs[TEXT_AREA];
19806 end = from + tused;
19807 to = it->glyph_row->glyphs[TEXT_AREA];
19808 toend = to + it->glyph_row->used[TEXT_AREA];
19809 if (FRAME_WINDOW_P (it->f))
19811 /* On GUI frames, when variable-size fonts are displayed,
19812 the truncation glyphs may need more pixels than the row's
19813 glyphs they overwrite. We overwrite more glyphs to free
19814 enough screen real estate, and enlarge the stretch glyph
19815 on the right (see display_line), if there is one, to
19816 preserve the screen position of the truncation glyphs on
19817 the right. */
19818 int w = 0;
19819 struct glyph *g = to;
19820 short used;
19822 /* The first glyph could be partially visible, in which case
19823 it->glyph_row->x will be negative. But we want the left
19824 truncation glyphs to be aligned at the left margin of the
19825 window, so we override the x coordinate at which the row
19826 will begin. */
19827 it->glyph_row->x = 0;
19828 while (g < toend && w < it->truncation_pixel_width)
19830 w += g->pixel_width;
19831 ++g;
19833 if (g - to - tused > 0)
19835 memmove (to + tused, g, (toend - g) * sizeof(*g));
19836 it->glyph_row->used[TEXT_AREA] -= g - to - tused;
19838 used = it->glyph_row->used[TEXT_AREA];
19839 if (it->glyph_row->truncated_on_right_p
19840 && WINDOW_RIGHT_FRINGE_WIDTH (it->w) == 0
19841 && it->glyph_row->glyphs[TEXT_AREA][used - 2].type
19842 == STRETCH_GLYPH)
19844 int extra = w - it->truncation_pixel_width;
19846 it->glyph_row->glyphs[TEXT_AREA][used - 2].pixel_width += extra;
19850 while (from < end)
19851 *to++ = *from++;
19853 /* There may be padding glyphs left over. Overwrite them too. */
19854 if (!FRAME_WINDOW_P (it->f))
19856 while (to < toend && CHAR_GLYPH_PADDING_P (*to))
19858 from = truncate_it.glyph_row->glyphs[TEXT_AREA];
19859 while (from < end)
19860 *to++ = *from++;
19864 if (to > toend)
19865 it->glyph_row->used[TEXT_AREA] = to - it->glyph_row->glyphs[TEXT_AREA];
19867 else
19869 short tused = truncate_it.glyph_row->used[TEXT_AREA];
19871 /* In R2L rows, overwrite the last (rightmost) glyphs, and do
19872 that back to front. */
19873 end = truncate_it.glyph_row->glyphs[TEXT_AREA];
19874 from = end + truncate_it.glyph_row->used[TEXT_AREA] - 1;
19875 toend = it->glyph_row->glyphs[TEXT_AREA];
19876 to = toend + it->glyph_row->used[TEXT_AREA] - 1;
19877 if (FRAME_WINDOW_P (it->f))
19879 int w = 0;
19880 struct glyph *g = to;
19882 while (g >= toend && w < it->truncation_pixel_width)
19884 w += g->pixel_width;
19885 --g;
19887 if (to - g - tused > 0)
19888 to = g + tused;
19889 if (it->glyph_row->truncated_on_right_p
19890 && WINDOW_LEFT_FRINGE_WIDTH (it->w) == 0
19891 && it->glyph_row->glyphs[TEXT_AREA][1].type == STRETCH_GLYPH)
19893 int extra = w - it->truncation_pixel_width;
19895 it->glyph_row->glyphs[TEXT_AREA][1].pixel_width += extra;
19899 while (from >= end && to >= toend)
19900 *to-- = *from--;
19901 if (!FRAME_WINDOW_P (it->f))
19903 while (to >= toend && CHAR_GLYPH_PADDING_P (*to))
19905 from =
19906 truncate_it.glyph_row->glyphs[TEXT_AREA]
19907 + truncate_it.glyph_row->used[TEXT_AREA] - 1;
19908 while (from >= end && to >= toend)
19909 *to-- = *from--;
19912 if (from >= end)
19914 /* Need to free some room before prepending additional
19915 glyphs. */
19916 int move_by = from - end + 1;
19917 struct glyph *g0 = it->glyph_row->glyphs[TEXT_AREA];
19918 struct glyph *g = g0 + it->glyph_row->used[TEXT_AREA] - 1;
19920 for ( ; g >= g0; g--)
19921 g[move_by] = *g;
19922 while (from >= end)
19923 *to-- = *from--;
19924 it->glyph_row->used[TEXT_AREA] += move_by;
19929 /* Compute the hash code for ROW. */
19930 unsigned
19931 row_hash (struct glyph_row *row)
19933 int area, k;
19934 unsigned hashval = 0;
19936 for (area = LEFT_MARGIN_AREA; area < LAST_AREA; ++area)
19937 for (k = 0; k < row->used[area]; ++k)
19938 hashval = ((((hashval << 4) + (hashval >> 24)) & 0x0fffffff)
19939 + row->glyphs[area][k].u.val
19940 + row->glyphs[area][k].face_id
19941 + row->glyphs[area][k].padding_p
19942 + (row->glyphs[area][k].type << 2));
19944 return hashval;
19947 /* Compute the pixel height and width of IT->glyph_row.
19949 Most of the time, ascent and height of a display line will be equal
19950 to the max_ascent and max_height values of the display iterator
19951 structure. This is not the case if
19953 1. We hit ZV without displaying anything. In this case, max_ascent
19954 and max_height will be zero.
19956 2. We have some glyphs that don't contribute to the line height.
19957 (The glyph row flag contributes_to_line_height_p is for future
19958 pixmap extensions).
19960 The first case is easily covered by using default values because in
19961 these cases, the line height does not really matter, except that it
19962 must not be zero. */
19964 static void
19965 compute_line_metrics (struct it *it)
19967 struct glyph_row *row = it->glyph_row;
19969 if (FRAME_WINDOW_P (it->f))
19971 int i, min_y, max_y;
19973 /* The line may consist of one space only, that was added to
19974 place the cursor on it. If so, the row's height hasn't been
19975 computed yet. */
19976 if (row->height == 0)
19978 if (it->max_ascent + it->max_descent == 0)
19979 it->max_descent = it->max_phys_descent = FRAME_LINE_HEIGHT (it->f);
19980 row->ascent = it->max_ascent;
19981 row->height = it->max_ascent + it->max_descent;
19982 row->phys_ascent = it->max_phys_ascent;
19983 row->phys_height = it->max_phys_ascent + it->max_phys_descent;
19984 row->extra_line_spacing = it->max_extra_line_spacing;
19987 /* Compute the width of this line. */
19988 row->pixel_width = row->x;
19989 for (i = 0; i < row->used[TEXT_AREA]; ++i)
19990 row->pixel_width += row->glyphs[TEXT_AREA][i].pixel_width;
19992 eassert (row->pixel_width >= 0);
19993 eassert (row->ascent >= 0 && row->height > 0);
19995 row->overlapping_p = (MATRIX_ROW_OVERLAPS_SUCC_P (row)
19996 || MATRIX_ROW_OVERLAPS_PRED_P (row));
19998 /* If first line's physical ascent is larger than its logical
19999 ascent, use the physical ascent, and make the row taller.
20000 This makes accented characters fully visible. */
20001 if (row == MATRIX_FIRST_TEXT_ROW (it->w->desired_matrix)
20002 && row->phys_ascent > row->ascent)
20004 row->height += row->phys_ascent - row->ascent;
20005 row->ascent = row->phys_ascent;
20008 /* Compute how much of the line is visible. */
20009 row->visible_height = row->height;
20011 min_y = WINDOW_HEADER_LINE_HEIGHT (it->w);
20012 max_y = WINDOW_BOX_HEIGHT_NO_MODE_LINE (it->w);
20014 if (row->y < min_y)
20015 row->visible_height -= min_y - row->y;
20016 if (row->y + row->height > max_y)
20017 row->visible_height -= row->y + row->height - max_y;
20019 else
20021 row->pixel_width = row->used[TEXT_AREA];
20022 if (row->continued_p)
20023 row->pixel_width -= it->continuation_pixel_width;
20024 else if (row->truncated_on_right_p)
20025 row->pixel_width -= it->truncation_pixel_width;
20026 row->ascent = row->phys_ascent = 0;
20027 row->height = row->phys_height = row->visible_height = 1;
20028 row->extra_line_spacing = 0;
20031 /* Compute a hash code for this row. */
20032 row->hash = row_hash (row);
20034 it->max_ascent = it->max_descent = 0;
20035 it->max_phys_ascent = it->max_phys_descent = 0;
20039 /* Append one space to the glyph row of iterator IT if doing a
20040 window-based redisplay. The space has the same face as
20041 IT->face_id. Value is true if a space was added.
20043 This function is called to make sure that there is always one glyph
20044 at the end of a glyph row that the cursor can be set on under
20045 window-systems. (If there weren't such a glyph we would not know
20046 how wide and tall a box cursor should be displayed).
20048 At the same time this space let's a nicely handle clearing to the
20049 end of the line if the row ends in italic text. */
20051 static bool
20052 append_space_for_newline (struct it *it, bool default_face_p)
20054 if (FRAME_WINDOW_P (it->f))
20056 int n = it->glyph_row->used[TEXT_AREA];
20058 if (it->glyph_row->glyphs[TEXT_AREA] + n
20059 < it->glyph_row->glyphs[1 + TEXT_AREA])
20061 /* Save some values that must not be changed.
20062 Must save IT->c and IT->len because otherwise
20063 ITERATOR_AT_END_P wouldn't work anymore after
20064 append_space_for_newline has been called. */
20065 enum display_element_type saved_what = it->what;
20066 int saved_c = it->c, saved_len = it->len;
20067 int saved_char_to_display = it->char_to_display;
20068 int saved_x = it->current_x;
20069 int saved_face_id = it->face_id;
20070 bool saved_box_end = it->end_of_box_run_p;
20071 struct text_pos saved_pos;
20072 Lisp_Object saved_object;
20073 struct face *face;
20075 saved_object = it->object;
20076 saved_pos = it->position;
20078 it->what = IT_CHARACTER;
20079 memset (&it->position, 0, sizeof it->position);
20080 it->object = Qnil;
20081 it->c = it->char_to_display = ' ';
20082 it->len = 1;
20084 /* If the default face was remapped, be sure to use the
20085 remapped face for the appended newline. */
20086 if (default_face_p)
20087 it->face_id = lookup_basic_face (it->w, it->f, DEFAULT_FACE_ID);
20088 else if (it->face_before_selective_p)
20089 it->face_id = it->saved_face_id;
20090 face = FACE_FROM_ID (it->f, it->face_id);
20091 it->face_id = FACE_FOR_CHAR (it->f, face, 0, -1, Qnil);
20092 /* In R2L rows, we will prepend a stretch glyph that will
20093 have the end_of_box_run_p flag set for it, so there's no
20094 need for the appended newline glyph to have that flag
20095 set. */
20096 if (it->glyph_row->reversed_p
20097 /* But if the appended newline glyph goes all the way to
20098 the end of the row, there will be no stretch glyph,
20099 so leave the box flag set. */
20100 && saved_x + FRAME_COLUMN_WIDTH (it->f) < it->last_visible_x)
20101 it->end_of_box_run_p = false;
20103 PRODUCE_GLYPHS (it);
20105 #ifdef HAVE_WINDOW_SYSTEM
20106 /* Make sure this space glyph has the right ascent and
20107 descent values, or else cursor at end of line will look
20108 funny, and height of empty lines will be incorrect. */
20109 struct glyph *g = it->glyph_row->glyphs[TEXT_AREA] + n;
20110 struct font *font = face->font ? face->font : FRAME_FONT (it->f);
20111 if (n == 0)
20113 Lisp_Object height, total_height;
20114 int extra_line_spacing = it->extra_line_spacing;
20115 int boff = font->baseline_offset;
20117 if (font->vertical_centering)
20118 boff = VCENTER_BASELINE_OFFSET (font, it->f) - boff;
20120 it->object = saved_object; /* get_it_property needs this */
20121 normal_char_ascent_descent (font, -1, &it->ascent, &it->descent);
20122 /* Must do a subset of line height processing from
20123 x_produce_glyph for newline characters. */
20124 height = get_it_property (it, Qline_height);
20125 if (CONSP (height)
20126 && CONSP (XCDR (height))
20127 && NILP (XCDR (XCDR (height))))
20129 total_height = XCAR (XCDR (height));
20130 height = XCAR (height);
20132 else
20133 total_height = Qnil;
20134 height = calc_line_height_property (it, height, font, boff, true);
20136 if (it->override_ascent >= 0)
20138 it->ascent = it->override_ascent;
20139 it->descent = it->override_descent;
20140 boff = it->override_boff;
20142 if (EQ (height, Qt))
20143 extra_line_spacing = 0;
20144 else
20146 Lisp_Object spacing;
20148 it->phys_ascent = it->ascent;
20149 it->phys_descent = it->descent;
20150 if (!NILP (height)
20151 && XINT (height) > it->ascent + it->descent)
20152 it->ascent = XINT (height) - it->descent;
20154 if (!NILP (total_height))
20155 spacing = calc_line_height_property (it, total_height, font,
20156 boff, false);
20157 else
20159 spacing = get_it_property (it, Qline_spacing);
20160 spacing = calc_line_height_property (it, spacing, font,
20161 boff, false);
20163 if (INTEGERP (spacing))
20165 extra_line_spacing = XINT (spacing);
20166 if (!NILP (total_height))
20167 extra_line_spacing -= (it->phys_ascent + it->phys_descent);
20170 if (extra_line_spacing > 0)
20172 it->descent += extra_line_spacing;
20173 if (extra_line_spacing > it->max_extra_line_spacing)
20174 it->max_extra_line_spacing = extra_line_spacing;
20176 it->max_ascent = it->ascent;
20177 it->max_descent = it->descent;
20178 /* Make sure compute_line_metrics recomputes the row height. */
20179 it->glyph_row->height = 0;
20182 g->ascent = it->max_ascent;
20183 g->descent = it->max_descent;
20184 #endif
20186 it->override_ascent = -1;
20187 it->constrain_row_ascent_descent_p = false;
20188 it->current_x = saved_x;
20189 it->object = saved_object;
20190 it->position = saved_pos;
20191 it->what = saved_what;
20192 it->face_id = saved_face_id;
20193 it->len = saved_len;
20194 it->c = saved_c;
20195 it->char_to_display = saved_char_to_display;
20196 it->end_of_box_run_p = saved_box_end;
20197 return true;
20201 return false;
20205 /* Extend the face of the last glyph in the text area of IT->glyph_row
20206 to the end of the display line. Called from display_line. If the
20207 glyph row is empty, add a space glyph to it so that we know the
20208 face to draw. Set the glyph row flag fill_line_p. If the glyph
20209 row is R2L, prepend a stretch glyph to cover the empty space to the
20210 left of the leftmost glyph. */
20212 static void
20213 extend_face_to_end_of_line (struct it *it)
20215 struct face *face, *default_face;
20216 struct frame *f = it->f;
20218 /* If line is already filled, do nothing. Non window-system frames
20219 get a grace of one more ``pixel'' because their characters are
20220 1-``pixel'' wide, so they hit the equality too early. This grace
20221 is needed only for R2L rows that are not continued, to produce
20222 one extra blank where we could display the cursor. */
20223 if ((it->current_x >= it->last_visible_x
20224 + (!FRAME_WINDOW_P (f)
20225 && it->glyph_row->reversed_p
20226 && !it->glyph_row->continued_p))
20227 /* If the window has display margins, we will need to extend
20228 their face even if the text area is filled. */
20229 && !(WINDOW_LEFT_MARGIN_WIDTH (it->w) > 0
20230 || WINDOW_RIGHT_MARGIN_WIDTH (it->w) > 0))
20231 return;
20233 /* The default face, possibly remapped. */
20234 default_face =
20235 FACE_FROM_ID_OR_NULL (f, lookup_basic_face (it->w, f, DEFAULT_FACE_ID));
20237 /* Face extension extends the background and box of IT->face_id
20238 to the end of the line. If the background equals the background
20239 of the frame, we don't have to do anything. */
20240 face = FACE_FROM_ID (f, (it->face_before_selective_p
20241 ? it->saved_face_id
20242 : it->face_id));
20244 if (FRAME_WINDOW_P (f)
20245 && MATRIX_ROW_DISPLAYS_TEXT_P (it->glyph_row)
20246 && face->box == FACE_NO_BOX
20247 && face->background == FRAME_BACKGROUND_PIXEL (f)
20248 #ifdef HAVE_WINDOW_SYSTEM
20249 && !face->stipple
20250 #endif
20251 && !it->glyph_row->reversed_p)
20252 return;
20254 /* Set the glyph row flag indicating that the face of the last glyph
20255 in the text area has to be drawn to the end of the text area. */
20256 it->glyph_row->fill_line_p = true;
20258 /* If current character of IT is not ASCII, make sure we have the
20259 ASCII face. This will be automatically undone the next time
20260 get_next_display_element returns a multibyte character. Note
20261 that the character will always be single byte in unibyte
20262 text. */
20263 if (!ASCII_CHAR_P (it->c))
20265 it->face_id = FACE_FOR_CHAR (f, face, 0, -1, Qnil);
20268 if (FRAME_WINDOW_P (f))
20270 /* If the row is empty, add a space with the current face of IT,
20271 so that we know which face to draw. */
20272 if (it->glyph_row->used[TEXT_AREA] == 0)
20274 it->glyph_row->glyphs[TEXT_AREA][0] = space_glyph;
20275 it->glyph_row->glyphs[TEXT_AREA][0].face_id = face->id;
20276 it->glyph_row->used[TEXT_AREA] = 1;
20278 /* Mode line and the header line don't have margins, and
20279 likewise the frame's tool-bar window, if there is any. */
20280 if (!(it->glyph_row->mode_line_p
20281 #if defined (HAVE_WINDOW_SYSTEM) && ! defined (USE_GTK) && ! defined (HAVE_NS)
20282 || (WINDOWP (f->tool_bar_window)
20283 && it->w == XWINDOW (f->tool_bar_window))
20284 #endif
20287 if (WINDOW_LEFT_MARGIN_WIDTH (it->w) > 0
20288 && it->glyph_row->used[LEFT_MARGIN_AREA] == 0)
20290 it->glyph_row->glyphs[LEFT_MARGIN_AREA][0] = space_glyph;
20291 it->glyph_row->glyphs[LEFT_MARGIN_AREA][0].face_id =
20292 default_face->id;
20293 it->glyph_row->used[LEFT_MARGIN_AREA] = 1;
20295 if (WINDOW_RIGHT_MARGIN_WIDTH (it->w) > 0
20296 && it->glyph_row->used[RIGHT_MARGIN_AREA] == 0)
20298 it->glyph_row->glyphs[RIGHT_MARGIN_AREA][0] = space_glyph;
20299 it->glyph_row->glyphs[RIGHT_MARGIN_AREA][0].face_id =
20300 default_face->id;
20301 it->glyph_row->used[RIGHT_MARGIN_AREA] = 1;
20304 #ifdef HAVE_WINDOW_SYSTEM
20305 if (it->glyph_row->reversed_p)
20307 /* Prepend a stretch glyph to the row, such that the
20308 rightmost glyph will be drawn flushed all the way to the
20309 right margin of the window. The stretch glyph that will
20310 occupy the empty space, if any, to the left of the
20311 glyphs. */
20312 struct font *font = face->font ? face->font : FRAME_FONT (f);
20313 struct glyph *row_start = it->glyph_row->glyphs[TEXT_AREA];
20314 struct glyph *row_end = row_start + it->glyph_row->used[TEXT_AREA];
20315 struct glyph *g;
20316 int row_width, stretch_ascent, stretch_width;
20317 struct text_pos saved_pos;
20318 int saved_face_id;
20319 bool saved_avoid_cursor, saved_box_start;
20321 for (row_width = 0, g = row_start; g < row_end; g++)
20322 row_width += g->pixel_width;
20324 /* FIXME: There are various minor display glitches in R2L
20325 rows when only one of the fringes is missing. The
20326 strange condition below produces the least bad effect. */
20327 if ((WINDOW_LEFT_FRINGE_WIDTH (it->w) == 0)
20328 == (WINDOW_RIGHT_FRINGE_WIDTH (it->w) == 0)
20329 || WINDOW_RIGHT_FRINGE_WIDTH (it->w) != 0)
20330 stretch_width = window_box_width (it->w, TEXT_AREA);
20331 else
20332 stretch_width = it->last_visible_x - it->first_visible_x;
20333 stretch_width -= row_width;
20335 if (stretch_width > 0)
20337 stretch_ascent =
20338 (((it->ascent + it->descent)
20339 * FONT_BASE (font)) / FONT_HEIGHT (font));
20340 saved_pos = it->position;
20341 memset (&it->position, 0, sizeof it->position);
20342 saved_avoid_cursor = it->avoid_cursor_p;
20343 it->avoid_cursor_p = true;
20344 saved_face_id = it->face_id;
20345 saved_box_start = it->start_of_box_run_p;
20346 /* The last row's stretch glyph should get the default
20347 face, to avoid painting the rest of the window with
20348 the region face, if the region ends at ZV. */
20349 if (it->glyph_row->ends_at_zv_p)
20350 it->face_id = default_face->id;
20351 else
20352 it->face_id = face->id;
20353 it->start_of_box_run_p = false;
20354 append_stretch_glyph (it, Qnil, stretch_width,
20355 it->ascent + it->descent, stretch_ascent);
20356 it->position = saved_pos;
20357 it->avoid_cursor_p = saved_avoid_cursor;
20358 it->face_id = saved_face_id;
20359 it->start_of_box_run_p = saved_box_start;
20361 /* If stretch_width comes out negative, it means that the
20362 last glyph is only partially visible. In R2L rows, we
20363 want the leftmost glyph to be partially visible, so we
20364 need to give the row the corresponding left offset. */
20365 if (stretch_width < 0)
20366 it->glyph_row->x = stretch_width;
20368 #endif /* HAVE_WINDOW_SYSTEM */
20370 else
20372 /* Save some values that must not be changed. */
20373 int saved_x = it->current_x;
20374 struct text_pos saved_pos;
20375 Lisp_Object saved_object;
20376 enum display_element_type saved_what = it->what;
20377 int saved_face_id = it->face_id;
20379 saved_object = it->object;
20380 saved_pos = it->position;
20382 it->what = IT_CHARACTER;
20383 memset (&it->position, 0, sizeof it->position);
20384 it->object = Qnil;
20385 it->c = it->char_to_display = ' ';
20386 it->len = 1;
20388 if (WINDOW_LEFT_MARGIN_WIDTH (it->w) > 0
20389 && (it->glyph_row->used[LEFT_MARGIN_AREA]
20390 < WINDOW_LEFT_MARGIN_WIDTH (it->w))
20391 && !it->glyph_row->mode_line_p
20392 && default_face->background != FRAME_BACKGROUND_PIXEL (f))
20394 struct glyph *g = it->glyph_row->glyphs[LEFT_MARGIN_AREA];
20395 struct glyph *e = g + it->glyph_row->used[LEFT_MARGIN_AREA];
20397 for (it->current_x = 0; g < e; g++)
20398 it->current_x += g->pixel_width;
20400 it->area = LEFT_MARGIN_AREA;
20401 it->face_id = default_face->id;
20402 while (it->glyph_row->used[LEFT_MARGIN_AREA]
20403 < WINDOW_LEFT_MARGIN_WIDTH (it->w)
20404 && g < it->glyph_row->glyphs[TEXT_AREA])
20406 PRODUCE_GLYPHS (it);
20407 /* term.c:produce_glyphs advances it->current_x only for
20408 TEXT_AREA. */
20409 it->current_x += it->pixel_width;
20410 g++;
20413 it->current_x = saved_x;
20414 it->area = TEXT_AREA;
20417 /* The last row's blank glyphs should get the default face, to
20418 avoid painting the rest of the window with the region face,
20419 if the region ends at ZV. */
20420 if (it->glyph_row->ends_at_zv_p)
20421 it->face_id = default_face->id;
20422 else
20423 it->face_id = face->id;
20424 PRODUCE_GLYPHS (it);
20426 while (it->current_x <= it->last_visible_x)
20427 PRODUCE_GLYPHS (it);
20429 if (WINDOW_RIGHT_MARGIN_WIDTH (it->w) > 0
20430 && (it->glyph_row->used[RIGHT_MARGIN_AREA]
20431 < WINDOW_RIGHT_MARGIN_WIDTH (it->w))
20432 && !it->glyph_row->mode_line_p
20433 && default_face->background != FRAME_BACKGROUND_PIXEL (f))
20435 struct glyph *g = it->glyph_row->glyphs[RIGHT_MARGIN_AREA];
20436 struct glyph *e = g + it->glyph_row->used[RIGHT_MARGIN_AREA];
20438 for ( ; g < e; g++)
20439 it->current_x += g->pixel_width;
20441 it->area = RIGHT_MARGIN_AREA;
20442 it->face_id = default_face->id;
20443 while (it->glyph_row->used[RIGHT_MARGIN_AREA]
20444 < WINDOW_RIGHT_MARGIN_WIDTH (it->w)
20445 && g < it->glyph_row->glyphs[LAST_AREA])
20447 PRODUCE_GLYPHS (it);
20448 it->current_x += it->pixel_width;
20449 g++;
20452 it->area = TEXT_AREA;
20455 /* Don't count these blanks really. It would let us insert a left
20456 truncation glyph below and make us set the cursor on them, maybe. */
20457 it->current_x = saved_x;
20458 it->object = saved_object;
20459 it->position = saved_pos;
20460 it->what = saved_what;
20461 it->face_id = saved_face_id;
20466 /* Value is true if text starting at CHARPOS in current_buffer is
20467 trailing whitespace. */
20469 static bool
20470 trailing_whitespace_p (ptrdiff_t charpos)
20472 ptrdiff_t bytepos = CHAR_TO_BYTE (charpos);
20473 int c = 0;
20475 while (bytepos < ZV_BYTE
20476 && (c = FETCH_CHAR (bytepos),
20477 c == ' ' || c == '\t'))
20478 ++bytepos;
20480 if (bytepos >= ZV_BYTE || c == '\n' || c == '\r')
20482 if (bytepos != PT_BYTE)
20483 return true;
20485 return false;
20489 /* Highlight trailing whitespace, if any, in row at IT. */
20491 static void
20492 highlight_trailing_whitespace (struct it *it)
20494 struct glyph_row *row = it->glyph_row;
20495 int used = row->used[TEXT_AREA];
20497 if (used)
20499 struct glyph *start = row->glyphs[TEXT_AREA];
20500 struct glyph *glyph = start + used - 1;
20502 if (row->reversed_p)
20504 /* Right-to-left rows need to be processed in the opposite
20505 direction, so swap the edge pointers. */
20506 glyph = start;
20507 start = row->glyphs[TEXT_AREA] + used - 1;
20510 /* Skip over glyphs inserted to display the cursor at the
20511 end of a line, for extending the face of the last glyph
20512 to the end of the line on terminals, and for truncation
20513 and continuation glyphs. */
20514 if (!row->reversed_p)
20516 while (glyph >= start
20517 && glyph->type == CHAR_GLYPH
20518 && NILP (glyph->object))
20519 --glyph;
20521 else
20523 while (glyph <= start
20524 && glyph->type == CHAR_GLYPH
20525 && NILP (glyph->object))
20526 ++glyph;
20529 /* If last glyph is a space or stretch, and it's trailing
20530 whitespace, set the face of all trailing whitespace glyphs in
20531 IT->glyph_row to `trailing-whitespace'. */
20532 if ((row->reversed_p ? glyph <= start : glyph >= start)
20533 && BUFFERP (glyph->object)
20534 && (glyph->type == STRETCH_GLYPH
20535 || (glyph->type == CHAR_GLYPH
20536 && glyph->u.ch == ' '))
20537 && trailing_whitespace_p (glyph->charpos))
20539 int face_id = lookup_named_face (it->w, it->f, Qtrailing_whitespace, false);
20540 if (face_id < 0)
20541 return;
20543 if (!row->reversed_p)
20545 while (glyph >= start
20546 && BUFFERP (glyph->object)
20547 && (glyph->type == STRETCH_GLYPH
20548 || (glyph->type == CHAR_GLYPH
20549 && glyph->u.ch == ' ')))
20550 (glyph--)->face_id = face_id;
20552 else
20554 while (glyph <= start
20555 && BUFFERP (glyph->object)
20556 && (glyph->type == STRETCH_GLYPH
20557 || (glyph->type == CHAR_GLYPH
20558 && glyph->u.ch == ' ')))
20559 (glyph++)->face_id = face_id;
20566 /* Value is true if glyph row ROW should be
20567 considered to hold the buffer position CHARPOS. */
20569 static bool
20570 row_for_charpos_p (struct glyph_row *row, ptrdiff_t charpos)
20572 bool result = true;
20574 if (charpos == CHARPOS (row->end.pos)
20575 || charpos == MATRIX_ROW_END_CHARPOS (row))
20577 /* Suppose the row ends on a string.
20578 Unless the row is continued, that means it ends on a newline
20579 in the string. If it's anything other than a display string
20580 (e.g., a before-string from an overlay), we don't want the
20581 cursor there. (This heuristic seems to give the optimal
20582 behavior for the various types of multi-line strings.)
20583 One exception: if the string has `cursor' property on one of
20584 its characters, we _do_ want the cursor there. */
20585 if (CHARPOS (row->end.string_pos) >= 0)
20587 if (row->continued_p)
20588 result = true;
20589 else
20591 /* Check for `display' property. */
20592 struct glyph *beg = row->glyphs[TEXT_AREA];
20593 struct glyph *end = beg + row->used[TEXT_AREA] - 1;
20594 struct glyph *glyph;
20596 result = false;
20597 for (glyph = end; glyph >= beg; --glyph)
20598 if (STRINGP (glyph->object))
20600 Lisp_Object prop
20601 = Fget_char_property (make_number (charpos),
20602 Qdisplay, Qnil);
20603 result =
20604 (!NILP (prop)
20605 && display_prop_string_p (prop, glyph->object));
20606 /* If there's a `cursor' property on one of the
20607 string's characters, this row is a cursor row,
20608 even though this is not a display string. */
20609 if (!result)
20611 Lisp_Object s = glyph->object;
20613 for ( ; glyph >= beg && EQ (glyph->object, s); --glyph)
20615 ptrdiff_t gpos = glyph->charpos;
20617 if (!NILP (Fget_char_property (make_number (gpos),
20618 Qcursor, s)))
20620 result = true;
20621 break;
20625 break;
20629 else if (MATRIX_ROW_ENDS_IN_MIDDLE_OF_CHAR_P (row))
20631 /* If the row ends in middle of a real character,
20632 and the line is continued, we want the cursor here.
20633 That's because CHARPOS (ROW->end.pos) would equal
20634 PT if PT is before the character. */
20635 if (!row->ends_in_ellipsis_p)
20636 result = row->continued_p;
20637 else
20638 /* If the row ends in an ellipsis, then
20639 CHARPOS (ROW->end.pos) will equal point after the
20640 invisible text. We want that position to be displayed
20641 after the ellipsis. */
20642 result = false;
20644 /* If the row ends at ZV, display the cursor at the end of that
20645 row instead of at the start of the row below. */
20646 else
20647 result = row->ends_at_zv_p;
20650 return result;
20653 /* Value is true if glyph row ROW should be
20654 used to hold the cursor. */
20656 static bool
20657 cursor_row_p (struct glyph_row *row)
20659 return row_for_charpos_p (row, PT);
20664 /* Push the property PROP so that it will be rendered at the current
20665 position in IT. Return true if PROP was successfully pushed, false
20666 otherwise. Called from handle_line_prefix to handle the
20667 `line-prefix' and `wrap-prefix' properties. */
20669 static bool
20670 push_prefix_prop (struct it *it, Lisp_Object prop)
20672 struct text_pos pos =
20673 STRINGP (it->string) ? it->current.string_pos : it->current.pos;
20675 eassert (it->method == GET_FROM_BUFFER
20676 || it->method == GET_FROM_DISPLAY_VECTOR
20677 || it->method == GET_FROM_STRING
20678 || it->method == GET_FROM_IMAGE);
20680 /* We need to save the current buffer/string position, so it will be
20681 restored by pop_it, because iterate_out_of_display_property
20682 depends on that being set correctly, but some situations leave
20683 it->position not yet set when this function is called. */
20684 push_it (it, &pos);
20686 if (STRINGP (prop))
20688 if (SCHARS (prop) == 0)
20690 pop_it (it);
20691 return false;
20694 it->string = prop;
20695 it->string_from_prefix_prop_p = true;
20696 it->multibyte_p = STRING_MULTIBYTE (it->string);
20697 it->current.overlay_string_index = -1;
20698 IT_STRING_CHARPOS (*it) = IT_STRING_BYTEPOS (*it) = 0;
20699 it->end_charpos = it->string_nchars = SCHARS (it->string);
20700 it->method = GET_FROM_STRING;
20701 it->stop_charpos = 0;
20702 it->prev_stop = 0;
20703 it->base_level_stop = 0;
20704 it->cmp_it.id = -1;
20706 /* Force paragraph direction to be that of the parent
20707 buffer/string. */
20708 if (it->bidi_p && it->bidi_it.paragraph_dir == R2L)
20709 it->paragraph_embedding = it->bidi_it.paragraph_dir;
20710 else
20711 it->paragraph_embedding = L2R;
20713 /* Set up the bidi iterator for this display string. */
20714 if (it->bidi_p)
20716 it->bidi_it.string.lstring = it->string;
20717 it->bidi_it.string.s = NULL;
20718 it->bidi_it.string.schars = it->end_charpos;
20719 it->bidi_it.string.bufpos = IT_CHARPOS (*it);
20720 it->bidi_it.string.from_disp_str = it->string_from_display_prop_p;
20721 it->bidi_it.string.unibyte = !it->multibyte_p;
20722 it->bidi_it.w = it->w;
20723 bidi_init_it (0, 0, FRAME_WINDOW_P (it->f), &it->bidi_it);
20726 else if (CONSP (prop) && EQ (XCAR (prop), Qspace))
20728 it->method = GET_FROM_STRETCH;
20729 it->object = prop;
20731 #ifdef HAVE_WINDOW_SYSTEM
20732 else if (IMAGEP (prop))
20734 it->what = IT_IMAGE;
20735 it->image_id = lookup_image (it->f, prop);
20736 it->method = GET_FROM_IMAGE;
20738 #endif /* HAVE_WINDOW_SYSTEM */
20739 else
20741 pop_it (it); /* bogus display property, give up */
20742 return false;
20745 return true;
20748 /* Return the character-property PROP at the current position in IT. */
20750 static Lisp_Object
20751 get_it_property (struct it *it, Lisp_Object prop)
20753 Lisp_Object position, object = it->object;
20755 if (STRINGP (object))
20756 position = make_number (IT_STRING_CHARPOS (*it));
20757 else if (BUFFERP (object))
20759 position = make_number (IT_CHARPOS (*it));
20760 object = it->window;
20762 else
20763 return Qnil;
20765 return Fget_char_property (position, prop, object);
20768 /* See if there's a line- or wrap-prefix, and if so, push it on IT. */
20770 static void
20771 handle_line_prefix (struct it *it)
20773 Lisp_Object prefix;
20775 if (it->continuation_lines_width > 0)
20777 prefix = get_it_property (it, Qwrap_prefix);
20778 if (NILP (prefix))
20779 prefix = Vwrap_prefix;
20781 else
20783 prefix = get_it_property (it, Qline_prefix);
20784 if (NILP (prefix))
20785 prefix = Vline_prefix;
20787 if (! NILP (prefix) && push_prefix_prop (it, prefix))
20789 /* If the prefix is wider than the window, and we try to wrap
20790 it, it would acquire its own wrap prefix, and so on till the
20791 iterator stack overflows. So, don't wrap the prefix. */
20792 it->line_wrap = TRUNCATE;
20793 it->avoid_cursor_p = true;
20799 /* Remove N glyphs at the start of a reversed IT->glyph_row. Called
20800 only for R2L lines from display_line and display_string, when they
20801 decide that too many glyphs were produced by PRODUCE_GLYPHS, and
20802 the line/string needs to be continued on the next glyph row. */
20803 static void
20804 unproduce_glyphs (struct it *it, int n)
20806 struct glyph *glyph, *end;
20808 eassert (it->glyph_row);
20809 eassert (it->glyph_row->reversed_p);
20810 eassert (it->area == TEXT_AREA);
20811 eassert (n <= it->glyph_row->used[TEXT_AREA]);
20813 if (n > it->glyph_row->used[TEXT_AREA])
20814 n = it->glyph_row->used[TEXT_AREA];
20815 glyph = it->glyph_row->glyphs[TEXT_AREA] + n;
20816 end = it->glyph_row->glyphs[TEXT_AREA] + it->glyph_row->used[TEXT_AREA];
20817 for ( ; glyph < end; glyph++)
20818 glyph[-n] = *glyph;
20821 /* Find the positions in a bidi-reordered ROW to serve as ROW->minpos
20822 and ROW->maxpos. */
20823 static void
20824 find_row_edges (struct it *it, struct glyph_row *row,
20825 ptrdiff_t min_pos, ptrdiff_t min_bpos,
20826 ptrdiff_t max_pos, ptrdiff_t max_bpos)
20828 /* FIXME: Revisit this when glyph ``spilling'' in continuation
20829 lines' rows is implemented for bidi-reordered rows. */
20831 /* ROW->minpos is the value of min_pos, the minimal buffer position
20832 we have in ROW, or ROW->start.pos if that is smaller. */
20833 if (min_pos <= ZV && min_pos < row->start.pos.charpos)
20834 SET_TEXT_POS (row->minpos, min_pos, min_bpos);
20835 else
20836 /* We didn't find buffer positions smaller than ROW->start, or
20837 didn't find _any_ valid buffer positions in any of the glyphs,
20838 so we must trust the iterator's computed positions. */
20839 row->minpos = row->start.pos;
20840 if (max_pos <= 0)
20842 max_pos = CHARPOS (it->current.pos);
20843 max_bpos = BYTEPOS (it->current.pos);
20846 /* Here are the various use-cases for ending the row, and the
20847 corresponding values for ROW->maxpos:
20849 Line ends in a newline from buffer eol_pos + 1
20850 Line is continued from buffer max_pos + 1
20851 Line is truncated on right it->current.pos
20852 Line ends in a newline from string max_pos + 1(*)
20853 (*) + 1 only when line ends in a forward scan
20854 Line is continued from string max_pos
20855 Line is continued from display vector max_pos
20856 Line is entirely from a string min_pos == max_pos
20857 Line is entirely from a display vector min_pos == max_pos
20858 Line that ends at ZV ZV
20860 If you discover other use-cases, please add them here as
20861 appropriate. */
20862 if (row->ends_at_zv_p)
20863 row->maxpos = it->current.pos;
20864 else if (row->used[TEXT_AREA])
20866 bool seen_this_string = false;
20867 struct glyph_row *r1 = row - 1;
20869 /* Did we see the same display string on the previous row? */
20870 if (STRINGP (it->object)
20871 /* this is not the first row */
20872 && row > it->w->desired_matrix->rows
20873 /* previous row is not the header line */
20874 && !r1->mode_line_p
20875 /* previous row also ends in a newline from a string */
20876 && r1->ends_in_newline_from_string_p)
20878 struct glyph *start, *end;
20880 /* Search for the last glyph of the previous row that came
20881 from buffer or string. Depending on whether the row is
20882 L2R or R2L, we need to process it front to back or the
20883 other way round. */
20884 if (!r1->reversed_p)
20886 start = r1->glyphs[TEXT_AREA];
20887 end = start + r1->used[TEXT_AREA];
20888 /* Glyphs inserted by redisplay have nil as their object. */
20889 while (end > start
20890 && NILP ((end - 1)->object)
20891 && (end - 1)->charpos <= 0)
20892 --end;
20893 if (end > start)
20895 if (EQ ((end - 1)->object, it->object))
20896 seen_this_string = true;
20898 else
20899 /* If all the glyphs of the previous row were inserted
20900 by redisplay, it means the previous row was
20901 produced from a single newline, which is only
20902 possible if that newline came from the same string
20903 as the one which produced this ROW. */
20904 seen_this_string = true;
20906 else
20908 end = r1->glyphs[TEXT_AREA] - 1;
20909 start = end + r1->used[TEXT_AREA];
20910 while (end < start
20911 && NILP ((end + 1)->object)
20912 && (end + 1)->charpos <= 0)
20913 ++end;
20914 if (end < start)
20916 if (EQ ((end + 1)->object, it->object))
20917 seen_this_string = true;
20919 else
20920 seen_this_string = true;
20923 /* Take note of each display string that covers a newline only
20924 once, the first time we see it. This is for when a display
20925 string includes more than one newline in it. */
20926 if (row->ends_in_newline_from_string_p && !seen_this_string)
20928 /* If we were scanning the buffer forward when we displayed
20929 the string, we want to account for at least one buffer
20930 position that belongs to this row (position covered by
20931 the display string), so that cursor positioning will
20932 consider this row as a candidate when point is at the end
20933 of the visual line represented by this row. This is not
20934 required when scanning back, because max_pos will already
20935 have a much larger value. */
20936 if (CHARPOS (row->end.pos) > max_pos)
20937 INC_BOTH (max_pos, max_bpos);
20938 SET_TEXT_POS (row->maxpos, max_pos, max_bpos);
20940 else if (CHARPOS (it->eol_pos) > 0)
20941 SET_TEXT_POS (row->maxpos,
20942 CHARPOS (it->eol_pos) + 1, BYTEPOS (it->eol_pos) + 1);
20943 else if (row->continued_p)
20945 /* If max_pos is different from IT's current position, it
20946 means IT->method does not belong to the display element
20947 at max_pos. However, it also means that the display
20948 element at max_pos was displayed in its entirety on this
20949 line, which is equivalent to saying that the next line
20950 starts at the next buffer position. */
20951 if (IT_CHARPOS (*it) == max_pos && it->method != GET_FROM_BUFFER)
20952 SET_TEXT_POS (row->maxpos, max_pos, max_bpos);
20953 else
20955 INC_BOTH (max_pos, max_bpos);
20956 SET_TEXT_POS (row->maxpos, max_pos, max_bpos);
20959 else if (row->truncated_on_right_p)
20960 /* display_line already called reseat_at_next_visible_line_start,
20961 which puts the iterator at the beginning of the next line, in
20962 the logical order. */
20963 row->maxpos = it->current.pos;
20964 else if (max_pos == min_pos && it->method != GET_FROM_BUFFER)
20965 /* A line that is entirely from a string/image/stretch... */
20966 row->maxpos = row->minpos;
20967 else
20968 emacs_abort ();
20970 else
20971 row->maxpos = it->current.pos;
20974 /* Like display_count_lines, but capable of counting outside of the
20975 current narrowed region. */
20976 static ptrdiff_t
20977 display_count_lines_logically (ptrdiff_t start_byte, ptrdiff_t limit_byte,
20978 ptrdiff_t count, ptrdiff_t *byte_pos_ptr)
20980 if (!display_line_numbers_widen || (BEGV == BEG && ZV == Z))
20981 return display_count_lines (start_byte, limit_byte, count, byte_pos_ptr);
20983 ptrdiff_t val;
20984 ptrdiff_t pdl_count = SPECPDL_INDEX ();
20985 record_unwind_protect (save_restriction_restore, save_restriction_save ());
20986 Fwiden ();
20987 val = display_count_lines (start_byte, limit_byte, count, byte_pos_ptr);
20988 unbind_to (pdl_count, Qnil);
20989 return val;
20992 /* Count the number of screen lines in window IT->w between character
20993 position IT_CHARPOS(*IT) and the line showing that window's point. */
20994 static ptrdiff_t
20995 display_count_lines_visually (struct it *it)
20997 struct it tem_it;
20998 ptrdiff_t to;
20999 struct text_pos from;
21001 /* If we already calculated a relative line number, use that. This
21002 trick relies on the fact that visual lines (a.k.a. "glyph rows")
21003 are laid out sequentially, one by one, for each sequence of calls
21004 to display_line or other similar function that follows a call to
21005 init_iterator. */
21006 if (it->lnum_bytepos > 0)
21007 return it->lnum + 1;
21008 else
21010 ptrdiff_t count = SPECPDL_INDEX ();
21012 if (IT_CHARPOS (*it) <= PT)
21014 from = it->current.pos;
21015 to = PT;
21017 else
21019 SET_TEXT_POS (from, PT, PT_BYTE);
21020 to = IT_CHARPOS (*it);
21022 start_display (&tem_it, it->w, from);
21023 /* Need to disable visual mode temporarily, since otherwise the
21024 call to move_it_to will cause infinite recursion. */
21025 specbind (Qdisplay_line_numbers, Qrelative);
21026 /* Some redisplay optimizations could invoke us very far from
21027 PT, which will make the caller painfully slow. There should
21028 be no need to go too far beyond the window's bottom, as any
21029 such optimization will fail to show point anyway. */
21030 move_it_to (&tem_it, to, -1,
21031 tem_it.last_visible_y
21032 + (SCROLL_LIMIT + 10) * FRAME_LINE_HEIGHT (tem_it.f),
21033 -1, MOVE_TO_POS | MOVE_TO_Y);
21034 unbind_to (count, Qnil);
21035 return IT_CHARPOS (*it) <= PT ? -tem_it.vpos : tem_it.vpos;
21039 /* Produce the line-number glyphs for the current glyph_row. If
21040 IT->glyph_row is non-NULL, populate the row with the produced
21041 glyphs. */
21042 static void
21043 maybe_produce_line_number (struct it *it)
21045 ptrdiff_t last_line = it->lnum;
21046 ptrdiff_t start_from, bytepos;
21047 ptrdiff_t this_line;
21048 bool first_time = false;
21049 ptrdiff_t beg_byte = display_line_numbers_widen ? BEG_BYTE : BEGV_BYTE;
21050 ptrdiff_t z_byte = display_line_numbers_widen ? Z_BYTE : ZV_BYTE;
21051 void *itdata = bidi_shelve_cache ();
21053 if (EQ (Vdisplay_line_numbers, Qvisual))
21054 this_line = display_count_lines_visually (it);
21055 else
21057 if (!last_line)
21059 /* If possible, reuse data cached by line-number-mode. */
21060 if (it->w->base_line_number > 0
21061 && it->w->base_line_pos > 0
21062 && it->w->base_line_pos <= IT_CHARPOS (*it)
21063 /* line-number-mode always displays narrowed line
21064 numbers, so we cannot use its data if the user wants
21065 line numbers that disregard narrowing, or if the
21066 buffer's narrowing has just changed. */
21067 && !(display_line_numbers_widen
21068 && (BEG_BYTE != BEGV_BYTE || Z_BYTE != ZV_BYTE))
21069 && !current_buffer->clip_changed)
21071 start_from = CHAR_TO_BYTE (it->w->base_line_pos);
21072 last_line = it->w->base_line_number - 1;
21074 else
21075 start_from = beg_byte;
21076 if (!it->lnum_bytepos)
21077 first_time = true;
21079 else
21080 start_from = it->lnum_bytepos;
21082 /* Paranoia: what if someone changes the narrowing since the
21083 last time display_line was called? Shouldn't really happen,
21084 but who knows what some crazy Lisp invoked by :eval could do? */
21085 if (!(beg_byte <= start_from && start_from <= z_byte))
21087 last_line = 0;
21088 start_from = beg_byte;
21091 this_line =
21092 last_line + display_count_lines_logically (start_from,
21093 IT_BYTEPOS (*it),
21094 IT_CHARPOS (*it), &bytepos);
21095 eassert (this_line > 0 || (this_line == 0 && start_from == beg_byte));
21096 eassert (bytepos == IT_BYTEPOS (*it));
21099 /* Record the line number information. */
21100 if (this_line != last_line || !it->lnum_bytepos)
21102 it->lnum = this_line;
21103 it->lnum_bytepos = IT_BYTEPOS (*it);
21106 /* Produce the glyphs for the line number. */
21107 struct it tem_it;
21108 char lnum_buf[INT_STRLEN_BOUND (ptrdiff_t) + 1];
21109 bool beyond_zv = IT_BYTEPOS (*it) >= ZV_BYTE ? true : false;
21110 ptrdiff_t lnum_offset = -1; /* to produce 1-based line numbers */
21111 int lnum_face_id = merge_faces (it->w, Qline_number, 0, DEFAULT_FACE_ID);
21112 int current_lnum_face_id
21113 = merge_faces (it->w, Qline_number_current_line, 0, DEFAULT_FACE_ID);
21114 /* Compute point's line number if needed. */
21115 if ((EQ (Vdisplay_line_numbers, Qrelative)
21116 || EQ (Vdisplay_line_numbers, Qvisual)
21117 || lnum_face_id != current_lnum_face_id)
21118 && !it->pt_lnum)
21120 ptrdiff_t ignored;
21121 if (PT_BYTE > it->lnum_bytepos && !EQ (Vdisplay_line_numbers, Qvisual))
21122 it->pt_lnum =
21123 this_line + display_count_lines_logically (it->lnum_bytepos, PT_BYTE,
21124 PT, &ignored);
21125 else
21126 it->pt_lnum = display_count_lines_logically (beg_byte, PT_BYTE, PT,
21127 &ignored);
21129 /* Compute the required width if needed. */
21130 if (!it->lnum_width)
21132 if (NATNUMP (Vdisplay_line_numbers_width))
21133 it->lnum_width = XFASTINT (Vdisplay_line_numbers_width);
21135 /* Max line number to be displayed cannot be more than the one
21136 corresponding to the last row of the desired matrix. */
21137 ptrdiff_t max_lnum;
21139 if (NILP (Vdisplay_line_numbers_current_absolute)
21140 && (EQ (Vdisplay_line_numbers, Qrelative)
21141 || EQ (Vdisplay_line_numbers, Qvisual)))
21142 /* We subtract one more because the current line is always
21143 zero in this mode. */
21144 max_lnum = it->w->desired_matrix->nrows - 2;
21145 else if (EQ (Vdisplay_line_numbers, Qvisual))
21146 max_lnum = it->pt_lnum + it->w->desired_matrix->nrows - 1;
21147 else
21148 max_lnum = this_line + it->w->desired_matrix->nrows - 1 - it->vpos;
21149 max_lnum = max (1, max_lnum);
21150 it->lnum_width = max (it->lnum_width, log10 (max_lnum) + 1);
21151 eassert (it->lnum_width > 0);
21153 if (EQ (Vdisplay_line_numbers, Qrelative))
21154 lnum_offset = it->pt_lnum;
21155 else if (EQ (Vdisplay_line_numbers, Qvisual))
21156 lnum_offset = 0;
21158 /* Under 'relative', display the absolute line number for the
21159 current line, unless the user requests otherwise. */
21160 ptrdiff_t lnum_to_display = eabs (this_line - lnum_offset);
21161 if ((EQ (Vdisplay_line_numbers, Qrelative)
21162 || EQ (Vdisplay_line_numbers, Qvisual))
21163 && lnum_to_display == 0
21164 && !NILP (Vdisplay_line_numbers_current_absolute))
21165 lnum_to_display = it->pt_lnum + 1;
21166 /* In L2R rows we need to append the blank separator, in R2L
21167 rows we need to prepend it. But this function is usually
21168 called when no display elements were produced from the
21169 following line, so the paragraph direction might be unknown.
21170 Therefore we cheat and add 2 blanks, one on either side. */
21171 pint2str (lnum_buf, it->lnum_width + 1, lnum_to_display);
21172 strcat (lnum_buf, " ");
21174 /* Setup for producing the glyphs. */
21175 init_iterator (&tem_it, it->w, -1, -1, &scratch_glyph_row,
21176 /* FIXME: Use specialized face. */
21177 DEFAULT_FACE_ID);
21178 scratch_glyph_row.reversed_p = false;
21179 scratch_glyph_row.used[TEXT_AREA] = 0;
21180 SET_TEXT_POS (tem_it.position, 0, 0);
21181 tem_it.avoid_cursor_p = true;
21182 tem_it.bidi_p = true;
21183 tem_it.bidi_it.type = WEAK_EN;
21184 /* According to UAX#9, EN goes up 2 levels in L2R paragraph and
21185 1 level in R2L paragraphs. Emulate that, assuming we are in
21186 an L2R paragraph. */
21187 tem_it.bidi_it.resolved_level = 2;
21189 /* Produce glyphs for the line number in a scratch glyph_row. */
21190 int n_glyphs_before;
21191 for (const char *p = lnum_buf; *p; p++)
21193 /* For continuation lines and lines after ZV, instead of a line
21194 number, produce a blank prefix of the same width. Use the
21195 default face for the blank field beyond ZV. */
21196 if (beyond_zv)
21197 tem_it.face_id = it->base_face_id;
21198 else if (lnum_face_id != current_lnum_face_id
21199 && (EQ (Vdisplay_line_numbers, Qvisual)
21200 ? this_line == 0
21201 : this_line == it->pt_lnum))
21202 tem_it.face_id = current_lnum_face_id;
21203 else
21204 tem_it.face_id = lnum_face_id;
21205 if (beyond_zv
21206 /* Don't display the same line number more than once. */
21207 || (!EQ (Vdisplay_line_numbers, Qvisual)
21208 && (it->continuation_lines_width > 0
21209 || (this_line == last_line && !first_time))))
21210 tem_it.c = tem_it.char_to_display = ' ';
21211 else
21212 tem_it.c = tem_it.char_to_display = *p;
21213 tem_it.len = 1;
21214 n_glyphs_before = scratch_glyph_row.used[TEXT_AREA];
21215 /* Make sure these glyphs will have a "position" of -1. */
21216 SET_TEXT_POS (tem_it.position, -1, -1);
21217 PRODUCE_GLYPHS (&tem_it);
21219 /* Stop producing glyphs if we don't have enough space on
21220 this line. FIXME: should we refrain from producing the
21221 line number at all in that case? */
21222 if (tem_it.current_x > tem_it.last_visible_x)
21224 scratch_glyph_row.used[TEXT_AREA] = n_glyphs_before;
21225 break;
21229 /* Record the width in pixels we need for the line number display. */
21230 it->lnum_pixel_width = tem_it.current_x;
21231 /* Copy the produced glyphs into IT's glyph_row. */
21232 struct glyph *g = scratch_glyph_row.glyphs[TEXT_AREA];
21233 struct glyph *e = g + scratch_glyph_row.used[TEXT_AREA];
21234 struct glyph *p = it->glyph_row ? it->glyph_row->glyphs[TEXT_AREA] : NULL;
21235 short *u = it->glyph_row ? &it->glyph_row->used[TEXT_AREA] : NULL;
21237 eassert (it->glyph_row == NULL || it->glyph_row->used[TEXT_AREA] == 0);
21239 for ( ; g < e; g++)
21241 it->current_x += g->pixel_width;
21242 /* The following is important when this function is called
21243 from move_it_in_display_line_to: HPOS is incremented only
21244 when we are in the visible portion of the glyph row. */
21245 if (it->current_x > it->first_visible_x)
21246 it->hpos++;
21247 if (p)
21249 *p++ = *g;
21250 (*u)++;
21254 /* Update IT's metrics due to glyphs produced for line numbers. */
21255 if (it->glyph_row)
21257 struct glyph_row *row = it->glyph_row;
21259 it->max_ascent = max (row->ascent, tem_it.max_ascent);
21260 it->max_descent = max (row->height - row->ascent, tem_it.max_descent);
21261 it->max_phys_ascent = max (row->phys_ascent, tem_it.max_phys_ascent);
21262 it->max_phys_descent = max (row->phys_height - row->phys_ascent,
21263 tem_it.max_phys_descent);
21265 else
21267 it->max_ascent = max (it->max_ascent, tem_it.max_ascent);
21268 it->max_descent = max (it->max_descent, tem_it.max_descent);
21269 it->max_phys_ascent = max (it->max_phys_ascent, tem_it.max_phys_ascent);
21270 it->max_phys_descent = max (it->max_phys_descent, tem_it.max_phys_descent);
21273 it->line_number_produced_p = true;
21275 bidi_unshelve_cache (itdata, false);
21278 /* Return true if this glyph row needs a line number to be produced
21279 for it. */
21280 static bool
21281 should_produce_line_number (struct it *it)
21283 if (NILP (Vdisplay_line_numbers))
21284 return false;
21286 /* Don't display line numbers in minibuffer windows. */
21287 if (MINI_WINDOW_P (it->w))
21288 return false;
21290 #ifdef HAVE_WINDOW_SYSTEM
21291 /* Don't display line number in tooltip frames. */
21292 if (FRAME_TOOLTIP_P (XFRAME (WINDOW_FRAME (it->w))))
21293 return false;
21294 #endif
21296 /* If the character at current position has a non-nil special
21297 property, disable line numbers for this row. This is for
21298 packages such as company-mode, which need this for their tricky
21299 layout, where line numbers get in the way. */
21300 Lisp_Object val = Fget_char_property (make_number (IT_CHARPOS (*it)),
21301 Qdisplay_line_numbers_disable,
21302 it->window);
21303 /* For ZV, we need to also look in empty overlays at that point,
21304 because get-char-property always returns nil for ZV, except if
21305 the property is in 'default-text-properties'. */
21306 if (NILP (val) && IT_CHARPOS (*it) >= ZV)
21307 val = disable_line_numbers_overlay_at_eob ();
21308 return NILP (val) ? true : false;
21311 /* Return true if ROW has no glyphs except those inserted by the
21312 display engine. This is needed for indicate-empty-lines and
21313 similar features when the glyph row starts with glyphs which didn't
21314 come from buffer or string. */
21315 static bool
21316 row_text_area_empty (struct glyph_row *row)
21318 if (!row->reversed_p)
21320 for (struct glyph *g = row->glyphs[TEXT_AREA];
21321 g < row->glyphs[TEXT_AREA] + row->used[TEXT_AREA];
21322 g++)
21323 if (!NILP (g->object) || g->charpos > 0)
21324 return false;
21326 else
21328 for (struct glyph *g = row->glyphs[TEXT_AREA] + row->used[TEXT_AREA] - 1;
21329 g > row->glyphs[TEXT_AREA];
21330 g--)
21331 if (!NILP ((g - 1)->object) || (g - 1)->charpos > 0)
21332 return false;
21335 return true;
21338 /* Construct the glyph row IT->glyph_row in the desired matrix of
21339 IT->w from text at the current position of IT. See dispextern.h
21340 for an overview of struct it. Value is true if
21341 IT->glyph_row displays text, as opposed to a line displaying ZV
21342 only. CURSOR_VPOS is the window-relative vertical position of
21343 the glyph row displaying the cursor, or -1 if unknown. */
21345 static bool
21346 display_line (struct it *it, int cursor_vpos)
21348 struct glyph_row *row = it->glyph_row;
21349 Lisp_Object overlay_arrow_string;
21350 struct it wrap_it;
21351 void *wrap_data = NULL;
21352 bool may_wrap = false;
21353 int wrap_x UNINIT;
21354 int wrap_row_used = -1;
21355 int wrap_row_ascent UNINIT, wrap_row_height UNINIT;
21356 int wrap_row_phys_ascent UNINIT, wrap_row_phys_height UNINIT;
21357 int wrap_row_extra_line_spacing UNINIT;
21358 ptrdiff_t wrap_row_min_pos UNINIT, wrap_row_min_bpos UNINIT;
21359 ptrdiff_t wrap_row_max_pos UNINIT, wrap_row_max_bpos UNINIT;
21360 int cvpos;
21361 ptrdiff_t min_pos = ZV + 1, max_pos = 0;
21362 ptrdiff_t min_bpos UNINIT, max_bpos UNINIT;
21363 bool pending_handle_line_prefix = false;
21364 int header_line = window_wants_header_line (it->w);
21365 bool hscroll_this_line = (cursor_vpos >= 0
21366 && it->vpos == cursor_vpos - header_line
21367 && hscrolling_current_line_p (it->w));
21368 int first_visible_x = it->first_visible_x;
21369 int last_visible_x = it->last_visible_x;
21370 int x_incr = 0;
21372 /* We always start displaying at hpos zero even if hscrolled. */
21373 eassert (it->hpos == 0 && it->current_x == 0);
21375 if (MATRIX_ROW_VPOS (row, it->w->desired_matrix)
21376 >= it->w->desired_matrix->nrows)
21378 it->w->nrows_scale_factor++;
21379 it->f->fonts_changed = true;
21380 return false;
21383 /* Clear the result glyph row and enable it. */
21384 prepare_desired_row (it->w, row, false);
21386 row->y = it->current_y;
21387 row->start = it->start;
21388 row->continuation_lines_width = it->continuation_lines_width;
21389 row->displays_text_p = true;
21390 row->starts_in_middle_of_char_p = it->starts_in_middle_of_char_p;
21391 it->starts_in_middle_of_char_p = false;
21392 it->tab_offset = 0;
21393 it->line_number_produced_p = false;
21395 /* Arrange the overlays nicely for our purposes. Usually, we call
21396 display_line on only one line at a time, in which case this
21397 can't really hurt too much, or we call it on lines which appear
21398 one after another in the buffer, in which case all calls to
21399 recenter_overlay_lists but the first will be pretty cheap. */
21400 recenter_overlay_lists (current_buffer, IT_CHARPOS (*it));
21402 /* If we are going to display the cursor's line, account for the
21403 hscroll of that line. We subtract the window's min_hscroll,
21404 because that was already accounted for in init_iterator. */
21405 if (hscroll_this_line)
21406 x_incr =
21407 (window_hscroll_limited (it->w, it->f) - it->w->min_hscroll)
21408 * FRAME_COLUMN_WIDTH (it->f);
21410 bool line_number_needed = should_produce_line_number (it);
21412 /* Move over display elements that are not visible because we are
21413 hscrolled. This may stop at an x-position < first_visible_x
21414 if the first glyph is partially visible or if we hit a line end. */
21415 if (it->current_x < it->first_visible_x + x_incr)
21417 enum move_it_result move_result;
21419 this_line_min_pos = row->start.pos;
21420 if (hscroll_this_line)
21422 it->first_visible_x += x_incr;
21423 it->last_visible_x += x_incr;
21425 move_result = move_it_in_display_line_to (it, ZV, it->first_visible_x,
21426 MOVE_TO_POS | MOVE_TO_X);
21427 /* If we are under a large hscroll, move_it_in_display_line_to
21428 could hit the end of the line without reaching
21429 first_visible_x. Pretend that we did reach it. This is
21430 especially important on a TTY, where we will call
21431 extend_face_to_end_of_line, which needs to know how many
21432 blank glyphs to produce. */
21433 if (it->current_x < it->first_visible_x
21434 && (move_result == MOVE_NEWLINE_OR_CR
21435 || move_result == MOVE_POS_MATCH_OR_ZV))
21436 it->current_x = it->first_visible_x;
21438 /* In case move_it_in_display_line_to above "produced" the line
21439 number. */
21440 it->line_number_produced_p = false;
21442 /* Record the smallest positions seen while we moved over
21443 display elements that are not visible. This is needed by
21444 redisplay_internal for optimizing the case where the cursor
21445 stays inside the same line. The rest of this function only
21446 considers positions that are actually displayed, so
21447 RECORD_MAX_MIN_POS will not otherwise record positions that
21448 are hscrolled to the left of the left edge of the window. */
21449 min_pos = CHARPOS (this_line_min_pos);
21450 min_bpos = BYTEPOS (this_line_min_pos);
21452 /* Produce line number, if needed. */
21453 if (line_number_needed)
21454 maybe_produce_line_number (it);
21456 else if (it->area == TEXT_AREA)
21458 /* Line numbers should precede the line-prefix or wrap-prefix. */
21459 if (line_number_needed)
21460 maybe_produce_line_number (it);
21462 /* We only do this when not calling move_it_in_display_line_to
21463 above, because that function calls itself handle_line_prefix. */
21464 handle_line_prefix (it);
21466 else
21468 /* Line-prefix and wrap-prefix are always displayed in the text
21469 area. But if this is the first call to display_line after
21470 init_iterator, the iterator might have been set up to write
21471 into a marginal area, e.g. if the line begins with some
21472 display property that writes to the margins. So we need to
21473 wait with the call to handle_line_prefix until whatever
21474 writes to the margin has done its job. */
21475 pending_handle_line_prefix = true;
21478 /* Get the initial row height. This is either the height of the
21479 text hscrolled, if there is any, or zero. */
21480 row->ascent = it->max_ascent;
21481 row->height = it->max_ascent + it->max_descent;
21482 row->phys_ascent = it->max_phys_ascent;
21483 row->phys_height = it->max_phys_ascent + it->max_phys_descent;
21484 row->extra_line_spacing = it->max_extra_line_spacing;
21486 /* Utility macro to record max and min buffer positions seen until now. */
21487 #define RECORD_MAX_MIN_POS(IT) \
21488 do \
21490 bool composition_p \
21491 = !STRINGP ((IT)->string) && ((IT)->what == IT_COMPOSITION); \
21492 ptrdiff_t current_pos = \
21493 composition_p ? (IT)->cmp_it.charpos \
21494 : IT_CHARPOS (*(IT)); \
21495 ptrdiff_t current_bpos = \
21496 composition_p ? CHAR_TO_BYTE (current_pos) \
21497 : IT_BYTEPOS (*(IT)); \
21498 if (current_pos < min_pos) \
21500 min_pos = current_pos; \
21501 min_bpos = current_bpos; \
21503 if (IT_CHARPOS (*it) > max_pos) \
21505 max_pos = IT_CHARPOS (*it); \
21506 max_bpos = IT_BYTEPOS (*it); \
21509 while (false)
21511 /* Loop generating characters. The loop is left with IT on the next
21512 character to display. */
21513 while (true)
21515 int n_glyphs_before, hpos_before, x_before;
21516 int x, nglyphs;
21517 int ascent = 0, descent = 0, phys_ascent = 0, phys_descent = 0;
21519 /* Retrieve the next thing to display. Value is false if end of
21520 buffer reached. */
21521 if (!get_next_display_element (it))
21523 bool row_has_glyphs = false;
21524 /* Maybe add a space at the end of this line that is used to
21525 display the cursor there under X. Set the charpos of the
21526 first glyph of blank lines not corresponding to any text
21527 to -1. */
21528 if (IT_OVERFLOW_NEWLINE_INTO_FRINGE (it))
21529 row->exact_window_width_line_p = true;
21530 else if ((append_space_for_newline (it, true)
21531 && row->used[TEXT_AREA] == 1)
21532 || row->used[TEXT_AREA] == 0
21533 || (row_has_glyphs = row_text_area_empty (row)))
21535 row->glyphs[TEXT_AREA]->charpos = -1;
21536 /* Don't reset the displays_text_p flag if we are
21537 displaying line numbers or line-prefix. */
21538 if (!row_has_glyphs)
21539 row->displays_text_p = false;
21541 if (!NILP (BVAR (XBUFFER (it->w->contents), indicate_empty_lines))
21542 && (!MINI_WINDOW_P (it->w)))
21543 row->indicate_empty_line_p = true;
21546 it->continuation_lines_width = 0;
21547 /* Reset those iterator values set from display property
21548 values. This is for the case when the display property
21549 ends at ZV, and is not a replacing property, so pop_it is
21550 not called. */
21551 it->font_height = Qnil;
21552 it->voffset = 0;
21553 row->ends_at_zv_p = true;
21554 /* A row that displays right-to-left text must always have
21555 its last face extended all the way to the end of line,
21556 even if this row ends in ZV, because we still write to
21557 the screen left to right. We also need to extend the
21558 last face if the default face is remapped to some
21559 different face, otherwise the functions that clear
21560 portions of the screen will clear with the default face's
21561 background color. */
21562 if (row->reversed_p
21563 || lookup_basic_face (it->w, it->f, DEFAULT_FACE_ID)
21564 != DEFAULT_FACE_ID)
21565 extend_face_to_end_of_line (it);
21566 break;
21569 /* Now, get the metrics of what we want to display. This also
21570 generates glyphs in `row' (which is IT->glyph_row). */
21571 n_glyphs_before = row->used[TEXT_AREA];
21572 x = it->current_x;
21574 /* Remember the line height so far in case the next element doesn't
21575 fit on the line. */
21576 if (it->line_wrap != TRUNCATE)
21578 ascent = it->max_ascent;
21579 descent = it->max_descent;
21580 phys_ascent = it->max_phys_ascent;
21581 phys_descent = it->max_phys_descent;
21583 if (it->line_wrap == WORD_WRAP && it->area == TEXT_AREA)
21585 if (IT_DISPLAYING_WHITESPACE (it))
21586 may_wrap = true;
21587 else if (may_wrap)
21589 SAVE_IT (wrap_it, *it, wrap_data);
21590 wrap_x = x;
21591 wrap_row_used = row->used[TEXT_AREA];
21592 wrap_row_ascent = row->ascent;
21593 wrap_row_height = row->height;
21594 wrap_row_phys_ascent = row->phys_ascent;
21595 wrap_row_phys_height = row->phys_height;
21596 wrap_row_extra_line_spacing = row->extra_line_spacing;
21597 wrap_row_min_pos = min_pos;
21598 wrap_row_min_bpos = min_bpos;
21599 wrap_row_max_pos = max_pos;
21600 wrap_row_max_bpos = max_bpos;
21601 may_wrap = false;
21606 PRODUCE_GLYPHS (it);
21608 /* If this display element was in marginal areas, continue with
21609 the next one. */
21610 if (it->area != TEXT_AREA)
21612 row->ascent = max (row->ascent, it->max_ascent);
21613 row->height = max (row->height, it->max_ascent + it->max_descent);
21614 row->phys_ascent = max (row->phys_ascent, it->max_phys_ascent);
21615 row->phys_height = max (row->phys_height,
21616 it->max_phys_ascent + it->max_phys_descent);
21617 row->extra_line_spacing = max (row->extra_line_spacing,
21618 it->max_extra_line_spacing);
21619 set_iterator_to_next (it, true);
21620 /* If we didn't handle the line/wrap prefix above, and the
21621 call to set_iterator_to_next just switched to TEXT_AREA,
21622 process the prefix now. */
21623 if (it->area == TEXT_AREA && pending_handle_line_prefix)
21625 /* Line numbers should precede the line-prefix or wrap-prefix. */
21626 if (line_number_needed)
21627 maybe_produce_line_number (it);
21629 pending_handle_line_prefix = false;
21630 handle_line_prefix (it);
21632 continue;
21635 /* Does the display element fit on the line? If we truncate
21636 lines, we should draw past the right edge of the window. If
21637 we don't truncate, we want to stop so that we can display the
21638 continuation glyph before the right margin. If lines are
21639 continued, there are two possible strategies for characters
21640 resulting in more than 1 glyph (e.g. tabs): Display as many
21641 glyphs as possible in this line and leave the rest for the
21642 continuation line, or display the whole element in the next
21643 line. Original redisplay did the former, so we do it also. */
21644 nglyphs = row->used[TEXT_AREA] - n_glyphs_before;
21645 hpos_before = it->hpos;
21646 x_before = x;
21648 if (/* Not a newline. */
21649 nglyphs > 0
21650 /* Glyphs produced fit entirely in the line. */
21651 && it->current_x < it->last_visible_x)
21653 it->hpos += nglyphs;
21654 row->ascent = max (row->ascent, it->max_ascent);
21655 row->height = max (row->height, it->max_ascent + it->max_descent);
21656 row->phys_ascent = max (row->phys_ascent, it->max_phys_ascent);
21657 row->phys_height = max (row->phys_height,
21658 it->max_phys_ascent + it->max_phys_descent);
21659 row->extra_line_spacing = max (row->extra_line_spacing,
21660 it->max_extra_line_spacing);
21661 if (it->current_x - it->pixel_width < it->first_visible_x
21662 /* When line numbers are displayed, row->x should not be
21663 offset, as the first glyph after the line number can
21664 never be partially visible. */
21665 && !line_number_needed
21666 /* In R2L rows, we arrange in extend_face_to_end_of_line
21667 to add a right offset to the line, by a suitable
21668 change to the stretch glyph that is the leftmost
21669 glyph of the line. */
21670 && !row->reversed_p)
21671 row->x = x - it->first_visible_x;
21672 /* Record the maximum and minimum buffer positions seen so
21673 far in glyphs that will be displayed by this row. */
21674 if (it->bidi_p)
21675 RECORD_MAX_MIN_POS (it);
21677 else
21679 int i, new_x;
21680 struct glyph *glyph;
21682 for (i = 0; i < nglyphs; ++i, x = new_x)
21684 /* Identify the glyphs added by the last call to
21685 PRODUCE_GLYPHS. In R2L rows, they are prepended to
21686 the previous glyphs. */
21687 if (!row->reversed_p)
21688 glyph = row->glyphs[TEXT_AREA] + n_glyphs_before + i;
21689 else
21690 glyph = row->glyphs[TEXT_AREA] + nglyphs - 1 - i;
21691 new_x = x + glyph->pixel_width;
21693 if (/* Lines are continued. */
21694 it->line_wrap != TRUNCATE
21695 && (/* Glyph doesn't fit on the line. */
21696 new_x > it->last_visible_x
21697 /* Or it fits exactly on a window system frame. */
21698 || (new_x == it->last_visible_x
21699 && FRAME_WINDOW_P (it->f)
21700 && (row->reversed_p
21701 ? WINDOW_LEFT_FRINGE_WIDTH (it->w)
21702 : WINDOW_RIGHT_FRINGE_WIDTH (it->w)))))
21704 /* End of a continued line. */
21706 if (it->hpos == 0
21707 || (new_x == it->last_visible_x
21708 && FRAME_WINDOW_P (it->f)
21709 && (row->reversed_p
21710 ? WINDOW_LEFT_FRINGE_WIDTH (it->w)
21711 : WINDOW_RIGHT_FRINGE_WIDTH (it->w))))
21713 /* Current glyph is the only one on the line or
21714 fits exactly on the line. We must continue
21715 the line because we can't draw the cursor
21716 after the glyph. */
21717 row->continued_p = true;
21718 it->current_x = new_x;
21719 it->continuation_lines_width += new_x;
21720 ++it->hpos;
21721 if (i == nglyphs - 1)
21723 /* If line-wrap is on, check if a previous
21724 wrap point was found. */
21725 if (!IT_OVERFLOW_NEWLINE_INTO_FRINGE (it)
21726 && wrap_row_used > 0
21727 /* Even if there is a previous wrap
21728 point, continue the line here as
21729 usual, if (i) the previous character
21730 was a space or tab AND (ii) the
21731 current character is not. */
21732 && (!may_wrap
21733 || IT_DISPLAYING_WHITESPACE (it)))
21734 goto back_to_wrap;
21736 /* Record the maximum and minimum buffer
21737 positions seen so far in glyphs that will be
21738 displayed by this row. */
21739 if (it->bidi_p)
21740 RECORD_MAX_MIN_POS (it);
21741 set_iterator_to_next (it, true);
21742 if (IT_OVERFLOW_NEWLINE_INTO_FRINGE (it))
21744 if (!get_next_display_element (it))
21746 row->exact_window_width_line_p = true;
21747 it->continuation_lines_width = 0;
21748 it->font_height = Qnil;
21749 it->voffset = 0;
21750 row->continued_p = false;
21751 row->ends_at_zv_p = true;
21753 else if (ITERATOR_AT_END_OF_LINE_P (it))
21755 row->continued_p = false;
21756 row->exact_window_width_line_p = true;
21758 /* If line-wrap is on, check if a
21759 previous wrap point was found. */
21760 else if (wrap_row_used > 0
21761 /* Even if there is a previous wrap
21762 point, continue the line here as
21763 usual, if (i) the previous character
21764 was a space or tab AND (ii) the
21765 current character is not. */
21766 && (!may_wrap
21767 || IT_DISPLAYING_WHITESPACE (it)))
21768 goto back_to_wrap;
21772 else if (it->bidi_p)
21773 RECORD_MAX_MIN_POS (it);
21774 if (WINDOW_LEFT_MARGIN_WIDTH (it->w) > 0
21775 || WINDOW_RIGHT_MARGIN_WIDTH (it->w) > 0)
21776 extend_face_to_end_of_line (it);
21778 else if (CHAR_GLYPH_PADDING_P (*glyph)
21779 && !FRAME_WINDOW_P (it->f))
21781 /* A padding glyph that doesn't fit on this line.
21782 This means the whole character doesn't fit
21783 on the line. */
21784 if (row->reversed_p)
21785 unproduce_glyphs (it, row->used[TEXT_AREA]
21786 - n_glyphs_before);
21787 row->used[TEXT_AREA] = n_glyphs_before;
21789 /* Fill the rest of the row with continuation
21790 glyphs like in 20.x. */
21791 while (row->glyphs[TEXT_AREA] + row->used[TEXT_AREA]
21792 < row->glyphs[1 + TEXT_AREA])
21793 produce_special_glyphs (it, IT_CONTINUATION);
21795 row->continued_p = true;
21796 it->current_x = x_before;
21797 it->continuation_lines_width += x_before;
21799 /* Restore the height to what it was before the
21800 element not fitting on the line. */
21801 it->max_ascent = ascent;
21802 it->max_descent = descent;
21803 it->max_phys_ascent = phys_ascent;
21804 it->max_phys_descent = phys_descent;
21805 if (WINDOW_LEFT_MARGIN_WIDTH (it->w) > 0
21806 || WINDOW_RIGHT_MARGIN_WIDTH (it->w) > 0)
21807 extend_face_to_end_of_line (it);
21809 else if (wrap_row_used > 0)
21811 back_to_wrap:
21812 if (row->reversed_p)
21813 unproduce_glyphs (it,
21814 row->used[TEXT_AREA] - wrap_row_used);
21815 RESTORE_IT (it, &wrap_it, wrap_data);
21816 it->continuation_lines_width += wrap_x;
21817 row->used[TEXT_AREA] = wrap_row_used;
21818 row->ascent = wrap_row_ascent;
21819 row->height = wrap_row_height;
21820 row->phys_ascent = wrap_row_phys_ascent;
21821 row->phys_height = wrap_row_phys_height;
21822 row->extra_line_spacing = wrap_row_extra_line_spacing;
21823 min_pos = wrap_row_min_pos;
21824 min_bpos = wrap_row_min_bpos;
21825 max_pos = wrap_row_max_pos;
21826 max_bpos = wrap_row_max_bpos;
21827 row->continued_p = true;
21828 row->ends_at_zv_p = false;
21829 row->exact_window_width_line_p = false;
21831 /* Make sure that a non-default face is extended
21832 up to the right margin of the window. */
21833 extend_face_to_end_of_line (it);
21835 else if ((it->what == IT_CHARACTER
21836 || it->what == IT_STRETCH
21837 || it->what == IT_COMPOSITION)
21838 && it->c == '\t' && FRAME_WINDOW_P (it->f))
21840 /* A TAB that extends past the right edge of the
21841 window. This produces a single glyph on
21842 window system frames. We leave the glyph in
21843 this row and let it fill the row, but don't
21844 consume the TAB. */
21845 if ((row->reversed_p
21846 ? WINDOW_LEFT_FRINGE_WIDTH (it->w)
21847 : WINDOW_RIGHT_FRINGE_WIDTH (it->w)) == 0)
21848 produce_special_glyphs (it, IT_CONTINUATION);
21849 it->continuation_lines_width += it->last_visible_x;
21850 row->ends_in_middle_of_char_p = true;
21851 row->continued_p = true;
21852 glyph->pixel_width = it->last_visible_x - x;
21853 it->starts_in_middle_of_char_p = true;
21854 if (WINDOW_LEFT_MARGIN_WIDTH (it->w) > 0
21855 || WINDOW_RIGHT_MARGIN_WIDTH (it->w) > 0)
21856 extend_face_to_end_of_line (it);
21858 else
21860 /* Something other than a TAB that draws past
21861 the right edge of the window. Restore
21862 positions to values before the element. */
21863 if (row->reversed_p)
21864 unproduce_glyphs (it, row->used[TEXT_AREA]
21865 - (n_glyphs_before + i));
21866 row->used[TEXT_AREA] = n_glyphs_before + i;
21868 /* Display continuation glyphs. */
21869 it->current_x = x_before;
21870 it->continuation_lines_width += x;
21871 if (!FRAME_WINDOW_P (it->f)
21872 || (row->reversed_p
21873 ? WINDOW_LEFT_FRINGE_WIDTH (it->w)
21874 : WINDOW_RIGHT_FRINGE_WIDTH (it->w)) == 0)
21875 produce_special_glyphs (it, IT_CONTINUATION);
21876 row->continued_p = true;
21878 extend_face_to_end_of_line (it);
21880 if (nglyphs > 1 && i > 0)
21882 row->ends_in_middle_of_char_p = true;
21883 it->starts_in_middle_of_char_p = true;
21886 /* Restore the height to what it was before the
21887 element not fitting on the line. */
21888 it->max_ascent = ascent;
21889 it->max_descent = descent;
21890 it->max_phys_ascent = phys_ascent;
21891 it->max_phys_descent = phys_descent;
21894 break;
21896 else if (new_x > it->first_visible_x)
21898 /* Increment number of glyphs actually displayed. */
21899 ++it->hpos;
21901 /* Record the maximum and minimum buffer positions
21902 seen so far in glyphs that will be displayed by
21903 this row. */
21904 if (it->bidi_p)
21905 RECORD_MAX_MIN_POS (it);
21907 if (x < it->first_visible_x && !row->reversed_p
21908 && !line_number_needed)
21909 /* Glyph is partially visible, i.e. row starts at
21910 negative X position. Don't do that in R2L
21911 rows, where we arrange to add a right offset to
21912 the line in extend_face_to_end_of_line, by a
21913 suitable change to the stretch glyph that is
21914 the leftmost glyph of the line. */
21915 row->x = x - it->first_visible_x;
21916 /* When the last glyph of an R2L row only fits
21917 partially on the line, we need to set row->x to a
21918 negative offset, so that the leftmost glyph is
21919 the one that is partially visible. But if we are
21920 going to produce the truncation glyph, this will
21921 be taken care of in produce_special_glyphs. */
21922 if (row->reversed_p
21923 && new_x > it->last_visible_x
21924 && !line_number_needed
21925 && !(it->line_wrap == TRUNCATE
21926 && WINDOW_LEFT_FRINGE_WIDTH (it->w) == 0))
21928 eassert (FRAME_WINDOW_P (it->f));
21929 row->x = it->last_visible_x - new_x;
21932 else
21934 /* Glyph is completely off the left margin of the
21935 window. This should not happen because of the
21936 move_it_in_display_line at the start of this
21937 function, unless the text display area of the
21938 window is empty. */
21939 eassert (it->first_visible_x <= it->last_visible_x);
21942 /* Even if this display element produced no glyphs at all,
21943 we want to record its position. */
21944 if (it->bidi_p && nglyphs == 0)
21945 RECORD_MAX_MIN_POS (it);
21947 row->ascent = max (row->ascent, it->max_ascent);
21948 row->height = max (row->height, it->max_ascent + it->max_descent);
21949 row->phys_ascent = max (row->phys_ascent, it->max_phys_ascent);
21950 row->phys_height = max (row->phys_height,
21951 it->max_phys_ascent + it->max_phys_descent);
21952 row->extra_line_spacing = max (row->extra_line_spacing,
21953 it->max_extra_line_spacing);
21955 /* End of this display line if row is continued. */
21956 if (row->continued_p || row->ends_at_zv_p)
21957 break;
21960 at_end_of_line:
21961 /* Is this a line end? If yes, we're also done, after making
21962 sure that a non-default face is extended up to the right
21963 margin of the window. */
21964 if (ITERATOR_AT_END_OF_LINE_P (it))
21966 int used_before = row->used[TEXT_AREA];
21968 row->ends_in_newline_from_string_p = STRINGP (it->object);
21970 /* Add a space at the end of the line that is used to
21971 display the cursor there. */
21972 if (!IT_OVERFLOW_NEWLINE_INTO_FRINGE (it))
21973 append_space_for_newline (it, false);
21975 /* Extend the face to the end of the line. */
21976 extend_face_to_end_of_line (it);
21978 /* Make sure we have the position. */
21979 if (used_before == 0)
21980 row->glyphs[TEXT_AREA]->charpos = CHARPOS (it->position);
21982 /* Record the position of the newline, for use in
21983 find_row_edges. */
21984 it->eol_pos = it->current.pos;
21986 /* Consume the line end. This skips over invisible lines. */
21987 set_iterator_to_next (it, true);
21988 it->continuation_lines_width = 0;
21989 break;
21992 /* Detect overly-wide wrap-prefixes made of (space ...) display
21993 properties. When such a wrap prefix reaches past the right
21994 margin of the window, we need to avoid the call to
21995 set_iterator_to_next below, so that it->line_wrap is left at
21996 its TRUNCATE value wisely set by handle_line_prefix.
21997 Otherwise, set_iterator_to_next will pop the iterator stack,
21998 restore it->line_wrap, and redisplay might infloop. */
21999 bool overwide_wrap_prefix =
22000 CONSP (it->object) && EQ (XCAR (it->object), Qspace)
22001 && it->sp > 0 && it->method == GET_FROM_STRETCH
22002 && it->current_x >= it->last_visible_x
22003 && it->continuation_lines_width > 0
22004 && it->line_wrap == TRUNCATE && it->stack[0].line_wrap != TRUNCATE;
22006 /* Proceed with next display element. Note that this skips
22007 over lines invisible because of selective display. */
22008 if (!overwide_wrap_prefix)
22009 set_iterator_to_next (it, true);
22011 /* If we truncate lines, we are done when the last displayed
22012 glyphs reach past the right margin of the window. */
22013 if (it->line_wrap == TRUNCATE
22014 && ((FRAME_WINDOW_P (it->f)
22015 /* Images are preprocessed in produce_image_glyph such
22016 that they are cropped at the right edge of the
22017 window, so an image glyph will always end exactly at
22018 last_visible_x, even if there's no right fringe. */
22019 && ((row->reversed_p
22020 ? WINDOW_LEFT_FRINGE_WIDTH (it->w)
22021 : WINDOW_RIGHT_FRINGE_WIDTH (it->w))
22022 || it->what == IT_IMAGE))
22023 ? (it->current_x >= it->last_visible_x)
22024 : (it->current_x > it->last_visible_x)))
22026 /* Maybe add truncation glyphs. */
22027 if (!FRAME_WINDOW_P (it->f)
22028 || (row->reversed_p
22029 ? WINDOW_LEFT_FRINGE_WIDTH (it->w)
22030 : WINDOW_RIGHT_FRINGE_WIDTH (it->w)) == 0)
22032 int i, n;
22034 if (!row->reversed_p)
22036 for (i = row->used[TEXT_AREA] - 1; i > 0; --i)
22037 if (!CHAR_GLYPH_PADDING_P (row->glyphs[TEXT_AREA][i]))
22038 break;
22040 else
22042 for (i = 0; i < row->used[TEXT_AREA]; i++)
22043 if (!CHAR_GLYPH_PADDING_P (row->glyphs[TEXT_AREA][i]))
22044 break;
22045 /* Remove any padding glyphs at the front of ROW, to
22046 make room for the truncation glyphs we will be
22047 adding below. The loop below always inserts at
22048 least one truncation glyph, so also remove the
22049 last glyph added to ROW. */
22050 unproduce_glyphs (it, i + 1);
22051 /* Adjust i for the loop below. */
22052 i = row->used[TEXT_AREA] - (i + 1);
22055 /* produce_special_glyphs overwrites the last glyph, so
22056 we don't want that if we want to keep that last
22057 glyph, which means it's an image. */
22058 if (it->current_x > it->last_visible_x)
22060 it->current_x = x_before;
22061 if (!FRAME_WINDOW_P (it->f))
22063 for (n = row->used[TEXT_AREA]; i < n; ++i)
22065 row->used[TEXT_AREA] = i;
22066 produce_special_glyphs (it, IT_TRUNCATION);
22069 else
22071 row->used[TEXT_AREA] = i;
22072 produce_special_glyphs (it, IT_TRUNCATION);
22074 it->hpos = hpos_before;
22077 else if (IT_OVERFLOW_NEWLINE_INTO_FRINGE (it))
22079 /* Don't truncate if we can overflow newline into fringe. */
22080 if (!get_next_display_element (it))
22082 it->continuation_lines_width = 0;
22083 it->font_height = Qnil;
22084 it->voffset = 0;
22085 row->ends_at_zv_p = true;
22086 row->exact_window_width_line_p = true;
22087 break;
22089 if (ITERATOR_AT_END_OF_LINE_P (it))
22091 row->exact_window_width_line_p = true;
22092 goto at_end_of_line;
22094 it->current_x = x_before;
22095 it->hpos = hpos_before;
22098 row->truncated_on_right_p = true;
22099 it->continuation_lines_width = 0;
22100 reseat_at_next_visible_line_start (it, false);
22101 /* We insist below that IT's position be at ZV because in
22102 bidi-reordered lines the character at visible line start
22103 might not be the character that follows the newline in
22104 the logical order. */
22105 if (IT_BYTEPOS (*it) > BEG_BYTE)
22106 row->ends_at_zv_p =
22107 IT_BYTEPOS (*it) >= ZV_BYTE && FETCH_BYTE (ZV_BYTE - 1) != '\n';
22108 else
22109 row->ends_at_zv_p = false;
22110 break;
22114 if (wrap_data)
22115 bidi_unshelve_cache (wrap_data, true);
22117 /* If line is not empty and hscrolled, maybe insert truncation glyphs
22118 at the left window margin. */
22119 if (it->first_visible_x
22120 && IT_CHARPOS (*it) != CHARPOS (row->start.pos))
22122 if (!FRAME_WINDOW_P (it->f)
22123 || (((row->reversed_p
22124 ? WINDOW_RIGHT_FRINGE_WIDTH (it->w)
22125 : WINDOW_LEFT_FRINGE_WIDTH (it->w)) == 0)
22126 /* Don't let insert_left_trunc_glyphs overwrite the
22127 first glyph of the row if it is an image. */
22128 && row->glyphs[TEXT_AREA]->type != IMAGE_GLYPH))
22129 insert_left_trunc_glyphs (it);
22130 row->truncated_on_left_p = true;
22133 /* Remember the position at which this line ends.
22135 BIDI Note: any code that needs MATRIX_ROW_START/END_CHARPOS
22136 cannot be before the call to find_row_edges below, since that is
22137 where these positions are determined. */
22138 row->end = it->current;
22139 if (!it->bidi_p)
22141 row->minpos = row->start.pos;
22142 row->maxpos = row->end.pos;
22144 else
22146 /* ROW->minpos and ROW->maxpos must be the smallest and
22147 `1 + the largest' buffer positions in ROW. But if ROW was
22148 bidi-reordered, these two positions can be anywhere in the
22149 row, so we must determine them now. */
22150 find_row_edges (it, row, min_pos, min_bpos, max_pos, max_bpos);
22153 /* If the start of this line is the overlay arrow-position, then
22154 mark this glyph row as the one containing the overlay arrow.
22155 This is clearly a mess with variable size fonts. It would be
22156 better to let it be displayed like cursors under X. */
22157 if ((MATRIX_ROW_DISPLAYS_TEXT_P (row) || !overlay_arrow_seen)
22158 && (overlay_arrow_string = overlay_arrow_at_row (it, row),
22159 !NILP (overlay_arrow_string)))
22161 /* Overlay arrow in window redisplay is a fringe bitmap. */
22162 if (STRINGP (overlay_arrow_string))
22164 struct glyph_row *arrow_row
22165 = get_overlay_arrow_glyph_row (it->w, overlay_arrow_string);
22166 struct glyph *glyph = arrow_row->glyphs[TEXT_AREA];
22167 struct glyph *arrow_end = glyph + arrow_row->used[TEXT_AREA];
22168 struct glyph *p = row->glyphs[TEXT_AREA];
22169 struct glyph *p2, *end;
22171 /* Copy the arrow glyphs. */
22172 while (glyph < arrow_end)
22173 *p++ = *glyph++;
22175 /* Throw away padding glyphs. */
22176 p2 = p;
22177 end = row->glyphs[TEXT_AREA] + row->used[TEXT_AREA];
22178 while (p2 < end && CHAR_GLYPH_PADDING_P (*p2))
22179 ++p2;
22180 if (p2 > p)
22182 while (p2 < end)
22183 *p++ = *p2++;
22184 row->used[TEXT_AREA] = p2 - row->glyphs[TEXT_AREA];
22187 else
22189 eassert (INTEGERP (overlay_arrow_string));
22190 row->overlay_arrow_bitmap = XINT (overlay_arrow_string);
22192 overlay_arrow_seen = true;
22195 /* Highlight trailing whitespace. */
22196 if (!NILP (Vshow_trailing_whitespace))
22197 highlight_trailing_whitespace (it);
22199 /* Compute pixel dimensions of this line. */
22200 compute_line_metrics (it);
22202 /* Implementation note: No changes in the glyphs of ROW or in their
22203 faces can be done past this point, because compute_line_metrics
22204 computes ROW's hash value and stores it within the glyph_row
22205 structure. */
22207 /* Record whether this row ends inside an ellipsis. */
22208 row->ends_in_ellipsis_p
22209 = (it->method == GET_FROM_DISPLAY_VECTOR
22210 && it->ellipsis_p);
22212 /* Save fringe bitmaps in this row. */
22213 row->left_user_fringe_bitmap = it->left_user_fringe_bitmap;
22214 row->left_user_fringe_face_id = it->left_user_fringe_face_id;
22215 row->right_user_fringe_bitmap = it->right_user_fringe_bitmap;
22216 row->right_user_fringe_face_id = it->right_user_fringe_face_id;
22218 it->left_user_fringe_bitmap = 0;
22219 it->left_user_fringe_face_id = 0;
22220 it->right_user_fringe_bitmap = 0;
22221 it->right_user_fringe_face_id = 0;
22223 /* Maybe set the cursor. */
22224 cvpos = it->w->cursor.vpos;
22225 if ((cvpos < 0
22226 /* In bidi-reordered rows, keep checking for proper cursor
22227 position even if one has been found already, because buffer
22228 positions in such rows change non-linearly with ROW->VPOS,
22229 when a line is continued. One exception: when we are at ZV,
22230 display cursor on the first suitable glyph row, since all
22231 the empty rows after that also have their position set to ZV. */
22232 /* FIXME: Revisit this when glyph ``spilling'' in continuation
22233 lines' rows is implemented for bidi-reordered rows. */
22234 || (it->bidi_p
22235 && !MATRIX_ROW (it->w->desired_matrix, cvpos)->ends_at_zv_p))
22236 && PT >= MATRIX_ROW_START_CHARPOS (row)
22237 && PT <= MATRIX_ROW_END_CHARPOS (row)
22238 && cursor_row_p (row))
22239 set_cursor_from_row (it->w, row, it->w->desired_matrix, 0, 0, 0, 0);
22241 /* Prepare for the next line. This line starts horizontally at (X
22242 HPOS) = (0 0). Vertical positions are incremented. As a
22243 convenience for the caller, IT->glyph_row is set to the next
22244 row to be used. */
22245 it->current_x = it->hpos = 0;
22246 it->current_y += row->height;
22247 /* Restore the first and last visible X if we adjusted them for
22248 current-line hscrolling. */
22249 if (hscroll_this_line)
22251 it->first_visible_x = first_visible_x;
22252 it->last_visible_x = last_visible_x;
22254 SET_TEXT_POS (it->eol_pos, 0, 0);
22255 ++it->vpos;
22256 ++it->glyph_row;
22257 /* The next row should by default use the same value of the
22258 reversed_p flag as this one. set_iterator_to_next decides when
22259 it's a new paragraph, and PRODUCE_GLYPHS recomputes the value of
22260 the flag accordingly. */
22261 if (it->glyph_row < MATRIX_BOTTOM_TEXT_ROW (it->w->desired_matrix, it->w))
22262 it->glyph_row->reversed_p = row->reversed_p;
22263 it->start = row->end;
22264 return MATRIX_ROW_DISPLAYS_TEXT_P (row);
22266 #undef RECORD_MAX_MIN_POS
22269 DEFUN ("current-bidi-paragraph-direction", Fcurrent_bidi_paragraph_direction,
22270 Scurrent_bidi_paragraph_direction, 0, 1, 0,
22271 doc: /* Return paragraph direction at point in BUFFER.
22272 Value is either `left-to-right' or `right-to-left'.
22273 If BUFFER is omitted or nil, it defaults to the current buffer.
22275 Paragraph direction determines how the text in the paragraph is displayed.
22276 In left-to-right paragraphs, text begins at the left margin of the window
22277 and the reading direction is generally left to right. In right-to-left
22278 paragraphs, text begins at the right margin and is read from right to left.
22280 See also `bidi-paragraph-direction'. */)
22281 (Lisp_Object buffer)
22283 struct buffer *buf = current_buffer;
22284 struct buffer *old = buf;
22286 if (! NILP (buffer))
22288 CHECK_BUFFER (buffer);
22289 buf = XBUFFER (buffer);
22292 if (NILP (BVAR (buf, bidi_display_reordering))
22293 || NILP (BVAR (buf, enable_multibyte_characters))
22294 /* When we are loading loadup.el, the character property tables
22295 needed for bidi iteration are not yet available. */
22296 || redisplay__inhibit_bidi)
22297 return Qleft_to_right;
22298 else if (!NILP (BVAR (buf, bidi_paragraph_direction)))
22299 return BVAR (buf, bidi_paragraph_direction);
22300 else
22302 /* Determine the direction from buffer text. We could try to
22303 use current_matrix if it is up to date, but this seems fast
22304 enough as it is. */
22305 struct bidi_it itb;
22306 ptrdiff_t pos = BUF_PT (buf);
22307 ptrdiff_t bytepos = BUF_PT_BYTE (buf);
22308 int c;
22309 void *itb_data = bidi_shelve_cache ();
22311 set_buffer_temp (buf);
22312 /* bidi_paragraph_init finds the base direction of the paragraph
22313 by searching forward from paragraph start. We need the base
22314 direction of the current or _previous_ paragraph, so we need
22315 to make sure we are within that paragraph. To that end, find
22316 the previous non-empty line. */
22317 if (pos >= ZV && pos > BEGV)
22318 DEC_BOTH (pos, bytepos);
22319 AUTO_STRING (trailing_white_space, "[\f\t ]*\n");
22320 if (fast_looking_at (trailing_white_space,
22321 pos, bytepos, ZV, ZV_BYTE, Qnil) > 0)
22323 while ((c = FETCH_BYTE (bytepos)) == '\n'
22324 || c == ' ' || c == '\t' || c == '\f')
22326 if (bytepos <= BEGV_BYTE)
22327 break;
22328 bytepos--;
22329 pos--;
22331 while (!CHAR_HEAD_P (FETCH_BYTE (bytepos)))
22332 bytepos--;
22334 bidi_init_it (pos, bytepos, FRAME_WINDOW_P (SELECTED_FRAME ()), &itb);
22335 itb.paragraph_dir = NEUTRAL_DIR;
22336 itb.string.s = NULL;
22337 itb.string.lstring = Qnil;
22338 itb.string.bufpos = 0;
22339 itb.string.from_disp_str = false;
22340 itb.string.unibyte = false;
22341 /* We have no window to use here for ignoring window-specific
22342 overlays. Using NULL for window pointer will cause
22343 compute_display_string_pos to use the current buffer. */
22344 itb.w = NULL;
22345 bidi_paragraph_init (NEUTRAL_DIR, &itb, true);
22346 bidi_unshelve_cache (itb_data, false);
22347 set_buffer_temp (old);
22348 switch (itb.paragraph_dir)
22350 case L2R:
22351 return Qleft_to_right;
22352 break;
22353 case R2L:
22354 return Qright_to_left;
22355 break;
22356 default:
22357 emacs_abort ();
22362 DEFUN ("bidi-find-overridden-directionality",
22363 Fbidi_find_overridden_directionality,
22364 Sbidi_find_overridden_directionality, 2, 3, 0,
22365 doc: /* Return position between FROM and TO where directionality was overridden.
22367 This function returns the first character position in the specified
22368 region of OBJECT where there is a character whose `bidi-class' property
22369 is `L', but which was forced to display as `R' by a directional
22370 override, and likewise with characters whose `bidi-class' is `R'
22371 or `AL' that were forced to display as `L'.
22373 If no such character is found, the function returns nil.
22375 OBJECT is a Lisp string or buffer to search for overridden
22376 directionality, and defaults to the current buffer if nil or omitted.
22377 OBJECT can also be a window, in which case the function will search
22378 the buffer displayed in that window. Passing the window instead of
22379 a buffer is preferable when the buffer is displayed in some window,
22380 because this function will then be able to correctly account for
22381 window-specific overlays, which can affect the results.
22383 Strong directional characters `L', `R', and `AL' can have their
22384 intrinsic directionality overridden by directional override
22385 control characters RLO (u+202e) and LRO (u+202d). See the
22386 function `get-char-code-property' for a way to inquire about
22387 the `bidi-class' property of a character. */)
22388 (Lisp_Object from, Lisp_Object to, Lisp_Object object)
22390 struct buffer *buf = current_buffer;
22391 struct buffer *old = buf;
22392 struct window *w = NULL;
22393 bool frame_window_p = FRAME_WINDOW_P (SELECTED_FRAME ());
22394 struct bidi_it itb;
22395 ptrdiff_t from_pos, to_pos, from_bpos;
22396 void *itb_data;
22398 if (!NILP (object))
22400 if (BUFFERP (object))
22401 buf = XBUFFER (object);
22402 else if (WINDOWP (object))
22404 w = decode_live_window (object);
22405 buf = XBUFFER (w->contents);
22406 frame_window_p = FRAME_WINDOW_P (XFRAME (w->frame));
22408 else
22409 CHECK_STRING (object);
22412 if (STRINGP (object))
22414 /* Characters in unibyte strings are always treated by bidi.c as
22415 strong LTR. */
22416 if (!STRING_MULTIBYTE (object)
22417 /* When we are loading loadup.el, the character property
22418 tables needed for bidi iteration are not yet
22419 available. */
22420 || redisplay__inhibit_bidi)
22421 return Qnil;
22423 validate_subarray (object, from, to, SCHARS (object), &from_pos, &to_pos);
22424 if (from_pos >= SCHARS (object))
22425 return Qnil;
22427 /* Set up the bidi iterator. */
22428 itb_data = bidi_shelve_cache ();
22429 itb.paragraph_dir = NEUTRAL_DIR;
22430 itb.string.lstring = object;
22431 itb.string.s = NULL;
22432 itb.string.schars = SCHARS (object);
22433 itb.string.bufpos = 0;
22434 itb.string.from_disp_str = false;
22435 itb.string.unibyte = false;
22436 itb.w = w;
22437 bidi_init_it (0, 0, frame_window_p, &itb);
22439 else
22441 /* Nothing this fancy can happen in unibyte buffers, or in a
22442 buffer that disabled reordering, or if FROM is at EOB. */
22443 if (NILP (BVAR (buf, bidi_display_reordering))
22444 || NILP (BVAR (buf, enable_multibyte_characters))
22445 /* When we are loading loadup.el, the character property
22446 tables needed for bidi iteration are not yet
22447 available. */
22448 || redisplay__inhibit_bidi)
22449 return Qnil;
22451 set_buffer_temp (buf);
22452 validate_region (&from, &to);
22453 from_pos = XINT (from);
22454 to_pos = XINT (to);
22455 if (from_pos >= ZV)
22456 return Qnil;
22458 /* Set up the bidi iterator. */
22459 itb_data = bidi_shelve_cache ();
22460 from_bpos = CHAR_TO_BYTE (from_pos);
22461 if (from_pos == BEGV)
22463 itb.charpos = BEGV;
22464 itb.bytepos = BEGV_BYTE;
22466 else if (FETCH_CHAR (from_bpos - 1) == '\n')
22468 itb.charpos = from_pos;
22469 itb.bytepos = from_bpos;
22471 else
22472 itb.charpos = find_newline_no_quit (from_pos, CHAR_TO_BYTE (from_pos),
22473 -1, &itb.bytepos);
22474 itb.paragraph_dir = NEUTRAL_DIR;
22475 itb.string.s = NULL;
22476 itb.string.lstring = Qnil;
22477 itb.string.bufpos = 0;
22478 itb.string.from_disp_str = false;
22479 itb.string.unibyte = false;
22480 itb.w = w;
22481 bidi_init_it (itb.charpos, itb.bytepos, frame_window_p, &itb);
22484 ptrdiff_t found;
22485 do {
22486 /* For the purposes of this function, the actual base direction of
22487 the paragraph doesn't matter, so just set it to L2R. */
22488 bidi_paragraph_init (L2R, &itb, false);
22489 while ((found = bidi_find_first_overridden (&itb)) < from_pos)
22491 } while (found == ZV && itb.ch == '\n' && itb.charpos < to_pos);
22493 bidi_unshelve_cache (itb_data, false);
22494 set_buffer_temp (old);
22496 return (from_pos <= found && found < to_pos) ? make_number (found) : Qnil;
22499 DEFUN ("move-point-visually", Fmove_point_visually,
22500 Smove_point_visually, 1, 1, 0,
22501 doc: /* Move point in the visual order in the specified DIRECTION.
22502 DIRECTION can be 1, meaning move to the right, or -1, which moves to the
22503 left.
22505 Value is the new character position of point. */)
22506 (Lisp_Object direction)
22508 struct window *w = XWINDOW (selected_window);
22509 struct buffer *b = XBUFFER (w->contents);
22510 struct glyph_row *row;
22511 int dir;
22512 Lisp_Object paragraph_dir;
22514 #define ROW_GLYPH_NEWLINE_P(ROW,GLYPH) \
22515 (!(ROW)->continued_p \
22516 && NILP ((GLYPH)->object) \
22517 && (GLYPH)->type == CHAR_GLYPH \
22518 && (GLYPH)->u.ch == ' ' \
22519 && (GLYPH)->charpos >= 0 \
22520 && !(GLYPH)->avoid_cursor_p)
22522 CHECK_NUMBER (direction);
22523 dir = XINT (direction);
22524 if (dir > 0)
22525 dir = 1;
22526 else
22527 dir = -1;
22529 /* If current matrix is up-to-date, we can use the information
22530 recorded in the glyphs, at least as long as the goal is on the
22531 screen. */
22532 if (w->window_end_valid
22533 && !windows_or_buffers_changed
22534 && b
22535 && !b->clip_changed
22536 && !b->prevent_redisplay_optimizations_p
22537 && !window_outdated (w)
22538 /* We rely below on the cursor coordinates to be up to date, but
22539 we cannot trust them if some command moved point since the
22540 last complete redisplay. */
22541 && w->last_point == BUF_PT (b)
22542 && w->cursor.vpos >= 0
22543 && w->cursor.vpos < w->current_matrix->nrows
22544 && (row = MATRIX_ROW (w->current_matrix, w->cursor.vpos))->enabled_p)
22546 struct glyph *g = row->glyphs[TEXT_AREA];
22547 struct glyph *e = dir > 0 ? g + row->used[TEXT_AREA] : g - 1;
22548 struct glyph *gpt = g + w->cursor.hpos;
22550 for (g = gpt + dir; (dir > 0 ? g < e : g > e); g += dir)
22552 if (BUFFERP (g->object) && g->charpos != PT)
22554 SET_PT (g->charpos);
22555 w->cursor.vpos = -1;
22556 return make_number (PT);
22558 else if (!NILP (g->object) && !EQ (g->object, gpt->object))
22560 ptrdiff_t new_pos;
22562 if (BUFFERP (gpt->object))
22564 new_pos = PT;
22565 if ((gpt->resolved_level - row->reversed_p) % 2 == 0)
22566 new_pos += (row->reversed_p ? -dir : dir);
22567 else
22568 new_pos -= (row->reversed_p ? -dir : dir);
22569 new_pos = clip_to_bounds (BEGV, new_pos, ZV);
22570 /* If we didn't move, we've hit BEGV or ZV, so we
22571 need to signal a suitable error. */
22572 if (new_pos == PT)
22573 break;
22575 else if (BUFFERP (g->object))
22576 new_pos = g->charpos;
22577 else
22578 break;
22579 SET_PT (new_pos);
22580 w->cursor.vpos = -1;
22581 return make_number (PT);
22583 else if (ROW_GLYPH_NEWLINE_P (row, g))
22585 /* Glyphs inserted at the end of a non-empty line for
22586 positioning the cursor have zero charpos, so we must
22587 deduce the value of point by other means. */
22588 if (g->charpos > 0)
22589 SET_PT (g->charpos);
22590 else if (row->ends_at_zv_p && PT != ZV)
22591 SET_PT (ZV);
22592 else if (PT != MATRIX_ROW_END_CHARPOS (row) - 1)
22593 SET_PT (MATRIX_ROW_END_CHARPOS (row) - 1);
22594 else
22595 break;
22596 w->cursor.vpos = -1;
22597 return make_number (PT);
22600 if (g == e || NILP (g->object))
22602 if (row->truncated_on_left_p || row->truncated_on_right_p)
22603 goto simulate_display;
22604 if (!row->reversed_p)
22605 row += dir;
22606 else
22607 row -= dir;
22608 if (!(MATRIX_FIRST_TEXT_ROW (w->current_matrix) <= row
22609 && row < MATRIX_BOTTOM_TEXT_ROW (w->current_matrix, w)))
22610 goto simulate_display;
22612 if (dir > 0)
22614 if (row->reversed_p && !row->continued_p)
22616 SET_PT (MATRIX_ROW_END_CHARPOS (row) - 1);
22617 w->cursor.vpos = -1;
22618 return make_number (PT);
22620 g = row->glyphs[TEXT_AREA];
22621 e = g + row->used[TEXT_AREA];
22622 for ( ; g < e; g++)
22624 if (BUFFERP (g->object)
22625 /* Empty lines have only one glyph, which stands
22626 for the newline, and whose charpos is the
22627 buffer position of the newline. */
22628 || ROW_GLYPH_NEWLINE_P (row, g)
22629 /* When the buffer ends in a newline, the line at
22630 EOB also has one glyph, but its charpos is -1. */
22631 || (row->ends_at_zv_p
22632 && !row->reversed_p
22633 && NILP (g->object)
22634 && g->type == CHAR_GLYPH
22635 && g->u.ch == ' '))
22637 if (g->charpos > 0)
22638 SET_PT (g->charpos);
22639 else if (!row->reversed_p
22640 && row->ends_at_zv_p
22641 && PT != ZV)
22642 SET_PT (ZV);
22643 else
22644 continue;
22645 w->cursor.vpos = -1;
22646 return make_number (PT);
22650 else
22652 if (!row->reversed_p && !row->continued_p)
22654 SET_PT (MATRIX_ROW_END_CHARPOS (row) - 1);
22655 w->cursor.vpos = -1;
22656 return make_number (PT);
22658 e = row->glyphs[TEXT_AREA];
22659 g = e + row->used[TEXT_AREA] - 1;
22660 for ( ; g >= e; g--)
22662 if (BUFFERP (g->object)
22663 || (ROW_GLYPH_NEWLINE_P (row, g)
22664 && g->charpos > 0)
22665 /* Empty R2L lines on GUI frames have the buffer
22666 position of the newline stored in the stretch
22667 glyph. */
22668 || g->type == STRETCH_GLYPH
22669 || (row->ends_at_zv_p
22670 && row->reversed_p
22671 && NILP (g->object)
22672 && g->type == CHAR_GLYPH
22673 && g->u.ch == ' '))
22675 if (g->charpos > 0)
22676 SET_PT (g->charpos);
22677 else if (row->reversed_p
22678 && row->ends_at_zv_p
22679 && PT != ZV)
22680 SET_PT (ZV);
22681 else
22682 continue;
22683 w->cursor.vpos = -1;
22684 return make_number (PT);
22691 simulate_display:
22693 /* If we wind up here, we failed to move by using the glyphs, so we
22694 need to simulate display instead. */
22696 if (b)
22697 paragraph_dir = Fcurrent_bidi_paragraph_direction (w->contents);
22698 else
22699 paragraph_dir = Qleft_to_right;
22700 if (EQ (paragraph_dir, Qright_to_left))
22701 dir = -dir;
22702 if (PT <= BEGV && dir < 0)
22703 xsignal0 (Qbeginning_of_buffer);
22704 else if (PT >= ZV && dir > 0)
22705 xsignal0 (Qend_of_buffer);
22706 else
22708 struct text_pos pt;
22709 struct it it;
22710 int pt_x, target_x, pixel_width, pt_vpos;
22711 bool at_eol_p;
22712 bool overshoot_expected = false;
22713 bool target_is_eol_p = false;
22715 /* Setup the arena. */
22716 SET_TEXT_POS (pt, PT, PT_BYTE);
22717 start_display (&it, w, pt);
22718 /* When lines are truncated, we could be called with point
22719 outside of the windows edges, in which case move_it_*
22720 functions either prematurely stop at window's edge or jump to
22721 the next screen line, whereas we rely below on our ability to
22722 reach point, in order to start from its X coordinate. So we
22723 need to disregard the window's horizontal extent in that case. */
22724 if (it.line_wrap == TRUNCATE)
22725 it.last_visible_x = DISP_INFINITY;
22727 if (it.cmp_it.id < 0
22728 && it.method == GET_FROM_STRING
22729 && it.area == TEXT_AREA
22730 && it.string_from_display_prop_p
22731 && (it.sp > 0 && it.stack[it.sp - 1].method == GET_FROM_BUFFER))
22732 overshoot_expected = true;
22734 /* Find the X coordinate of point. We start from the beginning
22735 of this or previous line to make sure we are before point in
22736 the logical order (since the move_it_* functions can only
22737 move forward). */
22738 reseat:
22739 reseat_at_previous_visible_line_start (&it);
22740 it.current_x = it.hpos = it.current_y = it.vpos = 0;
22741 if (IT_CHARPOS (it) != PT)
22743 move_it_to (&it, overshoot_expected ? PT - 1 : PT,
22744 -1, -1, -1, MOVE_TO_POS);
22745 /* If we missed point because the character there is
22746 displayed out of a display vector that has more than one
22747 glyph, retry expecting overshoot. */
22748 if (it.method == GET_FROM_DISPLAY_VECTOR
22749 && it.current.dpvec_index > 0
22750 && !overshoot_expected)
22752 overshoot_expected = true;
22753 goto reseat;
22755 else if (IT_CHARPOS (it) != PT && !overshoot_expected)
22756 move_it_in_display_line (&it, PT, -1, MOVE_TO_POS);
22758 pt_x = it.current_x;
22759 pt_vpos = it.vpos;
22760 if (dir > 0 || overshoot_expected)
22762 struct glyph_row *row = it.glyph_row;
22764 /* When point is at beginning of line, we don't have
22765 information about the glyph there loaded into struct
22766 it. Calling get_next_display_element fixes that. */
22767 if (pt_x == 0)
22768 get_next_display_element (&it);
22769 at_eol_p = ITERATOR_AT_END_OF_LINE_P (&it);
22770 it.glyph_row = NULL;
22771 PRODUCE_GLYPHS (&it); /* compute it.pixel_width */
22772 it.glyph_row = row;
22773 /* PRODUCE_GLYPHS advances it.current_x, so we must restore
22774 it, lest it will become out of sync with it's buffer
22775 position. */
22776 it.current_x = pt_x;
22778 else
22779 at_eol_p = ITERATOR_AT_END_OF_LINE_P (&it);
22780 pixel_width = it.pixel_width;
22781 if (overshoot_expected && at_eol_p)
22782 pixel_width = 0;
22783 else if (pixel_width <= 0)
22784 pixel_width = 1;
22786 /* If there's a display string (or something similar) at point,
22787 we are actually at the glyph to the left of point, so we need
22788 to correct the X coordinate. */
22789 if (overshoot_expected)
22791 if (it.bidi_p)
22792 pt_x += pixel_width * it.bidi_it.scan_dir;
22793 else
22794 pt_x += pixel_width;
22797 /* Compute target X coordinate, either to the left or to the
22798 right of point. On TTY frames, all characters have the same
22799 pixel width of 1, so we can use that. On GUI frames we don't
22800 have an easy way of getting at the pixel width of the
22801 character to the left of point, so we use a different method
22802 of getting to that place. */
22803 if (dir > 0)
22804 target_x = pt_x + pixel_width;
22805 else
22806 target_x = pt_x - (!FRAME_WINDOW_P (it.f)) * pixel_width;
22808 /* Target X coordinate could be one line above or below the line
22809 of point, in which case we need to adjust the target X
22810 coordinate. Also, if moving to the left, we need to begin at
22811 the left edge of the point's screen line. */
22812 if (dir < 0)
22814 if (pt_x > 0)
22816 start_display (&it, w, pt);
22817 if (it.line_wrap == TRUNCATE)
22818 it.last_visible_x = DISP_INFINITY;
22819 reseat_at_previous_visible_line_start (&it);
22820 it.current_x = it.current_y = it.hpos = 0;
22821 if (pt_vpos != 0)
22822 move_it_by_lines (&it, pt_vpos);
22824 else
22826 move_it_by_lines (&it, -1);
22827 target_x = it.last_visible_x - !FRAME_WINDOW_P (it.f);
22828 target_is_eol_p = true;
22829 /* Under word-wrap, we don't know the x coordinate of
22830 the last character displayed on the previous line,
22831 which immediately precedes the wrap point. To find
22832 out its x coordinate, we try moving to the right
22833 margin of the window, which will stop at the wrap
22834 point, and then reset target_x to point at the
22835 character that precedes the wrap point. This is not
22836 needed on GUI frames, because (see below) there we
22837 move from the left margin one grapheme cluster at a
22838 time, and stop when we hit the wrap point. */
22839 if (!FRAME_WINDOW_P (it.f) && it.line_wrap == WORD_WRAP)
22841 void *it_data = NULL;
22842 struct it it2;
22844 SAVE_IT (it2, it, it_data);
22845 move_it_in_display_line_to (&it, ZV, target_x,
22846 MOVE_TO_POS | MOVE_TO_X);
22847 /* If we arrived at target_x, that _is_ the last
22848 character on the previous line. */
22849 if (it.current_x != target_x)
22850 target_x = it.current_x - 1;
22851 RESTORE_IT (&it, &it2, it_data);
22855 else
22857 if (at_eol_p
22858 || (target_x >= it.last_visible_x
22859 && it.line_wrap != TRUNCATE))
22861 if (pt_x > 0)
22862 move_it_by_lines (&it, 0);
22863 move_it_by_lines (&it, 1);
22864 target_x = 0;
22868 /* Move to the target X coordinate. */
22869 /* On GUI frames, as we don't know the X coordinate of the
22870 character to the left of point, moving point to the left
22871 requires walking, one grapheme cluster at a time, until we
22872 find ourself at a place immediately to the left of the
22873 character at point. */
22874 if (FRAME_WINDOW_P (it.f) && dir < 0)
22876 struct text_pos new_pos;
22877 enum move_it_result rc = MOVE_X_REACHED;
22879 if (it.current_x == 0)
22880 get_next_display_element (&it);
22881 if (it.what == IT_COMPOSITION)
22883 new_pos.charpos = it.cmp_it.charpos;
22884 new_pos.bytepos = -1;
22886 else
22887 new_pos = it.current.pos;
22889 while (it.current_x + it.pixel_width <= target_x
22890 && (rc == MOVE_X_REACHED
22891 /* Under word-wrap, move_it_in_display_line_to
22892 stops at correct coordinates, but sometimes
22893 returns MOVE_POS_MATCH_OR_ZV. */
22894 || (it.line_wrap == WORD_WRAP
22895 && rc == MOVE_POS_MATCH_OR_ZV)))
22897 int new_x = it.current_x + it.pixel_width;
22899 /* For composed characters, we want the position of the
22900 first character in the grapheme cluster (usually, the
22901 composition's base character), whereas it.current
22902 might give us the position of the _last_ one, e.g. if
22903 the composition is rendered in reverse due to bidi
22904 reordering. */
22905 if (it.what == IT_COMPOSITION)
22907 new_pos.charpos = it.cmp_it.charpos;
22908 new_pos.bytepos = -1;
22910 else
22911 new_pos = it.current.pos;
22912 if (new_x == it.current_x)
22913 new_x++;
22914 rc = move_it_in_display_line_to (&it, ZV, new_x,
22915 MOVE_TO_POS | MOVE_TO_X);
22916 if (ITERATOR_AT_END_OF_LINE_P (&it) && !target_is_eol_p)
22917 break;
22919 /* The previous position we saw in the loop is the one we
22920 want. */
22921 if (new_pos.bytepos == -1)
22922 new_pos.bytepos = CHAR_TO_BYTE (new_pos.charpos);
22923 it.current.pos = new_pos;
22925 else if (it.current_x != target_x)
22926 move_it_in_display_line_to (&it, ZV, target_x, MOVE_TO_POS | MOVE_TO_X);
22928 /* If we ended up in a display string that covers point, move to
22929 buffer position to the right in the visual order. */
22930 if (dir > 0)
22932 while (IT_CHARPOS (it) == PT)
22934 set_iterator_to_next (&it, false);
22935 if (!get_next_display_element (&it))
22936 break;
22940 /* Move point to that position. */
22941 SET_PT_BOTH (IT_CHARPOS (it), IT_BYTEPOS (it));
22944 return make_number (PT);
22946 #undef ROW_GLYPH_NEWLINE_P
22949 DEFUN ("bidi-resolved-levels", Fbidi_resolved_levels,
22950 Sbidi_resolved_levels, 0, 1, 0,
22951 doc: /* Return the resolved bidirectional levels of characters at VPOS.
22953 The resolved levels are produced by the Emacs bidi reordering engine
22954 that implements the UBA, the Unicode Bidirectional Algorithm. Please
22955 read the Unicode Standard Annex 9 (UAX#9) for background information
22956 about these levels.
22958 VPOS is the zero-based number of the current window's screen line
22959 for which to produce the resolved levels. If VPOS is nil or omitted,
22960 it defaults to the screen line of point. If the window displays a
22961 header line, VPOS of zero will report on the header line, and first
22962 line of text in the window will have VPOS of 1.
22964 Value is an array of resolved levels, indexed by glyph number.
22965 Glyphs are numbered from zero starting from the beginning of the
22966 screen line, i.e. the left edge of the window for left-to-right lines
22967 and from the right edge for right-to-left lines. The resolved levels
22968 are produced only for the window's text area; text in display margins
22969 is not included.
22971 If the selected window's display is not up-to-date, or if the specified
22972 screen line does not display text, this function returns nil. It is
22973 highly recommended to bind this function to some simple key, like F8,
22974 in order to avoid these problems.
22976 This function exists mainly for testing the correctness of the
22977 Emacs UBA implementation, in particular with the test suite. */)
22978 (Lisp_Object vpos)
22980 struct window *w = XWINDOW (selected_window);
22981 struct buffer *b = XBUFFER (w->contents);
22982 int nrow;
22983 struct glyph_row *row;
22985 if (NILP (vpos))
22987 int d1, d2, d3, d4, d5;
22989 pos_visible_p (w, PT, &d1, &d2, &d3, &d4, &d5, &nrow);
22991 else
22993 CHECK_NUMBER_COERCE_MARKER (vpos);
22994 nrow = XINT (vpos);
22997 /* We require up-to-date glyph matrix for this window. */
22998 if (w->window_end_valid
22999 && !windows_or_buffers_changed
23000 && b
23001 && !b->clip_changed
23002 && !b->prevent_redisplay_optimizations_p
23003 && !window_outdated (w)
23004 && nrow >= 0
23005 && nrow < w->current_matrix->nrows
23006 && (row = MATRIX_ROW (w->current_matrix, nrow))->enabled_p
23007 && MATRIX_ROW_DISPLAYS_TEXT_P (row))
23009 struct glyph *g, *e, *g1;
23010 int nglyphs, i;
23011 Lisp_Object levels;
23013 if (!row->reversed_p) /* Left-to-right glyph row. */
23015 g = g1 = row->glyphs[TEXT_AREA];
23016 e = g + row->used[TEXT_AREA];
23018 /* Skip over glyphs at the start of the row that was
23019 generated by redisplay for its own needs. */
23020 while (g < e
23021 && NILP (g->object)
23022 && g->charpos < 0)
23023 g++;
23024 g1 = g;
23026 /* Count the "interesting" glyphs in this row. */
23027 for (nglyphs = 0; g < e && !NILP (g->object); g++)
23028 nglyphs++;
23030 /* Create and fill the array. */
23031 levels = make_uninit_vector (nglyphs);
23032 for (i = 0; g1 < g; i++, g1++)
23033 ASET (levels, i, make_number (g1->resolved_level));
23035 else /* Right-to-left glyph row. */
23037 g = row->glyphs[TEXT_AREA] + row->used[TEXT_AREA] - 1;
23038 e = row->glyphs[TEXT_AREA] - 1;
23039 while (g > e
23040 && NILP (g->object)
23041 && g->charpos < 0)
23042 g--;
23043 g1 = g;
23044 for (nglyphs = 0; g > e && !NILP (g->object); g--)
23045 nglyphs++;
23046 levels = make_uninit_vector (nglyphs);
23047 for (i = 0; g1 > g; i++, g1--)
23048 ASET (levels, i, make_number (g1->resolved_level));
23050 return levels;
23052 else
23053 return Qnil;
23058 /***********************************************************************
23059 Menu Bar
23060 ***********************************************************************/
23062 /* Redisplay the menu bar in the frame for window W.
23064 The menu bar of X frames that don't have X toolkit support is
23065 displayed in a special window W->frame->menu_bar_window.
23067 The menu bar of terminal frames is treated specially as far as
23068 glyph matrices are concerned. Menu bar lines are not part of
23069 windows, so the update is done directly on the frame matrix rows
23070 for the menu bar. */
23072 static void
23073 display_menu_bar (struct window *w)
23075 struct frame *f = XFRAME (WINDOW_FRAME (w));
23076 struct it it;
23077 Lisp_Object items;
23078 int i;
23080 /* Don't do all this for graphical frames. */
23081 #ifdef HAVE_NTGUI
23082 if (FRAME_W32_P (f))
23083 return;
23084 #endif
23085 #if defined (USE_X_TOOLKIT) || defined (USE_GTK)
23086 if (FRAME_X_P (f))
23087 return;
23088 #endif
23090 #ifdef HAVE_NS
23091 if (FRAME_NS_P (f))
23092 return;
23093 #endif /* HAVE_NS */
23095 #if defined (USE_X_TOOLKIT) || defined (USE_GTK)
23096 eassert (!FRAME_WINDOW_P (f));
23097 init_iterator (&it, w, -1, -1, f->desired_matrix->rows, MENU_FACE_ID);
23098 it.first_visible_x = 0;
23099 it.last_visible_x = FRAME_PIXEL_WIDTH (f);
23100 #elif defined (HAVE_X_WINDOWS) /* X without toolkit. */
23101 if (FRAME_WINDOW_P (f))
23103 /* Menu bar lines are displayed in the desired matrix of the
23104 dummy window menu_bar_window. */
23105 struct window *menu_w;
23106 menu_w = XWINDOW (f->menu_bar_window);
23107 init_iterator (&it, menu_w, -1, -1, menu_w->desired_matrix->rows,
23108 MENU_FACE_ID);
23109 it.first_visible_x = 0;
23110 it.last_visible_x = FRAME_PIXEL_WIDTH (f);
23112 else
23113 #endif /* not USE_X_TOOLKIT and not USE_GTK */
23115 /* This is a TTY frame, i.e. character hpos/vpos are used as
23116 pixel x/y. */
23117 init_iterator (&it, w, -1, -1, f->desired_matrix->rows,
23118 MENU_FACE_ID);
23119 it.first_visible_x = 0;
23120 it.last_visible_x = FRAME_COLS (f);
23123 /* FIXME: This should be controlled by a user option. See the
23124 comments in redisplay_tool_bar and display_mode_line about
23125 this. */
23126 it.paragraph_embedding = L2R;
23128 /* Clear all rows of the menu bar. */
23129 for (i = 0; i < FRAME_MENU_BAR_LINES (f); ++i)
23131 struct glyph_row *row = it.glyph_row + i;
23132 clear_glyph_row (row);
23133 row->enabled_p = true;
23134 row->full_width_p = true;
23135 row->reversed_p = false;
23138 /* Display all items of the menu bar. */
23139 items = FRAME_MENU_BAR_ITEMS (it.f);
23140 for (i = 0; i < ASIZE (items); i += 4)
23142 Lisp_Object string;
23144 /* Stop at nil string. */
23145 string = AREF (items, i + 1);
23146 if (NILP (string))
23147 break;
23149 /* Remember where item was displayed. */
23150 ASET (items, i + 3, make_number (it.hpos));
23152 /* Display the item, pad with one space. */
23153 if (it.current_x < it.last_visible_x)
23154 display_string (NULL, string, Qnil, 0, 0, &it,
23155 SCHARS (string) + 1, 0, 0, -1);
23158 /* Fill out the line with spaces. */
23159 if (it.current_x < it.last_visible_x)
23160 display_string ("", Qnil, Qnil, 0, 0, &it, -1, 0, 0, -1);
23162 /* Compute the total height of the lines. */
23163 compute_line_metrics (&it);
23166 /* Deep copy of a glyph row, including the glyphs. */
23167 static void
23168 deep_copy_glyph_row (struct glyph_row *to, struct glyph_row *from)
23170 struct glyph *pointers[1 + LAST_AREA];
23171 int to_used = to->used[TEXT_AREA];
23173 /* Save glyph pointers of TO. */
23174 memcpy (pointers, to->glyphs, sizeof to->glyphs);
23176 /* Do a structure assignment. */
23177 *to = *from;
23179 /* Restore original glyph pointers of TO. */
23180 memcpy (to->glyphs, pointers, sizeof to->glyphs);
23182 /* Copy the glyphs. */
23183 memcpy (to->glyphs[TEXT_AREA], from->glyphs[TEXT_AREA],
23184 min (from->used[TEXT_AREA], to_used) * sizeof (struct glyph));
23186 /* If we filled only part of the TO row, fill the rest with
23187 space_glyph (which will display as empty space). */
23188 if (to_used > from->used[TEXT_AREA])
23189 fill_up_frame_row_with_spaces (to, to_used);
23192 /* Display one menu item on a TTY, by overwriting the glyphs in the
23193 frame F's desired glyph matrix with glyphs produced from the menu
23194 item text. Called from term.c to display TTY drop-down menus one
23195 item at a time.
23197 ITEM_TEXT is the menu item text as a C string.
23199 FACE_ID is the face ID to be used for this menu item. FACE_ID
23200 could specify one of 3 faces: a face for an enabled item, a face
23201 for a disabled item, or a face for a selected item.
23203 X and Y are coordinates of the first glyph in the frame's desired
23204 matrix to be overwritten by the menu item. Since this is a TTY, Y
23205 is the zero-based number of the glyph row and X is the zero-based
23206 glyph number in the row, starting from left, where to start
23207 displaying the item.
23209 SUBMENU means this menu item drops down a submenu, which
23210 should be indicated by displaying a proper visual cue after the
23211 item text. */
23213 void
23214 display_tty_menu_item (const char *item_text, int width, int face_id,
23215 int x, int y, bool submenu)
23217 struct it it;
23218 struct frame *f = SELECTED_FRAME ();
23219 struct window *w = XWINDOW (f->selected_window);
23220 struct glyph_row *row;
23221 size_t item_len = strlen (item_text);
23223 eassert (FRAME_TERMCAP_P (f));
23225 /* Don't write beyond the matrix's last row. This can happen for
23226 TTY screens that are not high enough to show the entire menu.
23227 (This is actually a bit of defensive programming, as
23228 tty_menu_display already limits the number of menu items to one
23229 less than the number of screen lines.) */
23230 if (y >= f->desired_matrix->nrows)
23231 return;
23233 init_iterator (&it, w, -1, -1, f->desired_matrix->rows + y, MENU_FACE_ID);
23234 it.first_visible_x = 0;
23235 it.last_visible_x = FRAME_COLS (f) - 1;
23236 row = it.glyph_row;
23237 /* Start with the row contents from the current matrix. */
23238 deep_copy_glyph_row (row, f->current_matrix->rows + y);
23239 bool saved_width = row->full_width_p;
23240 row->full_width_p = true;
23241 bool saved_reversed = row->reversed_p;
23242 row->reversed_p = false;
23243 row->enabled_p = true;
23245 /* Arrange for the menu item glyphs to start at (X,Y) and have the
23246 desired face. */
23247 eassert (x < f->desired_matrix->matrix_w);
23248 it.current_x = it.hpos = x;
23249 it.current_y = it.vpos = y;
23250 int saved_used = row->used[TEXT_AREA];
23251 bool saved_truncated = row->truncated_on_right_p;
23252 row->used[TEXT_AREA] = x;
23253 it.face_id = face_id;
23254 it.line_wrap = TRUNCATE;
23256 /* FIXME: This should be controlled by a user option. See the
23257 comments in redisplay_tool_bar and display_mode_line about this.
23258 Also, if paragraph_embedding could ever be R2L, changes will be
23259 needed to avoid shifting to the right the row characters in
23260 term.c:append_glyph. */
23261 it.paragraph_embedding = L2R;
23263 /* Pad with a space on the left. */
23264 display_string (" ", Qnil, Qnil, 0, 0, &it, 1, 0, FRAME_COLS (f) - 1, -1);
23265 width--;
23266 /* Display the menu item, pad with spaces to WIDTH. */
23267 if (submenu)
23269 display_string (item_text, Qnil, Qnil, 0, 0, &it,
23270 item_len, 0, FRAME_COLS (f) - 1, -1);
23271 width -= item_len;
23272 /* Indicate with " >" that there's a submenu. */
23273 display_string (" >", Qnil, Qnil, 0, 0, &it, width, 0,
23274 FRAME_COLS (f) - 1, -1);
23276 else
23277 display_string (item_text, Qnil, Qnil, 0, 0, &it,
23278 width, 0, FRAME_COLS (f) - 1, -1);
23280 row->used[TEXT_AREA] = max (saved_used, row->used[TEXT_AREA]);
23281 row->truncated_on_right_p = saved_truncated;
23282 row->hash = row_hash (row);
23283 row->full_width_p = saved_width;
23284 row->reversed_p = saved_reversed;
23287 /***********************************************************************
23288 Mode Line
23289 ***********************************************************************/
23291 /* Redisplay mode lines in the window tree whose root is WINDOW.
23292 If FORCE, redisplay mode lines unconditionally.
23293 Otherwise, redisplay only mode lines that are garbaged. Value is
23294 the number of windows whose mode lines were redisplayed. */
23296 static int
23297 redisplay_mode_lines (Lisp_Object window, bool force)
23299 int nwindows = 0;
23301 while (!NILP (window))
23303 struct window *w = XWINDOW (window);
23305 if (WINDOWP (w->contents))
23306 nwindows += redisplay_mode_lines (w->contents, force);
23307 else if (force
23308 || FRAME_GARBAGED_P (XFRAME (w->frame))
23309 || !MATRIX_MODE_LINE_ROW (w->current_matrix)->enabled_p)
23311 struct text_pos lpoint;
23312 struct buffer *old = current_buffer;
23314 /* Set the window's buffer for the mode line display. */
23315 SET_TEXT_POS (lpoint, PT, PT_BYTE);
23316 set_buffer_internal_1 (XBUFFER (w->contents));
23318 /* Point refers normally to the selected window. For any
23319 other window, set up appropriate value. */
23320 if (!EQ (window, selected_window))
23322 struct text_pos pt;
23324 CLIP_TEXT_POS_FROM_MARKER (pt, w->pointm);
23325 TEMP_SET_PT_BOTH (CHARPOS (pt), BYTEPOS (pt));
23328 /* Display mode lines. */
23329 clear_glyph_matrix (w->desired_matrix);
23330 if (display_mode_lines (w))
23331 ++nwindows;
23333 /* Restore old settings. */
23334 set_buffer_internal_1 (old);
23335 TEMP_SET_PT_BOTH (CHARPOS (lpoint), BYTEPOS (lpoint));
23338 window = w->next;
23341 return nwindows;
23345 /* Display the mode and/or header line of window W. Value is the
23346 sum number of mode lines and header lines displayed. */
23348 static int
23349 display_mode_lines (struct window *w)
23351 Lisp_Object old_selected_window = selected_window;
23352 Lisp_Object old_selected_frame = selected_frame;
23353 Lisp_Object new_frame = w->frame;
23354 Lisp_Object old_frame_selected_window = XFRAME (new_frame)->selected_window;
23355 int n = 0;
23357 if (window_wants_mode_line (w))
23359 Lisp_Object window;
23360 Lisp_Object default_help
23361 = buffer_local_value (Qmode_line_default_help_echo, w->contents);
23363 /* Set up mode line help echo. Do this before selecting w so it
23364 can reasonably tell whether a mouse click will select w. */
23365 XSETWINDOW (window, w);
23366 if (FUNCTIONP (default_help))
23367 wset_mode_line_help_echo (w, safe_call1 (default_help, window));
23368 else if (STRINGP (default_help))
23369 wset_mode_line_help_echo (w, default_help);
23370 else
23371 wset_mode_line_help_echo (w, Qnil);
23374 selected_frame = new_frame;
23375 /* FIXME: If we were to allow the mode-line's computation changing the buffer
23376 or window's point, then we'd need select_window_1 here as well. */
23377 XSETWINDOW (selected_window, w);
23378 XFRAME (new_frame)->selected_window = selected_window;
23380 /* These will be set while the mode line specs are processed. */
23381 line_number_displayed = false;
23382 w->column_number_displayed = -1;
23384 if (window_wants_mode_line (w))
23386 Lisp_Object window_mode_line_format
23387 = window_parameter (w, Qmode_line_format);
23388 struct window *sel_w = XWINDOW (old_selected_window);
23390 /* Select mode line face based on the real selected window. */
23391 display_mode_line (w, CURRENT_MODE_LINE_FACE_ID_3 (sel_w, sel_w, w),
23392 NILP (window_mode_line_format)
23393 ? BVAR (current_buffer, mode_line_format)
23394 : window_mode_line_format);
23395 ++n;
23398 if (window_wants_header_line (w))
23400 Lisp_Object window_header_line_format
23401 = window_parameter (w, Qheader_line_format);
23403 display_mode_line (w, HEADER_LINE_FACE_ID,
23404 NILP (window_header_line_format)
23405 ? BVAR (current_buffer, header_line_format)
23406 : window_header_line_format);
23407 ++n;
23410 XFRAME (new_frame)->selected_window = old_frame_selected_window;
23411 selected_frame = old_selected_frame;
23412 selected_window = old_selected_window;
23413 if (n > 0)
23414 w->must_be_updated_p = true;
23415 return n;
23419 /* Display mode or header line of window W. FACE_ID specifies which
23420 line to display; it is either MODE_LINE_FACE_ID or
23421 HEADER_LINE_FACE_ID. FORMAT is the mode/header line format to
23422 display. Value is the pixel height of the mode/header line
23423 displayed. */
23425 static int
23426 display_mode_line (struct window *w, enum face_id face_id, Lisp_Object format)
23428 struct it it;
23429 struct face *face;
23430 ptrdiff_t count = SPECPDL_INDEX ();
23432 init_iterator (&it, w, -1, -1, NULL, face_id);
23433 /* Don't extend on a previously drawn mode-line.
23434 This may happen if called from pos_visible_p. */
23435 it.glyph_row->enabled_p = false;
23436 prepare_desired_row (w, it.glyph_row, true);
23438 it.glyph_row->mode_line_p = true;
23440 /* FIXME: This should be controlled by a user option. But
23441 supporting such an option is not trivial, since the mode line is
23442 made up of many separate strings. */
23443 it.paragraph_embedding = L2R;
23445 record_unwind_protect (unwind_format_mode_line,
23446 format_mode_line_unwind_data (NULL, NULL,
23447 Qnil, false));
23449 mode_line_target = MODE_LINE_DISPLAY;
23451 /* Temporarily make frame's keyboard the current kboard so that
23452 kboard-local variables in the mode_line_format will get the right
23453 values. */
23454 push_kboard (FRAME_KBOARD (it.f));
23455 record_unwind_save_match_data ();
23456 display_mode_element (&it, 0, 0, 0, format, Qnil, false);
23457 pop_kboard ();
23459 unbind_to (count, Qnil);
23461 /* Fill up with spaces. */
23462 display_string (" ", Qnil, Qnil, 0, 0, &it, 10000, -1, -1, 0);
23464 compute_line_metrics (&it);
23465 it.glyph_row->full_width_p = true;
23466 it.glyph_row->continued_p = false;
23467 it.glyph_row->truncated_on_left_p = false;
23468 it.glyph_row->truncated_on_right_p = false;
23470 /* Make a 3D mode-line have a shadow at its right end. */
23471 face = FACE_FROM_ID (it.f, face_id);
23472 extend_face_to_end_of_line (&it);
23473 if (face->box != FACE_NO_BOX)
23475 struct glyph *last = (it.glyph_row->glyphs[TEXT_AREA]
23476 + it.glyph_row->used[TEXT_AREA] - 1);
23477 last->right_box_line_p = true;
23480 return it.glyph_row->height;
23483 /* Move element ELT in LIST to the front of LIST.
23484 Return the updated list. */
23486 static Lisp_Object
23487 move_elt_to_front (Lisp_Object elt, Lisp_Object list)
23489 register Lisp_Object tail, prev;
23490 register Lisp_Object tem;
23492 tail = list;
23493 prev = Qnil;
23494 while (CONSP (tail))
23496 tem = XCAR (tail);
23498 if (EQ (elt, tem))
23500 /* Splice out the link TAIL. */
23501 if (NILP (prev))
23502 list = XCDR (tail);
23503 else
23504 Fsetcdr (prev, XCDR (tail));
23506 /* Now make it the first. */
23507 Fsetcdr (tail, list);
23508 return tail;
23510 else
23511 prev = tail;
23512 tail = XCDR (tail);
23513 maybe_quit ();
23516 /* Not found--return unchanged LIST. */
23517 return list;
23520 /* Contribute ELT to the mode line for window IT->w. How it
23521 translates into text depends on its data type.
23523 IT describes the display environment in which we display, as usual.
23525 DEPTH is the depth in recursion. It is used to prevent
23526 infinite recursion here.
23528 FIELD_WIDTH is the number of characters the display of ELT should
23529 occupy in the mode line, and PRECISION is the maximum number of
23530 characters to display from ELT's representation. See
23531 display_string for details.
23533 Returns the hpos of the end of the text generated by ELT.
23535 PROPS is a property list to add to any string we encounter.
23537 If RISKY, remove (disregard) any properties in any string
23538 we encounter, and ignore :eval and :propertize.
23540 The global variable `mode_line_target' determines whether the
23541 output is passed to `store_mode_line_noprop',
23542 `store_mode_line_string', or `display_string'. */
23544 static int
23545 display_mode_element (struct it *it, int depth, int field_width, int precision,
23546 Lisp_Object elt, Lisp_Object props, bool risky)
23548 int n = 0, field, prec;
23549 bool literal = false;
23551 tail_recurse:
23552 if (depth > 100)
23553 elt = build_string ("*too-deep*");
23555 depth++;
23557 switch (XTYPE (elt))
23559 case Lisp_String:
23561 /* A string: output it and check for %-constructs within it. */
23562 unsigned char c;
23563 ptrdiff_t offset = 0;
23565 if (SCHARS (elt) > 0
23566 && (!NILP (props) || risky))
23568 Lisp_Object oprops, aelt;
23569 oprops = Ftext_properties_at (make_number (0), elt);
23571 /* If the starting string's properties are not what
23572 we want, translate the string. Also, if the string
23573 is risky, do that anyway. */
23575 if (NILP (Fequal (props, oprops)) || risky)
23577 /* If the starting string has properties,
23578 merge the specified ones onto the existing ones. */
23579 if (! NILP (oprops) && !risky)
23581 Lisp_Object tem;
23583 oprops = Fcopy_sequence (oprops);
23584 tem = props;
23585 while (CONSP (tem))
23587 oprops = Fplist_put (oprops, XCAR (tem),
23588 XCAR (XCDR (tem)));
23589 tem = XCDR (XCDR (tem));
23591 props = oprops;
23594 aelt = Fassoc (elt, mode_line_proptrans_alist, Qnil);
23595 if (! NILP (aelt) && !NILP (Fequal (props, XCDR (aelt))))
23597 /* AELT is what we want. Move it to the front
23598 without consing. */
23599 elt = XCAR (aelt);
23600 mode_line_proptrans_alist
23601 = move_elt_to_front (aelt, mode_line_proptrans_alist);
23603 else
23605 Lisp_Object tem;
23607 /* If AELT has the wrong props, it is useless.
23608 so get rid of it. */
23609 if (! NILP (aelt))
23610 mode_line_proptrans_alist
23611 = Fdelq (aelt, mode_line_proptrans_alist);
23613 elt = Fcopy_sequence (elt);
23614 Fset_text_properties (make_number (0), Flength (elt),
23615 props, elt);
23616 /* Add this item to mode_line_proptrans_alist. */
23617 mode_line_proptrans_alist
23618 = Fcons (Fcons (elt, props),
23619 mode_line_proptrans_alist);
23620 /* Truncate mode_line_proptrans_alist
23621 to at most 50 elements. */
23622 tem = Fnthcdr (make_number (50),
23623 mode_line_proptrans_alist);
23624 if (! NILP (tem))
23625 XSETCDR (tem, Qnil);
23630 offset = 0;
23632 if (literal)
23634 prec = precision - n;
23635 switch (mode_line_target)
23637 case MODE_LINE_NOPROP:
23638 case MODE_LINE_TITLE:
23639 n += store_mode_line_noprop (SSDATA (elt), -1, prec);
23640 break;
23641 case MODE_LINE_STRING:
23642 n += store_mode_line_string (NULL, elt, true, 0, prec, Qnil);
23643 break;
23644 case MODE_LINE_DISPLAY:
23645 n += display_string (NULL, elt, Qnil, 0, 0, it,
23646 0, prec, 0, STRING_MULTIBYTE (elt));
23647 break;
23650 break;
23653 /* Handle the non-literal case. */
23655 while ((precision <= 0 || n < precision)
23656 && SREF (elt, offset) != 0
23657 && (mode_line_target != MODE_LINE_DISPLAY
23658 || it->current_x < it->last_visible_x))
23660 ptrdiff_t last_offset = offset;
23662 /* Advance to end of string or next format specifier. */
23663 while ((c = SREF (elt, offset++)) != '\0' && c != '%')
23666 if (offset - 1 != last_offset)
23668 ptrdiff_t nchars, nbytes;
23670 /* Output to end of string or up to '%'. Field width
23671 is length of string. Don't output more than
23672 PRECISION allows us. */
23673 offset--;
23675 prec = c_string_width (SDATA (elt) + last_offset,
23676 offset - last_offset, precision - n,
23677 &nchars, &nbytes);
23679 switch (mode_line_target)
23681 case MODE_LINE_NOPROP:
23682 case MODE_LINE_TITLE:
23683 n += store_mode_line_noprop (SSDATA (elt) + last_offset, 0, prec);
23684 break;
23685 case MODE_LINE_STRING:
23687 ptrdiff_t bytepos = last_offset;
23688 ptrdiff_t charpos = string_byte_to_char (elt, bytepos);
23689 ptrdiff_t endpos = (precision <= 0
23690 ? string_byte_to_char (elt, offset)
23691 : charpos + nchars);
23692 Lisp_Object mode_string
23693 = Fsubstring (elt, make_number (charpos),
23694 make_number (endpos));
23695 n += store_mode_line_string (NULL, mode_string, false,
23696 0, 0, Qnil);
23698 break;
23699 case MODE_LINE_DISPLAY:
23701 ptrdiff_t bytepos = last_offset;
23702 ptrdiff_t charpos = string_byte_to_char (elt, bytepos);
23704 if (precision <= 0)
23705 nchars = string_byte_to_char (elt, offset) - charpos;
23706 n += display_string (NULL, elt, Qnil, 0, charpos,
23707 it, 0, nchars, 0,
23708 STRING_MULTIBYTE (elt));
23710 break;
23713 else /* c == '%' */
23715 ptrdiff_t percent_position = offset;
23717 /* Get the specified minimum width. Zero means
23718 don't pad. */
23719 field = 0;
23720 while ((c = SREF (elt, offset++)) >= '0' && c <= '9')
23721 field = field * 10 + c - '0';
23723 /* Don't pad beyond the total padding allowed. */
23724 if (field_width - n > 0 && field > field_width - n)
23725 field = field_width - n;
23727 /* Note that either PRECISION <= 0 or N < PRECISION. */
23728 prec = precision - n;
23730 if (c == 'M')
23731 n += display_mode_element (it, depth, field, prec,
23732 Vglobal_mode_string, props,
23733 risky);
23734 else if (c != 0)
23736 bool multibyte;
23737 ptrdiff_t bytepos, charpos;
23738 const char *spec;
23739 Lisp_Object string;
23741 bytepos = percent_position;
23742 charpos = (STRING_MULTIBYTE (elt)
23743 ? string_byte_to_char (elt, bytepos)
23744 : bytepos);
23745 spec = decode_mode_spec (it->w, c, field, &string);
23746 multibyte = STRINGP (string) && STRING_MULTIBYTE (string);
23748 switch (mode_line_target)
23750 case MODE_LINE_NOPROP:
23751 case MODE_LINE_TITLE:
23752 n += store_mode_line_noprop (spec, field, prec);
23753 break;
23754 case MODE_LINE_STRING:
23756 Lisp_Object tem = build_string (spec);
23757 props = Ftext_properties_at (make_number (charpos), elt);
23758 /* Should only keep face property in props */
23759 n += store_mode_line_string (NULL, tem, false,
23760 field, prec, props);
23762 break;
23763 case MODE_LINE_DISPLAY:
23765 int nglyphs_before, nwritten;
23767 nglyphs_before = it->glyph_row->used[TEXT_AREA];
23768 nwritten = display_string (spec, string, elt,
23769 charpos, 0, it,
23770 field, prec, 0,
23771 multibyte);
23773 /* Assign to the glyphs written above the
23774 string where the `%x' came from, position
23775 of the `%'. */
23776 if (nwritten > 0)
23778 struct glyph *glyph
23779 = (it->glyph_row->glyphs[TEXT_AREA]
23780 + nglyphs_before);
23781 int i;
23783 for (i = 0; i < nwritten; ++i)
23785 glyph[i].object = elt;
23786 glyph[i].charpos = charpos;
23789 n += nwritten;
23792 break;
23795 else /* c == 0 */
23796 break;
23800 break;
23802 case Lisp_Symbol:
23803 /* A symbol: process the value of the symbol recursively
23804 as if it appeared here directly. Avoid error if symbol void.
23805 Special case: if value of symbol is a string, output the string
23806 literally. */
23808 register Lisp_Object tem;
23810 /* If the variable is not marked as risky to set
23811 then its contents are risky to use. */
23812 if (NILP (Fget (elt, Qrisky_local_variable)))
23813 risky = true;
23815 tem = Fboundp (elt);
23816 if (!NILP (tem))
23818 tem = Fsymbol_value (elt);
23819 /* If value is a string, output that string literally:
23820 don't check for % within it. */
23821 if (STRINGP (tem))
23822 literal = true;
23824 if (!EQ (tem, elt))
23826 /* Give up right away for nil or t. */
23827 elt = tem;
23828 goto tail_recurse;
23832 break;
23834 case Lisp_Cons:
23836 register Lisp_Object car, tem;
23838 /* A cons cell: five distinct cases.
23839 If first element is :eval or :propertize, do something special.
23840 If first element is a string or a cons, process all the elements
23841 and effectively concatenate them.
23842 If first element is a negative number, truncate displaying cdr to
23843 at most that many characters. If positive, pad (with spaces)
23844 to at least that many characters.
23845 If first element is a symbol, process the cadr or caddr recursively
23846 according to whether the symbol's value is non-nil or nil. */
23847 car = XCAR (elt);
23848 if (EQ (car, QCeval))
23850 /* An element of the form (:eval FORM) means evaluate FORM
23851 and use the result as mode line elements. */
23853 if (risky)
23854 break;
23856 if (CONSP (XCDR (elt)))
23858 Lisp_Object spec;
23859 spec = safe__eval (true, XCAR (XCDR (elt)));
23860 /* The :eval form could delete the frame stored in the
23861 iterator, which will cause a crash if we try to
23862 access faces and other fields (e.g., FRAME_KBOARD)
23863 on that frame. This is a nonsensical thing to do,
23864 and signaling an error from redisplay might be
23865 dangerous, but we cannot continue with an invalid frame. */
23866 if (!FRAME_LIVE_P (it->f))
23867 signal_error (":eval deleted the frame being displayed", elt);
23868 n += display_mode_element (it, depth, field_width - n,
23869 precision - n, spec, props,
23870 risky);
23873 else if (EQ (car, QCpropertize))
23875 /* An element of the form (:propertize ELT PROPS...)
23876 means display ELT but applying properties PROPS. */
23878 if (risky)
23879 break;
23881 if (CONSP (XCDR (elt)))
23882 n += display_mode_element (it, depth, field_width - n,
23883 precision - n, XCAR (XCDR (elt)),
23884 XCDR (XCDR (elt)), risky);
23886 else if (SYMBOLP (car))
23888 tem = Fboundp (car);
23889 elt = XCDR (elt);
23890 if (!CONSP (elt))
23891 goto invalid;
23892 /* elt is now the cdr, and we know it is a cons cell.
23893 Use its car if CAR has a non-nil value. */
23894 if (!NILP (tem))
23896 tem = Fsymbol_value (car);
23897 if (!NILP (tem))
23899 elt = XCAR (elt);
23900 goto tail_recurse;
23903 /* Symbol's value is nil (or symbol is unbound)
23904 Get the cddr of the original list
23905 and if possible find the caddr and use that. */
23906 elt = XCDR (elt);
23907 if (NILP (elt))
23908 break;
23909 else if (!CONSP (elt))
23910 goto invalid;
23911 elt = XCAR (elt);
23912 goto tail_recurse;
23914 else if (INTEGERP (car))
23916 register int lim = XINT (car);
23917 elt = XCDR (elt);
23918 if (lim < 0)
23920 /* Negative int means reduce maximum width. */
23921 if (precision <= 0)
23922 precision = -lim;
23923 else
23924 precision = min (precision, -lim);
23926 else if (lim > 0)
23928 /* Padding specified. Don't let it be more than
23929 current maximum. */
23930 if (precision > 0)
23931 lim = min (precision, lim);
23933 /* If that's more padding than already wanted, queue it.
23934 But don't reduce padding already specified even if
23935 that is beyond the current truncation point. */
23936 field_width = max (lim, field_width);
23938 goto tail_recurse;
23940 else if (STRINGP (car) || CONSP (car))
23941 FOR_EACH_TAIL_SAFE (elt)
23943 if (0 < precision && precision <= n)
23944 break;
23945 n += display_mode_element (it, depth,
23946 /* Pad after only the last
23947 list element. */
23948 (! CONSP (XCDR (elt))
23949 ? field_width - n
23950 : 0),
23951 precision - n, XCAR (elt),
23952 props, risky);
23955 break;
23957 default:
23958 invalid:
23959 elt = build_string ("*invalid*");
23960 goto tail_recurse;
23963 /* Pad to FIELD_WIDTH. */
23964 if (field_width > 0 && n < field_width)
23966 switch (mode_line_target)
23968 case MODE_LINE_NOPROP:
23969 case MODE_LINE_TITLE:
23970 n += store_mode_line_noprop ("", field_width - n, 0);
23971 break;
23972 case MODE_LINE_STRING:
23973 n += store_mode_line_string ("", Qnil, false, field_width - n, 0,
23974 Qnil);
23975 break;
23976 case MODE_LINE_DISPLAY:
23977 n += display_string ("", Qnil, Qnil, 0, 0, it, field_width - n,
23978 0, 0, 0);
23979 break;
23983 return n;
23986 /* Store a mode-line string element in mode_line_string_list.
23988 If STRING is non-null, display that C string. Otherwise, the Lisp
23989 string LISP_STRING is displayed.
23991 FIELD_WIDTH is the minimum number of output glyphs to produce.
23992 If STRING has fewer characters than FIELD_WIDTH, pad to the right
23993 with spaces. FIELD_WIDTH <= 0 means don't pad.
23995 PRECISION is the maximum number of characters to output from
23996 STRING. PRECISION <= 0 means don't truncate the string.
23998 If COPY_STRING, make a copy of LISP_STRING before adding
23999 properties to the string.
24001 PROPS are the properties to add to the string.
24002 The mode_line_string_face face property is always added to the string.
24005 static int
24006 store_mode_line_string (const char *string, Lisp_Object lisp_string,
24007 bool copy_string,
24008 int field_width, int precision, Lisp_Object props)
24010 ptrdiff_t len;
24011 int n = 0;
24013 if (string != NULL)
24015 len = strlen (string);
24016 if (precision > 0 && len > precision)
24017 len = precision;
24018 lisp_string = make_string (string, len);
24019 if (NILP (props))
24020 props = mode_line_string_face_prop;
24021 else if (!NILP (mode_line_string_face))
24023 Lisp_Object face = Fplist_get (props, Qface);
24024 props = Fcopy_sequence (props);
24025 if (NILP (face))
24026 face = mode_line_string_face;
24027 else
24028 face = list2 (face, mode_line_string_face);
24029 props = Fplist_put (props, Qface, face);
24031 Fadd_text_properties (make_number (0), make_number (len),
24032 props, lisp_string);
24034 else
24036 len = XFASTINT (Flength (lisp_string));
24037 if (precision > 0 && len > precision)
24039 len = precision;
24040 lisp_string = Fsubstring (lisp_string, make_number (0), make_number (len));
24041 precision = -1;
24043 if (!NILP (mode_line_string_face))
24045 Lisp_Object face;
24046 if (NILP (props))
24047 props = Ftext_properties_at (make_number (0), lisp_string);
24048 face = Fplist_get (props, Qface);
24049 if (NILP (face))
24050 face = mode_line_string_face;
24051 else
24052 face = list2 (face, mode_line_string_face);
24053 props = list2 (Qface, face);
24054 if (copy_string)
24055 lisp_string = Fcopy_sequence (lisp_string);
24057 if (!NILP (props))
24058 Fadd_text_properties (make_number (0), make_number (len),
24059 props, lisp_string);
24062 if (len > 0)
24064 mode_line_string_list = Fcons (lisp_string, mode_line_string_list);
24065 n += len;
24068 if (field_width > len)
24070 field_width -= len;
24071 lisp_string = Fmake_string (make_number (field_width), make_number (' '),
24072 Qnil);
24073 if (!NILP (props))
24074 Fadd_text_properties (make_number (0), make_number (field_width),
24075 props, lisp_string);
24076 mode_line_string_list = Fcons (lisp_string, mode_line_string_list);
24077 n += field_width;
24080 return n;
24084 DEFUN ("format-mode-line", Fformat_mode_line, Sformat_mode_line,
24085 1, 4, 0,
24086 doc: /* Format a string out of a mode line format specification.
24087 First arg FORMAT specifies the mode line format (see `mode-line-format'
24088 for details) to use.
24090 By default, the format is evaluated for the currently selected window.
24092 Optional second arg FACE specifies the face property to put on all
24093 characters for which no face is specified. The value nil means the
24094 default face. The value t means whatever face the window's mode line
24095 currently uses (either `mode-line' or `mode-line-inactive',
24096 depending on whether the window is the selected window or not).
24097 An integer value means the value string has no text
24098 properties.
24100 Optional third and fourth args WINDOW and BUFFER specify the window
24101 and buffer to use as the context for the formatting (defaults
24102 are the selected window and the WINDOW's buffer). */)
24103 (Lisp_Object format, Lisp_Object face,
24104 Lisp_Object window, Lisp_Object buffer)
24106 struct it it;
24107 int len;
24108 struct window *w;
24109 struct buffer *old_buffer = NULL;
24110 int face_id;
24111 bool no_props = INTEGERP (face);
24112 ptrdiff_t count = SPECPDL_INDEX ();
24113 Lisp_Object str;
24114 int string_start = 0;
24116 w = decode_any_window (window);
24117 XSETWINDOW (window, w);
24119 if (NILP (buffer))
24120 buffer = w->contents;
24121 CHECK_BUFFER (buffer);
24123 /* Make formatting the modeline a non-op when noninteractive, otherwise
24124 there will be problems later caused by a partially initialized frame. */
24125 if (NILP (format) || noninteractive)
24126 return empty_unibyte_string;
24128 if (no_props)
24129 face = Qnil;
24131 face_id = (NILP (face) || EQ (face, Qdefault)) ? DEFAULT_FACE_ID
24132 : EQ (face, Qt) ? (EQ (window, selected_window)
24133 ? MODE_LINE_FACE_ID : MODE_LINE_INACTIVE_FACE_ID)
24134 : EQ (face, Qmode_line) ? MODE_LINE_FACE_ID
24135 : EQ (face, Qmode_line_inactive) ? MODE_LINE_INACTIVE_FACE_ID
24136 : EQ (face, Qheader_line) ? HEADER_LINE_FACE_ID
24137 : EQ (face, Qtool_bar) ? TOOL_BAR_FACE_ID
24138 : DEFAULT_FACE_ID;
24140 old_buffer = current_buffer;
24142 /* Save things including mode_line_proptrans_alist,
24143 and set that to nil so that we don't alter the outer value. */
24144 record_unwind_protect (unwind_format_mode_line,
24145 format_mode_line_unwind_data
24146 (XFRAME (WINDOW_FRAME (w)),
24147 old_buffer, selected_window, true));
24148 mode_line_proptrans_alist = Qnil;
24150 Fselect_window (window, Qt);
24151 set_buffer_internal_1 (XBUFFER (buffer));
24153 init_iterator (&it, w, -1, -1, NULL, face_id);
24155 if (no_props)
24157 mode_line_target = MODE_LINE_NOPROP;
24158 mode_line_string_face_prop = Qnil;
24159 mode_line_string_list = Qnil;
24160 string_start = MODE_LINE_NOPROP_LEN (0);
24162 else
24164 mode_line_target = MODE_LINE_STRING;
24165 mode_line_string_list = Qnil;
24166 mode_line_string_face = face;
24167 mode_line_string_face_prop
24168 = NILP (face) ? Qnil : list2 (Qface, face);
24171 push_kboard (FRAME_KBOARD (it.f));
24172 display_mode_element (&it, 0, 0, 0, format, Qnil, false);
24173 pop_kboard ();
24175 if (no_props)
24177 len = MODE_LINE_NOPROP_LEN (string_start);
24178 str = make_string (mode_line_noprop_buf + string_start, len);
24180 else
24182 mode_line_string_list = Fnreverse (mode_line_string_list);
24183 str = Fmapconcat (Qidentity, mode_line_string_list,
24184 empty_unibyte_string);
24187 unbind_to (count, Qnil);
24188 return str;
24191 /* Write a null-terminated, right justified decimal representation of
24192 the positive integer D to BUF using a minimal field width WIDTH. */
24194 static void
24195 pint2str (register char *buf, register int width, register ptrdiff_t d)
24197 register char *p = buf;
24199 if (d <= 0)
24200 *p++ = '0';
24201 else
24203 while (d > 0)
24205 *p++ = d % 10 + '0';
24206 d /= 10;
24210 for (width -= (int) (p - buf); width > 0; --width)
24211 *p++ = ' ';
24212 *p-- = '\0';
24213 while (p > buf)
24215 d = *buf;
24216 *buf++ = *p;
24217 *p-- = d;
24221 /* Write a null-terminated, right justified decimal and "human
24222 readable" representation of the nonnegative integer D to BUF using
24223 a minimal field width WIDTH. D should be smaller than 999.5e24. */
24225 static const char power_letter[] =
24227 0, /* no letter */
24228 'k', /* kilo */
24229 'M', /* mega */
24230 'G', /* giga */
24231 'T', /* tera */
24232 'P', /* peta */
24233 'E', /* exa */
24234 'Z', /* zetta */
24235 'Y' /* yotta */
24238 static void
24239 pint2hrstr (char *buf, int width, ptrdiff_t d)
24241 /* We aim to represent the nonnegative integer D as
24242 QUOTIENT.TENTHS * 10 ^ (3 * EXPONENT). */
24243 ptrdiff_t quotient = d;
24244 int remainder = 0;
24245 /* -1 means: do not use TENTHS. */
24246 int tenths = -1;
24247 int exponent = 0;
24249 /* Length of QUOTIENT.TENTHS as a string. */
24250 int length;
24252 char * psuffix;
24253 char * p;
24255 if (quotient >= 1000)
24257 /* Scale to the appropriate EXPONENT. */
24260 remainder = quotient % 1000;
24261 quotient /= 1000;
24262 exponent++;
24264 while (quotient >= 1000);
24266 /* Round to nearest and decide whether to use TENTHS or not. */
24267 if (quotient <= 9)
24269 tenths = remainder / 100;
24270 if (remainder % 100 >= 50)
24272 if (tenths < 9)
24273 tenths++;
24274 else
24276 quotient++;
24277 if (quotient == 10)
24278 tenths = -1;
24279 else
24280 tenths = 0;
24284 else
24285 if (remainder >= 500)
24287 if (quotient < 999)
24288 quotient++;
24289 else
24291 quotient = 1;
24292 exponent++;
24293 tenths = 0;
24298 /* Calculate the LENGTH of QUOTIENT.TENTHS as a string. */
24299 if (tenths == -1 && quotient <= 99)
24300 if (quotient <= 9)
24301 length = 1;
24302 else
24303 length = 2;
24304 else
24305 length = 3;
24306 p = psuffix = buf + max (width, length);
24308 /* Print EXPONENT. */
24309 *psuffix++ = power_letter[exponent];
24310 *psuffix = '\0';
24312 /* Print TENTHS. */
24313 if (tenths >= 0)
24315 *--p = '0' + tenths;
24316 *--p = '.';
24319 /* Print QUOTIENT. */
24322 int digit = quotient % 10;
24323 *--p = '0' + digit;
24325 while ((quotient /= 10) != 0);
24327 /* Print leading spaces. */
24328 while (buf < p)
24329 *--p = ' ';
24332 /* Set a mnemonic character for coding_system (Lisp symbol) in BUF.
24333 If EOL_FLAG, set also a mnemonic character for end-of-line
24334 type of CODING_SYSTEM. Return updated pointer into BUF. */
24336 static unsigned char invalid_eol_type[] = "(*invalid*)";
24338 static char *
24339 decode_mode_spec_coding (Lisp_Object coding_system, char *buf, bool eol_flag)
24341 Lisp_Object val;
24342 bool multibyte = !NILP (BVAR (current_buffer, enable_multibyte_characters));
24343 const unsigned char *eol_str;
24344 int eol_str_len;
24345 /* The EOL conversion we are using. */
24346 Lisp_Object eoltype;
24348 val = CODING_SYSTEM_SPEC (coding_system);
24349 eoltype = Qnil;
24351 if (!VECTORP (val)) /* Not yet decided. */
24353 *buf++ = multibyte ? '-' : ' ';
24354 if (eol_flag)
24355 eoltype = eol_mnemonic_undecided;
24356 /* Don't mention EOL conversion if it isn't decided. */
24358 else
24360 Lisp_Object attrs;
24361 Lisp_Object eolvalue;
24363 attrs = AREF (val, 0);
24364 eolvalue = AREF (val, 2);
24366 *buf++ = multibyte
24367 ? XFASTINT (CODING_ATTR_MNEMONIC (attrs))
24368 : ' ';
24370 if (eol_flag)
24372 /* The EOL conversion that is normal on this system. */
24374 if (NILP (eolvalue)) /* Not yet decided. */
24375 eoltype = eol_mnemonic_undecided;
24376 else if (VECTORP (eolvalue)) /* Not yet decided. */
24377 eoltype = eol_mnemonic_undecided;
24378 else /* eolvalue is Qunix, Qdos, or Qmac. */
24379 eoltype = (EQ (eolvalue, Qunix)
24380 ? eol_mnemonic_unix
24381 : EQ (eolvalue, Qdos)
24382 ? eol_mnemonic_dos : eol_mnemonic_mac);
24386 if (eol_flag)
24388 /* Mention the EOL conversion if it is not the usual one. */
24389 if (STRINGP (eoltype))
24391 eol_str = SDATA (eoltype);
24392 eol_str_len = SBYTES (eoltype);
24394 else if (CHARACTERP (eoltype))
24396 int c = XFASTINT (eoltype);
24397 return buf + CHAR_STRING (c, (unsigned char *) buf);
24399 else
24401 eol_str = invalid_eol_type;
24402 eol_str_len = sizeof (invalid_eol_type) - 1;
24404 memcpy (buf, eol_str, eol_str_len);
24405 buf += eol_str_len;
24408 return buf;
24411 /* Return the approximate percentage N is of D (rounding upward), or 99,
24412 whichever is less. Assume 0 < D and 0 <= N <= D * INT_MAX / 100. */
24414 static int
24415 percent99 (ptrdiff_t n, ptrdiff_t d)
24417 int percent = (d - 1 + 100.0 * n) / d;
24418 return min (percent, 99);
24421 /* Return a string for the output of a mode line %-spec for window W,
24422 generated by character C. FIELD_WIDTH > 0 means pad the string
24423 returned with spaces to that value. Return a Lisp string in
24424 *STRING if the resulting string is taken from that Lisp string.
24426 Note we operate on the current buffer for most purposes. */
24428 static char lots_of_dashes[] = "--------------------------------------------------------------------------------------------------------------------------------------------";
24430 static const char *
24431 decode_mode_spec (struct window *w, register int c, int field_width,
24432 Lisp_Object *string)
24434 Lisp_Object obj;
24435 struct frame *f = XFRAME (WINDOW_FRAME (w));
24436 char *decode_mode_spec_buf = f->decode_mode_spec_buffer;
24437 /* We are going to use f->decode_mode_spec_buffer as the buffer to
24438 produce strings from numerical values, so limit preposterously
24439 large values of FIELD_WIDTH to avoid overrunning the buffer's
24440 end. The size of the buffer is enough for FRAME_MESSAGE_BUF_SIZE
24441 bytes plus the terminating null. */
24442 int width = min (field_width, FRAME_MESSAGE_BUF_SIZE (f));
24443 struct buffer *b = current_buffer;
24445 obj = Qnil;
24446 *string = Qnil;
24448 switch (c)
24450 case '*':
24451 if (!NILP (BVAR (b, read_only)))
24452 return "%";
24453 if (BUF_MODIFF (b) > BUF_SAVE_MODIFF (b))
24454 return "*";
24455 return "-";
24457 case '+':
24458 /* This differs from %* only for a modified read-only buffer. */
24459 if (BUF_MODIFF (b) > BUF_SAVE_MODIFF (b))
24460 return "*";
24461 if (!NILP (BVAR (b, read_only)))
24462 return "%";
24463 return "-";
24465 case '&':
24466 /* This differs from %* in ignoring read-only-ness. */
24467 if (BUF_MODIFF (b) > BUF_SAVE_MODIFF (b))
24468 return "*";
24469 return "-";
24471 case '%':
24472 return "%";
24474 case '[':
24476 int i;
24477 char *p;
24479 if (command_loop_level > 5)
24480 return "[[[... ";
24481 p = decode_mode_spec_buf;
24482 for (i = 0; i < command_loop_level; i++)
24483 *p++ = '[';
24484 *p = 0;
24485 return decode_mode_spec_buf;
24488 case ']':
24490 int i;
24491 char *p;
24493 if (command_loop_level > 5)
24494 return " ...]]]";
24495 p = decode_mode_spec_buf;
24496 for (i = 0; i < command_loop_level; i++)
24497 *p++ = ']';
24498 *p = 0;
24499 return decode_mode_spec_buf;
24502 case '-':
24504 register int i;
24506 /* Let lots_of_dashes be a string of infinite length. */
24507 if (mode_line_target == MODE_LINE_NOPROP
24508 || mode_line_target == MODE_LINE_STRING)
24509 return "--";
24510 if (field_width <= 0
24511 || field_width > sizeof (lots_of_dashes))
24513 for (i = 0; i < FRAME_MESSAGE_BUF_SIZE (f) - 1; ++i)
24514 decode_mode_spec_buf[i] = '-';
24515 decode_mode_spec_buf[i] = '\0';
24516 return decode_mode_spec_buf;
24518 else
24519 return lots_of_dashes;
24522 case 'b':
24523 obj = BVAR (b, name);
24524 break;
24526 case 'c':
24527 case 'C':
24528 /* %c, %C, and %l are ignored in `frame-title-format'.
24529 (In redisplay_internal, the frame title is drawn _before_ the
24530 windows are updated, so the stuff which depends on actual
24531 window contents (such as %l) may fail to render properly, or
24532 even crash emacs.) */
24533 if (mode_line_target == MODE_LINE_TITLE)
24534 return "";
24535 else
24537 ptrdiff_t col = current_column ();
24538 int disp_col = (c == 'C') ? col + 1 : col;
24539 w->column_number_displayed = col;
24540 pint2str (decode_mode_spec_buf, width, disp_col);
24541 return decode_mode_spec_buf;
24544 case 'e':
24545 #if !defined SYSTEM_MALLOC && !defined HYBRID_MALLOC
24547 if (NILP (Vmemory_full))
24548 return "";
24549 else
24550 return "!MEM FULL! ";
24552 #else
24553 return "";
24554 #endif
24556 case 'F':
24557 /* %F displays the frame name. */
24558 if (!NILP (f->title))
24559 return SSDATA (f->title);
24560 if (f->explicit_name || ! FRAME_WINDOW_P (f))
24561 return SSDATA (f->name);
24562 return "Emacs";
24564 case 'f':
24565 obj = BVAR (b, filename);
24566 break;
24568 case 'i':
24570 ptrdiff_t size = ZV - BEGV;
24571 pint2str (decode_mode_spec_buf, width, size);
24572 return decode_mode_spec_buf;
24575 case 'I':
24577 ptrdiff_t size = ZV - BEGV;
24578 pint2hrstr (decode_mode_spec_buf, width, size);
24579 return decode_mode_spec_buf;
24582 case 'l':
24584 ptrdiff_t startpos, startpos_byte, line, linepos, linepos_byte;
24585 ptrdiff_t topline, nlines, height;
24586 ptrdiff_t junk;
24588 /* %c, %C, and %l are ignored in `frame-title-format'. */
24589 if (mode_line_target == MODE_LINE_TITLE)
24590 return "";
24592 startpos = marker_position (w->start);
24593 startpos_byte = marker_byte_position (w->start);
24594 height = WINDOW_TOTAL_LINES (w);
24596 /* If we decided that this buffer isn't suitable for line numbers,
24597 don't forget that too fast. */
24598 if (w->base_line_pos == -1)
24599 goto no_value;
24601 /* If the buffer is very big, don't waste time. */
24602 if (INTEGERP (Vline_number_display_limit)
24603 && BUF_ZV (b) - BUF_BEGV (b) > XINT (Vline_number_display_limit))
24605 w->base_line_pos = 0;
24606 w->base_line_number = 0;
24607 goto no_value;
24610 if (w->base_line_number > 0
24611 && w->base_line_pos > 0
24612 && w->base_line_pos <= startpos)
24614 line = w->base_line_number;
24615 linepos = w->base_line_pos;
24616 linepos_byte = buf_charpos_to_bytepos (b, linepos);
24618 else
24620 line = 1;
24621 linepos = BUF_BEGV (b);
24622 linepos_byte = BUF_BEGV_BYTE (b);
24625 /* Count lines from base line to window start position. */
24626 nlines = display_count_lines (linepos_byte,
24627 startpos_byte,
24628 startpos, &junk);
24630 topline = nlines + line;
24632 /* Determine a new base line, if the old one is too close
24633 or too far away, or if we did not have one.
24634 "Too close" means it's plausible a scroll-down would
24635 go back past it. */
24636 if (startpos == BUF_BEGV (b))
24638 w->base_line_number = topline;
24639 w->base_line_pos = BUF_BEGV (b);
24641 else if (nlines < height + 25 || nlines > height * 3 + 50
24642 || linepos == BUF_BEGV (b))
24644 ptrdiff_t limit = BUF_BEGV (b);
24645 ptrdiff_t limit_byte = BUF_BEGV_BYTE (b);
24646 ptrdiff_t position;
24647 ptrdiff_t distance =
24648 (height * 2 + 30) * line_number_display_limit_width;
24650 if (startpos - distance > limit)
24652 limit = startpos - distance;
24653 limit_byte = CHAR_TO_BYTE (limit);
24656 nlines = display_count_lines (startpos_byte,
24657 limit_byte,
24658 - (height * 2 + 30),
24659 &position);
24660 /* If we couldn't find the lines we wanted within
24661 line_number_display_limit_width chars per line,
24662 give up on line numbers for this window. */
24663 if (position == limit_byte && limit == startpos - distance)
24665 w->base_line_pos = -1;
24666 w->base_line_number = 0;
24667 goto no_value;
24670 w->base_line_number = topline - nlines;
24671 w->base_line_pos = BYTE_TO_CHAR (position);
24674 /* Now count lines from the start pos to point. */
24675 nlines = display_count_lines (startpos_byte,
24676 PT_BYTE, PT, &junk);
24678 /* Record that we did display the line number. */
24679 line_number_displayed = true;
24681 /* Make the string to show. */
24682 pint2str (decode_mode_spec_buf, width, topline + nlines);
24683 return decode_mode_spec_buf;
24684 no_value:
24686 char *p = decode_mode_spec_buf;
24687 int pad = width - 2;
24688 while (pad-- > 0)
24689 *p++ = ' ';
24690 *p++ = '?';
24691 *p++ = '?';
24692 *p = '\0';
24693 return decode_mode_spec_buf;
24696 break;
24698 case 'm':
24699 obj = BVAR (b, mode_name);
24700 break;
24702 case 'n':
24703 if (BUF_BEGV (b) > BUF_BEG (b) || BUF_ZV (b) < BUF_Z (b))
24704 return " Narrow";
24705 break;
24707 /* Display the "degree of travel" of the window through the buffer. */
24708 case 'o':
24710 ptrdiff_t toppos = marker_position (w->start);
24711 ptrdiff_t botpos = BUF_Z (b) - w->window_end_pos;
24712 ptrdiff_t begv = BUF_BEGV (b);
24713 ptrdiff_t zv = BUF_ZV (b);
24715 if (zv <= botpos)
24716 return toppos <= begv ? "All" : "Bottom";
24717 else if (toppos <= begv)
24718 return "Top";
24719 else
24721 sprintf (decode_mode_spec_buf, "%2d%%",
24722 percent99 (toppos - begv, (toppos - begv) + (zv - botpos)));
24723 return decode_mode_spec_buf;
24727 /* Display percentage of buffer above the top of the screen. */
24728 case 'p':
24730 ptrdiff_t pos = marker_position (w->start);
24731 ptrdiff_t begv = BUF_BEGV (b);
24732 ptrdiff_t zv = BUF_ZV (b);
24734 if (w->window_end_pos <= BUF_Z (b) - zv)
24735 return pos <= begv ? "All" : "Bottom";
24736 else if (pos <= begv)
24737 return "Top";
24738 else
24740 sprintf (decode_mode_spec_buf, "%2d%%",
24741 percent99 (pos - begv, zv - begv));
24742 return decode_mode_spec_buf;
24746 /* Display percentage of size above the bottom of the screen. */
24747 case 'P':
24749 ptrdiff_t toppos = marker_position (w->start);
24750 ptrdiff_t botpos = BUF_Z (b) - w->window_end_pos;
24751 ptrdiff_t begv = BUF_BEGV (b);
24752 ptrdiff_t zv = BUF_ZV (b);
24754 if (zv <= botpos)
24755 return toppos <= begv ? "All" : "Bottom";
24756 else
24758 sprintf (decode_mode_spec_buf,
24759 &"Top%2d%%"[begv < toppos ? sizeof "Top" - 1 : 0],
24760 percent99 (botpos - begv, zv - begv));
24761 return decode_mode_spec_buf;
24765 /* Display percentage offsets of top and bottom of the window,
24766 using "All" (but not "Top" or "Bottom") where appropriate. */
24767 case 'q':
24769 ptrdiff_t toppos = marker_position (w->start);
24770 ptrdiff_t botpos = BUF_Z (b) - w->window_end_pos;
24771 ptrdiff_t begv = BUF_BEGV (b);
24772 ptrdiff_t zv = BUF_ZV (b);
24773 int top_perc, bot_perc;
24775 if ((toppos <= begv) && (zv <= botpos))
24776 return "All ";
24778 top_perc = toppos <= begv ? 0 : percent99 (toppos - begv, zv - begv);
24779 bot_perc = zv <= botpos ? 100 : percent99 (botpos - begv, zv - begv);
24781 if (top_perc == bot_perc)
24782 sprintf (decode_mode_spec_buf, "%d%%", top_perc);
24783 else
24784 sprintf (decode_mode_spec_buf, "%d-%d%%", top_perc, bot_perc);
24786 return decode_mode_spec_buf;
24789 case 's':
24790 /* status of process */
24791 obj = Fget_buffer_process (Fcurrent_buffer ());
24792 if (NILP (obj))
24793 return "no process";
24794 #ifndef MSDOS
24795 obj = Fsymbol_name (Fprocess_status (obj));
24796 #endif
24797 break;
24799 case '@':
24801 ptrdiff_t count = inhibit_garbage_collection ();
24802 Lisp_Object curdir = BVAR (current_buffer, directory);
24803 Lisp_Object val = Qnil;
24805 if (STRINGP (curdir))
24806 val = call1 (intern ("file-remote-p"), curdir);
24808 unbind_to (count, Qnil);
24810 if (NILP (val))
24811 return "-";
24812 else
24813 return "@";
24816 case 'z':
24817 /* coding-system (not including end-of-line format) */
24818 case 'Z':
24819 /* coding-system (including end-of-line type) */
24821 bool eol_flag = (c == 'Z');
24822 char *p = decode_mode_spec_buf;
24824 if (! FRAME_WINDOW_P (f))
24826 /* No need to mention EOL here--the terminal never needs
24827 to do EOL conversion. */
24828 p = decode_mode_spec_coding (CODING_ID_NAME
24829 (FRAME_KEYBOARD_CODING (f)->id),
24830 p, false);
24831 p = decode_mode_spec_coding (CODING_ID_NAME
24832 (FRAME_TERMINAL_CODING (f)->id),
24833 p, false);
24835 p = decode_mode_spec_coding (BVAR (b, buffer_file_coding_system),
24836 p, eol_flag);
24838 #if false /* This proves to be annoying; I think we can do without. -- rms. */
24839 #ifdef subprocesses
24840 obj = Fget_buffer_process (Fcurrent_buffer ());
24841 if (PROCESSP (obj))
24843 p = decode_mode_spec_coding
24844 (XPROCESS (obj)->decode_coding_system, p, eol_flag);
24845 p = decode_mode_spec_coding
24846 (XPROCESS (obj)->encode_coding_system, p, eol_flag);
24848 #endif /* subprocesses */
24849 #endif /* false */
24850 *p = 0;
24851 return decode_mode_spec_buf;
24855 if (STRINGP (obj))
24857 *string = obj;
24858 return SSDATA (obj);
24860 else
24861 return "";
24865 /* Count up to COUNT lines starting from START_BYTE. COUNT negative
24866 means count lines back from START_BYTE. But don't go beyond
24867 LIMIT_BYTE. Return the number of lines thus found (always
24868 nonnegative).
24870 Set *BYTE_POS_PTR to the byte position where we stopped. This is
24871 either the position COUNT lines after/before START_BYTE, if we
24872 found COUNT lines, or LIMIT_BYTE if we hit the limit before finding
24873 COUNT lines. */
24875 static ptrdiff_t
24876 display_count_lines (ptrdiff_t start_byte,
24877 ptrdiff_t limit_byte, ptrdiff_t count,
24878 ptrdiff_t *byte_pos_ptr)
24880 register unsigned char *cursor;
24881 unsigned char *base;
24883 register ptrdiff_t ceiling;
24884 register unsigned char *ceiling_addr;
24885 ptrdiff_t orig_count = count;
24887 /* If we are not in selective display mode,
24888 check only for newlines. */
24889 bool selective_display
24890 = (!NILP (BVAR (current_buffer, selective_display))
24891 && !INTEGERP (BVAR (current_buffer, selective_display)));
24893 if (count > 0)
24895 while (start_byte < limit_byte)
24897 ceiling = BUFFER_CEILING_OF (start_byte);
24898 ceiling = min (limit_byte - 1, ceiling);
24899 ceiling_addr = BYTE_POS_ADDR (ceiling) + 1;
24900 base = (cursor = BYTE_POS_ADDR (start_byte));
24904 if (selective_display)
24906 while (*cursor != '\n' && *cursor != 015
24907 && ++cursor != ceiling_addr)
24908 continue;
24909 if (cursor == ceiling_addr)
24910 break;
24912 else
24914 cursor = memchr (cursor, '\n', ceiling_addr - cursor);
24915 if (! cursor)
24916 break;
24919 cursor++;
24921 if (--count == 0)
24923 start_byte += cursor - base;
24924 *byte_pos_ptr = start_byte;
24925 return orig_count;
24928 while (cursor < ceiling_addr);
24930 start_byte += ceiling_addr - base;
24933 else
24935 while (start_byte > limit_byte)
24937 ceiling = BUFFER_FLOOR_OF (start_byte - 1);
24938 ceiling = max (limit_byte, ceiling);
24939 ceiling_addr = BYTE_POS_ADDR (ceiling);
24940 base = (cursor = BYTE_POS_ADDR (start_byte - 1) + 1);
24941 while (true)
24943 if (selective_display)
24945 while (--cursor >= ceiling_addr
24946 && *cursor != '\n' && *cursor != 015)
24947 continue;
24948 if (cursor < ceiling_addr)
24949 break;
24951 else
24953 cursor = memrchr (ceiling_addr, '\n', cursor - ceiling_addr);
24954 if (! cursor)
24955 break;
24958 if (++count == 0)
24960 start_byte += cursor - base + 1;
24961 *byte_pos_ptr = start_byte;
24962 /* When scanning backwards, we should
24963 not count the newline posterior to which we stop. */
24964 return - orig_count - 1;
24967 start_byte += ceiling_addr - base;
24971 *byte_pos_ptr = limit_byte;
24973 if (count < 0)
24974 return - orig_count + count;
24975 return orig_count - count;
24981 /***********************************************************************
24982 Displaying strings
24983 ***********************************************************************/
24985 /* Display a NUL-terminated string, starting with index START.
24987 If STRING is non-null, display that C string. Otherwise, the Lisp
24988 string LISP_STRING is displayed. There's a case that STRING is
24989 non-null and LISP_STRING is not nil. It means STRING is a string
24990 data of LISP_STRING. In that case, we display LISP_STRING while
24991 ignoring its text properties.
24993 If FACE_STRING is not nil, FACE_STRING_POS is a position in
24994 FACE_STRING. Display STRING or LISP_STRING with the face at
24995 FACE_STRING_POS in FACE_STRING:
24997 Display the string in the environment given by IT, but use the
24998 standard display table, temporarily.
25000 FIELD_WIDTH is the minimum number of output glyphs to produce.
25001 If STRING has fewer characters than FIELD_WIDTH, pad to the right
25002 with spaces. If STRING has more characters, more than FIELD_WIDTH
25003 glyphs will be produced. FIELD_WIDTH <= 0 means don't pad.
25005 PRECISION is the maximum number of characters to output from
25006 STRING. PRECISION < 0 means don't truncate the string.
25008 This is roughly equivalent to printf format specifiers:
25010 FIELD_WIDTH PRECISION PRINTF
25011 ----------------------------------------
25012 -1 -1 %s
25013 -1 10 %.10s
25014 10 -1 %10s
25015 20 10 %20.10s
25017 MULTIBYTE zero means do not display multibyte chars, > 0 means do
25018 display them, and < 0 means obey the current buffer's value of
25019 enable_multibyte_characters.
25021 Value is the number of columns displayed. */
25023 static int
25024 display_string (const char *string, Lisp_Object lisp_string, Lisp_Object face_string,
25025 ptrdiff_t face_string_pos, ptrdiff_t start, struct it *it,
25026 int field_width, int precision, int max_x, int multibyte)
25028 int hpos_at_start = it->hpos;
25029 int saved_face_id = it->face_id;
25030 struct glyph_row *row = it->glyph_row;
25031 ptrdiff_t it_charpos;
25033 /* Initialize the iterator IT for iteration over STRING beginning
25034 with index START. */
25035 reseat_to_string (it, NILP (lisp_string) ? string : NULL, lisp_string, start,
25036 precision, field_width, multibyte);
25037 if (string && STRINGP (lisp_string))
25038 /* LISP_STRING is the one returned by decode_mode_spec. We should
25039 ignore its text properties. */
25040 it->stop_charpos = it->end_charpos;
25042 /* If displaying STRING, set up the face of the iterator from
25043 FACE_STRING, if that's given. */
25044 if (STRINGP (face_string))
25046 ptrdiff_t endptr;
25047 struct face *face;
25049 it->face_id
25050 = face_at_string_position (it->w, face_string, face_string_pos,
25051 0, &endptr, it->base_face_id, false);
25052 face = FACE_FROM_ID (it->f, it->face_id);
25053 it->face_box_p = face->box != FACE_NO_BOX;
25056 /* Set max_x to the maximum allowed X position. Don't let it go
25057 beyond the right edge of the window. */
25058 if (max_x <= 0)
25059 max_x = it->last_visible_x;
25060 else
25061 max_x = min (max_x, it->last_visible_x);
25063 /* Skip over display elements that are not visible. because IT->w is
25064 hscrolled. */
25065 if (it->current_x < it->first_visible_x)
25066 move_it_in_display_line_to (it, 100000, it->first_visible_x,
25067 MOVE_TO_POS | MOVE_TO_X);
25069 row->ascent = it->max_ascent;
25070 row->height = it->max_ascent + it->max_descent;
25071 row->phys_ascent = it->max_phys_ascent;
25072 row->phys_height = it->max_phys_ascent + it->max_phys_descent;
25073 row->extra_line_spacing = it->max_extra_line_spacing;
25075 if (STRINGP (it->string))
25076 it_charpos = IT_STRING_CHARPOS (*it);
25077 else
25078 it_charpos = IT_CHARPOS (*it);
25080 /* This condition is for the case that we are called with current_x
25081 past last_visible_x. */
25082 while (it->current_x < max_x)
25084 int x_before, x, n_glyphs_before, i, nglyphs;
25086 /* Get the next display element. */
25087 if (!get_next_display_element (it))
25088 break;
25090 /* Produce glyphs. */
25091 x_before = it->current_x;
25092 n_glyphs_before = row->used[TEXT_AREA];
25093 PRODUCE_GLYPHS (it);
25095 nglyphs = row->used[TEXT_AREA] - n_glyphs_before;
25096 i = 0;
25097 x = x_before;
25098 while (i < nglyphs)
25100 struct glyph *glyph = row->glyphs[TEXT_AREA] + n_glyphs_before + i;
25102 if (it->line_wrap != TRUNCATE
25103 && x + glyph->pixel_width > max_x)
25105 /* End of continued line or max_x reached. */
25106 if (CHAR_GLYPH_PADDING_P (*glyph))
25108 /* A wide character is unbreakable. */
25109 if (row->reversed_p)
25110 unproduce_glyphs (it, row->used[TEXT_AREA]
25111 - n_glyphs_before);
25112 row->used[TEXT_AREA] = n_glyphs_before;
25113 it->current_x = x_before;
25115 else
25117 if (row->reversed_p)
25118 unproduce_glyphs (it, row->used[TEXT_AREA]
25119 - (n_glyphs_before + i));
25120 row->used[TEXT_AREA] = n_glyphs_before + i;
25121 it->current_x = x;
25123 break;
25125 else if (x + glyph->pixel_width >= it->first_visible_x)
25127 /* Glyph is at least partially visible. */
25128 ++it->hpos;
25129 if (x < it->first_visible_x)
25130 row->x = x - it->first_visible_x;
25132 else
25134 /* Glyph is off the left margin of the display area.
25135 Should not happen. */
25136 emacs_abort ();
25139 row->ascent = max (row->ascent, it->max_ascent);
25140 row->height = max (row->height, it->max_ascent + it->max_descent);
25141 row->phys_ascent = max (row->phys_ascent, it->max_phys_ascent);
25142 row->phys_height = max (row->phys_height,
25143 it->max_phys_ascent + it->max_phys_descent);
25144 row->extra_line_spacing = max (row->extra_line_spacing,
25145 it->max_extra_line_spacing);
25146 x += glyph->pixel_width;
25147 ++i;
25150 /* Stop if max_x reached. */
25151 if (i < nglyphs)
25152 break;
25154 /* Stop at line ends. */
25155 if (ITERATOR_AT_END_OF_LINE_P (it))
25157 it->continuation_lines_width = 0;
25158 break;
25161 set_iterator_to_next (it, true);
25162 if (STRINGP (it->string))
25163 it_charpos = IT_STRING_CHARPOS (*it);
25164 else
25165 it_charpos = IT_CHARPOS (*it);
25167 /* Stop if truncating at the right edge. */
25168 if (it->line_wrap == TRUNCATE
25169 && it->current_x >= it->last_visible_x)
25171 /* Add truncation mark, but don't do it if the line is
25172 truncated at a padding space. */
25173 if (it_charpos < it->string_nchars)
25175 if (!FRAME_WINDOW_P (it->f))
25177 int ii, n;
25179 if (it->current_x > it->last_visible_x)
25181 if (!row->reversed_p)
25183 for (ii = row->used[TEXT_AREA] - 1; ii > 0; --ii)
25184 if (!CHAR_GLYPH_PADDING_P (row->glyphs[TEXT_AREA][ii]))
25185 break;
25187 else
25189 for (ii = 0; ii < row->used[TEXT_AREA]; ii++)
25190 if (!CHAR_GLYPH_PADDING_P (row->glyphs[TEXT_AREA][ii]))
25191 break;
25192 unproduce_glyphs (it, ii + 1);
25193 ii = row->used[TEXT_AREA] - (ii + 1);
25195 for (n = row->used[TEXT_AREA]; ii < n; ++ii)
25197 row->used[TEXT_AREA] = ii;
25198 produce_special_glyphs (it, IT_TRUNCATION);
25201 produce_special_glyphs (it, IT_TRUNCATION);
25203 row->truncated_on_right_p = true;
25205 break;
25209 /* Maybe insert a truncation at the left. */
25210 if (it->first_visible_x
25211 && it_charpos > 0)
25213 if (!FRAME_WINDOW_P (it->f)
25214 || (row->reversed_p
25215 ? WINDOW_RIGHT_FRINGE_WIDTH (it->w)
25216 : WINDOW_LEFT_FRINGE_WIDTH (it->w)) == 0)
25217 insert_left_trunc_glyphs (it);
25218 row->truncated_on_left_p = true;
25221 it->face_id = saved_face_id;
25223 /* Value is number of columns displayed. */
25224 return it->hpos - hpos_at_start;
25229 /* This is like a combination of memq and assq. Return 1/2 if PROPVAL
25230 appears as an element of LIST or as the car of an element of LIST.
25231 If PROPVAL is a list, compare each element against LIST in that
25232 way, and return 1/2 if any element of PROPVAL is found in LIST.
25233 Otherwise return 0. This function cannot quit.
25234 The return value is 2 if the text is invisible but with an ellipsis
25235 and 1 if it's invisible and without an ellipsis. */
25238 invisible_prop (Lisp_Object propval, Lisp_Object list)
25240 Lisp_Object tail, proptail;
25242 for (tail = list; CONSP (tail); tail = XCDR (tail))
25244 register Lisp_Object tem;
25245 tem = XCAR (tail);
25246 if (EQ (propval, tem))
25247 return 1;
25248 if (CONSP (tem) && EQ (propval, XCAR (tem)))
25249 return NILP (XCDR (tem)) ? 1 : 2;
25252 if (CONSP (propval))
25254 for (proptail = propval; CONSP (proptail); proptail = XCDR (proptail))
25256 Lisp_Object propelt;
25257 propelt = XCAR (proptail);
25258 for (tail = list; CONSP (tail); tail = XCDR (tail))
25260 register Lisp_Object tem;
25261 tem = XCAR (tail);
25262 if (EQ (propelt, tem))
25263 return 1;
25264 if (CONSP (tem) && EQ (propelt, XCAR (tem)))
25265 return NILP (XCDR (tem)) ? 1 : 2;
25270 return 0;
25273 DEFUN ("invisible-p", Finvisible_p, Sinvisible_p, 1, 1, 0,
25274 doc: /* Non-nil if text properties at POS cause text there to be currently invisible.
25275 POS should be a marker or a buffer position; the value of the `invisible'
25276 property at that position in the current buffer is examined.
25277 POS can also be the actual value of the `invisible' text or overlay
25278 property of the text of interest, in which case the value itself is
25279 examined.
25281 The non-nil value returned can be t for currently invisible text that is
25282 entirely hidden on display, or some other non-nil, non-t value if the
25283 text is replaced by an ellipsis.
25285 Note that whether text with `invisible' property is actually hidden on
25286 display may depend on `buffer-invisibility-spec', which see. */)
25287 (Lisp_Object pos)
25289 Lisp_Object prop
25290 = (NATNUMP (pos) || MARKERP (pos)
25291 ? Fget_char_property (pos, Qinvisible, Qnil)
25292 : pos);
25293 int invis = TEXT_PROP_MEANS_INVISIBLE (prop);
25294 return (invis == 0 ? Qnil
25295 : invis == 1 ? Qt
25296 : make_number (invis));
25299 /* Calculate a width or height in pixels from a specification using
25300 the following elements:
25302 SPEC ::=
25303 NUM - a (fractional) multiple of the default font width/height
25304 (NUM) - specifies exactly NUM pixels
25305 UNIT - a fixed number of pixels, see below.
25306 ELEMENT - size of a display element in pixels, see below.
25307 (NUM . SPEC) - equals NUM * SPEC
25308 (+ SPEC SPEC ...) - add pixel values
25309 (- SPEC SPEC ...) - subtract pixel values
25310 (- SPEC) - negate pixel value
25312 NUM ::=
25313 INT or FLOAT - a number constant
25314 SYMBOL - use symbol's (buffer local) variable binding.
25316 UNIT ::=
25317 in - pixels per inch *)
25318 mm - pixels per 1/1000 meter *)
25319 cm - pixels per 1/100 meter *)
25320 width - width of current font in pixels.
25321 height - height of current font in pixels.
25323 *) using the ratio(s) defined in display-pixels-per-inch.
25325 ELEMENT ::=
25327 left-fringe - left fringe width in pixels
25328 right-fringe - right fringe width in pixels
25330 left-margin - left margin width in pixels
25331 right-margin - right margin width in pixels
25333 scroll-bar - scroll-bar area width in pixels
25335 Examples:
25337 Pixels corresponding to 5 inches:
25338 (5 . in)
25340 Total width of non-text areas on left side of window (if scroll-bar is on left):
25341 '(space :width (+ left-fringe left-margin scroll-bar))
25343 Align to first text column (in header line):
25344 '(space :align-to 0)
25346 Align to middle of text area minus half the width of variable `my-image'
25347 containing a loaded image:
25348 '(space :align-to (0.5 . (- text my-image)))
25350 Width of left margin minus width of 1 character in the default font:
25351 '(space :width (- left-margin 1))
25353 Width of left margin minus width of 2 characters in the current font:
25354 '(space :width (- left-margin (2 . width)))
25356 Center 1 character over left-margin (in header line):
25357 '(space :align-to (+ left-margin (0.5 . left-margin) -0.5))
25359 Different ways to express width of left fringe plus left margin minus one pixel:
25360 '(space :width (- (+ left-fringe left-margin) (1)))
25361 '(space :width (+ left-fringe left-margin (- (1))))
25362 '(space :width (+ left-fringe left-margin (-1)))
25364 If ALIGN_TO is NULL, returns the result in *RES. If ALIGN_TO is
25365 non-NULL, the value of *ALIGN_TO is a window-relative pixel
25366 coordinate, and *RES is the additional pixel width from that point
25367 till the end of the stretch glyph.
25369 WIDTH_P non-zero means take the width dimension or X coordinate of
25370 the object specified by PROP, WIDTH_P zero means take the height
25371 dimension or the Y coordinate. (Therefore, if ALIGN_TO is
25372 non-NULL, WIDTH_P should be non-zero.)
25374 FONT is the font of the face of the surrounding text.
25376 The return value is non-zero if width or height were successfully
25377 calculated, i.e. if PROP is a valid spec. */
25379 static bool
25380 calc_pixel_width_or_height (double *res, struct it *it, Lisp_Object prop,
25381 struct font *font, bool width_p, int *align_to)
25383 double pixels;
25385 # define OK_PIXELS(val) (*res = (val), true)
25386 # define OK_ALIGN_TO(val) (*align_to = (val), true)
25388 if (NILP (prop))
25389 return OK_PIXELS (0);
25391 eassert (FRAME_LIVE_P (it->f));
25393 if (SYMBOLP (prop))
25395 if (SCHARS (SYMBOL_NAME (prop)) == 2)
25397 char *unit = SSDATA (SYMBOL_NAME (prop));
25399 /* The UNIT expression, e.g. as part of (NUM . UNIT). */
25400 if (unit[0] == 'i' && unit[1] == 'n')
25401 pixels = 1.0;
25402 else if (unit[0] == 'm' && unit[1] == 'm')
25403 pixels = 25.4;
25404 else if (unit[0] == 'c' && unit[1] == 'm')
25405 pixels = 2.54;
25406 else
25407 pixels = 0;
25408 if (pixels > 0)
25410 double ppi = (width_p ? FRAME_RES_X (it->f)
25411 : FRAME_RES_Y (it->f));
25413 if (ppi > 0)
25414 return OK_PIXELS (ppi / pixels);
25415 return false;
25419 #ifdef HAVE_WINDOW_SYSTEM
25420 /* 'height': the height of FONT. */
25421 if (EQ (prop, Qheight))
25422 return OK_PIXELS (font
25423 ? normal_char_height (font, -1)
25424 : FRAME_LINE_HEIGHT (it->f));
25425 /* 'width': the width of FONT. */
25426 if (EQ (prop, Qwidth))
25427 return OK_PIXELS (font
25428 ? FONT_WIDTH (font)
25429 : FRAME_COLUMN_WIDTH (it->f));
25430 #else
25431 if (EQ (prop, Qheight) || EQ (prop, Qwidth))
25432 return OK_PIXELS (1);
25433 #endif
25435 /* 'text': the width or height of the text area. */
25436 if (EQ (prop, Qtext))
25437 return OK_PIXELS (width_p
25438 ? (window_box_width (it->w, TEXT_AREA)
25439 - it->lnum_pixel_width)
25440 : WINDOW_BOX_HEIGHT_NO_MODE_LINE (it->w));
25442 /* ':align_to'. First time we compute the value, window
25443 elements are interpreted as the position of the element's
25444 left edge. */
25445 if (align_to && *align_to < 0)
25447 *res = 0;
25448 /* 'left': left edge of the text area. */
25449 if (EQ (prop, Qleft))
25450 return OK_ALIGN_TO (window_box_left_offset (it->w, TEXT_AREA)
25451 + it->lnum_pixel_width);
25452 /* 'right': right edge of the text area. */
25453 if (EQ (prop, Qright))
25454 return OK_ALIGN_TO (window_box_right_offset (it->w, TEXT_AREA));
25455 /* 'center': the center of the text area. */
25456 if (EQ (prop, Qcenter))
25457 return OK_ALIGN_TO (window_box_left_offset (it->w, TEXT_AREA)
25458 + it->lnum_pixel_width
25459 + window_box_width (it->w, TEXT_AREA) / 2);
25460 /* 'left-fringe': left edge of the left fringe. */
25461 if (EQ (prop, Qleft_fringe))
25462 return OK_ALIGN_TO (WINDOW_HAS_FRINGES_OUTSIDE_MARGINS (it->w)
25463 ? WINDOW_LEFT_SCROLL_BAR_AREA_WIDTH (it->w)
25464 : window_box_right_offset (it->w, LEFT_MARGIN_AREA));
25465 /* 'right-fringe': left edge of the right fringe. */
25466 if (EQ (prop, Qright_fringe))
25467 return OK_ALIGN_TO (WINDOW_HAS_FRINGES_OUTSIDE_MARGINS (it->w)
25468 ? window_box_right_offset (it->w, RIGHT_MARGIN_AREA)
25469 : window_box_right_offset (it->w, TEXT_AREA));
25470 /* 'left-margin': left edge of the left display margin. */
25471 if (EQ (prop, Qleft_margin))
25472 return OK_ALIGN_TO (window_box_left_offset (it->w, LEFT_MARGIN_AREA));
25473 /* 'right-margin': left edge of the right display margin. */
25474 if (EQ (prop, Qright_margin))
25475 return OK_ALIGN_TO (window_box_left_offset (it->w, RIGHT_MARGIN_AREA));
25476 /* 'scroll-bar': left edge of the vertical scroll bar. */
25477 if (EQ (prop, Qscroll_bar))
25478 return OK_ALIGN_TO (WINDOW_HAS_VERTICAL_SCROLL_BAR_ON_LEFT (it->w)
25480 : (window_box_right_offset (it->w, RIGHT_MARGIN_AREA)
25481 + (WINDOW_HAS_FRINGES_OUTSIDE_MARGINS (it->w)
25482 ? WINDOW_RIGHT_FRINGE_WIDTH (it->w)
25483 : 0)));
25485 else
25487 /* Otherwise, the elements stand for their width. */
25488 if (EQ (prop, Qleft_fringe))
25489 return OK_PIXELS (WINDOW_LEFT_FRINGE_WIDTH (it->w));
25490 if (EQ (prop, Qright_fringe))
25491 return OK_PIXELS (WINDOW_RIGHT_FRINGE_WIDTH (it->w));
25492 if (EQ (prop, Qleft_margin))
25493 return OK_PIXELS (WINDOW_LEFT_MARGIN_WIDTH (it->w));
25494 if (EQ (prop, Qright_margin))
25495 return OK_PIXELS (WINDOW_RIGHT_MARGIN_WIDTH (it->w));
25496 if (EQ (prop, Qscroll_bar))
25497 return OK_PIXELS (WINDOW_SCROLL_BAR_AREA_WIDTH (it->w));
25500 prop = buffer_local_value (prop, it->w->contents);
25501 if (EQ (prop, Qunbound))
25502 prop = Qnil;
25505 if (NUMBERP (prop))
25507 int base_unit = (width_p
25508 ? FRAME_COLUMN_WIDTH (it->f)
25509 : FRAME_LINE_HEIGHT (it->f));
25510 if (width_p && align_to && *align_to < 0)
25511 return OK_PIXELS (XFLOATINT (prop) * base_unit + it->lnum_pixel_width);
25512 return OK_PIXELS (XFLOATINT (prop) * base_unit);
25515 if (CONSP (prop))
25517 Lisp_Object car = XCAR (prop);
25518 Lisp_Object cdr = XCDR (prop);
25520 if (SYMBOLP (car))
25522 #ifdef HAVE_WINDOW_SYSTEM
25523 /* '(image PROPS...)': width or height of the specified image. */
25524 if (FRAME_WINDOW_P (it->f)
25525 && valid_image_p (prop))
25527 ptrdiff_t id = lookup_image (it->f, prop);
25528 struct image *img = IMAGE_FROM_ID (it->f, id);
25530 return OK_PIXELS (width_p ? img->width : img->height);
25532 /* '(xwidget PROPS...)': dimensions of the specified xwidget. */
25533 if (FRAME_WINDOW_P (it->f) && valid_xwidget_spec_p (prop))
25535 /* TODO: Don't return dummy size. */
25536 return OK_PIXELS (100);
25538 #endif
25539 /* '(+ EXPR...)' or '(- EXPR...)' add or subtract
25540 recursively calculated values. */
25541 if (EQ (car, Qplus) || EQ (car, Qminus))
25543 bool first = true;
25544 double px;
25546 pixels = 0;
25547 while (CONSP (cdr))
25549 if (!calc_pixel_width_or_height (&px, it, XCAR (cdr),
25550 font, width_p, align_to))
25551 return false;
25552 if (first)
25553 pixels = (EQ (car, Qplus) ? px : -px), first = false;
25554 else
25555 pixels += px;
25556 cdr = XCDR (cdr);
25558 if (EQ (car, Qminus))
25559 pixels = -pixels;
25560 return OK_PIXELS (pixels);
25563 car = buffer_local_value (car, it->w->contents);
25564 if (EQ (car, Qunbound))
25565 car = Qnil;
25568 /* '(NUM)': absolute number of pixels. */
25569 if (NUMBERP (car))
25571 double fact;
25572 int offset =
25573 width_p && align_to && *align_to < 0 ? it->lnum_pixel_width : 0;
25574 pixels = XFLOATINT (car);
25575 if (NILP (cdr))
25576 return OK_PIXELS (pixels + offset);
25577 if (calc_pixel_width_or_height (&fact, it, cdr,
25578 font, width_p, align_to))
25579 return OK_PIXELS (pixels * fact + offset);
25580 return false;
25583 return false;
25586 return false;
25589 void
25590 get_font_ascent_descent (struct font *font, int *ascent, int *descent)
25592 #ifdef HAVE_WINDOW_SYSTEM
25593 normal_char_ascent_descent (font, -1, ascent, descent);
25594 #else
25595 *ascent = 1;
25596 *descent = 0;
25597 #endif
25601 /***********************************************************************
25602 Glyph Display
25603 ***********************************************************************/
25605 #ifdef HAVE_WINDOW_SYSTEM
25607 #ifdef GLYPH_DEBUG
25609 void
25610 dump_glyph_string (struct glyph_string *s)
25612 fprintf (stderr, "glyph string\n");
25613 fprintf (stderr, " x, y, w, h = %d, %d, %d, %d\n",
25614 s->x, s->y, s->width, s->height);
25615 fprintf (stderr, " ybase = %d\n", s->ybase);
25616 fprintf (stderr, " hl = %u\n", s->hl);
25617 fprintf (stderr, " left overhang = %d, right = %d\n",
25618 s->left_overhang, s->right_overhang);
25619 fprintf (stderr, " nchars = %d\n", s->nchars);
25620 fprintf (stderr, " extends to end of line = %d\n",
25621 s->extends_to_end_of_line_p);
25622 fprintf (stderr, " font height = %d\n", FONT_HEIGHT (s->font));
25623 fprintf (stderr, " bg width = %d\n", s->background_width);
25626 #endif /* GLYPH_DEBUG */
25628 /* Initialize glyph string S. CHAR2B is a suitably allocated vector
25629 of XChar2b structures for S; it can't be allocated in
25630 init_glyph_string because it must be allocated via `alloca'. W
25631 is the window on which S is drawn. ROW and AREA are the glyph row
25632 and area within the row from which S is constructed. START is the
25633 index of the first glyph structure covered by S. HL is a
25634 face-override for drawing S. */
25636 #ifdef HAVE_NTGUI
25637 #define OPTIONAL_HDC(hdc) HDC hdc,
25638 #define DECLARE_HDC(hdc) HDC hdc;
25639 #define ALLOCATE_HDC(hdc, f) hdc = get_frame_dc ((f))
25640 #define RELEASE_HDC(hdc, f) release_frame_dc ((f), (hdc))
25641 #endif
25643 #ifndef OPTIONAL_HDC
25644 #define OPTIONAL_HDC(hdc)
25645 #define DECLARE_HDC(hdc)
25646 #define ALLOCATE_HDC(hdc, f)
25647 #define RELEASE_HDC(hdc, f)
25648 #endif
25650 static void
25651 init_glyph_string (struct glyph_string *s,
25652 OPTIONAL_HDC (hdc)
25653 XChar2b *char2b, struct window *w, struct glyph_row *row,
25654 enum glyph_row_area area, int start, enum draw_glyphs_face hl)
25656 memset (s, 0, sizeof *s);
25657 s->w = w;
25658 s->f = XFRAME (w->frame);
25659 #ifdef HAVE_NTGUI
25660 s->hdc = hdc;
25661 #endif
25662 s->display = FRAME_X_DISPLAY (s->f);
25663 s->char2b = char2b;
25664 s->hl = hl;
25665 s->row = row;
25666 s->area = area;
25667 s->first_glyph = row->glyphs[area] + start;
25668 s->height = row->height;
25669 s->y = WINDOW_TO_FRAME_PIXEL_Y (w, row->y);
25670 s->ybase = s->y + row->ascent;
25674 /* Append the list of glyph strings with head H and tail T to the list
25675 with head *HEAD and tail *TAIL. Set *HEAD and *TAIL to the result. */
25677 static void
25678 append_glyph_string_lists (struct glyph_string **head, struct glyph_string **tail,
25679 struct glyph_string *h, struct glyph_string *t)
25681 if (h)
25683 if (*head)
25684 (*tail)->next = h;
25685 else
25686 *head = h;
25687 h->prev = *tail;
25688 *tail = t;
25693 /* Prepend the list of glyph strings with head H and tail T to the
25694 list with head *HEAD and tail *TAIL. Set *HEAD and *TAIL to the
25695 result. */
25697 static void
25698 prepend_glyph_string_lists (struct glyph_string **head, struct glyph_string **tail,
25699 struct glyph_string *h, struct glyph_string *t)
25701 if (h)
25703 if (*head)
25704 (*head)->prev = t;
25705 else
25706 *tail = t;
25707 t->next = *head;
25708 *head = h;
25713 /* Append glyph string S to the list with head *HEAD and tail *TAIL.
25714 Set *HEAD and *TAIL to the resulting list. */
25716 static void
25717 append_glyph_string (struct glyph_string **head, struct glyph_string **tail,
25718 struct glyph_string *s)
25720 s->next = s->prev = NULL;
25721 append_glyph_string_lists (head, tail, s, s);
25725 /* Get face and two-byte form of character C in face FACE_ID on frame F.
25726 The encoding of C is returned in *CHAR2B. DISPLAY_P means
25727 make sure that X resources for the face returned are allocated.
25728 Value is a pointer to a realized face that is ready for display if
25729 DISPLAY_P. */
25731 static struct face *
25732 get_char_face_and_encoding (struct frame *f, int c, int face_id,
25733 XChar2b *char2b, bool display_p)
25735 struct face *face = FACE_FROM_ID (f, face_id);
25736 unsigned code = 0;
25738 if (face->font)
25740 code = face->font->driver->encode_char (face->font, c);
25742 if (code == FONT_INVALID_CODE)
25743 code = 0;
25745 STORE_XCHAR2B (char2b, (code >> 8), (code & 0xFF));
25747 /* Make sure X resources of the face are allocated. */
25748 #ifdef HAVE_X_WINDOWS
25749 if (display_p)
25750 #endif
25752 eassert (face != NULL);
25753 prepare_face_for_display (f, face);
25756 return face;
25760 /* Get face and two-byte form of character glyph GLYPH on frame F.
25761 The encoding of GLYPH->u.ch is returned in *CHAR2B. Value is
25762 a pointer to a realized face that is ready for display. */
25764 static struct face *
25765 get_glyph_face_and_encoding (struct frame *f, struct glyph *glyph,
25766 XChar2b *char2b)
25768 struct face *face;
25769 unsigned code = 0;
25771 eassert (glyph->type == CHAR_GLYPH);
25772 face = FACE_FROM_ID (f, glyph->face_id);
25774 /* Make sure X resources of the face are allocated. */
25775 prepare_face_for_display (f, face);
25777 if (face->font)
25779 if (CHAR_BYTE8_P (glyph->u.ch))
25780 code = CHAR_TO_BYTE8 (glyph->u.ch);
25781 else
25782 code = face->font->driver->encode_char (face->font, glyph->u.ch);
25784 if (code == FONT_INVALID_CODE)
25785 code = 0;
25788 STORE_XCHAR2B (char2b, (code >> 8), (code & 0xFF));
25789 return face;
25793 /* Get glyph code of character C in FONT in the two-byte form CHAR2B.
25794 Return true iff FONT has a glyph for C. */
25796 static bool
25797 get_char_glyph_code (int c, struct font *font, XChar2b *char2b)
25799 unsigned code;
25801 if (CHAR_BYTE8_P (c))
25802 code = CHAR_TO_BYTE8 (c);
25803 else
25804 code = font->driver->encode_char (font, c);
25806 if (code == FONT_INVALID_CODE)
25807 return false;
25808 STORE_XCHAR2B (char2b, (code >> 8), (code & 0xFF));
25809 return true;
25813 /* Fill glyph string S with composition components specified by S->cmp.
25815 BASE_FACE is the base face of the composition.
25816 S->cmp_from is the index of the first component for S.
25818 OVERLAPS non-zero means S should draw the foreground only, and use
25819 its physical height for clipping. See also draw_glyphs.
25821 Value is the index of a component not in S. */
25823 static int
25824 fill_composite_glyph_string (struct glyph_string *s, struct face *base_face,
25825 int overlaps)
25827 int i;
25828 /* For all glyphs of this composition, starting at the offset
25829 S->cmp_from, until we reach the end of the definition or encounter a
25830 glyph that requires the different face, add it to S. */
25831 struct face *face;
25833 eassert (s);
25835 s->for_overlaps = overlaps;
25836 s->face = NULL;
25837 s->font = NULL;
25838 for (i = s->cmp_from; i < s->cmp->glyph_len; i++)
25840 int c = COMPOSITION_GLYPH (s->cmp, i);
25842 /* TAB in a composition means display glyphs with padding space
25843 on the left or right. */
25844 if (c != '\t')
25846 int face_id = FACE_FOR_CHAR (s->f, base_face->ascii_face, c,
25847 -1, Qnil);
25849 face = get_char_face_and_encoding (s->f, c, face_id,
25850 s->char2b + i, true);
25851 if (face)
25853 if (! s->face)
25855 s->face = face;
25856 s->font = s->face->font;
25858 else if (s->face != face)
25859 break;
25862 ++s->nchars;
25864 s->cmp_to = i;
25866 if (s->face == NULL)
25868 s->face = base_face->ascii_face;
25869 s->font = s->face->font;
25872 /* All glyph strings for the same composition has the same width,
25873 i.e. the width set for the first component of the composition. */
25874 s->width = s->first_glyph->pixel_width;
25876 /* If the specified font could not be loaded, use the frame's
25877 default font, but record the fact that we couldn't load it in
25878 the glyph string so that we can draw rectangles for the
25879 characters of the glyph string. */
25880 if (s->font == NULL)
25882 s->font_not_found_p = true;
25883 s->font = FRAME_FONT (s->f);
25886 /* Adjust base line for subscript/superscript text. */
25887 s->ybase += s->first_glyph->voffset;
25889 return s->cmp_to;
25892 static int
25893 fill_gstring_glyph_string (struct glyph_string *s, int face_id,
25894 int start, int end, int overlaps)
25896 struct glyph *glyph, *last;
25897 Lisp_Object lgstring;
25898 int i;
25900 s->for_overlaps = overlaps;
25901 glyph = s->row->glyphs[s->area] + start;
25902 last = s->row->glyphs[s->area] + end;
25903 s->cmp_id = glyph->u.cmp.id;
25904 s->cmp_from = glyph->slice.cmp.from;
25905 s->cmp_to = glyph->slice.cmp.to + 1;
25906 s->face = FACE_FROM_ID (s->f, face_id);
25907 lgstring = composition_gstring_from_id (s->cmp_id);
25908 s->font = XFONT_OBJECT (LGSTRING_FONT (lgstring));
25909 glyph++;
25910 while (glyph < last
25911 && glyph->u.cmp.automatic
25912 && glyph->u.cmp.id == s->cmp_id
25913 && s->cmp_to == glyph->slice.cmp.from)
25914 s->cmp_to = (glyph++)->slice.cmp.to + 1;
25916 for (i = s->cmp_from; i < s->cmp_to; i++)
25918 Lisp_Object lglyph = LGSTRING_GLYPH (lgstring, i);
25919 unsigned code = LGLYPH_CODE (lglyph);
25921 STORE_XCHAR2B ((s->char2b + i), code >> 8, code & 0xFF);
25923 s->width = composition_gstring_width (lgstring, s->cmp_from, s->cmp_to, NULL);
25924 return glyph - s->row->glyphs[s->area];
25928 /* Fill glyph string S from a sequence glyphs for glyphless characters.
25929 See the comment of fill_glyph_string for arguments.
25930 Value is the index of the first glyph not in S. */
25933 static int
25934 fill_glyphless_glyph_string (struct glyph_string *s, int face_id,
25935 int start, int end, int overlaps)
25937 struct glyph *glyph, *last;
25938 int voffset;
25940 eassert (s->first_glyph->type == GLYPHLESS_GLYPH);
25941 s->for_overlaps = overlaps;
25942 glyph = s->row->glyphs[s->area] + start;
25943 last = s->row->glyphs[s->area] + end;
25944 voffset = glyph->voffset;
25945 s->face = FACE_FROM_ID (s->f, face_id);
25946 s->font = s->face->font ? s->face->font : FRAME_FONT (s->f);
25947 s->nchars = 1;
25948 s->width = glyph->pixel_width;
25949 glyph++;
25950 while (glyph < last
25951 && glyph->type == GLYPHLESS_GLYPH
25952 && glyph->voffset == voffset
25953 && glyph->face_id == face_id)
25955 s->nchars++;
25956 s->width += glyph->pixel_width;
25957 glyph++;
25959 s->ybase += voffset;
25960 return glyph - s->row->glyphs[s->area];
25964 /* Fill glyph string S from a sequence of character glyphs.
25966 FACE_ID is the face id of the string. START is the index of the
25967 first glyph to consider, END is the index of the last + 1.
25968 OVERLAPS non-zero means S should draw the foreground only, and use
25969 its physical height for clipping. See also draw_glyphs.
25971 Value is the index of the first glyph not in S. */
25973 static int
25974 fill_glyph_string (struct glyph_string *s, int face_id,
25975 int start, int end, int overlaps)
25977 struct glyph *glyph, *last;
25978 int voffset;
25979 bool glyph_not_available_p;
25981 eassert (s->f == XFRAME (s->w->frame));
25982 eassert (s->nchars == 0);
25983 eassert (start >= 0 && end > start);
25985 s->for_overlaps = overlaps;
25986 glyph = s->row->glyphs[s->area] + start;
25987 last = s->row->glyphs[s->area] + end;
25988 voffset = glyph->voffset;
25989 s->padding_p = glyph->padding_p;
25990 glyph_not_available_p = glyph->glyph_not_available_p;
25992 while (glyph < last
25993 && glyph->type == CHAR_GLYPH
25994 && glyph->voffset == voffset
25995 /* Same face id implies same font, nowadays. */
25996 && glyph->face_id == face_id
25997 && glyph->glyph_not_available_p == glyph_not_available_p)
25999 s->face = get_glyph_face_and_encoding (s->f, glyph,
26000 s->char2b + s->nchars);
26001 ++s->nchars;
26002 eassert (s->nchars <= end - start);
26003 s->width += glyph->pixel_width;
26004 if (glyph++->padding_p != s->padding_p)
26005 break;
26008 s->font = s->face->font;
26010 /* If the specified font could not be loaded, use the frame's font,
26011 but record the fact that we couldn't load it in
26012 S->font_not_found_p so that we can draw rectangles for the
26013 characters of the glyph string. */
26014 if (s->font == NULL || glyph_not_available_p)
26016 s->font_not_found_p = true;
26017 s->font = FRAME_FONT (s->f);
26020 /* Adjust base line for subscript/superscript text. */
26021 s->ybase += voffset;
26023 eassert (s->face && s->face->gc);
26024 return glyph - s->row->glyphs[s->area];
26028 /* Fill glyph string S from image glyph S->first_glyph. */
26030 static void
26031 fill_image_glyph_string (struct glyph_string *s)
26033 eassert (s->first_glyph->type == IMAGE_GLYPH);
26034 s->img = IMAGE_FROM_ID (s->f, s->first_glyph->u.img_id);
26035 eassert (s->img);
26036 s->slice = s->first_glyph->slice.img;
26037 s->face = FACE_FROM_ID (s->f, s->first_glyph->face_id);
26038 s->font = s->face->font;
26039 s->width = s->first_glyph->pixel_width;
26041 /* Adjust base line for subscript/superscript text. */
26042 s->ybase += s->first_glyph->voffset;
26046 #ifdef HAVE_XWIDGETS
26047 static void
26048 fill_xwidget_glyph_string (struct glyph_string *s)
26050 eassert (s->first_glyph->type == XWIDGET_GLYPH);
26051 s->face = FACE_FROM_ID (s->f, s->first_glyph->face_id);
26052 s->font = s->face->font;
26053 s->width = s->first_glyph->pixel_width;
26054 s->ybase += s->first_glyph->voffset;
26055 s->xwidget = s->first_glyph->u.xwidget;
26057 #endif
26058 /* Fill glyph string S from a sequence of stretch glyphs.
26060 START is the index of the first glyph to consider,
26061 END is the index of the last + 1.
26063 Value is the index of the first glyph not in S. */
26065 static int
26066 fill_stretch_glyph_string (struct glyph_string *s, int start, int end)
26068 struct glyph *glyph, *last;
26069 int voffset, face_id;
26071 eassert (s->first_glyph->type == STRETCH_GLYPH);
26073 glyph = s->row->glyphs[s->area] + start;
26074 last = s->row->glyphs[s->area] + end;
26075 face_id = glyph->face_id;
26076 s->face = FACE_FROM_ID (s->f, face_id);
26077 s->font = s->face->font;
26078 s->width = glyph->pixel_width;
26079 s->nchars = 1;
26080 voffset = glyph->voffset;
26082 for (++glyph;
26083 (glyph < last
26084 && glyph->type == STRETCH_GLYPH
26085 && glyph->voffset == voffset
26086 && glyph->face_id == face_id);
26087 ++glyph)
26088 s->width += glyph->pixel_width;
26090 /* Adjust base line for subscript/superscript text. */
26091 s->ybase += voffset;
26093 /* The case that face->gc == 0 is handled when drawing the glyph
26094 string by calling prepare_face_for_display. */
26095 eassert (s->face);
26096 return glyph - s->row->glyphs[s->area];
26099 static struct font_metrics *
26100 get_per_char_metric (struct font *font, XChar2b *char2b)
26102 static struct font_metrics metrics;
26103 unsigned code;
26105 if (! font)
26106 return NULL;
26107 code = (XCHAR2B_BYTE1 (char2b) << 8) | XCHAR2B_BYTE2 (char2b);
26108 if (code == FONT_INVALID_CODE)
26109 return NULL;
26110 font->driver->text_extents (font, &code, 1, &metrics);
26111 return &metrics;
26114 /* A subroutine that computes "normal" values of ASCENT and DESCENT
26115 for FONT. Values are taken from font-global ones, except for fonts
26116 that claim preposterously large values, but whose glyphs actually
26117 have reasonable dimensions. C is the character to use for metrics
26118 if the font-global values are too large; if C is negative, the
26119 function selects a default character. */
26120 static void
26121 normal_char_ascent_descent (struct font *font, int c, int *ascent, int *descent)
26123 *ascent = FONT_BASE (font);
26124 *descent = FONT_DESCENT (font);
26126 if (FONT_TOO_HIGH (font))
26128 XChar2b char2b;
26130 /* Get metrics of C, defaulting to a reasonably sized ASCII
26131 character. */
26132 if (get_char_glyph_code (c >= 0 ? c : '{', font, &char2b))
26134 struct font_metrics *pcm = get_per_char_metric (font, &char2b);
26136 if (!(pcm->width == 0 && pcm->rbearing == 0 && pcm->lbearing == 0))
26138 /* We add 1 pixel to character dimensions as heuristics
26139 that produces nicer display, e.g. when the face has
26140 the box attribute. */
26141 *ascent = pcm->ascent + 1;
26142 *descent = pcm->descent + 1;
26148 /* A subroutine that computes a reasonable "normal character height"
26149 for fonts that claim preposterously large vertical dimensions, but
26150 whose glyphs are actually reasonably sized. C is the character
26151 whose metrics to use for those fonts, or -1 for default
26152 character. */
26153 static int
26154 normal_char_height (struct font *font, int c)
26156 int ascent, descent;
26158 normal_char_ascent_descent (font, c, &ascent, &descent);
26160 return ascent + descent;
26163 /* EXPORT for RIF:
26164 Set *LEFT and *RIGHT to the left and right overhang of GLYPH on
26165 frame F. Overhangs of glyphs other than type CHAR_GLYPH are
26166 assumed to be zero. */
26168 void
26169 x_get_glyph_overhangs (struct glyph *glyph, struct frame *f, int *left, int *right)
26171 *left = *right = 0;
26173 if (glyph->type == CHAR_GLYPH)
26175 XChar2b char2b;
26176 struct face *face = get_glyph_face_and_encoding (f, glyph, &char2b);
26177 if (face->font)
26179 struct font_metrics *pcm = get_per_char_metric (face->font, &char2b);
26180 if (pcm)
26182 if (pcm->rbearing > pcm->width)
26183 *right = pcm->rbearing - pcm->width;
26184 if (pcm->lbearing < 0)
26185 *left = -pcm->lbearing;
26189 else if (glyph->type == COMPOSITE_GLYPH)
26191 if (! glyph->u.cmp.automatic)
26193 struct composition *cmp = composition_table[glyph->u.cmp.id];
26195 if (cmp->rbearing > cmp->pixel_width)
26196 *right = cmp->rbearing - cmp->pixel_width;
26197 if (cmp->lbearing < 0)
26198 *left = - cmp->lbearing;
26200 else
26202 Lisp_Object gstring = composition_gstring_from_id (glyph->u.cmp.id);
26203 struct font_metrics metrics;
26205 composition_gstring_width (gstring, glyph->slice.cmp.from,
26206 glyph->slice.cmp.to + 1, &metrics);
26207 if (metrics.rbearing > metrics.width)
26208 *right = metrics.rbearing - metrics.width;
26209 if (metrics.lbearing < 0)
26210 *left = - metrics.lbearing;
26216 /* Return the index of the first glyph preceding glyph string S that
26217 is overwritten by S because of S's left overhang. Value is -1
26218 if no glyphs are overwritten. */
26220 static int
26221 left_overwritten (struct glyph_string *s)
26223 int k;
26225 if (s->left_overhang)
26227 int x = 0, i;
26228 struct glyph *glyphs = s->row->glyphs[s->area];
26229 int first = s->first_glyph - glyphs;
26231 for (i = first - 1; i >= 0 && x > -s->left_overhang; --i)
26232 x -= glyphs[i].pixel_width;
26234 k = i + 1;
26236 else
26237 k = -1;
26239 return k;
26243 /* Return the index of the first glyph preceding glyph string S that
26244 is overwriting S because of its right overhang. Value is -1 if no
26245 glyph in front of S overwrites S. */
26247 static int
26248 left_overwriting (struct glyph_string *s)
26250 int i, k, x;
26251 struct glyph *glyphs = s->row->glyphs[s->area];
26252 int first = s->first_glyph - glyphs;
26254 k = -1;
26255 x = 0;
26256 for (i = first - 1; i >= 0; --i)
26258 int left, right;
26259 x_get_glyph_overhangs (glyphs + i, s->f, &left, &right);
26260 if (x + right > 0)
26261 k = i;
26262 x -= glyphs[i].pixel_width;
26265 return k;
26269 /* Return the index of the last glyph following glyph string S that is
26270 overwritten by S because of S's right overhang. Value is -1 if
26271 no such glyph is found. */
26273 static int
26274 right_overwritten (struct glyph_string *s)
26276 int k = -1;
26278 if (s->right_overhang)
26280 int x = 0, i;
26281 struct glyph *glyphs = s->row->glyphs[s->area];
26282 int first = (s->first_glyph - glyphs
26283 + (s->first_glyph->type == COMPOSITE_GLYPH ? 1 : s->nchars));
26284 int end = s->row->used[s->area];
26286 for (i = first; i < end && s->right_overhang > x; ++i)
26287 x += glyphs[i].pixel_width;
26289 k = i;
26292 return k;
26296 /* Return the index of the last glyph following glyph string S that
26297 overwrites S because of its left overhang. Value is negative
26298 if no such glyph is found. */
26300 static int
26301 right_overwriting (struct glyph_string *s)
26303 int i, k, x;
26304 int end = s->row->used[s->area];
26305 struct glyph *glyphs = s->row->glyphs[s->area];
26306 int first = (s->first_glyph - glyphs
26307 + (s->first_glyph->type == COMPOSITE_GLYPH ? 1 : s->nchars));
26309 k = -1;
26310 x = 0;
26311 for (i = first; i < end; ++i)
26313 int left, right;
26314 x_get_glyph_overhangs (glyphs + i, s->f, &left, &right);
26315 if (x - left < 0)
26316 k = i;
26317 x += glyphs[i].pixel_width;
26320 return k;
26324 /* Set background width of glyph string S. START is the index of the
26325 first glyph following S. LAST_X is the right-most x-position + 1
26326 in the drawing area. */
26328 static void
26329 set_glyph_string_background_width (struct glyph_string *s, int start, int last_x)
26331 /* If the face of this glyph string has to be drawn to the end of
26332 the drawing area, set S->extends_to_end_of_line_p. */
26334 if (start == s->row->used[s->area]
26335 && ((s->row->fill_line_p
26336 && (s->hl == DRAW_NORMAL_TEXT
26337 || s->hl == DRAW_IMAGE_RAISED
26338 || s->hl == DRAW_IMAGE_SUNKEN))
26339 || s->hl == DRAW_MOUSE_FACE))
26340 s->extends_to_end_of_line_p = true;
26342 /* If S extends its face to the end of the line, set its
26343 background_width to the distance to the right edge of the drawing
26344 area. */
26345 if (s->extends_to_end_of_line_p)
26346 s->background_width = last_x - s->x + 1;
26347 else
26348 s->background_width = s->width;
26352 /* Return glyph string that shares background with glyph string S and
26353 whose `background_width' member has been set. */
26355 static struct glyph_string *
26356 glyph_string_containing_background_width (struct glyph_string *s)
26358 if (s->cmp)
26359 while (s->cmp_from)
26360 s = s->prev;
26362 return s;
26366 /* Compute overhangs and x-positions for glyph string S and its
26367 predecessors, or successors. X is the starting x-position for S.
26368 BACKWARD_P means process predecessors. */
26370 static void
26371 compute_overhangs_and_x (struct glyph_string *s, int x, bool backward_p)
26373 if (backward_p)
26375 while (s)
26377 if (FRAME_RIF (s->f)->compute_glyph_string_overhangs)
26378 FRAME_RIF (s->f)->compute_glyph_string_overhangs (s);
26379 if (!s->cmp || s->cmp_to == s->cmp->glyph_len)
26380 x -= s->width;
26381 s->x = x;
26382 s = s->prev;
26385 else
26387 while (s)
26389 if (FRAME_RIF (s->f)->compute_glyph_string_overhangs)
26390 FRAME_RIF (s->f)->compute_glyph_string_overhangs (s);
26391 s->x = x;
26392 if (!s->cmp || s->cmp_to == s->cmp->glyph_len)
26393 x += s->width;
26394 s = s->next;
26401 /* The following macros are only called from draw_glyphs below.
26402 They reference the following parameters of that function directly:
26403 `w', `row', `area', and `overlap_p'
26404 as well as the following local variables:
26405 `s', `f', and `hdc' (in W32) */
26407 #ifdef HAVE_NTGUI
26408 /* On W32, silently add local `hdc' variable to argument list of
26409 init_glyph_string. */
26410 #define INIT_GLYPH_STRING(s, char2b, w, row, area, start, hl) \
26411 init_glyph_string (s, hdc, char2b, w, row, area, start, hl)
26412 #else
26413 #define INIT_GLYPH_STRING(s, char2b, w, row, area, start, hl) \
26414 init_glyph_string (s, char2b, w, row, area, start, hl)
26415 #endif
26417 /* Add a glyph string for a stretch glyph to the list of strings
26418 between HEAD and TAIL. START is the index of the stretch glyph in
26419 row area AREA of glyph row ROW. END is the index of the last glyph
26420 in that glyph row area. X is the current output position assigned
26421 to the new glyph string constructed. HL overrides that face of the
26422 glyph; e.g. it is DRAW_CURSOR if a cursor has to be drawn. LAST_X
26423 is the right-most x-position of the drawing area. */
26425 /* SunOS 4 bundled cc, barfed on continuations in the arg lists here
26426 and below -- keep them on one line. */
26427 #define BUILD_STRETCH_GLYPH_STRING(START, END, HEAD, TAIL, HL, X, LAST_X) \
26428 do \
26430 s = alloca (sizeof *s); \
26431 INIT_GLYPH_STRING (s, NULL, w, row, area, START, HL); \
26432 START = fill_stretch_glyph_string (s, START, END); \
26433 append_glyph_string (&HEAD, &TAIL, s); \
26434 s->x = (X); \
26436 while (false)
26439 /* Add a glyph string for an image glyph to the list of strings
26440 between HEAD and TAIL. START is the index of the image glyph in
26441 row area AREA of glyph row ROW. END is the index of the last glyph
26442 in that glyph row area. X is the current output position assigned
26443 to the new glyph string constructed. HL overrides that face of the
26444 glyph; e.g. it is DRAW_CURSOR if a cursor has to be drawn. LAST_X
26445 is the right-most x-position of the drawing area. */
26447 #define BUILD_IMAGE_GLYPH_STRING(START, END, HEAD, TAIL, HL, X, LAST_X) \
26448 do \
26450 s = alloca (sizeof *s); \
26451 INIT_GLYPH_STRING (s, NULL, w, row, area, START, HL); \
26452 fill_image_glyph_string (s); \
26453 append_glyph_string (&HEAD, &TAIL, s); \
26454 ++START; \
26455 s->x = (X); \
26457 while (false)
26459 #ifndef HAVE_XWIDGETS
26460 # define BUILD_XWIDGET_GLYPH_STRING(START, END, HEAD, TAIL, HL, X, LAST_X) \
26461 eassume (false)
26462 #else
26463 # define BUILD_XWIDGET_GLYPH_STRING(START, END, HEAD, TAIL, HL, X, LAST_X) \
26464 do \
26466 s = alloca (sizeof *s); \
26467 INIT_GLYPH_STRING (s, NULL, w, row, area, START, HL); \
26468 fill_xwidget_glyph_string (s); \
26469 append_glyph_string (&(HEAD), &(TAIL), s); \
26470 ++(START); \
26471 s->x = (X); \
26473 while (false)
26474 #endif
26476 /* Add a glyph string for a sequence of character glyphs to the list
26477 of strings between HEAD and TAIL. START is the index of the first
26478 glyph in row area AREA of glyph row ROW that is part of the new
26479 glyph string. END is the index of the last glyph in that glyph row
26480 area. X is the current output position assigned to the new glyph
26481 string constructed. HL overrides that face of the glyph; e.g. it
26482 is DRAW_CURSOR if a cursor has to be drawn. LAST_X is the
26483 right-most x-position of the drawing area. */
26485 #define BUILD_CHAR_GLYPH_STRINGS(START, END, HEAD, TAIL, HL, X, LAST_X) \
26486 do \
26488 int face_id; \
26489 XChar2b *char2b; \
26491 face_id = (row)->glyphs[area][START].face_id; \
26493 s = alloca (sizeof *s); \
26494 SAFE_NALLOCA (char2b, 1, (END) - (START)); \
26495 INIT_GLYPH_STRING (s, char2b, w, row, area, START, HL); \
26496 append_glyph_string (&HEAD, &TAIL, s); \
26497 s->x = (X); \
26498 START = fill_glyph_string (s, face_id, START, END, overlaps); \
26500 while (false)
26503 /* Add a glyph string for a composite sequence to the list of strings
26504 between HEAD and TAIL. START is the index of the first glyph in
26505 row area AREA of glyph row ROW that is part of the new glyph
26506 string. END is the index of the last glyph in that glyph row area.
26507 X is the current output position assigned to the new glyph string
26508 constructed. HL overrides that face of the glyph; e.g. it is
26509 DRAW_CURSOR if a cursor has to be drawn. LAST_X is the right-most
26510 x-position of the drawing area. */
26512 #define BUILD_COMPOSITE_GLYPH_STRING(START, END, HEAD, TAIL, HL, X, LAST_X) \
26513 do { \
26514 int face_id = (row)->glyphs[area][START].face_id; \
26515 struct face *base_face = FACE_FROM_ID (f, face_id); \
26516 ptrdiff_t cmp_id = (row)->glyphs[area][START].u.cmp.id; \
26517 struct composition *cmp = composition_table[cmp_id]; \
26518 XChar2b *char2b; \
26519 struct glyph_string *first_s = NULL; \
26520 int n; \
26522 SAFE_NALLOCA (char2b, 1, cmp->glyph_len); \
26524 /* Make glyph_strings for each glyph sequence that is drawable by \
26525 the same face, and append them to HEAD/TAIL. */ \
26526 for (n = 0; n < cmp->glyph_len;) \
26528 s = alloca (sizeof *s); \
26529 INIT_GLYPH_STRING (s, char2b, w, row, area, START, HL); \
26530 append_glyph_string (&(HEAD), &(TAIL), s); \
26531 s->cmp = cmp; \
26532 s->cmp_from = n; \
26533 s->x = (X); \
26534 if (n == 0) \
26535 first_s = s; \
26536 n = fill_composite_glyph_string (s, base_face, overlaps); \
26539 ++START; \
26540 s = first_s; \
26541 } while (false)
26544 /* Add a glyph string for a glyph-string sequence to the list of strings
26545 between HEAD and TAIL. */
26547 #define BUILD_GSTRING_GLYPH_STRING(START, END, HEAD, TAIL, HL, X, LAST_X) \
26548 do { \
26549 int face_id; \
26550 XChar2b *char2b; \
26551 Lisp_Object gstring; \
26553 face_id = (row)->glyphs[area][START].face_id; \
26554 gstring = (composition_gstring_from_id \
26555 ((row)->glyphs[area][START].u.cmp.id)); \
26556 s = alloca (sizeof *s); \
26557 SAFE_NALLOCA (char2b, 1, LGSTRING_GLYPH_LEN (gstring)); \
26558 INIT_GLYPH_STRING (s, char2b, w, row, area, START, HL); \
26559 append_glyph_string (&(HEAD), &(TAIL), s); \
26560 s->x = (X); \
26561 START = fill_gstring_glyph_string (s, face_id, START, END, overlaps); \
26562 } while (false)
26565 /* Add a glyph string for a sequence of glyphless character's glyphs
26566 to the list of strings between HEAD and TAIL. The meanings of
26567 arguments are the same as those of BUILD_CHAR_GLYPH_STRINGS. */
26569 #define BUILD_GLYPHLESS_GLYPH_STRING(START, END, HEAD, TAIL, HL, X, LAST_X) \
26570 do \
26572 int face_id; \
26574 face_id = (row)->glyphs[area][START].face_id; \
26576 s = alloca (sizeof *s); \
26577 INIT_GLYPH_STRING (s, NULL, w, row, area, START, HL); \
26578 append_glyph_string (&HEAD, &TAIL, s); \
26579 s->x = (X); \
26580 START = fill_glyphless_glyph_string (s, face_id, START, END, \
26581 overlaps); \
26583 while (false)
26586 /* Build a list of glyph strings between HEAD and TAIL for the glyphs
26587 of AREA of glyph row ROW on window W between indices START and END.
26588 HL overrides the face for drawing glyph strings, e.g. it is
26589 DRAW_CURSOR to draw a cursor. X and LAST_X are start and end
26590 x-positions of the drawing area.
26592 This is an ugly monster macro construct because we must use alloca
26593 to allocate glyph strings (because draw_glyphs can be called
26594 asynchronously). */
26596 #define BUILD_GLYPH_STRINGS_1(START, END, HEAD, TAIL, HL, X, LAST_X) \
26597 do \
26599 HEAD = TAIL = NULL; \
26600 while (START < END) \
26602 struct glyph *first_glyph = (row)->glyphs[area] + START; \
26603 switch (first_glyph->type) \
26605 case CHAR_GLYPH: \
26606 BUILD_CHAR_GLYPH_STRINGS (START, END, HEAD, TAIL, \
26607 HL, X, LAST_X); \
26608 break; \
26610 case COMPOSITE_GLYPH: \
26611 if (first_glyph->u.cmp.automatic) \
26612 BUILD_GSTRING_GLYPH_STRING (START, END, HEAD, TAIL, \
26613 HL, X, LAST_X); \
26614 else \
26615 BUILD_COMPOSITE_GLYPH_STRING (START, END, HEAD, TAIL, \
26616 HL, X, LAST_X); \
26617 break; \
26619 case STRETCH_GLYPH: \
26620 BUILD_STRETCH_GLYPH_STRING (START, END, HEAD, TAIL, \
26621 HL, X, LAST_X); \
26622 break; \
26624 case IMAGE_GLYPH: \
26625 BUILD_IMAGE_GLYPH_STRING (START, END, HEAD, TAIL, \
26626 HL, X, LAST_X); \
26627 break;
26629 #define BUILD_GLYPH_STRINGS_XW(START, END, HEAD, TAIL, HL, X, LAST_X) \
26630 case XWIDGET_GLYPH: \
26631 BUILD_XWIDGET_GLYPH_STRING (START, END, HEAD, TAIL, \
26632 HL, X, LAST_X); \
26633 break;
26635 #define BUILD_GLYPH_STRINGS_2(START, END, HEAD, TAIL, HL, X, LAST_X) \
26636 case GLYPHLESS_GLYPH: \
26637 BUILD_GLYPHLESS_GLYPH_STRING (START, END, HEAD, TAIL, \
26638 HL, X, LAST_X); \
26639 break; \
26641 default: \
26642 emacs_abort (); \
26645 if (s) \
26647 set_glyph_string_background_width (s, START, LAST_X); \
26648 (X) += s->width; \
26651 } while (false)
26654 #define BUILD_GLYPH_STRINGS(START, END, HEAD, TAIL, HL, X, LAST_X) \
26655 BUILD_GLYPH_STRINGS_1(START, END, HEAD, TAIL, HL, X, LAST_X) \
26656 BUILD_GLYPH_STRINGS_XW(START, END, HEAD, TAIL, HL, X, LAST_X) \
26657 BUILD_GLYPH_STRINGS_2(START, END, HEAD, TAIL, HL, X, LAST_X)
26660 /* Draw glyphs between START and END in AREA of ROW on window W,
26661 starting at x-position X. X is relative to AREA in W. HL is a
26662 face-override with the following meaning:
26664 DRAW_NORMAL_TEXT draw normally
26665 DRAW_CURSOR draw in cursor face
26666 DRAW_MOUSE_FACE draw in mouse face.
26667 DRAW_INVERSE_VIDEO draw in mode line face
26668 DRAW_IMAGE_SUNKEN draw an image with a sunken relief around it
26669 DRAW_IMAGE_RAISED draw an image with a raised relief around it
26671 If OVERLAPS is non-zero, draw only the foreground of characters and
26672 clip to the physical height of ROW. Non-zero value also defines
26673 the overlapping part to be drawn:
26675 OVERLAPS_PRED overlap with preceding rows
26676 OVERLAPS_SUCC overlap with succeeding rows
26677 OVERLAPS_BOTH overlap with both preceding/succeeding rows
26678 OVERLAPS_ERASED_CURSOR overlap with erased cursor area
26680 Value is the x-position reached, relative to AREA of W. */
26682 static int
26683 draw_glyphs (struct window *w, int x, struct glyph_row *row,
26684 enum glyph_row_area area, ptrdiff_t start, ptrdiff_t end,
26685 enum draw_glyphs_face hl, int overlaps)
26687 struct glyph_string *head, *tail;
26688 struct glyph_string *s;
26689 struct glyph_string *clip_head = NULL, *clip_tail = NULL;
26690 int i, j, x_reached, last_x, area_left = 0;
26691 struct frame *f = XFRAME (WINDOW_FRAME (w));
26692 DECLARE_HDC (hdc);
26694 ALLOCATE_HDC (hdc, f);
26696 /* Let's rather be paranoid than getting a SEGV. */
26697 end = min (end, row->used[area]);
26698 start = clip_to_bounds (0, start, end);
26700 /* Translate X to frame coordinates. Set last_x to the right
26701 end of the drawing area. */
26702 if (row->full_width_p)
26704 /* X is relative to the left edge of W, without scroll bars
26705 or fringes. */
26706 area_left = WINDOW_LEFT_EDGE_X (w);
26707 last_x = (WINDOW_LEFT_EDGE_X (w) + WINDOW_PIXEL_WIDTH (w)
26708 - (row->mode_line_p ? WINDOW_RIGHT_DIVIDER_WIDTH (w) : 0));
26710 else
26712 area_left = window_box_left (w, area);
26713 last_x = area_left + window_box_width (w, area);
26715 x += area_left;
26717 /* Build a doubly-linked list of glyph_string structures between
26718 head and tail from what we have to draw. Note that the macro
26719 BUILD_GLYPH_STRINGS will modify its start parameter. That's
26720 the reason we use a separate variable `i'. */
26721 i = start;
26722 USE_SAFE_ALLOCA;
26723 BUILD_GLYPH_STRINGS (i, end, head, tail, hl, x, last_x);
26724 if (tail)
26726 s = glyph_string_containing_background_width (tail);
26727 x_reached = s->x + s->background_width;
26729 else
26730 x_reached = x;
26732 /* If there are any glyphs with lbearing < 0 or rbearing > width in
26733 the row, redraw some glyphs in front or following the glyph
26734 strings built above. */
26735 if (head && !overlaps && row->contains_overlapping_glyphs_p)
26737 struct glyph_string *h, *t;
26738 Mouse_HLInfo *hlinfo = MOUSE_HL_INFO (f);
26739 int mouse_beg_col UNINIT, mouse_end_col UNINIT;
26740 bool check_mouse_face = false;
26741 int dummy_x = 0;
26743 /* If mouse highlighting is on, we may need to draw adjacent
26744 glyphs using mouse-face highlighting. */
26745 if (area == TEXT_AREA && row->mouse_face_p
26746 && hlinfo->mouse_face_beg_row >= 0
26747 && hlinfo->mouse_face_end_row >= 0)
26749 ptrdiff_t row_vpos = MATRIX_ROW_VPOS (row, w->current_matrix);
26751 if (row_vpos >= hlinfo->mouse_face_beg_row
26752 && row_vpos <= hlinfo->mouse_face_end_row)
26754 check_mouse_face = true;
26755 mouse_beg_col = (row_vpos == hlinfo->mouse_face_beg_row)
26756 ? hlinfo->mouse_face_beg_col : 0;
26757 mouse_end_col = (row_vpos == hlinfo->mouse_face_end_row)
26758 ? hlinfo->mouse_face_end_col
26759 : row->used[TEXT_AREA];
26763 /* Compute overhangs for all glyph strings. */
26764 if (FRAME_RIF (f)->compute_glyph_string_overhangs)
26765 for (s = head; s; s = s->next)
26766 FRAME_RIF (f)->compute_glyph_string_overhangs (s);
26768 /* Prepend glyph strings for glyphs in front of the first glyph
26769 string that are overwritten because of the first glyph
26770 string's left overhang. The background of all strings
26771 prepended must be drawn because the first glyph string
26772 draws over it. */
26773 i = left_overwritten (head);
26774 if (i >= 0)
26776 enum draw_glyphs_face overlap_hl;
26778 /* If this row contains mouse highlighting, attempt to draw
26779 the overlapped glyphs with the correct highlight. This
26780 code fails if the overlap encompasses more than one glyph
26781 and mouse-highlight spans only some of these glyphs.
26782 However, making it work perfectly involves a lot more
26783 code, and I don't know if the pathological case occurs in
26784 practice, so we'll stick to this for now. --- cyd */
26785 if (check_mouse_face
26786 && mouse_beg_col < start && mouse_end_col > i)
26787 overlap_hl = DRAW_MOUSE_FACE;
26788 else
26789 overlap_hl = DRAW_NORMAL_TEXT;
26791 if (hl != overlap_hl)
26792 clip_head = head;
26793 j = i;
26794 BUILD_GLYPH_STRINGS (j, start, h, t,
26795 overlap_hl, dummy_x, last_x);
26796 start = i;
26797 compute_overhangs_and_x (t, head->x, true);
26798 prepend_glyph_string_lists (&head, &tail, h, t);
26799 if (clip_head == NULL)
26800 clip_head = head;
26803 /* Prepend glyph strings for glyphs in front of the first glyph
26804 string that overwrite that glyph string because of their
26805 right overhang. For these strings, only the foreground must
26806 be drawn, because it draws over the glyph string at `head'.
26807 The background must not be drawn because this would overwrite
26808 right overhangs of preceding glyphs for which no glyph
26809 strings exist. */
26810 i = left_overwriting (head);
26811 if (i >= 0)
26813 enum draw_glyphs_face overlap_hl;
26815 if (check_mouse_face
26816 && mouse_beg_col < start && mouse_end_col > i)
26817 overlap_hl = DRAW_MOUSE_FACE;
26818 else
26819 overlap_hl = DRAW_NORMAL_TEXT;
26821 if (hl == overlap_hl || clip_head == NULL)
26822 clip_head = head;
26823 BUILD_GLYPH_STRINGS (i, start, h, t,
26824 overlap_hl, dummy_x, last_x);
26825 for (s = h; s; s = s->next)
26826 s->background_filled_p = true;
26827 compute_overhangs_and_x (t, head->x, true);
26828 prepend_glyph_string_lists (&head, &tail, h, t);
26831 /* Append glyphs strings for glyphs following the last glyph
26832 string tail that are overwritten by tail. The background of
26833 these strings has to be drawn because tail's foreground draws
26834 over it. */
26835 i = right_overwritten (tail);
26836 if (i >= 0)
26838 enum draw_glyphs_face overlap_hl;
26840 if (check_mouse_face
26841 && mouse_beg_col < i && mouse_end_col > end)
26842 overlap_hl = DRAW_MOUSE_FACE;
26843 else
26844 overlap_hl = DRAW_NORMAL_TEXT;
26846 if (hl != overlap_hl)
26847 clip_tail = tail;
26848 BUILD_GLYPH_STRINGS (end, i, h, t,
26849 overlap_hl, x, last_x);
26850 /* Because BUILD_GLYPH_STRINGS updates the first argument,
26851 we don't have `end = i;' here. */
26852 compute_overhangs_and_x (h, tail->x + tail->width, false);
26853 append_glyph_string_lists (&head, &tail, h, t);
26854 if (clip_tail == NULL)
26855 clip_tail = tail;
26858 /* Append glyph strings for glyphs following the last glyph
26859 string tail that overwrite tail. The foreground of such
26860 glyphs has to be drawn because it writes into the background
26861 of tail. The background must not be drawn because it could
26862 paint over the foreground of following glyphs. */
26863 i = right_overwriting (tail);
26864 if (i >= 0)
26866 enum draw_glyphs_face overlap_hl;
26867 if (check_mouse_face
26868 && mouse_beg_col < i && mouse_end_col > end)
26869 overlap_hl = DRAW_MOUSE_FACE;
26870 else
26871 overlap_hl = DRAW_NORMAL_TEXT;
26873 if (hl == overlap_hl || clip_tail == NULL)
26874 clip_tail = tail;
26875 i++; /* We must include the Ith glyph. */
26876 BUILD_GLYPH_STRINGS (end, i, h, t,
26877 overlap_hl, x, last_x);
26878 for (s = h; s; s = s->next)
26879 s->background_filled_p = true;
26880 compute_overhangs_and_x (h, tail->x + tail->width, false);
26881 append_glyph_string_lists (&head, &tail, h, t);
26883 tail = glyph_string_containing_background_width (tail);
26884 if (clip_tail)
26885 clip_tail = glyph_string_containing_background_width (clip_tail);
26886 if (clip_head || clip_tail)
26887 for (s = head; s; s = s->next)
26889 s->clip_head = clip_head;
26890 s->clip_tail = clip_tail;
26894 /* Draw all strings. */
26895 for (s = head; s; s = s->next)
26896 FRAME_RIF (f)->draw_glyph_string (s);
26898 #ifndef HAVE_NS
26899 /* When focus a sole frame and move horizontally, this clears on_p
26900 causing a failure to erase prev cursor position. */
26901 if (area == TEXT_AREA
26902 && !row->full_width_p
26903 /* When drawing overlapping rows, only the glyph strings'
26904 foreground is drawn, which doesn't erase a cursor
26905 completely. */
26906 && !overlaps)
26908 int x0 = clip_head ? clip_head->x : (head ? head->x : x);
26909 int x1 = (clip_tail ? clip_tail->x + clip_tail->background_width
26910 : (tail ? tail->x + tail->background_width : x));
26911 x0 -= area_left;
26912 x1 -= area_left;
26914 notice_overwritten_cursor (w, TEXT_AREA, x0, x1,
26915 row->y, MATRIX_ROW_BOTTOM_Y (row));
26917 #endif
26919 /* Value is the x-position up to which drawn, relative to AREA of W.
26920 This doesn't include parts drawn because of overhangs. */
26921 if (row->full_width_p)
26922 x_reached = FRAME_TO_WINDOW_PIXEL_X (w, x_reached);
26923 else
26924 x_reached -= area_left;
26926 RELEASE_HDC (hdc, f);
26928 SAFE_FREE ();
26929 return x_reached;
26932 /* Find the first glyph in the run of underlined glyphs preceding the
26933 beginning of glyph string S, and return its font (which could be
26934 NULL). This is needed because that font determines the underline
26935 position and thickness for the entire run of the underlined glyphs.
26936 This function is called from the draw_glyph_string method of GUI
26937 frame's redisplay interface (RIF) when it needs to draw in an
26938 underlined face. */
26939 struct font *
26940 font_for_underline_metrics (struct glyph_string *s)
26942 struct glyph *g0 = s->row->glyphs[s->area], *g;
26944 for (g = s->first_glyph - 1; g >= g0; g--)
26946 struct face *prev_face = FACE_FROM_ID (s->f, g->face_id);
26947 if (!(prev_face && prev_face->underline_p))
26948 break;
26951 /* If preceding glyphs are not underlined, use the font of S. */
26952 if (g == s->first_glyph - 1)
26953 return s->font;
26954 else
26956 /* Otherwise use the font of the last glyph we saw in the above
26957 loop whose face had the underline_p flag set. */
26958 return FACE_FROM_ID (s->f, g[1].face_id)->font;
26962 /* Expand row matrix if too narrow. Don't expand if area
26963 is not present. */
26965 #define IT_EXPAND_MATRIX_WIDTH(it, area) \
26967 if (!it->f->fonts_changed \
26968 && (it->glyph_row->glyphs[area] \
26969 < it->glyph_row->glyphs[area + 1])) \
26971 it->w->ncols_scale_factor++; \
26972 it->f->fonts_changed = true; \
26976 /* Store one glyph for IT->char_to_display in IT->glyph_row.
26977 Called from x_produce_glyphs when IT->glyph_row is non-null. */
26979 static void
26980 append_glyph (struct it *it)
26982 struct glyph *glyph;
26983 enum glyph_row_area area = it->area;
26985 eassert (it->glyph_row);
26986 eassert (it->char_to_display != '\n' && it->char_to_display != '\t');
26988 glyph = it->glyph_row->glyphs[area] + it->glyph_row->used[area];
26989 if (glyph < it->glyph_row->glyphs[area + 1])
26991 /* If the glyph row is reversed, we need to prepend the glyph
26992 rather than append it. */
26993 if (it->glyph_row->reversed_p && area == TEXT_AREA)
26995 struct glyph *g;
26997 /* Make room for the additional glyph. */
26998 for (g = glyph - 1; g >= it->glyph_row->glyphs[area]; g--)
26999 g[1] = *g;
27000 glyph = it->glyph_row->glyphs[area];
27002 glyph->charpos = CHARPOS (it->position);
27003 glyph->object = it->object;
27004 if (it->pixel_width > 0)
27006 eassert (it->pixel_width <= SHRT_MAX);
27007 glyph->pixel_width = it->pixel_width;
27008 glyph->padding_p = false;
27010 else
27012 /* Assure at least 1-pixel width. Otherwise, cursor can't
27013 be displayed correctly. */
27014 glyph->pixel_width = 1;
27015 glyph->padding_p = true;
27017 glyph->ascent = it->ascent;
27018 glyph->descent = it->descent;
27019 glyph->voffset = it->voffset;
27020 glyph->type = CHAR_GLYPH;
27021 glyph->avoid_cursor_p = it->avoid_cursor_p;
27022 glyph->multibyte_p = it->multibyte_p;
27023 if (it->glyph_row->reversed_p && area == TEXT_AREA)
27025 /* In R2L rows, the left and the right box edges need to be
27026 drawn in reverse direction. */
27027 glyph->right_box_line_p = it->start_of_box_run_p;
27028 glyph->left_box_line_p = it->end_of_box_run_p;
27030 else
27032 glyph->left_box_line_p = it->start_of_box_run_p;
27033 glyph->right_box_line_p = it->end_of_box_run_p;
27035 glyph->overlaps_vertically_p = (it->phys_ascent > it->ascent
27036 || it->phys_descent > it->descent);
27037 glyph->glyph_not_available_p = it->glyph_not_available_p;
27038 glyph->face_id = it->face_id;
27039 glyph->u.ch = it->char_to_display;
27040 glyph->slice.img = null_glyph_slice;
27041 glyph->font_type = FONT_TYPE_UNKNOWN;
27042 if (it->bidi_p)
27044 glyph->resolved_level = it->bidi_it.resolved_level;
27045 eassert ((it->bidi_it.type & 7) == it->bidi_it.type);
27046 glyph->bidi_type = it->bidi_it.type;
27048 else
27050 glyph->resolved_level = 0;
27051 glyph->bidi_type = UNKNOWN_BT;
27053 ++it->glyph_row->used[area];
27055 else
27056 IT_EXPAND_MATRIX_WIDTH (it, area);
27059 /* Store one glyph for the composition IT->cmp_it.id in
27060 IT->glyph_row. Called from x_produce_glyphs when IT->glyph_row is
27061 non-null. */
27063 static void
27064 append_composite_glyph (struct it *it)
27066 struct glyph *glyph;
27067 enum glyph_row_area area = it->area;
27069 eassert (it->glyph_row);
27071 glyph = it->glyph_row->glyphs[area] + it->glyph_row->used[area];
27072 if (glyph < it->glyph_row->glyphs[area + 1])
27074 /* If the glyph row is reversed, we need to prepend the glyph
27075 rather than append it. */
27076 if (it->glyph_row->reversed_p && it->area == TEXT_AREA)
27078 struct glyph *g;
27080 /* Make room for the new glyph. */
27081 for (g = glyph - 1; g >= it->glyph_row->glyphs[it->area]; g--)
27082 g[1] = *g;
27083 glyph = it->glyph_row->glyphs[it->area];
27085 glyph->charpos = it->cmp_it.charpos;
27086 glyph->object = it->object;
27087 eassert (it->pixel_width <= SHRT_MAX);
27088 glyph->pixel_width = it->pixel_width;
27089 glyph->ascent = it->ascent;
27090 glyph->descent = it->descent;
27091 glyph->voffset = it->voffset;
27092 glyph->type = COMPOSITE_GLYPH;
27093 if (it->cmp_it.ch < 0)
27095 glyph->u.cmp.automatic = false;
27096 glyph->u.cmp.id = it->cmp_it.id;
27097 glyph->slice.cmp.from = glyph->slice.cmp.to = 0;
27099 else
27101 glyph->u.cmp.automatic = true;
27102 glyph->u.cmp.id = it->cmp_it.id;
27103 glyph->slice.cmp.from = it->cmp_it.from;
27104 glyph->slice.cmp.to = it->cmp_it.to - 1;
27106 glyph->avoid_cursor_p = it->avoid_cursor_p;
27107 glyph->multibyte_p = it->multibyte_p;
27108 if (it->glyph_row->reversed_p && area == TEXT_AREA)
27110 /* In R2L rows, the left and the right box edges need to be
27111 drawn in reverse direction. */
27112 glyph->right_box_line_p = it->start_of_box_run_p;
27113 glyph->left_box_line_p = it->end_of_box_run_p;
27115 else
27117 glyph->left_box_line_p = it->start_of_box_run_p;
27118 glyph->right_box_line_p = it->end_of_box_run_p;
27120 glyph->overlaps_vertically_p = (it->phys_ascent > it->ascent
27121 || it->phys_descent > it->descent);
27122 glyph->padding_p = false;
27123 glyph->glyph_not_available_p = false;
27124 glyph->face_id = it->face_id;
27125 glyph->font_type = FONT_TYPE_UNKNOWN;
27126 if (it->bidi_p)
27128 glyph->resolved_level = it->bidi_it.resolved_level;
27129 eassert ((it->bidi_it.type & 7) == it->bidi_it.type);
27130 glyph->bidi_type = it->bidi_it.type;
27132 ++it->glyph_row->used[area];
27134 else
27135 IT_EXPAND_MATRIX_WIDTH (it, area);
27139 /* Change IT->ascent and IT->height according to the setting of
27140 IT->voffset. */
27142 static void
27143 take_vertical_position_into_account (struct it *it)
27145 if (it->voffset)
27147 if (it->voffset < 0)
27148 /* Increase the ascent so that we can display the text higher
27149 in the line. */
27150 it->ascent -= it->voffset;
27151 else
27152 /* Increase the descent so that we can display the text lower
27153 in the line. */
27154 it->descent += it->voffset;
27159 /* Produce glyphs/get display metrics for the image IT is loaded with.
27160 See the description of struct display_iterator in dispextern.h for
27161 an overview of struct display_iterator. */
27163 static void
27164 produce_image_glyph (struct it *it)
27166 struct image *img;
27167 struct face *face;
27168 int glyph_ascent, crop;
27169 struct glyph_slice slice;
27171 eassert (it->what == IT_IMAGE);
27173 face = FACE_FROM_ID (it->f, it->face_id);
27174 /* Make sure X resources of the face is loaded. */
27175 prepare_face_for_display (it->f, face);
27177 if (it->image_id < 0)
27179 /* Fringe bitmap. */
27180 it->ascent = it->phys_ascent = 0;
27181 it->descent = it->phys_descent = 0;
27182 it->pixel_width = 0;
27183 it->nglyphs = 0;
27184 return;
27187 img = IMAGE_FROM_ID (it->f, it->image_id);
27188 /* Make sure X resources of the image is loaded. */
27189 prepare_image_for_display (it->f, img);
27191 slice.x = slice.y = 0;
27192 slice.width = img->width;
27193 slice.height = img->height;
27195 if (INTEGERP (it->slice.x))
27196 slice.x = XINT (it->slice.x);
27197 else if (FLOATP (it->slice.x))
27198 slice.x = XFLOAT_DATA (it->slice.x) * img->width;
27200 if (INTEGERP (it->slice.y))
27201 slice.y = XINT (it->slice.y);
27202 else if (FLOATP (it->slice.y))
27203 slice.y = XFLOAT_DATA (it->slice.y) * img->height;
27205 if (INTEGERP (it->slice.width))
27206 slice.width = XINT (it->slice.width);
27207 else if (FLOATP (it->slice.width))
27208 slice.width = XFLOAT_DATA (it->slice.width) * img->width;
27210 if (INTEGERP (it->slice.height))
27211 slice.height = XINT (it->slice.height);
27212 else if (FLOATP (it->slice.height))
27213 slice.height = XFLOAT_DATA (it->slice.height) * img->height;
27215 if (slice.x >= img->width)
27216 slice.x = img->width;
27217 if (slice.y >= img->height)
27218 slice.y = img->height;
27219 if (slice.x + slice.width >= img->width)
27220 slice.width = img->width - slice.x;
27221 if (slice.y + slice.height > img->height)
27222 slice.height = img->height - slice.y;
27224 if (slice.width == 0 || slice.height == 0)
27225 return;
27227 it->ascent = it->phys_ascent = glyph_ascent = image_ascent (img, face, &slice);
27229 it->descent = slice.height - glyph_ascent;
27230 if (slice.y == 0)
27231 it->descent += img->vmargin;
27232 if (slice.y + slice.height == img->height)
27233 it->descent += img->vmargin;
27234 it->phys_descent = it->descent;
27236 it->pixel_width = slice.width;
27237 if (slice.x == 0)
27238 it->pixel_width += img->hmargin;
27239 if (slice.x + slice.width == img->width)
27240 it->pixel_width += img->hmargin;
27242 /* It's quite possible for images to have an ascent greater than
27243 their height, so don't get confused in that case. */
27244 if (it->descent < 0)
27245 it->descent = 0;
27247 it->nglyphs = 1;
27249 if (face->box != FACE_NO_BOX)
27251 if (face->box_line_width > 0)
27253 if (slice.y == 0)
27254 it->ascent += face->box_line_width;
27255 if (slice.y + slice.height == img->height)
27256 it->descent += face->box_line_width;
27259 if (it->start_of_box_run_p && slice.x == 0)
27260 it->pixel_width += eabs (face->box_line_width);
27261 if (it->end_of_box_run_p && slice.x + slice.width == img->width)
27262 it->pixel_width += eabs (face->box_line_width);
27265 take_vertical_position_into_account (it);
27267 /* Automatically crop wide image glyphs at right edge so we can
27268 draw the cursor on same display row. */
27269 if ((crop = it->pixel_width - (it->last_visible_x - it->current_x), crop > 0)
27270 && (it->hpos == 0 || it->pixel_width > it->last_visible_x / 4))
27272 it->pixel_width -= crop;
27273 slice.width -= crop;
27276 if (it->glyph_row)
27278 struct glyph *glyph;
27279 enum glyph_row_area area = it->area;
27281 glyph = it->glyph_row->glyphs[area] + it->glyph_row->used[area];
27282 if (it->glyph_row->reversed_p)
27284 struct glyph *g;
27286 /* Make room for the new glyph. */
27287 for (g = glyph - 1; g >= it->glyph_row->glyphs[it->area]; g--)
27288 g[1] = *g;
27289 glyph = it->glyph_row->glyphs[it->area];
27291 if (glyph < it->glyph_row->glyphs[area + 1])
27293 glyph->charpos = CHARPOS (it->position);
27294 glyph->object = it->object;
27295 glyph->pixel_width = clip_to_bounds (-1, it->pixel_width, SHRT_MAX);
27296 glyph->ascent = glyph_ascent;
27297 glyph->descent = it->descent;
27298 glyph->voffset = it->voffset;
27299 glyph->type = IMAGE_GLYPH;
27300 glyph->avoid_cursor_p = it->avoid_cursor_p;
27301 glyph->multibyte_p = it->multibyte_p;
27302 if (it->glyph_row->reversed_p && area == TEXT_AREA)
27304 /* In R2L rows, the left and the right box edges need to be
27305 drawn in reverse direction. */
27306 glyph->right_box_line_p = it->start_of_box_run_p;
27307 glyph->left_box_line_p = it->end_of_box_run_p;
27309 else
27311 glyph->left_box_line_p = it->start_of_box_run_p;
27312 glyph->right_box_line_p = it->end_of_box_run_p;
27314 glyph->overlaps_vertically_p = false;
27315 glyph->padding_p = false;
27316 glyph->glyph_not_available_p = false;
27317 glyph->face_id = it->face_id;
27318 glyph->u.img_id = img->id;
27319 glyph->slice.img = slice;
27320 glyph->font_type = FONT_TYPE_UNKNOWN;
27321 if (it->bidi_p)
27323 glyph->resolved_level = it->bidi_it.resolved_level;
27324 eassert ((it->bidi_it.type & 7) == it->bidi_it.type);
27325 glyph->bidi_type = it->bidi_it.type;
27327 ++it->glyph_row->used[area];
27329 else
27330 IT_EXPAND_MATRIX_WIDTH (it, area);
27334 static void
27335 produce_xwidget_glyph (struct it *it)
27337 #ifdef HAVE_XWIDGETS
27338 struct xwidget *xw;
27339 int glyph_ascent, crop;
27340 eassert (it->what == IT_XWIDGET);
27342 struct face *face = FACE_FROM_ID (it->f, it->face_id);
27343 /* Make sure X resources of the face is loaded. */
27344 prepare_face_for_display (it->f, face);
27346 xw = it->xwidget;
27347 it->ascent = it->phys_ascent = glyph_ascent = xw->height/2;
27348 it->descent = xw->height/2;
27349 it->phys_descent = it->descent;
27350 it->pixel_width = xw->width;
27351 /* It's quite possible for images to have an ascent greater than
27352 their height, so don't get confused in that case. */
27353 if (it->descent < 0)
27354 it->descent = 0;
27356 it->nglyphs = 1;
27358 if (face->box != FACE_NO_BOX)
27360 if (face->box_line_width > 0)
27362 it->ascent += face->box_line_width;
27363 it->descent += face->box_line_width;
27366 if (it->start_of_box_run_p)
27367 it->pixel_width += eabs (face->box_line_width);
27368 it->pixel_width += eabs (face->box_line_width);
27371 take_vertical_position_into_account (it);
27373 /* Automatically crop wide image glyphs at right edge so we can
27374 draw the cursor on same display row. */
27375 crop = it->pixel_width - (it->last_visible_x - it->current_x);
27376 if (crop > 0 && (it->hpos == 0 || it->pixel_width > it->last_visible_x / 4))
27377 it->pixel_width -= crop;
27379 if (it->glyph_row)
27381 enum glyph_row_area area = it->area;
27382 struct glyph *glyph
27383 = it->glyph_row->glyphs[area] + it->glyph_row->used[area];
27385 if (it->glyph_row->reversed_p)
27387 struct glyph *g;
27389 /* Make room for the new glyph. */
27390 for (g = glyph - 1; g >= it->glyph_row->glyphs[it->area]; g--)
27391 g[1] = *g;
27392 glyph = it->glyph_row->glyphs[it->area];
27394 if (glyph < it->glyph_row->glyphs[area + 1])
27396 glyph->charpos = CHARPOS (it->position);
27397 glyph->object = it->object;
27398 glyph->pixel_width = clip_to_bounds (-1, it->pixel_width, SHRT_MAX);
27399 glyph->ascent = glyph_ascent;
27400 glyph->descent = it->descent;
27401 glyph->voffset = it->voffset;
27402 glyph->type = XWIDGET_GLYPH;
27403 glyph->avoid_cursor_p = it->avoid_cursor_p;
27404 glyph->multibyte_p = it->multibyte_p;
27405 if (it->glyph_row->reversed_p && area == TEXT_AREA)
27407 /* In R2L rows, the left and the right box edges need to be
27408 drawn in reverse direction. */
27409 glyph->right_box_line_p = it->start_of_box_run_p;
27410 glyph->left_box_line_p = it->end_of_box_run_p;
27412 else
27414 glyph->left_box_line_p = it->start_of_box_run_p;
27415 glyph->right_box_line_p = it->end_of_box_run_p;
27417 glyph->overlaps_vertically_p = 0;
27418 glyph->padding_p = 0;
27419 glyph->glyph_not_available_p = 0;
27420 glyph->face_id = it->face_id;
27421 glyph->u.xwidget = it->xwidget;
27422 glyph->font_type = FONT_TYPE_UNKNOWN;
27423 if (it->bidi_p)
27425 glyph->resolved_level = it->bidi_it.resolved_level;
27426 eassert ((it->bidi_it.type & 7) == it->bidi_it.type);
27427 glyph->bidi_type = it->bidi_it.type;
27429 ++it->glyph_row->used[area];
27431 else
27432 IT_EXPAND_MATRIX_WIDTH (it, area);
27434 #endif
27437 /* Append a stretch glyph to IT->glyph_row. OBJECT is the source
27438 of the glyph, WIDTH and HEIGHT are the width and height of the
27439 stretch. ASCENT is the ascent of the glyph (0 <= ASCENT <= HEIGHT). */
27441 static void
27442 append_stretch_glyph (struct it *it, Lisp_Object object,
27443 int width, int height, int ascent)
27445 struct glyph *glyph;
27446 enum glyph_row_area area = it->area;
27448 eassert (ascent >= 0 && ascent <= height);
27450 glyph = it->glyph_row->glyphs[area] + it->glyph_row->used[area];
27451 if (glyph < it->glyph_row->glyphs[area + 1])
27453 /* If the glyph row is reversed, we need to prepend the glyph
27454 rather than append it. */
27455 if (it->glyph_row->reversed_p && area == TEXT_AREA)
27457 struct glyph *g;
27459 /* Make room for the additional glyph. */
27460 for (g = glyph - 1; g >= it->glyph_row->glyphs[area]; g--)
27461 g[1] = *g;
27462 glyph = it->glyph_row->glyphs[area];
27464 /* Decrease the width of the first glyph of the row that
27465 begins before first_visible_x (e.g., due to hscroll).
27466 This is so the overall width of the row becomes smaller
27467 by the scroll amount, and the stretch glyph appended by
27468 extend_face_to_end_of_line will be wider, to shift the
27469 row glyphs to the right. (In L2R rows, the corresponding
27470 left-shift effect is accomplished by setting row->x to a
27471 negative value, which won't work with R2L rows.)
27473 This must leave us with a positive value of WIDTH, since
27474 otherwise the call to move_it_in_display_line_to at the
27475 beginning of display_line would have got past the entire
27476 first glyph, and then it->current_x would have been
27477 greater or equal to it->first_visible_x. */
27478 if (it->current_x < it->first_visible_x)
27479 width -= it->first_visible_x - it->current_x;
27480 eassert (width > 0);
27482 glyph->charpos = CHARPOS (it->position);
27483 glyph->object = object;
27484 /* FIXME: It would be better to use TYPE_MAX here, but
27485 __typeof__ is not portable enough... */
27486 glyph->pixel_width = clip_to_bounds (-1, width, SHRT_MAX);
27487 glyph->ascent = ascent;
27488 glyph->descent = height - ascent;
27489 glyph->voffset = it->voffset;
27490 glyph->type = STRETCH_GLYPH;
27491 glyph->avoid_cursor_p = it->avoid_cursor_p;
27492 glyph->multibyte_p = it->multibyte_p;
27493 if (it->glyph_row->reversed_p && area == TEXT_AREA)
27495 /* In R2L rows, the left and the right box edges need to be
27496 drawn in reverse direction. */
27497 glyph->right_box_line_p = it->start_of_box_run_p;
27498 glyph->left_box_line_p = it->end_of_box_run_p;
27500 else
27502 glyph->left_box_line_p = it->start_of_box_run_p;
27503 glyph->right_box_line_p = it->end_of_box_run_p;
27505 glyph->overlaps_vertically_p = false;
27506 glyph->padding_p = false;
27507 glyph->glyph_not_available_p = false;
27508 glyph->face_id = it->face_id;
27509 glyph->u.stretch.ascent = ascent;
27510 glyph->u.stretch.height = height;
27511 glyph->slice.img = null_glyph_slice;
27512 glyph->font_type = FONT_TYPE_UNKNOWN;
27513 if (it->bidi_p)
27515 glyph->resolved_level = it->bidi_it.resolved_level;
27516 eassert ((it->bidi_it.type & 7) == it->bidi_it.type);
27517 glyph->bidi_type = it->bidi_it.type;
27519 else
27521 glyph->resolved_level = 0;
27522 glyph->bidi_type = UNKNOWN_BT;
27524 ++it->glyph_row->used[area];
27526 else
27527 IT_EXPAND_MATRIX_WIDTH (it, area);
27530 #endif /* HAVE_WINDOW_SYSTEM */
27532 /* Produce a stretch glyph for iterator IT. IT->object is the value
27533 of the glyph property displayed. The value must be a list
27534 `(space KEYWORD VALUE ...)' with the following KEYWORD/VALUE pairs
27535 being recognized:
27537 1. `:width WIDTH' specifies that the space should be WIDTH *
27538 canonical char width wide. WIDTH may be an integer or floating
27539 point number.
27541 2. `:relative-width FACTOR' specifies that the width of the stretch
27542 should be computed from the width of the first character having the
27543 `glyph' property, and should be FACTOR times that width.
27545 3. `:align-to HPOS' specifies that the space should be wide enough
27546 to reach HPOS, a value in canonical character units.
27548 Exactly one of the above pairs must be present.
27550 4. `:height HEIGHT' specifies that the height of the stretch produced
27551 should be HEIGHT, measured in canonical character units.
27553 5. `:relative-height FACTOR' specifies that the height of the
27554 stretch should be FACTOR times the height of the characters having
27555 the glyph property.
27557 Either none or exactly one of 4 or 5 must be present.
27559 6. `:ascent ASCENT' specifies that ASCENT percent of the height
27560 of the stretch should be used for the ascent of the stretch.
27561 ASCENT must be in the range 0 <= ASCENT <= 100. */
27563 void
27564 produce_stretch_glyph (struct it *it)
27566 /* (space :width WIDTH :height HEIGHT ...) */
27567 Lisp_Object prop, plist;
27568 int width = 0, height = 0, align_to = -1;
27569 bool zero_width_ok_p = false;
27570 double tem;
27571 struct font *font = NULL;
27573 #ifdef HAVE_WINDOW_SYSTEM
27574 int ascent = 0;
27575 bool zero_height_ok_p = false;
27577 if (FRAME_WINDOW_P (it->f))
27579 struct face *face = FACE_FROM_ID (it->f, it->face_id);
27580 font = face->font ? face->font : FRAME_FONT (it->f);
27581 prepare_face_for_display (it->f, face);
27583 #endif
27585 /* List should start with `space'. */
27586 eassert (CONSP (it->object) && EQ (XCAR (it->object), Qspace));
27587 plist = XCDR (it->object);
27589 /* Compute the width of the stretch. */
27590 if ((prop = Fplist_get (plist, QCwidth), !NILP (prop))
27591 && calc_pixel_width_or_height (&tem, it, prop, font, true, 0))
27593 /* Absolute width `:width WIDTH' specified and valid. */
27594 zero_width_ok_p = true;
27595 width = (int)tem;
27597 else if (prop = Fplist_get (plist, QCrelative_width), NUMVAL (prop) > 0)
27599 /* Relative width `:relative-width FACTOR' specified and valid.
27600 Compute the width of the characters having the `glyph'
27601 property. */
27602 struct it it2;
27603 unsigned char *p = BYTE_POS_ADDR (IT_BYTEPOS (*it));
27605 it2 = *it;
27606 if (it->multibyte_p)
27607 it2.c = it2.char_to_display = STRING_CHAR_AND_LENGTH (p, it2.len);
27608 else
27610 it2.c = it2.char_to_display = *p, it2.len = 1;
27611 if (! ASCII_CHAR_P (it2.c))
27612 it2.char_to_display = BYTE8_TO_CHAR (it2.c);
27615 it2.glyph_row = NULL;
27616 it2.what = IT_CHARACTER;
27617 PRODUCE_GLYPHS (&it2);
27618 width = NUMVAL (prop) * it2.pixel_width;
27620 else if ((prop = Fplist_get (plist, QCalign_to), !NILP (prop))
27621 && calc_pixel_width_or_height (&tem, it, prop, font, true,
27622 &align_to))
27624 if (it->glyph_row == NULL || !it->glyph_row->mode_line_p)
27625 align_to = (align_to < 0
27627 : align_to - window_box_left_offset (it->w, TEXT_AREA));
27628 else if (align_to < 0)
27629 align_to = window_box_left_offset (it->w, TEXT_AREA);
27630 width = max (0, (int)tem + align_to - it->current_x);
27631 zero_width_ok_p = true;
27633 else
27634 /* Nothing specified -> width defaults to canonical char width. */
27635 width = FRAME_COLUMN_WIDTH (it->f);
27637 if (width <= 0 && (width < 0 || !zero_width_ok_p))
27638 width = 1;
27640 #ifdef HAVE_WINDOW_SYSTEM
27641 /* Compute height. */
27642 if (FRAME_WINDOW_P (it->f))
27644 int default_height = normal_char_height (font, ' ');
27646 if ((prop = Fplist_get (plist, QCheight), !NILP (prop))
27647 && calc_pixel_width_or_height (&tem, it, prop, font, false, 0))
27649 height = (int)tem;
27650 zero_height_ok_p = true;
27652 else if (prop = Fplist_get (plist, QCrelative_height),
27653 NUMVAL (prop) > 0)
27654 height = default_height * NUMVAL (prop);
27655 else
27656 height = default_height;
27658 if (height <= 0 && (height < 0 || !zero_height_ok_p))
27659 height = 1;
27661 /* Compute percentage of height used for ascent. If
27662 `:ascent ASCENT' is present and valid, use that. Otherwise,
27663 derive the ascent from the font in use. */
27664 if (prop = Fplist_get (plist, QCascent),
27665 NUMVAL (prop) > 0 && NUMVAL (prop) <= 100)
27666 ascent = height * NUMVAL (prop) / 100.0;
27667 else if (!NILP (prop)
27668 && calc_pixel_width_or_height (&tem, it, prop, font, false, 0))
27669 ascent = min (max (0, (int)tem), height);
27670 else
27671 ascent = (height * FONT_BASE (font)) / FONT_HEIGHT (font);
27673 else
27674 #endif /* HAVE_WINDOW_SYSTEM */
27675 height = 1;
27677 if (width > 0 && it->line_wrap != TRUNCATE
27678 && it->current_x + width > it->last_visible_x)
27680 width = it->last_visible_x - it->current_x;
27681 #ifdef HAVE_WINDOW_SYSTEM
27682 /* Subtract one more pixel from the stretch width, but only on
27683 GUI frames, since on a TTY each glyph is one "pixel" wide. */
27684 width -= FRAME_WINDOW_P (it->f);
27685 #endif
27688 if (width > 0 && height > 0 && it->glyph_row)
27690 Lisp_Object o_object = it->object;
27691 Lisp_Object object = it->stack[it->sp - 1].string;
27692 int n = width;
27694 if (!STRINGP (object))
27695 object = it->w->contents;
27696 #ifdef HAVE_WINDOW_SYSTEM
27697 if (FRAME_WINDOW_P (it->f))
27698 append_stretch_glyph (it, object, width, height, ascent);
27699 else
27700 #endif
27702 it->object = object;
27703 it->char_to_display = ' ';
27704 it->pixel_width = it->len = 1;
27705 while (n--)
27706 tty_append_glyph (it);
27707 it->object = o_object;
27711 it->pixel_width = width;
27712 #ifdef HAVE_WINDOW_SYSTEM
27713 if (FRAME_WINDOW_P (it->f))
27715 it->ascent = it->phys_ascent = ascent;
27716 it->descent = it->phys_descent = height - it->ascent;
27717 it->nglyphs = width > 0 && height > 0;
27718 take_vertical_position_into_account (it);
27720 else
27721 #endif
27722 it->nglyphs = width;
27725 /* Get information about special display element WHAT in an
27726 environment described by IT. WHAT is one of IT_TRUNCATION or
27727 IT_CONTINUATION. Maybe produce glyphs for WHAT if IT has a
27728 non-null glyph_row member. This function ensures that fields like
27729 face_id, c, len of IT are left untouched. */
27731 static void
27732 produce_special_glyphs (struct it *it, enum display_element_type what)
27734 struct it temp_it;
27735 Lisp_Object gc;
27736 GLYPH glyph;
27738 temp_it = *it;
27739 temp_it.object = Qnil;
27740 memset (&temp_it.current, 0, sizeof temp_it.current);
27742 if (what == IT_CONTINUATION)
27744 /* Continuation glyph. For R2L lines, we mirror it by hand. */
27745 if (it->bidi_it.paragraph_dir == R2L)
27746 SET_GLYPH_FROM_CHAR (glyph, '/');
27747 else
27748 SET_GLYPH_FROM_CHAR (glyph, '\\');
27749 if (it->dp
27750 && (gc = DISP_CONTINUE_GLYPH (it->dp), GLYPH_CODE_P (gc)))
27752 /* FIXME: Should we mirror GC for R2L lines? */
27753 SET_GLYPH_FROM_GLYPH_CODE (glyph, gc);
27754 spec_glyph_lookup_face (XWINDOW (it->window), &glyph);
27757 else if (what == IT_TRUNCATION)
27759 /* Truncation glyph. */
27760 SET_GLYPH_FROM_CHAR (glyph, '$');
27761 if (it->dp
27762 && (gc = DISP_TRUNC_GLYPH (it->dp), GLYPH_CODE_P (gc)))
27764 /* FIXME: Should we mirror GC for R2L lines? */
27765 SET_GLYPH_FROM_GLYPH_CODE (glyph, gc);
27766 spec_glyph_lookup_face (XWINDOW (it->window), &glyph);
27769 else
27770 emacs_abort ();
27772 #ifdef HAVE_WINDOW_SYSTEM
27773 /* On a GUI frame, when the right fringe (left fringe for R2L rows)
27774 is turned off, we precede the truncation/continuation glyphs by a
27775 stretch glyph whose width is computed such that these special
27776 glyphs are aligned at the window margin, even when very different
27777 fonts are used in different glyph rows. */
27778 if (FRAME_WINDOW_P (temp_it.f)
27779 /* init_iterator calls this with it->glyph_row == NULL, and it
27780 wants only the pixel width of the truncation/continuation
27781 glyphs. */
27782 && temp_it.glyph_row
27783 /* insert_left_trunc_glyphs calls us at the beginning of the
27784 row, and it has its own calculation of the stretch glyph
27785 width. */
27786 && temp_it.glyph_row->used[TEXT_AREA] > 0
27787 && (temp_it.glyph_row->reversed_p
27788 ? WINDOW_LEFT_FRINGE_WIDTH (temp_it.w)
27789 : WINDOW_RIGHT_FRINGE_WIDTH (temp_it.w)) == 0)
27791 int stretch_width = temp_it.last_visible_x - temp_it.current_x;
27793 if (stretch_width > 0)
27795 struct face *face = FACE_FROM_ID (temp_it.f, temp_it.face_id);
27796 struct font *font =
27797 face->font ? face->font : FRAME_FONT (temp_it.f);
27798 int stretch_ascent =
27799 (((temp_it.ascent + temp_it.descent)
27800 * FONT_BASE (font)) / FONT_HEIGHT (font));
27802 append_stretch_glyph (&temp_it, Qnil, stretch_width,
27803 temp_it.ascent + temp_it.descent,
27804 stretch_ascent);
27807 #endif
27809 temp_it.dp = NULL;
27810 temp_it.what = IT_CHARACTER;
27811 temp_it.c = temp_it.char_to_display = GLYPH_CHAR (glyph);
27812 temp_it.face_id = GLYPH_FACE (glyph);
27813 temp_it.len = CHAR_BYTES (temp_it.c);
27815 PRODUCE_GLYPHS (&temp_it);
27816 it->pixel_width = temp_it.pixel_width;
27817 it->nglyphs = temp_it.nglyphs;
27820 #ifdef HAVE_WINDOW_SYSTEM
27822 /* Calculate line-height and line-spacing properties.
27823 An integer value specifies explicit pixel value.
27824 A float value specifies relative value to current face height.
27825 A cons (float . face-name) specifies relative value to
27826 height of specified face font.
27828 Returns height in pixels, or nil. */
27830 static Lisp_Object
27831 calc_line_height_property (struct it *it, Lisp_Object val, struct font *font,
27832 int boff, bool override)
27834 Lisp_Object face_name = Qnil;
27835 int ascent, descent, height;
27837 if (NILP (val) || INTEGERP (val) || (override && EQ (val, Qt)))
27838 return val;
27840 if (CONSP (val))
27842 face_name = XCAR (val);
27843 val = XCDR (val);
27844 if (!NUMBERP (val))
27845 val = make_number (1);
27846 if (NILP (face_name))
27848 height = it->ascent + it->descent;
27849 goto scale;
27853 if (NILP (face_name))
27855 font = FRAME_FONT (it->f);
27856 boff = FRAME_BASELINE_OFFSET (it->f);
27858 else if (EQ (face_name, Qt))
27860 override = false;
27862 else
27864 int face_id;
27865 struct face *face;
27867 face_id = lookup_named_face (it->w, it->f, face_name, false);
27868 face = FACE_FROM_ID_OR_NULL (it->f, face_id);
27869 if (face == NULL || ((font = face->font) == NULL))
27870 return make_number (-1);
27871 boff = font->baseline_offset;
27872 if (font->vertical_centering)
27873 boff = VCENTER_BASELINE_OFFSET (font, it->f) - boff;
27876 normal_char_ascent_descent (font, -1, &ascent, &descent);
27878 if (override)
27880 it->override_ascent = ascent;
27881 it->override_descent = descent;
27882 it->override_boff = boff;
27885 height = ascent + descent;
27887 scale:
27888 if (FLOATP (val))
27889 height = (int)(XFLOAT_DATA (val) * height);
27890 else if (INTEGERP (val))
27891 height *= XINT (val);
27893 return make_number (height);
27897 /* Append a glyph for a glyphless character to IT->glyph_row. FACE_ID
27898 is a face ID to be used for the glyph. FOR_NO_FONT is true if
27899 and only if this is for a character for which no font was found.
27901 If the display method (it->glyphless_method) is
27902 GLYPHLESS_DISPLAY_ACRONYM or GLYPHLESS_DISPLAY_HEX_CODE, LEN is a
27903 length of the acronym or the hexadecimal string, UPPER_XOFF and
27904 UPPER_YOFF are pixel offsets for the upper part of the string,
27905 LOWER_XOFF and LOWER_YOFF are for the lower part.
27907 For the other display methods, LEN through LOWER_YOFF are zero. */
27909 static void
27910 append_glyphless_glyph (struct it *it, int face_id, bool for_no_font, int len,
27911 short upper_xoff, short upper_yoff,
27912 short lower_xoff, short lower_yoff)
27914 struct glyph *glyph;
27915 enum glyph_row_area area = it->area;
27917 glyph = it->glyph_row->glyphs[area] + it->glyph_row->used[area];
27918 if (glyph < it->glyph_row->glyphs[area + 1])
27920 /* If the glyph row is reversed, we need to prepend the glyph
27921 rather than append it. */
27922 if (it->glyph_row->reversed_p && area == TEXT_AREA)
27924 struct glyph *g;
27926 /* Make room for the additional glyph. */
27927 for (g = glyph - 1; g >= it->glyph_row->glyphs[area]; g--)
27928 g[1] = *g;
27929 glyph = it->glyph_row->glyphs[area];
27931 glyph->charpos = CHARPOS (it->position);
27932 glyph->object = it->object;
27933 eassert (it->pixel_width <= SHRT_MAX);
27934 glyph->pixel_width = it->pixel_width;
27935 glyph->ascent = it->ascent;
27936 glyph->descent = it->descent;
27937 glyph->voffset = it->voffset;
27938 glyph->type = GLYPHLESS_GLYPH;
27939 glyph->u.glyphless.method = it->glyphless_method;
27940 glyph->u.glyphless.for_no_font = for_no_font;
27941 glyph->u.glyphless.len = len;
27942 glyph->u.glyphless.ch = it->c;
27943 glyph->slice.glyphless.upper_xoff = upper_xoff;
27944 glyph->slice.glyphless.upper_yoff = upper_yoff;
27945 glyph->slice.glyphless.lower_xoff = lower_xoff;
27946 glyph->slice.glyphless.lower_yoff = lower_yoff;
27947 glyph->avoid_cursor_p = it->avoid_cursor_p;
27948 glyph->multibyte_p = it->multibyte_p;
27949 if (it->glyph_row->reversed_p && area == TEXT_AREA)
27951 /* In R2L rows, the left and the right box edges need to be
27952 drawn in reverse direction. */
27953 glyph->right_box_line_p = it->start_of_box_run_p;
27954 glyph->left_box_line_p = it->end_of_box_run_p;
27956 else
27958 glyph->left_box_line_p = it->start_of_box_run_p;
27959 glyph->right_box_line_p = it->end_of_box_run_p;
27961 glyph->overlaps_vertically_p = (it->phys_ascent > it->ascent
27962 || it->phys_descent > it->descent);
27963 glyph->padding_p = false;
27964 glyph->glyph_not_available_p = false;
27965 glyph->face_id = face_id;
27966 glyph->font_type = FONT_TYPE_UNKNOWN;
27967 if (it->bidi_p)
27969 glyph->resolved_level = it->bidi_it.resolved_level;
27970 eassert ((it->bidi_it.type & 7) == it->bidi_it.type);
27971 glyph->bidi_type = it->bidi_it.type;
27973 ++it->glyph_row->used[area];
27975 else
27976 IT_EXPAND_MATRIX_WIDTH (it, area);
27980 /* Produce a glyph for a glyphless character for iterator IT.
27981 IT->glyphless_method specifies which method to use for displaying
27982 the character. See the description of enum
27983 glyphless_display_method in dispextern.h for the detail.
27985 FOR_NO_FONT is true if and only if this is for a character for
27986 which no font was found. ACRONYM, if non-nil, is an acronym string
27987 for the character. */
27989 static void
27990 produce_glyphless_glyph (struct it *it, bool for_no_font, Lisp_Object acronym)
27992 int face_id;
27993 struct face *face;
27994 struct font *font;
27995 int base_width, base_height, width, height;
27996 short upper_xoff, upper_yoff, lower_xoff, lower_yoff;
27997 int len;
27999 /* Get the metrics of the base font. We always refer to the current
28000 ASCII face. */
28001 face = FACE_FROM_ID (it->f, it->face_id)->ascii_face;
28002 font = face->font ? face->font : FRAME_FONT (it->f);
28003 normal_char_ascent_descent (font, -1, &it->ascent, &it->descent);
28004 it->ascent += font->baseline_offset;
28005 it->descent -= font->baseline_offset;
28006 base_height = it->ascent + it->descent;
28007 base_width = font->average_width;
28009 face_id = merge_glyphless_glyph_face (it);
28011 if (it->glyphless_method == GLYPHLESS_DISPLAY_THIN_SPACE)
28013 it->pixel_width = THIN_SPACE_WIDTH;
28014 len = 0;
28015 upper_xoff = upper_yoff = lower_xoff = lower_yoff = 0;
28017 else if (it->glyphless_method == GLYPHLESS_DISPLAY_EMPTY_BOX)
28019 width = CHARACTER_WIDTH (it->c);
28020 if (width == 0)
28021 width = 1;
28022 else if (width > 4)
28023 width = 4;
28024 it->pixel_width = base_width * width;
28025 len = 0;
28026 upper_xoff = upper_yoff = lower_xoff = lower_yoff = 0;
28028 else
28030 char buf[7];
28031 const char *str;
28032 unsigned int code[6];
28033 int upper_len;
28034 int ascent, descent;
28035 struct font_metrics metrics_upper, metrics_lower;
28037 face = FACE_FROM_ID (it->f, face_id);
28038 font = face->font ? face->font : FRAME_FONT (it->f);
28039 prepare_face_for_display (it->f, face);
28041 if (it->glyphless_method == GLYPHLESS_DISPLAY_ACRONYM)
28043 if (! STRINGP (acronym) && CHAR_TABLE_P (Vglyphless_char_display))
28044 acronym = CHAR_TABLE_REF (Vglyphless_char_display, it->c);
28045 if (CONSP (acronym))
28046 acronym = XCAR (acronym);
28047 str = STRINGP (acronym) ? SSDATA (acronym) : "";
28049 else
28051 eassert (it->glyphless_method == GLYPHLESS_DISPLAY_HEX_CODE);
28052 sprintf (buf, "%0*X", it->c < 0x10000 ? 4 : 6, it->c + 0u);
28053 str = buf;
28055 for (len = 0; str[len] && ASCII_CHAR_P (str[len]) && len < 6; len++)
28056 code[len] = font->driver->encode_char (font, str[len]);
28057 upper_len = (len + 1) / 2;
28058 font->driver->text_extents (font, code, upper_len,
28059 &metrics_upper);
28060 font->driver->text_extents (font, code + upper_len, len - upper_len,
28061 &metrics_lower);
28065 /* +4 is for vertical bars of a box plus 1-pixel spaces at both side. */
28066 width = max (metrics_upper.width, metrics_lower.width) + 4;
28067 upper_xoff = upper_yoff = 2; /* the typical case */
28068 if (base_width >= width)
28070 /* Align the upper to the left, the lower to the right. */
28071 it->pixel_width = base_width;
28072 lower_xoff = base_width - 2 - metrics_lower.width;
28074 else
28076 /* Center the shorter one. */
28077 it->pixel_width = width;
28078 if (metrics_upper.width >= metrics_lower.width)
28079 lower_xoff = (width - metrics_lower.width) / 2;
28080 else
28082 /* FIXME: This code doesn't look right. It formerly was
28083 missing the "lower_xoff = 0;", which couldn't have
28084 been right since it left lower_xoff uninitialized. */
28085 lower_xoff = 0;
28086 upper_xoff = (width - metrics_upper.width) / 2;
28090 /* +5 is for horizontal bars of a box plus 1-pixel spaces at
28091 top, bottom, and between upper and lower strings. */
28092 height = (metrics_upper.ascent + metrics_upper.descent
28093 + metrics_lower.ascent + metrics_lower.descent) + 5;
28094 /* Center vertically.
28095 H:base_height, D:base_descent
28096 h:height, ld:lower_descent, la:lower_ascent, ud:upper_descent
28098 ascent = - (D - H/2 - h/2 + 1); "+ 1" for rounding up
28099 descent = D - H/2 + h/2;
28100 lower_yoff = descent - 2 - ld;
28101 upper_yoff = lower_yoff - la - 1 - ud; */
28102 ascent = - (it->descent - (base_height + height + 1) / 2);
28103 descent = it->descent - (base_height - height) / 2;
28104 lower_yoff = descent - 2 - metrics_lower.descent;
28105 upper_yoff = (lower_yoff - metrics_lower.ascent - 1
28106 - metrics_upper.descent);
28107 /* Don't make the height shorter than the base height. */
28108 if (height > base_height)
28110 it->ascent = ascent;
28111 it->descent = descent;
28115 it->phys_ascent = it->ascent;
28116 it->phys_descent = it->descent;
28117 if (it->glyph_row)
28118 append_glyphless_glyph (it, face_id, for_no_font, len,
28119 upper_xoff, upper_yoff,
28120 lower_xoff, lower_yoff);
28121 it->nglyphs = 1;
28122 take_vertical_position_into_account (it);
28126 /* RIF:
28127 Produce glyphs/get display metrics for the display element IT is
28128 loaded with. See the description of struct it in dispextern.h
28129 for an overview of struct it. */
28131 void
28132 x_produce_glyphs (struct it *it)
28134 int extra_line_spacing = it->extra_line_spacing;
28136 it->glyph_not_available_p = false;
28138 if (it->what == IT_CHARACTER)
28140 XChar2b char2b;
28141 struct face *face = FACE_FROM_ID (it->f, it->face_id);
28142 struct font *font = face->font;
28143 struct font_metrics *pcm = NULL;
28144 int boff; /* Baseline offset. */
28146 if (font == NULL)
28148 /* When no suitable font is found, display this character by
28149 the method specified in the first extra slot of
28150 Vglyphless_char_display. */
28151 Lisp_Object acronym = lookup_glyphless_char_display (-1, it);
28153 eassert (it->what == IT_GLYPHLESS);
28154 produce_glyphless_glyph (it, true,
28155 STRINGP (acronym) ? acronym : Qnil);
28156 goto done;
28159 boff = font->baseline_offset;
28160 if (font->vertical_centering)
28161 boff = VCENTER_BASELINE_OFFSET (font, it->f) - boff;
28163 if (it->char_to_display != '\n' && it->char_to_display != '\t')
28165 it->nglyphs = 1;
28167 if (it->override_ascent >= 0)
28169 it->ascent = it->override_ascent;
28170 it->descent = it->override_descent;
28171 boff = it->override_boff;
28173 else
28175 it->ascent = FONT_BASE (font) + boff;
28176 it->descent = FONT_DESCENT (font) - boff;
28179 if (get_char_glyph_code (it->char_to_display, font, &char2b))
28181 pcm = get_per_char_metric (font, &char2b);
28182 if (pcm->width == 0
28183 && pcm->rbearing == 0 && pcm->lbearing == 0)
28184 pcm = NULL;
28187 if (pcm)
28189 it->phys_ascent = pcm->ascent + boff;
28190 it->phys_descent = pcm->descent - boff;
28191 it->pixel_width = pcm->width;
28192 /* Don't use font-global values for ascent and descent
28193 if they result in an exceedingly large line height. */
28194 if (it->override_ascent < 0)
28196 if (FONT_TOO_HIGH (font))
28198 it->ascent = it->phys_ascent;
28199 it->descent = it->phys_descent;
28200 /* These limitations are enforced by an
28201 assertion near the end of this function. */
28202 if (it->ascent < 0)
28203 it->ascent = 0;
28204 if (it->descent < 0)
28205 it->descent = 0;
28209 else
28211 it->glyph_not_available_p = true;
28212 it->phys_ascent = it->ascent;
28213 it->phys_descent = it->descent;
28214 it->pixel_width = font->space_width;
28217 if (it->constrain_row_ascent_descent_p)
28219 if (it->descent > it->max_descent)
28221 it->ascent += it->descent - it->max_descent;
28222 it->descent = it->max_descent;
28224 if (it->ascent > it->max_ascent)
28226 it->descent = min (it->max_descent, it->descent + it->ascent - it->max_ascent);
28227 it->ascent = it->max_ascent;
28229 it->phys_ascent = min (it->phys_ascent, it->ascent);
28230 it->phys_descent = min (it->phys_descent, it->descent);
28231 extra_line_spacing = 0;
28234 /* If this is a space inside a region of text with
28235 `space-width' property, change its width. */
28236 bool stretched_p
28237 = it->char_to_display == ' ' && !NILP (it->space_width);
28238 if (stretched_p)
28239 it->pixel_width *= XFLOATINT (it->space_width);
28241 /* If face has a box, add the box thickness to the character
28242 height. If character has a box line to the left and/or
28243 right, add the box line width to the character's width. */
28244 if (face->box != FACE_NO_BOX)
28246 int thick = face->box_line_width;
28248 if (thick > 0)
28250 it->ascent += thick;
28251 it->descent += thick;
28253 else
28254 thick = -thick;
28256 if (it->start_of_box_run_p)
28257 it->pixel_width += thick;
28258 if (it->end_of_box_run_p)
28259 it->pixel_width += thick;
28262 /* If face has an overline, add the height of the overline
28263 (1 pixel) and a 1 pixel margin to the character height. */
28264 if (face->overline_p)
28265 it->ascent += overline_margin;
28267 if (it->constrain_row_ascent_descent_p)
28269 if (it->ascent > it->max_ascent)
28270 it->ascent = it->max_ascent;
28271 if (it->descent > it->max_descent)
28272 it->descent = it->max_descent;
28275 take_vertical_position_into_account (it);
28277 /* If we have to actually produce glyphs, do it. */
28278 if (it->glyph_row)
28280 if (stretched_p)
28282 /* Translate a space with a `space-width' property
28283 into a stretch glyph. */
28284 int ascent = (((it->ascent + it->descent) * FONT_BASE (font))
28285 / FONT_HEIGHT (font));
28286 append_stretch_glyph (it, it->object, it->pixel_width,
28287 it->ascent + it->descent, ascent);
28289 else
28290 append_glyph (it);
28292 /* If characters with lbearing or rbearing are displayed
28293 in this line, record that fact in a flag of the
28294 glyph row. This is used to optimize X output code. */
28295 if (pcm && (pcm->lbearing < 0 || pcm->rbearing > pcm->width))
28296 it->glyph_row->contains_overlapping_glyphs_p = true;
28298 if (! stretched_p && it->pixel_width == 0)
28299 /* We assure that all visible glyphs have at least 1-pixel
28300 width. */
28301 it->pixel_width = 1;
28303 else if (it->char_to_display == '\n')
28305 /* A newline has no width, but we need the height of the
28306 line. But if previous part of the line sets a height,
28307 don't increase that height. */
28309 Lisp_Object height;
28310 Lisp_Object total_height = Qnil;
28312 it->override_ascent = -1;
28313 it->pixel_width = 0;
28314 it->nglyphs = 0;
28316 height = get_it_property (it, Qline_height);
28317 /* Split (line-height total-height) list. */
28318 if (CONSP (height)
28319 && CONSP (XCDR (height))
28320 && NILP (XCDR (XCDR (height))))
28322 total_height = XCAR (XCDR (height));
28323 height = XCAR (height);
28325 height = calc_line_height_property (it, height, font, boff, true);
28327 if (it->override_ascent >= 0)
28329 it->ascent = it->override_ascent;
28330 it->descent = it->override_descent;
28331 boff = it->override_boff;
28333 else
28335 if (FONT_TOO_HIGH (font))
28337 it->ascent = font->pixel_size + boff - 1;
28338 it->descent = -boff + 1;
28339 if (it->descent < 0)
28340 it->descent = 0;
28342 else
28344 it->ascent = FONT_BASE (font) + boff;
28345 it->descent = FONT_DESCENT (font) - boff;
28349 if (EQ (height, Qt))
28351 if (it->descent > it->max_descent)
28353 it->ascent += it->descent - it->max_descent;
28354 it->descent = it->max_descent;
28356 if (it->ascent > it->max_ascent)
28358 it->descent = min (it->max_descent, it->descent + it->ascent - it->max_ascent);
28359 it->ascent = it->max_ascent;
28361 it->phys_ascent = min (it->phys_ascent, it->ascent);
28362 it->phys_descent = min (it->phys_descent, it->descent);
28363 it->constrain_row_ascent_descent_p = true;
28364 extra_line_spacing = 0;
28366 else
28368 Lisp_Object spacing;
28370 it->phys_ascent = it->ascent;
28371 it->phys_descent = it->descent;
28373 if ((it->max_ascent > 0 || it->max_descent > 0)
28374 && face->box != FACE_NO_BOX
28375 && face->box_line_width > 0)
28377 it->ascent += face->box_line_width;
28378 it->descent += face->box_line_width;
28380 if (!NILP (height)
28381 && XINT (height) > it->ascent + it->descent)
28382 it->ascent = XINT (height) - it->descent;
28384 if (!NILP (total_height))
28385 spacing = calc_line_height_property (it, total_height, font,
28386 boff, false);
28387 else
28389 spacing = get_it_property (it, Qline_spacing);
28390 spacing = calc_line_height_property (it, spacing, font,
28391 boff, false);
28393 if (INTEGERP (spacing))
28395 extra_line_spacing = XINT (spacing);
28396 if (!NILP (total_height))
28397 extra_line_spacing -= (it->phys_ascent + it->phys_descent);
28401 else /* i.e. (it->char_to_display == '\t') */
28403 if (font->space_width > 0)
28405 int tab_width = it->tab_width * font->space_width;
28406 int x = it->current_x + it->continuation_lines_width;
28407 int x0 = x;
28408 /* Adjust for line numbers, if needed. */
28409 if (!NILP (Vdisplay_line_numbers) && it->line_number_produced_p)
28411 x -= it->lnum_pixel_width;
28412 /* Restore the original TAB width, if required. */
28413 if (x + it->tab_offset >= it->first_visible_x)
28414 x += it->tab_offset;
28417 int next_tab_x = ((1 + x + tab_width - 1) / tab_width) * tab_width;
28419 /* If the distance from the current position to the next tab
28420 stop is less than a space character width, use the
28421 tab stop after that. */
28422 if (next_tab_x - x < font->space_width)
28423 next_tab_x += tab_width;
28424 if (!NILP (Vdisplay_line_numbers) && it->line_number_produced_p)
28426 next_tab_x += it->lnum_pixel_width;
28427 /* If the line is hscrolled, and the TAB starts before
28428 the first visible pixel, simulate negative row->x. */
28429 if (x < it->first_visible_x)
28431 next_tab_x -= it->first_visible_x - x;
28432 it->tab_offset = it->first_visible_x - x;
28434 else
28435 next_tab_x -= it->tab_offset;
28438 it->pixel_width = next_tab_x - x0;
28439 it->nglyphs = 1;
28440 if (FONT_TOO_HIGH (font))
28442 if (get_char_glyph_code (' ', font, &char2b))
28444 pcm = get_per_char_metric (font, &char2b);
28445 if (pcm->width == 0
28446 && pcm->rbearing == 0 && pcm->lbearing == 0)
28447 pcm = NULL;
28450 if (pcm)
28452 it->ascent = pcm->ascent + boff;
28453 it->descent = pcm->descent - boff;
28455 else
28457 it->ascent = font->pixel_size + boff - 1;
28458 it->descent = -boff + 1;
28460 if (it->ascent < 0)
28461 it->ascent = 0;
28462 if (it->descent < 0)
28463 it->descent = 0;
28465 else
28467 it->ascent = FONT_BASE (font) + boff;
28468 it->descent = FONT_DESCENT (font) - boff;
28470 it->phys_ascent = it->ascent;
28471 it->phys_descent = it->descent;
28473 if (it->glyph_row)
28475 append_stretch_glyph (it, it->object, it->pixel_width,
28476 it->ascent + it->descent, it->ascent);
28479 else
28481 it->pixel_width = 0;
28482 it->nglyphs = 1;
28486 if (FONT_TOO_HIGH (font))
28488 int font_ascent, font_descent;
28490 /* For very large fonts, where we ignore the declared font
28491 dimensions, and go by per-character metrics instead,
28492 don't let the row ascent and descent values (and the row
28493 height computed from them) be smaller than the "normal"
28494 character metrics. This avoids unpleasant effects
28495 whereby lines on display would change their height
28496 depending on which characters are shown. */
28497 normal_char_ascent_descent (font, -1, &font_ascent, &font_descent);
28498 it->max_ascent = max (it->max_ascent, font_ascent);
28499 it->max_descent = max (it->max_descent, font_descent);
28502 else if (it->what == IT_COMPOSITION && it->cmp_it.ch < 0)
28504 /* A static composition.
28506 Note: A composition is represented as one glyph in the
28507 glyph matrix. There are no padding glyphs.
28509 Important note: pixel_width, ascent, and descent are the
28510 values of what is drawn by draw_glyphs (i.e. the values of
28511 the overall glyphs composed). */
28512 struct face *face = FACE_FROM_ID (it->f, it->face_id);
28513 int boff; /* baseline offset */
28514 struct composition *cmp = composition_table[it->cmp_it.id];
28515 int glyph_len = cmp->glyph_len;
28516 struct font *font = face->font;
28518 it->nglyphs = 1;
28520 /* If we have not yet calculated pixel size data of glyphs of
28521 the composition for the current face font, calculate them
28522 now. Theoretically, we have to check all fonts for the
28523 glyphs, but that requires much time and memory space. So,
28524 here we check only the font of the first glyph. This may
28525 lead to incorrect display, but it's very rare, and C-l
28526 (recenter-top-bottom) can correct the display anyway. */
28527 if (! cmp->font || cmp->font != font)
28529 /* Ascent and descent of the font of the first character
28530 of this composition (adjusted by baseline offset).
28531 Ascent and descent of overall glyphs should not be less
28532 than these, respectively. */
28533 int font_ascent, font_descent, font_height;
28534 /* Bounding box of the overall glyphs. */
28535 int leftmost, rightmost, lowest, highest;
28536 int lbearing, rbearing;
28537 int i, width, ascent, descent;
28538 int c;
28539 XChar2b char2b;
28540 struct font_metrics *pcm;
28541 ptrdiff_t pos;
28543 eassume (0 < glyph_len); /* See Bug#8512. */
28545 c = COMPOSITION_GLYPH (cmp, glyph_len - 1);
28546 while (c == '\t' && 0 < --glyph_len);
28548 bool right_padded = glyph_len < cmp->glyph_len;
28549 for (i = 0; i < glyph_len; i++)
28551 c = COMPOSITION_GLYPH (cmp, i);
28552 if (c != '\t')
28553 break;
28554 cmp->offsets[i * 2] = cmp->offsets[i * 2 + 1] = 0;
28556 bool left_padded = i > 0;
28558 pos = (STRINGP (it->string) ? IT_STRING_CHARPOS (*it)
28559 : IT_CHARPOS (*it));
28560 /* If no suitable font is found, use the default font. */
28561 bool font_not_found_p = font == NULL;
28562 if (font_not_found_p)
28564 face = face->ascii_face;
28565 font = face->font;
28567 boff = font->baseline_offset;
28568 if (font->vertical_centering)
28569 boff = VCENTER_BASELINE_OFFSET (font, it->f) - boff;
28570 normal_char_ascent_descent (font, -1, &font_ascent, &font_descent);
28571 font_ascent += boff;
28572 font_descent -= boff;
28573 font_height = font_ascent + font_descent;
28575 cmp->font = font;
28577 pcm = NULL;
28578 if (! font_not_found_p)
28580 get_char_face_and_encoding (it->f, c, it->face_id,
28581 &char2b, false);
28582 pcm = get_per_char_metric (font, &char2b);
28585 /* Initialize the bounding box. */
28586 if (pcm)
28588 width = cmp->glyph_len > 0 ? pcm->width : 0;
28589 ascent = pcm->ascent;
28590 descent = pcm->descent;
28591 lbearing = pcm->lbearing;
28592 rbearing = pcm->rbearing;
28594 else
28596 width = cmp->glyph_len > 0 ? font->space_width : 0;
28597 ascent = FONT_BASE (font);
28598 descent = FONT_DESCENT (font);
28599 lbearing = 0;
28600 rbearing = width;
28603 rightmost = width;
28604 leftmost = 0;
28605 lowest = - descent + boff;
28606 highest = ascent + boff;
28608 if (! font_not_found_p
28609 && font->default_ascent
28610 && CHAR_TABLE_P (Vuse_default_ascent)
28611 && !NILP (Faref (Vuse_default_ascent,
28612 make_number (it->char_to_display))))
28613 highest = font->default_ascent + boff;
28615 /* Draw the first glyph at the normal position. It may be
28616 shifted to right later if some other glyphs are drawn
28617 at the left. */
28618 cmp->offsets[i * 2] = 0;
28619 cmp->offsets[i * 2 + 1] = boff;
28620 cmp->lbearing = lbearing;
28621 cmp->rbearing = rbearing;
28623 /* Set cmp->offsets for the remaining glyphs. */
28624 for (i++; i < glyph_len; i++)
28626 int left, right, btm, top;
28627 int ch = COMPOSITION_GLYPH (cmp, i);
28628 int face_id;
28629 struct face *this_face;
28631 if (ch == '\t')
28632 ch = ' ';
28633 face_id = FACE_FOR_CHAR (it->f, face, ch, pos, it->string);
28634 this_face = FACE_FROM_ID (it->f, face_id);
28635 font = this_face->font;
28637 if (font == NULL)
28638 pcm = NULL;
28639 else
28641 get_char_face_and_encoding (it->f, ch, face_id,
28642 &char2b, false);
28643 pcm = get_per_char_metric (font, &char2b);
28645 if (! pcm)
28646 cmp->offsets[i * 2] = cmp->offsets[i * 2 + 1] = 0;
28647 else
28649 width = pcm->width;
28650 ascent = pcm->ascent;
28651 descent = pcm->descent;
28652 lbearing = pcm->lbearing;
28653 rbearing = pcm->rbearing;
28654 if (cmp->method != COMPOSITION_WITH_RULE_ALTCHARS)
28656 /* Relative composition with or without
28657 alternate chars. */
28658 left = (leftmost + rightmost - width) / 2;
28659 btm = - descent + boff;
28660 if (font->relative_compose
28661 && (! CHAR_TABLE_P (Vignore_relative_composition)
28662 || NILP (Faref (Vignore_relative_composition,
28663 make_number (ch)))))
28666 if (- descent >= font->relative_compose)
28667 /* One extra pixel between two glyphs. */
28668 btm = highest + 1;
28669 else if (ascent <= 0)
28670 /* One extra pixel between two glyphs. */
28671 btm = lowest - 1 - ascent - descent;
28674 else
28676 /* A composition rule is specified by an integer
28677 value that encodes global and new reference
28678 points (GREF and NREF). GREF and NREF are
28679 specified by numbers as below:
28681 0---1---2 -- ascent
28685 9--10--11 -- center
28687 ---3---4---5--- baseline
28689 6---7---8 -- descent
28691 int rule = COMPOSITION_RULE (cmp, i);
28692 int gref, nref, grefx, grefy, nrefx, nrefy, xoff, yoff;
28694 COMPOSITION_DECODE_RULE (rule, gref, nref, xoff, yoff);
28695 grefx = gref % 3, nrefx = nref % 3;
28696 grefy = gref / 3, nrefy = nref / 3;
28697 if (xoff)
28698 xoff = font_height * (xoff - 128) / 256;
28699 if (yoff)
28700 yoff = font_height * (yoff - 128) / 256;
28702 left = (leftmost
28703 + grefx * (rightmost - leftmost) / 2
28704 - nrefx * width / 2
28705 + xoff);
28707 btm = ((grefy == 0 ? highest
28708 : grefy == 1 ? 0
28709 : grefy == 2 ? lowest
28710 : (highest + lowest) / 2)
28711 - (nrefy == 0 ? ascent + descent
28712 : nrefy == 1 ? descent - boff
28713 : nrefy == 2 ? 0
28714 : (ascent + descent) / 2)
28715 + yoff);
28718 cmp->offsets[i * 2] = left;
28719 cmp->offsets[i * 2 + 1] = btm + descent;
28721 /* Update the bounding box of the overall glyphs. */
28722 if (width > 0)
28724 right = left + width;
28725 if (left < leftmost)
28726 leftmost = left;
28727 if (right > rightmost)
28728 rightmost = right;
28730 top = btm + descent + ascent;
28731 if (top > highest)
28732 highest = top;
28733 if (btm < lowest)
28734 lowest = btm;
28736 if (cmp->lbearing > left + lbearing)
28737 cmp->lbearing = left + lbearing;
28738 if (cmp->rbearing < left + rbearing)
28739 cmp->rbearing = left + rbearing;
28743 /* If there are glyphs whose x-offsets are negative,
28744 shift all glyphs to the right and make all x-offsets
28745 non-negative. */
28746 if (leftmost < 0)
28748 for (i = 0; i < cmp->glyph_len; i++)
28749 cmp->offsets[i * 2] -= leftmost;
28750 rightmost -= leftmost;
28751 cmp->lbearing -= leftmost;
28752 cmp->rbearing -= leftmost;
28755 if (left_padded && cmp->lbearing < 0)
28757 for (i = 0; i < cmp->glyph_len; i++)
28758 cmp->offsets[i * 2] -= cmp->lbearing;
28759 rightmost -= cmp->lbearing;
28760 cmp->rbearing -= cmp->lbearing;
28761 cmp->lbearing = 0;
28763 if (right_padded && rightmost < cmp->rbearing)
28765 rightmost = cmp->rbearing;
28768 cmp->pixel_width = rightmost;
28769 cmp->ascent = highest;
28770 cmp->descent = - lowest;
28771 if (cmp->ascent < font_ascent)
28772 cmp->ascent = font_ascent;
28773 if (cmp->descent < font_descent)
28774 cmp->descent = font_descent;
28777 if (it->glyph_row
28778 && (cmp->lbearing < 0
28779 || cmp->rbearing > cmp->pixel_width))
28780 it->glyph_row->contains_overlapping_glyphs_p = true;
28782 it->pixel_width = cmp->pixel_width;
28783 it->ascent = it->phys_ascent = cmp->ascent;
28784 it->descent = it->phys_descent = cmp->descent;
28785 if (face->box != FACE_NO_BOX)
28787 int thick = face->box_line_width;
28789 if (thick > 0)
28791 it->ascent += thick;
28792 it->descent += thick;
28794 else
28795 thick = - thick;
28797 if (it->start_of_box_run_p)
28798 it->pixel_width += thick;
28799 if (it->end_of_box_run_p)
28800 it->pixel_width += thick;
28803 /* If face has an overline, add the height of the overline
28804 (1 pixel) and a 1 pixel margin to the character height. */
28805 if (face->overline_p)
28806 it->ascent += overline_margin;
28808 take_vertical_position_into_account (it);
28809 if (it->ascent < 0)
28810 it->ascent = 0;
28811 if (it->descent < 0)
28812 it->descent = 0;
28814 if (it->glyph_row && cmp->glyph_len > 0)
28815 append_composite_glyph (it);
28817 else if (it->what == IT_COMPOSITION)
28819 /* A dynamic (automatic) composition. */
28820 struct face *face = FACE_FROM_ID (it->f, it->face_id);
28821 Lisp_Object gstring;
28822 struct font_metrics metrics;
28824 it->nglyphs = 1;
28826 gstring = composition_gstring_from_id (it->cmp_it.id);
28827 it->pixel_width
28828 = composition_gstring_width (gstring, it->cmp_it.from, it->cmp_it.to,
28829 &metrics);
28830 if (it->glyph_row
28831 && (metrics.lbearing < 0 || metrics.rbearing > metrics.width))
28832 it->glyph_row->contains_overlapping_glyphs_p = true;
28833 it->ascent = it->phys_ascent = metrics.ascent;
28834 it->descent = it->phys_descent = metrics.descent;
28835 if (face->box != FACE_NO_BOX)
28837 int thick = face->box_line_width;
28839 if (thick > 0)
28841 it->ascent += thick;
28842 it->descent += thick;
28844 else
28845 thick = - thick;
28847 if (it->start_of_box_run_p)
28848 it->pixel_width += thick;
28849 if (it->end_of_box_run_p)
28850 it->pixel_width += thick;
28852 /* If face has an overline, add the height of the overline
28853 (1 pixel) and a 1 pixel margin to the character height. */
28854 if (face->overline_p)
28855 it->ascent += overline_margin;
28856 take_vertical_position_into_account (it);
28857 if (it->ascent < 0)
28858 it->ascent = 0;
28859 if (it->descent < 0)
28860 it->descent = 0;
28862 if (it->glyph_row)
28863 append_composite_glyph (it);
28865 else if (it->what == IT_GLYPHLESS)
28866 produce_glyphless_glyph (it, false, Qnil);
28867 else if (it->what == IT_IMAGE)
28868 produce_image_glyph (it);
28869 else if (it->what == IT_STRETCH)
28870 produce_stretch_glyph (it);
28871 else if (it->what == IT_XWIDGET)
28872 produce_xwidget_glyph (it);
28874 done:
28875 /* Accumulate dimensions. Note: can't assume that it->descent > 0
28876 because this isn't true for images with `:ascent 100'. */
28877 eassert (it->ascent >= 0 && it->descent >= 0);
28878 if (it->area == TEXT_AREA)
28879 it->current_x += it->pixel_width;
28881 if (extra_line_spacing > 0)
28883 it->descent += extra_line_spacing;
28884 if (extra_line_spacing > it->max_extra_line_spacing)
28885 it->max_extra_line_spacing = extra_line_spacing;
28888 it->max_ascent = max (it->max_ascent, it->ascent);
28889 it->max_descent = max (it->max_descent, it->descent);
28890 it->max_phys_ascent = max (it->max_phys_ascent, it->phys_ascent);
28891 it->max_phys_descent = max (it->max_phys_descent, it->phys_descent);
28894 /* EXPORT for RIF:
28895 Output LEN glyphs starting at START at the nominal cursor position.
28896 Advance the nominal cursor over the text. UPDATED_ROW is the glyph row
28897 being updated, and UPDATED_AREA is the area of that row being updated. */
28899 void
28900 x_write_glyphs (struct window *w, struct glyph_row *updated_row,
28901 struct glyph *start, enum glyph_row_area updated_area, int len)
28903 int x, hpos, chpos = w->phys_cursor.hpos;
28905 eassert (updated_row);
28906 /* When the window is hscrolled, cursor hpos can legitimately be out
28907 of bounds, but we draw the cursor at the corresponding window
28908 margin in that case. */
28909 if (!updated_row->reversed_p && chpos < 0)
28910 chpos = 0;
28911 if (updated_row->reversed_p && chpos >= updated_row->used[TEXT_AREA])
28912 chpos = updated_row->used[TEXT_AREA] - 1;
28914 block_input ();
28916 /* Write glyphs. */
28918 hpos = start - updated_row->glyphs[updated_area];
28919 x = draw_glyphs (w, w->output_cursor.x,
28920 updated_row, updated_area,
28921 hpos, hpos + len,
28922 DRAW_NORMAL_TEXT, 0);
28924 /* Invalidate old phys cursor if the glyph at its hpos is redrawn. */
28925 if (updated_area == TEXT_AREA
28926 && w->phys_cursor_on_p
28927 && w->phys_cursor.vpos == w->output_cursor.vpos
28928 && chpos >= hpos
28929 && chpos < hpos + len)
28930 w->phys_cursor_on_p = false;
28932 unblock_input ();
28934 /* Advance the output cursor. */
28935 w->output_cursor.hpos += len;
28936 w->output_cursor.x = x;
28940 /* EXPORT for RIF:
28941 Insert LEN glyphs from START at the nominal cursor position. */
28943 void
28944 x_insert_glyphs (struct window *w, struct glyph_row *updated_row,
28945 struct glyph *start, enum glyph_row_area updated_area, int len)
28947 struct frame *f;
28948 int line_height, shift_by_width, shifted_region_width;
28949 struct glyph_row *row;
28950 struct glyph *glyph;
28951 int frame_x, frame_y;
28952 ptrdiff_t hpos;
28954 eassert (updated_row);
28955 block_input ();
28956 f = XFRAME (WINDOW_FRAME (w));
28958 /* Get the height of the line we are in. */
28959 row = updated_row;
28960 line_height = row->height;
28962 /* Get the width of the glyphs to insert. */
28963 shift_by_width = 0;
28964 for (glyph = start; glyph < start + len; ++glyph)
28965 shift_by_width += glyph->pixel_width;
28967 /* Get the width of the region to shift right. */
28968 shifted_region_width = (window_box_width (w, updated_area)
28969 - w->output_cursor.x
28970 - shift_by_width);
28972 /* Shift right. */
28973 frame_x = window_box_left (w, updated_area) + w->output_cursor.x;
28974 frame_y = WINDOW_TO_FRAME_PIXEL_Y (w, w->output_cursor.y);
28976 FRAME_RIF (f)->shift_glyphs_for_insert (f, frame_x, frame_y, shifted_region_width,
28977 line_height, shift_by_width);
28979 /* Write the glyphs. */
28980 hpos = start - row->glyphs[updated_area];
28981 draw_glyphs (w, w->output_cursor.x, row, updated_area,
28982 hpos, hpos + len,
28983 DRAW_NORMAL_TEXT, 0);
28985 /* Advance the output cursor. */
28986 w->output_cursor.hpos += len;
28987 w->output_cursor.x += shift_by_width;
28988 unblock_input ();
28992 /* EXPORT for RIF:
28993 Erase the current text line from the nominal cursor position
28994 (inclusive) to pixel column TO_X (exclusive). The idea is that
28995 everything from TO_X onward is already erased.
28997 TO_X is a pixel position relative to UPDATED_AREA of currently
28998 updated window W. TO_X == -1 means clear to the end of this area. */
29000 void
29001 x_clear_end_of_line (struct window *w, struct glyph_row *updated_row,
29002 enum glyph_row_area updated_area, int to_x)
29004 struct frame *f;
29005 int max_x, min_y, max_y;
29006 int from_x, from_y, to_y;
29008 eassert (updated_row);
29009 f = XFRAME (w->frame);
29011 if (updated_row->full_width_p)
29012 max_x = (WINDOW_PIXEL_WIDTH (w)
29013 - (updated_row->mode_line_p ? WINDOW_RIGHT_DIVIDER_WIDTH (w) : 0));
29014 else
29015 max_x = window_box_width (w, updated_area);
29016 max_y = window_text_bottom_y (w);
29018 /* TO_X == 0 means don't do anything. TO_X < 0 means clear to end
29019 of window. For TO_X > 0, truncate to end of drawing area. */
29020 if (to_x == 0)
29021 return;
29022 else if (to_x < 0)
29023 to_x = max_x;
29024 else
29025 to_x = min (to_x, max_x);
29027 to_y = min (max_y, w->output_cursor.y + updated_row->height);
29029 /* Notice if the cursor will be cleared by this operation. */
29030 if (!updated_row->full_width_p)
29031 notice_overwritten_cursor (w, updated_area,
29032 w->output_cursor.x, -1,
29033 updated_row->y,
29034 MATRIX_ROW_BOTTOM_Y (updated_row));
29036 from_x = w->output_cursor.x;
29038 /* Translate to frame coordinates. */
29039 if (updated_row->full_width_p)
29041 from_x = WINDOW_TO_FRAME_PIXEL_X (w, from_x);
29042 to_x = WINDOW_TO_FRAME_PIXEL_X (w, to_x);
29044 else
29046 int area_left = window_box_left (w, updated_area);
29047 from_x += area_left;
29048 to_x += area_left;
29051 min_y = WINDOW_HEADER_LINE_HEIGHT (w);
29052 from_y = WINDOW_TO_FRAME_PIXEL_Y (w, max (min_y, w->output_cursor.y));
29053 to_y = WINDOW_TO_FRAME_PIXEL_Y (w, to_y);
29055 /* Prevent inadvertently clearing to end of the X window. */
29056 if (to_x > from_x && to_y > from_y)
29058 block_input ();
29059 FRAME_RIF (f)->clear_frame_area (f, from_x, from_y,
29060 to_x - from_x, to_y - from_y);
29061 unblock_input ();
29065 #endif /* HAVE_WINDOW_SYSTEM */
29069 /***********************************************************************
29070 Cursor types
29071 ***********************************************************************/
29073 /* Value is the internal representation of the specified cursor type
29074 ARG. If type is BAR_CURSOR, return in *WIDTH the specified width
29075 of the bar cursor. */
29077 static enum text_cursor_kinds
29078 get_specified_cursor_type (Lisp_Object arg, int *width)
29080 enum text_cursor_kinds type;
29082 if (NILP (arg))
29083 return NO_CURSOR;
29085 if (EQ (arg, Qbox))
29086 return FILLED_BOX_CURSOR;
29088 if (EQ (arg, Qhollow))
29089 return HOLLOW_BOX_CURSOR;
29091 if (EQ (arg, Qbar))
29093 *width = 2;
29094 return BAR_CURSOR;
29097 if (CONSP (arg)
29098 && EQ (XCAR (arg), Qbar)
29099 && RANGED_INTEGERP (0, XCDR (arg), INT_MAX))
29101 *width = XINT (XCDR (arg));
29102 return BAR_CURSOR;
29105 if (EQ (arg, Qhbar))
29107 *width = 2;
29108 return HBAR_CURSOR;
29111 if (CONSP (arg)
29112 && EQ (XCAR (arg), Qhbar)
29113 && RANGED_INTEGERP (0, XCDR (arg), INT_MAX))
29115 *width = XINT (XCDR (arg));
29116 return HBAR_CURSOR;
29119 /* Treat anything unknown as "hollow box cursor".
29120 It was bad to signal an error; people have trouble fixing
29121 .Xdefaults with Emacs, when it has something bad in it. */
29122 type = HOLLOW_BOX_CURSOR;
29124 return type;
29127 /* Set the default cursor types for specified frame. */
29128 void
29129 set_frame_cursor_types (struct frame *f, Lisp_Object arg)
29131 int width = 1;
29132 Lisp_Object tem;
29134 FRAME_DESIRED_CURSOR (f) = get_specified_cursor_type (arg, &width);
29135 FRAME_CURSOR_WIDTH (f) = width;
29137 /* By default, set up the blink-off state depending on the on-state. */
29139 tem = Fassoc (arg, Vblink_cursor_alist, Qnil);
29140 if (!NILP (tem))
29142 FRAME_BLINK_OFF_CURSOR (f)
29143 = get_specified_cursor_type (XCDR (tem), &width);
29144 FRAME_BLINK_OFF_CURSOR_WIDTH (f) = width;
29146 else
29147 FRAME_BLINK_OFF_CURSOR (f) = DEFAULT_CURSOR;
29149 /* Make sure the cursor gets redrawn. */
29150 f->cursor_type_changed = true;
29154 #ifdef HAVE_WINDOW_SYSTEM
29156 /* Return the cursor we want to be displayed in window W. Return
29157 width of bar/hbar cursor through WIDTH arg. Return with
29158 ACTIVE_CURSOR arg set to true if cursor in window W is `active'
29159 (i.e. if the `system caret' should track this cursor).
29161 In a mini-buffer window, we want the cursor only to appear if we
29162 are reading input from this window. For the selected window, we
29163 want the cursor type given by the frame parameter or buffer local
29164 setting of cursor-type. If explicitly marked off, draw no cursor.
29165 In all other cases, we want a hollow box cursor. */
29167 static enum text_cursor_kinds
29168 get_window_cursor_type (struct window *w, struct glyph *glyph, int *width,
29169 bool *active_cursor)
29171 struct frame *f = XFRAME (w->frame);
29172 struct buffer *b = XBUFFER (w->contents);
29173 int cursor_type = DEFAULT_CURSOR;
29174 Lisp_Object alt_cursor;
29175 bool non_selected = false;
29177 *active_cursor = true;
29179 /* Echo area */
29180 if (cursor_in_echo_area
29181 && FRAME_HAS_MINIBUF_P (f)
29182 && EQ (FRAME_MINIBUF_WINDOW (f), echo_area_window))
29184 if (w == XWINDOW (echo_area_window))
29186 if (EQ (BVAR (b, cursor_type), Qt) || NILP (BVAR (b, cursor_type)))
29188 *width = FRAME_CURSOR_WIDTH (f);
29189 return FRAME_DESIRED_CURSOR (f);
29191 else
29192 return get_specified_cursor_type (BVAR (b, cursor_type), width);
29195 *active_cursor = false;
29196 non_selected = true;
29199 /* Detect a nonselected window or nonselected frame. */
29200 else if (w != XWINDOW (f->selected_window)
29201 || f != FRAME_DISPLAY_INFO (f)->x_highlight_frame)
29203 *active_cursor = false;
29205 if (MINI_WINDOW_P (w) && minibuf_level == 0)
29206 return NO_CURSOR;
29208 non_selected = true;
29211 /* Never display a cursor in a window in which cursor-type is nil. */
29212 if (NILP (BVAR (b, cursor_type)))
29213 return NO_CURSOR;
29215 /* Get the normal cursor type for this window. */
29216 if (EQ (BVAR (b, cursor_type), Qt))
29218 cursor_type = FRAME_DESIRED_CURSOR (f);
29219 *width = FRAME_CURSOR_WIDTH (f);
29221 else
29222 cursor_type = get_specified_cursor_type (BVAR (b, cursor_type), width);
29224 /* Use cursor-in-non-selected-windows instead
29225 for non-selected window or frame. */
29226 if (non_selected)
29228 alt_cursor = BVAR (b, cursor_in_non_selected_windows);
29229 if (!EQ (Qt, alt_cursor))
29230 return get_specified_cursor_type (alt_cursor, width);
29231 /* t means modify the normal cursor type. */
29232 if (cursor_type == FILLED_BOX_CURSOR)
29233 cursor_type = HOLLOW_BOX_CURSOR;
29234 else if (cursor_type == BAR_CURSOR && *width > 1)
29235 --*width;
29236 return cursor_type;
29239 /* Use normal cursor if not blinked off. */
29240 if (!w->cursor_off_p)
29242 if (glyph != NULL && glyph->type == XWIDGET_GLYPH)
29243 return NO_CURSOR;
29244 if (glyph != NULL && glyph->type == IMAGE_GLYPH)
29246 if (cursor_type == FILLED_BOX_CURSOR)
29248 /* Using a block cursor on large images can be very annoying.
29249 So use a hollow cursor for "large" images.
29250 If image is not transparent (no mask), also use hollow cursor. */
29251 struct image *img = IMAGE_OPT_FROM_ID (f, glyph->u.img_id);
29252 if (img != NULL && IMAGEP (img->spec))
29254 /* Arbitrarily, interpret "Large" as >32x32 and >NxN
29255 where N = size of default frame font size.
29256 This should cover most of the "tiny" icons people may use. */
29257 if (!img->mask
29258 || img->width > max (32, WINDOW_FRAME_COLUMN_WIDTH (w))
29259 || img->height > max (32, WINDOW_FRAME_LINE_HEIGHT (w)))
29260 cursor_type = HOLLOW_BOX_CURSOR;
29263 else if (cursor_type != NO_CURSOR)
29265 /* Display current only supports BOX and HOLLOW cursors for images.
29266 So for now, unconditionally use a HOLLOW cursor when cursor is
29267 not a solid box cursor. */
29268 cursor_type = HOLLOW_BOX_CURSOR;
29271 return cursor_type;
29274 /* Cursor is blinked off, so determine how to "toggle" it. */
29276 /* First look for an entry matching the buffer's cursor-type in blink-cursor-alist. */
29277 if ((alt_cursor = Fassoc (BVAR (b, cursor_type), Vblink_cursor_alist, Qnil), !NILP (alt_cursor)))
29278 return get_specified_cursor_type (XCDR (alt_cursor), width);
29280 /* Then see if frame has specified a specific blink off cursor type. */
29281 if (FRAME_BLINK_OFF_CURSOR (f) != DEFAULT_CURSOR)
29283 *width = FRAME_BLINK_OFF_CURSOR_WIDTH (f);
29284 return FRAME_BLINK_OFF_CURSOR (f);
29287 #if false
29288 /* Some people liked having a permanently visible blinking cursor,
29289 while others had very strong opinions against it. So it was
29290 decided to remove it. KFS 2003-09-03 */
29292 /* Finally perform built-in cursor blinking:
29293 filled box <-> hollow box
29294 wide [h]bar <-> narrow [h]bar
29295 narrow [h]bar <-> no cursor
29296 other type <-> no cursor */
29298 if (cursor_type == FILLED_BOX_CURSOR)
29299 return HOLLOW_BOX_CURSOR;
29301 if ((cursor_type == BAR_CURSOR || cursor_type == HBAR_CURSOR) && *width > 1)
29303 *width = 1;
29304 return cursor_type;
29306 #endif
29308 return NO_CURSOR;
29312 /* Notice when the text cursor of window W has been completely
29313 overwritten by a drawing operation that outputs glyphs in AREA
29314 starting at X0 and ending at X1 in the line starting at Y0 and
29315 ending at Y1. X coordinates are area-relative. X1 < 0 means all
29316 the rest of the line after X0 has been written. Y coordinates
29317 are window-relative. */
29319 static void
29320 notice_overwritten_cursor (struct window *w, enum glyph_row_area area,
29321 int x0, int x1, int y0, int y1)
29323 int cx0, cx1, cy0, cy1;
29324 struct glyph_row *row;
29326 if (!w->phys_cursor_on_p)
29327 return;
29328 if (area != TEXT_AREA)
29329 return;
29331 if (w->phys_cursor.vpos < 0
29332 || w->phys_cursor.vpos >= w->current_matrix->nrows
29333 || (row = w->current_matrix->rows + w->phys_cursor.vpos,
29334 !(row->enabled_p && MATRIX_ROW_DISPLAYS_TEXT_P (row))))
29335 return;
29337 if (row->cursor_in_fringe_p)
29339 row->cursor_in_fringe_p = false;
29340 draw_fringe_bitmap (w, row, row->reversed_p);
29341 w->phys_cursor_on_p = false;
29342 return;
29345 cx0 = w->phys_cursor.x;
29346 cx1 = cx0 + w->phys_cursor_width;
29347 if (x0 > cx0 || (x1 >= 0 && x1 < cx1))
29348 return;
29350 /* The cursor image will be completely removed from the
29351 screen if the output area intersects the cursor area in
29352 y-direction. When we draw in [y0 y1[, and some part of
29353 the cursor is at y < y0, that part must have been drawn
29354 before. When scrolling, the cursor is erased before
29355 actually scrolling, so we don't come here. When not
29356 scrolling, the rows above the old cursor row must have
29357 changed, and in this case these rows must have written
29358 over the cursor image.
29360 Likewise if part of the cursor is below y1, with the
29361 exception of the cursor being in the first blank row at
29362 the buffer and window end because update_text_area
29363 doesn't draw that row. (Except when it does, but
29364 that's handled in update_text_area.) */
29366 cy0 = w->phys_cursor.y;
29367 cy1 = cy0 + w->phys_cursor_height;
29368 if ((y0 < cy0 || y0 >= cy1) && (y1 <= cy0 || y1 >= cy1))
29369 return;
29371 w->phys_cursor_on_p = false;
29374 #endif /* HAVE_WINDOW_SYSTEM */
29377 /************************************************************************
29378 Mouse Face
29379 ************************************************************************/
29381 #ifdef HAVE_WINDOW_SYSTEM
29383 /* EXPORT for RIF:
29384 Fix the display of area AREA of overlapping row ROW in window W
29385 with respect to the overlapping part OVERLAPS. */
29387 void
29388 x_fix_overlapping_area (struct window *w, struct glyph_row *row,
29389 enum glyph_row_area area, int overlaps)
29391 int i, x;
29393 block_input ();
29395 x = 0;
29396 for (i = 0; i < row->used[area];)
29398 if (row->glyphs[area][i].overlaps_vertically_p)
29400 int start = i, start_x = x;
29404 x += row->glyphs[area][i].pixel_width;
29405 ++i;
29407 while (i < row->used[area]
29408 && row->glyphs[area][i].overlaps_vertically_p);
29410 draw_glyphs (w, start_x, row, area,
29411 start, i,
29412 DRAW_NORMAL_TEXT, overlaps);
29414 else
29416 x += row->glyphs[area][i].pixel_width;
29417 ++i;
29421 unblock_input ();
29425 /* EXPORT:
29426 Draw the cursor glyph of window W in glyph row ROW. See the
29427 comment of draw_glyphs for the meaning of HL. */
29429 void
29430 draw_phys_cursor_glyph (struct window *w, struct glyph_row *row,
29431 enum draw_glyphs_face hl)
29433 /* If cursor hpos is out of bounds, don't draw garbage. This can
29434 happen in mini-buffer windows when switching between echo area
29435 glyphs and mini-buffer. */
29436 if ((row->reversed_p
29437 ? (w->phys_cursor.hpos >= 0)
29438 : (w->phys_cursor.hpos < row->used[TEXT_AREA])))
29440 bool on_p = w->phys_cursor_on_p;
29441 int x1;
29442 int hpos = w->phys_cursor.hpos;
29444 /* When the window is hscrolled, cursor hpos can legitimately be
29445 out of bounds, but we draw the cursor at the corresponding
29446 window margin in that case. */
29447 if (!row->reversed_p && hpos < 0)
29448 hpos = 0;
29449 if (row->reversed_p && hpos >= row->used[TEXT_AREA])
29450 hpos = row->used[TEXT_AREA] - 1;
29452 x1 = draw_glyphs (w, w->phys_cursor.x, row, TEXT_AREA, hpos, hpos + 1,
29453 hl, 0);
29454 w->phys_cursor_on_p = on_p;
29456 if (hl == DRAW_CURSOR)
29457 w->phys_cursor_width = x1 - w->phys_cursor.x;
29458 /* When we erase the cursor, and ROW is overlapped by other
29459 rows, make sure that these overlapping parts of other rows
29460 are redrawn. */
29461 else if (hl == DRAW_NORMAL_TEXT && row->overlapped_p)
29463 w->phys_cursor_width = x1 - w->phys_cursor.x;
29465 if (row > w->current_matrix->rows
29466 && MATRIX_ROW_OVERLAPS_SUCC_P (row - 1))
29467 x_fix_overlapping_area (w, row - 1, TEXT_AREA,
29468 OVERLAPS_ERASED_CURSOR);
29470 if (MATRIX_ROW_BOTTOM_Y (row) < window_text_bottom_y (w)
29471 && MATRIX_ROW_OVERLAPS_PRED_P (row + 1))
29472 x_fix_overlapping_area (w, row + 1, TEXT_AREA,
29473 OVERLAPS_ERASED_CURSOR);
29479 /* Erase the image of a cursor of window W from the screen. */
29481 void
29482 erase_phys_cursor (struct window *w)
29484 struct frame *f = XFRAME (w->frame);
29485 Mouse_HLInfo *hlinfo = MOUSE_HL_INFO (f);
29486 int hpos = w->phys_cursor.hpos;
29487 int vpos = w->phys_cursor.vpos;
29488 bool mouse_face_here_p = false;
29489 struct glyph_matrix *active_glyphs = w->current_matrix;
29490 struct glyph_row *cursor_row;
29491 struct glyph *cursor_glyph;
29492 enum draw_glyphs_face hl;
29494 /* No cursor displayed or row invalidated => nothing to do on the
29495 screen. */
29496 if (w->phys_cursor_type == NO_CURSOR)
29497 goto mark_cursor_off;
29499 /* VPOS >= active_glyphs->nrows means that window has been resized.
29500 Don't bother to erase the cursor. */
29501 if (vpos >= active_glyphs->nrows)
29502 goto mark_cursor_off;
29504 /* If row containing cursor is marked invalid, there is nothing we
29505 can do. */
29506 cursor_row = MATRIX_ROW (active_glyphs, vpos);
29507 if (!cursor_row->enabled_p)
29508 goto mark_cursor_off;
29510 /* If line spacing is > 0, old cursor may only be partially visible in
29511 window after split-window. So adjust visible height. */
29512 cursor_row->visible_height = min (cursor_row->visible_height,
29513 window_text_bottom_y (w) - cursor_row->y);
29515 /* If row is completely invisible, don't attempt to delete a cursor which
29516 isn't there. This can happen if cursor is at top of a window, and
29517 we switch to a buffer with a header line in that window. */
29518 if (cursor_row->visible_height <= 0)
29519 goto mark_cursor_off;
29521 /* If cursor is in the fringe, erase by drawing actual bitmap there. */
29522 if (cursor_row->cursor_in_fringe_p)
29524 cursor_row->cursor_in_fringe_p = false;
29525 draw_fringe_bitmap (w, cursor_row, cursor_row->reversed_p);
29526 goto mark_cursor_off;
29529 /* This can happen when the new row is shorter than the old one.
29530 In this case, either draw_glyphs or clear_end_of_line
29531 should have cleared the cursor. Note that we wouldn't be
29532 able to erase the cursor in this case because we don't have a
29533 cursor glyph at hand. */
29534 if ((cursor_row->reversed_p
29535 ? (w->phys_cursor.hpos < 0)
29536 : (w->phys_cursor.hpos >= cursor_row->used[TEXT_AREA])))
29537 goto mark_cursor_off;
29539 /* When the window is hscrolled, cursor hpos can legitimately be out
29540 of bounds, but we draw the cursor at the corresponding window
29541 margin in that case. */
29542 if (!cursor_row->reversed_p && hpos < 0)
29543 hpos = 0;
29544 if (cursor_row->reversed_p && hpos >= cursor_row->used[TEXT_AREA])
29545 hpos = cursor_row->used[TEXT_AREA] - 1;
29547 /* If the cursor is in the mouse face area, redisplay that when
29548 we clear the cursor. */
29549 if (! NILP (hlinfo->mouse_face_window)
29550 && coords_in_mouse_face_p (w, hpos, vpos)
29551 /* Don't redraw the cursor's spot in mouse face if it is at the
29552 end of a line (on a newline). The cursor appears there, but
29553 mouse highlighting does not. */
29554 && cursor_row->used[TEXT_AREA] > hpos && hpos >= 0)
29555 mouse_face_here_p = true;
29557 /* Maybe clear the display under the cursor. */
29558 if (w->phys_cursor_type == HOLLOW_BOX_CURSOR)
29560 int x, y;
29561 int header_line_height = WINDOW_HEADER_LINE_HEIGHT (w);
29562 int width;
29564 cursor_glyph = get_phys_cursor_glyph (w);
29565 if (cursor_glyph == NULL)
29566 goto mark_cursor_off;
29568 width = cursor_glyph->pixel_width;
29569 x = w->phys_cursor.x;
29570 if (x < 0)
29572 width += x;
29573 x = 0;
29575 width = min (width, window_box_width (w, TEXT_AREA) - x);
29576 y = WINDOW_TO_FRAME_PIXEL_Y (w, max (header_line_height, cursor_row->y));
29577 x = WINDOW_TEXT_TO_FRAME_PIXEL_X (w, x);
29579 if (width > 0)
29580 FRAME_RIF (f)->clear_frame_area (f, x, y, width, cursor_row->visible_height);
29583 /* Erase the cursor by redrawing the character underneath it. */
29584 if (mouse_face_here_p)
29585 hl = DRAW_MOUSE_FACE;
29586 else
29587 hl = DRAW_NORMAL_TEXT;
29588 draw_phys_cursor_glyph (w, cursor_row, hl);
29590 mark_cursor_off:
29591 w->phys_cursor_on_p = false;
29592 w->phys_cursor_type = NO_CURSOR;
29596 /* Display or clear cursor of window W. If !ON, clear the cursor.
29597 If ON, display the cursor; where to put the cursor is specified by
29598 HPOS, VPOS, X and Y. */
29600 void
29601 display_and_set_cursor (struct window *w, bool on,
29602 int hpos, int vpos, int x, int y)
29604 struct frame *f = XFRAME (w->frame);
29605 int new_cursor_type;
29606 int new_cursor_width;
29607 bool active_cursor;
29608 struct glyph_row *glyph_row;
29609 struct glyph *glyph;
29611 /* This is pointless on invisible frames, and dangerous on garbaged
29612 windows and frames; in the latter case, the frame or window may
29613 be in the midst of changing its size, and x and y may be off the
29614 window. */
29615 if (! FRAME_VISIBLE_P (f)
29616 || vpos >= w->current_matrix->nrows
29617 || hpos >= w->current_matrix->matrix_w)
29618 return;
29620 /* If cursor is off and we want it off, return quickly. */
29621 if (!on && !w->phys_cursor_on_p)
29622 return;
29624 glyph_row = MATRIX_ROW (w->current_matrix, vpos);
29625 /* If cursor row is not enabled, we don't really know where to
29626 display the cursor. */
29627 if (!glyph_row->enabled_p)
29629 w->phys_cursor_on_p = false;
29630 return;
29633 /* A frame might be marked garbaged even though its cursor position
29634 is correct, and will not change upon subsequent redisplay. This
29635 happens in some rare situations, like toggling the sort order in
29636 Dired windows. We've already established that VPOS is valid, so
29637 it shouldn't do any harm to record the cursor position, as we are
29638 going to return without acting on it anyway. Otherwise, expose
29639 events might come in and call update_window_cursor, which will
29640 blindly use outdated values in w->phys_cursor. */
29641 if (FRAME_GARBAGED_P (f))
29643 if (on)
29645 w->phys_cursor.x = x;
29646 w->phys_cursor.y = glyph_row->y;
29647 w->phys_cursor.hpos = hpos;
29648 w->phys_cursor.vpos = vpos;
29650 return;
29653 glyph = NULL;
29654 if (0 <= hpos && hpos < glyph_row->used[TEXT_AREA])
29655 glyph = glyph_row->glyphs[TEXT_AREA] + hpos;
29657 eassert (input_blocked_p ());
29659 /* Set new_cursor_type to the cursor we want to be displayed. */
29660 new_cursor_type = get_window_cursor_type (w, glyph,
29661 &new_cursor_width, &active_cursor);
29663 /* If cursor is currently being shown and we don't want it to be or
29664 it is in the wrong place, or the cursor type is not what we want,
29665 erase it. */
29666 if (w->phys_cursor_on_p
29667 && (!on
29668 || w->phys_cursor.x != x
29669 || w->phys_cursor.y != y
29670 /* HPOS can be negative in R2L rows whose
29671 exact_window_width_line_p flag is set (i.e. their newline
29672 would "overflow into the fringe"). */
29673 || hpos < 0
29674 || new_cursor_type != w->phys_cursor_type
29675 || ((new_cursor_type == BAR_CURSOR || new_cursor_type == HBAR_CURSOR)
29676 && new_cursor_width != w->phys_cursor_width)))
29677 erase_phys_cursor (w);
29679 /* Don't check phys_cursor_on_p here because that flag is only set
29680 to false in some cases where we know that the cursor has been
29681 completely erased, to avoid the extra work of erasing the cursor
29682 twice. In other words, phys_cursor_on_p can be true and the cursor
29683 still not be visible, or it has only been partly erased. */
29684 if (on)
29686 w->phys_cursor_ascent = glyph_row->ascent;
29687 w->phys_cursor_height = glyph_row->height;
29689 /* Set phys_cursor_.* before x_draw_.* is called because some
29690 of them may need the information. */
29691 w->phys_cursor.x = x;
29692 w->phys_cursor.y = glyph_row->y;
29693 w->phys_cursor.hpos = hpos;
29694 w->phys_cursor.vpos = vpos;
29697 FRAME_RIF (f)->draw_window_cursor (w, glyph_row, x, y,
29698 new_cursor_type, new_cursor_width,
29699 on, active_cursor);
29703 /* Switch the display of W's cursor on or off, according to the value
29704 of ON. */
29706 static void
29707 update_window_cursor (struct window *w, bool on)
29709 /* Don't update cursor in windows whose frame is in the process
29710 of being deleted. */
29711 if (w->current_matrix)
29713 int hpos = w->phys_cursor.hpos;
29714 int vpos = w->phys_cursor.vpos;
29715 struct glyph_row *row;
29717 if (vpos >= w->current_matrix->nrows
29718 || hpos >= w->current_matrix->matrix_w)
29719 return;
29721 row = MATRIX_ROW (w->current_matrix, vpos);
29723 /* When the window is hscrolled, cursor hpos can legitimately be
29724 out of bounds, but we draw the cursor at the corresponding
29725 window margin in that case. */
29726 if (!row->reversed_p && hpos < 0)
29727 hpos = 0;
29728 if (row->reversed_p && hpos >= row->used[TEXT_AREA])
29729 hpos = row->used[TEXT_AREA] - 1;
29731 block_input ();
29732 display_and_set_cursor (w, on, hpos, vpos,
29733 w->phys_cursor.x, w->phys_cursor.y);
29734 unblock_input ();
29739 /* Call update_window_cursor with parameter ON_P on all leaf windows
29740 in the window tree rooted at W. */
29742 static void
29743 update_cursor_in_window_tree (struct window *w, bool on_p)
29745 while (w)
29747 if (WINDOWP (w->contents))
29748 update_cursor_in_window_tree (XWINDOW (w->contents), on_p);
29749 else
29750 update_window_cursor (w, on_p);
29752 w = NILP (w->next) ? 0 : XWINDOW (w->next);
29757 /* EXPORT:
29758 Display the cursor on window W, or clear it, according to ON_P.
29759 Don't change the cursor's position. */
29761 void
29762 x_update_cursor (struct frame *f, bool on_p)
29764 update_cursor_in_window_tree (XWINDOW (f->root_window), on_p);
29768 /* EXPORT:
29769 Clear the cursor of window W to background color, and mark the
29770 cursor as not shown. This is used when the text where the cursor
29771 is about to be rewritten. */
29773 void
29774 x_clear_cursor (struct window *w)
29776 if (FRAME_VISIBLE_P (XFRAME (w->frame)) && w->phys_cursor_on_p)
29777 update_window_cursor (w, false);
29780 #endif /* HAVE_WINDOW_SYSTEM */
29782 /* Implementation of draw_row_with_mouse_face for GUI sessions, GPM,
29783 and MSDOS. */
29784 static void
29785 draw_row_with_mouse_face (struct window *w, int start_x, struct glyph_row *row,
29786 int start_hpos, int end_hpos,
29787 enum draw_glyphs_face draw)
29789 #ifdef HAVE_WINDOW_SYSTEM
29790 if (FRAME_WINDOW_P (XFRAME (w->frame)))
29792 draw_glyphs (w, start_x, row, TEXT_AREA, start_hpos, end_hpos, draw, 0);
29793 return;
29795 #endif
29796 #if defined (HAVE_GPM) || defined (MSDOS) || defined (WINDOWSNT)
29797 tty_draw_row_with_mouse_face (w, row, start_hpos, end_hpos, draw);
29798 #endif
29801 /* Display the active region described by mouse_face_* according to DRAW. */
29803 static void
29804 show_mouse_face (Mouse_HLInfo *hlinfo, enum draw_glyphs_face draw)
29806 struct window *w = XWINDOW (hlinfo->mouse_face_window);
29807 struct frame *f = XFRAME (WINDOW_FRAME (w));
29809 if (/* If window is in the process of being destroyed, don't bother
29810 to do anything. */
29811 w->current_matrix != NULL
29812 /* Don't update mouse highlight if hidden. */
29813 && (draw != DRAW_MOUSE_FACE || !hlinfo->mouse_face_hidden)
29814 /* Recognize when we are called to operate on rows that don't exist
29815 anymore. This can happen when a window is split. */
29816 && hlinfo->mouse_face_end_row < w->current_matrix->nrows)
29818 bool phys_cursor_on_p = w->phys_cursor_on_p;
29819 struct glyph_row *row, *first, *last;
29821 first = MATRIX_ROW (w->current_matrix, hlinfo->mouse_face_beg_row);
29822 last = MATRIX_ROW (w->current_matrix, hlinfo->mouse_face_end_row);
29824 for (row = first; row <= last && row->enabled_p; ++row)
29826 int start_hpos, end_hpos, start_x;
29828 /* For all but the first row, the highlight starts at column 0. */
29829 if (row == first)
29831 /* R2L rows have BEG and END in reversed order, but the
29832 screen drawing geometry is always left to right. So
29833 we need to mirror the beginning and end of the
29834 highlighted area in R2L rows. */
29835 if (!row->reversed_p)
29837 start_hpos = hlinfo->mouse_face_beg_col;
29838 start_x = hlinfo->mouse_face_beg_x;
29840 else if (row == last)
29842 start_hpos = hlinfo->mouse_face_end_col;
29843 start_x = hlinfo->mouse_face_end_x;
29845 else
29847 start_hpos = 0;
29848 start_x = 0;
29851 else if (row->reversed_p && row == last)
29853 start_hpos = hlinfo->mouse_face_end_col;
29854 start_x = hlinfo->mouse_face_end_x;
29856 else
29858 start_hpos = 0;
29859 start_x = 0;
29862 if (row == last)
29864 if (!row->reversed_p)
29865 end_hpos = hlinfo->mouse_face_end_col;
29866 else if (row == first)
29867 end_hpos = hlinfo->mouse_face_beg_col;
29868 else
29870 end_hpos = row->used[TEXT_AREA];
29871 if (draw == DRAW_NORMAL_TEXT)
29872 row->fill_line_p = true; /* Clear to end of line. */
29875 else if (row->reversed_p && row == first)
29876 end_hpos = hlinfo->mouse_face_beg_col;
29877 else
29879 end_hpos = row->used[TEXT_AREA];
29880 if (draw == DRAW_NORMAL_TEXT)
29881 row->fill_line_p = true; /* Clear to end of line. */
29884 if (end_hpos > start_hpos)
29886 draw_row_with_mouse_face (w, start_x, row,
29887 start_hpos, end_hpos, draw);
29889 row->mouse_face_p
29890 = draw == DRAW_MOUSE_FACE || draw == DRAW_IMAGE_RAISED;
29894 /* When we've written over the cursor, arrange for it to
29895 be displayed again. */
29896 if (FRAME_WINDOW_P (f)
29897 && phys_cursor_on_p && !w->phys_cursor_on_p)
29899 #ifdef HAVE_WINDOW_SYSTEM
29900 int hpos = w->phys_cursor.hpos;
29902 /* When the window is hscrolled, cursor hpos can legitimately be
29903 out of bounds, but we draw the cursor at the corresponding
29904 window margin in that case. */
29905 if (!row->reversed_p && hpos < 0)
29906 hpos = 0;
29907 if (row->reversed_p && hpos >= row->used[TEXT_AREA])
29908 hpos = row->used[TEXT_AREA] - 1;
29910 block_input ();
29911 display_and_set_cursor (w, true, hpos, w->phys_cursor.vpos,
29912 w->phys_cursor.x, w->phys_cursor.y);
29913 unblock_input ();
29914 #endif /* HAVE_WINDOW_SYSTEM */
29918 #ifdef HAVE_WINDOW_SYSTEM
29919 /* Change the mouse cursor. */
29920 if (FRAME_WINDOW_P (f) && NILP (do_mouse_tracking))
29922 #if ! defined (USE_GTK) && ! defined (HAVE_NS)
29923 if (draw == DRAW_NORMAL_TEXT
29924 && !EQ (hlinfo->mouse_face_window, f->tool_bar_window))
29925 FRAME_RIF (f)->define_frame_cursor (f, FRAME_X_OUTPUT (f)->text_cursor);
29926 else
29927 #endif
29928 if (draw == DRAW_MOUSE_FACE)
29929 FRAME_RIF (f)->define_frame_cursor (f, FRAME_X_OUTPUT (f)->hand_cursor);
29930 else
29931 FRAME_RIF (f)->define_frame_cursor (f, FRAME_X_OUTPUT (f)->nontext_cursor);
29933 #endif /* HAVE_WINDOW_SYSTEM */
29936 /* EXPORT:
29937 Clear out the mouse-highlighted active region.
29938 Redraw it un-highlighted first. Value is true if mouse
29939 face was actually drawn unhighlighted. */
29941 bool
29942 clear_mouse_face (Mouse_HLInfo *hlinfo)
29944 bool cleared
29945 = !hlinfo->mouse_face_hidden && !NILP (hlinfo->mouse_face_window);
29946 if (cleared)
29947 show_mouse_face (hlinfo, DRAW_NORMAL_TEXT);
29948 hlinfo->mouse_face_beg_row = hlinfo->mouse_face_beg_col = -1;
29949 hlinfo->mouse_face_end_row = hlinfo->mouse_face_end_col = -1;
29950 hlinfo->mouse_face_window = Qnil;
29951 hlinfo->mouse_face_overlay = Qnil;
29952 return cleared;
29955 /* Return true if the coordinates HPOS and VPOS on windows W are
29956 within the mouse face on that window. */
29957 static bool
29958 coords_in_mouse_face_p (struct window *w, int hpos, int vpos)
29960 Mouse_HLInfo *hlinfo = MOUSE_HL_INFO (XFRAME (w->frame));
29962 /* Quickly resolve the easy cases. */
29963 if (!(WINDOWP (hlinfo->mouse_face_window)
29964 && XWINDOW (hlinfo->mouse_face_window) == w))
29965 return false;
29966 if (vpos < hlinfo->mouse_face_beg_row
29967 || vpos > hlinfo->mouse_face_end_row)
29968 return false;
29969 if (vpos > hlinfo->mouse_face_beg_row
29970 && vpos < hlinfo->mouse_face_end_row)
29971 return true;
29973 if (!MATRIX_ROW (w->current_matrix, vpos)->reversed_p)
29975 if (hlinfo->mouse_face_beg_row == hlinfo->mouse_face_end_row)
29977 if (hlinfo->mouse_face_beg_col <= hpos && hpos < hlinfo->mouse_face_end_col)
29978 return true;
29980 else if ((vpos == hlinfo->mouse_face_beg_row
29981 && hpos >= hlinfo->mouse_face_beg_col)
29982 || (vpos == hlinfo->mouse_face_end_row
29983 && hpos < hlinfo->mouse_face_end_col))
29984 return true;
29986 else
29988 if (hlinfo->mouse_face_beg_row == hlinfo->mouse_face_end_row)
29990 if (hlinfo->mouse_face_end_col < hpos && hpos <= hlinfo->mouse_face_beg_col)
29991 return true;
29993 else if ((vpos == hlinfo->mouse_face_beg_row
29994 && hpos <= hlinfo->mouse_face_beg_col)
29995 || (vpos == hlinfo->mouse_face_end_row
29996 && hpos > hlinfo->mouse_face_end_col))
29997 return true;
29999 return false;
30003 /* EXPORT:
30004 True if physical cursor of window W is within mouse face. */
30006 bool
30007 cursor_in_mouse_face_p (struct window *w)
30009 int hpos = w->phys_cursor.hpos;
30010 int vpos = w->phys_cursor.vpos;
30011 struct glyph_row *row = MATRIX_ROW (w->current_matrix, vpos);
30013 /* When the window is hscrolled, cursor hpos can legitimately be out
30014 of bounds, but we draw the cursor at the corresponding window
30015 margin in that case. */
30016 if (!row->reversed_p && hpos < 0)
30017 hpos = 0;
30018 if (row->reversed_p && hpos >= row->used[TEXT_AREA])
30019 hpos = row->used[TEXT_AREA] - 1;
30021 return coords_in_mouse_face_p (w, hpos, vpos);
30026 /* Find the glyph rows START_ROW and END_ROW of window W that display
30027 characters between buffer positions START_CHARPOS and END_CHARPOS
30028 (excluding END_CHARPOS). DISP_STRING is a display string that
30029 covers these buffer positions. This is similar to
30030 row_containing_pos, but is more accurate when bidi reordering makes
30031 buffer positions change non-linearly with glyph rows. */
30032 static void
30033 rows_from_pos_range (struct window *w,
30034 ptrdiff_t start_charpos, ptrdiff_t end_charpos,
30035 Lisp_Object disp_string,
30036 struct glyph_row **start, struct glyph_row **end)
30038 struct glyph_row *first = MATRIX_FIRST_TEXT_ROW (w->current_matrix);
30039 int last_y = window_text_bottom_y (w);
30040 struct glyph_row *row;
30042 *start = NULL;
30043 *end = NULL;
30045 while (!first->enabled_p
30046 && first < MATRIX_BOTTOM_TEXT_ROW (w->current_matrix, w))
30047 first++;
30049 /* Find the START row. */
30050 for (row = first;
30051 row->enabled_p && MATRIX_ROW_BOTTOM_Y (row) <= last_y;
30052 row++)
30054 /* A row can potentially be the START row if the range of the
30055 characters it displays intersects the range
30056 [START_CHARPOS..END_CHARPOS). */
30057 if (! ((start_charpos < MATRIX_ROW_START_CHARPOS (row)
30058 && end_charpos < MATRIX_ROW_START_CHARPOS (row))
30059 /* See the commentary in row_containing_pos, for the
30060 explanation of the complicated way to check whether
30061 some position is beyond the end of the characters
30062 displayed by a row. */
30063 || ((start_charpos > MATRIX_ROW_END_CHARPOS (row)
30064 || (start_charpos == MATRIX_ROW_END_CHARPOS (row)
30065 && !row->ends_at_zv_p
30066 && !MATRIX_ROW_ENDS_IN_MIDDLE_OF_CHAR_P (row)))
30067 && (end_charpos > MATRIX_ROW_END_CHARPOS (row)
30068 || (end_charpos == MATRIX_ROW_END_CHARPOS (row)
30069 && !row->ends_at_zv_p
30070 && !MATRIX_ROW_ENDS_IN_MIDDLE_OF_CHAR_P (row))))))
30072 /* Found a candidate row. Now make sure at least one of the
30073 glyphs it displays has a charpos from the range
30074 [START_CHARPOS..END_CHARPOS).
30076 This is not obvious because bidi reordering could make
30077 buffer positions of a row be 1,2,3,102,101,100, and if we
30078 want to highlight characters in [50..60), we don't want
30079 this row, even though [50..60) does intersect [1..103),
30080 the range of character positions given by the row's start
30081 and end positions. */
30082 struct glyph *g = row->glyphs[TEXT_AREA];
30083 struct glyph *e = g + row->used[TEXT_AREA];
30085 while (g < e)
30087 if (((BUFFERP (g->object) || NILP (g->object))
30088 && start_charpos <= g->charpos && g->charpos < end_charpos)
30089 /* A glyph that comes from DISP_STRING is by
30090 definition to be highlighted. */
30091 || EQ (g->object, disp_string))
30092 *start = row;
30093 g++;
30095 if (*start)
30096 break;
30100 /* Find the END row. */
30101 if (!*start
30102 /* If the last row is partially visible, start looking for END
30103 from that row, instead of starting from FIRST. */
30104 && !(row->enabled_p
30105 && row->y < last_y && MATRIX_ROW_BOTTOM_Y (row) > last_y))
30106 row = first;
30107 for ( ; row->enabled_p && MATRIX_ROW_BOTTOM_Y (row) <= last_y; row++)
30109 struct glyph_row *next = row + 1;
30110 ptrdiff_t next_start = MATRIX_ROW_START_CHARPOS (next);
30112 if (!next->enabled_p
30113 || next >= MATRIX_BOTTOM_TEXT_ROW (w->current_matrix, w)
30114 /* The first row >= START whose range of displayed characters
30115 does NOT intersect the range [START_CHARPOS..END_CHARPOS]
30116 is the row END + 1. */
30117 || (start_charpos < next_start
30118 && end_charpos < next_start)
30119 || ((start_charpos > MATRIX_ROW_END_CHARPOS (next)
30120 || (start_charpos == MATRIX_ROW_END_CHARPOS (next)
30121 && !next->ends_at_zv_p
30122 && !MATRIX_ROW_ENDS_IN_MIDDLE_OF_CHAR_P (next)))
30123 && (end_charpos > MATRIX_ROW_END_CHARPOS (next)
30124 || (end_charpos == MATRIX_ROW_END_CHARPOS (next)
30125 && !next->ends_at_zv_p
30126 && !MATRIX_ROW_ENDS_IN_MIDDLE_OF_CHAR_P (next)))))
30128 *end = row;
30129 break;
30131 else
30133 /* If the next row's edges intersect [START_CHARPOS..END_CHARPOS],
30134 but none of the characters it displays are in the range, it is
30135 also END + 1. */
30136 struct glyph *g = next->glyphs[TEXT_AREA];
30137 struct glyph *s = g;
30138 struct glyph *e = g + next->used[TEXT_AREA];
30140 while (g < e)
30142 if (((BUFFERP (g->object) || NILP (g->object))
30143 && ((start_charpos <= g->charpos && g->charpos < end_charpos)
30144 /* If the buffer position of the first glyph in
30145 the row is equal to END_CHARPOS, it means
30146 the last character to be highlighted is the
30147 newline of ROW, and we must consider NEXT as
30148 END, not END+1. */
30149 || (((!next->reversed_p && g == s)
30150 || (next->reversed_p && g == e - 1))
30151 && (g->charpos == end_charpos
30152 /* Special case for when NEXT is an
30153 empty line at ZV. */
30154 || (g->charpos == -1
30155 && !row->ends_at_zv_p
30156 && next_start == end_charpos)))))
30157 /* A glyph that comes from DISP_STRING is by
30158 definition to be highlighted. */
30159 || EQ (g->object, disp_string))
30160 break;
30161 g++;
30163 if (g == e)
30165 *end = row;
30166 break;
30168 /* The first row that ends at ZV must be the last to be
30169 highlighted. */
30170 else if (next->ends_at_zv_p)
30172 *end = next;
30173 break;
30179 /* This function sets the mouse_face_* elements of HLINFO, assuming
30180 the mouse cursor is on a glyph with buffer charpos MOUSE_CHARPOS in
30181 window WINDOW. START_CHARPOS and END_CHARPOS are buffer positions
30182 for the overlay or run of text properties specifying the mouse
30183 face. BEFORE_STRING and AFTER_STRING, if non-nil, are a
30184 before-string and after-string that must also be highlighted.
30185 DISP_STRING, if non-nil, is a display string that may cover some
30186 or all of the highlighted text. */
30188 static void
30189 mouse_face_from_buffer_pos (Lisp_Object window,
30190 Mouse_HLInfo *hlinfo,
30191 ptrdiff_t mouse_charpos,
30192 ptrdiff_t start_charpos,
30193 ptrdiff_t end_charpos,
30194 Lisp_Object before_string,
30195 Lisp_Object after_string,
30196 Lisp_Object disp_string)
30198 struct window *w = XWINDOW (window);
30199 struct glyph_row *first = MATRIX_FIRST_TEXT_ROW (w->current_matrix);
30200 struct glyph_row *r1, *r2;
30201 struct glyph *glyph, *end;
30202 ptrdiff_t ignore, pos;
30203 int x;
30205 eassert (NILP (disp_string) || STRINGP (disp_string));
30206 eassert (NILP (before_string) || STRINGP (before_string));
30207 eassert (NILP (after_string) || STRINGP (after_string));
30209 /* Find the rows corresponding to START_CHARPOS and END_CHARPOS. */
30210 rows_from_pos_range (w, start_charpos, end_charpos, disp_string, &r1, &r2);
30211 if (r1 == NULL)
30212 r1 = MATRIX_ROW (w->current_matrix, w->window_end_vpos);
30213 /* If the before-string or display-string contains newlines,
30214 rows_from_pos_range skips to its last row. Move back. */
30215 if (!NILP (before_string) || !NILP (disp_string))
30217 struct glyph_row *prev;
30218 while ((prev = r1 - 1, prev >= first)
30219 && MATRIX_ROW_END_CHARPOS (prev) == start_charpos
30220 && prev->used[TEXT_AREA] > 0)
30222 struct glyph *beg = prev->glyphs[TEXT_AREA];
30223 glyph = beg + prev->used[TEXT_AREA];
30224 while (--glyph >= beg && NILP (glyph->object));
30225 if (glyph < beg
30226 || !(EQ (glyph->object, before_string)
30227 || EQ (glyph->object, disp_string)))
30228 break;
30229 r1 = prev;
30232 if (r2 == NULL)
30234 r2 = MATRIX_ROW (w->current_matrix, w->window_end_vpos);
30235 hlinfo->mouse_face_past_end = true;
30237 else if (!NILP (after_string))
30239 /* If the after-string has newlines, advance to its last row. */
30240 struct glyph_row *next;
30241 struct glyph_row *last
30242 = MATRIX_ROW (w->current_matrix, w->window_end_vpos);
30244 for (next = r2 + 1;
30245 next <= last
30246 && next->used[TEXT_AREA] > 0
30247 && EQ (next->glyphs[TEXT_AREA]->object, after_string);
30248 ++next)
30249 r2 = next;
30251 /* The rest of the display engine assumes that mouse_face_beg_row is
30252 either above mouse_face_end_row or identical to it. But with
30253 bidi-reordered continued lines, the row for START_CHARPOS could
30254 be below the row for END_CHARPOS. If so, swap the rows and store
30255 them in correct order. */
30256 if (r1->y > r2->y)
30258 struct glyph_row *tem = r2;
30260 r2 = r1;
30261 r1 = tem;
30264 hlinfo->mouse_face_beg_row = MATRIX_ROW_VPOS (r1, w->current_matrix);
30265 hlinfo->mouse_face_end_row = MATRIX_ROW_VPOS (r2, w->current_matrix);
30267 /* For a bidi-reordered row, the positions of BEFORE_STRING,
30268 AFTER_STRING, DISP_STRING, START_CHARPOS, and END_CHARPOS
30269 could be anywhere in the row and in any order. The strategy
30270 below is to find the leftmost and the rightmost glyph that
30271 belongs to either of these 3 strings, or whose position is
30272 between START_CHARPOS and END_CHARPOS, and highlight all the
30273 glyphs between those two. This may cover more than just the text
30274 between START_CHARPOS and END_CHARPOS if the range of characters
30275 strides the bidi level boundary, e.g. if the beginning is in R2L
30276 text while the end is in L2R text or vice versa. */
30277 if (!r1->reversed_p)
30279 /* This row is in a left to right paragraph. Scan it left to
30280 right. */
30281 glyph = r1->glyphs[TEXT_AREA];
30282 end = glyph + r1->used[TEXT_AREA];
30283 x = r1->x;
30285 /* Skip truncation glyphs at the start of the glyph row. */
30286 if (MATRIX_ROW_DISPLAYS_TEXT_P (r1))
30287 for (; glyph < end
30288 && NILP (glyph->object)
30289 && glyph->charpos < 0;
30290 ++glyph)
30291 x += glyph->pixel_width;
30293 /* Scan the glyph row, looking for BEFORE_STRING, AFTER_STRING,
30294 or DISP_STRING, and the first glyph from buffer whose
30295 position is between START_CHARPOS and END_CHARPOS. */
30296 for (; glyph < end
30297 && !NILP (glyph->object)
30298 && !EQ (glyph->object, disp_string)
30299 && !(BUFFERP (glyph->object)
30300 && (glyph->charpos >= start_charpos
30301 && glyph->charpos < end_charpos));
30302 ++glyph)
30304 /* BEFORE_STRING or AFTER_STRING are only relevant if they
30305 are present at buffer positions between START_CHARPOS and
30306 END_CHARPOS, or if they come from an overlay. */
30307 if (EQ (glyph->object, before_string))
30309 pos = string_buffer_position (before_string,
30310 start_charpos);
30311 /* If pos == 0, it means before_string came from an
30312 overlay, not from a buffer position. */
30313 if (!pos || (pos >= start_charpos && pos < end_charpos))
30314 break;
30316 else if (EQ (glyph->object, after_string))
30318 pos = string_buffer_position (after_string, end_charpos);
30319 if (!pos || (pos >= start_charpos && pos < end_charpos))
30320 break;
30322 x += glyph->pixel_width;
30324 hlinfo->mouse_face_beg_x = x;
30325 hlinfo->mouse_face_beg_col = glyph - r1->glyphs[TEXT_AREA];
30327 else
30329 /* This row is in a right to left paragraph. Scan it right to
30330 left. */
30331 struct glyph *g;
30333 end = r1->glyphs[TEXT_AREA] - 1;
30334 glyph = end + r1->used[TEXT_AREA];
30336 /* Skip truncation glyphs at the start of the glyph row. */
30337 if (MATRIX_ROW_DISPLAYS_TEXT_P (r1))
30338 for (; glyph > end
30339 && NILP (glyph->object)
30340 && glyph->charpos < 0;
30341 --glyph)
30344 /* Scan the glyph row, looking for BEFORE_STRING, AFTER_STRING,
30345 or DISP_STRING, and the first glyph from buffer whose
30346 position is between START_CHARPOS and END_CHARPOS. */
30347 for (; glyph > end
30348 && !NILP (glyph->object)
30349 && !EQ (glyph->object, disp_string)
30350 && !(BUFFERP (glyph->object)
30351 && (glyph->charpos >= start_charpos
30352 && glyph->charpos < end_charpos));
30353 --glyph)
30355 /* BEFORE_STRING or AFTER_STRING are only relevant if they
30356 are present at buffer positions between START_CHARPOS and
30357 END_CHARPOS, or if they come from an overlay. */
30358 if (EQ (glyph->object, before_string))
30360 pos = string_buffer_position (before_string, start_charpos);
30361 /* If pos == 0, it means before_string came from an
30362 overlay, not from a buffer position. */
30363 if (!pos || (pos >= start_charpos && pos < end_charpos))
30364 break;
30366 else if (EQ (glyph->object, after_string))
30368 pos = string_buffer_position (after_string, end_charpos);
30369 if (!pos || (pos >= start_charpos && pos < end_charpos))
30370 break;
30374 glyph++; /* first glyph to the right of the highlighted area */
30375 for (g = r1->glyphs[TEXT_AREA], x = r1->x; g < glyph; g++)
30376 x += g->pixel_width;
30377 hlinfo->mouse_face_beg_x = x;
30378 hlinfo->mouse_face_beg_col = glyph - r1->glyphs[TEXT_AREA];
30381 /* If the highlight ends in a different row, compute GLYPH and END
30382 for the end row. Otherwise, reuse the values computed above for
30383 the row where the highlight begins. */
30384 if (r2 != r1)
30386 if (!r2->reversed_p)
30388 glyph = r2->glyphs[TEXT_AREA];
30389 end = glyph + r2->used[TEXT_AREA];
30390 x = r2->x;
30392 else
30394 end = r2->glyphs[TEXT_AREA] - 1;
30395 glyph = end + r2->used[TEXT_AREA];
30399 if (!r2->reversed_p)
30401 /* Skip truncation and continuation glyphs near the end of the
30402 row, and also blanks and stretch glyphs inserted by
30403 extend_face_to_end_of_line. */
30404 while (end > glyph
30405 && NILP ((end - 1)->object))
30406 --end;
30407 /* Scan the rest of the glyph row from the end, looking for the
30408 first glyph that comes from BEFORE_STRING, AFTER_STRING, or
30409 DISP_STRING, or whose position is between START_CHARPOS
30410 and END_CHARPOS */
30411 for (--end;
30412 end > glyph
30413 && !NILP (end->object)
30414 && !EQ (end->object, disp_string)
30415 && !(BUFFERP (end->object)
30416 && (end->charpos >= start_charpos
30417 && end->charpos < end_charpos));
30418 --end)
30420 /* BEFORE_STRING or AFTER_STRING are only relevant if they
30421 are present at buffer positions between START_CHARPOS and
30422 END_CHARPOS, or if they come from an overlay. */
30423 if (EQ (end->object, before_string))
30425 pos = string_buffer_position (before_string, start_charpos);
30426 if (!pos || (pos >= start_charpos && pos < end_charpos))
30427 break;
30429 else if (EQ (end->object, after_string))
30431 pos = string_buffer_position (after_string, end_charpos);
30432 if (!pos || (pos >= start_charpos && pos < end_charpos))
30433 break;
30436 /* Find the X coordinate of the last glyph to be highlighted. */
30437 for (; glyph <= end; ++glyph)
30438 x += glyph->pixel_width;
30440 hlinfo->mouse_face_end_x = x;
30441 hlinfo->mouse_face_end_col = glyph - r2->glyphs[TEXT_AREA];
30443 else
30445 /* Skip truncation and continuation glyphs near the end of the
30446 row, and also blanks and stretch glyphs inserted by
30447 extend_face_to_end_of_line. */
30448 x = r2->x;
30449 end++;
30450 while (end < glyph
30451 && NILP (end->object))
30453 x += end->pixel_width;
30454 ++end;
30456 /* Scan the rest of the glyph row from the end, looking for the
30457 first glyph that comes from BEFORE_STRING, AFTER_STRING, or
30458 DISP_STRING, or whose position is between START_CHARPOS
30459 and END_CHARPOS */
30460 for ( ;
30461 end < glyph
30462 && !NILP (end->object)
30463 && !EQ (end->object, disp_string)
30464 && !(BUFFERP (end->object)
30465 && (end->charpos >= start_charpos
30466 && end->charpos < end_charpos));
30467 ++end)
30469 /* BEFORE_STRING or AFTER_STRING are only relevant if they
30470 are present at buffer positions between START_CHARPOS and
30471 END_CHARPOS, or if they come from an overlay. */
30472 if (EQ (end->object, before_string))
30474 pos = string_buffer_position (before_string, start_charpos);
30475 if (!pos || (pos >= start_charpos && pos < end_charpos))
30476 break;
30478 else if (EQ (end->object, after_string))
30480 pos = string_buffer_position (after_string, end_charpos);
30481 if (!pos || (pos >= start_charpos && pos < end_charpos))
30482 break;
30484 x += end->pixel_width;
30486 /* If we exited the above loop because we arrived at the last
30487 glyph of the row, and its buffer position is still not in
30488 range, it means the last character in range is the preceding
30489 newline. Bump the end column and x values to get past the
30490 last glyph. */
30491 if (end == glyph
30492 && BUFFERP (end->object)
30493 && (end->charpos < start_charpos
30494 || end->charpos >= end_charpos))
30496 x += end->pixel_width;
30497 ++end;
30499 hlinfo->mouse_face_end_x = x;
30500 hlinfo->mouse_face_end_col = end - r2->glyphs[TEXT_AREA];
30503 hlinfo->mouse_face_window = window;
30504 hlinfo->mouse_face_face_id
30505 = face_at_buffer_position (w, mouse_charpos, &ignore,
30506 mouse_charpos + 1,
30507 !hlinfo->mouse_face_hidden, -1);
30508 show_mouse_face (hlinfo, DRAW_MOUSE_FACE);
30511 /* The following function is not used anymore (replaced with
30512 mouse_face_from_string_pos), but I leave it here for the time
30513 being, in case someone would. */
30515 #if false /* not used */
30517 /* Find the position of the glyph for position POS in OBJECT in
30518 window W's current matrix, and return in *X, *Y the pixel
30519 coordinates, and return in *HPOS, *VPOS the column/row of the glyph.
30521 RIGHT_P means return the position of the right edge of the glyph.
30522 !RIGHT_P means return the left edge position.
30524 If no glyph for POS exists in the matrix, return the position of
30525 the glyph with the next smaller position that is in the matrix, if
30526 RIGHT_P is false. If RIGHT_P, and no glyph for POS
30527 exists in the matrix, return the position of the glyph with the
30528 next larger position in OBJECT.
30530 Value is true if a glyph was found. */
30532 static bool
30533 fast_find_string_pos (struct window *w, ptrdiff_t pos, Lisp_Object object,
30534 int *hpos, int *vpos, int *x, int *y, bool right_p)
30536 int yb = window_text_bottom_y (w);
30537 struct glyph_row *r;
30538 struct glyph *best_glyph = NULL;
30539 struct glyph_row *best_row = NULL;
30540 int best_x = 0;
30542 for (r = MATRIX_FIRST_TEXT_ROW (w->current_matrix);
30543 r->enabled_p && r->y < yb;
30544 ++r)
30546 struct glyph *g = r->glyphs[TEXT_AREA];
30547 struct glyph *e = g + r->used[TEXT_AREA];
30548 int gx;
30550 for (gx = r->x; g < e; gx += g->pixel_width, ++g)
30551 if (EQ (g->object, object))
30553 if (g->charpos == pos)
30555 best_glyph = g;
30556 best_x = gx;
30557 best_row = r;
30558 goto found;
30560 else if (best_glyph == NULL
30561 || ((eabs (g->charpos - pos)
30562 < eabs (best_glyph->charpos - pos))
30563 && (right_p
30564 ? g->charpos < pos
30565 : g->charpos > pos)))
30567 best_glyph = g;
30568 best_x = gx;
30569 best_row = r;
30574 found:
30576 if (best_glyph)
30578 *x = best_x;
30579 *hpos = best_glyph - best_row->glyphs[TEXT_AREA];
30581 if (right_p)
30583 *x += best_glyph->pixel_width;
30584 ++*hpos;
30587 *y = best_row->y;
30588 *vpos = MATRIX_ROW_VPOS (best_row, w->current_matrix);
30591 return best_glyph != NULL;
30593 #endif /* not used */
30595 /* Find the positions of the first and the last glyphs in window W's
30596 current matrix that occlude positions [STARTPOS..ENDPOS) in OBJECT
30597 (assumed to be a string), and return in HLINFO's mouse_face_*
30598 members the pixel and column/row coordinates of those glyphs. */
30600 static void
30601 mouse_face_from_string_pos (struct window *w, Mouse_HLInfo *hlinfo,
30602 Lisp_Object object,
30603 ptrdiff_t startpos, ptrdiff_t endpos)
30605 int yb = window_text_bottom_y (w);
30606 struct glyph_row *r;
30607 struct glyph *g, *e;
30608 int gx;
30609 bool found = false;
30611 /* Find the glyph row with at least one position in the range
30612 [STARTPOS..ENDPOS), and the first glyph in that row whose
30613 position belongs to that range. */
30614 for (r = MATRIX_FIRST_TEXT_ROW (w->current_matrix);
30615 r->enabled_p && r->y < yb;
30616 ++r)
30618 if (!r->reversed_p)
30620 g = r->glyphs[TEXT_AREA];
30621 e = g + r->used[TEXT_AREA];
30622 for (gx = r->x; g < e; gx += g->pixel_width, ++g)
30623 if (EQ (g->object, object)
30624 && startpos <= g->charpos && g->charpos < endpos)
30626 hlinfo->mouse_face_beg_row
30627 = MATRIX_ROW_VPOS (r, w->current_matrix);
30628 hlinfo->mouse_face_beg_col = g - r->glyphs[TEXT_AREA];
30629 hlinfo->mouse_face_beg_x = gx;
30630 found = true;
30631 break;
30634 else
30636 struct glyph *g1;
30638 e = r->glyphs[TEXT_AREA];
30639 g = e + r->used[TEXT_AREA];
30640 for ( ; g > e; --g)
30641 if (EQ ((g-1)->object, object)
30642 && startpos <= (g-1)->charpos && (g-1)->charpos < endpos)
30644 hlinfo->mouse_face_beg_row
30645 = MATRIX_ROW_VPOS (r, w->current_matrix);
30646 hlinfo->mouse_face_beg_col = g - r->glyphs[TEXT_AREA];
30647 for (gx = r->x, g1 = r->glyphs[TEXT_AREA]; g1 < g; ++g1)
30648 gx += g1->pixel_width;
30649 hlinfo->mouse_face_beg_x = gx;
30650 found = true;
30651 break;
30654 if (found)
30655 break;
30658 if (!found)
30659 return;
30661 /* Starting with the next row, look for the first row which does NOT
30662 include any glyphs whose positions are in the range. */
30663 for (++r; r->enabled_p && r->y < yb; ++r)
30665 g = r->glyphs[TEXT_AREA];
30666 e = g + r->used[TEXT_AREA];
30667 found = false;
30668 for ( ; g < e; ++g)
30669 if (EQ (g->object, object)
30670 && startpos <= g->charpos && g->charpos < endpos)
30672 found = true;
30673 break;
30675 if (!found)
30676 break;
30679 /* The highlighted region ends on the previous row. */
30680 r--;
30682 /* Set the end row. */
30683 hlinfo->mouse_face_end_row = MATRIX_ROW_VPOS (r, w->current_matrix);
30685 /* Compute and set the end column and the end column's horizontal
30686 pixel coordinate. */
30687 if (!r->reversed_p)
30689 g = r->glyphs[TEXT_AREA];
30690 e = g + r->used[TEXT_AREA];
30691 for ( ; e > g; --e)
30692 if (EQ ((e-1)->object, object)
30693 && startpos <= (e-1)->charpos && (e-1)->charpos < endpos)
30694 break;
30695 hlinfo->mouse_face_end_col = e - g;
30697 for (gx = r->x; g < e; ++g)
30698 gx += g->pixel_width;
30699 hlinfo->mouse_face_end_x = gx;
30701 else
30703 e = r->glyphs[TEXT_AREA];
30704 g = e + r->used[TEXT_AREA];
30705 for (gx = r->x ; e < g; ++e)
30707 if (EQ (e->object, object)
30708 && startpos <= e->charpos && e->charpos < endpos)
30709 break;
30710 gx += e->pixel_width;
30712 hlinfo->mouse_face_end_col = e - r->glyphs[TEXT_AREA];
30713 hlinfo->mouse_face_end_x = gx;
30717 #ifdef HAVE_WINDOW_SYSTEM
30719 /* See if position X, Y is within a hot-spot of an image. */
30721 static bool
30722 on_hot_spot_p (Lisp_Object hot_spot, int x, int y)
30724 if (!CONSP (hot_spot))
30725 return false;
30727 if (EQ (XCAR (hot_spot), Qrect))
30729 /* CDR is (Top-Left . Bottom-Right) = ((x0 . y0) . (x1 . y1)) */
30730 Lisp_Object rect = XCDR (hot_spot);
30731 Lisp_Object tem;
30732 if (!CONSP (rect))
30733 return false;
30734 if (!CONSP (XCAR (rect)))
30735 return false;
30736 if (!CONSP (XCDR (rect)))
30737 return false;
30738 if (!(tem = XCAR (XCAR (rect)), INTEGERP (tem) && x >= XINT (tem)))
30739 return false;
30740 if (!(tem = XCDR (XCAR (rect)), INTEGERP (tem) && y >= XINT (tem)))
30741 return false;
30742 if (!(tem = XCAR (XCDR (rect)), INTEGERP (tem) && x <= XINT (tem)))
30743 return false;
30744 if (!(tem = XCDR (XCDR (rect)), INTEGERP (tem) && y <= XINT (tem)))
30745 return false;
30746 return true;
30748 else if (EQ (XCAR (hot_spot), Qcircle))
30750 /* CDR is (Center . Radius) = ((x0 . y0) . r) */
30751 Lisp_Object circ = XCDR (hot_spot);
30752 Lisp_Object lr, lx0, ly0;
30753 if (CONSP (circ)
30754 && CONSP (XCAR (circ))
30755 && (lr = XCDR (circ), NUMBERP (lr))
30756 && (lx0 = XCAR (XCAR (circ)), INTEGERP (lx0))
30757 && (ly0 = XCDR (XCAR (circ)), INTEGERP (ly0)))
30759 double r = XFLOATINT (lr);
30760 double dx = XINT (lx0) - x;
30761 double dy = XINT (ly0) - y;
30762 return (dx * dx + dy * dy <= r * r);
30765 else if (EQ (XCAR (hot_spot), Qpoly))
30767 /* CDR is [x0 y0 x1 y1 x2 y2 ...x(n-1) y(n-1)] */
30768 if (VECTORP (XCDR (hot_spot)))
30770 struct Lisp_Vector *v = XVECTOR (XCDR (hot_spot));
30771 Lisp_Object *poly = v->contents;
30772 ptrdiff_t n = v->header.size;
30773 ptrdiff_t i;
30774 bool inside = false;
30775 Lisp_Object lx, ly;
30776 int x0, y0;
30778 /* Need an even number of coordinates, and at least 3 edges. */
30779 if (n < 6 || n & 1)
30780 return false;
30782 /* Count edge segments intersecting line from (X,Y) to (X,infinity).
30783 If count is odd, we are inside polygon. Pixels on edges
30784 may or may not be included depending on actual geometry of the
30785 polygon. */
30786 if ((lx = poly[n-2], !INTEGERP (lx))
30787 || (ly = poly[n-1], !INTEGERP (lx)))
30788 return false;
30789 x0 = XINT (lx), y0 = XINT (ly);
30790 for (i = 0; i < n; i += 2)
30792 int x1 = x0, y1 = y0;
30793 if ((lx = poly[i], !INTEGERP (lx))
30794 || (ly = poly[i+1], !INTEGERP (ly)))
30795 return false;
30796 x0 = XINT (lx), y0 = XINT (ly);
30798 /* Does this segment cross the X line? */
30799 if (x0 >= x)
30801 if (x1 >= x)
30802 continue;
30804 else if (x1 < x)
30805 continue;
30806 if (y > y0 && y > y1)
30807 continue;
30808 if (y < y0 + ((y1 - y0) * (x - x0)) / (x1 - x0))
30809 inside = !inside;
30811 return inside;
30814 return false;
30817 Lisp_Object
30818 find_hot_spot (Lisp_Object map, int x, int y)
30820 while (CONSP (map))
30822 if (CONSP (XCAR (map))
30823 && on_hot_spot_p (XCAR (XCAR (map)), x, y))
30824 return XCAR (map);
30825 map = XCDR (map);
30828 return Qnil;
30831 DEFUN ("lookup-image-map", Flookup_image_map, Slookup_image_map,
30832 3, 3, 0,
30833 doc: /* Lookup in image map MAP coordinates X and Y.
30834 An image map is an alist where each element has the format (AREA ID PLIST).
30835 An AREA is specified as either a rectangle, a circle, or a polygon:
30836 A rectangle is a cons (rect . ((x0 . y0) . (x1 . y1))) specifying the
30837 pixel coordinates of the upper left and bottom right corners.
30838 A circle is a cons (circle . ((x0 . y0) . r)) specifying the center
30839 and the radius of the circle; r may be a float or integer.
30840 A polygon is a cons (poly . [x0 y0 x1 y1 ...]) where each pair in the
30841 vector describes one corner in the polygon.
30842 Returns the alist element for the first matching AREA in MAP. */)
30843 (Lisp_Object map, Lisp_Object x, Lisp_Object y)
30845 if (NILP (map))
30846 return Qnil;
30848 CHECK_NUMBER (x);
30849 CHECK_NUMBER (y);
30851 return find_hot_spot (map,
30852 clip_to_bounds (INT_MIN, XINT (x), INT_MAX),
30853 clip_to_bounds (INT_MIN, XINT (y), INT_MAX));
30855 #endif /* HAVE_WINDOW_SYSTEM */
30858 /* Display frame CURSOR, optionally using shape defined by POINTER. */
30859 static void
30860 define_frame_cursor1 (struct frame *f, Cursor cursor, Lisp_Object pointer)
30862 #ifdef HAVE_WINDOW_SYSTEM
30863 if (!FRAME_WINDOW_P (f))
30864 return;
30866 /* Do not change cursor shape while dragging mouse. */
30867 if (EQ (do_mouse_tracking, Qdragging))
30868 return;
30870 if (!NILP (pointer))
30872 if (EQ (pointer, Qarrow))
30873 cursor = FRAME_X_OUTPUT (f)->nontext_cursor;
30874 else if (EQ (pointer, Qhand))
30875 cursor = FRAME_X_OUTPUT (f)->hand_cursor;
30876 else if (EQ (pointer, Qtext))
30877 cursor = FRAME_X_OUTPUT (f)->text_cursor;
30878 else if (EQ (pointer, intern ("hdrag")))
30879 cursor = FRAME_X_OUTPUT (f)->horizontal_drag_cursor;
30880 else if (EQ (pointer, intern ("nhdrag")))
30881 cursor = FRAME_X_OUTPUT (f)->vertical_drag_cursor;
30882 # ifdef HAVE_X_WINDOWS
30883 else if (EQ (pointer, intern ("vdrag")))
30884 cursor = FRAME_DISPLAY_INFO (f)->vertical_scroll_bar_cursor;
30885 # endif
30886 else if (EQ (pointer, intern ("hourglass")))
30887 cursor = FRAME_X_OUTPUT (f)->hourglass_cursor;
30888 else if (EQ (pointer, Qmodeline))
30889 cursor = FRAME_X_OUTPUT (f)->modeline_cursor;
30890 else
30891 cursor = FRAME_X_OUTPUT (f)->nontext_cursor;
30894 if (cursor != No_Cursor)
30895 FRAME_RIF (f)->define_frame_cursor (f, cursor);
30896 #endif
30899 /* Take proper action when mouse has moved to the mode or header line
30900 or marginal area AREA of window W, x-position X and y-position Y.
30901 X is relative to the start of the text display area of W, so the
30902 width of bitmap areas and scroll bars must be subtracted to get a
30903 position relative to the start of the mode line. */
30905 static void
30906 note_mode_line_or_margin_highlight (Lisp_Object window, int x, int y,
30907 enum window_part area)
30909 struct window *w = XWINDOW (window);
30910 struct frame *f = XFRAME (w->frame);
30911 Mouse_HLInfo *hlinfo = MOUSE_HL_INFO (f);
30912 Cursor cursor = No_Cursor;
30913 Lisp_Object pointer = Qnil;
30914 int dx, dy, width, height;
30915 ptrdiff_t charpos;
30916 Lisp_Object string, object = Qnil;
30917 Lisp_Object pos UNINIT;
30918 Lisp_Object mouse_face;
30919 int original_x_pixel = x;
30920 struct glyph * glyph = NULL, * row_start_glyph = NULL;
30921 struct glyph_row *row UNINIT;
30923 if (area == ON_MODE_LINE || area == ON_HEADER_LINE)
30925 int x0;
30926 struct glyph *end;
30928 /* Kludge alert: mode_line_string takes X/Y in pixels, but
30929 returns them in row/column units! */
30930 string = mode_line_string (w, area, &x, &y, &charpos,
30931 &object, &dx, &dy, &width, &height);
30933 row = (area == ON_MODE_LINE
30934 ? MATRIX_MODE_LINE_ROW (w->current_matrix)
30935 : MATRIX_HEADER_LINE_ROW (w->current_matrix));
30937 /* Find the glyph under the mouse pointer. */
30938 if (row->mode_line_p && row->enabled_p)
30940 glyph = row_start_glyph = row->glyphs[TEXT_AREA];
30941 end = glyph + row->used[TEXT_AREA];
30943 for (x0 = original_x_pixel;
30944 glyph < end && x0 >= glyph->pixel_width;
30945 ++glyph)
30946 x0 -= glyph->pixel_width;
30948 if (glyph >= end)
30949 glyph = NULL;
30952 else
30954 x -= WINDOW_LEFT_SCROLL_BAR_AREA_WIDTH (w);
30955 /* Kludge alert: marginal_area_string takes X/Y in pixels, but
30956 returns them in row/column units! */
30957 string = marginal_area_string (w, area, &x, &y, &charpos,
30958 &object, &dx, &dy, &width, &height);
30961 Lisp_Object help = Qnil;
30963 #ifdef HAVE_WINDOW_SYSTEM
30964 if (IMAGEP (object))
30966 Lisp_Object image_map, hotspot;
30967 if ((image_map = Fplist_get (XCDR (object), QCmap),
30968 !NILP (image_map))
30969 && (hotspot = find_hot_spot (image_map, dx, dy),
30970 CONSP (hotspot))
30971 && (hotspot = XCDR (hotspot), CONSP (hotspot)))
30973 Lisp_Object plist;
30975 /* Could check XCAR (hotspot) to see if we enter/leave this hot-spot.
30976 If so, we could look for mouse-enter, mouse-leave
30977 properties in PLIST (and do something...). */
30978 hotspot = XCDR (hotspot);
30979 if (CONSP (hotspot)
30980 && (plist = XCAR (hotspot), CONSP (plist)))
30982 pointer = Fplist_get (plist, Qpointer);
30983 if (NILP (pointer))
30984 pointer = Qhand;
30985 help = Fplist_get (plist, Qhelp_echo);
30986 if (!NILP (help))
30988 help_echo_string = help;
30989 XSETWINDOW (help_echo_window, w);
30990 help_echo_object = w->contents;
30991 help_echo_pos = charpos;
30995 if (NILP (pointer))
30996 pointer = Fplist_get (XCDR (object), QCpointer);
30998 #endif /* HAVE_WINDOW_SYSTEM */
31000 if (STRINGP (string))
31001 pos = make_number (charpos);
31003 /* Set the help text and mouse pointer. If the mouse is on a part
31004 of the mode line without any text (e.g. past the right edge of
31005 the mode line text), use that windows's mode line help echo if it
31006 has been set. */
31007 if (STRINGP (string) || area == ON_MODE_LINE)
31009 /* Arrange to display the help by setting the global variables
31010 help_echo_string, help_echo_object, and help_echo_pos. */
31011 if (NILP (help))
31013 if (STRINGP (string))
31014 help = Fget_text_property (pos, Qhelp_echo, string);
31016 if (!NILP (help))
31018 help_echo_string = help;
31019 XSETWINDOW (help_echo_window, w);
31020 help_echo_object = string;
31021 help_echo_pos = charpos;
31023 else if (area == ON_MODE_LINE
31024 && !NILP (w->mode_line_help_echo))
31026 help_echo_string = w->mode_line_help_echo;
31027 XSETWINDOW (help_echo_window, w);
31028 help_echo_object = Qnil;
31029 help_echo_pos = -1;
31033 #ifdef HAVE_WINDOW_SYSTEM
31034 /* Change the mouse pointer according to what is under it. */
31035 if (FRAME_WINDOW_P (f))
31037 bool draggable = (! WINDOW_BOTTOMMOST_P (w)
31038 || minibuf_level
31039 || NILP (Vresize_mini_windows));
31041 if (STRINGP (string))
31043 cursor = FRAME_X_OUTPUT (f)->nontext_cursor;
31045 if (NILP (pointer))
31046 pointer = Fget_text_property (pos, Qpointer, string);
31048 /* Change the mouse pointer according to what is under X/Y. */
31049 if (NILP (pointer)
31050 && (area == ON_MODE_LINE || area == ON_HEADER_LINE))
31052 Lisp_Object map;
31054 map = Fget_text_property (pos, Qlocal_map, string);
31055 if (!KEYMAPP (map))
31056 map = Fget_text_property (pos, Qkeymap, string);
31057 if (!KEYMAPP (map) && draggable && area == ON_MODE_LINE)
31058 cursor = FRAME_X_OUTPUT (f)->vertical_drag_cursor;
31061 else if (draggable && area == ON_MODE_LINE)
31062 cursor = FRAME_X_OUTPUT (f)->vertical_drag_cursor;
31063 else
31064 cursor = FRAME_X_OUTPUT (f)->nontext_cursor;
31066 #endif
31069 /* Change the mouse face according to what is under X/Y. */
31070 bool mouse_face_shown = false;
31072 if (STRINGP (string))
31074 mouse_face = Fget_text_property (pos, Qmouse_face, string);
31075 if (!NILP (Vmouse_highlight) && !NILP (mouse_face)
31076 && ((area == ON_MODE_LINE) || (area == ON_HEADER_LINE))
31077 && glyph)
31079 Lisp_Object b, e;
31081 struct glyph * tmp_glyph;
31083 int gpos;
31084 int gseq_length;
31085 int total_pixel_width;
31086 ptrdiff_t begpos, endpos, ignore;
31088 int vpos, hpos;
31090 b = Fprevious_single_property_change (make_number (charpos + 1),
31091 Qmouse_face, string, Qnil);
31092 if (NILP (b))
31093 begpos = 0;
31094 else
31095 begpos = XINT (b);
31097 e = Fnext_single_property_change (pos, Qmouse_face, string, Qnil);
31098 if (NILP (e))
31099 endpos = SCHARS (string);
31100 else
31101 endpos = XINT (e);
31103 /* Calculate the glyph position GPOS of GLYPH in the
31104 displayed string, relative to the beginning of the
31105 highlighted part of the string.
31107 Note: GPOS is different from CHARPOS. CHARPOS is the
31108 position of GLYPH in the internal string object. A mode
31109 line string format has structures which are converted to
31110 a flattened string by the Emacs Lisp interpreter. The
31111 internal string is an element of those structures. The
31112 displayed string is the flattened string. */
31113 tmp_glyph = row_start_glyph;
31114 while (tmp_glyph < glyph
31115 && (!(EQ (tmp_glyph->object, glyph->object)
31116 && begpos <= tmp_glyph->charpos
31117 && tmp_glyph->charpos < endpos)))
31118 tmp_glyph++;
31119 gpos = glyph - tmp_glyph;
31121 /* Calculate the length GSEQ_LENGTH of the glyph sequence of
31122 the highlighted part of the displayed string to which
31123 GLYPH belongs. Note: GSEQ_LENGTH is different from
31124 SCHARS (STRING), because the latter returns the length of
31125 the internal string. */
31126 for (tmp_glyph = row->glyphs[TEXT_AREA] + row->used[TEXT_AREA] - 1;
31127 tmp_glyph > glyph
31128 && (!(EQ (tmp_glyph->object, glyph->object)
31129 && begpos <= tmp_glyph->charpos
31130 && tmp_glyph->charpos < endpos));
31131 tmp_glyph--)
31133 gseq_length = gpos + (tmp_glyph - glyph) + 1;
31135 /* Calculate the total pixel width of all the glyphs between
31136 the beginning of the highlighted area and GLYPH. */
31137 total_pixel_width = 0;
31138 for (tmp_glyph = glyph - gpos; tmp_glyph != glyph; tmp_glyph++)
31139 total_pixel_width += tmp_glyph->pixel_width;
31141 /* Pre calculation of re-rendering position. Note: X is in
31142 column units here, after the call to mode_line_string or
31143 marginal_area_string. */
31144 hpos = x - gpos;
31145 vpos = (area == ON_MODE_LINE
31146 ? (w->current_matrix)->nrows - 1
31147 : 0);
31149 /* If GLYPH's position is included in the region that is
31150 already drawn in mouse face, we have nothing to do. */
31151 if ( EQ (window, hlinfo->mouse_face_window)
31152 && (!row->reversed_p
31153 ? (hlinfo->mouse_face_beg_col <= hpos
31154 && hpos < hlinfo->mouse_face_end_col)
31155 /* In R2L rows we swap BEG and END, see below. */
31156 : (hlinfo->mouse_face_end_col <= hpos
31157 && hpos < hlinfo->mouse_face_beg_col))
31158 && hlinfo->mouse_face_beg_row == vpos )
31159 return;
31161 if (clear_mouse_face (hlinfo))
31162 cursor = No_Cursor;
31164 if (!row->reversed_p)
31166 hlinfo->mouse_face_beg_col = hpos;
31167 hlinfo->mouse_face_beg_x = original_x_pixel
31168 - (total_pixel_width + dx);
31169 hlinfo->mouse_face_end_col = hpos + gseq_length;
31170 hlinfo->mouse_face_end_x = 0;
31172 else
31174 /* In R2L rows, show_mouse_face expects BEG and END
31175 coordinates to be swapped. */
31176 hlinfo->mouse_face_end_col = hpos;
31177 hlinfo->mouse_face_end_x = original_x_pixel
31178 - (total_pixel_width + dx);
31179 hlinfo->mouse_face_beg_col = hpos + gseq_length;
31180 hlinfo->mouse_face_beg_x = 0;
31183 hlinfo->mouse_face_beg_row = vpos;
31184 hlinfo->mouse_face_end_row = hlinfo->mouse_face_beg_row;
31185 hlinfo->mouse_face_past_end = false;
31186 hlinfo->mouse_face_window = window;
31188 hlinfo->mouse_face_face_id = face_at_string_position (w, string,
31189 charpos,
31190 0, &ignore,
31191 glyph->face_id,
31192 true);
31193 show_mouse_face (hlinfo, DRAW_MOUSE_FACE);
31194 mouse_face_shown = true;
31196 if (NILP (pointer))
31197 pointer = Qhand;
31201 /* If mouse-face doesn't need to be shown, clear any existing
31202 mouse-face. */
31203 if ((area == ON_MODE_LINE || area == ON_HEADER_LINE) && !mouse_face_shown)
31204 clear_mouse_face (hlinfo);
31206 define_frame_cursor1 (f, cursor, pointer);
31210 /* EXPORT:
31211 Take proper action when the mouse has moved to position X, Y on
31212 frame F with regards to highlighting portions of display that have
31213 mouse-face properties. Also de-highlight portions of display where
31214 the mouse was before, set the mouse pointer shape as appropriate
31215 for the mouse coordinates, and activate help echo (tooltips).
31216 X and Y can be negative or out of range. */
31218 void
31219 note_mouse_highlight (struct frame *f, int x, int y)
31221 Mouse_HLInfo *hlinfo = MOUSE_HL_INFO (f);
31222 enum window_part part = ON_NOTHING;
31223 Lisp_Object window;
31224 struct window *w;
31225 Cursor cursor = No_Cursor;
31226 Lisp_Object pointer = Qnil; /* Takes precedence over cursor! */
31227 struct buffer *b;
31229 /* When a menu is active, don't highlight because this looks odd. */
31230 #if defined (USE_X_TOOLKIT) || defined (USE_GTK) || defined (HAVE_NS) || defined (MSDOS)
31231 if (popup_activated ())
31232 return;
31233 #endif
31235 if (!f->glyphs_initialized_p
31236 || f->pointer_invisible)
31237 return;
31239 hlinfo->mouse_face_mouse_x = x;
31240 hlinfo->mouse_face_mouse_y = y;
31241 hlinfo->mouse_face_mouse_frame = f;
31243 if (hlinfo->mouse_face_defer)
31244 return;
31246 /* Which window is that in? */
31247 window = window_from_coordinates (f, x, y, &part, true);
31249 /* If displaying active text in another window, clear that. */
31250 if (! EQ (window, hlinfo->mouse_face_window)
31251 /* Also clear if we move out of text area in same window. */
31252 || (!NILP (hlinfo->mouse_face_window)
31253 && !NILP (window)
31254 && part != ON_TEXT
31255 && part != ON_MODE_LINE
31256 && part != ON_HEADER_LINE))
31257 clear_mouse_face (hlinfo);
31259 /* Reset help_echo_string. It will get recomputed below. */
31260 help_echo_string = Qnil;
31262 #ifdef HAVE_WINDOW_SYSTEM
31263 /* If the cursor is on the internal border of FRAME and FRAME's
31264 internal border is draggable, provide some visual feedback. */
31265 if (FRAME_INTERNAL_BORDER_WIDTH (f) > 0
31266 && !NILP (get_frame_param (f, Qdrag_internal_border)))
31268 enum internal_border_part part = frame_internal_border_part (f, x, y);
31270 switch (part)
31272 case INTERNAL_BORDER_NONE:
31273 if (cursor != FRAME_X_OUTPUT (f)->nontext_cursor)
31274 /* Reset cursor. */
31275 cursor = FRAME_X_OUTPUT (f)->nontext_cursor;
31276 break;
31277 case INTERNAL_BORDER_LEFT_EDGE:
31278 cursor = FRAME_X_OUTPUT (f)->left_edge_cursor;
31279 break;
31280 case INTERNAL_BORDER_TOP_LEFT_CORNER:
31281 cursor = FRAME_X_OUTPUT (f)->top_left_corner_cursor;
31282 break;
31283 case INTERNAL_BORDER_TOP_EDGE:
31284 cursor = FRAME_X_OUTPUT (f)->top_edge_cursor;
31285 break;
31286 case INTERNAL_BORDER_TOP_RIGHT_CORNER:
31287 cursor = FRAME_X_OUTPUT (f)->top_right_corner_cursor;
31288 break;
31289 case INTERNAL_BORDER_RIGHT_EDGE:
31290 cursor = FRAME_X_OUTPUT (f)->right_edge_cursor;
31291 break;
31292 case INTERNAL_BORDER_BOTTOM_RIGHT_CORNER:
31293 cursor = FRAME_X_OUTPUT (f)->bottom_right_corner_cursor;
31294 break;
31295 case INTERNAL_BORDER_BOTTOM_EDGE:
31296 cursor = FRAME_X_OUTPUT (f)->bottom_edge_cursor;
31297 break;
31298 case INTERNAL_BORDER_BOTTOM_LEFT_CORNER:
31299 cursor = FRAME_X_OUTPUT (f)->bottom_left_corner_cursor;
31300 break;
31301 default:
31302 /* This should not happen. */
31303 if (cursor != FRAME_X_OUTPUT (f)->nontext_cursor)
31304 cursor = FRAME_X_OUTPUT (f)->nontext_cursor;
31307 if (cursor != FRAME_X_OUTPUT (f)->nontext_cursor)
31309 /* Do we really want a help echo here? */
31310 help_echo_string = build_string ("drag-mouse-1: resize frame");
31311 goto set_cursor;
31314 #endif /* HAVE_WINDOW_SYSTEM */
31316 /* Not on a window -> return. */
31317 if (!WINDOWP (window))
31318 return;
31320 /* Convert to window-relative pixel coordinates. */
31321 w = XWINDOW (window);
31322 frame_to_window_pixel_xy (w, &x, &y);
31324 #if defined (HAVE_WINDOW_SYSTEM) && ! defined (USE_GTK) && ! defined (HAVE_NS)
31325 /* Handle tool-bar window differently since it doesn't display a
31326 buffer. */
31327 if (EQ (window, f->tool_bar_window))
31329 note_tool_bar_highlight (f, x, y);
31330 return;
31332 #endif
31334 /* Mouse is on the mode, header line or margin? */
31335 if (part == ON_MODE_LINE || part == ON_HEADER_LINE
31336 || part == ON_LEFT_MARGIN || part == ON_RIGHT_MARGIN)
31338 note_mode_line_or_margin_highlight (window, x, y, part);
31340 #ifdef HAVE_WINDOW_SYSTEM
31341 if (part == ON_LEFT_MARGIN || part == ON_RIGHT_MARGIN)
31343 cursor = FRAME_X_OUTPUT (f)->nontext_cursor;
31344 /* Show non-text cursor (Bug#16647). */
31345 goto set_cursor;
31347 else
31348 #endif
31349 return;
31352 #ifdef HAVE_WINDOW_SYSTEM
31353 if (part == ON_VERTICAL_BORDER)
31355 cursor = FRAME_X_OUTPUT (f)->horizontal_drag_cursor;
31356 help_echo_string = build_string ("drag-mouse-1: resize");
31357 goto set_cursor;
31359 else if (part == ON_RIGHT_DIVIDER)
31361 cursor = FRAME_X_OUTPUT (f)->horizontal_drag_cursor;
31362 help_echo_string = build_string ("drag-mouse-1: resize");
31363 goto set_cursor;
31365 else if (part == ON_BOTTOM_DIVIDER)
31366 if (! WINDOW_BOTTOMMOST_P (w)
31367 || minibuf_level
31368 || NILP (Vresize_mini_windows))
31370 cursor = FRAME_X_OUTPUT (f)->vertical_drag_cursor;
31371 help_echo_string = build_string ("drag-mouse-1: resize");
31372 goto set_cursor;
31374 else
31375 cursor = FRAME_X_OUTPUT (f)->nontext_cursor;
31376 else if (part == ON_LEFT_FRINGE || part == ON_RIGHT_FRINGE
31377 || part == ON_VERTICAL_SCROLL_BAR
31378 || part == ON_HORIZONTAL_SCROLL_BAR)
31379 cursor = FRAME_X_OUTPUT (f)->nontext_cursor;
31380 else
31381 cursor = FRAME_X_OUTPUT (f)->text_cursor;
31382 #endif
31384 /* Are we in a window whose display is up to date?
31385 And verify the buffer's text has not changed. */
31386 b = XBUFFER (w->contents);
31387 if (part == ON_TEXT && w->window_end_valid && !window_outdated (w))
31389 int hpos, vpos, dx, dy, area = LAST_AREA;
31390 ptrdiff_t pos;
31391 struct glyph *glyph;
31392 Lisp_Object object;
31393 Lisp_Object mouse_face = Qnil, position;
31394 Lisp_Object *overlay_vec = NULL;
31395 ptrdiff_t i, noverlays;
31396 struct buffer *obuf;
31397 ptrdiff_t obegv, ozv;
31398 bool same_region;
31400 /* Find the glyph under X/Y. */
31401 glyph = x_y_to_hpos_vpos (w, x, y, &hpos, &vpos, &dx, &dy, &area);
31403 #ifdef HAVE_WINDOW_SYSTEM
31404 /* Look for :pointer property on image. */
31405 if (glyph != NULL && glyph->type == IMAGE_GLYPH)
31407 struct image *img = IMAGE_OPT_FROM_ID (f, glyph->u.img_id);
31408 if (img != NULL && IMAGEP (img->spec))
31410 Lisp_Object image_map, hotspot;
31411 if ((image_map = Fplist_get (XCDR (img->spec), QCmap),
31412 !NILP (image_map))
31413 && (hotspot = find_hot_spot (image_map,
31414 glyph->slice.img.x + dx,
31415 glyph->slice.img.y + dy),
31416 CONSP (hotspot))
31417 && (hotspot = XCDR (hotspot), CONSP (hotspot)))
31419 Lisp_Object plist;
31421 /* Could check XCAR (hotspot) to see if we enter/leave
31422 this hot-spot.
31423 If so, we could look for mouse-enter, mouse-leave
31424 properties in PLIST (and do something...). */
31425 hotspot = XCDR (hotspot);
31426 if (CONSP (hotspot)
31427 && (plist = XCAR (hotspot), CONSP (plist)))
31429 pointer = Fplist_get (plist, Qpointer);
31430 if (NILP (pointer))
31431 pointer = Qhand;
31432 help_echo_string = Fplist_get (plist, Qhelp_echo);
31433 if (!NILP (help_echo_string))
31435 help_echo_window = window;
31436 help_echo_object = glyph->object;
31437 help_echo_pos = glyph->charpos;
31441 if (NILP (pointer))
31442 pointer = Fplist_get (XCDR (img->spec), QCpointer);
31445 #endif /* HAVE_WINDOW_SYSTEM */
31447 /* Clear mouse face if X/Y not over text. */
31448 if (glyph == NULL
31449 || area != TEXT_AREA
31450 || !MATRIX_ROW_DISPLAYS_TEXT_P (MATRIX_ROW (w->current_matrix, vpos))
31451 /* Glyph's OBJECT is nil for glyphs inserted by the
31452 display engine for its internal purposes, like truncation
31453 and continuation glyphs and blanks beyond the end of
31454 line's text on text terminals. If we are over such a
31455 glyph, we are not over any text. */
31456 || NILP (glyph->object)
31457 /* R2L rows have a stretch glyph at their front, which
31458 stands for no text, whereas L2R rows have no glyphs at
31459 all beyond the end of text. Treat such stretch glyphs
31460 like we do with NULL glyphs in L2R rows. */
31461 || (MATRIX_ROW (w->current_matrix, vpos)->reversed_p
31462 && glyph == MATRIX_ROW_GLYPH_START (w->current_matrix, vpos)
31463 && glyph->type == STRETCH_GLYPH
31464 && glyph->avoid_cursor_p))
31466 if (clear_mouse_face (hlinfo))
31467 cursor = No_Cursor;
31468 if (FRAME_WINDOW_P (f) && NILP (pointer))
31470 #ifdef HAVE_WINDOW_SYSTEM
31471 if (area != TEXT_AREA)
31472 cursor = FRAME_X_OUTPUT (f)->nontext_cursor;
31473 else
31474 pointer = Vvoid_text_area_pointer;
31475 #endif
31477 goto set_cursor;
31480 pos = glyph->charpos;
31481 object = glyph->object;
31482 if (!STRINGP (object) && !BUFFERP (object))
31483 goto set_cursor;
31485 /* If we get an out-of-range value, return now; avoid an error. */
31486 if (BUFFERP (object) && pos > BUF_Z (b))
31487 goto set_cursor;
31489 /* Make the window's buffer temporarily current for
31490 overlays_at and compute_char_face. */
31491 obuf = current_buffer;
31492 current_buffer = b;
31493 obegv = BEGV;
31494 ozv = ZV;
31495 BEGV = BEG;
31496 ZV = Z;
31498 /* Is this char mouse-active or does it have help-echo? */
31499 position = make_number (pos);
31501 USE_SAFE_ALLOCA;
31503 if (BUFFERP (object))
31505 /* Put all the overlays we want in a vector in overlay_vec. */
31506 GET_OVERLAYS_AT (pos, overlay_vec, noverlays, NULL, false);
31507 /* Sort overlays into increasing priority order. */
31508 noverlays = sort_overlays (overlay_vec, noverlays, w);
31510 else
31511 noverlays = 0;
31513 if (NILP (Vmouse_highlight))
31515 clear_mouse_face (hlinfo);
31516 goto check_help_echo;
31519 same_region = coords_in_mouse_face_p (w, hpos, vpos);
31521 if (same_region)
31522 cursor = No_Cursor;
31524 /* Check mouse-face highlighting. */
31525 if (! same_region
31526 /* If there exists an overlay with mouse-face overlapping
31527 the one we are currently highlighting, we have to check
31528 if we enter the overlapping overlay, and then highlight
31529 only that. Skip the check when mouse-face highlighting
31530 is currently hidden to avoid Bug#30519. */
31531 || (!hlinfo->mouse_face_hidden
31532 && OVERLAYP (hlinfo->mouse_face_overlay)
31533 && mouse_face_overlay_overlaps (hlinfo->mouse_face_overlay)))
31535 /* Find the highest priority overlay with a mouse-face. */
31536 Lisp_Object overlay = Qnil;
31537 for (i = noverlays - 1; i >= 0 && NILP (overlay); --i)
31539 mouse_face = Foverlay_get (overlay_vec[i], Qmouse_face);
31540 if (!NILP (mouse_face))
31541 overlay = overlay_vec[i];
31544 /* If we're highlighting the same overlay as before, there's
31545 no need to do that again. */
31546 if (!NILP (overlay) && EQ (overlay, hlinfo->mouse_face_overlay))
31547 goto check_help_echo;
31549 /* Clear the display of the old active region, if any. */
31550 if (clear_mouse_face (hlinfo))
31551 cursor = No_Cursor;
31553 /* Record the overlay, if any, to be highlighted. */
31554 hlinfo->mouse_face_overlay = overlay;
31556 /* If no overlay applies, get a text property. */
31557 if (NILP (overlay))
31558 mouse_face = Fget_text_property (position, Qmouse_face, object);
31560 /* Next, compute the bounds of the mouse highlighting and
31561 display it. */
31562 if (!NILP (mouse_face) && STRINGP (object))
31564 /* The mouse-highlighting comes from a display string
31565 with a mouse-face. */
31566 Lisp_Object s, e;
31567 ptrdiff_t ignore;
31569 s = Fprevious_single_property_change
31570 (make_number (pos + 1), Qmouse_face, object, Qnil);
31571 e = Fnext_single_property_change
31572 (position, Qmouse_face, object, Qnil);
31573 if (NILP (s))
31574 s = make_number (0);
31575 if (NILP (e))
31576 e = make_number (SCHARS (object));
31577 mouse_face_from_string_pos (w, hlinfo, object,
31578 XINT (s), XINT (e));
31579 hlinfo->mouse_face_past_end = false;
31580 hlinfo->mouse_face_window = window;
31581 hlinfo->mouse_face_face_id
31582 = face_at_string_position (w, object, pos, 0, &ignore,
31583 glyph->face_id, true);
31584 show_mouse_face (hlinfo, DRAW_MOUSE_FACE);
31585 cursor = No_Cursor;
31587 else
31589 /* The mouse-highlighting, if any, comes from an overlay
31590 or text property in the buffer. */
31591 Lisp_Object buffer UNINIT;
31592 Lisp_Object disp_string UNINIT;
31594 if (STRINGP (object))
31596 /* If we are on a display string with no mouse-face,
31597 check if the text under it has one. */
31598 struct glyph_row *r = MATRIX_ROW (w->current_matrix, vpos);
31599 ptrdiff_t start = MATRIX_ROW_START_CHARPOS (r);
31600 pos = string_buffer_position (object, start);
31601 if (pos > 0)
31603 mouse_face = get_char_property_and_overlay
31604 (make_number (pos), Qmouse_face, w->contents, &overlay);
31605 buffer = w->contents;
31606 disp_string = object;
31609 else
31611 buffer = object;
31612 disp_string = Qnil;
31615 if (!NILP (mouse_face))
31617 Lisp_Object before, after;
31618 Lisp_Object before_string, after_string;
31619 /* To correctly find the limits of mouse highlight
31620 in a bidi-reordered buffer, we must not use the
31621 optimization of limiting the search in
31622 previous-single-property-change and
31623 next-single-property-change, because
31624 rows_from_pos_range needs the real start and end
31625 positions to DTRT in this case. That's because
31626 the first row visible in a window does not
31627 necessarily display the character whose position
31628 is the smallest. */
31629 Lisp_Object lim1
31630 = NILP (BVAR (XBUFFER (buffer), bidi_display_reordering))
31631 ? Fmarker_position (w->start)
31632 : Qnil;
31633 Lisp_Object lim2
31634 = NILP (BVAR (XBUFFER (buffer), bidi_display_reordering))
31635 ? make_number (BUF_Z (XBUFFER (buffer))
31636 - w->window_end_pos)
31637 : Qnil;
31639 if (NILP (overlay))
31641 /* Handle the text property case. */
31642 before = Fprevious_single_property_change
31643 (make_number (pos + 1), Qmouse_face, buffer, lim1);
31644 after = Fnext_single_property_change
31645 (make_number (pos), Qmouse_face, buffer, lim2);
31646 before_string = after_string = Qnil;
31648 else
31650 /* Handle the overlay case. */
31651 before = Foverlay_start (overlay);
31652 after = Foverlay_end (overlay);
31653 before_string = Foverlay_get (overlay, Qbefore_string);
31654 after_string = Foverlay_get (overlay, Qafter_string);
31656 if (!STRINGP (before_string)) before_string = Qnil;
31657 if (!STRINGP (after_string)) after_string = Qnil;
31660 mouse_face_from_buffer_pos (window, hlinfo, pos,
31661 NILP (before)
31663 : XFASTINT (before),
31664 NILP (after)
31665 ? BUF_Z (XBUFFER (buffer))
31666 : XFASTINT (after),
31667 before_string, after_string,
31668 disp_string);
31669 cursor = No_Cursor;
31674 check_help_echo:
31676 /* Look for a `help-echo' property. */
31677 if (NILP (help_echo_string)) {
31678 Lisp_Object help, overlay;
31680 /* Check overlays first. */
31681 help = overlay = Qnil;
31682 for (i = noverlays - 1; i >= 0 && NILP (help); --i)
31684 overlay = overlay_vec[i];
31685 help = Foverlay_get (overlay, Qhelp_echo);
31688 if (!NILP (help))
31690 help_echo_string = help;
31691 help_echo_window = window;
31692 help_echo_object = overlay;
31693 help_echo_pos = pos;
31695 else
31697 Lisp_Object obj = glyph->object;
31698 ptrdiff_t charpos = glyph->charpos;
31700 /* Try text properties. */
31701 if (STRINGP (obj)
31702 && charpos >= 0
31703 && charpos < SCHARS (obj))
31705 help = Fget_text_property (make_number (charpos),
31706 Qhelp_echo, obj);
31707 if (NILP (help))
31709 /* If the string itself doesn't specify a help-echo,
31710 see if the buffer text ``under'' it does. */
31711 struct glyph_row *r
31712 = MATRIX_ROW (w->current_matrix, vpos);
31713 ptrdiff_t start = MATRIX_ROW_START_CHARPOS (r);
31714 ptrdiff_t p = string_buffer_position (obj, start);
31715 if (p > 0)
31717 help = Fget_char_property (make_number (p),
31718 Qhelp_echo, w->contents);
31719 if (!NILP (help))
31721 charpos = p;
31722 obj = w->contents;
31727 else if (BUFFERP (obj)
31728 && charpos >= BEGV
31729 && charpos < ZV)
31730 help = Fget_text_property (make_number (charpos), Qhelp_echo,
31731 obj);
31733 if (!NILP (help))
31735 help_echo_string = help;
31736 help_echo_window = window;
31737 help_echo_object = obj;
31738 help_echo_pos = charpos;
31743 #ifdef HAVE_WINDOW_SYSTEM
31744 /* Look for a `pointer' property. */
31745 if (FRAME_WINDOW_P (f) && NILP (pointer))
31747 /* Check overlays first. */
31748 for (i = noverlays - 1; i >= 0 && NILP (pointer); --i)
31749 pointer = Foverlay_get (overlay_vec[i], Qpointer);
31751 if (NILP (pointer))
31753 Lisp_Object obj = glyph->object;
31754 ptrdiff_t charpos = glyph->charpos;
31756 /* Try text properties. */
31757 if (STRINGP (obj)
31758 && charpos >= 0
31759 && charpos < SCHARS (obj))
31761 pointer = Fget_text_property (make_number (charpos),
31762 Qpointer, obj);
31763 if (NILP (pointer))
31765 /* If the string itself doesn't specify a pointer,
31766 see if the buffer text ``under'' it does. */
31767 struct glyph_row *r
31768 = MATRIX_ROW (w->current_matrix, vpos);
31769 ptrdiff_t start = MATRIX_ROW_START_CHARPOS (r);
31770 ptrdiff_t p = string_buffer_position (obj, start);
31771 if (p > 0)
31772 pointer = Fget_char_property (make_number (p),
31773 Qpointer, w->contents);
31776 else if (BUFFERP (obj)
31777 && charpos >= BEGV
31778 && charpos < ZV)
31779 pointer = Fget_text_property (make_number (charpos),
31780 Qpointer, obj);
31783 #endif /* HAVE_WINDOW_SYSTEM */
31785 BEGV = obegv;
31786 ZV = ozv;
31787 current_buffer = obuf;
31788 SAFE_FREE ();
31791 set_cursor:
31792 define_frame_cursor1 (f, cursor, pointer);
31796 /* EXPORT for RIF:
31797 Clear any mouse-face on window W. This function is part of the
31798 redisplay interface, and is called from try_window_id and similar
31799 functions to ensure the mouse-highlight is off. */
31801 void
31802 x_clear_window_mouse_face (struct window *w)
31804 Mouse_HLInfo *hlinfo = MOUSE_HL_INFO (XFRAME (w->frame));
31805 Lisp_Object window;
31807 block_input ();
31808 XSETWINDOW (window, w);
31809 if (EQ (window, hlinfo->mouse_face_window))
31810 clear_mouse_face (hlinfo);
31811 unblock_input ();
31815 /* EXPORT:
31816 Just discard the mouse face information for frame F, if any.
31817 This is used when the size of F is changed. */
31819 void
31820 cancel_mouse_face (struct frame *f)
31822 Lisp_Object window;
31823 Mouse_HLInfo *hlinfo = MOUSE_HL_INFO (f);
31825 window = hlinfo->mouse_face_window;
31826 if (! NILP (window) && XFRAME (XWINDOW (window)->frame) == f)
31827 reset_mouse_highlight (hlinfo);
31832 /***********************************************************************
31833 Exposure Events
31834 ***********************************************************************/
31836 #ifdef HAVE_WINDOW_SYSTEM
31838 /* Redraw the part of glyph row area AREA of glyph row ROW on window W
31839 which intersects rectangle R. R is in window-relative coordinates. */
31841 static void
31842 expose_area (struct window *w, struct glyph_row *row, XRectangle *r,
31843 enum glyph_row_area area)
31845 struct glyph *first = row->glyphs[area];
31846 struct glyph *end = row->glyphs[area] + row->used[area];
31847 struct glyph *last;
31848 int first_x, start_x, x;
31850 if (area == TEXT_AREA && row->fill_line_p)
31851 /* If row extends face to end of line write the whole line. */
31852 draw_glyphs (w, 0, row, area,
31853 0, row->used[area],
31854 DRAW_NORMAL_TEXT, 0);
31855 else
31857 /* Set START_X to the window-relative start position for drawing glyphs of
31858 AREA. The first glyph of the text area can be partially visible.
31859 The first glyphs of other areas cannot. */
31860 start_x = window_box_left_offset (w, area);
31861 x = start_x;
31862 if (area == TEXT_AREA)
31863 x += row->x;
31865 /* Find the first glyph that must be redrawn. */
31866 while (first < end
31867 && x + first->pixel_width < r->x)
31869 x += first->pixel_width;
31870 ++first;
31873 /* Find the last one. */
31874 last = first;
31875 first_x = x;
31876 /* Use a signed int intermediate value to avoid catastrophic
31877 failures due to comparison between signed and unsigned, when
31878 x is negative (can happen for wide images that are hscrolled). */
31879 int r_end = r->x + r->width;
31880 while (last < end && x < r_end)
31882 x += last->pixel_width;
31883 ++last;
31886 /* Repaint. */
31887 if (last > first)
31888 draw_glyphs (w, first_x - start_x, row, area,
31889 first - row->glyphs[area], last - row->glyphs[area],
31890 DRAW_NORMAL_TEXT, 0);
31895 /* Redraw the parts of the glyph row ROW on window W intersecting
31896 rectangle R. R is in window-relative coordinates. Value is
31897 true if mouse-face was overwritten. */
31899 static bool
31900 expose_line (struct window *w, struct glyph_row *row, XRectangle *r)
31902 eassert (row->enabled_p);
31904 if (row->mode_line_p || w->pseudo_window_p)
31905 draw_glyphs (w, 0, row, TEXT_AREA,
31906 0, row->used[TEXT_AREA],
31907 DRAW_NORMAL_TEXT, 0);
31908 else
31910 if (row->used[LEFT_MARGIN_AREA])
31911 expose_area (w, row, r, LEFT_MARGIN_AREA);
31912 if (row->used[TEXT_AREA])
31913 expose_area (w, row, r, TEXT_AREA);
31914 if (row->used[RIGHT_MARGIN_AREA])
31915 expose_area (w, row, r, RIGHT_MARGIN_AREA);
31916 draw_row_fringe_bitmaps (w, row);
31919 return row->mouse_face_p;
31923 /* Redraw those parts of glyphs rows during expose event handling that
31924 overlap other rows. Redrawing of an exposed line writes over parts
31925 of lines overlapping that exposed line; this function fixes that.
31927 W is the window being exposed. FIRST_OVERLAPPING_ROW is the first
31928 row in W's current matrix that is exposed and overlaps other rows.
31929 LAST_OVERLAPPING_ROW is the last such row. */
31931 static void
31932 expose_overlaps (struct window *w,
31933 struct glyph_row *first_overlapping_row,
31934 struct glyph_row *last_overlapping_row,
31935 XRectangle *r)
31937 struct glyph_row *row;
31939 for (row = first_overlapping_row; row <= last_overlapping_row; ++row)
31940 if (row->overlapping_p)
31942 eassert (row->enabled_p && !row->mode_line_p);
31944 row->clip = r;
31945 if (row->used[LEFT_MARGIN_AREA])
31946 x_fix_overlapping_area (w, row, LEFT_MARGIN_AREA, OVERLAPS_BOTH);
31948 if (row->used[TEXT_AREA])
31949 x_fix_overlapping_area (w, row, TEXT_AREA, OVERLAPS_BOTH);
31951 if (row->used[RIGHT_MARGIN_AREA])
31952 x_fix_overlapping_area (w, row, RIGHT_MARGIN_AREA, OVERLAPS_BOTH);
31953 row->clip = NULL;
31958 /* Return true if W's cursor intersects rectangle R. */
31960 static bool
31961 phys_cursor_in_rect_p (struct window *w, XRectangle *r)
31963 XRectangle cr, result;
31964 struct glyph *cursor_glyph;
31965 struct glyph_row *row;
31967 if (w->phys_cursor.vpos >= 0
31968 && w->phys_cursor.vpos < w->current_matrix->nrows
31969 && (row = MATRIX_ROW (w->current_matrix, w->phys_cursor.vpos),
31970 row->enabled_p)
31971 && row->cursor_in_fringe_p)
31973 /* Cursor is in the fringe. */
31974 cr.x = window_box_right_offset (w,
31975 (WINDOW_HAS_FRINGES_OUTSIDE_MARGINS (w)
31976 ? RIGHT_MARGIN_AREA
31977 : TEXT_AREA));
31978 cr.y = row->y;
31979 cr.width = WINDOW_RIGHT_FRINGE_WIDTH (w);
31980 cr.height = row->height;
31981 return x_intersect_rectangles (&cr, r, &result);
31984 cursor_glyph = get_phys_cursor_glyph (w);
31985 if (cursor_glyph)
31987 /* r is relative to W's box, but w->phys_cursor.x is relative
31988 to left edge of W's TEXT area. Adjust it. */
31989 cr.x = window_box_left_offset (w, TEXT_AREA) + w->phys_cursor.x;
31990 cr.y = w->phys_cursor.y;
31991 cr.width = cursor_glyph->pixel_width;
31992 cr.height = w->phys_cursor_height;
31993 /* ++KFS: W32 version used W32-specific IntersectRect here, but
31994 I assume the effect is the same -- and this is portable. */
31995 return x_intersect_rectangles (&cr, r, &result);
31997 /* If we don't understand the format, pretend we're not in the hot-spot. */
31998 return false;
32002 /* EXPORT:
32003 Draw a vertical window border to the right of window W if W doesn't
32004 have vertical scroll bars. */
32006 void
32007 x_draw_vertical_border (struct window *w)
32009 struct frame *f = XFRAME (WINDOW_FRAME (w));
32011 /* We could do better, if we knew what type of scroll-bar the adjacent
32012 windows (on either side) have... But we don't :-(
32013 However, I think this works ok. ++KFS 2003-04-25 */
32015 /* Redraw borders between horizontally adjacent windows. Don't
32016 do it for frames with vertical scroll bars because either the
32017 right scroll bar of a window, or the left scroll bar of its
32018 neighbor will suffice as a border. */
32019 if (FRAME_HAS_VERTICAL_SCROLL_BARS (f) || FRAME_RIGHT_DIVIDER_WIDTH (f))
32020 return;
32022 /* Note: It is necessary to redraw both the left and the right
32023 borders, for when only this single window W is being
32024 redisplayed. */
32025 if (!WINDOW_RIGHTMOST_P (w)
32026 && !WINDOW_HAS_VERTICAL_SCROLL_BAR_ON_RIGHT (w))
32028 int x0, x1, y0, y1;
32030 window_box_edges (w, &x0, &y0, &x1, &y1);
32031 y1 -= 1;
32033 if (WINDOW_LEFT_FRINGE_WIDTH (w) == 0)
32034 x1 -= 1;
32036 FRAME_RIF (f)->draw_vertical_window_border (w, x1, y0, y1);
32039 if (!WINDOW_LEFTMOST_P (w)
32040 && !WINDOW_HAS_VERTICAL_SCROLL_BAR_ON_LEFT (w))
32042 int x0, x1, y0, y1;
32044 window_box_edges (w, &x0, &y0, &x1, &y1);
32045 y1 -= 1;
32047 if (WINDOW_LEFT_FRINGE_WIDTH (w) == 0)
32048 x0 -= 1;
32050 FRAME_RIF (f)->draw_vertical_window_border (w, x0, y0, y1);
32055 /* Draw window dividers for window W. */
32057 void
32058 x_draw_right_divider (struct window *w)
32060 struct frame *f = WINDOW_XFRAME (w);
32062 if (w->mini || w->pseudo_window_p)
32063 return;
32064 else if (WINDOW_RIGHT_DIVIDER_WIDTH (w))
32066 int x0 = WINDOW_RIGHT_EDGE_X (w) - WINDOW_RIGHT_DIVIDER_WIDTH (w);
32067 int x1 = WINDOW_RIGHT_EDGE_X (w);
32068 int y0 = WINDOW_TOP_EDGE_Y (w);
32069 int y1 = WINDOW_BOTTOM_EDGE_Y (w);
32071 /* If W is horizontally combined and has a right sibling, don't
32072 draw over any bottom divider. */
32073 if (WINDOW_BOTTOM_DIVIDER_WIDTH (w)
32074 && !NILP (w->parent)
32075 && WINDOW_HORIZONTAL_COMBINATION_P (XWINDOW (w->parent))
32076 && !NILP (w->next))
32077 y1 -= WINDOW_BOTTOM_DIVIDER_WIDTH (w);
32079 FRAME_RIF (f)->draw_window_divider (w, x0, x1, y0, y1);
32083 static void
32084 x_draw_bottom_divider (struct window *w)
32086 struct frame *f = XFRAME (WINDOW_FRAME (w));
32088 if (w->mini || w->pseudo_window_p)
32089 return;
32090 else if (WINDOW_BOTTOM_DIVIDER_WIDTH (w))
32092 int x0 = WINDOW_LEFT_EDGE_X (w);
32093 int x1 = WINDOW_RIGHT_EDGE_X (w);
32094 int y0 = WINDOW_BOTTOM_EDGE_Y (w) - WINDOW_BOTTOM_DIVIDER_WIDTH (w);
32095 int y1 = WINDOW_BOTTOM_EDGE_Y (w);
32096 struct window *p = !NILP (w->parent) ? XWINDOW (w->parent) : NULL;
32098 /* If W is vertically combined and has a sibling below, don't draw
32099 over any right divider. */
32100 if (WINDOW_RIGHT_DIVIDER_WIDTH (w)
32101 && p
32102 && ((WINDOW_VERTICAL_COMBINATION_P (p)
32103 && !NILP (w->next))
32104 || (WINDOW_HORIZONTAL_COMBINATION_P (p)
32105 && NILP (w->next)
32106 && !NILP (p->parent)
32107 && WINDOW_VERTICAL_COMBINATION_P (XWINDOW (p->parent))
32108 && !NILP (XWINDOW (p->parent)->next))))
32109 x1 -= WINDOW_RIGHT_DIVIDER_WIDTH (w);
32111 FRAME_RIF (f)->draw_window_divider (w, x0, x1, y0, y1);
32115 /* Redraw the part of window W intersection rectangle FR. Pixel
32116 coordinates in FR are frame-relative. Call this function with
32117 input blocked. Value is true if the exposure overwrites
32118 mouse-face. */
32120 static bool
32121 expose_window (struct window *w, XRectangle *fr)
32123 struct frame *f = XFRAME (w->frame);
32124 XRectangle wr, r;
32125 bool mouse_face_overwritten_p = false;
32127 /* If window is not yet fully initialized, do nothing. This can
32128 happen when toolkit scroll bars are used and a window is split.
32129 Reconfiguring the scroll bar will generate an expose for a newly
32130 created window. */
32131 if (w->current_matrix == NULL)
32132 return false;
32134 /* When we're currently updating the window, display and current
32135 matrix usually don't agree. Arrange for a thorough display
32136 later. */
32137 if (w->must_be_updated_p)
32139 SET_FRAME_GARBAGED (f);
32140 return false;
32143 /* Frame-relative pixel rectangle of W. */
32144 wr.x = WINDOW_LEFT_EDGE_X (w);
32145 wr.y = WINDOW_TOP_EDGE_Y (w);
32146 wr.width = WINDOW_PIXEL_WIDTH (w);
32147 wr.height = WINDOW_PIXEL_HEIGHT (w);
32149 if (x_intersect_rectangles (fr, &wr, &r))
32151 int yb = window_text_bottom_y (w);
32152 struct glyph_row *row;
32153 struct glyph_row *first_overlapping_row, *last_overlapping_row;
32155 TRACE ((stderr, "expose_window (%d, %d, %d, %d)\n",
32156 r.x, r.y, r.width, r.height));
32158 /* Convert to window coordinates. */
32159 r.x -= WINDOW_LEFT_EDGE_X (w);
32160 r.y -= WINDOW_TOP_EDGE_Y (w);
32162 /* Turn off the cursor. */
32163 bool cursor_cleared_p = (!w->pseudo_window_p
32164 && phys_cursor_in_rect_p (w, &r));
32165 if (cursor_cleared_p)
32166 x_clear_cursor (w);
32168 /* If the row containing the cursor extends face to end of line,
32169 then expose_area might overwrite the cursor outside the
32170 rectangle and thus notice_overwritten_cursor might clear
32171 w->phys_cursor_on_p. We remember the original value and
32172 check later if it is changed. */
32173 bool phys_cursor_on_p = w->phys_cursor_on_p;
32175 /* Use a signed int intermediate value to avoid catastrophic
32176 failures due to comparison between signed and unsigned, when
32177 y0 or y1 is negative (can happen for tall images). */
32178 int r_bottom = r.y + r.height;
32180 /* Update lines intersecting rectangle R. */
32181 first_overlapping_row = last_overlapping_row = NULL;
32182 for (row = w->current_matrix->rows;
32183 row->enabled_p;
32184 ++row)
32186 int y0 = row->y;
32187 int y1 = MATRIX_ROW_BOTTOM_Y (row);
32189 if ((y0 >= r.y && y0 < r_bottom)
32190 || (y1 > r.y && y1 < r_bottom)
32191 || (r.y >= y0 && r.y < y1)
32192 || (r_bottom > y0 && r_bottom < y1))
32194 /* A header line may be overlapping, but there is no need
32195 to fix overlapping areas for them. KFS 2005-02-12 */
32196 if (row->overlapping_p && !row->mode_line_p)
32198 if (first_overlapping_row == NULL)
32199 first_overlapping_row = row;
32200 last_overlapping_row = row;
32203 row->clip = fr;
32204 if (expose_line (w, row, &r))
32205 mouse_face_overwritten_p = true;
32206 row->clip = NULL;
32208 else if (row->overlapping_p)
32210 /* We must redraw a row overlapping the exposed area. */
32211 if (y0 < r.y
32212 ? y0 + row->phys_height > r.y
32213 : y0 + row->ascent - row->phys_ascent < r.y +r.height)
32215 if (first_overlapping_row == NULL)
32216 first_overlapping_row = row;
32217 last_overlapping_row = row;
32221 if (y1 >= yb)
32222 break;
32225 /* Display the mode line if there is one. */
32226 if (window_wants_mode_line (w)
32227 && (row = MATRIX_MODE_LINE_ROW (w->current_matrix),
32228 row->enabled_p)
32229 && row->y < r_bottom)
32231 if (expose_line (w, row, &r))
32232 mouse_face_overwritten_p = true;
32235 if (!w->pseudo_window_p)
32237 /* Fix the display of overlapping rows. */
32238 if (first_overlapping_row)
32239 expose_overlaps (w, first_overlapping_row, last_overlapping_row,
32240 fr);
32242 /* Draw border between windows. */
32243 if (WINDOW_RIGHT_DIVIDER_WIDTH (w))
32244 x_draw_right_divider (w);
32245 else
32246 x_draw_vertical_border (w);
32248 if (WINDOW_BOTTOM_DIVIDER_WIDTH (w))
32249 x_draw_bottom_divider (w);
32251 /* Turn the cursor on again. */
32252 if (cursor_cleared_p
32253 || (phys_cursor_on_p && !w->phys_cursor_on_p))
32254 update_window_cursor (w, true);
32258 return mouse_face_overwritten_p;
32263 /* Redraw (parts) of all windows in the window tree rooted at W that
32264 intersect R. R contains frame pixel coordinates. Value is
32265 true if the exposure overwrites mouse-face. */
32267 static bool
32268 expose_window_tree (struct window *w, XRectangle *r)
32270 struct frame *f = XFRAME (w->frame);
32271 bool mouse_face_overwritten_p = false;
32273 while (w && !FRAME_GARBAGED_P (f))
32275 mouse_face_overwritten_p
32276 |= (WINDOWP (w->contents)
32277 ? expose_window_tree (XWINDOW (w->contents), r)
32278 : expose_window (w, r));
32280 w = NILP (w->next) ? NULL : XWINDOW (w->next);
32283 return mouse_face_overwritten_p;
32287 /* EXPORT:
32288 Redisplay an exposed area of frame F. X and Y are the upper-left
32289 corner of the exposed rectangle. W and H are width and height of
32290 the exposed area. All are pixel values. W or H zero means redraw
32291 the entire frame. */
32293 void
32294 expose_frame (struct frame *f, int x, int y, int w, int h)
32296 XRectangle r;
32297 bool mouse_face_overwritten_p = false;
32299 TRACE ((stderr, "expose_frame "));
32301 /* No need to redraw if frame will be redrawn soon. */
32302 if (FRAME_GARBAGED_P (f))
32304 TRACE ((stderr, " garbaged\n"));
32305 return;
32308 /* If basic faces haven't been realized yet, there is no point in
32309 trying to redraw anything. This can happen when we get an expose
32310 event while Emacs is starting, e.g. by moving another window. */
32311 if (FRAME_FACE_CACHE (f) == NULL
32312 || FRAME_FACE_CACHE (f)->used < BASIC_FACE_ID_SENTINEL)
32314 TRACE ((stderr, " no faces\n"));
32315 return;
32318 if (w == 0 || h == 0)
32320 r.x = r.y = 0;
32321 r.width = FRAME_TEXT_WIDTH (f);
32322 r.height = FRAME_TEXT_HEIGHT (f);
32324 else
32326 r.x = x;
32327 r.y = y;
32328 r.width = w;
32329 r.height = h;
32332 TRACE ((stderr, "(%d, %d, %d, %d)\n", r.x, r.y, r.width, r.height));
32333 mouse_face_overwritten_p = expose_window_tree (XWINDOW (f->root_window), &r);
32335 #if ! defined (USE_GTK) && ! defined (HAVE_NS)
32336 if (WINDOWP (f->tool_bar_window))
32337 mouse_face_overwritten_p
32338 |= expose_window (XWINDOW (f->tool_bar_window), &r);
32339 #endif
32341 #ifdef HAVE_X_WINDOWS
32342 #ifndef MSDOS
32343 #if ! defined (USE_X_TOOLKIT) && ! defined (USE_GTK)
32344 if (WINDOWP (f->menu_bar_window))
32345 mouse_face_overwritten_p
32346 |= expose_window (XWINDOW (f->menu_bar_window), &r);
32347 #endif /* not USE_X_TOOLKIT and not USE_GTK */
32348 #endif
32349 #endif
32351 /* Some window managers support a focus-follows-mouse style with
32352 delayed raising of frames. Imagine a partially obscured frame,
32353 and moving the mouse into partially obscured mouse-face on that
32354 frame. The visible part of the mouse-face will be highlighted,
32355 then the WM raises the obscured frame. With at least one WM, KDE
32356 2.1, Emacs is not getting any event for the raising of the frame
32357 (even tried with SubstructureRedirectMask), only Expose events.
32358 These expose events will draw text normally, i.e. not
32359 highlighted. Which means we must redo the highlight here.
32360 Subsume it under ``we love X''. --gerd 2001-08-15 */
32361 /* Included in Windows version because Windows most likely does not
32362 do the right thing if any third party tool offers
32363 focus-follows-mouse with delayed raise. --jason 2001-10-12 */
32364 if (mouse_face_overwritten_p && !FRAME_GARBAGED_P (f))
32366 Mouse_HLInfo *hlinfo = MOUSE_HL_INFO (f);
32367 if (f == hlinfo->mouse_face_mouse_frame)
32369 int mouse_x = hlinfo->mouse_face_mouse_x;
32370 int mouse_y = hlinfo->mouse_face_mouse_y;
32371 clear_mouse_face (hlinfo);
32372 note_mouse_highlight (f, mouse_x, mouse_y);
32378 /* EXPORT:
32379 Determine the intersection of two rectangles R1 and R2. Return
32380 the intersection in *RESULT. Value is true if RESULT is not
32381 empty. */
32383 bool
32384 x_intersect_rectangles (XRectangle *r1, XRectangle *r2, XRectangle *result)
32386 XRectangle *left, *right;
32387 XRectangle *upper, *lower;
32388 bool intersection_p = false;
32390 /* Rearrange so that R1 is the left-most rectangle. */
32391 if (r1->x < r2->x)
32392 left = r1, right = r2;
32393 else
32394 left = r2, right = r1;
32396 /* X0 of the intersection is right.x0, if this is inside R1,
32397 otherwise there is no intersection. */
32398 if (right->x <= left->x + left->width)
32400 result->x = right->x;
32402 /* The right end of the intersection is the minimum of
32403 the right ends of left and right. */
32404 result->width = (min (left->x + left->width, right->x + right->width)
32405 - result->x);
32407 /* Same game for Y. */
32408 if (r1->y < r2->y)
32409 upper = r1, lower = r2;
32410 else
32411 upper = r2, lower = r1;
32413 /* The upper end of the intersection is lower.y0, if this is inside
32414 of upper. Otherwise, there is no intersection. */
32415 if (lower->y <= upper->y + upper->height)
32417 result->y = lower->y;
32419 /* The lower end of the intersection is the minimum of the lower
32420 ends of upper and lower. */
32421 result->height = (min (lower->y + lower->height,
32422 upper->y + upper->height)
32423 - result->y);
32424 intersection_p = true;
32428 return intersection_p;
32431 #endif /* HAVE_WINDOW_SYSTEM */
32434 /***********************************************************************
32435 Initialization
32436 ***********************************************************************/
32438 void
32439 syms_of_xdisp (void)
32441 Vwith_echo_area_save_vector = Qnil;
32442 staticpro (&Vwith_echo_area_save_vector);
32444 Vmessage_stack = Qnil;
32445 staticpro (&Vmessage_stack);
32447 /* Non-nil means don't actually do any redisplay. */
32448 DEFSYM (Qinhibit_redisplay, "inhibit-redisplay");
32450 DEFSYM (Qredisplay_internal_xC_functionx, "redisplay_internal (C function)");
32452 DEFVAR_BOOL("inhibit-message", inhibit_message,
32453 doc: /* Non-nil means calls to `message' are not displayed.
32454 They are still logged to the *Messages* buffer.
32456 Do NOT set this globally to a non-nil value, as doing that will
32457 disable messages everywhere, including in I-search and other
32458 places where they are necessary. This variable is intended to
32459 be let-bound around code that needs to disable messages temporarily. */);
32460 inhibit_message = 0;
32462 message_dolog_marker1 = Fmake_marker ();
32463 staticpro (&message_dolog_marker1);
32464 message_dolog_marker2 = Fmake_marker ();
32465 staticpro (&message_dolog_marker2);
32466 message_dolog_marker3 = Fmake_marker ();
32467 staticpro (&message_dolog_marker3);
32469 defsubr (&Sset_buffer_redisplay);
32470 #ifdef GLYPH_DEBUG
32471 defsubr (&Sdump_frame_glyph_matrix);
32472 defsubr (&Sdump_glyph_matrix);
32473 defsubr (&Sdump_glyph_row);
32474 defsubr (&Sdump_tool_bar_row);
32475 defsubr (&Strace_redisplay);
32476 defsubr (&Strace_to_stderr);
32477 #endif
32478 #ifdef HAVE_WINDOW_SYSTEM
32479 defsubr (&Stool_bar_height);
32480 defsubr (&Slookup_image_map);
32481 #endif
32482 defsubr (&Sline_pixel_height);
32483 defsubr (&Sformat_mode_line);
32484 defsubr (&Sinvisible_p);
32485 defsubr (&Scurrent_bidi_paragraph_direction);
32486 defsubr (&Swindow_text_pixel_size);
32487 defsubr (&Smove_point_visually);
32488 defsubr (&Sbidi_find_overridden_directionality);
32490 DEFSYM (Qmenu_bar_update_hook, "menu-bar-update-hook");
32491 DEFSYM (Qoverriding_terminal_local_map, "overriding-terminal-local-map");
32492 DEFSYM (Qoverriding_local_map, "overriding-local-map");
32493 DEFSYM (Qwindow_scroll_functions, "window-scroll-functions");
32494 DEFSYM (Qredisplay_end_trigger_functions, "redisplay-end-trigger-functions");
32495 DEFSYM (Qinhibit_point_motion_hooks, "inhibit-point-motion-hooks");
32496 DEFSYM (Qeval, "eval");
32497 DEFSYM (QCdata, ":data");
32499 /* Names of text properties relevant for redisplay. */
32500 DEFSYM (Qdisplay, "display");
32501 DEFSYM (Qspace_width, "space-width");
32502 DEFSYM (Qraise, "raise");
32503 DEFSYM (Qslice, "slice");
32504 DEFSYM (Qspace, "space");
32505 DEFSYM (Qmargin, "margin");
32506 DEFSYM (Qpointer, "pointer");
32507 DEFSYM (Qleft_margin, "left-margin");
32508 DEFSYM (Qright_margin, "right-margin");
32509 DEFSYM (Qcenter, "center");
32510 DEFSYM (Qline_height, "line-height");
32511 DEFSYM (QCalign_to, ":align-to");
32512 DEFSYM (QCrelative_width, ":relative-width");
32513 DEFSYM (QCrelative_height, ":relative-height");
32514 DEFSYM (QCeval, ":eval");
32515 DEFSYM (QCpropertize, ":propertize");
32516 DEFSYM (QCfile, ":file");
32517 DEFSYM (Qfontified, "fontified");
32518 DEFSYM (Qfontification_functions, "fontification-functions");
32520 /* Name of the symbol which disables Lisp evaluation in 'display'
32521 properties. This is used by enriched.el. */
32522 DEFSYM (Qdisable_eval, "disable-eval");
32524 /* Name of the face used to highlight trailing whitespace. */
32525 DEFSYM (Qtrailing_whitespace, "trailing-whitespace");
32527 /* Names of the faces used to display line numbers. */
32528 DEFSYM (Qline_number, "line-number");
32529 DEFSYM (Qline_number_current_line, "line-number-current-line");
32530 /* Name of a text property which disables line-number display. */
32531 DEFSYM (Qdisplay_line_numbers_disable, "display-line-numbers-disable");
32533 /* Name and number of the face used to highlight escape glyphs. */
32534 DEFSYM (Qescape_glyph, "escape-glyph");
32536 /* Name and number of the face used to highlight non-breaking
32537 spaces/hyphens. */
32538 DEFSYM (Qnobreak_space, "nobreak-space");
32539 DEFSYM (Qnobreak_hyphen, "nobreak-hyphen");
32541 /* The symbol 'image' which is the car of the lists used to represent
32542 images in Lisp. Also a tool bar style. */
32543 DEFSYM (Qimage, "image");
32545 /* Tool bar styles. */
32546 DEFSYM (Qtext, "text");
32547 DEFSYM (Qboth, "both");
32548 DEFSYM (Qboth_horiz, "both-horiz");
32549 DEFSYM (Qtext_image_horiz, "text-image-horiz");
32551 /* The image map types. */
32552 DEFSYM (QCmap, ":map");
32553 DEFSYM (QCpointer, ":pointer");
32554 DEFSYM (Qrect, "rect");
32555 DEFSYM (Qcircle, "circle");
32556 DEFSYM (Qpoly, "poly");
32558 DEFSYM (Qinhibit_menubar_update, "inhibit-menubar-update");
32560 DEFSYM (Qgrow_only, "grow-only");
32561 DEFSYM (Qinhibit_eval_during_redisplay, "inhibit-eval-during-redisplay");
32562 DEFSYM (Qposition, "position");
32563 DEFSYM (Qbuffer_position, "buffer-position");
32564 DEFSYM (Qobject, "object");
32566 /* Cursor shapes. */
32567 DEFSYM (Qbar, "bar");
32568 DEFSYM (Qhbar, "hbar");
32569 DEFSYM (Qbox, "box");
32570 DEFSYM (Qhollow, "hollow");
32572 /* Pointer shapes. */
32573 DEFSYM (Qhand, "hand");
32574 DEFSYM (Qarrow, "arrow");
32575 /* also Qtext */
32577 DEFSYM (Qdragging, "dragging");
32579 DEFSYM (Qinhibit_free_realized_faces, "inhibit-free-realized-faces");
32581 list_of_error = list1 (list2 (Qerror, Qvoid_variable));
32582 staticpro (&list_of_error);
32584 /* Values of those variables at last redisplay are stored as
32585 properties on 'overlay-arrow-position' symbol. However, if
32586 Voverlay_arrow_position is a marker, last-arrow-position is its
32587 numerical position. */
32588 DEFSYM (Qlast_arrow_position, "last-arrow-position");
32589 DEFSYM (Qlast_arrow_string, "last-arrow-string");
32591 /* Alternative overlay-arrow-string and overlay-arrow-bitmap
32592 properties on a symbol in overlay-arrow-variable-list. */
32593 DEFSYM (Qoverlay_arrow_string, "overlay-arrow-string");
32594 DEFSYM (Qoverlay_arrow_bitmap, "overlay-arrow-bitmap");
32596 echo_buffer[0] = echo_buffer[1] = Qnil;
32597 staticpro (&echo_buffer[0]);
32598 staticpro (&echo_buffer[1]);
32600 echo_area_buffer[0] = echo_area_buffer[1] = Qnil;
32601 staticpro (&echo_area_buffer[0]);
32602 staticpro (&echo_area_buffer[1]);
32604 Vmessages_buffer_name = build_pure_c_string ("*Messages*");
32605 staticpro (&Vmessages_buffer_name);
32607 mode_line_proptrans_alist = Qnil;
32608 staticpro (&mode_line_proptrans_alist);
32609 mode_line_string_list = Qnil;
32610 staticpro (&mode_line_string_list);
32611 mode_line_string_face = Qnil;
32612 staticpro (&mode_line_string_face);
32613 mode_line_string_face_prop = Qnil;
32614 staticpro (&mode_line_string_face_prop);
32615 Vmode_line_unwind_vector = Qnil;
32616 staticpro (&Vmode_line_unwind_vector);
32618 DEFSYM (Qmode_line_default_help_echo, "mode-line-default-help-echo");
32620 help_echo_string = Qnil;
32621 staticpro (&help_echo_string);
32622 help_echo_object = Qnil;
32623 staticpro (&help_echo_object);
32624 help_echo_window = Qnil;
32625 staticpro (&help_echo_window);
32626 previous_help_echo_string = Qnil;
32627 staticpro (&previous_help_echo_string);
32628 help_echo_pos = -1;
32630 DEFSYM (Qright_to_left, "right-to-left");
32631 DEFSYM (Qleft_to_right, "left-to-right");
32632 defsubr (&Sbidi_resolved_levels);
32634 #ifdef HAVE_WINDOW_SYSTEM
32635 DEFVAR_BOOL ("x-stretch-cursor", x_stretch_cursor_p,
32636 doc: /* Non-nil means draw block cursor as wide as the glyph under it.
32637 For example, if a block cursor is over a tab, it will be drawn as
32638 wide as that tab on the display. */);
32639 x_stretch_cursor_p = 0;
32640 #endif
32642 DEFVAR_LISP ("show-trailing-whitespace", Vshow_trailing_whitespace,
32643 doc: /* Non-nil means highlight trailing whitespace.
32644 The face used for trailing whitespace is `trailing-whitespace'. */);
32645 Vshow_trailing_whitespace = Qnil;
32647 DEFVAR_LISP ("nobreak-char-display", Vnobreak_char_display,
32648 doc: /* Control highlighting of non-ASCII space and hyphen chars.
32649 If the value is t, Emacs highlights non-ASCII chars which have the
32650 same appearance as an ASCII space or hyphen, using the `nobreak-space'
32651 or `nobreak-hyphen' face respectively.
32653 U+00A0 (no-break space), U+00AD (soft hyphen), U+2010 (hyphen), and
32654 U+2011 (non-breaking hyphen) are affected.
32656 Any other non-nil value means to display these characters as an escape
32657 glyph followed by an ordinary space or hyphen.
32659 A value of nil means no special handling of these characters. */);
32660 Vnobreak_char_display = Qt;
32662 DEFVAR_LISP ("void-text-area-pointer", Vvoid_text_area_pointer,
32663 doc: /* The pointer shape to show in void text areas.
32664 A value of nil means to show the text pointer. Other options are
32665 `arrow', `text', `hand', `vdrag', `hdrag', `nhdrag', `modeline', and
32666 `hourglass'. */);
32667 Vvoid_text_area_pointer = Qarrow;
32669 DEFVAR_LISP ("inhibit-redisplay", Vinhibit_redisplay,
32670 doc: /* Non-nil means don't actually do any redisplay.
32671 This is used for internal purposes. */);
32672 Vinhibit_redisplay = Qnil;
32674 DEFVAR_LISP ("global-mode-string", Vglobal_mode_string,
32675 doc: /* String (or mode line construct) included (normally) in `mode-line-format'. */);
32676 Vglobal_mode_string = Qnil;
32678 DEFVAR_LISP ("overlay-arrow-position", Voverlay_arrow_position,
32679 doc: /* Marker for where to display an arrow on top of the buffer text.
32680 This must be the beginning of a line in order to work.
32681 See also `overlay-arrow-string'. */);
32682 Voverlay_arrow_position = Qnil;
32684 DEFVAR_LISP ("overlay-arrow-string", Voverlay_arrow_string,
32685 doc: /* String to display as an arrow in non-window frames.
32686 See also `overlay-arrow-position'. */);
32687 Voverlay_arrow_string = build_pure_c_string ("=>");
32689 DEFVAR_LISP ("overlay-arrow-variable-list", Voverlay_arrow_variable_list,
32690 doc: /* List of variables (symbols) which hold markers for overlay arrows.
32691 The symbols on this list are examined during redisplay to determine
32692 where to display overlay arrows. */);
32693 Voverlay_arrow_variable_list
32694 = list1 (intern_c_string ("overlay-arrow-position"));
32696 DEFVAR_INT ("scroll-step", emacs_scroll_step,
32697 doc: /* The number of lines to try scrolling a window by when point moves out.
32698 If that fails to bring point back on frame, point is centered instead.
32699 If this is zero, point is always centered after it moves off frame.
32700 If you want scrolling to always be a line at a time, you should set
32701 `scroll-conservatively' to a large value rather than set this to 1. */);
32703 DEFVAR_INT ("scroll-conservatively", scroll_conservatively,
32704 doc: /* Scroll up to this many lines, to bring point back on screen.
32705 If point moves off-screen, redisplay will scroll by up to
32706 `scroll-conservatively' lines in order to bring point just barely
32707 onto the screen again. If that cannot be done, then redisplay
32708 recenters point as usual.
32710 If the value is greater than 100, redisplay will never recenter point,
32711 but will always scroll just enough text to bring point into view, even
32712 if you move far away.
32714 A value of zero means always recenter point if it moves off screen. */);
32715 scroll_conservatively = 0;
32717 DEFVAR_INT ("scroll-margin", scroll_margin,
32718 doc: /* Number of lines of margin at the top and bottom of a window.
32719 Trigger automatic scrolling whenever point gets within this many lines
32720 of the top or bottom of the window (see info node `Auto Scrolling'). */);
32721 scroll_margin = 0;
32723 DEFVAR_LISP ("maximum-scroll-margin", Vmaximum_scroll_margin,
32724 doc: /* Maximum effective value of `scroll-margin'.
32725 Given as a fraction of the current window's lines. The value should
32726 be a floating point number between 0.0 and 0.5. The effective maximum
32727 is limited to (/ (1- window-lines) 2). Non-float values for this
32728 variable are ignored and the default 0.25 is used instead. */);
32729 Vmaximum_scroll_margin = make_float (0.25);
32731 DEFVAR_LISP ("display-pixels-per-inch", Vdisplay_pixels_per_inch,
32732 doc: /* Pixels per inch value for non-window system displays.
32733 Value is a number or a cons (WIDTH-DPI . HEIGHT-DPI). */);
32734 Vdisplay_pixels_per_inch = make_float (72.0);
32736 #ifdef GLYPH_DEBUG
32737 DEFVAR_INT ("debug-end-pos", debug_end_pos, doc: /* Don't ask. */);
32738 #endif
32740 DEFVAR_LISP ("truncate-partial-width-windows",
32741 Vtruncate_partial_width_windows,
32742 doc: /* Non-nil means truncate lines in windows narrower than the frame.
32743 For an integer value, truncate lines in each window narrower than the
32744 full frame width, provided the total window width in column units is less
32745 than that integer; otherwise, respect the value of `truncate-lines'.
32746 The total width of the window is as returned by `window-total-width', it
32747 includes the fringes, the continuation and truncation glyphs, the
32748 display margins (if any), and the scroll bar
32750 For any other non-nil value, truncate lines in all windows that do
32751 not span the full frame width.
32753 A value of nil means to respect the value of `truncate-lines'.
32755 If `word-wrap' is enabled, you might want to reduce this. */);
32756 Vtruncate_partial_width_windows = make_number (50);
32758 DEFVAR_LISP ("line-number-display-limit", Vline_number_display_limit,
32759 doc: /* Maximum buffer size for which line number should be displayed.
32760 If the buffer is bigger than this, the line number does not appear
32761 in the mode line. A value of nil means no limit. */);
32762 Vline_number_display_limit = Qnil;
32764 DEFVAR_INT ("line-number-display-limit-width",
32765 line_number_display_limit_width,
32766 doc: /* Maximum line width (in characters) for line number display.
32767 If the average length of the lines near point is bigger than this, then the
32768 line number may be omitted from the mode line. */);
32769 line_number_display_limit_width = 200;
32771 DEFVAR_BOOL ("highlight-nonselected-windows", highlight_nonselected_windows,
32772 doc: /* Non-nil means highlight region even in nonselected windows. */);
32773 highlight_nonselected_windows = false;
32775 DEFVAR_BOOL ("multiple-frames", multiple_frames,
32776 doc: /* Non-nil if more than one frame is visible on this display.
32777 Minibuffer-only frames don't count, but iconified frames do.
32778 This variable is not guaranteed to be accurate except while processing
32779 `frame-title-format' and `icon-title-format'. */);
32781 DEFVAR_LISP ("frame-title-format", Vframe_title_format,
32782 doc: /* Template for displaying the title bar of visible frames.
32783 \(Assuming the window manager supports this feature.)
32785 This variable has the same structure as `mode-line-format', except that
32786 the %c, %C, and %l constructs are ignored. It is used only on frames for
32787 which no explicit name has been set (see `modify-frame-parameters'). */);
32789 DEFVAR_LISP ("icon-title-format", Vicon_title_format,
32790 doc: /* Template for displaying the title bar of an iconified frame.
32791 \(Assuming the window manager supports this feature.)
32792 This variable has the same structure as `mode-line-format' (which see),
32793 and is used only on frames for which no explicit name has been set
32794 \(see `modify-frame-parameters'). */);
32795 Vicon_title_format
32796 = Vframe_title_format
32797 = listn (CONSTYPE_PURE, 3,
32798 intern_c_string ("multiple-frames"),
32799 build_pure_c_string ("%b"),
32800 listn (CONSTYPE_PURE, 4,
32801 empty_unibyte_string,
32802 intern_c_string ("invocation-name"),
32803 build_pure_c_string ("@"),
32804 intern_c_string ("system-name")));
32806 DEFVAR_LISP ("message-log-max", Vmessage_log_max,
32807 doc: /* Maximum number of lines to keep in the message log buffer.
32808 If nil, disable message logging. If t, log messages but don't truncate
32809 the buffer when it becomes large. */);
32810 Vmessage_log_max = make_number (1000);
32812 DEFVAR_LISP ("window-scroll-functions", Vwindow_scroll_functions,
32813 doc: /* List of functions to call before redisplaying a window with scrolling.
32814 Each function is called with two arguments, the window and its new
32815 display-start position.
32816 These functions are called whenever the `window-start' marker is modified,
32817 either to point into another buffer (e.g. via `set-window-buffer') or another
32818 place in the same buffer.
32819 When each function is called, the `window-start' marker of its window
32820 argument has been already set to the new value, and the buffer which that
32821 window will display is set to be the current buffer.
32822 Note that the value of `window-end' is not valid when these functions are
32823 called.
32825 Warning: Do not use this feature to alter the way the window
32826 is scrolled. It is not designed for that, and such use probably won't
32827 work. */);
32828 Vwindow_scroll_functions = Qnil;
32830 DEFVAR_LISP ("redisplay-end-trigger-functions", Vredisplay_end_trigger_functions,
32831 doc: /* Functions called when redisplay of a window reaches the end trigger.
32832 Each function is called with two arguments, the window and the end trigger value.
32833 See `set-window-redisplay-end-trigger'. */);
32834 Vredisplay_end_trigger_functions = Qnil;
32836 DEFVAR_LISP ("mouse-autoselect-window", Vmouse_autoselect_window,
32837 doc: /* Non-nil means autoselect window with mouse pointer.
32838 If nil, do not autoselect windows.
32839 A positive number means delay autoselection by that many seconds: a
32840 window is autoselected only after the mouse has remained in that
32841 window for the duration of the delay.
32842 A negative number has a similar effect, but causes windows to be
32843 autoselected only after the mouse has stopped moving. (Because of
32844 the way Emacs compares mouse events, you will occasionally wait twice
32845 that time before the window gets selected.)
32846 Any other value means to autoselect window instantaneously when the
32847 mouse pointer enters it.
32849 Autoselection selects the minibuffer only if it is active, and never
32850 unselects the minibuffer if it is active.
32852 When customizing this variable make sure that the actual value of
32853 `focus-follows-mouse' matches the behavior of your window manager. */);
32854 Vmouse_autoselect_window = Qnil;
32856 DEFVAR_LISP ("auto-resize-tool-bars", Vauto_resize_tool_bars,
32857 doc: /* Non-nil means automatically resize tool-bars.
32858 This dynamically changes the tool-bar's height to the minimum height
32859 that is needed to make all tool-bar items visible.
32860 If value is `grow-only', the tool-bar's height is only increased
32861 automatically; to decrease the tool-bar height, use \\[recenter]. */);
32862 Vauto_resize_tool_bars = Qt;
32864 DEFVAR_BOOL ("auto-raise-tool-bar-buttons", auto_raise_tool_bar_buttons_p,
32865 doc: /* Non-nil means raise tool-bar buttons when the mouse moves over them. */);
32866 auto_raise_tool_bar_buttons_p = true;
32868 DEFVAR_BOOL ("make-cursor-line-fully-visible", make_cursor_line_fully_visible_p,
32869 doc: /* Non-nil means to scroll (recenter) cursor line if it is not fully visible. */);
32870 make_cursor_line_fully_visible_p = true;
32872 DEFVAR_LISP ("tool-bar-border", Vtool_bar_border,
32873 doc: /* Border below tool-bar in pixels.
32874 If an integer, use it as the height of the border.
32875 If it is one of `internal-border-width' or `border-width', use the
32876 value of the corresponding frame parameter.
32877 Otherwise, no border is added below the tool-bar. */);
32878 Vtool_bar_border = Qinternal_border_width;
32880 DEFVAR_LISP ("tool-bar-button-margin", Vtool_bar_button_margin,
32881 doc: /* Margin around tool-bar buttons in pixels.
32882 If an integer, use that for both horizontal and vertical margins.
32883 Otherwise, value should be a pair of integers `(HORZ . VERT)' with
32884 HORZ specifying the horizontal margin, and VERT specifying the
32885 vertical margin. */);
32886 Vtool_bar_button_margin = make_number (DEFAULT_TOOL_BAR_BUTTON_MARGIN);
32888 DEFVAR_INT ("tool-bar-button-relief", tool_bar_button_relief,
32889 doc: /* Relief thickness of tool-bar buttons. */);
32890 tool_bar_button_relief = DEFAULT_TOOL_BAR_BUTTON_RELIEF;
32892 DEFVAR_LISP ("tool-bar-style", Vtool_bar_style,
32893 doc: /* Tool bar style to use.
32894 It can be one of
32895 image - show images only
32896 text - show text only
32897 both - show both, text below image
32898 both-horiz - show text to the right of the image
32899 text-image-horiz - show text to the left of the image
32900 any other - use system default or image if no system default.
32902 This variable only affects the GTK+ toolkit version of Emacs. */);
32903 Vtool_bar_style = Qnil;
32905 DEFVAR_INT ("tool-bar-max-label-size", tool_bar_max_label_size,
32906 doc: /* Maximum number of characters a label can have to be shown.
32907 The tool bar style must also show labels for this to have any effect, see
32908 `tool-bar-style'. */);
32909 tool_bar_max_label_size = DEFAULT_TOOL_BAR_LABEL_SIZE;
32911 DEFVAR_LISP ("fontification-functions", Vfontification_functions,
32912 doc: /* List of functions to call to fontify regions of text.
32913 Each function is called with one argument POS. Functions must
32914 fontify a region starting at POS in the current buffer, and give
32915 fontified regions the property `fontified'. */);
32916 Vfontification_functions = Qnil;
32917 Fmake_variable_buffer_local (Qfontification_functions);
32919 DEFVAR_BOOL ("unibyte-display-via-language-environment",
32920 unibyte_display_via_language_environment,
32921 doc: /* Non-nil means display unibyte text according to language environment.
32922 Specifically, this means that raw bytes in the range 160-255 decimal
32923 are displayed by converting them to the equivalent multibyte characters
32924 according to the current language environment. As a result, they are
32925 displayed according to the current fontset.
32927 Note that this variable affects only how these bytes are displayed,
32928 but does not change the fact they are interpreted as raw bytes. */);
32929 unibyte_display_via_language_environment = false;
32931 DEFVAR_LISP ("max-mini-window-height", Vmax_mini_window_height,
32932 doc: /* Maximum height for resizing mini-windows (the minibuffer and the echo area).
32933 If a float, it specifies a fraction of the mini-window frame's height.
32934 If an integer, it specifies a number of lines. */);
32935 Vmax_mini_window_height = make_float (0.25);
32937 DEFVAR_LISP ("resize-mini-windows", Vresize_mini_windows,
32938 doc: /* How to resize mini-windows (the minibuffer and the echo area).
32939 A value of nil means don't automatically resize mini-windows.
32940 A value of t means resize them to fit the text displayed in them.
32941 A value of `grow-only', the default, means let mini-windows grow only;
32942 they return to their normal size when the minibuffer is closed, or the
32943 echo area becomes empty. */);
32944 /* Contrary to the doc string, we initialize this to nil, so that
32945 loading loadup.el won't try to resize windows before loading
32946 window.el, where some functions we need to call for this live.
32947 We assign the 'grow-only' value right after loading window.el
32948 during loadup. */
32949 Vresize_mini_windows = Qnil;
32951 DEFVAR_LISP ("blink-cursor-alist", Vblink_cursor_alist,
32952 doc: /* Alist specifying how to blink the cursor off.
32953 Each element has the form (ON-STATE . OFF-STATE). Whenever the
32954 `cursor-type' frame-parameter or variable equals ON-STATE,
32955 comparing using `equal', Emacs uses OFF-STATE to specify
32956 how to blink it off. ON-STATE and OFF-STATE are values for
32957 the `cursor-type' frame parameter.
32959 If a frame's ON-STATE has no entry in this list,
32960 the frame's other specifications determine how to blink the cursor off. */);
32961 Vblink_cursor_alist = Qnil;
32963 DEFVAR_LISP ("auto-hscroll-mode", automatic_hscrolling,
32964 doc: /* Allow or disallow automatic horizontal scrolling of windows.
32965 The value `current-line' means the line displaying point in each window
32966 is automatically scrolled horizontally to make point visible.
32967 Any other non-nil value means all the lines in a window are automatically
32968 scrolled horizontally to make point visible. */);
32969 automatic_hscrolling = Qt;
32970 DEFSYM (Qauto_hscroll_mode, "auto-hscroll-mode");
32971 DEFSYM (Qcurrent_line, "current-line");
32973 DEFVAR_INT ("hscroll-margin", hscroll_margin,
32974 doc: /* How many columns away from the window edge point is allowed to get
32975 before automatic hscrolling will horizontally scroll the window. */);
32976 hscroll_margin = 5;
32978 DEFVAR_LISP ("hscroll-step", Vhscroll_step,
32979 doc: /* How many columns to scroll the window when point gets too close to the edge.
32980 When point is less than `hscroll-margin' columns from the window
32981 edge, automatic hscrolling will scroll the window by the amount of columns
32982 determined by this variable. If its value is a positive integer, scroll that
32983 many columns. If it's a positive floating-point number, it specifies the
32984 fraction of the window's width to scroll. If it's nil or zero, point will be
32985 centered horizontally after the scroll. Any other value, including negative
32986 numbers, are treated as if the value were zero.
32988 Automatic hscrolling always moves point outside the scroll margin, so if
32989 point was more than scroll step columns inside the margin, the window will
32990 scroll more than the value given by the scroll step.
32992 Note that the lower bound for automatic hscrolling specified by `scroll-left'
32993 and `scroll-right' overrides this variable's effect. */);
32994 Vhscroll_step = make_number (0);
32996 DEFVAR_BOOL ("message-truncate-lines", message_truncate_lines,
32997 doc: /* If non-nil, messages are truncated instead of resizing the echo area.
32998 Bind this around calls to `message' to let it take effect. */);
32999 message_truncate_lines = false;
33001 DEFVAR_LISP ("menu-bar-update-hook", Vmenu_bar_update_hook,
33002 doc: /* Normal hook run to update the menu bar definitions.
33003 Redisplay runs this hook before it redisplays the menu bar.
33004 This is used to update menus such as Buffers, whose contents depend on
33005 various data. */);
33006 Vmenu_bar_update_hook = Qnil;
33008 DEFVAR_LISP ("menu-updating-frame", Vmenu_updating_frame,
33009 doc: /* Frame for which we are updating a menu.
33010 The enable predicate for a menu binding should check this variable. */);
33011 Vmenu_updating_frame = Qnil;
33013 DEFVAR_BOOL ("inhibit-menubar-update", inhibit_menubar_update,
33014 doc: /* Non-nil means don't update menu bars. Internal use only. */);
33015 inhibit_menubar_update = false;
33017 DEFVAR_LISP ("wrap-prefix", Vwrap_prefix,
33018 doc: /* Prefix prepended to all continuation lines at display time.
33019 The value may be a string, an image, or a stretch-glyph; it is
33020 interpreted in the same way as the value of a `display' text property.
33022 This variable is overridden by any `wrap-prefix' text or overlay
33023 property.
33025 To add a prefix to non-continuation lines, use `line-prefix'. */);
33026 Vwrap_prefix = Qnil;
33027 DEFSYM (Qwrap_prefix, "wrap-prefix");
33028 Fmake_variable_buffer_local (Qwrap_prefix);
33030 DEFVAR_LISP ("line-prefix", Vline_prefix,
33031 doc: /* Prefix prepended to all non-continuation lines at display time.
33032 The value may be a string, an image, or a stretch-glyph; it is
33033 interpreted in the same way as the value of a `display' text property.
33035 This variable is overridden by any `line-prefix' text or overlay
33036 property.
33038 To add a prefix to continuation lines, use `wrap-prefix'. */);
33039 Vline_prefix = Qnil;
33040 DEFSYM (Qline_prefix, "line-prefix");
33041 Fmake_variable_buffer_local (Qline_prefix);
33043 DEFVAR_LISP ("display-line-numbers", Vdisplay_line_numbers,
33044 doc: /* Non-nil means display line numbers.
33045 If the value is t, display the absolute number of each line of a buffer
33046 shown in a window. Absolute line numbers count from the beginning of
33047 the current narrowing, or from buffer beginning. If the value is
33048 `relative', display for each line not containing the window's point its
33049 relative number instead, i.e. the number of the line relative to the
33050 line showing the window's point.
33052 In either case, line numbers are displayed at the beginning of each
33053 non-continuation line that displays buffer text, i.e. after each newline
33054 character that comes from the buffer. The value `visual' is like
33055 `relative' but counts screen lines instead of buffer lines. In practice
33056 this means that continuation lines count as well when calculating the
33057 relative number of a line.
33059 Lisp programs can disable display of a line number of a particular
33060 buffer line by putting the `display-line-numbers-disable' text property
33061 or overlay property on the first visible character of that line. */);
33062 Vdisplay_line_numbers = Qnil;
33063 DEFSYM (Qdisplay_line_numbers, "display-line-numbers");
33064 Fmake_variable_buffer_local (Qdisplay_line_numbers);
33065 DEFSYM (Qrelative, "relative");
33066 DEFSYM (Qvisual, "visual");
33068 DEFVAR_LISP ("display-line-numbers-width", Vdisplay_line_numbers_width,
33069 doc: /* Minimum width of space reserved for line number display.
33070 A positive number means reserve that many columns for line numbers,
33071 even if the actual number needs less space.
33072 The default value of nil means compute the space dynamically.
33073 Any other value is treated as nil. */);
33074 Vdisplay_line_numbers_width = Qnil;
33075 DEFSYM (Qdisplay_line_numbers_width, "display-line-numbers-width");
33076 Fmake_variable_buffer_local (Qdisplay_line_numbers_width);
33078 DEFVAR_LISP ("display-line-numbers-current-absolute",
33079 Vdisplay_line_numbers_current_absolute,
33080 doc: /* Non-nil means display absolute number of current line.
33081 This variable has effect only when `display-line-numbers' is
33082 either `relative' or `visual'. */);
33083 Vdisplay_line_numbers_current_absolute = Qt;
33085 DEFVAR_BOOL ("display-line-numbers-widen", display_line_numbers_widen,
33086 doc: /* Non-nil means display line numbers disregarding any narrowing. */);
33087 display_line_numbers_widen = false;
33088 DEFSYM (Qdisplay_line_numbers_widen, "display-line-numbers-widen");
33089 Fmake_variable_buffer_local (Qdisplay_line_numbers_widen);
33091 DEFVAR_BOOL ("inhibit-eval-during-redisplay", inhibit_eval_during_redisplay,
33092 doc: /* Non-nil means don't eval Lisp during redisplay. */);
33093 inhibit_eval_during_redisplay = false;
33095 DEFVAR_BOOL ("inhibit-free-realized-faces", inhibit_free_realized_faces,
33096 doc: /* Non-nil means don't free realized faces. Internal use only. */);
33097 inhibit_free_realized_faces = false;
33099 DEFVAR_BOOL ("inhibit-bidi-mirroring", inhibit_bidi_mirroring,
33100 doc: /* Non-nil means don't mirror characters even when bidi context requires that.
33101 Intended for use during debugging and for testing bidi display;
33102 see biditest.el in the test suite. */);
33103 inhibit_bidi_mirroring = false;
33105 #ifdef GLYPH_DEBUG
33106 DEFVAR_BOOL ("inhibit-try-window-id", inhibit_try_window_id,
33107 doc: /* Inhibit try_window_id display optimization. */);
33108 inhibit_try_window_id = false;
33110 DEFVAR_BOOL ("inhibit-try-window-reusing", inhibit_try_window_reusing,
33111 doc: /* Inhibit try_window_reusing display optimization. */);
33112 inhibit_try_window_reusing = false;
33114 DEFVAR_BOOL ("inhibit-try-cursor-movement", inhibit_try_cursor_movement,
33115 doc: /* Inhibit try_cursor_movement display optimization. */);
33116 inhibit_try_cursor_movement = false;
33117 #endif /* GLYPH_DEBUG */
33119 DEFVAR_INT ("overline-margin", overline_margin,
33120 doc: /* Space between overline and text, in pixels.
33121 The default value is 2: the height of the overline (1 pixel) plus 1 pixel
33122 margin to the character height. */);
33123 overline_margin = 2;
33125 DEFVAR_INT ("underline-minimum-offset",
33126 underline_minimum_offset,
33127 doc: /* Minimum distance between baseline and underline.
33128 This can improve legibility of underlined text at small font sizes,
33129 particularly when using variable `x-use-underline-position-properties'
33130 with fonts that specify an UNDERLINE_POSITION relatively close to the
33131 baseline. The default value is 1. */);
33132 underline_minimum_offset = 1;
33133 DEFSYM (Qunderline_minimum_offset, "underline-minimum-offset");
33135 DEFVAR_BOOL ("display-hourglass", display_hourglass_p,
33136 doc: /* Non-nil means show an hourglass pointer, when Emacs is busy.
33137 This feature only works when on a window system that can change
33138 cursor shapes. */);
33139 display_hourglass_p = true;
33141 DEFVAR_LISP ("hourglass-delay", Vhourglass_delay,
33142 doc: /* Seconds to wait before displaying an hourglass pointer when Emacs is busy. */);
33143 Vhourglass_delay = make_number (DEFAULT_HOURGLASS_DELAY);
33145 #ifdef HAVE_WINDOW_SYSTEM
33146 hourglass_atimer = NULL;
33147 hourglass_shown_p = false;
33148 #endif /* HAVE_WINDOW_SYSTEM */
33150 /* Name of the face used to display glyphless characters. */
33151 DEFSYM (Qglyphless_char, "glyphless-char");
33153 /* Method symbols for Vglyphless_char_display. */
33154 DEFSYM (Qhex_code, "hex-code");
33155 DEFSYM (Qempty_box, "empty-box");
33156 DEFSYM (Qthin_space, "thin-space");
33157 DEFSYM (Qzero_width, "zero-width");
33159 DEFVAR_LISP ("pre-redisplay-function", Vpre_redisplay_function,
33160 doc: /* Function run just before redisplay.
33161 It is called with one argument, which is the set of windows that are to
33162 be redisplayed. This set can be nil (meaning, only the selected window),
33163 or t (meaning all windows). */);
33164 Vpre_redisplay_function = intern ("ignore");
33166 /* Symbol for the purpose of Vglyphless_char_display. */
33167 DEFSYM (Qglyphless_char_display, "glyphless-char-display");
33168 Fput (Qglyphless_char_display, Qchar_table_extra_slots, make_number (1));
33170 DEFVAR_LISP ("glyphless-char-display", Vglyphless_char_display,
33171 doc: /* Char-table defining glyphless characters.
33172 Each element, if non-nil, should be one of the following:
33173 an ASCII acronym string: display this string in a box
33174 `hex-code': display the hexadecimal code of a character in a box
33175 `empty-box': display as an empty box
33176 `thin-space': display as 1-pixel width space
33177 `zero-width': don't display
33178 An element may also be a cons cell (GRAPHICAL . TEXT), which specifies the
33179 display method for graphical terminals and text terminals respectively.
33180 GRAPHICAL and TEXT should each have one of the values listed above.
33182 The char-table has one extra slot to control the display of a character for
33183 which no font is found. This slot only takes effect on graphical terminals.
33184 Its value should be an ASCII acronym string, `hex-code', `empty-box', or
33185 `thin-space'. The default is `empty-box'.
33187 If a character has a non-nil entry in an active display table, the
33188 display table takes effect; in this case, Emacs does not consult
33189 `glyphless-char-display' at all. */);
33190 Vglyphless_char_display = Fmake_char_table (Qglyphless_char_display, Qnil);
33191 Fset_char_table_extra_slot (Vglyphless_char_display, make_number (0),
33192 Qempty_box);
33194 DEFVAR_LISP ("debug-on-message", Vdebug_on_message,
33195 doc: /* If non-nil, debug if a message matching this regexp is displayed. */);
33196 Vdebug_on_message = Qnil;
33198 DEFVAR_LISP ("redisplay--all-windows-cause", Vredisplay__all_windows_cause,
33199 doc: /* */);
33200 Vredisplay__all_windows_cause = Fmake_hash_table (0, NULL);
33202 DEFVAR_LISP ("redisplay--mode-lines-cause", Vredisplay__mode_lines_cause,
33203 doc: /* */);
33204 Vredisplay__mode_lines_cause = Fmake_hash_table (0, NULL);
33206 DEFVAR_BOOL ("redisplay--inhibit-bidi", redisplay__inhibit_bidi,
33207 doc: /* Non-nil means it is not safe to attempt bidi reordering for display. */);
33208 /* Initialize to t, since we need to disable reordering until
33209 loadup.el successfully loads charprop.el. */
33210 redisplay__inhibit_bidi = true;
33212 DEFVAR_BOOL ("display-raw-bytes-as-hex", display_raw_bytes_as_hex,
33213 doc: /* Non-nil means display raw bytes in hexadecimal format.
33214 The default is to use octal format (\200) whereas hexadecimal (\x80)
33215 may be more familiar to users. */);
33216 display_raw_bytes_as_hex = false;
33221 /* Initialize this module when Emacs starts. */
33223 void
33224 init_xdisp (void)
33226 CHARPOS (this_line_start_pos) = 0;
33228 if (!noninteractive)
33230 struct window *m = XWINDOW (minibuf_window);
33231 Lisp_Object frame = m->frame;
33232 struct frame *f = XFRAME (frame);
33233 Lisp_Object root = FRAME_ROOT_WINDOW (f);
33234 struct window *r = XWINDOW (root);
33235 int i;
33237 echo_area_window = minibuf_window;
33239 r->top_line = FRAME_TOP_MARGIN (f);
33240 r->pixel_top = r->top_line * FRAME_LINE_HEIGHT (f);
33241 r->total_cols = FRAME_COLS (f);
33242 r->pixel_width = r->total_cols * FRAME_COLUMN_WIDTH (f);
33243 r->total_lines = FRAME_TOTAL_LINES (f) - 1 - FRAME_TOP_MARGIN (f);
33244 r->pixel_height = r->total_lines * FRAME_LINE_HEIGHT (f);
33246 m->top_line = FRAME_TOTAL_LINES (f) - 1;
33247 m->pixel_top = m->top_line * FRAME_LINE_HEIGHT (f);
33248 m->total_cols = FRAME_COLS (f);
33249 m->pixel_width = m->total_cols * FRAME_COLUMN_WIDTH (f);
33250 m->total_lines = 1;
33251 m->pixel_height = m->total_lines * FRAME_LINE_HEIGHT (f);
33253 scratch_glyph_row.glyphs[TEXT_AREA] = scratch_glyphs;
33254 scratch_glyph_row.glyphs[TEXT_AREA + 1]
33255 = scratch_glyphs + MAX_SCRATCH_GLYPHS;
33257 /* The default ellipsis glyphs `...'. */
33258 for (i = 0; i < 3; ++i)
33259 default_invis_vector[i] = make_number ('.');
33263 /* Allocate the buffer for frame titles.
33264 Also used for `format-mode-line'. */
33265 int size = 100;
33266 mode_line_noprop_buf = xmalloc (size);
33267 mode_line_noprop_buf_end = mode_line_noprop_buf + size;
33268 mode_line_noprop_ptr = mode_line_noprop_buf;
33269 mode_line_target = MODE_LINE_DISPLAY;
33272 help_echo_showing_p = false;
33275 #ifdef HAVE_WINDOW_SYSTEM
33277 /* Platform-independent portion of hourglass implementation. */
33279 /* Timer function of hourglass_atimer. */
33281 static void
33282 show_hourglass (struct atimer *timer)
33284 /* The timer implementation will cancel this timer automatically
33285 after this function has run. Set hourglass_atimer to null
33286 so that we know the timer doesn't have to be canceled. */
33287 hourglass_atimer = NULL;
33289 if (!hourglass_shown_p)
33291 Lisp_Object tail, frame;
33293 block_input ();
33295 FOR_EACH_FRAME (tail, frame)
33297 struct frame *f = XFRAME (frame);
33299 if (FRAME_LIVE_P (f) && FRAME_WINDOW_P (f)
33300 && FRAME_RIF (f)->show_hourglass)
33301 FRAME_RIF (f)->show_hourglass (f);
33304 hourglass_shown_p = true;
33305 unblock_input ();
33309 /* Cancel a currently active hourglass timer, and start a new one. */
33311 void
33312 start_hourglass (void)
33314 struct timespec delay;
33316 cancel_hourglass ();
33318 if (INTEGERP (Vhourglass_delay)
33319 && XINT (Vhourglass_delay) > 0)
33320 delay = make_timespec (min (XINT (Vhourglass_delay),
33321 TYPE_MAXIMUM (time_t)),
33323 else if (FLOATP (Vhourglass_delay)
33324 && XFLOAT_DATA (Vhourglass_delay) > 0)
33325 delay = dtotimespec (XFLOAT_DATA (Vhourglass_delay));
33326 else
33327 delay = make_timespec (DEFAULT_HOURGLASS_DELAY, 0);
33329 hourglass_atimer = start_atimer (ATIMER_RELATIVE, delay,
33330 show_hourglass, NULL);
33333 /* Cancel the hourglass cursor timer if active, hide a busy cursor if
33334 shown. */
33336 void
33337 cancel_hourglass (void)
33339 if (hourglass_atimer)
33341 cancel_atimer (hourglass_atimer);
33342 hourglass_atimer = NULL;
33345 if (hourglass_shown_p)
33347 Lisp_Object tail, frame;
33349 block_input ();
33351 FOR_EACH_FRAME (tail, frame)
33353 struct frame *f = XFRAME (frame);
33355 if (FRAME_LIVE_P (f) && FRAME_WINDOW_P (f)
33356 && FRAME_RIF (f)->hide_hourglass)
33357 FRAME_RIF (f)->hide_hourglass (f);
33358 #ifdef HAVE_NTGUI
33359 /* No cursors on non GUI frames - restore to stock arrow cursor. */
33360 else if (!FRAME_W32_P (f))
33361 w32_arrow_cursor ();
33362 #endif
33365 hourglass_shown_p = false;
33366 unblock_input ();
33370 #endif /* HAVE_WINDOW_SYSTEM */