Tell user about read-integer-overflow-as-float
[emacs.git] / src / xdisp.c
blob50fd6857784b7537a43bfbcb47dcedc14a9df59e
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 (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->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->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->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->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->f, 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->f, 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->f, 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->f, 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->f, 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->f, 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->f, 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->f, 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 /* do_pending_window_change could change the selected_window due to
14031 frame resizing which makes the selected window too small. */
14032 if (WINDOWP (selected_window) && (w = XWINDOW (selected_window)) != sw)
14033 sw = w;
14035 /* Clear frames marked as garbaged. */
14036 clear_garbaged_frames ();
14038 /* Build menubar and tool-bar items. */
14039 if (NILP (Vmemory_full))
14040 prepare_menu_bars ();
14042 reconsider_clip_changes (w);
14044 /* In most cases selected window displays current buffer. */
14045 match_p = XBUFFER (w->contents) == current_buffer;
14046 if (match_p)
14048 /* Detect case that we need to write or remove a star in the mode line. */
14049 if ((SAVE_MODIFF < MODIFF) != w->last_had_star)
14050 w->update_mode_line = true;
14052 if (mode_line_update_needed (w))
14053 w->update_mode_line = true;
14055 /* If reconsider_clip_changes above decided that the narrowing
14056 in the current buffer changed, make sure all other windows
14057 showing that buffer will be redisplayed. */
14058 if (current_buffer->clip_changed)
14059 bset_update_mode_line (current_buffer);
14062 /* Normally the message* functions will have already displayed and
14063 updated the echo area, but the frame may have been trashed, or
14064 the update may have been preempted, so display the echo area
14065 again here. Checking message_cleared_p captures the case that
14066 the echo area should be cleared. */
14067 if ((!NILP (echo_area_buffer[0]) && !display_last_displayed_message_p)
14068 || (!NILP (echo_area_buffer[1]) && display_last_displayed_message_p)
14069 || (message_cleared_p
14070 && minibuf_level == 0
14071 /* If the mini-window is currently selected, this means the
14072 echo-area doesn't show through. */
14073 && !MINI_WINDOW_P (XWINDOW (selected_window))))
14075 echo_area_display (false);
14077 /* If echo_area_display resizes the mini-window, the redisplay and
14078 window_sizes_changed flags of the selected frame are set, but
14079 it's too late for the hooks in window-size-change-functions,
14080 which have been examined already in prepare_menu_bars. So in
14081 that case we call the hooks here only for the selected frame. */
14082 if (sf->redisplay)
14084 ptrdiff_t count1 = SPECPDL_INDEX ();
14086 record_unwind_save_match_data ();
14087 run_window_size_change_functions (selected_frame);
14088 unbind_to (count1, Qnil);
14091 if (message_cleared_p)
14092 update_miniwindow_p = true;
14094 must_finish = true;
14096 /* If we don't display the current message, don't clear the
14097 message_cleared_p flag, because, if we did, we wouldn't clear
14098 the echo area in the next redisplay which doesn't preserve
14099 the echo area. */
14100 if (!display_last_displayed_message_p)
14101 message_cleared_p = false;
14103 else if (EQ (selected_window, minibuf_window)
14104 && (current_buffer->clip_changed || window_outdated (w))
14105 && resize_mini_window (w, false))
14107 if (sf->redisplay)
14109 ptrdiff_t count1 = SPECPDL_INDEX ();
14111 record_unwind_save_match_data ();
14112 run_window_size_change_functions (selected_frame);
14113 unbind_to (count1, Qnil);
14116 /* Resized active mini-window to fit the size of what it is
14117 showing if its contents might have changed. */
14118 must_finish = true;
14120 /* If window configuration was changed, frames may have been
14121 marked garbaged. Clear them or we will experience
14122 surprises wrt scrolling. */
14123 clear_garbaged_frames ();
14126 if (windows_or_buffers_changed && !update_mode_lines)
14127 /* Code that sets windows_or_buffers_changed doesn't distinguish whether
14128 only the windows's contents needs to be refreshed, or whether the
14129 mode-lines also need a refresh. */
14130 update_mode_lines = (windows_or_buffers_changed == REDISPLAY_SOME
14131 ? REDISPLAY_SOME : 32);
14133 /* If specs for an arrow have changed, do thorough redisplay
14134 to ensure we remove any arrow that should no longer exist. */
14135 /* Apparently, this is the only case where we update other windows,
14136 without updating other mode-lines. */
14137 overlay_arrows_changed_p (true);
14139 consider_all_windows_p = (update_mode_lines
14140 || windows_or_buffers_changed);
14142 #define AINC(a,i) \
14144 Lisp_Object entry = Fgethash (make_number (i), a, make_number (0)); \
14145 if (INTEGERP (entry)) \
14146 Fputhash (make_number (i), make_number (1 + XINT (entry)), a); \
14149 AINC (Vredisplay__all_windows_cause, windows_or_buffers_changed);
14150 AINC (Vredisplay__mode_lines_cause, update_mode_lines);
14152 /* Optimize the case that only the line containing the cursor in the
14153 selected window has changed. Variables starting with this_ are
14154 set in display_line and record information about the line
14155 containing the cursor. */
14156 tlbufpos = this_line_start_pos;
14157 tlendpos = this_line_end_pos;
14158 if (!consider_all_windows_p
14159 && CHARPOS (tlbufpos) > 0
14160 && !w->update_mode_line
14161 && !current_buffer->clip_changed
14162 && !current_buffer->prevent_redisplay_optimizations_p
14163 && FRAME_VISIBLE_P (XFRAME (w->frame))
14164 && !FRAME_OBSCURED_P (XFRAME (w->frame))
14165 && !XFRAME (w->frame)->cursor_type_changed
14166 && !XFRAME (w->frame)->face_change
14167 /* Make sure recorded data applies to current buffer, etc. */
14168 && this_line_buffer == current_buffer
14169 && match_p
14170 && !w->force_start
14171 && !w->optional_new_start
14172 /* Point must be on the line that we have info recorded about. */
14173 && PT >= CHARPOS (tlbufpos)
14174 && PT <= Z - CHARPOS (tlendpos)
14175 /* All text outside that line, including its final newline,
14176 must be unchanged. */
14177 && text_outside_line_unchanged_p (w, CHARPOS (tlbufpos),
14178 CHARPOS (tlendpos)))
14180 if (CHARPOS (tlbufpos) > BEGV
14181 && FETCH_BYTE (BYTEPOS (tlbufpos) - 1) != '\n'
14182 && (CHARPOS (tlbufpos) == ZV
14183 || FETCH_BYTE (BYTEPOS (tlbufpos)) == '\n'))
14184 /* Former continuation line has disappeared by becoming empty. */
14185 goto cancel;
14186 else if (window_outdated (w) || MINI_WINDOW_P (w))
14188 /* We have to handle the case of continuation around a
14189 wide-column character (see the comment in indent.c around
14190 line 1340).
14192 For instance, in the following case:
14194 -------- Insert --------
14195 K_A_N_\\ `a' K_A_N_a\ `X_' are wide-column chars.
14196 J_I_ ==> J_I_ `^^' are cursors.
14197 ^^ ^^
14198 -------- --------
14200 As we have to redraw the line above, we cannot use this
14201 optimization. */
14203 struct it it;
14204 int line_height_before = this_line_pixel_height;
14206 /* Note that start_display will handle the case that the
14207 line starting at tlbufpos is a continuation line. */
14208 start_display (&it, w, tlbufpos);
14210 /* Implementation note: It this still necessary? */
14211 if (it.current_x != this_line_start_x)
14212 goto cancel;
14214 TRACE ((stderr, "trying display optimization 1\n"));
14215 w->cursor.vpos = -1;
14216 overlay_arrow_seen = false;
14217 it.vpos = this_line_vpos;
14218 it.current_y = this_line_y;
14219 it.glyph_row = MATRIX_ROW (w->desired_matrix, this_line_vpos);
14220 display_line (&it, -1);
14222 /* If line contains point, is not continued,
14223 and ends at same distance from eob as before, we win. */
14224 if (w->cursor.vpos >= 0
14225 /* Line is not continued, otherwise this_line_start_pos
14226 would have been set to 0 in display_line. */
14227 && CHARPOS (this_line_start_pos)
14228 /* Line ends as before. */
14229 && CHARPOS (this_line_end_pos) == CHARPOS (tlendpos)
14230 /* Line has same height as before. Otherwise other lines
14231 would have to be shifted up or down. */
14232 && this_line_pixel_height == line_height_before)
14234 /* If this is not the window's last line, we must adjust
14235 the charstarts of the lines below. */
14236 if (it.current_y < it.last_visible_y)
14238 struct glyph_row *row
14239 = MATRIX_ROW (w->current_matrix, this_line_vpos + 1);
14240 ptrdiff_t delta, delta_bytes;
14242 /* We used to distinguish between two cases here,
14243 conditioned by Z - CHARPOS (tlendpos) == ZV, for
14244 when the line ends in a newline or the end of the
14245 buffer's accessible portion. But both cases did
14246 the same, so they were collapsed. */
14247 delta = (Z
14248 - CHARPOS (tlendpos)
14249 - MATRIX_ROW_START_CHARPOS (row));
14250 delta_bytes = (Z_BYTE
14251 - BYTEPOS (tlendpos)
14252 - MATRIX_ROW_START_BYTEPOS (row));
14254 increment_matrix_positions (w->current_matrix,
14255 this_line_vpos + 1,
14256 w->current_matrix->nrows,
14257 delta, delta_bytes);
14260 /* If this row displays text now but previously didn't,
14261 or vice versa, w->window_end_vpos may have to be
14262 adjusted. */
14263 if (MATRIX_ROW_DISPLAYS_TEXT_P (it.glyph_row - 1))
14265 if (w->window_end_vpos < this_line_vpos)
14266 w->window_end_vpos = this_line_vpos;
14268 else if (w->window_end_vpos == this_line_vpos
14269 && this_line_vpos > 0)
14270 w->window_end_vpos = this_line_vpos - 1;
14271 w->window_end_valid = false;
14273 /* Update hint: No need to try to scroll in update_window. */
14274 w->desired_matrix->no_scrolling_p = true;
14276 #ifdef GLYPH_DEBUG
14277 *w->desired_matrix->method = 0;
14278 debug_method_add (w, "optimization 1");
14279 #endif
14280 #ifdef HAVE_WINDOW_SYSTEM
14281 update_window_fringes (w, false);
14282 #endif
14283 goto update;
14285 else
14286 goto cancel;
14288 else if (/* Cursor position hasn't changed. */
14289 PT == w->last_point
14290 /* Make sure the cursor was last displayed
14291 in this window. Otherwise we have to reposition it. */
14293 /* PXW: Must be converted to pixels, probably. */
14294 && 0 <= w->cursor.vpos
14295 && w->cursor.vpos < WINDOW_TOTAL_LINES (w))
14297 if (!must_finish)
14299 do_pending_window_change (true);
14300 /* If selected_window changed, redisplay again. */
14301 if (WINDOWP (selected_window)
14302 && (w = XWINDOW (selected_window)) != sw)
14303 goto retry;
14305 /* We used to always goto end_of_redisplay here, but this
14306 isn't enough if we have a blinking cursor. */
14307 if (w->cursor_off_p == w->last_cursor_off_p)
14308 goto end_of_redisplay;
14310 goto update;
14312 /* If highlighting the region, or if the cursor is in the echo area,
14313 then we can't just move the cursor. */
14314 else if (NILP (Vshow_trailing_whitespace)
14315 && !cursor_in_echo_area)
14317 struct it it;
14318 struct glyph_row *row;
14320 /* Skip from tlbufpos to PT and see where it is. Note that
14321 PT may be in invisible text. If so, we will end at the
14322 next visible position. */
14323 init_iterator (&it, w, CHARPOS (tlbufpos), BYTEPOS (tlbufpos),
14324 NULL, DEFAULT_FACE_ID);
14325 it.current_x = this_line_start_x;
14326 it.current_y = this_line_y;
14327 it.vpos = this_line_vpos;
14329 /* The call to move_it_to stops in front of PT, but
14330 moves over before-strings. */
14331 move_it_to (&it, PT, -1, -1, -1, MOVE_TO_POS);
14333 if (it.vpos == this_line_vpos
14334 && (row = MATRIX_ROW (w->current_matrix, this_line_vpos),
14335 row->enabled_p))
14337 eassert (this_line_vpos == it.vpos);
14338 eassert (this_line_y == it.current_y);
14339 set_cursor_from_row (w, row, w->current_matrix, 0, 0, 0, 0);
14340 if (cursor_row_fully_visible_p (w, false, true))
14342 #ifdef GLYPH_DEBUG
14343 *w->desired_matrix->method = 0;
14344 debug_method_add (w, "optimization 3");
14345 #endif
14346 goto update;
14348 else
14349 goto cancel;
14351 else
14352 goto cancel;
14355 cancel:
14356 /* Text changed drastically or point moved off of line. */
14357 SET_MATRIX_ROW_ENABLED_P (w->desired_matrix, this_line_vpos, false);
14360 CHARPOS (this_line_start_pos) = 0;
14361 ++clear_face_cache_count;
14362 #ifdef HAVE_WINDOW_SYSTEM
14363 ++clear_image_cache_count;
14364 #endif
14366 /* Build desired matrices, and update the display. If
14367 consider_all_windows_p, do it for all windows on all frames that
14368 require redisplay, as specified by their 'redisplay' flag.
14369 Otherwise do it for selected_window, only. */
14371 if (consider_all_windows_p)
14373 FOR_EACH_FRAME (tail, frame)
14374 XFRAME (frame)->updated_p = false;
14376 propagate_buffer_redisplay ();
14378 FOR_EACH_FRAME (tail, frame)
14380 struct frame *f = XFRAME (frame);
14382 /* We don't have to do anything for unselected terminal
14383 frames. */
14384 if ((FRAME_TERMCAP_P (f) || FRAME_MSDOS_P (f))
14385 && !EQ (FRAME_TTY (f)->top_frame, frame))
14386 continue;
14388 retry_frame:
14389 if (FRAME_WINDOW_P (f) || FRAME_TERMCAP_P (f) || f == sf)
14391 bool gcscrollbars
14392 /* Only GC scrollbars when we redisplay the whole frame. */
14393 = f->redisplay || !REDISPLAY_SOME_P ();
14394 bool f_redisplay_flag = f->redisplay;
14395 /* Mark all the scroll bars to be removed; we'll redeem
14396 the ones we want when we redisplay their windows. */
14397 if (gcscrollbars && FRAME_TERMINAL (f)->condemn_scroll_bars_hook)
14398 FRAME_TERMINAL (f)->condemn_scroll_bars_hook (f);
14400 if (FRAME_VISIBLE_P (f) && !FRAME_OBSCURED_P (f))
14401 redisplay_windows (FRAME_ROOT_WINDOW (f));
14402 /* Remember that the invisible frames need to be redisplayed next
14403 time they're visible. */
14404 else if (!REDISPLAY_SOME_P ())
14405 f->redisplay = true;
14407 /* The X error handler may have deleted that frame. */
14408 if (!FRAME_LIVE_P (f))
14409 continue;
14411 /* Any scroll bars which redisplay_windows should have
14412 nuked should now go away. */
14413 if (gcscrollbars && FRAME_TERMINAL (f)->judge_scroll_bars_hook)
14414 FRAME_TERMINAL (f)->judge_scroll_bars_hook (f);
14416 if (FRAME_VISIBLE_P (f) && !FRAME_OBSCURED_P (f))
14418 /* If fonts changed on visible frame, display again. */
14419 if (f->fonts_changed)
14421 adjust_frame_glyphs (f);
14422 /* Disable all redisplay optimizations for this
14423 frame. For the reasons, see the comment near
14424 the previous call to adjust_frame_glyphs above. */
14425 SET_FRAME_GARBAGED (f);
14426 f->fonts_changed = false;
14427 goto retry_frame;
14430 /* See if we have to hscroll. */
14431 if (!f->already_hscrolled_p)
14433 f->already_hscrolled_p = true;
14434 if (hscroll_retries <= MAX_HSCROLL_RETRIES
14435 && hscroll_windows (f->root_window))
14437 hscroll_retries++;
14438 goto retry_frame;
14442 /* If the frame's redisplay flag was not set before
14443 we went about redisplaying its windows, but it is
14444 set now, that means we employed some redisplay
14445 optimizations inside redisplay_windows, and
14446 bypassed producing some screen lines. But if
14447 f->redisplay is now set, it might mean the old
14448 faces are no longer valid (e.g., if redisplaying
14449 some window called some Lisp which defined a new
14450 face or redefined an existing face), so trying to
14451 use them in update_frame will segfault.
14452 Therefore, we must redisplay this frame. */
14453 if (!f_redisplay_flag && f->redisplay)
14454 goto retry_frame;
14455 /* In some case (e.g., window resize), we notice
14456 only during window updating that the window
14457 content changed unpredictably (e.g., a GTK
14458 scrollbar moved, or some Lisp hook that winds up
14459 calling adjust_frame_glyphs) and that our
14460 previous estimation of the frame content was
14461 garbage. We have to start over. These cases
14462 should be rare, so going all the way back to the
14463 top of redisplay should be good enough. */
14464 if (FRAME_GARBAGED_P (f)
14465 && garbaged_frame_retries++ < MAX_GARBAGED_FRAME_RETRIES)
14466 goto retry;
14468 #if defined (HAVE_WINDOW_SYSTEM) && !defined (HAVE_NS)
14469 x_clear_under_internal_border (f);
14470 #endif /* HAVE_WINDOW_SYSTEM && !HAVE_NS */
14472 /* Prevent various kinds of signals during display
14473 update. stdio is not robust about handling
14474 signals, which can cause an apparent I/O error. */
14475 if (interrupt_input)
14476 unrequest_sigio ();
14477 STOP_POLLING;
14479 pending |= update_frame (f, false, false);
14480 f->cursor_type_changed = false;
14481 f->updated_p = true;
14486 eassert (EQ (XFRAME (selected_frame)->selected_window, selected_window));
14488 if (!pending)
14490 /* Do the mark_window_display_accurate after all windows have
14491 been redisplayed because this call resets flags in buffers
14492 which are needed for proper redisplay. */
14493 FOR_EACH_FRAME (tail, frame)
14495 struct frame *f = XFRAME (frame);
14496 if (f->updated_p)
14498 f->redisplay = false;
14499 f->garbaged = false;
14500 mark_window_display_accurate (f->root_window, true);
14501 if (FRAME_TERMINAL (f)->frame_up_to_date_hook)
14502 FRAME_TERMINAL (f)->frame_up_to_date_hook (f);
14507 else if (FRAME_VISIBLE_P (sf) && !FRAME_OBSCURED_P (sf))
14509 displayed_buffer = XBUFFER (XWINDOW (selected_window)->contents);
14510 /* Use list_of_error, not Qerror, so that
14511 we catch only errors and don't run the debugger. */
14512 internal_condition_case_1 (redisplay_window_1, selected_window,
14513 list_of_error,
14514 redisplay_window_error);
14515 if (update_miniwindow_p)
14516 internal_condition_case_1 (redisplay_window_1,
14517 FRAME_MINIBUF_WINDOW (sf), list_of_error,
14518 redisplay_window_error);
14520 /* Compare desired and current matrices, perform output. */
14522 update:
14523 /* If fonts changed, display again. Likewise if redisplay_window_1
14524 above caused some change (e.g., a change in faces) that requires
14525 considering the entire frame again. */
14526 if (sf->fonts_changed || sf->redisplay)
14528 if (sf->redisplay)
14530 /* Set this to force a more thorough redisplay.
14531 Otherwise, we might immediately loop back to the
14532 above "else-if" clause (since all the conditions that
14533 led here might still be true), and we will then
14534 infloop, because the selected-frame's redisplay flag
14535 is not (and cannot be) reset. */
14536 windows_or_buffers_changed = 50;
14538 goto retry;
14541 /* Prevent freeing of realized faces, since desired matrices are
14542 pending that reference the faces we computed and cached. */
14543 inhibit_free_realized_faces = true;
14545 /* Prevent various kinds of signals during display update.
14546 stdio is not robust about handling signals,
14547 which can cause an apparent I/O error. */
14548 if (interrupt_input)
14549 unrequest_sigio ();
14550 STOP_POLLING;
14552 if (FRAME_VISIBLE_P (sf) && !FRAME_OBSCURED_P (sf))
14554 if (hscroll_retries <= MAX_HSCROLL_RETRIES
14555 && hscroll_windows (selected_window))
14557 hscroll_retries++;
14558 goto retry;
14561 XWINDOW (selected_window)->must_be_updated_p = true;
14562 pending = update_frame (sf, false, false);
14563 sf->cursor_type_changed = false;
14566 /* We may have called echo_area_display at the top of this
14567 function. If the echo area is on another frame, that may
14568 have put text on a frame other than the selected one, so the
14569 above call to update_frame would not have caught it. Catch
14570 it here. */
14571 Lisp_Object mini_window = FRAME_MINIBUF_WINDOW (sf);
14572 struct frame *mini_frame = XFRAME (WINDOW_FRAME (XWINDOW (mini_window)));
14574 if (mini_frame != sf && FRAME_WINDOW_P (mini_frame))
14576 XWINDOW (mini_window)->must_be_updated_p = true;
14577 pending |= update_frame (mini_frame, false, false);
14578 mini_frame->cursor_type_changed = false;
14579 if (!pending && hscroll_retries <= MAX_HSCROLL_RETRIES
14580 && hscroll_windows (mini_window))
14582 hscroll_retries++;
14583 goto retry;
14588 /* If display was paused because of pending input, make sure we do a
14589 thorough update the next time. */
14590 if (pending)
14592 /* Prevent the optimization at the beginning of
14593 redisplay_internal that tries a single-line update of the
14594 line containing the cursor in the selected window. */
14595 CHARPOS (this_line_start_pos) = 0;
14597 /* Let the overlay arrow be updated the next time. */
14598 update_overlay_arrows (0);
14600 /* If we pause after scrolling, some rows in the current
14601 matrices of some windows are not valid. */
14602 if (!WINDOW_FULL_WIDTH_P (w)
14603 && !FRAME_WINDOW_P (XFRAME (w->frame)))
14604 update_mode_lines = 36;
14606 else
14608 if (!consider_all_windows_p)
14610 /* This has already been done above if
14611 consider_all_windows_p is set. */
14612 if (XBUFFER (w->contents)->text->redisplay
14613 && buffer_window_count (XBUFFER (w->contents)) > 1)
14614 /* This can happen if b->text->redisplay was set during
14615 jit-lock. */
14616 propagate_buffer_redisplay ();
14617 mark_window_display_accurate_1 (w, true);
14619 /* Say overlay arrows are up to date. */
14620 update_overlay_arrows (1);
14622 if (FRAME_TERMINAL (sf)->frame_up_to_date_hook != 0)
14623 FRAME_TERMINAL (sf)->frame_up_to_date_hook (sf);
14626 update_mode_lines = 0;
14627 windows_or_buffers_changed = 0;
14630 /* Start SIGIO interrupts coming again. Having them off during the
14631 code above makes it less likely one will discard output, but not
14632 impossible, since there might be stuff in the system buffer here.
14633 But it is much hairier to try to do anything about that. */
14634 if (interrupt_input)
14635 request_sigio ();
14636 RESUME_POLLING;
14638 /* If a frame has become visible which was not before, redisplay
14639 again, so that we display it. Expose events for such a frame
14640 (which it gets when becoming visible) don't call the parts of
14641 redisplay constructing glyphs, so simply exposing a frame won't
14642 display anything in this case. So, we have to display these
14643 frames here explicitly. */
14644 if (!pending)
14646 int new_count = 0;
14648 FOR_EACH_FRAME (tail, frame)
14650 if (XFRAME (frame)->visible)
14651 new_count++;
14654 if (new_count != number_of_visible_frames)
14655 windows_or_buffers_changed = 52;
14658 /* Change frame size now if a change is pending. */
14659 do_pending_window_change (true);
14661 /* If we just did a pending size change, or have additional
14662 visible frames, or selected_window changed, redisplay again. */
14663 if ((windows_or_buffers_changed && !pending)
14664 || (WINDOWP (selected_window) && (w = XWINDOW (selected_window)) != sw))
14665 goto retry;
14667 /* Clear the face and image caches.
14669 We used to do this only if consider_all_windows_p. But the cache
14670 needs to be cleared if a timer creates images in the current
14671 buffer (e.g. the test case in Bug#6230). */
14673 if (clear_face_cache_count > CLEAR_FACE_CACHE_COUNT)
14675 clear_face_cache (false);
14676 clear_face_cache_count = 0;
14679 #ifdef HAVE_WINDOW_SYSTEM
14680 if (clear_image_cache_count > CLEAR_IMAGE_CACHE_COUNT)
14682 clear_image_caches (Qnil);
14683 clear_image_cache_count = 0;
14685 #endif /* HAVE_WINDOW_SYSTEM */
14687 end_of_redisplay:
14688 #ifdef HAVE_NS
14689 ns_set_doc_edited ();
14690 #endif
14691 if (interrupt_input && interrupts_deferred)
14692 request_sigio ();
14694 unbind_to (count, Qnil);
14695 RESUME_POLLING;
14698 static void
14699 unwind_redisplay_preserve_echo_area (void)
14701 unblock_buffer_flips ();
14704 /* Redisplay, but leave alone any recent echo area message unless
14705 another message has been requested in its place.
14707 This is useful in situations where you need to redisplay but no
14708 user action has occurred, making it inappropriate for the message
14709 area to be cleared. See tracking_off and
14710 wait_reading_process_output for examples of these situations.
14712 FROM_WHERE is an integer saying from where this function was
14713 called. This is useful for debugging. */
14715 void
14716 redisplay_preserve_echo_area (int from_where)
14718 TRACE ((stderr, "redisplay_preserve_echo_area (%d)\n", from_where));
14720 block_input ();
14721 ptrdiff_t count = SPECPDL_INDEX ();
14722 record_unwind_protect_void (unwind_redisplay_preserve_echo_area);
14723 block_buffer_flips ();
14724 unblock_input ();
14726 if (!NILP (echo_area_buffer[1]))
14728 /* We have a previously displayed message, but no current
14729 message. Redisplay the previous message. */
14730 display_last_displayed_message_p = true;
14731 redisplay_internal ();
14732 display_last_displayed_message_p = false;
14734 else
14735 redisplay_internal ();
14737 flush_frame (SELECTED_FRAME ());
14738 unbind_to (count, Qnil);
14742 /* Function registered with record_unwind_protect in redisplay_internal. */
14744 static void
14745 unwind_redisplay (void)
14747 redisplaying_p = false;
14748 unblock_buffer_flips ();
14749 #ifdef NS_IMPL_COCOA
14750 /* On macOS we may have disabled screen updates due to window
14751 resizing. When redisplay completes we want to re-enable
14752 them. */
14753 ns_enable_screen_updates ();
14754 #endif
14758 /* Mark the display of leaf window W as accurate or inaccurate.
14759 If ACCURATE_P, mark display of W as accurate.
14760 If !ACCURATE_P, arrange for W to be redisplayed the next
14761 time redisplay_internal is called. */
14763 static void
14764 mark_window_display_accurate_1 (struct window *w, bool accurate_p)
14766 struct buffer *b = XBUFFER (w->contents);
14768 w->last_modified = accurate_p ? BUF_MODIFF (b) : 0;
14769 w->last_overlay_modified = accurate_p ? BUF_OVERLAY_MODIFF (b) : 0;
14770 w->last_had_star = BUF_MODIFF (b) > BUF_SAVE_MODIFF (b);
14772 if (accurate_p)
14774 b->clip_changed = false;
14775 b->prevent_redisplay_optimizations_p = false;
14776 eassert (buffer_window_count (b) > 0);
14777 /* Resetting b->text->redisplay is problematic!
14778 In order to make it safer to do it here, redisplay_internal must
14779 have copied all b->text->redisplay to their respective windows. */
14780 b->text->redisplay = false;
14782 BUF_UNCHANGED_MODIFIED (b) = BUF_MODIFF (b);
14783 BUF_OVERLAY_UNCHANGED_MODIFIED (b) = BUF_OVERLAY_MODIFF (b);
14784 BUF_BEG_UNCHANGED (b) = BUF_GPT (b) - BUF_BEG (b);
14785 BUF_END_UNCHANGED (b) = BUF_Z (b) - BUF_GPT (b);
14787 w->current_matrix->buffer = b;
14788 w->current_matrix->begv = BUF_BEGV (b);
14789 w->current_matrix->zv = BUF_ZV (b);
14791 w->last_cursor_vpos = w->cursor.vpos;
14792 w->last_cursor_off_p = w->cursor_off_p;
14794 if (w == XWINDOW (selected_window))
14795 w->last_point = BUF_PT (b);
14796 else
14797 w->last_point = marker_position (w->pointm);
14799 w->window_end_valid = true;
14800 w->update_mode_line = false;
14803 w->redisplay = !accurate_p;
14807 /* Mark the display of windows in the window tree rooted at WINDOW as
14808 accurate or inaccurate. If ACCURATE_P, mark display of
14809 windows as accurate. If !ACCURATE_P, arrange for windows to
14810 be redisplayed the next time redisplay_internal is called. */
14812 void
14813 mark_window_display_accurate (Lisp_Object window, bool accurate_p)
14815 struct window *w;
14817 for (; !NILP (window); window = w->next)
14819 w = XWINDOW (window);
14820 if (WINDOWP (w->contents))
14821 mark_window_display_accurate (w->contents, accurate_p);
14822 else
14823 mark_window_display_accurate_1 (w, accurate_p);
14826 if (accurate_p)
14827 update_overlay_arrows (1);
14828 else
14829 /* Force a thorough redisplay the next time by setting
14830 last_arrow_position and last_arrow_string to t, which is
14831 unequal to any useful value of Voverlay_arrow_... */
14832 update_overlay_arrows (-1);
14836 /* Return value in display table DP (Lisp_Char_Table *) for character
14837 C. Since a display table doesn't have any parent, we don't have to
14838 follow parent. Do not call this function directly but use the
14839 macro DISP_CHAR_VECTOR. */
14841 Lisp_Object
14842 disp_char_vector (struct Lisp_Char_Table *dp, int c)
14844 Lisp_Object val;
14846 if (ASCII_CHAR_P (c))
14848 val = dp->ascii;
14849 if (SUB_CHAR_TABLE_P (val))
14850 val = XSUB_CHAR_TABLE (val)->contents[c];
14852 else
14854 Lisp_Object table;
14856 XSETCHAR_TABLE (table, dp);
14857 val = char_table_ref (table, c);
14859 if (NILP (val))
14860 val = dp->defalt;
14861 return val;
14864 static int buffer_flip_blocked_depth;
14866 static void
14867 block_buffer_flips (void)
14869 eassert (buffer_flip_blocked_depth >= 0);
14870 buffer_flip_blocked_depth++;
14873 static void
14874 unblock_buffer_flips (void)
14876 eassert (buffer_flip_blocked_depth > 0);
14877 if (--buffer_flip_blocked_depth == 0)
14879 Lisp_Object tail, frame;
14880 block_input ();
14881 FOR_EACH_FRAME (tail, frame)
14883 struct frame *f = XFRAME (frame);
14884 if (FRAME_TERMINAL (f)->buffer_flipping_unblocked_hook)
14885 (*FRAME_TERMINAL (f)->buffer_flipping_unblocked_hook) (f);
14887 unblock_input ();
14891 bool
14892 buffer_flipping_blocked_p (void)
14894 return buffer_flip_blocked_depth > 0;
14898 /***********************************************************************
14899 Window Redisplay
14900 ***********************************************************************/
14902 /* Redisplay all leaf windows in the window tree rooted at WINDOW. */
14904 static void
14905 redisplay_windows (Lisp_Object window)
14907 while (!NILP (window))
14909 struct window *w = XWINDOW (window);
14911 if (WINDOWP (w->contents))
14912 redisplay_windows (w->contents);
14913 else if (BUFFERP (w->contents))
14915 displayed_buffer = XBUFFER (w->contents);
14916 /* Use list_of_error, not Qerror, so that
14917 we catch only errors and don't run the debugger. */
14918 internal_condition_case_1 (redisplay_window_0, window,
14919 list_of_error,
14920 redisplay_window_error);
14923 window = w->next;
14927 static Lisp_Object
14928 redisplay_window_error (Lisp_Object ignore)
14930 displayed_buffer->display_error_modiff = BUF_MODIFF (displayed_buffer);
14931 return Qnil;
14934 static Lisp_Object
14935 redisplay_window_0 (Lisp_Object window)
14937 if (displayed_buffer->display_error_modiff < BUF_MODIFF (displayed_buffer))
14938 redisplay_window (window, false);
14939 return Qnil;
14942 static Lisp_Object
14943 redisplay_window_1 (Lisp_Object window)
14945 if (displayed_buffer->display_error_modiff < BUF_MODIFF (displayed_buffer))
14946 redisplay_window (window, true);
14947 return Qnil;
14951 /* Set cursor position of W. PT is assumed to be displayed in ROW.
14952 DELTA and DELTA_BYTES are the numbers of characters and bytes by
14953 which positions recorded in ROW differ from current buffer
14954 positions.
14956 Return true iff cursor is on this row. */
14958 static bool
14959 set_cursor_from_row (struct window *w, struct glyph_row *row,
14960 struct glyph_matrix *matrix,
14961 ptrdiff_t delta, ptrdiff_t delta_bytes,
14962 int dy, int dvpos)
14964 struct glyph *glyph = row->glyphs[TEXT_AREA];
14965 struct glyph *end = glyph + row->used[TEXT_AREA];
14966 struct glyph *cursor = NULL;
14967 /* The last known character position in row. */
14968 ptrdiff_t last_pos = MATRIX_ROW_START_CHARPOS (row) + delta;
14969 int x = row->x;
14970 ptrdiff_t pt_old = PT - delta;
14971 ptrdiff_t pos_before = MATRIX_ROW_START_CHARPOS (row) + delta;
14972 ptrdiff_t pos_after = MATRIX_ROW_END_CHARPOS (row) + delta;
14973 struct glyph *glyph_before = glyph - 1, *glyph_after = end;
14974 /* A glyph beyond the edge of TEXT_AREA which we should never
14975 touch. */
14976 struct glyph *glyphs_end = end;
14977 /* True means we've found a match for cursor position, but that
14978 glyph has the avoid_cursor_p flag set. */
14979 bool match_with_avoid_cursor = false;
14980 /* True means we've seen at least one glyph that came from a
14981 display string. */
14982 bool string_seen = false;
14983 /* Largest and smallest buffer positions seen so far during scan of
14984 glyph row. */
14985 ptrdiff_t bpos_max = pos_before;
14986 ptrdiff_t bpos_min = pos_after;
14987 /* Last buffer position covered by an overlay string with an integer
14988 `cursor' property. */
14989 ptrdiff_t bpos_covered = 0;
14990 /* True means the display string on which to display the cursor
14991 comes from a text property, not from an overlay. */
14992 bool string_from_text_prop = false;
14994 /* Don't even try doing anything if called for a mode-line or
14995 header-line row, since the rest of the code isn't prepared to
14996 deal with such calamities. */
14997 eassert (!row->mode_line_p);
14998 if (row->mode_line_p)
14999 return false;
15001 /* Skip over glyphs not having an object at the start and the end of
15002 the row. These are special glyphs like truncation marks on
15003 terminal frames. */
15004 if (MATRIX_ROW_DISPLAYS_TEXT_P (row))
15006 if (!row->reversed_p)
15008 while (glyph < end
15009 && NILP (glyph->object)
15010 && glyph->charpos < 0)
15012 x += glyph->pixel_width;
15013 ++glyph;
15015 while (end > glyph
15016 && NILP ((end - 1)->object)
15017 /* CHARPOS is zero for blanks and stretch glyphs
15018 inserted by extend_face_to_end_of_line. */
15019 && (end - 1)->charpos <= 0)
15020 --end;
15021 glyph_before = glyph - 1;
15022 glyph_after = end;
15024 else
15026 struct glyph *g;
15028 /* If the glyph row is reversed, we need to process it from back
15029 to front, so swap the edge pointers. */
15030 glyphs_end = end = glyph - 1;
15031 glyph += row->used[TEXT_AREA] - 1;
15033 while (glyph > end + 1
15034 && NILP (glyph->object)
15035 && glyph->charpos < 0)
15036 --glyph;
15037 if (NILP (glyph->object) && glyph->charpos < 0)
15038 --glyph;
15039 /* By default, in reversed rows we put the cursor on the
15040 rightmost (first in the reading order) glyph. */
15041 for (x = 0, g = end + 1; g < glyph; g++)
15042 x += g->pixel_width;
15043 while (end < glyph
15044 && NILP ((end + 1)->object)
15045 && (end + 1)->charpos <= 0)
15046 ++end;
15047 glyph_before = glyph + 1;
15048 glyph_after = end;
15051 else if (row->reversed_p)
15053 /* In R2L rows that don't display text, put the cursor on the
15054 rightmost glyph. Case in point: an empty last line that is
15055 part of an R2L paragraph. */
15056 cursor = end - 1;
15057 /* Avoid placing the cursor on the last glyph of the row, where
15058 on terminal frames we hold the vertical border between
15059 adjacent windows. */
15060 if (!FRAME_WINDOW_P (WINDOW_XFRAME (w))
15061 && !WINDOW_RIGHTMOST_P (w)
15062 && cursor == row->glyphs[LAST_AREA] - 1)
15063 cursor--;
15064 x = -1; /* will be computed below, at label compute_x */
15067 /* Step 1: Try to find the glyph whose character position
15068 corresponds to point. If that's not possible, find 2 glyphs
15069 whose character positions are the closest to point, one before
15070 point, the other after it. */
15071 if (!row->reversed_p)
15072 while (/* not marched to end of glyph row */
15073 glyph < end
15074 /* glyph was not inserted by redisplay for internal purposes */
15075 && !NILP (glyph->object))
15077 if (BUFFERP (glyph->object))
15079 ptrdiff_t dpos = glyph->charpos - pt_old;
15081 if (glyph->charpos > bpos_max)
15082 bpos_max = glyph->charpos;
15083 if (glyph->charpos < bpos_min)
15084 bpos_min = glyph->charpos;
15085 if (!glyph->avoid_cursor_p)
15087 /* If we hit point, we've found the glyph on which to
15088 display the cursor. */
15089 if (dpos == 0)
15091 match_with_avoid_cursor = false;
15092 break;
15094 /* See if we've found a better approximation to
15095 POS_BEFORE or to POS_AFTER. */
15096 if (0 > dpos && dpos > pos_before - pt_old)
15098 pos_before = glyph->charpos;
15099 glyph_before = glyph;
15101 else if (0 < dpos && dpos < pos_after - pt_old)
15103 pos_after = glyph->charpos;
15104 glyph_after = glyph;
15107 else if (dpos == 0)
15108 match_with_avoid_cursor = true;
15110 else if (STRINGP (glyph->object))
15112 Lisp_Object chprop;
15113 ptrdiff_t glyph_pos = glyph->charpos;
15115 chprop = Fget_char_property (make_number (glyph_pos), Qcursor,
15116 glyph->object);
15117 if (!NILP (chprop))
15119 /* If the string came from a `display' text property,
15120 look up the buffer position of that property and
15121 use that position to update bpos_max, as if we
15122 actually saw such a position in one of the row's
15123 glyphs. This helps with supporting integer values
15124 of `cursor' property on the display string in
15125 situations where most or all of the row's buffer
15126 text is completely covered by display properties,
15127 so that no glyph with valid buffer positions is
15128 ever seen in the row. */
15129 ptrdiff_t prop_pos =
15130 string_buffer_position_lim (glyph->object, pos_before,
15131 pos_after, false);
15133 if (prop_pos >= pos_before)
15134 bpos_max = prop_pos;
15136 if (INTEGERP (chprop))
15138 bpos_covered = bpos_max + XINT (chprop);
15139 /* If the `cursor' property covers buffer positions up
15140 to and including point, we should display cursor on
15141 this glyph. Note that, if a `cursor' property on one
15142 of the string's characters has an integer value, we
15143 will break out of the loop below _before_ we get to
15144 the position match above. IOW, integer values of
15145 the `cursor' property override the "exact match for
15146 point" strategy of positioning the cursor. */
15147 /* Implementation note: bpos_max == pt_old when, e.g.,
15148 we are in an empty line, where bpos_max is set to
15149 MATRIX_ROW_START_CHARPOS, see above. */
15150 if (bpos_max <= pt_old && bpos_covered >= pt_old)
15152 cursor = glyph;
15153 break;
15157 string_seen = true;
15159 x += glyph->pixel_width;
15160 ++glyph;
15162 else if (glyph > end) /* row is reversed */
15163 while (!NILP (glyph->object))
15165 if (BUFFERP (glyph->object))
15167 ptrdiff_t dpos = glyph->charpos - pt_old;
15169 if (glyph->charpos > bpos_max)
15170 bpos_max = glyph->charpos;
15171 if (glyph->charpos < bpos_min)
15172 bpos_min = glyph->charpos;
15173 if (!glyph->avoid_cursor_p)
15175 if (dpos == 0)
15177 match_with_avoid_cursor = false;
15178 break;
15180 if (0 > dpos && dpos > pos_before - pt_old)
15182 pos_before = glyph->charpos;
15183 glyph_before = glyph;
15185 else if (0 < dpos && dpos < pos_after - pt_old)
15187 pos_after = glyph->charpos;
15188 glyph_after = glyph;
15191 else if (dpos == 0)
15192 match_with_avoid_cursor = true;
15194 else if (STRINGP (glyph->object))
15196 Lisp_Object chprop;
15197 ptrdiff_t glyph_pos = glyph->charpos;
15199 chprop = Fget_char_property (make_number (glyph_pos), Qcursor,
15200 glyph->object);
15201 if (!NILP (chprop))
15203 ptrdiff_t prop_pos =
15204 string_buffer_position_lim (glyph->object, pos_before,
15205 pos_after, false);
15207 if (prop_pos >= pos_before)
15208 bpos_max = prop_pos;
15210 if (INTEGERP (chprop))
15212 bpos_covered = bpos_max + XINT (chprop);
15213 /* If the `cursor' property covers buffer positions up
15214 to and including point, we should display cursor on
15215 this glyph. */
15216 if (bpos_max <= pt_old && bpos_covered >= pt_old)
15218 cursor = glyph;
15219 break;
15222 string_seen = true;
15224 --glyph;
15225 if (glyph == glyphs_end) /* don't dereference outside TEXT_AREA */
15227 x--; /* can't use any pixel_width */
15228 break;
15230 x -= glyph->pixel_width;
15233 /* Step 2: If we didn't find an exact match for point, we need to
15234 look for a proper place to put the cursor among glyphs between
15235 GLYPH_BEFORE and GLYPH_AFTER. */
15236 if (!((row->reversed_p ? glyph > glyphs_end : glyph < glyphs_end)
15237 && BUFFERP (glyph->object) && glyph->charpos == pt_old)
15238 && !(bpos_max <= pt_old && pt_old <= bpos_covered))
15240 /* An empty line has a single glyph whose OBJECT is nil and
15241 whose CHARPOS is the position of a newline on that line.
15242 Note that on a TTY, there are more glyphs after that, which
15243 were produced by extend_face_to_end_of_line, but their
15244 CHARPOS is zero or negative. */
15245 bool empty_line_p =
15246 ((row->reversed_p ? glyph > glyphs_end : glyph < glyphs_end)
15247 && NILP (glyph->object) && glyph->charpos > 0
15248 /* On a TTY, continued and truncated rows also have a glyph at
15249 their end whose OBJECT is nil and whose CHARPOS is
15250 positive (the continuation and truncation glyphs), but such
15251 rows are obviously not "empty". */
15252 && !(row->continued_p || row->truncated_on_right_p));
15254 if (row->ends_in_ellipsis_p && pos_after == last_pos)
15256 ptrdiff_t ellipsis_pos;
15258 /* Scan back over the ellipsis glyphs. */
15259 if (!row->reversed_p)
15261 ellipsis_pos = (glyph - 1)->charpos;
15262 while (glyph > row->glyphs[TEXT_AREA]
15263 && (glyph - 1)->charpos == ellipsis_pos)
15264 glyph--, x -= glyph->pixel_width;
15265 /* That loop always goes one position too far, including
15266 the glyph before the ellipsis. So scan forward over
15267 that one. */
15268 x += glyph->pixel_width;
15269 glyph++;
15271 else /* row is reversed */
15273 ellipsis_pos = (glyph + 1)->charpos;
15274 while (glyph < row->glyphs[TEXT_AREA] + row->used[TEXT_AREA] - 1
15275 && (glyph + 1)->charpos == ellipsis_pos)
15276 glyph++, x += glyph->pixel_width;
15277 x -= glyph->pixel_width;
15278 glyph--;
15281 else if (match_with_avoid_cursor)
15283 cursor = glyph_after;
15284 x = -1;
15286 else if (string_seen)
15288 int incr = row->reversed_p ? -1 : +1;
15290 /* Need to find the glyph that came out of a string which is
15291 present at point. That glyph is somewhere between
15292 GLYPH_BEFORE and GLYPH_AFTER, and it came from a string
15293 positioned between POS_BEFORE and POS_AFTER in the
15294 buffer. */
15295 struct glyph *start, *stop;
15296 ptrdiff_t pos = pos_before;
15298 x = -1;
15300 /* If the row ends in a newline from a display string,
15301 reordering could have moved the glyphs belonging to the
15302 string out of the [GLYPH_BEFORE..GLYPH_AFTER] range. So
15303 in this case we extend the search to the last glyph in
15304 the row that was not inserted by redisplay. */
15305 if (row->ends_in_newline_from_string_p)
15307 glyph_after = end;
15308 pos_after = MATRIX_ROW_END_CHARPOS (row) + delta;
15311 /* GLYPH_BEFORE and GLYPH_AFTER are the glyphs that
15312 correspond to POS_BEFORE and POS_AFTER, respectively. We
15313 need START and STOP in the order that corresponds to the
15314 row's direction as given by its reversed_p flag. If the
15315 directionality of characters between POS_BEFORE and
15316 POS_AFTER is the opposite of the row's base direction,
15317 these characters will have been reordered for display,
15318 and we need to reverse START and STOP. */
15319 if (!row->reversed_p)
15321 start = min (glyph_before, glyph_after);
15322 stop = max (glyph_before, glyph_after);
15324 else
15326 start = max (glyph_before, glyph_after);
15327 stop = min (glyph_before, glyph_after);
15329 for (glyph = start + incr;
15330 row->reversed_p ? glyph > stop : glyph < stop; )
15333 /* Any glyphs that come from the buffer are here because
15334 of bidi reordering. Skip them, and only pay
15335 attention to glyphs that came from some string. */
15336 if (STRINGP (glyph->object))
15338 Lisp_Object str;
15339 ptrdiff_t tem;
15340 /* If the display property covers the newline, we
15341 need to search for it one position farther. */
15342 ptrdiff_t lim = pos_after
15343 + (pos_after == MATRIX_ROW_END_CHARPOS (row) + delta);
15345 string_from_text_prop = false;
15346 str = glyph->object;
15347 tem = string_buffer_position_lim (str, pos, lim, false);
15348 if (tem == 0 /* from overlay */
15349 || pos <= tem)
15351 /* If the string from which this glyph came is
15352 found in the buffer at point, or at position
15353 that is closer to point than pos_after, then
15354 we've found the glyph we've been looking for.
15355 If it comes from an overlay (tem == 0), and
15356 it has the `cursor' property on one of its
15357 glyphs, record that glyph as a candidate for
15358 displaying the cursor. (As in the
15359 unidirectional version, we will display the
15360 cursor on the last candidate we find.) */
15361 if (tem == 0
15362 || tem == pt_old
15363 || (tem - pt_old > 0 && tem < pos_after))
15365 /* The glyphs from this string could have
15366 been reordered. Find the one with the
15367 smallest string position. Or there could
15368 be a character in the string with the
15369 `cursor' property, which means display
15370 cursor on that character's glyph. */
15371 ptrdiff_t strpos = glyph->charpos;
15373 if (tem)
15375 cursor = glyph;
15376 string_from_text_prop = true;
15378 for ( ;
15379 (row->reversed_p ? glyph > stop : glyph < stop)
15380 && EQ (glyph->object, str);
15381 glyph += incr)
15383 Lisp_Object cprop;
15384 ptrdiff_t gpos = glyph->charpos;
15386 cprop = Fget_char_property (make_number (gpos),
15387 Qcursor,
15388 glyph->object);
15389 if (!NILP (cprop))
15391 cursor = glyph;
15392 break;
15394 if (tem && glyph->charpos < strpos)
15396 strpos = glyph->charpos;
15397 cursor = glyph;
15401 if (tem == pt_old
15402 || (tem - pt_old > 0 && tem < pos_after))
15403 goto compute_x;
15405 if (tem)
15406 pos = tem + 1; /* don't find previous instances */
15408 /* This string is not what we want; skip all of the
15409 glyphs that came from it. */
15410 while ((row->reversed_p ? glyph > stop : glyph < stop)
15411 && EQ (glyph->object, str))
15412 glyph += incr;
15414 else
15415 glyph += incr;
15418 /* If we reached the end of the line, and END was from a string,
15419 the cursor is not on this line. */
15420 if (cursor == NULL
15421 && (row->reversed_p ? glyph <= end : glyph >= end)
15422 && (row->reversed_p ? end > glyphs_end : end < glyphs_end)
15423 && STRINGP (end->object)
15424 && row->continued_p)
15425 return false;
15427 /* A truncated row may not include PT among its character positions.
15428 Setting the cursor inside the scroll margin will trigger
15429 recalculation of hscroll in hscroll_window_tree. But if a
15430 display string covers point, defer to the string-handling
15431 code below to figure this out. */
15432 else if (row->truncated_on_left_p && pt_old < bpos_min)
15434 cursor = glyph_before;
15435 x = -1;
15437 else if ((row->truncated_on_right_p && pt_old > bpos_max)
15438 /* Zero-width characters produce no glyphs. */
15439 || (!empty_line_p
15440 && (row->reversed_p
15441 ? glyph_after > glyphs_end
15442 : glyph_after < glyphs_end)))
15444 cursor = glyph_after;
15445 x = -1;
15449 compute_x:
15450 if (cursor != NULL)
15451 glyph = cursor;
15452 else if (glyph == glyphs_end
15453 && pos_before == pos_after
15454 && STRINGP ((row->reversed_p
15455 ? row->glyphs[TEXT_AREA] + row->used[TEXT_AREA] - 1
15456 : row->glyphs[TEXT_AREA])->object))
15458 /* If all the glyphs of this row came from strings, put the
15459 cursor on the first glyph of the row. This avoids having the
15460 cursor outside of the text area in this very rare and hard
15461 use case. */
15462 glyph =
15463 row->reversed_p
15464 ? row->glyphs[TEXT_AREA] + row->used[TEXT_AREA] - 1
15465 : row->glyphs[TEXT_AREA];
15467 if (x < 0)
15469 struct glyph *g;
15471 /* Need to compute x that corresponds to GLYPH. */
15472 for (g = row->glyphs[TEXT_AREA], x = row->x; g < glyph; g++)
15474 if (g >= row->glyphs[TEXT_AREA] + row->used[TEXT_AREA])
15475 emacs_abort ();
15476 x += g->pixel_width;
15480 /* ROW could be part of a continued line, which, under bidi
15481 reordering, might have other rows whose start and end charpos
15482 occlude point. Only set w->cursor if we found a better
15483 approximation to the cursor position than we have from previously
15484 examined candidate rows belonging to the same continued line. */
15485 if (/* We already have a candidate row. */
15486 w->cursor.vpos >= 0
15487 /* That candidate is not the row we are processing. */
15488 && MATRIX_ROW (matrix, w->cursor.vpos) != row
15489 /* Make sure cursor.vpos specifies a row whose start and end
15490 charpos occlude point, and it is valid candidate for being a
15491 cursor-row. This is because some callers of this function
15492 leave cursor.vpos at the row where the cursor was displayed
15493 during the last redisplay cycle. */
15494 && MATRIX_ROW_START_CHARPOS (MATRIX_ROW (matrix, w->cursor.vpos)) <= pt_old
15495 && pt_old <= MATRIX_ROW_END_CHARPOS (MATRIX_ROW (matrix, w->cursor.vpos))
15496 && cursor_row_p (MATRIX_ROW (matrix, w->cursor.vpos)))
15498 struct glyph *g1
15499 = MATRIX_ROW_GLYPH_START (matrix, w->cursor.vpos) + w->cursor.hpos;
15501 /* Don't consider glyphs that are outside TEXT_AREA. */
15502 if (!(row->reversed_p ? glyph > glyphs_end : glyph < glyphs_end))
15503 return false;
15504 /* Keep the candidate whose buffer position is the closest to
15505 point or has the `cursor' property. */
15506 if (/* Previous candidate is a glyph in TEXT_AREA of that row. */
15507 w->cursor.hpos >= 0
15508 && w->cursor.hpos < MATRIX_ROW_USED (matrix, w->cursor.vpos)
15509 && ((BUFFERP (g1->object)
15510 && (g1->charpos == pt_old /* An exact match always wins. */
15511 || (BUFFERP (glyph->object)
15512 && eabs (g1->charpos - pt_old)
15513 < eabs (glyph->charpos - pt_old))))
15514 /* Previous candidate is a glyph from a string that has
15515 a non-nil `cursor' property. */
15516 || (STRINGP (g1->object)
15517 && (!NILP (Fget_char_property (make_number (g1->charpos),
15518 Qcursor, g1->object))
15519 /* Previous candidate is from the same display
15520 string as this one, and the display string
15521 came from a text property. */
15522 || (EQ (g1->object, glyph->object)
15523 && string_from_text_prop)
15524 /* this candidate is from newline and its
15525 position is not an exact match */
15526 || (NILP (glyph->object)
15527 && glyph->charpos != pt_old)))))
15528 return false;
15529 /* If this candidate gives an exact match, use that. */
15530 if (!((BUFFERP (glyph->object) && glyph->charpos == pt_old)
15531 /* If this candidate is a glyph created for the
15532 terminating newline of a line, and point is on that
15533 newline, it wins because it's an exact match. */
15534 || (!row->continued_p
15535 && NILP (glyph->object)
15536 && glyph->charpos == 0
15537 && pt_old == MATRIX_ROW_END_CHARPOS (row) - 1))
15538 /* Otherwise, keep the candidate that comes from a row
15539 spanning less buffer positions. This may win when one or
15540 both candidate positions are on glyphs that came from
15541 display strings, for which we cannot compare buffer
15542 positions. */
15543 && MATRIX_ROW_END_CHARPOS (MATRIX_ROW (matrix, w->cursor.vpos))
15544 - MATRIX_ROW_START_CHARPOS (MATRIX_ROW (matrix, w->cursor.vpos))
15545 < MATRIX_ROW_END_CHARPOS (row) - MATRIX_ROW_START_CHARPOS (row))
15546 return false;
15548 w->cursor.hpos = glyph - row->glyphs[TEXT_AREA];
15549 w->cursor.x = x;
15550 w->cursor.vpos = MATRIX_ROW_VPOS (row, matrix) + dvpos;
15551 w->cursor.y = row->y + dy;
15553 if (w == XWINDOW (selected_window))
15555 if (!row->continued_p
15556 && !MATRIX_ROW_CONTINUATION_LINE_P (row)
15557 && row->x == 0)
15559 this_line_buffer = XBUFFER (w->contents);
15561 CHARPOS (this_line_start_pos)
15562 = MATRIX_ROW_START_CHARPOS (row) + delta;
15563 BYTEPOS (this_line_start_pos)
15564 = MATRIX_ROW_START_BYTEPOS (row) + delta_bytes;
15566 CHARPOS (this_line_end_pos)
15567 = Z - (MATRIX_ROW_END_CHARPOS (row) + delta);
15568 BYTEPOS (this_line_end_pos)
15569 = Z_BYTE - (MATRIX_ROW_END_BYTEPOS (row) + delta_bytes);
15571 this_line_y = w->cursor.y;
15572 this_line_pixel_height = row->height;
15573 this_line_vpos = w->cursor.vpos;
15574 this_line_start_x = row->x;
15576 else
15577 CHARPOS (this_line_start_pos) = 0;
15580 return true;
15584 /* Run window scroll functions, if any, for WINDOW with new window
15585 start STARTP. Sets the window start of WINDOW to that position.
15587 We assume that the window's buffer is really current. */
15589 static struct text_pos
15590 run_window_scroll_functions (Lisp_Object window, struct text_pos startp)
15592 struct window *w = XWINDOW (window);
15593 SET_MARKER_FROM_TEXT_POS (w->start, startp);
15595 eassert (current_buffer == XBUFFER (w->contents));
15597 if (!NILP (Vwindow_scroll_functions))
15599 run_hook_with_args_2 (Qwindow_scroll_functions, window,
15600 make_number (CHARPOS (startp)));
15601 SET_TEXT_POS_FROM_MARKER (startp, w->start);
15602 /* In case the hook functions switch buffers. */
15603 set_buffer_internal (XBUFFER (w->contents));
15606 return startp;
15610 /* Make sure the line containing the cursor is fully visible.
15611 A value of true means there is nothing to be done.
15612 (Either the line is fully visible, or it cannot be made so,
15613 or we cannot tell.)
15615 If FORCE_P, return false even if partial visible cursor row
15616 is higher than window.
15618 If CURRENT_MATRIX_P, use the information from the
15619 window's current glyph matrix; otherwise use the desired glyph
15620 matrix.
15622 A value of false means the caller should do scrolling
15623 as if point had gone off the screen. */
15625 static bool
15626 cursor_row_fully_visible_p (struct window *w, bool force_p,
15627 bool current_matrix_p)
15629 struct glyph_matrix *matrix;
15630 struct glyph_row *row;
15631 int window_height;
15633 if (!make_cursor_line_fully_visible_p)
15634 return true;
15636 /* It's not always possible to find the cursor, e.g, when a window
15637 is full of overlay strings. Don't do anything in that case. */
15638 if (w->cursor.vpos < 0)
15639 return true;
15641 matrix = current_matrix_p ? w->current_matrix : w->desired_matrix;
15642 row = MATRIX_ROW (matrix, w->cursor.vpos);
15644 /* If the cursor row is not partially visible, there's nothing to do. */
15645 if (!MATRIX_ROW_PARTIALLY_VISIBLE_P (w, row))
15646 return true;
15648 /* If the row the cursor is in is taller than the window's height,
15649 it's not clear what to do, so do nothing. */
15650 window_height = window_box_height (w);
15651 if (row->height >= window_height)
15653 if (!force_p || MINI_WINDOW_P (w)
15654 || w->vscroll || w->cursor.vpos == 0)
15655 return true;
15657 return false;
15661 /* Try scrolling PT into view in window WINDOW. JUST_THIS_ONE_P
15662 means only WINDOW is redisplayed in redisplay_internal.
15663 TEMP_SCROLL_STEP has the same meaning as emacs_scroll_step, and is used
15664 in redisplay_window to bring a partially visible line into view in
15665 the case that only the cursor has moved.
15667 LAST_LINE_MISFIT should be true if we're scrolling because the
15668 last screen line's vertical height extends past the end of the screen.
15670 Value is
15672 1 if scrolling succeeded
15674 0 if scrolling didn't find point.
15676 -1 if new fonts have been loaded so that we must interrupt
15677 redisplay, adjust glyph matrices, and try again. */
15679 enum
15681 SCROLLING_SUCCESS,
15682 SCROLLING_FAILED,
15683 SCROLLING_NEED_LARGER_MATRICES
15686 /* If scroll-conservatively is more than this, never recenter.
15688 If you change this, don't forget to update the doc string of
15689 `scroll-conservatively' and the Emacs manual. */
15690 #define SCROLL_LIMIT 100
15692 static int
15693 try_scrolling (Lisp_Object window, bool just_this_one_p,
15694 ptrdiff_t arg_scroll_conservatively, ptrdiff_t scroll_step,
15695 bool temp_scroll_step, bool last_line_misfit)
15697 struct window *w = XWINDOW (window);
15698 struct text_pos pos, startp;
15699 struct it it;
15700 int this_scroll_margin, scroll_max, rc, height;
15701 int dy = 0, amount_to_scroll = 0;
15702 bool scroll_down_p = false;
15703 int extra_scroll_margin_lines = last_line_misfit;
15704 Lisp_Object aggressive;
15705 /* We will never try scrolling more than this number of lines. */
15706 int scroll_limit = SCROLL_LIMIT;
15707 int frame_line_height = default_line_pixel_height (w);
15709 #ifdef GLYPH_DEBUG
15710 debug_method_add (w, "try_scrolling");
15711 #endif
15713 SET_TEXT_POS_FROM_MARKER (startp, w->start);
15715 this_scroll_margin = window_scroll_margin (w, MARGIN_IN_PIXELS);
15717 /* Force arg_scroll_conservatively to have a reasonable value, to
15718 avoid scrolling too far away with slow move_it_* functions. Note
15719 that the user can supply scroll-conservatively equal to
15720 `most-positive-fixnum', which can be larger than INT_MAX. */
15721 if (arg_scroll_conservatively > scroll_limit)
15723 arg_scroll_conservatively = scroll_limit + 1;
15724 scroll_max = scroll_limit * frame_line_height;
15726 else if (scroll_step || arg_scroll_conservatively || temp_scroll_step)
15727 /* Compute how much we should try to scroll maximally to bring
15728 point into view. */
15729 scroll_max = (max (scroll_step,
15730 max (arg_scroll_conservatively, temp_scroll_step))
15731 * frame_line_height);
15732 else if (NUMBERP (BVAR (current_buffer, scroll_down_aggressively))
15733 || NUMBERP (BVAR (current_buffer, scroll_up_aggressively)))
15734 /* We're trying to scroll because of aggressive scrolling but no
15735 scroll_step is set. Choose an arbitrary one. */
15736 scroll_max = 10 * frame_line_height;
15737 else
15738 scroll_max = 0;
15740 too_near_end:
15742 /* Decide whether to scroll down. */
15743 if (PT > CHARPOS (startp))
15745 int scroll_margin_y;
15747 /* Compute the pixel ypos of the scroll margin, then move IT to
15748 either that ypos or PT, whichever comes first. */
15749 start_display (&it, w, startp);
15750 scroll_margin_y = it.last_visible_y - partial_line_height (&it)
15751 - this_scroll_margin
15752 - frame_line_height * extra_scroll_margin_lines;
15753 move_it_to (&it, PT, -1, scroll_margin_y - 1, -1,
15754 (MOVE_TO_POS | MOVE_TO_Y));
15756 if (PT > CHARPOS (it.current.pos))
15758 int y0 = line_bottom_y (&it);
15759 /* Compute how many pixels below window bottom to stop searching
15760 for PT. This avoids costly search for PT that is far away if
15761 the user limited scrolling by a small number of lines, but
15762 always finds PT if scroll_conservatively is set to a large
15763 number, such as most-positive-fixnum. */
15764 int slack = max (scroll_max, 10 * frame_line_height);
15765 int y_to_move = it.last_visible_y + slack;
15767 /* Compute the distance from the scroll margin to PT or to
15768 the scroll limit, whichever comes first. This should
15769 include the height of the cursor line, to make that line
15770 fully visible. */
15771 move_it_to (&it, PT, -1, y_to_move,
15772 -1, MOVE_TO_POS | MOVE_TO_Y);
15773 dy = line_bottom_y (&it) - y0;
15775 if (dy > scroll_max)
15776 return SCROLLING_FAILED;
15778 if (dy > 0)
15779 scroll_down_p = true;
15781 else if (PT == IT_CHARPOS (it)
15782 && IT_CHARPOS (it) < ZV
15783 && it.method == GET_FROM_STRING
15784 && arg_scroll_conservatively > scroll_limit
15785 && it.current_x == 0)
15787 enum move_it_result skip;
15788 int y1 = it.current_y;
15789 int vpos;
15791 /* A before-string that includes newlines and is displayed
15792 on the last visible screen line could fail us under
15793 scroll-conservatively > 100, because we will be unable to
15794 position the cursor on that last visible line. Try to
15795 recover by finding the first screen line that has some
15796 glyphs coming from the buffer text. */
15797 do {
15798 skip = move_it_in_display_line_to (&it, ZV, -1, MOVE_TO_POS);
15799 if (skip != MOVE_NEWLINE_OR_CR
15800 || IT_CHARPOS (it) != PT
15801 || it.method == GET_FROM_BUFFER)
15802 break;
15803 vpos = it.vpos;
15804 move_it_to (&it, -1, -1, -1, vpos + 1, MOVE_TO_VPOS);
15805 } while (it.vpos > vpos);
15807 dy = it.current_y - y1;
15809 if (dy > scroll_max)
15810 return SCROLLING_FAILED;
15812 if (dy > 0)
15813 scroll_down_p = true;
15817 if (scroll_down_p)
15819 /* Point is in or below the bottom scroll margin, so move the
15820 window start down. If scrolling conservatively, move it just
15821 enough down to make point visible. If scroll_step is set,
15822 move it down by scroll_step. */
15823 if (arg_scroll_conservatively)
15824 amount_to_scroll
15825 = min (max (dy, frame_line_height),
15826 frame_line_height * arg_scroll_conservatively);
15827 else if (scroll_step || temp_scroll_step)
15828 amount_to_scroll = scroll_max;
15829 else
15831 aggressive = BVAR (current_buffer, scroll_up_aggressively);
15832 height = WINDOW_BOX_TEXT_HEIGHT (w);
15833 if (NUMBERP (aggressive))
15835 double float_amount = XFLOATINT (aggressive) * height;
15836 int aggressive_scroll = float_amount;
15837 if (aggressive_scroll == 0 && float_amount > 0)
15838 aggressive_scroll = 1;
15839 /* Don't let point enter the scroll margin near top of
15840 the window. This could happen if the value of
15841 scroll_up_aggressively is too large and there are
15842 non-zero margins, because scroll_up_aggressively
15843 means put point that fraction of window height
15844 _from_the_bottom_margin_. */
15845 if (aggressive_scroll + 2 * this_scroll_margin > height)
15846 aggressive_scroll = height - 2 * this_scroll_margin;
15847 amount_to_scroll = dy + aggressive_scroll;
15851 if (amount_to_scroll <= 0)
15852 return SCROLLING_FAILED;
15854 start_display (&it, w, startp);
15855 if (arg_scroll_conservatively <= scroll_limit)
15856 move_it_vertically (&it, amount_to_scroll);
15857 else
15859 /* Extra precision for users who set scroll-conservatively
15860 to a large number: make sure the amount we scroll
15861 the window start is never less than amount_to_scroll,
15862 which was computed as distance from window bottom to
15863 point. This matters when lines at window top and lines
15864 below window bottom have different height. */
15865 struct it it1;
15866 void *it1data = NULL;
15867 /* We use a temporary it1 because line_bottom_y can modify
15868 its argument, if it moves one line down; see there. */
15869 int start_y;
15871 SAVE_IT (it1, it, it1data);
15872 start_y = line_bottom_y (&it1);
15873 do {
15874 RESTORE_IT (&it, &it, it1data);
15875 move_it_by_lines (&it, 1);
15876 SAVE_IT (it1, it, it1data);
15877 } while (IT_CHARPOS (it) < ZV
15878 && line_bottom_y (&it1) - start_y < amount_to_scroll);
15879 bidi_unshelve_cache (it1data, true);
15882 /* If STARTP is unchanged, move it down another screen line. */
15883 if (IT_CHARPOS (it) == CHARPOS (startp))
15884 move_it_by_lines (&it, 1);
15885 startp = it.current.pos;
15887 else
15889 struct text_pos scroll_margin_pos = startp;
15890 int y_offset = 0;
15892 /* See if point is inside the scroll margin at the top of the
15893 window. */
15894 if (this_scroll_margin)
15896 int y_start;
15898 start_display (&it, w, startp);
15899 y_start = it.current_y;
15900 move_it_vertically (&it, this_scroll_margin);
15901 scroll_margin_pos = it.current.pos;
15902 /* If we didn't move enough before hitting ZV, request
15903 additional amount of scroll, to move point out of the
15904 scroll margin. */
15905 if (IT_CHARPOS (it) == ZV
15906 && it.current_y - y_start < this_scroll_margin)
15907 y_offset = this_scroll_margin - (it.current_y - y_start);
15910 if (PT < CHARPOS (scroll_margin_pos))
15912 /* Point is in the scroll margin at the top of the window or
15913 above what is displayed in the window. */
15914 int y0, y_to_move;
15916 /* Compute the vertical distance from PT to the scroll
15917 margin position. Move as far as scroll_max allows, or
15918 one screenful, or 10 screen lines, whichever is largest.
15919 Give up if distance is greater than scroll_max or if we
15920 didn't reach the scroll margin position. */
15921 SET_TEXT_POS (pos, PT, PT_BYTE);
15922 start_display (&it, w, pos);
15923 y0 = it.current_y;
15924 y_to_move = max (it.last_visible_y,
15925 max (scroll_max, 10 * frame_line_height));
15926 move_it_to (&it, CHARPOS (scroll_margin_pos), 0,
15927 y_to_move, -1,
15928 MOVE_TO_POS | MOVE_TO_X | MOVE_TO_Y);
15929 dy = it.current_y - y0;
15930 if (dy > scroll_max
15931 || IT_CHARPOS (it) < CHARPOS (scroll_margin_pos))
15932 return SCROLLING_FAILED;
15934 /* Additional scroll for when ZV was too close to point. */
15935 dy += y_offset;
15937 /* Compute new window start. */
15938 start_display (&it, w, startp);
15940 if (arg_scroll_conservatively)
15941 amount_to_scroll = max (dy, frame_line_height
15942 * max (scroll_step, temp_scroll_step));
15943 else if (scroll_step || temp_scroll_step)
15944 amount_to_scroll = scroll_max;
15945 else
15947 aggressive = BVAR (current_buffer, scroll_down_aggressively);
15948 height = WINDOW_BOX_TEXT_HEIGHT (w);
15949 if (NUMBERP (aggressive))
15951 double float_amount = XFLOATINT (aggressive) * height;
15952 int aggressive_scroll = float_amount;
15953 if (aggressive_scroll == 0 && float_amount > 0)
15954 aggressive_scroll = 1;
15955 /* Don't let point enter the scroll margin near
15956 bottom of the window, if the value of
15957 scroll_down_aggressively happens to be too
15958 large. */
15959 if (aggressive_scroll + 2 * this_scroll_margin > height)
15960 aggressive_scroll = height - 2 * this_scroll_margin;
15961 amount_to_scroll = dy + aggressive_scroll;
15965 if (amount_to_scroll <= 0)
15966 return SCROLLING_FAILED;
15968 move_it_vertically_backward (&it, amount_to_scroll);
15969 startp = it.current.pos;
15973 /* Run window scroll functions. */
15974 startp = run_window_scroll_functions (window, startp);
15976 /* Display the window. Give up if new fonts are loaded, or if point
15977 doesn't appear. */
15978 if (!try_window (window, startp, 0))
15979 rc = SCROLLING_NEED_LARGER_MATRICES;
15980 else if (w->cursor.vpos < 0)
15982 clear_glyph_matrix (w->desired_matrix);
15983 rc = SCROLLING_FAILED;
15985 else
15987 /* Maybe forget recorded base line for line number display. */
15988 if (!just_this_one_p
15989 || current_buffer->clip_changed
15990 || BEG_UNCHANGED < CHARPOS (startp))
15991 w->base_line_number = 0;
15993 /* If cursor ends up on a partially visible line,
15994 treat that as being off the bottom of the screen. */
15995 if (! cursor_row_fully_visible_p (w, extra_scroll_margin_lines <= 1,
15996 false)
15997 /* It's possible that the cursor is on the first line of the
15998 buffer, which is partially obscured due to a vscroll
15999 (Bug#7537). In that case, avoid looping forever. */
16000 && extra_scroll_margin_lines < w->desired_matrix->nrows - 1)
16002 clear_glyph_matrix (w->desired_matrix);
16003 ++extra_scroll_margin_lines;
16004 goto too_near_end;
16006 rc = SCROLLING_SUCCESS;
16009 return rc;
16013 /* Compute a suitable window start for window W if display of W starts
16014 on a continuation line. Value is true if a new window start
16015 was computed.
16017 The new window start will be computed, based on W's width, starting
16018 from the start of the continued line. It is the start of the
16019 screen line with the minimum distance from the old start W->start,
16020 which is still before point (otherwise point will definitely not
16021 be visible in the window). */
16023 static bool
16024 compute_window_start_on_continuation_line (struct window *w)
16026 struct text_pos pos, start_pos, pos_before_pt;
16027 bool window_start_changed_p = false;
16029 SET_TEXT_POS_FROM_MARKER (start_pos, w->start);
16031 /* If window start is on a continuation line... Window start may be
16032 < BEGV in case there's invisible text at the start of the
16033 buffer (M-x rmail, for example). */
16034 if (CHARPOS (start_pos) > BEGV
16035 && FETCH_BYTE (BYTEPOS (start_pos) - 1) != '\n')
16037 struct it it;
16038 struct glyph_row *row;
16040 /* Handle the case that the window start is out of range. */
16041 if (CHARPOS (start_pos) < BEGV)
16042 SET_TEXT_POS (start_pos, BEGV, BEGV_BYTE);
16043 else if (CHARPOS (start_pos) > ZV)
16044 SET_TEXT_POS (start_pos, ZV, ZV_BYTE);
16046 /* Find the start of the continued line. This should be fast
16047 because find_newline is fast (newline cache). */
16048 row = w->desired_matrix->rows + window_wants_header_line (w);
16049 init_iterator (&it, w, CHARPOS (start_pos), BYTEPOS (start_pos),
16050 row, DEFAULT_FACE_ID);
16051 reseat_at_previous_visible_line_start (&it);
16053 /* If the line start is "too far" away from the window start,
16054 say it takes too much time to compute a new window start.
16055 Also, give up if the line start is after point, as in that
16056 case point will not be visible with any window start we
16057 compute. */
16058 if (IT_CHARPOS (it) <= PT
16059 || (CHARPOS (start_pos) - IT_CHARPOS (it)
16060 /* PXW: Do we need upper bounds here? */
16061 < WINDOW_TOTAL_LINES (w) * WINDOW_TOTAL_COLS (w)))
16063 int min_distance, distance;
16065 /* Move forward by display lines to find the new window
16066 start. If window width was enlarged, the new start can
16067 be expected to be > the old start. If window width was
16068 decreased, the new window start will be < the old start.
16069 So, we're looking for the display line start with the
16070 minimum distance from the old window start. */
16071 pos_before_pt = pos = it.current.pos;
16072 min_distance = DISP_INFINITY;
16073 while ((distance = eabs (CHARPOS (start_pos) - IT_CHARPOS (it))),
16074 distance < min_distance)
16076 min_distance = distance;
16077 if (CHARPOS (pos) <= PT)
16078 pos_before_pt = pos;
16079 pos = it.current.pos;
16080 if (it.line_wrap == WORD_WRAP)
16082 /* Under WORD_WRAP, move_it_by_lines is likely to
16083 overshoot and stop not at the first, but the
16084 second character from the left margin. So in
16085 that case, we need a more tight control on the X
16086 coordinate of the iterator than move_it_by_lines
16087 promises in its contract. The method is to first
16088 go to the last (rightmost) visible character of a
16089 line, then move to the leftmost character on the
16090 next line in a separate call. */
16091 move_it_to (&it, ZV, it.last_visible_x, it.current_y, -1,
16092 MOVE_TO_POS | MOVE_TO_X | MOVE_TO_Y);
16093 move_it_to (&it, ZV, 0,
16094 it.current_y + it.max_ascent + it.max_descent, -1,
16095 MOVE_TO_POS | MOVE_TO_X | MOVE_TO_Y);
16097 else
16098 move_it_by_lines (&it, 1);
16101 /* It makes very little sense to make the new window start
16102 after point, as point won't be visible. If that's what
16103 the loop above finds, fall back on the candidate before
16104 or at point that is closest to the old window start. */
16105 if (CHARPOS (pos) > PT)
16106 pos = pos_before_pt;
16108 /* Set the window start there. */
16109 SET_MARKER_FROM_TEXT_POS (w->start, pos);
16110 window_start_changed_p = true;
16114 return window_start_changed_p;
16118 /* Try cursor movement in case text has not changed in window WINDOW,
16119 with window start STARTP. Value is
16121 CURSOR_MOVEMENT_SUCCESS if successful
16123 CURSOR_MOVEMENT_CANNOT_BE_USED if this method cannot be used
16125 CURSOR_MOVEMENT_MUST_SCROLL if we know we have to scroll the
16126 display. *SCROLL_STEP is set to true, under certain circumstances, if
16127 we want to scroll as if scroll-step were set to 1. See the code.
16129 CURSOR_MOVEMENT_NEED_LARGER_MATRICES if we need larger matrices, in
16130 which case we have to abort this redisplay, and adjust matrices
16131 first. */
16133 enum
16135 CURSOR_MOVEMENT_SUCCESS,
16136 CURSOR_MOVEMENT_CANNOT_BE_USED,
16137 CURSOR_MOVEMENT_MUST_SCROLL,
16138 CURSOR_MOVEMENT_NEED_LARGER_MATRICES
16141 static int
16142 try_cursor_movement (Lisp_Object window, struct text_pos startp,
16143 bool *scroll_step)
16145 struct window *w = XWINDOW (window);
16146 struct frame *f = XFRAME (w->frame);
16147 int rc = CURSOR_MOVEMENT_CANNOT_BE_USED;
16149 #ifdef GLYPH_DEBUG
16150 if (inhibit_try_cursor_movement)
16151 return rc;
16152 #endif
16154 /* Previously, there was a check for Lisp integer in the
16155 if-statement below. Now, this field is converted to
16156 ptrdiff_t, thus zero means invalid position in a buffer. */
16157 eassert (w->last_point > 0);
16158 /* Likewise there was a check whether window_end_vpos is nil or larger
16159 than the window. Now window_end_vpos is int and so never nil, but
16160 let's leave eassert to check whether it fits in the window. */
16161 eassert (!w->window_end_valid
16162 || w->window_end_vpos < w->current_matrix->nrows);
16164 /* Handle case where text has not changed, only point, and it has
16165 not moved off the frame. */
16166 if (/* Point may be in this window. */
16167 PT >= CHARPOS (startp)
16168 /* Selective display hasn't changed. */
16169 && !current_buffer->clip_changed
16170 /* Function force-mode-line-update is used to force a thorough
16171 redisplay. It sets either windows_or_buffers_changed or
16172 update_mode_lines. So don't take a shortcut here for these
16173 cases. */
16174 && !update_mode_lines
16175 && !windows_or_buffers_changed
16176 && !f->cursor_type_changed
16177 && NILP (Vshow_trailing_whitespace)
16178 /* When display-line-numbers is in relative mode, moving point
16179 requires to redraw the entire window. */
16180 && !EQ (Vdisplay_line_numbers, Qrelative)
16181 && !EQ (Vdisplay_line_numbers, Qvisual)
16182 /* When the current line number should be displayed in a
16183 distinct face, moving point cannot be handled in optimized
16184 way as below. */
16185 && !(!NILP (Vdisplay_line_numbers)
16186 && NILP (Finternal_lisp_face_equal_p (Qline_number,
16187 Qline_number_current_line,
16188 w->frame)))
16189 /* This code is not used for mini-buffer for the sake of the case
16190 of redisplaying to replace an echo area message; since in
16191 that case the mini-buffer contents per se are usually
16192 unchanged. This code is of no real use in the mini-buffer
16193 since the handling of this_line_start_pos, etc., in redisplay
16194 handles the same cases. */
16195 && !EQ (window, minibuf_window)
16196 /* When overlay arrow is shown in current buffer, point movement
16197 is no longer "simple", as it typically causes the overlay
16198 arrow to move as well. */
16199 && !overlay_arrow_in_current_buffer_p ())
16201 int this_scroll_margin, top_scroll_margin;
16202 struct glyph_row *row = NULL;
16204 #ifdef GLYPH_DEBUG
16205 debug_method_add (w, "cursor movement");
16206 #endif
16208 this_scroll_margin = window_scroll_margin (w, MARGIN_IN_PIXELS);
16210 top_scroll_margin = this_scroll_margin;
16211 if (window_wants_header_line (w))
16212 top_scroll_margin += CURRENT_HEADER_LINE_HEIGHT (w);
16214 /* Start with the row the cursor was displayed during the last
16215 not paused redisplay. Give up if that row is not valid. */
16216 if (w->last_cursor_vpos < 0
16217 || w->last_cursor_vpos >= w->current_matrix->nrows)
16218 rc = CURSOR_MOVEMENT_MUST_SCROLL;
16219 else
16221 row = MATRIX_ROW (w->current_matrix, w->last_cursor_vpos);
16222 if (row->mode_line_p)
16223 ++row;
16224 if (!row->enabled_p)
16225 rc = CURSOR_MOVEMENT_MUST_SCROLL;
16228 if (rc == CURSOR_MOVEMENT_CANNOT_BE_USED)
16230 bool scroll_p = false, must_scroll = false;
16231 int last_y = window_text_bottom_y (w) - this_scroll_margin;
16233 if (PT > w->last_point)
16235 /* Point has moved forward. */
16236 while (MATRIX_ROW_END_CHARPOS (row) < PT
16237 && MATRIX_ROW_BOTTOM_Y (row) < last_y)
16239 eassert (row->enabled_p);
16240 ++row;
16243 /* If the end position of a row equals the start
16244 position of the next row, and PT is at that position,
16245 we would rather display cursor in the next line. */
16246 while (MATRIX_ROW_BOTTOM_Y (row) < last_y
16247 && MATRIX_ROW_END_CHARPOS (row) == PT
16248 && row < MATRIX_MODE_LINE_ROW (w->current_matrix)
16249 && MATRIX_ROW_START_CHARPOS (row+1) == PT
16250 && !cursor_row_p (row))
16251 ++row;
16253 /* If within the scroll margin, scroll. Note that
16254 MATRIX_ROW_BOTTOM_Y gives the pixel position at which
16255 the next line would be drawn, and that
16256 this_scroll_margin can be zero. */
16257 if (MATRIX_ROW_BOTTOM_Y (row) > last_y
16258 || PT > MATRIX_ROW_END_CHARPOS (row)
16259 /* Line is completely visible last line in window
16260 and PT is to be set in the next line. */
16261 || (MATRIX_ROW_BOTTOM_Y (row) == last_y
16262 && PT == MATRIX_ROW_END_CHARPOS (row)
16263 && !row->ends_at_zv_p
16264 && !MATRIX_ROW_ENDS_IN_MIDDLE_OF_CHAR_P (row)))
16265 scroll_p = true;
16267 else if (PT < w->last_point)
16269 /* Cursor has to be moved backward. Note that PT >=
16270 CHARPOS (startp) because of the outer if-statement. */
16271 while (!row->mode_line_p
16272 && (MATRIX_ROW_START_CHARPOS (row) > PT
16273 || (MATRIX_ROW_START_CHARPOS (row) == PT
16274 && (MATRIX_ROW_STARTS_IN_MIDDLE_OF_CHAR_P (row)
16275 || (/* STARTS_IN_MIDDLE_OF_STRING_P (row) */
16276 row > w->current_matrix->rows
16277 && (row-1)->ends_in_newline_from_string_p))))
16278 && (row->y > top_scroll_margin
16279 || CHARPOS (startp) == BEGV))
16281 eassert (row->enabled_p);
16282 --row;
16285 /* Consider the following case: Window starts at BEGV,
16286 there is invisible, intangible text at BEGV, so that
16287 display starts at some point START > BEGV. It can
16288 happen that we are called with PT somewhere between
16289 BEGV and START. Try to handle that case. */
16290 if (row < w->current_matrix->rows
16291 || row->mode_line_p)
16293 row = w->current_matrix->rows;
16294 if (row->mode_line_p)
16295 ++row;
16298 /* Due to newlines in overlay strings, we may have to
16299 skip forward over overlay strings. */
16300 while (MATRIX_ROW_BOTTOM_Y (row) < last_y
16301 && MATRIX_ROW_END_CHARPOS (row) == PT
16302 && !cursor_row_p (row))
16303 ++row;
16305 /* If within the scroll margin, scroll. */
16306 if (row->y < top_scroll_margin
16307 && CHARPOS (startp) != BEGV)
16308 scroll_p = true;
16310 else
16312 /* Cursor did not move. So don't scroll even if cursor line
16313 is partially visible, as it was so before. */
16314 rc = CURSOR_MOVEMENT_SUCCESS;
16317 if (PT < MATRIX_ROW_START_CHARPOS (row)
16318 || PT > MATRIX_ROW_END_CHARPOS (row))
16320 /* if PT is not in the glyph row, give up. */
16321 rc = CURSOR_MOVEMENT_MUST_SCROLL;
16322 must_scroll = true;
16324 else if (rc != CURSOR_MOVEMENT_SUCCESS
16325 && !NILP (BVAR (XBUFFER (w->contents), bidi_display_reordering)))
16327 struct glyph_row *row1;
16329 /* If rows are bidi-reordered and point moved, back up
16330 until we find a row that does not belong to a
16331 continuation line. This is because we must consider
16332 all rows of a continued line as candidates for the
16333 new cursor positioning, since row start and end
16334 positions change non-linearly with vertical position
16335 in such rows. */
16336 /* FIXME: Revisit this when glyph ``spilling'' in
16337 continuation lines' rows is implemented for
16338 bidi-reordered rows. */
16339 for (row1 = MATRIX_FIRST_TEXT_ROW (w->current_matrix);
16340 MATRIX_ROW_CONTINUATION_LINE_P (row);
16341 --row)
16343 /* If we hit the beginning of the displayed portion
16344 without finding the first row of a continued
16345 line, give up. */
16346 if (row <= row1)
16348 rc = CURSOR_MOVEMENT_MUST_SCROLL;
16349 break;
16351 eassert (row->enabled_p);
16354 if (must_scroll)
16356 else if (rc != CURSOR_MOVEMENT_SUCCESS
16357 && MATRIX_ROW_PARTIALLY_VISIBLE_P (w, row)
16358 /* Make sure this isn't a header line by any chance, since
16359 then MATRIX_ROW_PARTIALLY_VISIBLE_P might yield true. */
16360 && !row->mode_line_p
16361 && make_cursor_line_fully_visible_p)
16363 if (PT == MATRIX_ROW_END_CHARPOS (row)
16364 && !row->ends_at_zv_p
16365 && !MATRIX_ROW_ENDS_IN_MIDDLE_OF_CHAR_P (row))
16366 rc = CURSOR_MOVEMENT_MUST_SCROLL;
16367 else if (row->height > window_box_height (w))
16369 /* If we end up in a partially visible line, let's
16370 make it fully visible, except when it's taller
16371 than the window, in which case we can't do much
16372 about it. */
16373 *scroll_step = true;
16374 rc = CURSOR_MOVEMENT_MUST_SCROLL;
16376 else
16378 set_cursor_from_row (w, row, w->current_matrix, 0, 0, 0, 0);
16379 if (!cursor_row_fully_visible_p (w, false, true))
16380 rc = CURSOR_MOVEMENT_MUST_SCROLL;
16381 else
16382 rc = CURSOR_MOVEMENT_SUCCESS;
16385 else if (scroll_p)
16386 rc = CURSOR_MOVEMENT_MUST_SCROLL;
16387 else if (rc != CURSOR_MOVEMENT_SUCCESS
16388 && !NILP (BVAR (XBUFFER (w->contents), bidi_display_reordering)))
16390 /* With bidi-reordered rows, there could be more than
16391 one candidate row whose start and end positions
16392 occlude point. We need to let set_cursor_from_row
16393 find the best candidate. */
16394 /* FIXME: Revisit this when glyph ``spilling'' in
16395 continuation lines' rows is implemented for
16396 bidi-reordered rows. */
16397 bool rv = false;
16401 bool at_zv_p = false, exact_match_p = false;
16403 if (MATRIX_ROW_START_CHARPOS (row) <= PT
16404 && PT <= MATRIX_ROW_END_CHARPOS (row)
16405 && cursor_row_p (row))
16406 rv |= set_cursor_from_row (w, row, w->current_matrix,
16407 0, 0, 0, 0);
16408 /* As soon as we've found the exact match for point,
16409 or the first suitable row whose ends_at_zv_p flag
16410 is set, we are done. */
16411 if (rv)
16413 at_zv_p = MATRIX_ROW (w->current_matrix,
16414 w->cursor.vpos)->ends_at_zv_p;
16415 if (!at_zv_p
16416 && w->cursor.hpos >= 0
16417 && w->cursor.hpos < MATRIX_ROW_USED (w->current_matrix,
16418 w->cursor.vpos))
16420 struct glyph_row *candidate =
16421 MATRIX_ROW (w->current_matrix, w->cursor.vpos);
16422 struct glyph *g =
16423 candidate->glyphs[TEXT_AREA] + w->cursor.hpos;
16424 ptrdiff_t endpos = MATRIX_ROW_END_CHARPOS (candidate);
16426 exact_match_p =
16427 (BUFFERP (g->object) && g->charpos == PT)
16428 || (NILP (g->object)
16429 && (g->charpos == PT
16430 || (g->charpos == 0 && endpos - 1 == PT)));
16432 if (at_zv_p || exact_match_p)
16434 rc = CURSOR_MOVEMENT_SUCCESS;
16435 break;
16438 if (MATRIX_ROW_BOTTOM_Y (row) == last_y)
16439 break;
16440 ++row;
16442 while (((MATRIX_ROW_CONTINUATION_LINE_P (row)
16443 || row->continued_p)
16444 && MATRIX_ROW_BOTTOM_Y (row) <= last_y)
16445 || (MATRIX_ROW_START_CHARPOS (row) == PT
16446 && MATRIX_ROW_BOTTOM_Y (row) < last_y));
16447 /* If we didn't find any candidate rows, or exited the
16448 loop before all the candidates were examined, signal
16449 to the caller that this method failed. */
16450 if (rc != CURSOR_MOVEMENT_SUCCESS
16451 && !(rv
16452 && !MATRIX_ROW_CONTINUATION_LINE_P (row)
16453 && !row->continued_p))
16454 rc = CURSOR_MOVEMENT_MUST_SCROLL;
16455 else if (rv)
16456 rc = CURSOR_MOVEMENT_SUCCESS;
16458 else
16462 if (set_cursor_from_row (w, row, w->current_matrix, 0, 0, 0, 0))
16464 rc = CURSOR_MOVEMENT_SUCCESS;
16465 break;
16467 ++row;
16469 while (MATRIX_ROW_BOTTOM_Y (row) < last_y
16470 && MATRIX_ROW_START_CHARPOS (row) == PT
16471 && cursor_row_p (row));
16476 return rc;
16480 void
16481 set_vertical_scroll_bar (struct window *w)
16483 ptrdiff_t start, end, whole;
16485 /* Calculate the start and end positions for the current window.
16486 At some point, it would be nice to choose between scrollbars
16487 which reflect the whole buffer size, with special markers
16488 indicating narrowing, and scrollbars which reflect only the
16489 visible region.
16491 Note that mini-buffers sometimes aren't displaying any text. */
16492 if (!MINI_WINDOW_P (w)
16493 || (w == XWINDOW (minibuf_window)
16494 && NILP (echo_area_buffer[0])))
16496 struct buffer *buf = XBUFFER (w->contents);
16497 whole = BUF_ZV (buf) - BUF_BEGV (buf);
16498 start = marker_position (w->start) - BUF_BEGV (buf);
16499 /* I don't think this is guaranteed to be right. For the
16500 moment, we'll pretend it is. */
16501 end = BUF_Z (buf) - w->window_end_pos - BUF_BEGV (buf);
16503 if (end < start)
16504 end = start;
16505 if (whole < (end - start))
16506 whole = end - start;
16508 else
16509 start = end = whole = 0;
16511 /* Indicate what this scroll bar ought to be displaying now. */
16512 if (FRAME_TERMINAL (XFRAME (w->frame))->set_vertical_scroll_bar_hook)
16513 (*FRAME_TERMINAL (XFRAME (w->frame))->set_vertical_scroll_bar_hook)
16514 (w, end - start, whole, start);
16518 void
16519 set_horizontal_scroll_bar (struct window *w)
16521 int start, end, whole, portion;
16523 if (!MINI_WINDOW_P (w)
16524 || (w == XWINDOW (minibuf_window)
16525 && NILP (echo_area_buffer[0])))
16527 struct buffer *b = XBUFFER (w->contents);
16528 struct buffer *old_buffer = NULL;
16529 struct it it;
16530 struct text_pos startp;
16532 if (b != current_buffer)
16534 old_buffer = current_buffer;
16535 set_buffer_internal (b);
16538 SET_TEXT_POS_FROM_MARKER (startp, w->start);
16539 start_display (&it, w, startp);
16540 it.last_visible_x = INT_MAX;
16541 whole = move_it_to (&it, -1, INT_MAX, window_box_height (w), -1,
16542 MOVE_TO_X | MOVE_TO_Y);
16543 /* whole = move_it_to (&it, w->window_end_pos, INT_MAX,
16544 window_box_height (w), -1,
16545 MOVE_TO_POS | MOVE_TO_X | MOVE_TO_Y); */
16547 start = w->hscroll * FRAME_COLUMN_WIDTH (WINDOW_XFRAME (w));
16548 end = start + window_box_width (w, TEXT_AREA);
16549 portion = end - start;
16550 /* After enlarging a horizontally scrolled window such that it
16551 gets at least as wide as the text it contains, make sure that
16552 the thumb doesn't fill the entire scroll bar so we can still
16553 drag it back to see the entire text. */
16554 whole = max (whole, end);
16556 if (it.bidi_p)
16558 Lisp_Object pdir;
16560 pdir = Fcurrent_bidi_paragraph_direction (Qnil);
16561 if (EQ (pdir, Qright_to_left))
16563 start = whole - end;
16564 end = start + portion;
16568 if (old_buffer)
16569 set_buffer_internal (old_buffer);
16571 else
16572 start = end = whole = portion = 0;
16574 w->hscroll_whole = whole;
16576 /* Indicate what this scroll bar ought to be displaying now. */
16577 if (FRAME_TERMINAL (XFRAME (w->frame))->set_horizontal_scroll_bar_hook)
16578 (*FRAME_TERMINAL (XFRAME (w->frame))->set_horizontal_scroll_bar_hook)
16579 (w, portion, whole, start);
16583 /* Redisplay leaf window WINDOW. JUST_THIS_ONE_P means only
16584 selected_window is redisplayed.
16586 We can return without actually redisplaying the window if fonts has been
16587 changed on window's frame. In that case, redisplay_internal will retry.
16589 As one of the important parts of redisplaying a window, we need to
16590 decide whether the previous window-start position (stored in the
16591 window's w->start marker position) is still valid, and if it isn't,
16592 recompute it. Some details about that:
16594 . The previous window-start could be in a continuation line, in
16595 which case we need to recompute it when the window width
16596 changes. See compute_window_start_on_continuation_line and its
16597 call below.
16599 . The text that changed since last redisplay could include the
16600 previous window-start position. In that case, we try to salvage
16601 what we can from the current glyph matrix by calling
16602 try_scrolling, which see.
16604 . Some Emacs command could force us to use a specific window-start
16605 position by setting the window's force_start flag, or gently
16606 propose doing that by setting the window's optional_new_start
16607 flag. In these cases, we try using the specified start point if
16608 that succeeds (i.e. the window desired matrix is successfully
16609 recomputed, and point location is within the window). In case
16610 of optional_new_start, we first check if the specified start
16611 position is feasible, i.e. if it will allow point to be
16612 displayed in the window. If using the specified start point
16613 fails, e.g., if new fonts are needed to be loaded, we abort the
16614 redisplay cycle and leave it up to the next cycle to figure out
16615 things.
16617 . Note that the window's force_start flag is sometimes set by
16618 redisplay itself, when it decides that the previous window start
16619 point is fine and should be kept. Search for "goto force_start"
16620 below to see the details. Like the values of window-start
16621 specified outside of redisplay, these internally-deduced values
16622 are tested for feasibility, and ignored if found to be
16623 unfeasible.
16625 . Note that the function try_window, used to completely redisplay
16626 a window, accepts the window's start point as its argument.
16627 This is used several times in the redisplay code to control
16628 where the window start will be, according to user options such
16629 as scroll-conservatively, and also to ensure the screen line
16630 showing point will be fully (as opposed to partially) visible on
16631 display. */
16633 static void
16634 redisplay_window (Lisp_Object window, bool just_this_one_p)
16636 struct window *w = XWINDOW (window);
16637 struct frame *f = XFRAME (w->frame);
16638 struct buffer *buffer = XBUFFER (w->contents);
16639 struct buffer *old = current_buffer;
16640 struct text_pos lpoint, opoint, startp;
16641 bool update_mode_line;
16642 int tem;
16643 struct it it;
16644 /* Record it now because it's overwritten. */
16645 bool current_matrix_up_to_date_p = false;
16646 bool used_current_matrix_p = false;
16647 /* This is less strict than current_matrix_up_to_date_p.
16648 It indicates that the buffer contents and narrowing are unchanged. */
16649 bool buffer_unchanged_p = false;
16650 bool temp_scroll_step = false;
16651 ptrdiff_t count = SPECPDL_INDEX ();
16652 int rc;
16653 int centering_position = -1;
16654 bool last_line_misfit = false;
16655 ptrdiff_t beg_unchanged, end_unchanged;
16656 int frame_line_height, margin;
16657 bool use_desired_matrix;
16658 void *itdata = NULL;
16660 SET_TEXT_POS (lpoint, PT, PT_BYTE);
16661 opoint = lpoint;
16663 #ifdef GLYPH_DEBUG
16664 *w->desired_matrix->method = 0;
16665 #endif
16667 if (!just_this_one_p
16668 && REDISPLAY_SOME_P ()
16669 && !w->redisplay
16670 && !w->update_mode_line
16671 && !f->face_change
16672 && !f->redisplay
16673 && !buffer->text->redisplay
16674 && BUF_PT (buffer) == w->last_point)
16675 return;
16677 /* Make sure that both W's markers are valid. */
16678 eassert (XMARKER (w->start)->buffer == buffer);
16679 eassert (XMARKER (w->pointm)->buffer == buffer);
16681 reconsider_clip_changes (w);
16682 frame_line_height = default_line_pixel_height (w);
16683 margin = window_scroll_margin (w, MARGIN_IN_LINES);
16686 /* Has the mode line to be updated? */
16687 update_mode_line = (w->update_mode_line
16688 || update_mode_lines
16689 || buffer->clip_changed
16690 || buffer->prevent_redisplay_optimizations_p);
16692 if (!just_this_one_p)
16693 /* If `just_this_one_p' is set, we apparently set must_be_updated_p more
16694 cleverly elsewhere. */
16695 w->must_be_updated_p = true;
16697 if (MINI_WINDOW_P (w))
16699 if (w == XWINDOW (echo_area_window)
16700 && !NILP (echo_area_buffer[0]))
16702 if (update_mode_line)
16703 /* We may have to update a tty frame's menu bar or a
16704 tool-bar. Example `M-x C-h C-h C-g'. */
16705 goto finish_menu_bars;
16706 else
16707 /* We've already displayed the echo area glyphs in this window. */
16708 goto finish_scroll_bars;
16710 else if ((w != XWINDOW (minibuf_window)
16711 || minibuf_level == 0)
16712 /* When buffer is nonempty, redisplay window normally. */
16713 && BUF_Z (XBUFFER (w->contents)) == BUF_BEG (XBUFFER (w->contents))
16714 /* Quail displays non-mini buffers in minibuffer window.
16715 In that case, redisplay the window normally. */
16716 && !NILP (Fmemq (w->contents, Vminibuffer_list)))
16718 /* W is a mini-buffer window, but it's not active, so clear
16719 it. */
16720 int yb = window_text_bottom_y (w);
16721 struct glyph_row *row;
16722 int y;
16724 for (y = 0, row = w->desired_matrix->rows;
16725 y < yb;
16726 y += row->height, ++row)
16727 blank_row (w, row, y);
16728 goto finish_scroll_bars;
16731 clear_glyph_matrix (w->desired_matrix);
16734 /* Otherwise set up data on this window; select its buffer and point
16735 value. */
16736 /* Really select the buffer, for the sake of buffer-local
16737 variables. */
16738 set_buffer_internal_1 (XBUFFER (w->contents));
16740 current_matrix_up_to_date_p
16741 = (w->window_end_valid
16742 && !current_buffer->clip_changed
16743 && !current_buffer->prevent_redisplay_optimizations_p
16744 && !window_outdated (w)
16745 && !hscrolling_current_line_p (w));
16747 beg_unchanged = BEG_UNCHANGED;
16748 end_unchanged = END_UNCHANGED;
16750 SET_TEXT_POS (opoint, PT, PT_BYTE);
16752 specbind (Qinhibit_point_motion_hooks, Qt);
16754 buffer_unchanged_p
16755 = (w->window_end_valid
16756 && !current_buffer->clip_changed
16757 && !window_outdated (w));
16759 /* When windows_or_buffers_changed is non-zero, we can't rely
16760 on the window end being valid, so set it to zero there. */
16761 if (windows_or_buffers_changed)
16763 /* If window starts on a continuation line, maybe adjust the
16764 window start in case the window's width changed. */
16765 if (XMARKER (w->start)->buffer == current_buffer)
16766 compute_window_start_on_continuation_line (w);
16768 w->window_end_valid = false;
16769 /* If so, we also can't rely on current matrix
16770 and should not fool try_cursor_movement below. */
16771 current_matrix_up_to_date_p = false;
16774 /* Some sanity checks. */
16775 CHECK_WINDOW_END (w);
16776 if (Z == Z_BYTE && CHARPOS (opoint) != BYTEPOS (opoint))
16777 emacs_abort ();
16778 if (BYTEPOS (opoint) < CHARPOS (opoint))
16779 emacs_abort ();
16781 if (mode_line_update_needed (w))
16782 update_mode_line = true;
16784 /* Point refers normally to the selected window. For any other
16785 window, set up appropriate value. */
16786 if (!EQ (window, selected_window))
16788 ptrdiff_t new_pt = marker_position (w->pointm);
16789 ptrdiff_t new_pt_byte = marker_byte_position (w->pointm);
16791 if (new_pt < BEGV)
16793 new_pt = BEGV;
16794 new_pt_byte = BEGV_BYTE;
16795 set_marker_both (w->pointm, Qnil, BEGV, BEGV_BYTE);
16797 else if (new_pt > (ZV - 1))
16799 new_pt = ZV;
16800 new_pt_byte = ZV_BYTE;
16801 set_marker_both (w->pointm, Qnil, ZV, ZV_BYTE);
16804 /* We don't use SET_PT so that the point-motion hooks don't run. */
16805 TEMP_SET_PT_BOTH (new_pt, new_pt_byte);
16808 /* If any of the character widths specified in the display table
16809 have changed, invalidate the width run cache. It's true that
16810 this may be a bit late to catch such changes, but the rest of
16811 redisplay goes (non-fatally) haywire when the display table is
16812 changed, so why should we worry about doing any better? */
16813 if (current_buffer->width_run_cache
16814 || (current_buffer->base_buffer
16815 && current_buffer->base_buffer->width_run_cache))
16817 struct Lisp_Char_Table *disptab = buffer_display_table ();
16819 if (! disptab_matches_widthtab
16820 (disptab, XVECTOR (BVAR (current_buffer, width_table))))
16822 struct buffer *buf = current_buffer;
16824 if (buf->base_buffer)
16825 buf = buf->base_buffer;
16826 invalidate_region_cache (buf, buf->width_run_cache, BEG, Z);
16827 recompute_width_table (current_buffer, disptab);
16831 /* If window-start is screwed up, choose a new one. */
16832 if (XMARKER (w->start)->buffer != current_buffer)
16833 goto recenter;
16835 SET_TEXT_POS_FROM_MARKER (startp, w->start);
16837 /* If someone specified a new starting point but did not insist,
16838 check whether it can be used. */
16839 if ((w->optional_new_start || window_frozen_p (w))
16840 && CHARPOS (startp) >= BEGV
16841 && CHARPOS (startp) <= ZV)
16843 ptrdiff_t it_charpos;
16845 w->optional_new_start = false;
16846 start_display (&it, w, startp);
16847 move_it_to (&it, PT, 0, it.last_visible_y, -1,
16848 MOVE_TO_POS | MOVE_TO_X | MOVE_TO_Y);
16849 /* Record IT's position now, since line_bottom_y might change
16850 that. */
16851 it_charpos = IT_CHARPOS (it);
16852 /* Make sure we set the force_start flag only if the cursor row
16853 will be fully visible. Otherwise, the code under force_start
16854 label below will try to move point back into view, which is
16855 not what the code which sets optional_new_start wants. */
16856 if ((it.current_y == 0 || line_bottom_y (&it) < it.last_visible_y)
16857 && !w->force_start)
16859 if (it_charpos == PT)
16860 w->force_start = true;
16861 /* IT may overshoot PT if text at PT is invisible. */
16862 else if (it_charpos > PT && CHARPOS (startp) <= PT)
16863 w->force_start = true;
16864 #ifdef GLYPH_DEBUG
16865 if (w->force_start)
16867 if (window_frozen_p (w))
16868 debug_method_add (w, "set force_start from frozen window start");
16869 else
16870 debug_method_add (w, "set force_start from optional_new_start");
16872 #endif
16876 force_start:
16878 /* Handle case where place to start displaying has been specified,
16879 unless the specified location is outside the accessible range. */
16880 if (w->force_start)
16882 /* We set this later on if we have to adjust point. */
16883 int new_vpos = -1;
16885 w->force_start = false;
16886 w->vscroll = 0;
16887 w->window_end_valid = false;
16889 /* Forget any recorded base line for line number display. */
16890 if (!buffer_unchanged_p)
16891 w->base_line_number = 0;
16893 /* Redisplay the mode line. Select the buffer properly for that.
16894 Also, run the hook window-scroll-functions
16895 because we have scrolled. */
16896 /* Note, we do this after clearing force_start because
16897 if there's an error, it is better to forget about force_start
16898 than to get into an infinite loop calling the hook functions
16899 and having them get more errors. */
16900 if (!update_mode_line
16901 || ! NILP (Vwindow_scroll_functions))
16903 update_mode_line = true;
16904 w->update_mode_line = true;
16905 startp = run_window_scroll_functions (window, startp);
16908 if (CHARPOS (startp) < BEGV)
16909 SET_TEXT_POS (startp, BEGV, BEGV_BYTE);
16910 else if (CHARPOS (startp) > ZV)
16911 SET_TEXT_POS (startp, ZV, ZV_BYTE);
16913 /* Redisplay, then check if cursor has been set during the
16914 redisplay. Give up if new fonts were loaded. */
16915 /* We used to issue a CHECK_MARGINS argument to try_window here,
16916 but this causes scrolling to fail when point begins inside
16917 the scroll margin (bug#148) -- cyd */
16918 if (!try_window (window, startp, 0))
16920 w->force_start = true;
16921 clear_glyph_matrix (w->desired_matrix);
16922 goto need_larger_matrices;
16925 if (w->cursor.vpos < 0)
16927 /* If point does not appear, try to move point so it does
16928 appear. The desired matrix has been built above, so we
16929 can use it here. First see if point is in invisible
16930 text, and if so, move it to the first visible buffer
16931 position past that. */
16932 struct glyph_row *r = NULL;
16933 Lisp_Object invprop =
16934 get_char_property_and_overlay (make_number (PT), Qinvisible,
16935 Qnil, NULL);
16937 if (TEXT_PROP_MEANS_INVISIBLE (invprop) != 0)
16939 ptrdiff_t alt_pt;
16940 Lisp_Object invprop_end =
16941 Fnext_single_char_property_change (make_number (PT), Qinvisible,
16942 Qnil, Qnil);
16944 if (NATNUMP (invprop_end))
16945 alt_pt = XFASTINT (invprop_end);
16946 else
16947 alt_pt = ZV;
16948 r = row_containing_pos (w, alt_pt, w->desired_matrix->rows,
16949 NULL, 0);
16951 if (r)
16952 new_vpos = MATRIX_ROW_BOTTOM_Y (r);
16953 else /* Give up and just move to the middle of the window. */
16954 new_vpos = window_box_height (w) / 2;
16957 if (!cursor_row_fully_visible_p (w, false, false))
16959 /* Point does appear, but on a line partly visible at end of window.
16960 Move it back to a fully-visible line. */
16961 new_vpos = window_box_height (w);
16962 /* But if window_box_height suggests a Y coordinate that is
16963 not less than we already have, that line will clearly not
16964 be fully visible, so give up and scroll the display.
16965 This can happen when the default face uses a font whose
16966 dimensions are different from the frame's default
16967 font. */
16968 if (new_vpos >= w->cursor.y)
16970 w->cursor.vpos = -1;
16971 clear_glyph_matrix (w->desired_matrix);
16972 goto try_to_scroll;
16975 else if (w->cursor.vpos >= 0)
16977 /* Some people insist on not letting point enter the scroll
16978 margin, even though this part handles windows that didn't
16979 scroll at all. */
16980 int pixel_margin = margin * frame_line_height;
16981 bool header_line = window_wants_header_line (w);
16983 /* Note: We add an extra FRAME_LINE_HEIGHT, because the loop
16984 below, which finds the row to move point to, advances by
16985 the Y coordinate of the _next_ row, see the definition of
16986 MATRIX_ROW_BOTTOM_Y. */
16987 if (w->cursor.vpos < margin + header_line)
16989 w->cursor.vpos = -1;
16990 clear_glyph_matrix (w->desired_matrix);
16991 goto try_to_scroll;
16993 else
16995 int window_height = window_box_height (w);
16997 if (header_line)
16998 window_height += CURRENT_HEADER_LINE_HEIGHT (w);
16999 if (w->cursor.y >= window_height - pixel_margin)
17001 w->cursor.vpos = -1;
17002 clear_glyph_matrix (w->desired_matrix);
17003 goto try_to_scroll;
17008 /* If we need to move point for either of the above reasons,
17009 now actually do it. */
17010 if (new_vpos >= 0)
17012 struct glyph_row *row;
17014 row = MATRIX_FIRST_TEXT_ROW (w->desired_matrix);
17015 while (MATRIX_ROW_BOTTOM_Y (row) < new_vpos)
17016 ++row;
17018 TEMP_SET_PT_BOTH (MATRIX_ROW_START_CHARPOS (row),
17019 MATRIX_ROW_START_BYTEPOS (row));
17021 if (w != XWINDOW (selected_window))
17022 set_marker_both (w->pointm, Qnil, PT, PT_BYTE);
17023 else if (current_buffer == old)
17024 SET_TEXT_POS (lpoint, PT, PT_BYTE);
17026 set_cursor_from_row (w, row, w->desired_matrix, 0, 0, 0, 0);
17028 /* Re-run pre-redisplay-function so it can update the region
17029 according to the new position of point. */
17030 /* Other than the cursor, w's redisplay is done so we can set its
17031 redisplay to false. Also the buffer's redisplay can be set to
17032 false, since propagate_buffer_redisplay should have already
17033 propagated its info to `w' anyway. */
17034 w->redisplay = false;
17035 XBUFFER (w->contents)->text->redisplay = false;
17036 safe__call1 (true, Vpre_redisplay_function, Fcons (window, Qnil));
17038 if (w->redisplay || XBUFFER (w->contents)->text->redisplay
17039 || ((EQ (Vdisplay_line_numbers, Qrelative)
17040 || EQ (Vdisplay_line_numbers, Qvisual))
17041 && row != MATRIX_FIRST_TEXT_ROW (w->desired_matrix)))
17043 /* Either pre-redisplay-function made changes (e.g. move
17044 the region), or we moved point in a window that is
17045 under display-line-numbers = relative mode. We need
17046 another round of redisplay. */
17047 clear_glyph_matrix (w->desired_matrix);
17048 if (!try_window (window, startp, 0))
17049 goto need_larger_matrices;
17052 if (w->cursor.vpos < 0 || !cursor_row_fully_visible_p (w, false, false))
17054 clear_glyph_matrix (w->desired_matrix);
17055 goto try_to_scroll;
17058 #ifdef GLYPH_DEBUG
17059 debug_method_add (w, "forced window start");
17060 #endif
17061 goto done;
17064 /* Handle case where text has not changed, only point, and it has
17065 not moved off the frame, and we are not retrying after hscroll.
17066 (current_matrix_up_to_date_p is true when retrying.) */
17067 if (current_matrix_up_to_date_p
17068 && (rc = try_cursor_movement (window, startp, &temp_scroll_step),
17069 rc != CURSOR_MOVEMENT_CANNOT_BE_USED))
17071 switch (rc)
17073 case CURSOR_MOVEMENT_SUCCESS:
17074 used_current_matrix_p = true;
17075 goto done;
17077 case CURSOR_MOVEMENT_MUST_SCROLL:
17078 goto try_to_scroll;
17080 default:
17081 emacs_abort ();
17084 /* If current starting point was originally the beginning of a line
17085 but no longer is, find a new starting point. */
17086 else if (w->start_at_line_beg
17087 && !(CHARPOS (startp) <= BEGV
17088 || FETCH_BYTE (BYTEPOS (startp) - 1) == '\n'))
17090 #ifdef GLYPH_DEBUG
17091 debug_method_add (w, "recenter 1");
17092 #endif
17093 goto recenter;
17096 /* Try scrolling with try_window_id. Value is > 0 if update has
17097 been done, it is -1 if we know that the same window start will
17098 not work. It is 0 if unsuccessful for some other reason. */
17099 else if ((tem = try_window_id (w)) != 0)
17101 #ifdef GLYPH_DEBUG
17102 debug_method_add (w, "try_window_id %d", tem);
17103 #endif
17105 if (f->fonts_changed)
17106 goto need_larger_matrices;
17107 if (tem > 0)
17108 goto done;
17110 /* Otherwise try_window_id has returned -1 which means that we
17111 don't want the alternative below this comment to execute. */
17113 else if (CHARPOS (startp) >= BEGV
17114 && CHARPOS (startp) <= ZV
17115 && PT >= CHARPOS (startp)
17116 && (CHARPOS (startp) < ZV
17117 /* Avoid starting at end of buffer. */
17118 || CHARPOS (startp) == BEGV
17119 || !window_outdated (w)))
17121 int d1, d2, d5, d6;
17122 int rtop, rbot;
17124 /* If first window line is a continuation line, and window start
17125 is inside the modified region, but the first change is before
17126 current window start, we must select a new window start.
17128 However, if this is the result of a down-mouse event (e.g. by
17129 extending the mouse-drag-overlay), we don't want to select a
17130 new window start, since that would change the position under
17131 the mouse, resulting in an unwanted mouse-movement rather
17132 than a simple mouse-click. */
17133 if (!w->start_at_line_beg
17134 && NILP (do_mouse_tracking)
17135 && CHARPOS (startp) > BEGV
17136 && CHARPOS (startp) > BEG + beg_unchanged
17137 && CHARPOS (startp) <= Z - end_unchanged
17138 /* Even if w->start_at_line_beg is nil, a new window may
17139 start at a line_beg, since that's how set_buffer_window
17140 sets it. So, we need to check the return value of
17141 compute_window_start_on_continuation_line. (See also
17142 bug#197). */
17143 && XMARKER (w->start)->buffer == current_buffer
17144 && compute_window_start_on_continuation_line (w)
17145 /* It doesn't make sense to force the window start like we
17146 do at label force_start if it is already known that point
17147 will not be fully visible in the resulting window, because
17148 doing so will move point from its correct position
17149 instead of scrolling the window to bring point into view.
17150 See bug#9324. */
17151 && pos_visible_p (w, PT, &d1, &d2, &rtop, &rbot, &d5, &d6)
17152 /* A very tall row could need more than the window height,
17153 in which case we accept that it is partially visible. */
17154 && (rtop != 0) == (rbot != 0))
17156 w->force_start = true;
17157 SET_TEXT_POS_FROM_MARKER (startp, w->start);
17158 #ifdef GLYPH_DEBUG
17159 debug_method_add (w, "recomputed window start in continuation line");
17160 #endif
17161 goto force_start;
17164 #ifdef GLYPH_DEBUG
17165 debug_method_add (w, "same window start");
17166 #endif
17168 /* Try to redisplay starting at same place as before.
17169 If point has not moved off frame, accept the results. */
17170 if (!current_matrix_up_to_date_p
17171 /* Don't use try_window_reusing_current_matrix in this case
17172 because a window scroll function can have changed the
17173 buffer. */
17174 || !NILP (Vwindow_scroll_functions)
17175 || MINI_WINDOW_P (w)
17176 || !(used_current_matrix_p
17177 = try_window_reusing_current_matrix (w)))
17179 IF_DEBUG (debug_method_add (w, "1"));
17180 clear_glyph_matrix (w->desired_matrix);
17181 if (try_window (window, startp, TRY_WINDOW_CHECK_MARGINS) < 0)
17182 /* -1 means we need to scroll.
17183 0 means we need new matrices, but fonts_changed
17184 is set in that case, so we will detect it below. */
17185 goto try_to_scroll;
17188 if (f->fonts_changed)
17189 goto need_larger_matrices;
17191 if (w->cursor.vpos >= 0)
17193 if (!just_this_one_p
17194 || current_buffer->clip_changed
17195 || BEG_UNCHANGED < CHARPOS (startp))
17196 /* Forget any recorded base line for line number display. */
17197 w->base_line_number = 0;
17199 if (!cursor_row_fully_visible_p (w, true, false))
17201 clear_glyph_matrix (w->desired_matrix);
17202 last_line_misfit = true;
17204 /* Drop through and scroll. */
17205 else
17206 goto done;
17208 else
17209 clear_glyph_matrix (w->desired_matrix);
17212 try_to_scroll:
17214 /* Redisplay the mode line. Select the buffer properly for that. */
17215 if (!update_mode_line)
17217 update_mode_line = true;
17218 w->update_mode_line = true;
17221 /* Try to scroll by specified few lines. */
17222 if ((scroll_conservatively
17223 || emacs_scroll_step
17224 || temp_scroll_step
17225 || NUMBERP (BVAR (current_buffer, scroll_up_aggressively))
17226 || NUMBERP (BVAR (current_buffer, scroll_down_aggressively)))
17227 && CHARPOS (startp) >= BEGV
17228 && CHARPOS (startp) <= ZV)
17230 /* The function returns -1 if new fonts were loaded, 1 if
17231 successful, 0 if not successful. */
17232 int ss = try_scrolling (window, just_this_one_p,
17233 scroll_conservatively,
17234 emacs_scroll_step,
17235 temp_scroll_step, last_line_misfit);
17236 switch (ss)
17238 case SCROLLING_SUCCESS:
17239 goto done;
17241 case SCROLLING_NEED_LARGER_MATRICES:
17242 goto need_larger_matrices;
17244 case SCROLLING_FAILED:
17245 break;
17247 default:
17248 emacs_abort ();
17252 /* Finally, just choose a place to start which positions point
17253 according to user preferences. */
17255 recenter:
17257 #ifdef GLYPH_DEBUG
17258 debug_method_add (w, "recenter");
17259 #endif
17261 /* Forget any previously recorded base line for line number display. */
17262 if (!buffer_unchanged_p)
17263 w->base_line_number = 0;
17265 /* Determine the window start relative to point. */
17266 init_iterator (&it, w, PT, PT_BYTE, NULL, DEFAULT_FACE_ID);
17267 it.current_y = it.last_visible_y;
17268 if (centering_position < 0)
17270 ptrdiff_t margin_pos = CHARPOS (startp);
17271 Lisp_Object aggressive;
17272 bool scrolling_up;
17274 /* If there is a scroll margin at the top of the window, find
17275 its character position. */
17276 if (margin
17277 /* Cannot call start_display if startp is not in the
17278 accessible region of the buffer. This can happen when we
17279 have just switched to a different buffer and/or changed
17280 its restriction. In that case, startp is initialized to
17281 the character position 1 (BEGV) because we did not yet
17282 have chance to display the buffer even once. */
17283 && BEGV <= CHARPOS (startp) && CHARPOS (startp) <= ZV)
17285 struct it it1;
17286 void *it1data = NULL;
17288 SAVE_IT (it1, it, it1data);
17289 start_display (&it1, w, startp);
17290 move_it_vertically (&it1, margin * frame_line_height);
17291 margin_pos = IT_CHARPOS (it1);
17292 RESTORE_IT (&it, &it, it1data);
17294 scrolling_up = PT > margin_pos;
17295 aggressive =
17296 scrolling_up
17297 ? BVAR (current_buffer, scroll_up_aggressively)
17298 : BVAR (current_buffer, scroll_down_aggressively);
17300 if (!MINI_WINDOW_P (w)
17301 && (scroll_conservatively > SCROLL_LIMIT || NUMBERP (aggressive)))
17303 int pt_offset = 0;
17305 /* Setting scroll-conservatively overrides
17306 scroll-*-aggressively. */
17307 if (!scroll_conservatively && NUMBERP (aggressive))
17309 double float_amount = XFLOATINT (aggressive);
17311 pt_offset = float_amount * WINDOW_BOX_TEXT_HEIGHT (w);
17312 if (pt_offset == 0 && float_amount > 0)
17313 pt_offset = 1;
17314 if (pt_offset && margin > 0)
17315 margin -= 1;
17317 /* Compute how much to move the window start backward from
17318 point so that point will be displayed where the user
17319 wants it. */
17320 if (scrolling_up)
17322 centering_position = it.last_visible_y;
17323 if (pt_offset)
17324 centering_position -= pt_offset;
17325 centering_position -=
17326 (frame_line_height * (1 + margin + last_line_misfit)
17327 + WINDOW_HEADER_LINE_HEIGHT (w));
17328 /* Don't let point enter the scroll margin near top of
17329 the window. */
17330 if (centering_position < margin * frame_line_height)
17331 centering_position = margin * frame_line_height;
17333 else
17334 centering_position = margin * frame_line_height + pt_offset;
17336 else
17337 /* Set the window start half the height of the window backward
17338 from point. */
17339 centering_position = window_box_height (w) / 2;
17341 move_it_vertically_backward (&it, centering_position);
17343 eassert (IT_CHARPOS (it) >= BEGV);
17345 /* The function move_it_vertically_backward may move over more
17346 than the specified y-distance. If it->w is small, e.g. a
17347 mini-buffer window, we may end up in front of the window's
17348 display area. Start displaying at the start of the line
17349 containing PT in this case. */
17350 if (it.current_y <= 0)
17352 init_iterator (&it, w, PT, PT_BYTE, NULL, DEFAULT_FACE_ID);
17353 move_it_vertically_backward (&it, 0);
17354 it.current_y = 0;
17357 it.current_x = it.hpos = 0;
17359 /* Set the window start position here explicitly, to avoid an
17360 infinite loop in case the functions in window-scroll-functions
17361 get errors. */
17362 set_marker_both (w->start, Qnil, IT_CHARPOS (it), IT_BYTEPOS (it));
17364 /* Run scroll hooks. */
17365 startp = run_window_scroll_functions (window, it.current.pos);
17367 /* We invoke try_window and try_window_reusing_current_matrix below,
17368 and they manipulate the bidi cache. Save and restore the cache
17369 state of our iterator, so we could continue using it after that. */
17370 itdata = bidi_shelve_cache ();
17372 /* Redisplay the window. */
17373 use_desired_matrix = false;
17374 if (!current_matrix_up_to_date_p
17375 || windows_or_buffers_changed
17376 || f->cursor_type_changed
17377 /* Don't use try_window_reusing_current_matrix in this case
17378 because it can have changed the buffer. */
17379 || !NILP (Vwindow_scroll_functions)
17380 || !just_this_one_p
17381 || MINI_WINDOW_P (w)
17382 || !(used_current_matrix_p
17383 = try_window_reusing_current_matrix (w)))
17384 use_desired_matrix = (try_window (window, startp, 0) == 1);
17386 bidi_unshelve_cache (itdata, false);
17388 /* If new fonts have been loaded (due to fontsets), give up. We
17389 have to start a new redisplay since we need to re-adjust glyph
17390 matrices. */
17391 if (f->fonts_changed)
17392 goto need_larger_matrices;
17394 /* If cursor did not appear assume that the middle of the window is
17395 in the first line of the window. Do it again with the next line.
17396 (Imagine a window of height 100, displaying two lines of height
17397 60. Moving back 50 from it->last_visible_y will end in the first
17398 line.) */
17399 if (w->cursor.vpos < 0)
17401 if (w->window_end_valid && PT >= Z - w->window_end_pos)
17403 clear_glyph_matrix (w->desired_matrix);
17404 move_it_by_lines (&it, 1);
17405 try_window (window, it.current.pos, 0);
17407 else if (PT < IT_CHARPOS (it))
17409 clear_glyph_matrix (w->desired_matrix);
17410 move_it_by_lines (&it, -1);
17411 try_window (window, it.current.pos, 0);
17413 else if (scroll_conservatively > SCROLL_LIMIT
17414 && (it.method == GET_FROM_STRING
17415 || overlay_touches_p (IT_CHARPOS (it)))
17416 && IT_CHARPOS (it) < ZV)
17418 /* If the window starts with a before-string that spans more
17419 than one screen line, using that position to display the
17420 window might fail to bring point into the view, because
17421 start_display will always start by displaying the string,
17422 whereas the code above determines where to set w->start
17423 by the buffer position of the place where it takes screen
17424 coordinates. Try to recover by finding the next screen
17425 line that displays buffer text. */
17426 ptrdiff_t pos0 = IT_CHARPOS (it);
17428 clear_glyph_matrix (w->desired_matrix);
17429 do {
17430 move_it_by_lines (&it, 1);
17431 } while (IT_CHARPOS (it) == pos0);
17432 try_window (window, it.current.pos, 0);
17434 else
17436 /* Not much we can do about it. */
17440 /* Consider the following case: Window starts at BEGV, there is
17441 invisible, intangible text at BEGV, so that display starts at
17442 some point START > BEGV. It can happen that we are called with
17443 PT somewhere between BEGV and START. Try to handle that case,
17444 and similar ones. */
17445 if (w->cursor.vpos < 0)
17447 /* Prefer the desired matrix to the current matrix, if possible,
17448 in the fallback calculations below. This is because using
17449 the current matrix might completely goof, e.g. if its first
17450 row is after point. */
17451 struct glyph_matrix *matrix =
17452 use_desired_matrix ? w->desired_matrix : w->current_matrix;
17453 /* First, try locating the proper glyph row for PT. */
17454 struct glyph_row *row =
17455 row_containing_pos (w, PT, matrix->rows, NULL, 0);
17457 /* Sometimes point is at the beginning of invisible text that is
17458 before the 1st character displayed in the row. In that case,
17459 row_containing_pos fails to find the row, because no glyphs
17460 with appropriate buffer positions are present in the row.
17461 Therefore, we next try to find the row which shows the 1st
17462 position after the invisible text. */
17463 if (!row)
17465 Lisp_Object val =
17466 get_char_property_and_overlay (make_number (PT), Qinvisible,
17467 Qnil, NULL);
17469 if (TEXT_PROP_MEANS_INVISIBLE (val) != 0)
17471 ptrdiff_t alt_pos;
17472 Lisp_Object invis_end =
17473 Fnext_single_char_property_change (make_number (PT), Qinvisible,
17474 Qnil, Qnil);
17476 if (NATNUMP (invis_end))
17477 alt_pos = XFASTINT (invis_end);
17478 else
17479 alt_pos = ZV;
17480 row = row_containing_pos (w, alt_pos, matrix->rows, NULL, 0);
17483 /* Finally, fall back on the first row of the window after the
17484 header line (if any). This is slightly better than not
17485 displaying the cursor at all. */
17486 if (!row)
17488 row = matrix->rows;
17489 if (row->mode_line_p)
17490 ++row;
17492 set_cursor_from_row (w, row, matrix, 0, 0, 0, 0);
17495 if (!cursor_row_fully_visible_p (w, false, false))
17497 /* If vscroll is enabled, disable it and try again. */
17498 if (w->vscroll)
17500 w->vscroll = 0;
17501 clear_glyph_matrix (w->desired_matrix);
17502 goto recenter;
17505 /* Users who set scroll-conservatively to a large number want
17506 point just above/below the scroll margin. If we ended up
17507 with point's row partially visible, move the window start to
17508 make that row fully visible and out of the margin. */
17509 if (scroll_conservatively > SCROLL_LIMIT)
17511 int window_total_lines
17512 = WINDOW_TOTAL_LINES (w) * FRAME_LINE_HEIGHT (f) / frame_line_height;
17513 bool move_down = w->cursor.vpos >= window_total_lines / 2;
17515 move_it_by_lines (&it, move_down ? margin + 1 : -(margin + 1));
17516 clear_glyph_matrix (w->desired_matrix);
17517 if (1 == try_window (window, it.current.pos,
17518 TRY_WINDOW_CHECK_MARGINS))
17519 goto done;
17522 /* If centering point failed to make the whole line visible,
17523 put point at the top instead. That has to make the whole line
17524 visible, if it can be done. */
17525 if (centering_position == 0)
17526 goto done;
17528 clear_glyph_matrix (w->desired_matrix);
17529 centering_position = 0;
17530 goto recenter;
17533 done:
17535 SET_TEXT_POS_FROM_MARKER (startp, w->start);
17536 w->start_at_line_beg = (CHARPOS (startp) == BEGV
17537 || FETCH_BYTE (BYTEPOS (startp) - 1) == '\n');
17539 /* Display the mode line, if we must. */
17540 if ((update_mode_line
17541 /* If window not full width, must redo its mode line
17542 if (a) the window to its side is being redone and
17543 (b) we do a frame-based redisplay. This is a consequence
17544 of how inverted lines are drawn in frame-based redisplay. */
17545 || (!just_this_one_p
17546 && !FRAME_WINDOW_P (f)
17547 && !WINDOW_FULL_WIDTH_P (w))
17548 /* Line number to display. */
17549 || w->base_line_pos > 0
17550 /* Column number is displayed and different from the one displayed. */
17551 || (w->column_number_displayed != -1
17552 && (w->column_number_displayed != current_column ())))
17553 /* This means that the window has a mode line. */
17554 && (window_wants_mode_line (w)
17555 || window_wants_header_line (w)))
17558 display_mode_lines (w);
17560 /* If mode line height has changed, arrange for a thorough
17561 immediate redisplay using the correct mode line height. */
17562 if (window_wants_mode_line (w)
17563 && CURRENT_MODE_LINE_HEIGHT (w) != DESIRED_MODE_LINE_HEIGHT (w))
17565 f->fonts_changed = true;
17566 w->mode_line_height = -1;
17567 MATRIX_MODE_LINE_ROW (w->current_matrix)->height
17568 = DESIRED_MODE_LINE_HEIGHT (w);
17571 /* If header line height has changed, arrange for a thorough
17572 immediate redisplay using the correct header line height. */
17573 if (window_wants_header_line (w)
17574 && CURRENT_HEADER_LINE_HEIGHT (w) != DESIRED_HEADER_LINE_HEIGHT (w))
17576 f->fonts_changed = true;
17577 w->header_line_height = -1;
17578 MATRIX_HEADER_LINE_ROW (w->current_matrix)->height
17579 = DESIRED_HEADER_LINE_HEIGHT (w);
17582 if (f->fonts_changed)
17583 goto need_larger_matrices;
17586 if (!line_number_displayed && w->base_line_pos != -1)
17588 w->base_line_pos = 0;
17589 w->base_line_number = 0;
17592 finish_menu_bars:
17594 /* When we reach a frame's selected window, redo the frame's menu
17595 bar and the frame's title. */
17596 if (update_mode_line
17597 && EQ (FRAME_SELECTED_WINDOW (f), window))
17599 bool redisplay_menu_p;
17601 if (FRAME_WINDOW_P (f))
17603 #if defined (USE_X_TOOLKIT) || defined (HAVE_NTGUI) \
17604 || defined (HAVE_NS) || defined (USE_GTK)
17605 redisplay_menu_p = FRAME_EXTERNAL_MENU_BAR (f);
17606 #else
17607 redisplay_menu_p = FRAME_MENU_BAR_LINES (f) > 0;
17608 #endif
17610 else
17611 redisplay_menu_p = FRAME_MENU_BAR_LINES (f) > 0;
17613 if (redisplay_menu_p)
17614 display_menu_bar (w);
17616 #ifdef HAVE_WINDOW_SYSTEM
17617 if (FRAME_WINDOW_P (f))
17619 #if defined (USE_GTK) || defined (HAVE_NS)
17620 if (FRAME_EXTERNAL_TOOL_BAR (f))
17621 redisplay_tool_bar (f);
17622 #else
17623 if (WINDOWP (f->tool_bar_window)
17624 && (FRAME_TOOL_BAR_LINES (f) > 0
17625 || !NILP (Vauto_resize_tool_bars))
17626 && redisplay_tool_bar (f))
17627 ignore_mouse_drag_p = true;
17628 #endif
17630 x_consider_frame_title (w->frame);
17631 #endif
17634 #ifdef HAVE_WINDOW_SYSTEM
17635 if (FRAME_WINDOW_P (f)
17636 && update_window_fringes (w, (just_this_one_p
17637 || (!used_current_matrix_p && !overlay_arrow_seen)
17638 || w->pseudo_window_p)))
17640 update_begin (f);
17641 block_input ();
17642 if (draw_window_fringes (w, true))
17644 if (WINDOW_RIGHT_DIVIDER_WIDTH (w))
17645 x_draw_right_divider (w);
17646 else
17647 x_draw_vertical_border (w);
17649 unblock_input ();
17650 update_end (f);
17653 if (WINDOW_BOTTOM_DIVIDER_WIDTH (w))
17654 x_draw_bottom_divider (w);
17655 #endif /* HAVE_WINDOW_SYSTEM */
17657 /* We go to this label, with fonts_changed set, if it is
17658 necessary to try again using larger glyph matrices.
17659 We have to redeem the scroll bar even in this case,
17660 because the loop in redisplay_internal expects that. */
17661 need_larger_matrices:
17663 finish_scroll_bars:
17665 if (WINDOW_HAS_VERTICAL_SCROLL_BAR (w) || WINDOW_HAS_HORIZONTAL_SCROLL_BAR (w))
17667 if (WINDOW_HAS_VERTICAL_SCROLL_BAR (w))
17668 /* Set the thumb's position and size. */
17669 set_vertical_scroll_bar (w);
17671 if (WINDOW_HAS_HORIZONTAL_SCROLL_BAR (w))
17672 /* Set the thumb's position and size. */
17673 set_horizontal_scroll_bar (w);
17675 /* Note that we actually used the scroll bar attached to this
17676 window, so it shouldn't be deleted at the end of redisplay. */
17677 if (FRAME_TERMINAL (f)->redeem_scroll_bar_hook)
17678 (*FRAME_TERMINAL (f)->redeem_scroll_bar_hook) (w);
17681 /* Restore current_buffer and value of point in it. The window
17682 update may have changed the buffer, so first make sure `opoint'
17683 is still valid (Bug#6177). */
17684 if (CHARPOS (opoint) < BEGV)
17685 TEMP_SET_PT_BOTH (BEGV, BEGV_BYTE);
17686 else if (CHARPOS (opoint) > ZV)
17687 TEMP_SET_PT_BOTH (Z, Z_BYTE);
17688 else
17689 TEMP_SET_PT_BOTH (CHARPOS (opoint), BYTEPOS (opoint));
17691 set_buffer_internal_1 (old);
17692 /* Avoid an abort in TEMP_SET_PT_BOTH if the buffer has become
17693 shorter. This can be caused by log truncation in *Messages*. */
17694 if (CHARPOS (lpoint) <= ZV)
17695 TEMP_SET_PT_BOTH (CHARPOS (lpoint), BYTEPOS (lpoint));
17697 unbind_to (count, Qnil);
17701 /* Build the complete desired matrix of WINDOW with a window start
17702 buffer position POS.
17704 Value is 1 if successful. It is zero if fonts were loaded during
17705 redisplay which makes re-adjusting glyph matrices necessary, and -1
17706 if point would appear in the scroll margins.
17707 (We check the former only if TRY_WINDOW_IGNORE_FONTS_CHANGE is
17708 unset in FLAGS, and the latter only if TRY_WINDOW_CHECK_MARGINS is
17709 set in FLAGS.) */
17712 try_window (Lisp_Object window, struct text_pos pos, int flags)
17714 struct window *w = XWINDOW (window);
17715 struct it it;
17716 struct glyph_row *last_text_row = NULL;
17717 struct frame *f = XFRAME (w->frame);
17718 int cursor_vpos = w->cursor.vpos;
17720 /* Make POS the new window start. */
17721 set_marker_both (w->start, Qnil, CHARPOS (pos), BYTEPOS (pos));
17723 /* Mark cursor position as unknown. No overlay arrow seen. */
17724 w->cursor.vpos = -1;
17725 overlay_arrow_seen = false;
17727 /* Initialize iterator and info to start at POS. */
17728 start_display (&it, w, pos);
17729 it.glyph_row->reversed_p = false;
17731 /* Display all lines of W. */
17732 while (it.current_y < it.last_visible_y)
17734 if (display_line (&it, cursor_vpos))
17735 last_text_row = it.glyph_row - 1;
17736 if (f->fonts_changed && !(flags & TRY_WINDOW_IGNORE_FONTS_CHANGE))
17737 return 0;
17740 /* Save the character position of 'it' before we call
17741 'start_display' again. */
17742 ptrdiff_t it_charpos = IT_CHARPOS (it);
17744 /* Don't let the cursor end in the scroll margins. */
17745 if ((flags & TRY_WINDOW_CHECK_MARGINS)
17746 && !MINI_WINDOW_P (w))
17748 int this_scroll_margin = window_scroll_margin (w, MARGIN_IN_PIXELS);
17749 start_display (&it, w, pos);
17751 if ((w->cursor.y >= 0 /* not vscrolled */
17752 && w->cursor.y < this_scroll_margin
17753 && CHARPOS (pos) > BEGV
17754 && it_charpos < ZV)
17755 /* rms: considering make_cursor_line_fully_visible_p here
17756 seems to give wrong results. We don't want to recenter
17757 when the last line is partly visible, we want to allow
17758 that case to be handled in the usual way. */
17759 || w->cursor.y > (it.last_visible_y - partial_line_height (&it)
17760 - this_scroll_margin - 1))
17762 w->cursor.vpos = -1;
17763 clear_glyph_matrix (w->desired_matrix);
17764 return -1;
17768 /* If bottom moved off end of frame, change mode line percentage. */
17769 if (w->window_end_pos <= 0 && Z != it_charpos)
17770 w->update_mode_line = true;
17772 /* Set window_end_pos to the offset of the last character displayed
17773 on the window from the end of current_buffer. Set
17774 window_end_vpos to its row number. */
17775 if (last_text_row)
17777 eassert (MATRIX_ROW_DISPLAYS_TEXT_P (last_text_row));
17778 adjust_window_ends (w, last_text_row, false);
17779 eassert
17780 (MATRIX_ROW_DISPLAYS_TEXT_P (MATRIX_ROW (w->desired_matrix,
17781 w->window_end_vpos)));
17783 else
17785 w->window_end_bytepos = Z_BYTE - ZV_BYTE;
17786 w->window_end_pos = Z - ZV;
17787 w->window_end_vpos = 0;
17790 /* But that is not valid info until redisplay finishes. */
17791 w->window_end_valid = false;
17792 return 1;
17797 /************************************************************************
17798 Window redisplay reusing current matrix when buffer has not changed
17799 ************************************************************************/
17801 /* Try redisplay of window W showing an unchanged buffer with a
17802 different window start than the last time it was displayed by
17803 reusing its current matrix. Value is true if successful.
17804 W->start is the new window start. */
17806 static bool
17807 try_window_reusing_current_matrix (struct window *w)
17809 struct frame *f = XFRAME (w->frame);
17810 struct glyph_row *bottom_row;
17811 struct it it;
17812 struct run run;
17813 struct text_pos start, new_start;
17814 int nrows_scrolled, i;
17815 struct glyph_row *last_text_row;
17816 struct glyph_row *last_reused_text_row;
17817 struct glyph_row *start_row;
17818 int start_vpos, min_y, max_y;
17820 #ifdef GLYPH_DEBUG
17821 if (inhibit_try_window_reusing)
17822 return false;
17823 #endif
17825 if (/* This function doesn't handle terminal frames. */
17826 !FRAME_WINDOW_P (f)
17827 /* Don't try to reuse the display if windows have been split
17828 or such. */
17829 || windows_or_buffers_changed
17830 || f->cursor_type_changed
17831 /* This function cannot handle buffers where the overlay arrow
17832 is shown on the fringes, because if the arrow position
17833 changes, we cannot just reuse the current matrix. */
17834 || overlay_arrow_in_current_buffer_p ())
17835 return false;
17837 /* Can't do this if showing trailing whitespace. */
17838 if (!NILP (Vshow_trailing_whitespace))
17839 return false;
17841 /* If top-line visibility has changed, give up. */
17842 if (window_wants_header_line (w)
17843 != MATRIX_HEADER_LINE_ROW (w->current_matrix)->mode_line_p)
17844 return false;
17846 /* Give up if old or new display is scrolled vertically. We could
17847 make this function handle this, but right now it doesn't. */
17848 start_row = MATRIX_FIRST_TEXT_ROW (w->current_matrix);
17849 if (w->vscroll || MATRIX_ROW_PARTIALLY_VISIBLE_P (w, start_row))
17850 return false;
17852 /* Clear the desired matrix for the display below. */
17853 clear_glyph_matrix (w->desired_matrix);
17855 /* Give up if line numbers are being displayed, because reusing the
17856 current matrix might use the wrong width for line-number
17857 display. */
17858 if (!NILP (Vdisplay_line_numbers))
17859 return false;
17861 /* The variable new_start now holds the new window start. The old
17862 start `start' can be determined from the current matrix. */
17863 SET_TEXT_POS_FROM_MARKER (new_start, w->start);
17864 start = start_row->minpos;
17865 start_vpos = MATRIX_ROW_VPOS (start_row, w->current_matrix);
17867 if (CHARPOS (new_start) <= CHARPOS (start))
17869 /* Don't use this method if the display starts with an ellipsis
17870 displayed for invisible text. It's not easy to handle that case
17871 below, and it's certainly not worth the effort since this is
17872 not a frequent case. */
17873 if (in_ellipses_for_invisible_text_p (&start_row->start, w))
17874 return false;
17876 IF_DEBUG (debug_method_add (w, "twu1"));
17878 /* Display up to a row that can be reused. The variable
17879 last_text_row is set to the last row displayed that displays
17880 text. Note that it.vpos == 0 if or if not there is a
17881 header-line; it's not the same as the MATRIX_ROW_VPOS! */
17882 start_display (&it, w, new_start);
17883 w->cursor.vpos = -1;
17884 last_text_row = last_reused_text_row = NULL;
17886 while (it.current_y < it.last_visible_y && !f->fonts_changed)
17888 /* If we have reached into the characters in the START row,
17889 that means the line boundaries have changed. So we
17890 can't start copying with the row START. Maybe it will
17891 work to start copying with the following row. */
17892 while (IT_CHARPOS (it) > CHARPOS (start))
17894 /* Advance to the next row as the "start". */
17895 start_row++;
17896 start = start_row->minpos;
17897 /* If there are no more rows to try, or just one, give up. */
17898 if (start_row == MATRIX_MODE_LINE_ROW (w->current_matrix) - 1
17899 || w->vscroll || MATRIX_ROW_PARTIALLY_VISIBLE_P (w, start_row)
17900 || CHARPOS (start) == ZV)
17902 clear_glyph_matrix (w->desired_matrix);
17903 return false;
17906 start_vpos = MATRIX_ROW_VPOS (start_row, w->current_matrix);
17908 /* If we have reached alignment, we can copy the rest of the
17909 rows. */
17910 if (IT_CHARPOS (it) == CHARPOS (start)
17911 /* Don't accept "alignment" inside a display vector,
17912 since start_row could have started in the middle of
17913 that same display vector (thus their character
17914 positions match), and we have no way of telling if
17915 that is the case. */
17916 && it.current.dpvec_index < 0)
17917 break;
17919 it.glyph_row->reversed_p = false;
17920 if (display_line (&it, -1))
17921 last_text_row = it.glyph_row - 1;
17925 /* A value of current_y < last_visible_y means that we stopped
17926 at the previous window start, which in turn means that we
17927 have at least one reusable row. */
17928 if (it.current_y < it.last_visible_y)
17930 struct glyph_row *row;
17932 /* IT.vpos always starts from 0; it counts text lines. */
17933 nrows_scrolled = it.vpos - (start_row - MATRIX_FIRST_TEXT_ROW (w->current_matrix));
17935 /* Find PT if not already found in the lines displayed. */
17936 if (w->cursor.vpos < 0)
17938 int dy = it.current_y - start_row->y;
17940 row = MATRIX_FIRST_TEXT_ROW (w->current_matrix);
17941 row = row_containing_pos (w, PT, row, NULL, dy);
17942 if (row)
17943 set_cursor_from_row (w, row, w->current_matrix, 0, 0,
17944 dy, nrows_scrolled);
17945 else
17947 clear_glyph_matrix (w->desired_matrix);
17948 return false;
17952 /* Scroll the display. Do it before the current matrix is
17953 changed. The problem here is that update has not yet
17954 run, i.e. part of the current matrix is not up to date.
17955 scroll_run_hook will clear the cursor, and use the
17956 current matrix to get the height of the row the cursor is
17957 in. */
17958 run.current_y = start_row->y;
17959 run.desired_y = it.current_y;
17960 run.height = it.last_visible_y - it.current_y;
17962 if (run.height > 0 && run.current_y != run.desired_y)
17964 update_begin (f);
17965 FRAME_RIF (f)->update_window_begin_hook (w);
17966 FRAME_RIF (f)->clear_window_mouse_face (w);
17967 FRAME_RIF (f)->scroll_run_hook (w, &run);
17968 FRAME_RIF (f)->update_window_end_hook (w, false, false);
17969 update_end (f);
17972 /* Shift current matrix down by nrows_scrolled lines. */
17973 bottom_row = MATRIX_BOTTOM_TEXT_ROW (w->current_matrix, w);
17974 rotate_matrix (w->current_matrix,
17975 start_vpos,
17976 MATRIX_ROW_VPOS (bottom_row, w->current_matrix),
17977 nrows_scrolled);
17979 /* Disable lines that must be updated. */
17980 for (i = 0; i < nrows_scrolled; ++i)
17981 (start_row + i)->enabled_p = false;
17983 /* Re-compute Y positions. */
17984 min_y = WINDOW_HEADER_LINE_HEIGHT (w);
17985 max_y = it.last_visible_y;
17986 for (row = start_row + nrows_scrolled;
17987 row < bottom_row;
17988 ++row)
17990 row->y = it.current_y;
17991 row->visible_height = row->height;
17993 if (row->y < min_y)
17994 row->visible_height -= min_y - row->y;
17995 if (row->y + row->height > max_y)
17996 row->visible_height -= row->y + row->height - max_y;
17997 if (row->fringe_bitmap_periodic_p)
17998 row->redraw_fringe_bitmaps_p = true;
18000 it.current_y += row->height;
18002 if (MATRIX_ROW_DISPLAYS_TEXT_P (row))
18003 last_reused_text_row = row;
18004 if (MATRIX_ROW_BOTTOM_Y (row) >= it.last_visible_y)
18005 break;
18008 /* Disable lines in the current matrix which are now
18009 below the window. */
18010 for (++row; row < bottom_row; ++row)
18011 row->enabled_p = row->mode_line_p = false;
18014 /* Update window_end_pos etc.; last_reused_text_row is the last
18015 reused row from the current matrix containing text, if any.
18016 The value of last_text_row is the last displayed line
18017 containing text. */
18018 if (last_reused_text_row)
18019 adjust_window_ends (w, last_reused_text_row, true);
18020 else if (last_text_row)
18021 adjust_window_ends (w, last_text_row, false);
18022 else
18024 /* This window must be completely empty. */
18025 w->window_end_bytepos = Z_BYTE - ZV_BYTE;
18026 w->window_end_pos = Z - ZV;
18027 w->window_end_vpos = 0;
18029 w->window_end_valid = false;
18031 /* Update hint: don't try scrolling again in update_window. */
18032 w->desired_matrix->no_scrolling_p = true;
18034 #ifdef GLYPH_DEBUG
18035 debug_method_add (w, "try_window_reusing_current_matrix 1");
18036 #endif
18037 return true;
18039 else if (CHARPOS (new_start) > CHARPOS (start))
18041 struct glyph_row *pt_row, *row;
18042 struct glyph_row *first_reusable_row;
18043 struct glyph_row *first_row_to_display;
18044 int dy;
18045 int yb = window_text_bottom_y (w);
18047 /* Find the row starting at new_start, if there is one. Don't
18048 reuse a partially visible line at the end. */
18049 first_reusable_row = start_row;
18050 while (first_reusable_row->enabled_p
18051 && MATRIX_ROW_BOTTOM_Y (first_reusable_row) < yb
18052 && (MATRIX_ROW_START_CHARPOS (first_reusable_row)
18053 < CHARPOS (new_start)))
18054 ++first_reusable_row;
18056 /* Give up if there is no row to reuse. */
18057 if (MATRIX_ROW_BOTTOM_Y (first_reusable_row) >= yb
18058 || !first_reusable_row->enabled_p
18059 || (MATRIX_ROW_START_CHARPOS (first_reusable_row)
18060 != CHARPOS (new_start)))
18061 return false;
18063 /* We can reuse fully visible rows beginning with
18064 first_reusable_row to the end of the window. Set
18065 first_row_to_display to the first row that cannot be reused.
18066 Set pt_row to the row containing point, if there is any. */
18067 pt_row = NULL;
18068 for (first_row_to_display = first_reusable_row;
18069 MATRIX_ROW_BOTTOM_Y (first_row_to_display) < yb;
18070 ++first_row_to_display)
18072 if (PT >= MATRIX_ROW_START_CHARPOS (first_row_to_display)
18073 && (PT < MATRIX_ROW_END_CHARPOS (first_row_to_display)
18074 || (PT == MATRIX_ROW_END_CHARPOS (first_row_to_display)
18075 && first_row_to_display->ends_at_zv_p
18076 && pt_row == NULL)))
18077 pt_row = first_row_to_display;
18080 /* Start displaying at the start of first_row_to_display. */
18081 eassert (first_row_to_display->y < yb);
18082 init_to_row_start (&it, w, first_row_to_display);
18084 nrows_scrolled = (MATRIX_ROW_VPOS (first_reusable_row, w->current_matrix)
18085 - start_vpos);
18086 it.vpos = (MATRIX_ROW_VPOS (first_row_to_display, w->current_matrix)
18087 - nrows_scrolled);
18088 it.current_y = (first_row_to_display->y - first_reusable_row->y
18089 + WINDOW_HEADER_LINE_HEIGHT (w));
18091 /* Display lines beginning with first_row_to_display in the
18092 desired matrix. Set last_text_row to the last row displayed
18093 that displays text. */
18094 it.glyph_row = MATRIX_ROW (w->desired_matrix, it.vpos);
18095 if (pt_row == NULL)
18096 w->cursor.vpos = -1;
18097 last_text_row = NULL;
18098 while (it.current_y < it.last_visible_y && !f->fonts_changed)
18099 if (display_line (&it, w->cursor.vpos))
18100 last_text_row = it.glyph_row - 1;
18102 /* If point is in a reused row, adjust y and vpos of the cursor
18103 position. */
18104 if (pt_row)
18106 w->cursor.vpos -= nrows_scrolled;
18107 w->cursor.y -= first_reusable_row->y - start_row->y;
18110 /* Give up if point isn't in a row displayed or reused. (This
18111 also handles the case where w->cursor.vpos < nrows_scrolled
18112 after the calls to display_line, which can happen with scroll
18113 margins. See bug#1295.) */
18114 if (w->cursor.vpos < 0)
18116 clear_glyph_matrix (w->desired_matrix);
18117 return false;
18120 /* Scroll the display. */
18121 run.current_y = first_reusable_row->y;
18122 run.desired_y = WINDOW_HEADER_LINE_HEIGHT (w);
18123 run.height = it.last_visible_y - run.current_y;
18124 dy = run.current_y - run.desired_y;
18126 if (run.height)
18128 update_begin (f);
18129 FRAME_RIF (f)->update_window_begin_hook (w);
18130 FRAME_RIF (f)->clear_window_mouse_face (w);
18131 FRAME_RIF (f)->scroll_run_hook (w, &run);
18132 FRAME_RIF (f)->update_window_end_hook (w, false, false);
18133 update_end (f);
18136 /* Adjust Y positions of reused rows. */
18137 bottom_row = MATRIX_BOTTOM_TEXT_ROW (w->current_matrix, w);
18138 min_y = WINDOW_HEADER_LINE_HEIGHT (w);
18139 max_y = it.last_visible_y;
18140 for (row = first_reusable_row; row < first_row_to_display; ++row)
18142 row->y -= dy;
18143 row->visible_height = row->height;
18144 if (row->y < min_y)
18145 row->visible_height -= min_y - row->y;
18146 if (row->y + row->height > max_y)
18147 row->visible_height -= row->y + row->height - max_y;
18148 if (row->fringe_bitmap_periodic_p)
18149 row->redraw_fringe_bitmaps_p = true;
18152 /* Scroll the current matrix. */
18153 eassert (nrows_scrolled > 0);
18154 rotate_matrix (w->current_matrix,
18155 start_vpos,
18156 MATRIX_ROW_VPOS (bottom_row, w->current_matrix),
18157 -nrows_scrolled);
18159 /* Disable rows not reused. */
18160 for (row -= nrows_scrolled; row < bottom_row; ++row)
18161 row->enabled_p = false;
18163 /* Point may have moved to a different line, so we cannot assume that
18164 the previous cursor position is valid; locate the correct row. */
18165 if (pt_row)
18167 for (row = MATRIX_ROW (w->current_matrix, w->cursor.vpos);
18168 row < bottom_row
18169 && PT >= MATRIX_ROW_END_CHARPOS (row)
18170 && !row->ends_at_zv_p;
18171 row++)
18173 w->cursor.vpos++;
18174 w->cursor.y = row->y;
18176 if (row < bottom_row)
18178 /* Can't simply scan the row for point with
18179 bidi-reordered glyph rows. Let set_cursor_from_row
18180 figure out where to put the cursor, and if it fails,
18181 give up. */
18182 if (!NILP (BVAR (XBUFFER (w->contents), bidi_display_reordering)))
18184 if (!set_cursor_from_row (w, row, w->current_matrix,
18185 0, 0, 0, 0))
18187 clear_glyph_matrix (w->desired_matrix);
18188 return false;
18191 else
18193 struct glyph *glyph = row->glyphs[TEXT_AREA] + w->cursor.hpos;
18194 struct glyph *end = row->glyphs[TEXT_AREA] + row->used[TEXT_AREA];
18196 for (; glyph < end
18197 && (!BUFFERP (glyph->object)
18198 || glyph->charpos < PT);
18199 glyph++)
18201 w->cursor.hpos++;
18202 w->cursor.x += glyph->pixel_width;
18208 /* Adjust window end. A null value of last_text_row means that
18209 the window end is in reused rows which in turn means that
18210 only its vpos can have changed. */
18211 if (last_text_row)
18212 adjust_window_ends (w, last_text_row, false);
18213 else
18214 w->window_end_vpos -= nrows_scrolled;
18216 w->window_end_valid = false;
18217 w->desired_matrix->no_scrolling_p = true;
18219 #ifdef GLYPH_DEBUG
18220 debug_method_add (w, "try_window_reusing_current_matrix 2");
18221 #endif
18222 return true;
18225 return false;
18230 /************************************************************************
18231 Window redisplay reusing current matrix when buffer has changed
18232 ************************************************************************/
18234 static struct glyph_row *find_last_unchanged_at_beg_row (struct window *);
18235 static struct glyph_row *find_first_unchanged_at_end_row (struct window *,
18236 ptrdiff_t *, ptrdiff_t *);
18237 static struct glyph_row *
18238 find_last_row_displaying_text (struct glyph_matrix *, struct it *,
18239 struct glyph_row *);
18242 /* Return the last row in MATRIX displaying text. If row START is
18243 non-null, start searching with that row. IT gives the dimensions
18244 of the display. Value is null if matrix is empty; otherwise it is
18245 a pointer to the row found. */
18247 static struct glyph_row *
18248 find_last_row_displaying_text (struct glyph_matrix *matrix, struct it *it,
18249 struct glyph_row *start)
18251 struct glyph_row *row, *row_found;
18253 /* Set row_found to the last row in IT->w's current matrix
18254 displaying text. The loop looks funny but think of partially
18255 visible lines. */
18256 row_found = NULL;
18257 row = start ? start : MATRIX_FIRST_TEXT_ROW (matrix);
18258 while (MATRIX_ROW_DISPLAYS_TEXT_P (row))
18260 eassert (row->enabled_p);
18261 row_found = row;
18262 if (MATRIX_ROW_BOTTOM_Y (row) >= it->last_visible_y)
18263 break;
18264 ++row;
18267 return row_found;
18271 /* Return the last row in the current matrix of W that is not affected
18272 by changes at the start of current_buffer that occurred since W's
18273 current matrix was built. Value is null if no such row exists.
18275 BEG_UNCHANGED us the number of characters unchanged at the start of
18276 current_buffer. BEG + BEG_UNCHANGED is the buffer position of the
18277 first changed character in current_buffer. Characters at positions <
18278 BEG + BEG_UNCHANGED are at the same buffer positions as they were
18279 when the current matrix was built. */
18281 static struct glyph_row *
18282 find_last_unchanged_at_beg_row (struct window *w)
18284 ptrdiff_t first_changed_pos = BEG + BEG_UNCHANGED;
18285 struct glyph_row *row;
18286 struct glyph_row *row_found = NULL;
18287 int yb = window_text_bottom_y (w);
18289 /* Find the last row displaying unchanged text. */
18290 for (row = MATRIX_FIRST_TEXT_ROW (w->current_matrix);
18291 MATRIX_ROW_DISPLAYS_TEXT_P (row)
18292 && MATRIX_ROW_START_CHARPOS (row) < first_changed_pos;
18293 ++row)
18295 if (/* If row ends before first_changed_pos, it is unchanged,
18296 except in some case. */
18297 MATRIX_ROW_END_CHARPOS (row) <= first_changed_pos
18298 /* When row ends in ZV and we write at ZV it is not
18299 unchanged. */
18300 && !row->ends_at_zv_p
18301 /* When first_changed_pos is the end of a continued line,
18302 row is not unchanged because it may be no longer
18303 continued. */
18304 && !(MATRIX_ROW_END_CHARPOS (row) == first_changed_pos
18305 && (row->continued_p
18306 || row->exact_window_width_line_p))
18307 /* If ROW->end is beyond ZV, then ROW->end is outdated and
18308 needs to be recomputed, so don't consider this row as
18309 unchanged. This happens when the last line was
18310 bidi-reordered and was killed immediately before this
18311 redisplay cycle. In that case, ROW->end stores the
18312 buffer position of the first visual-order character of
18313 the killed text, which is now beyond ZV. */
18314 && CHARPOS (row->end.pos) <= ZV)
18315 row_found = row;
18317 /* Stop if last visible row. */
18318 if (MATRIX_ROW_BOTTOM_Y (row) >= yb)
18319 break;
18322 return row_found;
18326 /* Find the first glyph row in the current matrix of W that is not
18327 affected by changes at the end of current_buffer since the
18328 time W's current matrix was built.
18330 Return in *DELTA the number of chars by which buffer positions in
18331 unchanged text at the end of current_buffer must be adjusted.
18333 Return in *DELTA_BYTES the corresponding number of bytes.
18335 Value is null if no such row exists, i.e. all rows are affected by
18336 changes. */
18338 static struct glyph_row *
18339 find_first_unchanged_at_end_row (struct window *w,
18340 ptrdiff_t *delta, ptrdiff_t *delta_bytes)
18342 struct glyph_row *row;
18343 struct glyph_row *row_found = NULL;
18345 *delta = *delta_bytes = 0;
18347 /* Display must not have been paused, otherwise the current matrix
18348 is not up to date. */
18349 eassert (w->window_end_valid);
18351 /* A value of window_end_pos >= END_UNCHANGED means that the window
18352 end is in the range of changed text. If so, there is no
18353 unchanged row at the end of W's current matrix. */
18354 if (w->window_end_pos >= END_UNCHANGED)
18355 return NULL;
18357 /* Set row to the last row in W's current matrix displaying text. */
18358 row = MATRIX_ROW (w->current_matrix, w->window_end_vpos);
18360 /* If matrix is entirely empty, no unchanged row exists. */
18361 if (MATRIX_ROW_DISPLAYS_TEXT_P (row))
18363 /* The value of row is the last glyph row in the matrix having a
18364 meaningful buffer position in it. The end position of row
18365 corresponds to window_end_pos. This allows us to translate
18366 buffer positions in the current matrix to current buffer
18367 positions for characters not in changed text. */
18368 ptrdiff_t Z_old =
18369 MATRIX_ROW_END_CHARPOS (row) + w->window_end_pos;
18370 ptrdiff_t Z_BYTE_old =
18371 MATRIX_ROW_END_BYTEPOS (row) + w->window_end_bytepos;
18372 ptrdiff_t last_unchanged_pos, last_unchanged_pos_old;
18373 struct glyph_row *first_text_row
18374 = MATRIX_FIRST_TEXT_ROW (w->current_matrix);
18376 *delta = Z - Z_old;
18377 *delta_bytes = Z_BYTE - Z_BYTE_old;
18379 /* Set last_unchanged_pos to the buffer position of the last
18380 character in the buffer that has not been changed. Z is the
18381 index + 1 of the last character in current_buffer, i.e. by
18382 subtracting END_UNCHANGED we get the index of the last
18383 unchanged character, and we have to add BEG to get its buffer
18384 position. */
18385 last_unchanged_pos = Z - END_UNCHANGED + BEG;
18386 last_unchanged_pos_old = last_unchanged_pos - *delta;
18388 /* Search backward from ROW for a row displaying a line that
18389 starts at a minimum position >= last_unchanged_pos_old. */
18390 for (; row > first_text_row; --row)
18392 /* This used to abort, but it can happen.
18393 It is ok to just stop the search instead here. KFS. */
18394 if (!row->enabled_p || !MATRIX_ROW_DISPLAYS_TEXT_P (row))
18395 break;
18397 if (MATRIX_ROW_START_CHARPOS (row) >= last_unchanged_pos_old)
18398 row_found = row;
18402 eassert (!row_found || MATRIX_ROW_DISPLAYS_TEXT_P (row_found));
18404 return row_found;
18408 /* Make sure that glyph rows in the current matrix of window W
18409 reference the same glyph memory as corresponding rows in the
18410 frame's frame matrix. This function is called after scrolling W's
18411 current matrix on a terminal frame in try_window_id and
18412 try_window_reusing_current_matrix. */
18414 static void
18415 sync_frame_with_window_matrix_rows (struct window *w)
18417 struct frame *f = XFRAME (w->frame);
18418 struct glyph_row *window_row, *window_row_end, *frame_row;
18420 /* Preconditions: W must be a leaf window and full-width. Its frame
18421 must have a frame matrix. */
18422 eassert (BUFFERP (w->contents));
18423 eassert (WINDOW_FULL_WIDTH_P (w));
18424 eassert (!FRAME_WINDOW_P (f));
18426 /* If W is a full-width window, glyph pointers in W's current matrix
18427 have, by definition, to be the same as glyph pointers in the
18428 corresponding frame matrix. Note that frame matrices have no
18429 marginal areas (see build_frame_matrix). */
18430 window_row = w->current_matrix->rows;
18431 window_row_end = window_row + w->current_matrix->nrows;
18432 frame_row = f->current_matrix->rows + WINDOW_TOP_EDGE_LINE (w);
18433 while (window_row < window_row_end)
18435 struct glyph *start = window_row->glyphs[LEFT_MARGIN_AREA];
18436 struct glyph *end = window_row->glyphs[LAST_AREA];
18438 frame_row->glyphs[LEFT_MARGIN_AREA] = start;
18439 frame_row->glyphs[TEXT_AREA] = start;
18440 frame_row->glyphs[RIGHT_MARGIN_AREA] = end;
18441 frame_row->glyphs[LAST_AREA] = end;
18443 /* Disable frame rows whose corresponding window rows have
18444 been disabled in try_window_id. */
18445 if (!window_row->enabled_p)
18446 frame_row->enabled_p = false;
18448 ++window_row, ++frame_row;
18453 /* Find the glyph row in window W containing CHARPOS. Consider all
18454 rows between START and END (not inclusive). END null means search
18455 all rows to the end of the display area of W. Value is the row
18456 containing CHARPOS or null. */
18458 struct glyph_row *
18459 row_containing_pos (struct window *w, ptrdiff_t charpos,
18460 struct glyph_row *start, struct glyph_row *end, int dy)
18462 struct glyph_row *row = start;
18463 struct glyph_row *best_row = NULL;
18464 ptrdiff_t mindif = BUF_ZV (XBUFFER (w->contents)) + 1;
18465 int last_y;
18467 /* If we happen to start on a header-line, skip that. */
18468 if (row->mode_line_p)
18469 ++row;
18471 if ((end && row >= end) || !row->enabled_p)
18472 return NULL;
18474 last_y = window_text_bottom_y (w) - dy;
18476 while (true)
18478 /* Give up if we have gone too far. */
18479 if ((end && row >= end) || !row->enabled_p)
18480 return NULL;
18481 /* This formerly returned if they were equal.
18482 I think that both quantities are of a "last plus one" type;
18483 if so, when they are equal, the row is within the screen. -- rms. */
18484 if (MATRIX_ROW_BOTTOM_Y (row) > last_y)
18485 return NULL;
18487 /* If it is in this row, return this row. */
18488 if (! (MATRIX_ROW_END_CHARPOS (row) < charpos
18489 || (MATRIX_ROW_END_CHARPOS (row) == charpos
18490 /* The end position of a row equals the start
18491 position of the next row. If CHARPOS is there, we
18492 would rather consider it displayed in the next
18493 line, except when this line ends in ZV. */
18494 && !row_for_charpos_p (row, charpos)))
18495 && charpos >= MATRIX_ROW_START_CHARPOS (row))
18497 struct glyph *g;
18499 if (NILP (BVAR (XBUFFER (w->contents), bidi_display_reordering))
18500 || (!best_row && !row->continued_p))
18501 return row;
18502 /* In bidi-reordered rows, there could be several rows whose
18503 edges surround CHARPOS, all of these rows belonging to
18504 the same continued line. We need to find the row which
18505 fits CHARPOS the best. */
18506 for (g = row->glyphs[TEXT_AREA];
18507 g < row->glyphs[TEXT_AREA] + row->used[TEXT_AREA];
18508 g++)
18510 if (!STRINGP (g->object))
18512 if (g->charpos > 0 && eabs (g->charpos - charpos) < mindif)
18514 mindif = eabs (g->charpos - charpos);
18515 best_row = row;
18516 /* Exact match always wins. */
18517 if (mindif == 0)
18518 return best_row;
18523 else if (best_row && !row->continued_p)
18524 return best_row;
18525 ++row;
18530 /* Try to redisplay window W by reusing its existing display. W's
18531 current matrix must be up to date when this function is called,
18532 i.e., window_end_valid must be true.
18534 Value is
18536 >= 1 if successful, i.e. display has been updated
18537 specifically:
18538 1 means the changes were in front of a newline that precedes
18539 the window start, and the whole current matrix was reused
18540 2 means the changes were after the last position displayed
18541 in the window, and the whole current matrix was reused
18542 3 means portions of the current matrix were reused, while
18543 some of the screen lines were redrawn
18544 -1 if redisplay with same window start is known not to succeed
18545 0 if otherwise unsuccessful
18547 The following steps are performed:
18549 1. Find the last row in the current matrix of W that is not
18550 affected by changes at the start of current_buffer. If no such row
18551 is found, give up.
18553 2. Find the first row in W's current matrix that is not affected by
18554 changes at the end of current_buffer. Maybe there is no such row.
18556 3. Display lines beginning with the row + 1 found in step 1 to the
18557 row found in step 2 or, if step 2 didn't find a row, to the end of
18558 the window.
18560 4. If cursor is not known to appear on the window, give up.
18562 5. If display stopped at the row found in step 2, scroll the
18563 display and current matrix as needed.
18565 6. Maybe display some lines at the end of W, if we must. This can
18566 happen under various circumstances, like a partially visible line
18567 becoming fully visible, or because newly displayed lines are displayed
18568 in smaller font sizes.
18570 7. Update W's window end information. */
18572 static int
18573 try_window_id (struct window *w)
18575 struct frame *f = XFRAME (w->frame);
18576 struct glyph_matrix *current_matrix = w->current_matrix;
18577 struct glyph_matrix *desired_matrix = w->desired_matrix;
18578 struct glyph_row *last_unchanged_at_beg_row;
18579 struct glyph_row *first_unchanged_at_end_row;
18580 struct glyph_row *row;
18581 struct glyph_row *bottom_row;
18582 int bottom_vpos;
18583 struct it it;
18584 ptrdiff_t delta = 0, delta_bytes = 0, stop_pos;
18585 int dvpos, dy;
18586 struct text_pos start_pos;
18587 struct run run;
18588 int first_unchanged_at_end_vpos = 0;
18589 struct glyph_row *last_text_row, *last_text_row_at_end;
18590 struct text_pos start;
18591 ptrdiff_t first_changed_charpos, last_changed_charpos;
18593 #ifdef GLYPH_DEBUG
18594 if (inhibit_try_window_id)
18595 return 0;
18596 #endif
18598 /* This is handy for debugging. */
18599 #if false
18600 #define GIVE_UP(X) \
18601 do { \
18602 TRACE ((stderr, "try_window_id give up %d\n", (X))); \
18603 return 0; \
18604 } while (false)
18605 #else
18606 #define GIVE_UP(X) return 0
18607 #endif
18609 SET_TEXT_POS_FROM_MARKER (start, w->start);
18611 /* Don't use this for mini-windows because these can show
18612 messages and mini-buffers, and we don't handle that here. */
18613 if (MINI_WINDOW_P (w))
18614 GIVE_UP (1);
18616 /* This flag is used to prevent redisplay optimizations. */
18617 if (windows_or_buffers_changed || f->cursor_type_changed)
18618 GIVE_UP (2);
18620 /* This function's optimizations cannot be used if overlays have
18621 changed in the buffer displayed by the window, so give up if they
18622 have. */
18623 if (w->last_overlay_modified != OVERLAY_MODIFF)
18624 GIVE_UP (200);
18626 /* Verify that narrowing has not changed.
18627 Also verify that we were not told to prevent redisplay optimizations.
18628 It would be nice to further
18629 reduce the number of cases where this prevents try_window_id. */
18630 if (current_buffer->clip_changed
18631 || current_buffer->prevent_redisplay_optimizations_p)
18632 GIVE_UP (3);
18634 /* Window must either use window-based redisplay or be full width. */
18635 if (!FRAME_WINDOW_P (f)
18636 && (!FRAME_LINE_INS_DEL_OK (f)
18637 || !WINDOW_FULL_WIDTH_P (w)))
18638 GIVE_UP (4);
18640 /* Give up if point is known NOT to appear in W. */
18641 if (PT < CHARPOS (start))
18642 GIVE_UP (5);
18644 /* Another way to prevent redisplay optimizations. */
18645 if (w->last_modified == 0)
18646 GIVE_UP (6);
18648 /* Verify that window is not hscrolled. */
18649 if (w->hscroll != 0)
18650 GIVE_UP (7);
18652 /* Verify that display wasn't paused. */
18653 if (!w->window_end_valid)
18654 GIVE_UP (8);
18656 /* Likewise if highlighting trailing whitespace. */
18657 if (!NILP (Vshow_trailing_whitespace))
18658 GIVE_UP (11);
18660 /* Can't use this if overlay arrow position and/or string have
18661 changed. */
18662 if (overlay_arrows_changed_p (false))
18663 GIVE_UP (12);
18665 /* When word-wrap is on, adding a space to the first word of a
18666 wrapped line can change the wrap position, altering the line
18667 above it. It might be worthwhile to handle this more
18668 intelligently, but for now just redisplay from scratch. */
18669 if (!NILP (BVAR (XBUFFER (w->contents), word_wrap)))
18670 GIVE_UP (21);
18672 /* Under bidi reordering, adding or deleting a character in the
18673 beginning of a paragraph, before the first strong directional
18674 character, can change the base direction of the paragraph (unless
18675 the buffer specifies a fixed paragraph direction), which will
18676 require redisplaying the whole paragraph. It might be worthwhile
18677 to find the paragraph limits and widen the range of redisplayed
18678 lines to that, but for now just give up this optimization and
18679 redisplay from scratch. */
18680 if (!NILP (BVAR (XBUFFER (w->contents), bidi_display_reordering))
18681 && NILP (BVAR (XBUFFER (w->contents), bidi_paragraph_direction)))
18682 GIVE_UP (22);
18684 /* Give up if the buffer has line-spacing set, as Lisp-level changes
18685 to that variable require thorough redisplay. */
18686 if (!NILP (BVAR (XBUFFER (w->contents), extra_line_spacing)))
18687 GIVE_UP (23);
18689 /* Give up if display-line-numbers is in relative mode, or when the
18690 current line's number needs to be displayed in a distinct face. */
18691 if (EQ (Vdisplay_line_numbers, Qrelative)
18692 || EQ (Vdisplay_line_numbers, Qvisual)
18693 || (!NILP (Vdisplay_line_numbers)
18694 && NILP (Finternal_lisp_face_equal_p (Qline_number,
18695 Qline_number_current_line,
18696 w->frame))))
18697 GIVE_UP (24);
18699 /* Make sure beg_unchanged and end_unchanged are up to date. Do it
18700 only if buffer has really changed. The reason is that the gap is
18701 initially at Z for freshly visited files. The code below would
18702 set end_unchanged to 0 in that case. */
18703 if (MODIFF > SAVE_MODIFF
18704 /* This seems to happen sometimes after saving a buffer. */
18705 || BEG_UNCHANGED + END_UNCHANGED > Z_BYTE)
18707 if (GPT - BEG < BEG_UNCHANGED)
18708 BEG_UNCHANGED = GPT - BEG;
18709 if (Z - GPT < END_UNCHANGED)
18710 END_UNCHANGED = Z - GPT;
18713 /* The position of the first and last character that has been changed. */
18714 first_changed_charpos = BEG + BEG_UNCHANGED;
18715 last_changed_charpos = Z - END_UNCHANGED;
18717 /* If window starts after a line end, and the last change is in
18718 front of that newline, then changes don't affect the display.
18719 This case happens with stealth-fontification. Note that although
18720 the display is unchanged, glyph positions in the matrix have to
18721 be adjusted, of course. */
18722 row = MATRIX_ROW (w->current_matrix, w->window_end_vpos);
18723 if (MATRIX_ROW_DISPLAYS_TEXT_P (row)
18724 && ((last_changed_charpos < CHARPOS (start)
18725 && CHARPOS (start) == BEGV)
18726 || (last_changed_charpos < CHARPOS (start) - 1
18727 && FETCH_BYTE (BYTEPOS (start) - 1) == '\n')))
18729 ptrdiff_t Z_old, Z_delta, Z_BYTE_old, Z_delta_bytes;
18730 struct glyph_row *r0;
18732 /* Compute how many chars/bytes have been added to or removed
18733 from the buffer. */
18734 Z_old = MATRIX_ROW_END_CHARPOS (row) + w->window_end_pos;
18735 Z_BYTE_old = MATRIX_ROW_END_BYTEPOS (row) + w->window_end_bytepos;
18736 Z_delta = Z - Z_old;
18737 Z_delta_bytes = Z_BYTE - Z_BYTE_old;
18739 /* Give up if PT is not in the window. Note that it already has
18740 been checked at the start of try_window_id that PT is not in
18741 front of the window start. */
18742 if (PT >= MATRIX_ROW_END_CHARPOS (row) + Z_delta)
18743 GIVE_UP (13);
18745 /* If window start is unchanged, we can reuse the whole matrix
18746 as is, after adjusting glyph positions. No need to compute
18747 the window end again, since its offset from Z hasn't changed. */
18748 r0 = MATRIX_FIRST_TEXT_ROW (current_matrix);
18749 if (CHARPOS (start) == MATRIX_ROW_START_CHARPOS (r0) + Z_delta
18750 && BYTEPOS (start) == MATRIX_ROW_START_BYTEPOS (r0) + Z_delta_bytes
18751 /* PT must not be in a partially visible line. */
18752 && !(PT >= MATRIX_ROW_START_CHARPOS (row) + Z_delta
18753 && MATRIX_ROW_BOTTOM_Y (row) > window_text_bottom_y (w)))
18755 /* Adjust positions in the glyph matrix. */
18756 if (Z_delta || Z_delta_bytes)
18758 struct glyph_row *r1
18759 = MATRIX_BOTTOM_TEXT_ROW (current_matrix, w);
18760 increment_matrix_positions (w->current_matrix,
18761 MATRIX_ROW_VPOS (r0, current_matrix),
18762 MATRIX_ROW_VPOS (r1, current_matrix),
18763 Z_delta, Z_delta_bytes);
18766 /* Set the cursor. */
18767 row = row_containing_pos (w, PT, r0, NULL, 0);
18768 if (row)
18769 set_cursor_from_row (w, row, current_matrix, 0, 0, 0, 0);
18770 return 1;
18774 /* Handle the case that changes are all below what is displayed in
18775 the window, and that PT is in the window. This shortcut cannot
18776 be taken if ZV is visible in the window, and text has been added
18777 there that is visible in the window. */
18778 if (first_changed_charpos >= MATRIX_ROW_END_CHARPOS (row)
18779 /* ZV is not visible in the window, or there are no
18780 changes at ZV, actually. */
18781 && (current_matrix->zv > MATRIX_ROW_END_CHARPOS (row)
18782 || first_changed_charpos == last_changed_charpos))
18784 struct glyph_row *r0;
18786 /* Give up if PT is not in the window. Note that it already has
18787 been checked at the start of try_window_id that PT is not in
18788 front of the window start. */
18789 if (PT >= MATRIX_ROW_END_CHARPOS (row))
18790 GIVE_UP (14);
18792 /* If window start is unchanged, we can reuse the whole matrix
18793 as is, without changing glyph positions since no text has
18794 been added/removed in front of the window end. */
18795 r0 = MATRIX_FIRST_TEXT_ROW (current_matrix);
18796 if (TEXT_POS_EQUAL_P (start, r0->minpos)
18797 /* PT must not be in a partially visible line. */
18798 && !(PT >= MATRIX_ROW_START_CHARPOS (row)
18799 && MATRIX_ROW_BOTTOM_Y (row) > window_text_bottom_y (w)))
18801 /* We have to compute the window end anew since text
18802 could have been added/removed after it. */
18803 w->window_end_pos = Z - MATRIX_ROW_END_CHARPOS (row);
18804 w->window_end_bytepos = Z_BYTE - MATRIX_ROW_END_BYTEPOS (row);
18806 /* Set the cursor. */
18807 row = row_containing_pos (w, PT, r0, NULL, 0);
18808 if (row)
18809 set_cursor_from_row (w, row, current_matrix, 0, 0, 0, 0);
18810 return 2;
18814 /* Give up if window start is in the changed area.
18816 The condition used to read
18818 (BEG_UNCHANGED + END_UNCHANGED != Z - BEG && ...)
18820 but why that was tested escapes me at the moment. */
18821 if (CHARPOS (start) >= first_changed_charpos
18822 && CHARPOS (start) <= last_changed_charpos)
18823 GIVE_UP (15);
18825 /* Check that window start agrees with the start of the first glyph
18826 row in its current matrix. Check this after we know the window
18827 start is not in changed text, otherwise positions would not be
18828 comparable. */
18829 row = MATRIX_FIRST_TEXT_ROW (current_matrix);
18830 if (!TEXT_POS_EQUAL_P (start, row->minpos))
18831 GIVE_UP (16);
18833 /* Give up if the window ends in strings. Overlay strings
18834 at the end are difficult to handle, so don't try. */
18835 row = MATRIX_ROW (current_matrix, w->window_end_vpos);
18836 if (MATRIX_ROW_START_CHARPOS (row) == MATRIX_ROW_END_CHARPOS (row))
18837 GIVE_UP (20);
18839 /* Compute the position at which we have to start displaying new
18840 lines. Some of the lines at the top of the window might be
18841 reusable because they are not displaying changed text. Find the
18842 last row in W's current matrix not affected by changes at the
18843 start of current_buffer. Value is null if changes start in the
18844 first line of window. */
18845 last_unchanged_at_beg_row = find_last_unchanged_at_beg_row (w);
18846 if (last_unchanged_at_beg_row)
18848 /* Avoid starting to display in the middle of a character, a TAB
18849 for instance. This is easier than to set up the iterator
18850 exactly, and it's not a frequent case, so the additional
18851 effort wouldn't really pay off. */
18852 while ((MATRIX_ROW_ENDS_IN_MIDDLE_OF_CHAR_P (last_unchanged_at_beg_row)
18853 || last_unchanged_at_beg_row->ends_in_newline_from_string_p)
18854 && last_unchanged_at_beg_row > w->current_matrix->rows)
18855 --last_unchanged_at_beg_row;
18857 if (MATRIX_ROW_ENDS_IN_MIDDLE_OF_CHAR_P (last_unchanged_at_beg_row))
18858 GIVE_UP (17);
18860 if (! init_to_row_end (&it, w, last_unchanged_at_beg_row))
18861 GIVE_UP (18);
18862 start_pos = it.current.pos;
18864 /* Start displaying new lines in the desired matrix at the same
18865 vpos we would use in the current matrix, i.e. below
18866 last_unchanged_at_beg_row. */
18867 it.vpos = 1 + MATRIX_ROW_VPOS (last_unchanged_at_beg_row,
18868 current_matrix);
18869 it.glyph_row = MATRIX_ROW (desired_matrix, it.vpos);
18870 it.current_y = MATRIX_ROW_BOTTOM_Y (last_unchanged_at_beg_row);
18872 eassert (it.hpos == 0 && it.current_x == 0);
18874 else
18876 /* There are no reusable lines at the start of the window.
18877 Start displaying in the first text line. */
18878 start_display (&it, w, start);
18879 it.vpos = it.first_vpos;
18880 start_pos = it.current.pos;
18883 /* Find the first row that is not affected by changes at the end of
18884 the buffer. Value will be null if there is no unchanged row, in
18885 which case we must redisplay to the end of the window. delta
18886 will be set to the value by which buffer positions beginning with
18887 first_unchanged_at_end_row have to be adjusted due to text
18888 changes. */
18889 first_unchanged_at_end_row
18890 = find_first_unchanged_at_end_row (w, &delta, &delta_bytes);
18891 IF_DEBUG (debug_delta = delta);
18892 IF_DEBUG (debug_delta_bytes = delta_bytes);
18894 /* Set stop_pos to the buffer position up to which we will have to
18895 display new lines. If first_unchanged_at_end_row != NULL, this
18896 is the buffer position of the start of the line displayed in that
18897 row. For first_unchanged_at_end_row == NULL, use 0 to indicate
18898 that we don't stop at a buffer position. */
18899 stop_pos = 0;
18900 if (first_unchanged_at_end_row)
18902 eassert (last_unchanged_at_beg_row == NULL
18903 || first_unchanged_at_end_row >= last_unchanged_at_beg_row);
18905 /* If this is a continuation line, move forward to the next one
18906 that isn't. Changes in lines above affect this line.
18907 Caution: this may move first_unchanged_at_end_row to a row
18908 not displaying text. */
18909 while (MATRIX_ROW_CONTINUATION_LINE_P (first_unchanged_at_end_row)
18910 && MATRIX_ROW_DISPLAYS_TEXT_P (first_unchanged_at_end_row)
18911 && (MATRIX_ROW_BOTTOM_Y (first_unchanged_at_end_row)
18912 < it.last_visible_y))
18913 ++first_unchanged_at_end_row;
18915 if (!MATRIX_ROW_DISPLAYS_TEXT_P (first_unchanged_at_end_row)
18916 || (MATRIX_ROW_BOTTOM_Y (first_unchanged_at_end_row)
18917 >= it.last_visible_y))
18918 first_unchanged_at_end_row = NULL;
18919 else
18921 stop_pos = (MATRIX_ROW_START_CHARPOS (first_unchanged_at_end_row)
18922 + delta);
18923 first_unchanged_at_end_vpos
18924 = MATRIX_ROW_VPOS (first_unchanged_at_end_row, current_matrix);
18925 eassert (stop_pos >= Z - END_UNCHANGED);
18928 else if (last_unchanged_at_beg_row == NULL)
18929 GIVE_UP (19);
18932 #ifdef GLYPH_DEBUG
18934 /* Either there is no unchanged row at the end, or the one we have
18935 now displays text. This is a necessary condition for the window
18936 end pos calculation at the end of this function. */
18937 eassert (first_unchanged_at_end_row == NULL
18938 || MATRIX_ROW_DISPLAYS_TEXT_P (first_unchanged_at_end_row));
18940 debug_last_unchanged_at_beg_vpos
18941 = (last_unchanged_at_beg_row
18942 ? MATRIX_ROW_VPOS (last_unchanged_at_beg_row, current_matrix)
18943 : -1);
18944 debug_first_unchanged_at_end_vpos = first_unchanged_at_end_vpos;
18946 #endif /* GLYPH_DEBUG */
18949 /* Display new lines. Set last_text_row to the last new line
18950 displayed which has text on it, i.e. might end up as being the
18951 line where the window_end_vpos is. */
18952 w->cursor.vpos = -1;
18953 last_text_row = NULL;
18954 overlay_arrow_seen = false;
18955 if (it.current_y < it.last_visible_y
18956 && !f->fonts_changed
18957 && (first_unchanged_at_end_row == NULL
18958 || IT_CHARPOS (it) < stop_pos))
18959 it.glyph_row->reversed_p = false;
18960 while (it.current_y < it.last_visible_y
18961 && !f->fonts_changed
18962 && (first_unchanged_at_end_row == NULL
18963 || IT_CHARPOS (it) < stop_pos))
18965 if (display_line (&it, -1))
18966 last_text_row = it.glyph_row - 1;
18969 if (f->fonts_changed)
18970 return -1;
18972 /* The redisplay iterations in display_line above could have
18973 triggered font-lock, which could have done something that
18974 invalidates IT->w window's end-point information, on which we
18975 rely below. E.g., one package, which will remain unnamed, used
18976 to install a font-lock-fontify-region-function that called
18977 bury-buffer, whose side effect is to switch the buffer displayed
18978 by IT->w, and that predictably resets IT->w's window_end_valid
18979 flag, which we already tested at the entry to this function.
18980 Amply punish such packages/modes by giving up on this
18981 optimization in those cases. */
18982 if (!w->window_end_valid)
18984 clear_glyph_matrix (w->desired_matrix);
18985 return -1;
18988 /* Compute differences in buffer positions, y-positions etc. for
18989 lines reused at the bottom of the window. Compute what we can
18990 scroll. */
18991 if (first_unchanged_at_end_row
18992 /* No lines reused because we displayed everything up to the
18993 bottom of the window. */
18994 && it.current_y < it.last_visible_y)
18996 dvpos = (it.vpos
18997 - MATRIX_ROW_VPOS (first_unchanged_at_end_row,
18998 current_matrix));
18999 dy = it.current_y - first_unchanged_at_end_row->y;
19000 run.current_y = first_unchanged_at_end_row->y;
19001 run.desired_y = run.current_y + dy;
19002 run.height = it.last_visible_y - max (run.current_y, run.desired_y);
19004 else
19006 delta = delta_bytes = dvpos = dy
19007 = run.current_y = run.desired_y = run.height = 0;
19008 first_unchanged_at_end_row = NULL;
19010 IF_DEBUG ((debug_dvpos = dvpos, debug_dy = dy));
19013 /* Find the cursor if not already found. We have to decide whether
19014 PT will appear on this window (it sometimes doesn't, but this is
19015 not a very frequent case.) This decision has to be made before
19016 the current matrix is altered. A value of cursor.vpos < 0 means
19017 that PT is either in one of the lines beginning at
19018 first_unchanged_at_end_row or below the window. Don't care for
19019 lines that might be displayed later at the window end; as
19020 mentioned, this is not a frequent case. */
19021 if (w->cursor.vpos < 0)
19023 /* Cursor in unchanged rows at the top? */
19024 if (PT < CHARPOS (start_pos)
19025 && last_unchanged_at_beg_row)
19027 row = row_containing_pos (w, PT,
19028 MATRIX_FIRST_TEXT_ROW (w->current_matrix),
19029 last_unchanged_at_beg_row + 1, 0);
19030 if (row)
19031 set_cursor_from_row (w, row, w->current_matrix, 0, 0, 0, 0);
19034 /* Start from first_unchanged_at_end_row looking for PT. */
19035 else if (first_unchanged_at_end_row)
19037 row = row_containing_pos (w, PT - delta,
19038 first_unchanged_at_end_row, NULL, 0);
19039 if (row)
19040 set_cursor_from_row (w, row, w->current_matrix, delta,
19041 delta_bytes, dy, dvpos);
19044 /* Give up if cursor was not found. */
19045 if (w->cursor.vpos < 0)
19047 clear_glyph_matrix (w->desired_matrix);
19048 return -1;
19052 /* Don't let the cursor end in the scroll margins. */
19054 int this_scroll_margin = window_scroll_margin (w, MARGIN_IN_PIXELS);
19055 int cursor_height = MATRIX_ROW (w->desired_matrix, w->cursor.vpos)->height;
19057 if ((w->cursor.y < this_scroll_margin
19058 && CHARPOS (start) > BEGV)
19059 /* Old redisplay didn't take scroll margin into account at the bottom,
19060 but then global-hl-line-mode doesn't scroll. KFS 2004-06-14 */
19061 || (w->cursor.y + (make_cursor_line_fully_visible_p
19062 ? cursor_height + this_scroll_margin
19063 : 1)) > it.last_visible_y)
19065 w->cursor.vpos = -1;
19066 clear_glyph_matrix (w->desired_matrix);
19067 return -1;
19071 /* Scroll the display. Do it before changing the current matrix so
19072 that xterm.c doesn't get confused about where the cursor glyph is
19073 found. */
19074 if (dy && run.height)
19076 update_begin (f);
19078 if (FRAME_WINDOW_P (f))
19080 FRAME_RIF (f)->update_window_begin_hook (w);
19081 FRAME_RIF (f)->clear_window_mouse_face (w);
19082 FRAME_RIF (f)->scroll_run_hook (w, &run);
19083 FRAME_RIF (f)->update_window_end_hook (w, false, false);
19085 else
19087 /* Terminal frame. In this case, dvpos gives the number of
19088 lines to scroll by; dvpos < 0 means scroll up. */
19089 int from_vpos
19090 = MATRIX_ROW_VPOS (first_unchanged_at_end_row, w->current_matrix);
19091 int from = WINDOW_TOP_EDGE_LINE (w) + from_vpos;
19092 int end = (WINDOW_TOP_EDGE_LINE (w)
19093 + window_wants_header_line (w)
19094 + window_internal_height (w));
19096 #if defined (HAVE_GPM) || defined (MSDOS)
19097 x_clear_window_mouse_face (w);
19098 #endif
19099 /* Perform the operation on the screen. */
19100 if (dvpos > 0)
19102 /* Scroll last_unchanged_at_beg_row to the end of the
19103 window down dvpos lines. */
19104 set_terminal_window (f, end);
19106 /* On dumb terminals delete dvpos lines at the end
19107 before inserting dvpos empty lines. */
19108 if (!FRAME_SCROLL_REGION_OK (f))
19109 ins_del_lines (f, end - dvpos, -dvpos);
19111 /* Insert dvpos empty lines in front of
19112 last_unchanged_at_beg_row. */
19113 ins_del_lines (f, from, dvpos);
19115 else if (dvpos < 0)
19117 /* Scroll up last_unchanged_at_beg_vpos to the end of
19118 the window to last_unchanged_at_beg_vpos - |dvpos|. */
19119 set_terminal_window (f, end);
19121 /* Delete dvpos lines in front of
19122 last_unchanged_at_beg_vpos. ins_del_lines will set
19123 the cursor to the given vpos and emit |dvpos| delete
19124 line sequences. */
19125 ins_del_lines (f, from + dvpos, dvpos);
19127 /* On a dumb terminal insert dvpos empty lines at the
19128 end. */
19129 if (!FRAME_SCROLL_REGION_OK (f))
19130 ins_del_lines (f, end + dvpos, -dvpos);
19133 set_terminal_window (f, 0);
19136 update_end (f);
19139 /* Shift reused rows of the current matrix to the right position.
19140 BOTTOM_ROW is the last + 1 row in the current matrix reserved for
19141 text. */
19142 bottom_row = MATRIX_BOTTOM_TEXT_ROW (current_matrix, w);
19143 bottom_vpos = MATRIX_ROW_VPOS (bottom_row, current_matrix);
19144 if (dvpos < 0)
19146 rotate_matrix (current_matrix, first_unchanged_at_end_vpos + dvpos,
19147 bottom_vpos, dvpos);
19148 clear_glyph_matrix_rows (current_matrix, bottom_vpos + dvpos,
19149 bottom_vpos);
19151 else if (dvpos > 0)
19153 rotate_matrix (current_matrix, first_unchanged_at_end_vpos,
19154 bottom_vpos, dvpos);
19155 clear_glyph_matrix_rows (current_matrix, first_unchanged_at_end_vpos,
19156 first_unchanged_at_end_vpos + dvpos);
19159 /* For frame-based redisplay, make sure that current frame and window
19160 matrix are in sync with respect to glyph memory. */
19161 if (!FRAME_WINDOW_P (f))
19162 sync_frame_with_window_matrix_rows (w);
19164 /* Adjust buffer positions in reused rows. */
19165 if (delta || delta_bytes)
19166 increment_matrix_positions (current_matrix,
19167 first_unchanged_at_end_vpos + dvpos,
19168 bottom_vpos, delta, delta_bytes);
19170 /* Adjust Y positions. */
19171 if (dy)
19172 shift_glyph_matrix (w, current_matrix,
19173 first_unchanged_at_end_vpos + dvpos,
19174 bottom_vpos, dy);
19176 if (first_unchanged_at_end_row)
19178 first_unchanged_at_end_row += dvpos;
19179 if (first_unchanged_at_end_row->y >= it.last_visible_y
19180 || !MATRIX_ROW_DISPLAYS_TEXT_P (first_unchanged_at_end_row))
19181 first_unchanged_at_end_row = NULL;
19184 /* If scrolling up, there may be some lines to display at the end of
19185 the window. */
19186 last_text_row_at_end = NULL;
19187 if (dy < 0)
19189 /* Scrolling up can leave for example a partially visible line
19190 at the end of the window to be redisplayed. */
19191 /* Set last_row to the glyph row in the current matrix where the
19192 window end line is found. It has been moved up or down in
19193 the matrix by dvpos. */
19194 int last_vpos = w->window_end_vpos + dvpos;
19195 struct glyph_row *last_row = MATRIX_ROW (current_matrix, last_vpos);
19197 /* If last_row is the window end line, it should display text. */
19198 eassert (MATRIX_ROW_DISPLAYS_TEXT_P (last_row));
19200 /* If window end line was partially visible before, begin
19201 displaying at that line. Otherwise begin displaying with the
19202 line following it. */
19203 if (MATRIX_ROW_BOTTOM_Y (last_row) - dy >= it.last_visible_y)
19205 init_to_row_start (&it, w, last_row);
19206 it.vpos = last_vpos;
19207 it.current_y = last_row->y;
19209 else
19211 init_to_row_end (&it, w, last_row);
19212 it.vpos = 1 + last_vpos;
19213 it.current_y = MATRIX_ROW_BOTTOM_Y (last_row);
19214 ++last_row;
19217 /* We may start in a continuation line. If so, we have to
19218 get the right continuation_lines_width and current_x. */
19219 it.continuation_lines_width = last_row->continuation_lines_width;
19220 it.hpos = it.current_x = 0;
19222 /* Display the rest of the lines at the window end. */
19223 it.glyph_row = MATRIX_ROW (desired_matrix, it.vpos);
19224 while (it.current_y < it.last_visible_y && !f->fonts_changed)
19226 /* Is it always sure that the display agrees with lines in
19227 the current matrix? I don't think so, so we mark rows
19228 displayed invalid in the current matrix by setting their
19229 enabled_p flag to false. */
19230 SET_MATRIX_ROW_ENABLED_P (w->current_matrix, it.vpos, false);
19231 if (display_line (&it, w->cursor.vpos))
19232 last_text_row_at_end = it.glyph_row - 1;
19236 /* Update window_end_pos and window_end_vpos. */
19237 if (first_unchanged_at_end_row && !last_text_row_at_end)
19239 /* Window end line if one of the preserved rows from the current
19240 matrix. Set row to the last row displaying text in current
19241 matrix starting at first_unchanged_at_end_row, after
19242 scrolling. */
19243 eassert (MATRIX_ROW_DISPLAYS_TEXT_P (first_unchanged_at_end_row));
19244 row = find_last_row_displaying_text (w->current_matrix, &it,
19245 first_unchanged_at_end_row);
19246 eassume (row && MATRIX_ROW_DISPLAYS_TEXT_P (row));
19247 adjust_window_ends (w, row, true);
19248 eassert (w->window_end_bytepos >= 0);
19249 IF_DEBUG (debug_method_add (w, "A"));
19251 else if (last_text_row_at_end)
19253 adjust_window_ends (w, last_text_row_at_end, false);
19254 eassert (w->window_end_bytepos >= 0);
19255 IF_DEBUG (debug_method_add (w, "B"));
19257 else if (last_text_row)
19259 /* We have displayed either to the end of the window or at the
19260 end of the window, i.e. the last row with text is to be found
19261 in the desired matrix. */
19262 adjust_window_ends (w, last_text_row, false);
19263 eassert (w->window_end_bytepos >= 0);
19265 else if (first_unchanged_at_end_row == NULL
19266 && last_text_row == NULL
19267 && last_text_row_at_end == NULL)
19269 /* Displayed to end of window, but no line containing text was
19270 displayed. Lines were deleted at the end of the window. */
19271 bool first_vpos = window_wants_header_line (w);
19272 int vpos = w->window_end_vpos;
19273 struct glyph_row *current_row = current_matrix->rows + vpos;
19274 struct glyph_row *desired_row = desired_matrix->rows + vpos;
19276 for (row = NULL; !row; --vpos, --current_row, --desired_row)
19278 eassert (first_vpos <= vpos);
19279 if (desired_row->enabled_p)
19281 if (MATRIX_ROW_DISPLAYS_TEXT_P (desired_row))
19282 row = desired_row;
19284 else if (MATRIX_ROW_DISPLAYS_TEXT_P (current_row))
19285 row = current_row;
19288 w->window_end_vpos = vpos + 1;
19289 w->window_end_pos = Z - MATRIX_ROW_END_CHARPOS (row);
19290 w->window_end_bytepos = Z_BYTE - MATRIX_ROW_END_BYTEPOS (row);
19291 eassert (w->window_end_bytepos >= 0);
19292 IF_DEBUG (debug_method_add (w, "C"));
19294 else
19295 emacs_abort ();
19297 IF_DEBUG ((debug_end_pos = w->window_end_pos,
19298 debug_end_vpos = w->window_end_vpos));
19300 /* Record that display has not been completed. */
19301 w->window_end_valid = false;
19302 w->desired_matrix->no_scrolling_p = true;
19303 return 3;
19305 #undef GIVE_UP
19310 /***********************************************************************
19311 More debugging support
19312 ***********************************************************************/
19314 #ifdef GLYPH_DEBUG
19316 void dump_glyph_row (struct glyph_row *, int, int) EXTERNALLY_VISIBLE;
19317 void dump_glyph_matrix (struct glyph_matrix *, int) EXTERNALLY_VISIBLE;
19318 void dump_glyph (struct glyph_row *, struct glyph *, int) EXTERNALLY_VISIBLE;
19321 /* Dump the contents of glyph matrix MATRIX on stderr.
19323 GLYPHS 0 means don't show glyph contents.
19324 GLYPHS 1 means show glyphs in short form
19325 GLYPHS > 1 means show glyphs in long form. */
19327 void
19328 dump_glyph_matrix (struct glyph_matrix *matrix, int glyphs)
19330 int i;
19331 for (i = 0; i < matrix->nrows; ++i)
19332 dump_glyph_row (MATRIX_ROW (matrix, i), i, glyphs);
19336 /* Dump contents of glyph GLYPH to stderr. ROW and AREA are
19337 the glyph row and area where the glyph comes from. */
19339 void
19340 dump_glyph (struct glyph_row *row, struct glyph *glyph, int area)
19342 if (glyph->type == CHAR_GLYPH
19343 || glyph->type == GLYPHLESS_GLYPH)
19345 fprintf (stderr,
19346 " %5"pD"d %c %9"pD"d %c %3d 0x%06x %c %4d %1.1d%1.1d\n",
19347 glyph - row->glyphs[TEXT_AREA],
19348 (glyph->type == CHAR_GLYPH
19349 ? 'C'
19350 : 'G'),
19351 glyph->charpos,
19352 (BUFFERP (glyph->object)
19353 ? 'B'
19354 : (STRINGP (glyph->object)
19355 ? 'S'
19356 : (NILP (glyph->object)
19357 ? '0'
19358 : '-'))),
19359 glyph->pixel_width,
19360 glyph->u.ch,
19361 (glyph->u.ch < 0x80 && glyph->u.ch >= ' '
19362 ? (int) glyph->u.ch
19363 : '.'),
19364 glyph->face_id,
19365 glyph->left_box_line_p,
19366 glyph->right_box_line_p);
19368 else if (glyph->type == STRETCH_GLYPH)
19370 fprintf (stderr,
19371 " %5"pD"d %c %9"pD"d %c %3d 0x%06x %c %4d %1.1d%1.1d\n",
19372 glyph - row->glyphs[TEXT_AREA],
19373 'S',
19374 glyph->charpos,
19375 (BUFFERP (glyph->object)
19376 ? 'B'
19377 : (STRINGP (glyph->object)
19378 ? 'S'
19379 : (NILP (glyph->object)
19380 ? '0'
19381 : '-'))),
19382 glyph->pixel_width,
19384 ' ',
19385 glyph->face_id,
19386 glyph->left_box_line_p,
19387 glyph->right_box_line_p);
19389 else if (glyph->type == IMAGE_GLYPH)
19391 fprintf (stderr,
19392 " %5"pD"d %c %9"pD"d %c %3d 0x%06x %c %4d %1.1d%1.1d\n",
19393 glyph - row->glyphs[TEXT_AREA],
19394 'I',
19395 glyph->charpos,
19396 (BUFFERP (glyph->object)
19397 ? 'B'
19398 : (STRINGP (glyph->object)
19399 ? 'S'
19400 : (NILP (glyph->object)
19401 ? '0'
19402 : '-'))),
19403 glyph->pixel_width,
19404 (unsigned int) glyph->u.img_id,
19405 '.',
19406 glyph->face_id,
19407 glyph->left_box_line_p,
19408 glyph->right_box_line_p);
19410 else if (glyph->type == COMPOSITE_GLYPH)
19412 fprintf (stderr,
19413 " %5"pD"d %c %9"pD"d %c %3d 0x%06x",
19414 glyph - row->glyphs[TEXT_AREA],
19415 '+',
19416 glyph->charpos,
19417 (BUFFERP (glyph->object)
19418 ? 'B'
19419 : (STRINGP (glyph->object)
19420 ? 'S'
19421 : (NILP (glyph->object)
19422 ? '0'
19423 : '-'))),
19424 glyph->pixel_width,
19425 (unsigned int) glyph->u.cmp.id);
19426 if (glyph->u.cmp.automatic)
19427 fprintf (stderr,
19428 "[%d-%d]",
19429 glyph->slice.cmp.from, glyph->slice.cmp.to);
19430 fprintf (stderr, " . %4d %1.1d%1.1d\n",
19431 glyph->face_id,
19432 glyph->left_box_line_p,
19433 glyph->right_box_line_p);
19435 else if (glyph->type == XWIDGET_GLYPH)
19437 #ifndef HAVE_XWIDGETS
19438 eassume (false);
19439 #else
19440 fprintf (stderr,
19441 " %5d %4c %6d %c %3d 0x%05x %c %4d %1.1d%1.1d\n",
19442 glyph - row->glyphs[TEXT_AREA],
19443 'X',
19444 glyph->charpos,
19445 (BUFFERP (glyph->object)
19446 ? 'B'
19447 : (STRINGP (glyph->object)
19448 ? 'S'
19449 : '-')),
19450 glyph->pixel_width,
19451 glyph->u.xwidget,
19452 '.',
19453 glyph->face_id,
19454 glyph->left_box_line_p,
19455 glyph->right_box_line_p);
19456 #endif
19461 /* Dump the contents of glyph row at VPOS in MATRIX to stderr.
19462 GLYPHS 0 means don't show glyph contents.
19463 GLYPHS 1 means show glyphs in short form
19464 GLYPHS > 1 means show glyphs in long form. */
19466 void
19467 dump_glyph_row (struct glyph_row *row, int vpos, int glyphs)
19469 if (glyphs != 1)
19471 fprintf (stderr, "Row Start End Used oE><\\CTZFesm X Y W H V A P\n");
19472 fprintf (stderr, "==============================================================================\n");
19474 fprintf (stderr, "%3d %9"pD"d %9"pD"d %4d %1.1d%1.1d%1.1d%1.1d\
19475 %1.1d%1.1d%1.1d%1.1d%1.1d%1.1d%1.1d%1.1d %4d %4d %4d %4d %4d %4d %4d\n",
19476 vpos,
19477 MATRIX_ROW_START_CHARPOS (row),
19478 MATRIX_ROW_END_CHARPOS (row),
19479 row->used[TEXT_AREA],
19480 row->contains_overlapping_glyphs_p,
19481 row->enabled_p,
19482 row->truncated_on_left_p,
19483 row->truncated_on_right_p,
19484 row->continued_p,
19485 MATRIX_ROW_CONTINUATION_LINE_P (row),
19486 MATRIX_ROW_DISPLAYS_TEXT_P (row),
19487 row->ends_at_zv_p,
19488 row->fill_line_p,
19489 row->ends_in_middle_of_char_p,
19490 row->starts_in_middle_of_char_p,
19491 row->mouse_face_p,
19492 row->x,
19493 row->y,
19494 row->pixel_width,
19495 row->height,
19496 row->visible_height,
19497 row->ascent,
19498 row->phys_ascent);
19499 /* The next 3 lines should align to "Start" in the header. */
19500 fprintf (stderr, " %9"pD"d %9"pD"d\t%5d\n", row->start.overlay_string_index,
19501 row->end.overlay_string_index,
19502 row->continuation_lines_width);
19503 fprintf (stderr, " %9"pD"d %9"pD"d\n",
19504 CHARPOS (row->start.string_pos),
19505 CHARPOS (row->end.string_pos));
19506 fprintf (stderr, " %9d %9d\n", row->start.dpvec_index,
19507 row->end.dpvec_index);
19510 if (glyphs > 1)
19512 int area;
19514 for (area = LEFT_MARGIN_AREA; area < LAST_AREA; ++area)
19516 struct glyph *glyph = row->glyphs[area];
19517 struct glyph *glyph_end = glyph + row->used[area];
19519 /* Glyph for a line end in text. */
19520 if (area == TEXT_AREA && glyph == glyph_end && glyph->charpos > 0)
19521 ++glyph_end;
19523 if (glyph < glyph_end)
19524 fprintf (stderr, " Glyph# Type Pos O W Code C Face LR\n");
19526 for (; glyph < glyph_end; ++glyph)
19527 dump_glyph (row, glyph, area);
19530 else if (glyphs == 1)
19532 int area;
19533 char s[SHRT_MAX + 4];
19535 for (area = LEFT_MARGIN_AREA; area < LAST_AREA; ++area)
19537 int i;
19539 for (i = 0; i < row->used[area]; ++i)
19541 struct glyph *glyph = row->glyphs[area] + i;
19542 if (i == row->used[area] - 1
19543 && area == TEXT_AREA
19544 && NILP (glyph->object)
19545 && glyph->type == CHAR_GLYPH
19546 && glyph->u.ch == ' ')
19548 strcpy (&s[i], "[\\n]");
19549 i += 4;
19551 else if (glyph->type == CHAR_GLYPH
19552 && glyph->u.ch < 0x80
19553 && glyph->u.ch >= ' ')
19554 s[i] = glyph->u.ch;
19555 else
19556 s[i] = '.';
19559 s[i] = '\0';
19560 fprintf (stderr, "%3d: (%d) '%s'\n", vpos, row->enabled_p, s);
19566 DEFUN ("dump-glyph-matrix", Fdump_glyph_matrix,
19567 Sdump_glyph_matrix, 0, 1, "p",
19568 doc: /* Dump the current matrix of the selected window to stderr.
19569 Shows contents of glyph row structures. With non-nil
19570 parameter GLYPHS, dump glyphs as well. If GLYPHS is 1 show
19571 glyphs in short form, otherwise show glyphs in long form.
19573 Interactively, no argument means show glyphs in short form;
19574 with numeric argument, its value is passed as the GLYPHS flag. */)
19575 (Lisp_Object glyphs)
19577 struct window *w = XWINDOW (selected_window);
19578 struct buffer *buffer = XBUFFER (w->contents);
19580 fprintf (stderr, "PT = %"pD"d, BEGV = %"pD"d. ZV = %"pD"d\n",
19581 BUF_PT (buffer), BUF_BEGV (buffer), BUF_ZV (buffer));
19582 fprintf (stderr, "Cursor x = %d, y = %d, hpos = %d, vpos = %d\n",
19583 w->cursor.x, w->cursor.y, w->cursor.hpos, w->cursor.vpos);
19584 fprintf (stderr, "=============================================\n");
19585 dump_glyph_matrix (w->current_matrix,
19586 TYPE_RANGED_INTEGERP (int, glyphs) ? XINT (glyphs) : 0);
19587 return Qnil;
19591 DEFUN ("dump-frame-glyph-matrix", Fdump_frame_glyph_matrix,
19592 Sdump_frame_glyph_matrix, 0, 0, "", doc: /* Dump the current glyph matrix of the selected frame to stderr.
19593 Only text-mode frames have frame glyph matrices. */)
19594 (void)
19596 struct frame *f = XFRAME (selected_frame);
19598 if (f->current_matrix)
19599 dump_glyph_matrix (f->current_matrix, 1);
19600 else
19601 fprintf (stderr, "*** This frame doesn't have a frame glyph matrix ***\n");
19602 return Qnil;
19606 DEFUN ("dump-glyph-row", Fdump_glyph_row, Sdump_glyph_row, 1, 2, "P",
19607 doc: /* Dump glyph row ROW to stderr.
19608 Interactively, ROW is the prefix numeric argument and defaults to
19609 the row which displays point.
19610 Optional argument GLYPHS 0 means don't dump glyphs.
19611 GLYPHS 1 means dump glyphs in short form.
19612 GLYPHS > 1 or omitted means dump glyphs in long form. */)
19613 (Lisp_Object row, Lisp_Object glyphs)
19615 struct glyph_matrix *matrix;
19616 EMACS_INT vpos;
19618 if (NILP (row))
19620 int d1, d2, d3, d4, d5, ypos;
19621 bool visible_p = pos_visible_p (XWINDOW (selected_window), PT,
19622 &d1, &d2, &d3, &d4, &d5, &ypos);
19623 if (visible_p)
19624 vpos = ypos;
19625 else
19626 vpos = 0;
19628 else
19630 CHECK_NUMBER (row);
19631 vpos = XINT (row);
19633 matrix = XWINDOW (selected_window)->current_matrix;
19634 if (vpos >= 0 && vpos < matrix->nrows)
19635 dump_glyph_row (MATRIX_ROW (matrix, vpos),
19636 vpos,
19637 TYPE_RANGED_INTEGERP (int, glyphs) ? XINT (glyphs) : 2);
19638 return Qnil;
19642 DEFUN ("dump-tool-bar-row", Fdump_tool_bar_row, Sdump_tool_bar_row, 1, 2, "P",
19643 doc: /* Dump glyph row ROW of the tool-bar of the current frame to stderr.
19644 Interactively, ROW is the prefix numeric argument and defaults to zero.
19645 GLYPHS 0 means don't dump glyphs.
19646 GLYPHS 1 means dump glyphs in short form.
19647 GLYPHS > 1 or omitted means dump glyphs in long form.
19649 If there's no tool-bar, or if the tool-bar is not drawn by Emacs,
19650 do nothing. */)
19651 (Lisp_Object row, Lisp_Object glyphs)
19653 #if defined (HAVE_WINDOW_SYSTEM) && ! defined (USE_GTK) && ! defined (HAVE_NS)
19654 struct frame *sf = SELECTED_FRAME ();
19655 struct glyph_matrix *m = XWINDOW (sf->tool_bar_window)->current_matrix;
19656 EMACS_INT vpos;
19658 if (NILP (row))
19659 vpos = 0;
19660 else
19662 CHECK_NUMBER (row);
19663 vpos = XINT (row);
19665 if (vpos >= 0 && vpos < m->nrows)
19666 dump_glyph_row (MATRIX_ROW (m, vpos), vpos,
19667 TYPE_RANGED_INTEGERP (int, glyphs) ? XINT (glyphs) : 2);
19668 #endif
19669 return Qnil;
19673 DEFUN ("trace-redisplay", Ftrace_redisplay, Strace_redisplay, 0, 1, "P",
19674 doc: /* Toggle tracing of redisplay.
19675 With ARG, turn tracing on if and only if ARG is positive. */)
19676 (Lisp_Object arg)
19678 if (NILP (arg))
19679 trace_redisplay_p = !trace_redisplay_p;
19680 else
19682 arg = Fprefix_numeric_value (arg);
19683 trace_redisplay_p = XINT (arg) > 0;
19686 return Qnil;
19690 DEFUN ("trace-to-stderr", Ftrace_to_stderr, Strace_to_stderr, 1, MANY, "",
19691 doc: /* Like `format', but print result to stderr.
19692 usage: (trace-to-stderr STRING &rest OBJECTS) */)
19693 (ptrdiff_t nargs, Lisp_Object *args)
19695 Lisp_Object s = Fformat (nargs, args);
19696 fwrite (SDATA (s), 1, SBYTES (s), stderr);
19697 return Qnil;
19700 #endif /* GLYPH_DEBUG */
19704 /***********************************************************************
19705 Building Desired Matrix Rows
19706 ***********************************************************************/
19708 /* Return a temporary glyph row holding the glyphs of an overlay arrow.
19709 Used for non-window-redisplay windows, and for windows w/o left fringe. */
19711 static struct glyph_row *
19712 get_overlay_arrow_glyph_row (struct window *w, Lisp_Object overlay_arrow_string)
19714 struct frame *f = XFRAME (WINDOW_FRAME (w));
19715 struct buffer *buffer = XBUFFER (w->contents);
19716 struct buffer *old = current_buffer;
19717 const unsigned char *arrow_string = SDATA (overlay_arrow_string);
19718 ptrdiff_t arrow_len = SCHARS (overlay_arrow_string);
19719 const unsigned char *arrow_end = arrow_string + arrow_len;
19720 const unsigned char *p;
19721 struct it it;
19722 bool multibyte_p;
19723 int n_glyphs_before;
19725 set_buffer_temp (buffer);
19726 init_iterator (&it, w, -1, -1, &scratch_glyph_row, DEFAULT_FACE_ID);
19727 scratch_glyph_row.reversed_p = false;
19728 it.glyph_row->used[TEXT_AREA] = 0;
19729 SET_TEXT_POS (it.position, 0, 0);
19731 multibyte_p = !NILP (BVAR (buffer, enable_multibyte_characters));
19732 p = arrow_string;
19733 while (p < arrow_end)
19735 Lisp_Object face, ilisp;
19737 /* Get the next character. */
19738 if (multibyte_p)
19739 it.c = it.char_to_display = string_char_and_length (p, &it.len);
19740 else
19742 it.c = it.char_to_display = *p, it.len = 1;
19743 if (! ASCII_CHAR_P (it.c))
19744 it.char_to_display = BYTE8_TO_CHAR (it.c);
19746 p += it.len;
19748 /* Get its face. */
19749 ilisp = make_number (p - arrow_string);
19750 face = Fget_text_property (ilisp, Qface, overlay_arrow_string);
19751 it.face_id = compute_char_face (f, it.char_to_display, face);
19753 /* Compute its width, get its glyphs. */
19754 n_glyphs_before = it.glyph_row->used[TEXT_AREA];
19755 SET_TEXT_POS (it.position, -1, -1);
19756 PRODUCE_GLYPHS (&it);
19758 /* If this character doesn't fit any more in the line, we have
19759 to remove some glyphs. */
19760 if (it.current_x > it.last_visible_x)
19762 it.glyph_row->used[TEXT_AREA] = n_glyphs_before;
19763 break;
19767 set_buffer_temp (old);
19768 return it.glyph_row;
19772 /* Insert truncation glyphs at the start of IT->glyph_row. Which
19773 glyphs to insert is determined by produce_special_glyphs. */
19775 static void
19776 insert_left_trunc_glyphs (struct it *it)
19778 struct it truncate_it;
19779 struct glyph *from, *end, *to, *toend;
19781 eassert (!FRAME_WINDOW_P (it->f)
19782 || (!it->glyph_row->reversed_p
19783 && WINDOW_LEFT_FRINGE_WIDTH (it->w) == 0)
19784 || (it->glyph_row->reversed_p
19785 && WINDOW_RIGHT_FRINGE_WIDTH (it->w) == 0));
19787 /* Get the truncation glyphs. */
19788 truncate_it = *it;
19789 truncate_it.current_x = 0;
19790 truncate_it.face_id = DEFAULT_FACE_ID;
19791 truncate_it.glyph_row = &scratch_glyph_row;
19792 truncate_it.area = TEXT_AREA;
19793 truncate_it.glyph_row->used[TEXT_AREA] = 0;
19794 CHARPOS (truncate_it.position) = BYTEPOS (truncate_it.position) = -1;
19795 truncate_it.object = Qnil;
19796 produce_special_glyphs (&truncate_it, IT_TRUNCATION);
19798 /* Overwrite glyphs from IT with truncation glyphs. */
19799 if (!it->glyph_row->reversed_p)
19801 short tused = truncate_it.glyph_row->used[TEXT_AREA];
19803 from = truncate_it.glyph_row->glyphs[TEXT_AREA];
19804 end = from + tused;
19805 to = it->glyph_row->glyphs[TEXT_AREA];
19806 toend = to + it->glyph_row->used[TEXT_AREA];
19807 if (FRAME_WINDOW_P (it->f))
19809 /* On GUI frames, when variable-size fonts are displayed,
19810 the truncation glyphs may need more pixels than the row's
19811 glyphs they overwrite. We overwrite more glyphs to free
19812 enough screen real estate, and enlarge the stretch glyph
19813 on the right (see display_line), if there is one, to
19814 preserve the screen position of the truncation glyphs on
19815 the right. */
19816 int w = 0;
19817 struct glyph *g = to;
19818 short used;
19820 /* The first glyph could be partially visible, in which case
19821 it->glyph_row->x will be negative. But we want the left
19822 truncation glyphs to be aligned at the left margin of the
19823 window, so we override the x coordinate at which the row
19824 will begin. */
19825 it->glyph_row->x = 0;
19826 while (g < toend && w < it->truncation_pixel_width)
19828 w += g->pixel_width;
19829 ++g;
19831 if (g - to - tused > 0)
19833 memmove (to + tused, g, (toend - g) * sizeof(*g));
19834 it->glyph_row->used[TEXT_AREA] -= g - to - tused;
19836 used = it->glyph_row->used[TEXT_AREA];
19837 if (it->glyph_row->truncated_on_right_p
19838 && WINDOW_RIGHT_FRINGE_WIDTH (it->w) == 0
19839 && it->glyph_row->glyphs[TEXT_AREA][used - 2].type
19840 == STRETCH_GLYPH)
19842 int extra = w - it->truncation_pixel_width;
19844 it->glyph_row->glyphs[TEXT_AREA][used - 2].pixel_width += extra;
19848 while (from < end)
19849 *to++ = *from++;
19851 /* There may be padding glyphs left over. Overwrite them too. */
19852 if (!FRAME_WINDOW_P (it->f))
19854 while (to < toend && CHAR_GLYPH_PADDING_P (*to))
19856 from = truncate_it.glyph_row->glyphs[TEXT_AREA];
19857 while (from < end)
19858 *to++ = *from++;
19862 if (to > toend)
19863 it->glyph_row->used[TEXT_AREA] = to - it->glyph_row->glyphs[TEXT_AREA];
19865 else
19867 short tused = truncate_it.glyph_row->used[TEXT_AREA];
19869 /* In R2L rows, overwrite the last (rightmost) glyphs, and do
19870 that back to front. */
19871 end = truncate_it.glyph_row->glyphs[TEXT_AREA];
19872 from = end + truncate_it.glyph_row->used[TEXT_AREA] - 1;
19873 toend = it->glyph_row->glyphs[TEXT_AREA];
19874 to = toend + it->glyph_row->used[TEXT_AREA] - 1;
19875 if (FRAME_WINDOW_P (it->f))
19877 int w = 0;
19878 struct glyph *g = to;
19880 while (g >= toend && w < it->truncation_pixel_width)
19882 w += g->pixel_width;
19883 --g;
19885 if (to - g - tused > 0)
19886 to = g + tused;
19887 if (it->glyph_row->truncated_on_right_p
19888 && WINDOW_LEFT_FRINGE_WIDTH (it->w) == 0
19889 && it->glyph_row->glyphs[TEXT_AREA][1].type == STRETCH_GLYPH)
19891 int extra = w - it->truncation_pixel_width;
19893 it->glyph_row->glyphs[TEXT_AREA][1].pixel_width += extra;
19897 while (from >= end && to >= toend)
19898 *to-- = *from--;
19899 if (!FRAME_WINDOW_P (it->f))
19901 while (to >= toend && CHAR_GLYPH_PADDING_P (*to))
19903 from =
19904 truncate_it.glyph_row->glyphs[TEXT_AREA]
19905 + truncate_it.glyph_row->used[TEXT_AREA] - 1;
19906 while (from >= end && to >= toend)
19907 *to-- = *from--;
19910 if (from >= end)
19912 /* Need to free some room before prepending additional
19913 glyphs. */
19914 int move_by = from - end + 1;
19915 struct glyph *g0 = it->glyph_row->glyphs[TEXT_AREA];
19916 struct glyph *g = g0 + it->glyph_row->used[TEXT_AREA] - 1;
19918 for ( ; g >= g0; g--)
19919 g[move_by] = *g;
19920 while (from >= end)
19921 *to-- = *from--;
19922 it->glyph_row->used[TEXT_AREA] += move_by;
19927 /* Compute the hash code for ROW. */
19928 unsigned
19929 row_hash (struct glyph_row *row)
19931 int area, k;
19932 unsigned hashval = 0;
19934 for (area = LEFT_MARGIN_AREA; area < LAST_AREA; ++area)
19935 for (k = 0; k < row->used[area]; ++k)
19936 hashval = ((((hashval << 4) + (hashval >> 24)) & 0x0fffffff)
19937 + row->glyphs[area][k].u.val
19938 + row->glyphs[area][k].face_id
19939 + row->glyphs[area][k].padding_p
19940 + (row->glyphs[area][k].type << 2));
19942 return hashval;
19945 /* Compute the pixel height and width of IT->glyph_row.
19947 Most of the time, ascent and height of a display line will be equal
19948 to the max_ascent and max_height values of the display iterator
19949 structure. This is not the case if
19951 1. We hit ZV without displaying anything. In this case, max_ascent
19952 and max_height will be zero.
19954 2. We have some glyphs that don't contribute to the line height.
19955 (The glyph row flag contributes_to_line_height_p is for future
19956 pixmap extensions).
19958 The first case is easily covered by using default values because in
19959 these cases, the line height does not really matter, except that it
19960 must not be zero. */
19962 static void
19963 compute_line_metrics (struct it *it)
19965 struct glyph_row *row = it->glyph_row;
19967 if (FRAME_WINDOW_P (it->f))
19969 int i, min_y, max_y;
19971 /* The line may consist of one space only, that was added to
19972 place the cursor on it. If so, the row's height hasn't been
19973 computed yet. */
19974 if (row->height == 0)
19976 if (it->max_ascent + it->max_descent == 0)
19977 it->max_descent = it->max_phys_descent = FRAME_LINE_HEIGHT (it->f);
19978 row->ascent = it->max_ascent;
19979 row->height = it->max_ascent + it->max_descent;
19980 row->phys_ascent = it->max_phys_ascent;
19981 row->phys_height = it->max_phys_ascent + it->max_phys_descent;
19982 row->extra_line_spacing = it->max_extra_line_spacing;
19985 /* Compute the width of this line. */
19986 row->pixel_width = row->x;
19987 for (i = 0; i < row->used[TEXT_AREA]; ++i)
19988 row->pixel_width += row->glyphs[TEXT_AREA][i].pixel_width;
19990 eassert (row->pixel_width >= 0);
19991 eassert (row->ascent >= 0 && row->height > 0);
19993 row->overlapping_p = (MATRIX_ROW_OVERLAPS_SUCC_P (row)
19994 || MATRIX_ROW_OVERLAPS_PRED_P (row));
19996 /* If first line's physical ascent is larger than its logical
19997 ascent, use the physical ascent, and make the row taller.
19998 This makes accented characters fully visible. */
19999 if (row == MATRIX_FIRST_TEXT_ROW (it->w->desired_matrix)
20000 && row->phys_ascent > row->ascent)
20002 row->height += row->phys_ascent - row->ascent;
20003 row->ascent = row->phys_ascent;
20006 /* Compute how much of the line is visible. */
20007 row->visible_height = row->height;
20009 min_y = WINDOW_HEADER_LINE_HEIGHT (it->w);
20010 max_y = WINDOW_BOX_HEIGHT_NO_MODE_LINE (it->w);
20012 if (row->y < min_y)
20013 row->visible_height -= min_y - row->y;
20014 if (row->y + row->height > max_y)
20015 row->visible_height -= row->y + row->height - max_y;
20017 else
20019 row->pixel_width = row->used[TEXT_AREA];
20020 if (row->continued_p)
20021 row->pixel_width -= it->continuation_pixel_width;
20022 else if (row->truncated_on_right_p)
20023 row->pixel_width -= it->truncation_pixel_width;
20024 row->ascent = row->phys_ascent = 0;
20025 row->height = row->phys_height = row->visible_height = 1;
20026 row->extra_line_spacing = 0;
20029 /* Compute a hash code for this row. */
20030 row->hash = row_hash (row);
20032 it->max_ascent = it->max_descent = 0;
20033 it->max_phys_ascent = it->max_phys_descent = 0;
20037 /* Append one space to the glyph row of iterator IT if doing a
20038 window-based redisplay. The space has the same face as
20039 IT->face_id. Value is true if a space was added.
20041 This function is called to make sure that there is always one glyph
20042 at the end of a glyph row that the cursor can be set on under
20043 window-systems. (If there weren't such a glyph we would not know
20044 how wide and tall a box cursor should be displayed).
20046 At the same time this space let's a nicely handle clearing to the
20047 end of the line if the row ends in italic text. */
20049 static bool
20050 append_space_for_newline (struct it *it, bool default_face_p)
20052 if (FRAME_WINDOW_P (it->f))
20054 int n = it->glyph_row->used[TEXT_AREA];
20056 if (it->glyph_row->glyphs[TEXT_AREA] + n
20057 < it->glyph_row->glyphs[1 + TEXT_AREA])
20059 /* Save some values that must not be changed.
20060 Must save IT->c and IT->len because otherwise
20061 ITERATOR_AT_END_P wouldn't work anymore after
20062 append_space_for_newline has been called. */
20063 enum display_element_type saved_what = it->what;
20064 int saved_c = it->c, saved_len = it->len;
20065 int saved_char_to_display = it->char_to_display;
20066 int saved_x = it->current_x;
20067 int saved_face_id = it->face_id;
20068 bool saved_box_end = it->end_of_box_run_p;
20069 struct text_pos saved_pos;
20070 Lisp_Object saved_object;
20071 struct face *face;
20073 saved_object = it->object;
20074 saved_pos = it->position;
20076 it->what = IT_CHARACTER;
20077 memset (&it->position, 0, sizeof it->position);
20078 it->object = Qnil;
20079 it->c = it->char_to_display = ' ';
20080 it->len = 1;
20082 /* If the default face was remapped, be sure to use the
20083 remapped face for the appended newline. */
20084 if (default_face_p)
20085 it->face_id = lookup_basic_face (it->f, DEFAULT_FACE_ID);
20086 else if (it->face_before_selective_p)
20087 it->face_id = it->saved_face_id;
20088 face = FACE_FROM_ID (it->f, it->face_id);
20089 it->face_id = FACE_FOR_CHAR (it->f, face, 0, -1, Qnil);
20090 /* In R2L rows, we will prepend a stretch glyph that will
20091 have the end_of_box_run_p flag set for it, so there's no
20092 need for the appended newline glyph to have that flag
20093 set. */
20094 if (it->glyph_row->reversed_p
20095 /* But if the appended newline glyph goes all the way to
20096 the end of the row, there will be no stretch glyph,
20097 so leave the box flag set. */
20098 && saved_x + FRAME_COLUMN_WIDTH (it->f) < it->last_visible_x)
20099 it->end_of_box_run_p = false;
20101 PRODUCE_GLYPHS (it);
20103 #ifdef HAVE_WINDOW_SYSTEM
20104 /* Make sure this space glyph has the right ascent and
20105 descent values, or else cursor at end of line will look
20106 funny, and height of empty lines will be incorrect. */
20107 struct glyph *g = it->glyph_row->glyphs[TEXT_AREA] + n;
20108 struct font *font = face->font ? face->font : FRAME_FONT (it->f);
20109 if (n == 0)
20111 Lisp_Object height, total_height;
20112 int extra_line_spacing = it->extra_line_spacing;
20113 int boff = font->baseline_offset;
20115 if (font->vertical_centering)
20116 boff = VCENTER_BASELINE_OFFSET (font, it->f) - boff;
20118 it->object = saved_object; /* get_it_property needs this */
20119 normal_char_ascent_descent (font, -1, &it->ascent, &it->descent);
20120 /* Must do a subset of line height processing from
20121 x_produce_glyph for newline characters. */
20122 height = get_it_property (it, Qline_height);
20123 if (CONSP (height)
20124 && CONSP (XCDR (height))
20125 && NILP (XCDR (XCDR (height))))
20127 total_height = XCAR (XCDR (height));
20128 height = XCAR (height);
20130 else
20131 total_height = Qnil;
20132 height = calc_line_height_property (it, height, font, boff, true);
20134 if (it->override_ascent >= 0)
20136 it->ascent = it->override_ascent;
20137 it->descent = it->override_descent;
20138 boff = it->override_boff;
20140 if (EQ (height, Qt))
20141 extra_line_spacing = 0;
20142 else
20144 Lisp_Object spacing;
20146 it->phys_ascent = it->ascent;
20147 it->phys_descent = it->descent;
20148 if (!NILP (height)
20149 && XINT (height) > it->ascent + it->descent)
20150 it->ascent = XINT (height) - it->descent;
20152 if (!NILP (total_height))
20153 spacing = calc_line_height_property (it, total_height, font,
20154 boff, false);
20155 else
20157 spacing = get_it_property (it, Qline_spacing);
20158 spacing = calc_line_height_property (it, spacing, font,
20159 boff, false);
20161 if (INTEGERP (spacing))
20163 extra_line_spacing = XINT (spacing);
20164 if (!NILP (total_height))
20165 extra_line_spacing -= (it->phys_ascent + it->phys_descent);
20168 if (extra_line_spacing > 0)
20170 it->descent += extra_line_spacing;
20171 if (extra_line_spacing > it->max_extra_line_spacing)
20172 it->max_extra_line_spacing = extra_line_spacing;
20174 it->max_ascent = it->ascent;
20175 it->max_descent = it->descent;
20176 /* Make sure compute_line_metrics recomputes the row height. */
20177 it->glyph_row->height = 0;
20180 g->ascent = it->max_ascent;
20181 g->descent = it->max_descent;
20182 #endif
20184 it->override_ascent = -1;
20185 it->constrain_row_ascent_descent_p = false;
20186 it->current_x = saved_x;
20187 it->object = saved_object;
20188 it->position = saved_pos;
20189 it->what = saved_what;
20190 it->face_id = saved_face_id;
20191 it->len = saved_len;
20192 it->c = saved_c;
20193 it->char_to_display = saved_char_to_display;
20194 it->end_of_box_run_p = saved_box_end;
20195 return true;
20199 return false;
20203 /* Extend the face of the last glyph in the text area of IT->glyph_row
20204 to the end of the display line. Called from display_line. If the
20205 glyph row is empty, add a space glyph to it so that we know the
20206 face to draw. Set the glyph row flag fill_line_p. If the glyph
20207 row is R2L, prepend a stretch glyph to cover the empty space to the
20208 left of the leftmost glyph. */
20210 static void
20211 extend_face_to_end_of_line (struct it *it)
20213 struct face *face, *default_face;
20214 struct frame *f = it->f;
20216 /* If line is already filled, do nothing. Non window-system frames
20217 get a grace of one more ``pixel'' because their characters are
20218 1-``pixel'' wide, so they hit the equality too early. This grace
20219 is needed only for R2L rows that are not continued, to produce
20220 one extra blank where we could display the cursor. */
20221 if ((it->current_x >= it->last_visible_x
20222 + (!FRAME_WINDOW_P (f)
20223 && it->glyph_row->reversed_p
20224 && !it->glyph_row->continued_p))
20225 /* If the window has display margins, we will need to extend
20226 their face even if the text area is filled. */
20227 && !(WINDOW_LEFT_MARGIN_WIDTH (it->w) > 0
20228 || WINDOW_RIGHT_MARGIN_WIDTH (it->w) > 0))
20229 return;
20231 /* The default face, possibly remapped. */
20232 default_face = FACE_FROM_ID_OR_NULL (f,
20233 lookup_basic_face (f, DEFAULT_FACE_ID));
20235 /* Face extension extends the background and box of IT->face_id
20236 to the end of the line. If the background equals the background
20237 of the frame, we don't have to do anything. */
20238 face = FACE_FROM_ID (f, (it->face_before_selective_p
20239 ? it->saved_face_id
20240 : it->face_id));
20242 if (FRAME_WINDOW_P (f)
20243 && MATRIX_ROW_DISPLAYS_TEXT_P (it->glyph_row)
20244 && face->box == FACE_NO_BOX
20245 && face->background == FRAME_BACKGROUND_PIXEL (f)
20246 #ifdef HAVE_WINDOW_SYSTEM
20247 && !face->stipple
20248 #endif
20249 && !it->glyph_row->reversed_p)
20250 return;
20252 /* Set the glyph row flag indicating that the face of the last glyph
20253 in the text area has to be drawn to the end of the text area. */
20254 it->glyph_row->fill_line_p = true;
20256 /* If current character of IT is not ASCII, make sure we have the
20257 ASCII face. This will be automatically undone the next time
20258 get_next_display_element returns a multibyte character. Note
20259 that the character will always be single byte in unibyte
20260 text. */
20261 if (!ASCII_CHAR_P (it->c))
20263 it->face_id = FACE_FOR_CHAR (f, face, 0, -1, Qnil);
20266 if (FRAME_WINDOW_P (f))
20268 /* If the row is empty, add a space with the current face of IT,
20269 so that we know which face to draw. */
20270 if (it->glyph_row->used[TEXT_AREA] == 0)
20272 it->glyph_row->glyphs[TEXT_AREA][0] = space_glyph;
20273 it->glyph_row->glyphs[TEXT_AREA][0].face_id = face->id;
20274 it->glyph_row->used[TEXT_AREA] = 1;
20276 /* Mode line and the header line don't have margins, and
20277 likewise the frame's tool-bar window, if there is any. */
20278 if (!(it->glyph_row->mode_line_p
20279 #if defined (HAVE_WINDOW_SYSTEM) && ! defined (USE_GTK) && ! defined (HAVE_NS)
20280 || (WINDOWP (f->tool_bar_window)
20281 && it->w == XWINDOW (f->tool_bar_window))
20282 #endif
20285 if (WINDOW_LEFT_MARGIN_WIDTH (it->w) > 0
20286 && it->glyph_row->used[LEFT_MARGIN_AREA] == 0)
20288 it->glyph_row->glyphs[LEFT_MARGIN_AREA][0] = space_glyph;
20289 it->glyph_row->glyphs[LEFT_MARGIN_AREA][0].face_id =
20290 default_face->id;
20291 it->glyph_row->used[LEFT_MARGIN_AREA] = 1;
20293 if (WINDOW_RIGHT_MARGIN_WIDTH (it->w) > 0
20294 && it->glyph_row->used[RIGHT_MARGIN_AREA] == 0)
20296 it->glyph_row->glyphs[RIGHT_MARGIN_AREA][0] = space_glyph;
20297 it->glyph_row->glyphs[RIGHT_MARGIN_AREA][0].face_id =
20298 default_face->id;
20299 it->glyph_row->used[RIGHT_MARGIN_AREA] = 1;
20302 #ifdef HAVE_WINDOW_SYSTEM
20303 if (it->glyph_row->reversed_p)
20305 /* Prepend a stretch glyph to the row, such that the
20306 rightmost glyph will be drawn flushed all the way to the
20307 right margin of the window. The stretch glyph that will
20308 occupy the empty space, if any, to the left of the
20309 glyphs. */
20310 struct font *font = face->font ? face->font : FRAME_FONT (f);
20311 struct glyph *row_start = it->glyph_row->glyphs[TEXT_AREA];
20312 struct glyph *row_end = row_start + it->glyph_row->used[TEXT_AREA];
20313 struct glyph *g;
20314 int row_width, stretch_ascent, stretch_width;
20315 struct text_pos saved_pos;
20316 int saved_face_id;
20317 bool saved_avoid_cursor, saved_box_start;
20319 for (row_width = 0, g = row_start; g < row_end; g++)
20320 row_width += g->pixel_width;
20322 /* FIXME: There are various minor display glitches in R2L
20323 rows when only one of the fringes is missing. The
20324 strange condition below produces the least bad effect. */
20325 if ((WINDOW_LEFT_FRINGE_WIDTH (it->w) == 0)
20326 == (WINDOW_RIGHT_FRINGE_WIDTH (it->w) == 0)
20327 || WINDOW_RIGHT_FRINGE_WIDTH (it->w) != 0)
20328 stretch_width = window_box_width (it->w, TEXT_AREA);
20329 else
20330 stretch_width = it->last_visible_x - it->first_visible_x;
20331 stretch_width -= row_width;
20333 if (stretch_width > 0)
20335 stretch_ascent =
20336 (((it->ascent + it->descent)
20337 * FONT_BASE (font)) / FONT_HEIGHT (font));
20338 saved_pos = it->position;
20339 memset (&it->position, 0, sizeof it->position);
20340 saved_avoid_cursor = it->avoid_cursor_p;
20341 it->avoid_cursor_p = true;
20342 saved_face_id = it->face_id;
20343 saved_box_start = it->start_of_box_run_p;
20344 /* The last row's stretch glyph should get the default
20345 face, to avoid painting the rest of the window with
20346 the region face, if the region ends at ZV. */
20347 if (it->glyph_row->ends_at_zv_p)
20348 it->face_id = default_face->id;
20349 else
20350 it->face_id = face->id;
20351 it->start_of_box_run_p = false;
20352 append_stretch_glyph (it, Qnil, stretch_width,
20353 it->ascent + it->descent, stretch_ascent);
20354 it->position = saved_pos;
20355 it->avoid_cursor_p = saved_avoid_cursor;
20356 it->face_id = saved_face_id;
20357 it->start_of_box_run_p = saved_box_start;
20359 /* If stretch_width comes out negative, it means that the
20360 last glyph is only partially visible. In R2L rows, we
20361 want the leftmost glyph to be partially visible, so we
20362 need to give the row the corresponding left offset. */
20363 if (stretch_width < 0)
20364 it->glyph_row->x = stretch_width;
20366 #endif /* HAVE_WINDOW_SYSTEM */
20368 else
20370 /* Save some values that must not be changed. */
20371 int saved_x = it->current_x;
20372 struct text_pos saved_pos;
20373 Lisp_Object saved_object;
20374 enum display_element_type saved_what = it->what;
20375 int saved_face_id = it->face_id;
20377 saved_object = it->object;
20378 saved_pos = it->position;
20380 it->what = IT_CHARACTER;
20381 memset (&it->position, 0, sizeof it->position);
20382 it->object = Qnil;
20383 it->c = it->char_to_display = ' ';
20384 it->len = 1;
20386 if (WINDOW_LEFT_MARGIN_WIDTH (it->w) > 0
20387 && (it->glyph_row->used[LEFT_MARGIN_AREA]
20388 < WINDOW_LEFT_MARGIN_WIDTH (it->w))
20389 && !it->glyph_row->mode_line_p
20390 && default_face->background != FRAME_BACKGROUND_PIXEL (f))
20392 struct glyph *g = it->glyph_row->glyphs[LEFT_MARGIN_AREA];
20393 struct glyph *e = g + it->glyph_row->used[LEFT_MARGIN_AREA];
20395 for (it->current_x = 0; g < e; g++)
20396 it->current_x += g->pixel_width;
20398 it->area = LEFT_MARGIN_AREA;
20399 it->face_id = default_face->id;
20400 while (it->glyph_row->used[LEFT_MARGIN_AREA]
20401 < WINDOW_LEFT_MARGIN_WIDTH (it->w)
20402 && g < it->glyph_row->glyphs[TEXT_AREA])
20404 PRODUCE_GLYPHS (it);
20405 /* term.c:produce_glyphs advances it->current_x only for
20406 TEXT_AREA. */
20407 it->current_x += it->pixel_width;
20408 g++;
20411 it->current_x = saved_x;
20412 it->area = TEXT_AREA;
20415 /* The last row's blank glyphs should get the default face, to
20416 avoid painting the rest of the window with the region face,
20417 if the region ends at ZV. */
20418 if (it->glyph_row->ends_at_zv_p)
20419 it->face_id = default_face->id;
20420 else
20421 it->face_id = face->id;
20422 PRODUCE_GLYPHS (it);
20424 while (it->current_x <= it->last_visible_x)
20425 PRODUCE_GLYPHS (it);
20427 if (WINDOW_RIGHT_MARGIN_WIDTH (it->w) > 0
20428 && (it->glyph_row->used[RIGHT_MARGIN_AREA]
20429 < WINDOW_RIGHT_MARGIN_WIDTH (it->w))
20430 && !it->glyph_row->mode_line_p
20431 && default_face->background != FRAME_BACKGROUND_PIXEL (f))
20433 struct glyph *g = it->glyph_row->glyphs[RIGHT_MARGIN_AREA];
20434 struct glyph *e = g + it->glyph_row->used[RIGHT_MARGIN_AREA];
20436 for ( ; g < e; g++)
20437 it->current_x += g->pixel_width;
20439 it->area = RIGHT_MARGIN_AREA;
20440 it->face_id = default_face->id;
20441 while (it->glyph_row->used[RIGHT_MARGIN_AREA]
20442 < WINDOW_RIGHT_MARGIN_WIDTH (it->w)
20443 && g < it->glyph_row->glyphs[LAST_AREA])
20445 PRODUCE_GLYPHS (it);
20446 it->current_x += it->pixel_width;
20447 g++;
20450 it->area = TEXT_AREA;
20453 /* Don't count these blanks really. It would let us insert a left
20454 truncation glyph below and make us set the cursor on them, maybe. */
20455 it->current_x = saved_x;
20456 it->object = saved_object;
20457 it->position = saved_pos;
20458 it->what = saved_what;
20459 it->face_id = saved_face_id;
20464 /* Value is true if text starting at CHARPOS in current_buffer is
20465 trailing whitespace. */
20467 static bool
20468 trailing_whitespace_p (ptrdiff_t charpos)
20470 ptrdiff_t bytepos = CHAR_TO_BYTE (charpos);
20471 int c = 0;
20473 while (bytepos < ZV_BYTE
20474 && (c = FETCH_CHAR (bytepos),
20475 c == ' ' || c == '\t'))
20476 ++bytepos;
20478 if (bytepos >= ZV_BYTE || c == '\n' || c == '\r')
20480 if (bytepos != PT_BYTE)
20481 return true;
20483 return false;
20487 /* Highlight trailing whitespace, if any, in ROW. */
20489 static void
20490 highlight_trailing_whitespace (struct frame *f, struct glyph_row *row)
20492 int used = row->used[TEXT_AREA];
20494 if (used)
20496 struct glyph *start = row->glyphs[TEXT_AREA];
20497 struct glyph *glyph = start + used - 1;
20499 if (row->reversed_p)
20501 /* Right-to-left rows need to be processed in the opposite
20502 direction, so swap the edge pointers. */
20503 glyph = start;
20504 start = row->glyphs[TEXT_AREA] + used - 1;
20507 /* Skip over glyphs inserted to display the cursor at the
20508 end of a line, for extending the face of the last glyph
20509 to the end of the line on terminals, and for truncation
20510 and continuation glyphs. */
20511 if (!row->reversed_p)
20513 while (glyph >= start
20514 && glyph->type == CHAR_GLYPH
20515 && NILP (glyph->object))
20516 --glyph;
20518 else
20520 while (glyph <= start
20521 && glyph->type == CHAR_GLYPH
20522 && NILP (glyph->object))
20523 ++glyph;
20526 /* If last glyph is a space or stretch, and it's trailing
20527 whitespace, set the face of all trailing whitespace glyphs in
20528 IT->glyph_row to `trailing-whitespace'. */
20529 if ((row->reversed_p ? glyph <= start : glyph >= start)
20530 && BUFFERP (glyph->object)
20531 && (glyph->type == STRETCH_GLYPH
20532 || (glyph->type == CHAR_GLYPH
20533 && glyph->u.ch == ' '))
20534 && trailing_whitespace_p (glyph->charpos))
20536 int face_id = lookup_named_face (f, Qtrailing_whitespace, false);
20537 if (face_id < 0)
20538 return;
20540 if (!row->reversed_p)
20542 while (glyph >= start
20543 && BUFFERP (glyph->object)
20544 && (glyph->type == STRETCH_GLYPH
20545 || (glyph->type == CHAR_GLYPH
20546 && glyph->u.ch == ' ')))
20547 (glyph--)->face_id = face_id;
20549 else
20551 while (glyph <= start
20552 && BUFFERP (glyph->object)
20553 && (glyph->type == STRETCH_GLYPH
20554 || (glyph->type == CHAR_GLYPH
20555 && glyph->u.ch == ' ')))
20556 (glyph++)->face_id = face_id;
20563 /* Value is true if glyph row ROW should be
20564 considered to hold the buffer position CHARPOS. */
20566 static bool
20567 row_for_charpos_p (struct glyph_row *row, ptrdiff_t charpos)
20569 bool result = true;
20571 if (charpos == CHARPOS (row->end.pos)
20572 || charpos == MATRIX_ROW_END_CHARPOS (row))
20574 /* Suppose the row ends on a string.
20575 Unless the row is continued, that means it ends on a newline
20576 in the string. If it's anything other than a display string
20577 (e.g., a before-string from an overlay), we don't want the
20578 cursor there. (This heuristic seems to give the optimal
20579 behavior for the various types of multi-line strings.)
20580 One exception: if the string has `cursor' property on one of
20581 its characters, we _do_ want the cursor there. */
20582 if (CHARPOS (row->end.string_pos) >= 0)
20584 if (row->continued_p)
20585 result = true;
20586 else
20588 /* Check for `display' property. */
20589 struct glyph *beg = row->glyphs[TEXT_AREA];
20590 struct glyph *end = beg + row->used[TEXT_AREA] - 1;
20591 struct glyph *glyph;
20593 result = false;
20594 for (glyph = end; glyph >= beg; --glyph)
20595 if (STRINGP (glyph->object))
20597 Lisp_Object prop
20598 = Fget_char_property (make_number (charpos),
20599 Qdisplay, Qnil);
20600 result =
20601 (!NILP (prop)
20602 && display_prop_string_p (prop, glyph->object));
20603 /* If there's a `cursor' property on one of the
20604 string's characters, this row is a cursor row,
20605 even though this is not a display string. */
20606 if (!result)
20608 Lisp_Object s = glyph->object;
20610 for ( ; glyph >= beg && EQ (glyph->object, s); --glyph)
20612 ptrdiff_t gpos = glyph->charpos;
20614 if (!NILP (Fget_char_property (make_number (gpos),
20615 Qcursor, s)))
20617 result = true;
20618 break;
20622 break;
20626 else if (MATRIX_ROW_ENDS_IN_MIDDLE_OF_CHAR_P (row))
20628 /* If the row ends in middle of a real character,
20629 and the line is continued, we want the cursor here.
20630 That's because CHARPOS (ROW->end.pos) would equal
20631 PT if PT is before the character. */
20632 if (!row->ends_in_ellipsis_p)
20633 result = row->continued_p;
20634 else
20635 /* If the row ends in an ellipsis, then
20636 CHARPOS (ROW->end.pos) will equal point after the
20637 invisible text. We want that position to be displayed
20638 after the ellipsis. */
20639 result = false;
20641 /* If the row ends at ZV, display the cursor at the end of that
20642 row instead of at the start of the row below. */
20643 else
20644 result = row->ends_at_zv_p;
20647 return result;
20650 /* Value is true if glyph row ROW should be
20651 used to hold the cursor. */
20653 static bool
20654 cursor_row_p (struct glyph_row *row)
20656 return row_for_charpos_p (row, PT);
20661 /* Push the property PROP so that it will be rendered at the current
20662 position in IT. Return true if PROP was successfully pushed, false
20663 otherwise. Called from handle_line_prefix to handle the
20664 `line-prefix' and `wrap-prefix' properties. */
20666 static bool
20667 push_prefix_prop (struct it *it, Lisp_Object prop)
20669 struct text_pos pos =
20670 STRINGP (it->string) ? it->current.string_pos : it->current.pos;
20672 eassert (it->method == GET_FROM_BUFFER
20673 || it->method == GET_FROM_DISPLAY_VECTOR
20674 || it->method == GET_FROM_STRING
20675 || it->method == GET_FROM_IMAGE);
20677 /* We need to save the current buffer/string position, so it will be
20678 restored by pop_it, because iterate_out_of_display_property
20679 depends on that being set correctly, but some situations leave
20680 it->position not yet set when this function is called. */
20681 push_it (it, &pos);
20683 if (STRINGP (prop))
20685 if (SCHARS (prop) == 0)
20687 pop_it (it);
20688 return false;
20691 it->string = prop;
20692 it->string_from_prefix_prop_p = true;
20693 it->multibyte_p = STRING_MULTIBYTE (it->string);
20694 it->current.overlay_string_index = -1;
20695 IT_STRING_CHARPOS (*it) = IT_STRING_BYTEPOS (*it) = 0;
20696 it->end_charpos = it->string_nchars = SCHARS (it->string);
20697 it->method = GET_FROM_STRING;
20698 it->stop_charpos = 0;
20699 it->prev_stop = 0;
20700 it->base_level_stop = 0;
20701 it->cmp_it.id = -1;
20703 /* Force paragraph direction to be that of the parent
20704 buffer/string. */
20705 if (it->bidi_p && it->bidi_it.paragraph_dir == R2L)
20706 it->paragraph_embedding = it->bidi_it.paragraph_dir;
20707 else
20708 it->paragraph_embedding = L2R;
20710 /* Set up the bidi iterator for this display string. */
20711 if (it->bidi_p)
20713 it->bidi_it.string.lstring = it->string;
20714 it->bidi_it.string.s = NULL;
20715 it->bidi_it.string.schars = it->end_charpos;
20716 it->bidi_it.string.bufpos = IT_CHARPOS (*it);
20717 it->bidi_it.string.from_disp_str = it->string_from_display_prop_p;
20718 it->bidi_it.string.unibyte = !it->multibyte_p;
20719 it->bidi_it.w = it->w;
20720 bidi_init_it (0, 0, FRAME_WINDOW_P (it->f), &it->bidi_it);
20723 else if (CONSP (prop) && EQ (XCAR (prop), Qspace))
20725 it->method = GET_FROM_STRETCH;
20726 it->object = prop;
20728 #ifdef HAVE_WINDOW_SYSTEM
20729 else if (IMAGEP (prop))
20731 it->what = IT_IMAGE;
20732 it->image_id = lookup_image (it->f, prop);
20733 it->method = GET_FROM_IMAGE;
20735 #endif /* HAVE_WINDOW_SYSTEM */
20736 else
20738 pop_it (it); /* bogus display property, give up */
20739 return false;
20742 return true;
20745 /* Return the character-property PROP at the current position in IT. */
20747 static Lisp_Object
20748 get_it_property (struct it *it, Lisp_Object prop)
20750 Lisp_Object position, object = it->object;
20752 if (STRINGP (object))
20753 position = make_number (IT_STRING_CHARPOS (*it));
20754 else if (BUFFERP (object))
20756 position = make_number (IT_CHARPOS (*it));
20757 object = it->window;
20759 else
20760 return Qnil;
20762 return Fget_char_property (position, prop, object);
20765 /* See if there's a line- or wrap-prefix, and if so, push it on IT. */
20767 static void
20768 handle_line_prefix (struct it *it)
20770 Lisp_Object prefix;
20772 if (it->continuation_lines_width > 0)
20774 prefix = get_it_property (it, Qwrap_prefix);
20775 if (NILP (prefix))
20776 prefix = Vwrap_prefix;
20778 else
20780 prefix = get_it_property (it, Qline_prefix);
20781 if (NILP (prefix))
20782 prefix = Vline_prefix;
20784 if (! NILP (prefix) && push_prefix_prop (it, prefix))
20786 /* If the prefix is wider than the window, and we try to wrap
20787 it, it would acquire its own wrap prefix, and so on till the
20788 iterator stack overflows. So, don't wrap the prefix. */
20789 it->line_wrap = TRUNCATE;
20790 it->avoid_cursor_p = true;
20796 /* Remove N glyphs at the start of a reversed IT->glyph_row. Called
20797 only for R2L lines from display_line and display_string, when they
20798 decide that too many glyphs were produced by PRODUCE_GLYPHS, and
20799 the line/string needs to be continued on the next glyph row. */
20800 static void
20801 unproduce_glyphs (struct it *it, int n)
20803 struct glyph *glyph, *end;
20805 eassert (it->glyph_row);
20806 eassert (it->glyph_row->reversed_p);
20807 eassert (it->area == TEXT_AREA);
20808 eassert (n <= it->glyph_row->used[TEXT_AREA]);
20810 if (n > it->glyph_row->used[TEXT_AREA])
20811 n = it->glyph_row->used[TEXT_AREA];
20812 glyph = it->glyph_row->glyphs[TEXT_AREA] + n;
20813 end = it->glyph_row->glyphs[TEXT_AREA] + it->glyph_row->used[TEXT_AREA];
20814 for ( ; glyph < end; glyph++)
20815 glyph[-n] = *glyph;
20818 /* Find the positions in a bidi-reordered ROW to serve as ROW->minpos
20819 and ROW->maxpos. */
20820 static void
20821 find_row_edges (struct it *it, struct glyph_row *row,
20822 ptrdiff_t min_pos, ptrdiff_t min_bpos,
20823 ptrdiff_t max_pos, ptrdiff_t max_bpos)
20825 /* FIXME: Revisit this when glyph ``spilling'' in continuation
20826 lines' rows is implemented for bidi-reordered rows. */
20828 /* ROW->minpos is the value of min_pos, the minimal buffer position
20829 we have in ROW, or ROW->start.pos if that is smaller. */
20830 if (min_pos <= ZV && min_pos < row->start.pos.charpos)
20831 SET_TEXT_POS (row->minpos, min_pos, min_bpos);
20832 else
20833 /* We didn't find buffer positions smaller than ROW->start, or
20834 didn't find _any_ valid buffer positions in any of the glyphs,
20835 so we must trust the iterator's computed positions. */
20836 row->minpos = row->start.pos;
20837 if (max_pos <= 0)
20839 max_pos = CHARPOS (it->current.pos);
20840 max_bpos = BYTEPOS (it->current.pos);
20843 /* Here are the various use-cases for ending the row, and the
20844 corresponding values for ROW->maxpos:
20846 Line ends in a newline from buffer eol_pos + 1
20847 Line is continued from buffer max_pos + 1
20848 Line is truncated on right it->current.pos
20849 Line ends in a newline from string max_pos + 1(*)
20850 (*) + 1 only when line ends in a forward scan
20851 Line is continued from string max_pos
20852 Line is continued from display vector max_pos
20853 Line is entirely from a string min_pos == max_pos
20854 Line is entirely from a display vector min_pos == max_pos
20855 Line that ends at ZV ZV
20857 If you discover other use-cases, please add them here as
20858 appropriate. */
20859 if (row->ends_at_zv_p)
20860 row->maxpos = it->current.pos;
20861 else if (row->used[TEXT_AREA])
20863 bool seen_this_string = false;
20864 struct glyph_row *r1 = row - 1;
20866 /* Did we see the same display string on the previous row? */
20867 if (STRINGP (it->object)
20868 /* this is not the first row */
20869 && row > it->w->desired_matrix->rows
20870 /* previous row is not the header line */
20871 && !r1->mode_line_p
20872 /* previous row also ends in a newline from a string */
20873 && r1->ends_in_newline_from_string_p)
20875 struct glyph *start, *end;
20877 /* Search for the last glyph of the previous row that came
20878 from buffer or string. Depending on whether the row is
20879 L2R or R2L, we need to process it front to back or the
20880 other way round. */
20881 if (!r1->reversed_p)
20883 start = r1->glyphs[TEXT_AREA];
20884 end = start + r1->used[TEXT_AREA];
20885 /* Glyphs inserted by redisplay have nil as their object. */
20886 while (end > start
20887 && NILP ((end - 1)->object)
20888 && (end - 1)->charpos <= 0)
20889 --end;
20890 if (end > start)
20892 if (EQ ((end - 1)->object, it->object))
20893 seen_this_string = true;
20895 else
20896 /* If all the glyphs of the previous row were inserted
20897 by redisplay, it means the previous row was
20898 produced from a single newline, which is only
20899 possible if that newline came from the same string
20900 as the one which produced this ROW. */
20901 seen_this_string = true;
20903 else
20905 end = r1->glyphs[TEXT_AREA] - 1;
20906 start = end + r1->used[TEXT_AREA];
20907 while (end < start
20908 && NILP ((end + 1)->object)
20909 && (end + 1)->charpos <= 0)
20910 ++end;
20911 if (end < start)
20913 if (EQ ((end + 1)->object, it->object))
20914 seen_this_string = true;
20916 else
20917 seen_this_string = true;
20920 /* Take note of each display string that covers a newline only
20921 once, the first time we see it. This is for when a display
20922 string includes more than one newline in it. */
20923 if (row->ends_in_newline_from_string_p && !seen_this_string)
20925 /* If we were scanning the buffer forward when we displayed
20926 the string, we want to account for at least one buffer
20927 position that belongs to this row (position covered by
20928 the display string), so that cursor positioning will
20929 consider this row as a candidate when point is at the end
20930 of the visual line represented by this row. This is not
20931 required when scanning back, because max_pos will already
20932 have a much larger value. */
20933 if (CHARPOS (row->end.pos) > max_pos)
20934 INC_BOTH (max_pos, max_bpos);
20935 SET_TEXT_POS (row->maxpos, max_pos, max_bpos);
20937 else if (CHARPOS (it->eol_pos) > 0)
20938 SET_TEXT_POS (row->maxpos,
20939 CHARPOS (it->eol_pos) + 1, BYTEPOS (it->eol_pos) + 1);
20940 else if (row->continued_p)
20942 /* If max_pos is different from IT's current position, it
20943 means IT->method does not belong to the display element
20944 at max_pos. However, it also means that the display
20945 element at max_pos was displayed in its entirety on this
20946 line, which is equivalent to saying that the next line
20947 starts at the next buffer position. */
20948 if (IT_CHARPOS (*it) == max_pos && it->method != GET_FROM_BUFFER)
20949 SET_TEXT_POS (row->maxpos, max_pos, max_bpos);
20950 else
20952 INC_BOTH (max_pos, max_bpos);
20953 SET_TEXT_POS (row->maxpos, max_pos, max_bpos);
20956 else if (row->truncated_on_right_p)
20957 /* display_line already called reseat_at_next_visible_line_start,
20958 which puts the iterator at the beginning of the next line, in
20959 the logical order. */
20960 row->maxpos = it->current.pos;
20961 else if (max_pos == min_pos && it->method != GET_FROM_BUFFER)
20962 /* A line that is entirely from a string/image/stretch... */
20963 row->maxpos = row->minpos;
20964 else
20965 emacs_abort ();
20967 else
20968 row->maxpos = it->current.pos;
20971 /* Like display_count_lines, but capable of counting outside of the
20972 current narrowed region. */
20973 static ptrdiff_t
20974 display_count_lines_logically (ptrdiff_t start_byte, ptrdiff_t limit_byte,
20975 ptrdiff_t count, ptrdiff_t *byte_pos_ptr)
20977 if (!display_line_numbers_widen || (BEGV == BEG && ZV == Z))
20978 return display_count_lines (start_byte, limit_byte, count, byte_pos_ptr);
20980 ptrdiff_t val;
20981 ptrdiff_t pdl_count = SPECPDL_INDEX ();
20982 record_unwind_protect (save_restriction_restore, save_restriction_save ());
20983 Fwiden ();
20984 val = display_count_lines (start_byte, limit_byte, count, byte_pos_ptr);
20985 unbind_to (pdl_count, Qnil);
20986 return val;
20989 /* Count the number of screen lines in window IT->w between character
20990 position IT_CHARPOS(*IT) and the line showing that window's point. */
20991 static ptrdiff_t
20992 display_count_lines_visually (struct it *it)
20994 struct it tem_it;
20995 ptrdiff_t to;
20996 struct text_pos from;
20998 /* If we already calculated a relative line number, use that. This
20999 trick relies on the fact that visual lines (a.k.a. "glyph rows")
21000 are laid out sequentially, one by one, for each sequence of calls
21001 to display_line or other similar function that follows a call to
21002 init_iterator. */
21003 if (it->lnum_bytepos > 0)
21004 return it->lnum + 1;
21005 else
21007 ptrdiff_t count = SPECPDL_INDEX ();
21009 if (IT_CHARPOS (*it) <= PT)
21011 from = it->current.pos;
21012 to = PT;
21014 else
21016 SET_TEXT_POS (from, PT, PT_BYTE);
21017 to = IT_CHARPOS (*it);
21019 start_display (&tem_it, it->w, from);
21020 /* Need to disable visual mode temporarily, since otherwise the
21021 call to move_it_to will cause infinite recursion. */
21022 specbind (Qdisplay_line_numbers, Qrelative);
21023 /* Some redisplay optimizations could invoke us very far from
21024 PT, which will make the caller painfully slow. There should
21025 be no need to go too far beyond the window's bottom, as any
21026 such optimization will fail to show point anyway. */
21027 move_it_to (&tem_it, to, -1,
21028 tem_it.last_visible_y
21029 + (SCROLL_LIMIT + 10) * FRAME_LINE_HEIGHT (tem_it.f),
21030 -1, MOVE_TO_POS | MOVE_TO_Y);
21031 unbind_to (count, Qnil);
21032 return IT_CHARPOS (*it) <= PT ? -tem_it.vpos : tem_it.vpos;
21036 /* Produce the line-number glyphs for the current glyph_row. If
21037 IT->glyph_row is non-NULL, populate the row with the produced
21038 glyphs. */
21039 static void
21040 maybe_produce_line_number (struct it *it)
21042 ptrdiff_t last_line = it->lnum;
21043 ptrdiff_t start_from, bytepos;
21044 ptrdiff_t this_line;
21045 bool first_time = false;
21046 ptrdiff_t beg_byte = display_line_numbers_widen ? BEG_BYTE : BEGV_BYTE;
21047 ptrdiff_t z_byte = display_line_numbers_widen ? Z_BYTE : ZV_BYTE;
21048 void *itdata = bidi_shelve_cache ();
21050 if (EQ (Vdisplay_line_numbers, Qvisual))
21051 this_line = display_count_lines_visually (it);
21052 else
21054 if (!last_line)
21056 /* If possible, reuse data cached by line-number-mode. */
21057 if (it->w->base_line_number > 0
21058 && it->w->base_line_pos > 0
21059 && it->w->base_line_pos <= IT_CHARPOS (*it)
21060 /* line-number-mode always displays narrowed line
21061 numbers, so we cannot use its data if the user wants
21062 line numbers that disregard narrowing, or if the
21063 buffer's narrowing has just changed. */
21064 && !(display_line_numbers_widen
21065 && (BEG_BYTE != BEGV_BYTE || Z_BYTE != ZV_BYTE))
21066 && !current_buffer->clip_changed)
21068 start_from = CHAR_TO_BYTE (it->w->base_line_pos);
21069 last_line = it->w->base_line_number - 1;
21071 else
21072 start_from = beg_byte;
21073 if (!it->lnum_bytepos)
21074 first_time = true;
21076 else
21077 start_from = it->lnum_bytepos;
21079 /* Paranoia: what if someone changes the narrowing since the
21080 last time display_line was called? Shouldn't really happen,
21081 but who knows what some crazy Lisp invoked by :eval could do? */
21082 if (!(beg_byte <= start_from && start_from <= z_byte))
21084 last_line = 0;
21085 start_from = beg_byte;
21088 this_line =
21089 last_line + display_count_lines_logically (start_from,
21090 IT_BYTEPOS (*it),
21091 IT_CHARPOS (*it), &bytepos);
21092 eassert (this_line > 0 || (this_line == 0 && start_from == beg_byte));
21093 eassert (bytepos == IT_BYTEPOS (*it));
21096 /* Record the line number information. */
21097 if (this_line != last_line || !it->lnum_bytepos)
21099 it->lnum = this_line;
21100 it->lnum_bytepos = IT_BYTEPOS (*it);
21103 /* Produce the glyphs for the line number. */
21104 struct it tem_it;
21105 char lnum_buf[INT_STRLEN_BOUND (ptrdiff_t) + 1];
21106 bool beyond_zv = IT_BYTEPOS (*it) >= ZV_BYTE ? true : false;
21107 ptrdiff_t lnum_offset = -1; /* to produce 1-based line numbers */
21108 int lnum_face_id = merge_faces (it->f, Qline_number, 0, DEFAULT_FACE_ID);
21109 int current_lnum_face_id
21110 = merge_faces (it->f, Qline_number_current_line, 0, DEFAULT_FACE_ID);
21111 /* Compute point's line number if needed. */
21112 if ((EQ (Vdisplay_line_numbers, Qrelative)
21113 || EQ (Vdisplay_line_numbers, Qvisual)
21114 || lnum_face_id != current_lnum_face_id)
21115 && !it->pt_lnum)
21117 ptrdiff_t ignored;
21118 if (PT_BYTE > it->lnum_bytepos && !EQ (Vdisplay_line_numbers, Qvisual))
21119 it->pt_lnum =
21120 this_line + display_count_lines_logically (it->lnum_bytepos, PT_BYTE,
21121 PT, &ignored);
21122 else
21123 it->pt_lnum = display_count_lines_logically (beg_byte, PT_BYTE, PT,
21124 &ignored);
21126 /* Compute the required width if needed. */
21127 if (!it->lnum_width)
21129 if (NATNUMP (Vdisplay_line_numbers_width))
21130 it->lnum_width = XFASTINT (Vdisplay_line_numbers_width);
21132 /* Max line number to be displayed cannot be more than the one
21133 corresponding to the last row of the desired matrix. */
21134 ptrdiff_t max_lnum;
21136 if (NILP (Vdisplay_line_numbers_current_absolute)
21137 && (EQ (Vdisplay_line_numbers, Qrelative)
21138 || EQ (Vdisplay_line_numbers, Qvisual)))
21139 /* We subtract one more because the current line is always
21140 zero in this mode. */
21141 max_lnum = it->w->desired_matrix->nrows - 2;
21142 else if (EQ (Vdisplay_line_numbers, Qvisual))
21143 max_lnum = it->pt_lnum + it->w->desired_matrix->nrows - 1;
21144 else
21145 max_lnum = this_line + it->w->desired_matrix->nrows - 1 - it->vpos;
21146 max_lnum = max (1, max_lnum);
21147 it->lnum_width = max (it->lnum_width, log10 (max_lnum) + 1);
21148 eassert (it->lnum_width > 0);
21150 if (EQ (Vdisplay_line_numbers, Qrelative))
21151 lnum_offset = it->pt_lnum;
21152 else if (EQ (Vdisplay_line_numbers, Qvisual))
21153 lnum_offset = 0;
21155 /* Under 'relative', display the absolute line number for the
21156 current line, unless the user requests otherwise. */
21157 ptrdiff_t lnum_to_display = eabs (this_line - lnum_offset);
21158 if ((EQ (Vdisplay_line_numbers, Qrelative)
21159 || EQ (Vdisplay_line_numbers, Qvisual))
21160 && lnum_to_display == 0
21161 && !NILP (Vdisplay_line_numbers_current_absolute))
21162 lnum_to_display = it->pt_lnum + 1;
21163 /* In L2R rows we need to append the blank separator, in R2L
21164 rows we need to prepend it. But this function is usually
21165 called when no display elements were produced from the
21166 following line, so the paragraph direction might be unknown.
21167 Therefore we cheat and add 2 blanks, one on either side. */
21168 pint2str (lnum_buf, it->lnum_width + 1, lnum_to_display);
21169 strcat (lnum_buf, " ");
21171 /* Setup for producing the glyphs. */
21172 init_iterator (&tem_it, it->w, -1, -1, &scratch_glyph_row,
21173 /* FIXME: Use specialized face. */
21174 DEFAULT_FACE_ID);
21175 scratch_glyph_row.reversed_p = false;
21176 scratch_glyph_row.used[TEXT_AREA] = 0;
21177 SET_TEXT_POS (tem_it.position, 0, 0);
21178 tem_it.avoid_cursor_p = true;
21179 tem_it.bidi_p = true;
21180 tem_it.bidi_it.type = WEAK_EN;
21181 /* According to UAX#9, EN goes up 2 levels in L2R paragraph and
21182 1 level in R2L paragraphs. Emulate that, assuming we are in
21183 an L2R paragraph. */
21184 tem_it.bidi_it.resolved_level = 2;
21186 /* Produce glyphs for the line number in a scratch glyph_row. */
21187 int n_glyphs_before;
21188 for (const char *p = lnum_buf; *p; p++)
21190 /* For continuation lines and lines after ZV, instead of a line
21191 number, produce a blank prefix of the same width. Use the
21192 default face for the blank field beyond ZV. */
21193 if (beyond_zv)
21194 tem_it.face_id = it->base_face_id;
21195 else if (lnum_face_id != current_lnum_face_id
21196 && (EQ (Vdisplay_line_numbers, Qvisual)
21197 ? this_line == 0
21198 : this_line == it->pt_lnum))
21199 tem_it.face_id = current_lnum_face_id;
21200 else
21201 tem_it.face_id = lnum_face_id;
21202 if (beyond_zv
21203 /* Don't display the same line number more than once. */
21204 || (!EQ (Vdisplay_line_numbers, Qvisual)
21205 && (it->continuation_lines_width > 0
21206 || (this_line == last_line && !first_time))))
21207 tem_it.c = tem_it.char_to_display = ' ';
21208 else
21209 tem_it.c = tem_it.char_to_display = *p;
21210 tem_it.len = 1;
21211 n_glyphs_before = scratch_glyph_row.used[TEXT_AREA];
21212 /* Make sure these glyphs will have a "position" of -1. */
21213 SET_TEXT_POS (tem_it.position, -1, -1);
21214 PRODUCE_GLYPHS (&tem_it);
21216 /* Stop producing glyphs if we don't have enough space on
21217 this line. FIXME: should we refrain from producing the
21218 line number at all in that case? */
21219 if (tem_it.current_x > tem_it.last_visible_x)
21221 scratch_glyph_row.used[TEXT_AREA] = n_glyphs_before;
21222 break;
21226 /* Record the width in pixels we need for the line number display. */
21227 it->lnum_pixel_width = tem_it.current_x;
21228 /* Copy the produced glyphs into IT's glyph_row. */
21229 struct glyph *g = scratch_glyph_row.glyphs[TEXT_AREA];
21230 struct glyph *e = g + scratch_glyph_row.used[TEXT_AREA];
21231 struct glyph *p = it->glyph_row ? it->glyph_row->glyphs[TEXT_AREA] : NULL;
21232 short *u = it->glyph_row ? &it->glyph_row->used[TEXT_AREA] : NULL;
21234 eassert (it->glyph_row == NULL || it->glyph_row->used[TEXT_AREA] == 0);
21236 for ( ; g < e; g++)
21238 it->current_x += g->pixel_width;
21239 /* The following is important when this function is called
21240 from move_it_in_display_line_to: HPOS is incremented only
21241 when we are in the visible portion of the glyph row. */
21242 if (it->current_x > it->first_visible_x)
21243 it->hpos++;
21244 if (p)
21246 *p++ = *g;
21247 (*u)++;
21251 /* Update IT's metrics due to glyphs produced for line numbers. */
21252 if (it->glyph_row)
21254 struct glyph_row *row = it->glyph_row;
21256 it->max_ascent = max (row->ascent, tem_it.max_ascent);
21257 it->max_descent = max (row->height - row->ascent, tem_it.max_descent);
21258 it->max_phys_ascent = max (row->phys_ascent, tem_it.max_phys_ascent);
21259 it->max_phys_descent = max (row->phys_height - row->phys_ascent,
21260 tem_it.max_phys_descent);
21262 else
21264 it->max_ascent = max (it->max_ascent, tem_it.max_ascent);
21265 it->max_descent = max (it->max_descent, tem_it.max_descent);
21266 it->max_phys_ascent = max (it->max_phys_ascent, tem_it.max_phys_ascent);
21267 it->max_phys_descent = max (it->max_phys_descent, tem_it.max_phys_descent);
21270 it->line_number_produced_p = true;
21272 bidi_unshelve_cache (itdata, false);
21275 /* Return true if this glyph row needs a line number to be produced
21276 for it. */
21277 static bool
21278 should_produce_line_number (struct it *it)
21280 if (NILP (Vdisplay_line_numbers))
21281 return false;
21283 /* Don't display line numbers in minibuffer windows. */
21284 if (MINI_WINDOW_P (it->w))
21285 return false;
21287 #ifdef HAVE_WINDOW_SYSTEM
21288 /* Don't display line number in tooltip frames. */
21289 if (FRAME_TOOLTIP_P (XFRAME (WINDOW_FRAME (it->w))))
21290 return false;
21291 #endif
21293 /* If the character at current position has a non-nil special
21294 property, disable line numbers for this row. This is for
21295 packages such as company-mode, which need this for their tricky
21296 layout, where line numbers get in the way. */
21297 Lisp_Object val = Fget_char_property (make_number (IT_CHARPOS (*it)),
21298 Qdisplay_line_numbers_disable,
21299 it->window);
21300 /* For ZV, we need to also look in empty overlays at that point,
21301 because get-char-property always returns nil for ZV, except if
21302 the property is in 'default-text-properties'. */
21303 if (NILP (val) && IT_CHARPOS (*it) >= ZV)
21304 val = disable_line_numbers_overlay_at_eob ();
21305 return NILP (val) ? true : false;
21308 /* Return true if ROW has no glyphs except those inserted by the
21309 display engine. This is needed for indicate-empty-lines and
21310 similar features when the glyph row starts with glyphs which didn't
21311 come from buffer or string. */
21312 static bool
21313 row_text_area_empty (struct glyph_row *row)
21315 if (!row->reversed_p)
21317 for (struct glyph *g = row->glyphs[TEXT_AREA];
21318 g < row->glyphs[TEXT_AREA] + row->used[TEXT_AREA];
21319 g++)
21320 if (!NILP (g->object) || g->charpos > 0)
21321 return false;
21323 else
21325 for (struct glyph *g = row->glyphs[TEXT_AREA] + row->used[TEXT_AREA] - 1;
21326 g > row->glyphs[TEXT_AREA];
21327 g--)
21328 if (!NILP ((g - 1)->object) || (g - 1)->charpos > 0)
21329 return false;
21332 return true;
21335 /* Construct the glyph row IT->glyph_row in the desired matrix of
21336 IT->w from text at the current position of IT. See dispextern.h
21337 for an overview of struct it. Value is true if
21338 IT->glyph_row displays text, as opposed to a line displaying ZV
21339 only. CURSOR_VPOS is the window-relative vertical position of
21340 the glyph row displaying the cursor, or -1 if unknown. */
21342 static bool
21343 display_line (struct it *it, int cursor_vpos)
21345 struct glyph_row *row = it->glyph_row;
21346 Lisp_Object overlay_arrow_string;
21347 struct it wrap_it;
21348 void *wrap_data = NULL;
21349 bool may_wrap = false;
21350 int wrap_x UNINIT;
21351 int wrap_row_used = -1;
21352 int wrap_row_ascent UNINIT, wrap_row_height UNINIT;
21353 int wrap_row_phys_ascent UNINIT, wrap_row_phys_height UNINIT;
21354 int wrap_row_extra_line_spacing UNINIT;
21355 ptrdiff_t wrap_row_min_pos UNINIT, wrap_row_min_bpos UNINIT;
21356 ptrdiff_t wrap_row_max_pos UNINIT, wrap_row_max_bpos UNINIT;
21357 int cvpos;
21358 ptrdiff_t min_pos = ZV + 1, max_pos = 0;
21359 ptrdiff_t min_bpos UNINIT, max_bpos UNINIT;
21360 bool pending_handle_line_prefix = false;
21361 int header_line = window_wants_header_line (it->w);
21362 bool hscroll_this_line = (cursor_vpos >= 0
21363 && it->vpos == cursor_vpos - header_line
21364 && hscrolling_current_line_p (it->w));
21365 int first_visible_x = it->first_visible_x;
21366 int last_visible_x = it->last_visible_x;
21367 int x_incr = 0;
21369 /* We always start displaying at hpos zero even if hscrolled. */
21370 eassert (it->hpos == 0 && it->current_x == 0);
21372 if (MATRIX_ROW_VPOS (row, it->w->desired_matrix)
21373 >= it->w->desired_matrix->nrows)
21375 it->w->nrows_scale_factor++;
21376 it->f->fonts_changed = true;
21377 return false;
21380 /* Clear the result glyph row and enable it. */
21381 prepare_desired_row (it->w, row, false);
21383 row->y = it->current_y;
21384 row->start = it->start;
21385 row->continuation_lines_width = it->continuation_lines_width;
21386 row->displays_text_p = true;
21387 row->starts_in_middle_of_char_p = it->starts_in_middle_of_char_p;
21388 it->starts_in_middle_of_char_p = false;
21389 it->tab_offset = 0;
21390 it->line_number_produced_p = false;
21392 /* Arrange the overlays nicely for our purposes. Usually, we call
21393 display_line on only one line at a time, in which case this
21394 can't really hurt too much, or we call it on lines which appear
21395 one after another in the buffer, in which case all calls to
21396 recenter_overlay_lists but the first will be pretty cheap. */
21397 recenter_overlay_lists (current_buffer, IT_CHARPOS (*it));
21399 /* If we are going to display the cursor's line, account for the
21400 hscroll of that line. We subtract the window's min_hscroll,
21401 because that was already accounted for in init_iterator. */
21402 if (hscroll_this_line)
21403 x_incr =
21404 (window_hscroll_limited (it->w, it->f) - it->w->min_hscroll)
21405 * FRAME_COLUMN_WIDTH (it->f);
21407 bool line_number_needed = should_produce_line_number (it);
21409 /* Move over display elements that are not visible because we are
21410 hscrolled. This may stop at an x-position < first_visible_x
21411 if the first glyph is partially visible or if we hit a line end. */
21412 if (it->current_x < it->first_visible_x + x_incr)
21414 enum move_it_result move_result;
21416 this_line_min_pos = row->start.pos;
21417 if (hscroll_this_line)
21419 it->first_visible_x += x_incr;
21420 it->last_visible_x += x_incr;
21422 move_result = move_it_in_display_line_to (it, ZV, it->first_visible_x,
21423 MOVE_TO_POS | MOVE_TO_X);
21424 /* If we are under a large hscroll, move_it_in_display_line_to
21425 could hit the end of the line without reaching
21426 first_visible_x. Pretend that we did reach it. This is
21427 especially important on a TTY, where we will call
21428 extend_face_to_end_of_line, which needs to know how many
21429 blank glyphs to produce. */
21430 if (it->current_x < it->first_visible_x
21431 && (move_result == MOVE_NEWLINE_OR_CR
21432 || move_result == MOVE_POS_MATCH_OR_ZV))
21433 it->current_x = it->first_visible_x;
21435 /* In case move_it_in_display_line_to above "produced" the line
21436 number. */
21437 it->line_number_produced_p = false;
21439 /* Record the smallest positions seen while we moved over
21440 display elements that are not visible. This is needed by
21441 redisplay_internal for optimizing the case where the cursor
21442 stays inside the same line. The rest of this function only
21443 considers positions that are actually displayed, so
21444 RECORD_MAX_MIN_POS will not otherwise record positions that
21445 are hscrolled to the left of the left edge of the window. */
21446 min_pos = CHARPOS (this_line_min_pos);
21447 min_bpos = BYTEPOS (this_line_min_pos);
21449 /* Produce line number, if needed. */
21450 if (line_number_needed)
21451 maybe_produce_line_number (it);
21453 else if (it->area == TEXT_AREA)
21455 /* Line numbers should precede the line-prefix or wrap-prefix. */
21456 if (line_number_needed)
21457 maybe_produce_line_number (it);
21459 /* We only do this when not calling move_it_in_display_line_to
21460 above, because that function calls itself handle_line_prefix. */
21461 handle_line_prefix (it);
21463 else
21465 /* Line-prefix and wrap-prefix are always displayed in the text
21466 area. But if this is the first call to display_line after
21467 init_iterator, the iterator might have been set up to write
21468 into a marginal area, e.g. if the line begins with some
21469 display property that writes to the margins. So we need to
21470 wait with the call to handle_line_prefix until whatever
21471 writes to the margin has done its job. */
21472 pending_handle_line_prefix = true;
21475 /* Get the initial row height. This is either the height of the
21476 text hscrolled, if there is any, or zero. */
21477 row->ascent = it->max_ascent;
21478 row->height = it->max_ascent + it->max_descent;
21479 row->phys_ascent = it->max_phys_ascent;
21480 row->phys_height = it->max_phys_ascent + it->max_phys_descent;
21481 row->extra_line_spacing = it->max_extra_line_spacing;
21483 /* Utility macro to record max and min buffer positions seen until now. */
21484 #define RECORD_MAX_MIN_POS(IT) \
21485 do \
21487 bool composition_p \
21488 = !STRINGP ((IT)->string) && ((IT)->what == IT_COMPOSITION); \
21489 ptrdiff_t current_pos = \
21490 composition_p ? (IT)->cmp_it.charpos \
21491 : IT_CHARPOS (*(IT)); \
21492 ptrdiff_t current_bpos = \
21493 composition_p ? CHAR_TO_BYTE (current_pos) \
21494 : IT_BYTEPOS (*(IT)); \
21495 if (current_pos < min_pos) \
21497 min_pos = current_pos; \
21498 min_bpos = current_bpos; \
21500 if (IT_CHARPOS (*it) > max_pos) \
21502 max_pos = IT_CHARPOS (*it); \
21503 max_bpos = IT_BYTEPOS (*it); \
21506 while (false)
21508 /* Loop generating characters. The loop is left with IT on the next
21509 character to display. */
21510 while (true)
21512 int n_glyphs_before, hpos_before, x_before;
21513 int x, nglyphs;
21514 int ascent = 0, descent = 0, phys_ascent = 0, phys_descent = 0;
21516 /* Retrieve the next thing to display. Value is false if end of
21517 buffer reached. */
21518 if (!get_next_display_element (it))
21520 bool row_has_glyphs = false;
21521 /* Maybe add a space at the end of this line that is used to
21522 display the cursor there under X. Set the charpos of the
21523 first glyph of blank lines not corresponding to any text
21524 to -1. */
21525 if (IT_OVERFLOW_NEWLINE_INTO_FRINGE (it))
21526 row->exact_window_width_line_p = true;
21527 else if ((append_space_for_newline (it, true)
21528 && row->used[TEXT_AREA] == 1)
21529 || row->used[TEXT_AREA] == 0
21530 || (row_has_glyphs = row_text_area_empty (row)))
21532 row->glyphs[TEXT_AREA]->charpos = -1;
21533 /* Don't reset the displays_text_p flag if we are
21534 displaying line numbers or line-prefix. */
21535 if (!row_has_glyphs)
21536 row->displays_text_p = false;
21538 if (!NILP (BVAR (XBUFFER (it->w->contents), indicate_empty_lines))
21539 && (!MINI_WINDOW_P (it->w)))
21540 row->indicate_empty_line_p = true;
21543 it->continuation_lines_width = 0;
21544 /* Reset those iterator values set from display property
21545 values. This is for the case when the display property
21546 ends at ZV, and is not a replacing property, so pop_it is
21547 not called. */
21548 it->font_height = Qnil;
21549 it->voffset = 0;
21550 row->ends_at_zv_p = true;
21551 /* A row that displays right-to-left text must always have
21552 its last face extended all the way to the end of line,
21553 even if this row ends in ZV, because we still write to
21554 the screen left to right. We also need to extend the
21555 last face if the default face is remapped to some
21556 different face, otherwise the functions that clear
21557 portions of the screen will clear with the default face's
21558 background color. */
21559 if (row->reversed_p
21560 || lookup_basic_face (it->f, DEFAULT_FACE_ID) != DEFAULT_FACE_ID)
21561 extend_face_to_end_of_line (it);
21562 break;
21565 /* Now, get the metrics of what we want to display. This also
21566 generates glyphs in `row' (which is IT->glyph_row). */
21567 n_glyphs_before = row->used[TEXT_AREA];
21568 x = it->current_x;
21570 /* Remember the line height so far in case the next element doesn't
21571 fit on the line. */
21572 if (it->line_wrap != TRUNCATE)
21574 ascent = it->max_ascent;
21575 descent = it->max_descent;
21576 phys_ascent = it->max_phys_ascent;
21577 phys_descent = it->max_phys_descent;
21579 if (it->line_wrap == WORD_WRAP && it->area == TEXT_AREA)
21581 if (IT_DISPLAYING_WHITESPACE (it))
21582 may_wrap = true;
21583 else if (may_wrap)
21585 SAVE_IT (wrap_it, *it, wrap_data);
21586 wrap_x = x;
21587 wrap_row_used = row->used[TEXT_AREA];
21588 wrap_row_ascent = row->ascent;
21589 wrap_row_height = row->height;
21590 wrap_row_phys_ascent = row->phys_ascent;
21591 wrap_row_phys_height = row->phys_height;
21592 wrap_row_extra_line_spacing = row->extra_line_spacing;
21593 wrap_row_min_pos = min_pos;
21594 wrap_row_min_bpos = min_bpos;
21595 wrap_row_max_pos = max_pos;
21596 wrap_row_max_bpos = max_bpos;
21597 may_wrap = false;
21602 PRODUCE_GLYPHS (it);
21604 /* If this display element was in marginal areas, continue with
21605 the next one. */
21606 if (it->area != TEXT_AREA)
21608 row->ascent = max (row->ascent, it->max_ascent);
21609 row->height = max (row->height, it->max_ascent + it->max_descent);
21610 row->phys_ascent = max (row->phys_ascent, it->max_phys_ascent);
21611 row->phys_height = max (row->phys_height,
21612 it->max_phys_ascent + it->max_phys_descent);
21613 row->extra_line_spacing = max (row->extra_line_spacing,
21614 it->max_extra_line_spacing);
21615 set_iterator_to_next (it, true);
21616 /* If we didn't handle the line/wrap prefix above, and the
21617 call to set_iterator_to_next just switched to TEXT_AREA,
21618 process the prefix now. */
21619 if (it->area == TEXT_AREA && pending_handle_line_prefix)
21621 /* Line numbers should precede the line-prefix or wrap-prefix. */
21622 if (line_number_needed)
21623 maybe_produce_line_number (it);
21625 pending_handle_line_prefix = false;
21626 handle_line_prefix (it);
21628 continue;
21631 /* Does the display element fit on the line? If we truncate
21632 lines, we should draw past the right edge of the window. If
21633 we don't truncate, we want to stop so that we can display the
21634 continuation glyph before the right margin. If lines are
21635 continued, there are two possible strategies for characters
21636 resulting in more than 1 glyph (e.g. tabs): Display as many
21637 glyphs as possible in this line and leave the rest for the
21638 continuation line, or display the whole element in the next
21639 line. Original redisplay did the former, so we do it also. */
21640 nglyphs = row->used[TEXT_AREA] - n_glyphs_before;
21641 hpos_before = it->hpos;
21642 x_before = x;
21644 if (/* Not a newline. */
21645 nglyphs > 0
21646 /* Glyphs produced fit entirely in the line. */
21647 && it->current_x < it->last_visible_x)
21649 it->hpos += nglyphs;
21650 row->ascent = max (row->ascent, it->max_ascent);
21651 row->height = max (row->height, it->max_ascent + it->max_descent);
21652 row->phys_ascent = max (row->phys_ascent, it->max_phys_ascent);
21653 row->phys_height = max (row->phys_height,
21654 it->max_phys_ascent + it->max_phys_descent);
21655 row->extra_line_spacing = max (row->extra_line_spacing,
21656 it->max_extra_line_spacing);
21657 if (it->current_x - it->pixel_width < it->first_visible_x
21658 /* When line numbers are displayed, row->x should not be
21659 offset, as the first glyph after the line number can
21660 never be partially visible. */
21661 && !line_number_needed
21662 /* In R2L rows, we arrange in extend_face_to_end_of_line
21663 to add a right offset to the line, by a suitable
21664 change to the stretch glyph that is the leftmost
21665 glyph of the line. */
21666 && !row->reversed_p)
21667 row->x = x - it->first_visible_x;
21668 /* Record the maximum and minimum buffer positions seen so
21669 far in glyphs that will be displayed by this row. */
21670 if (it->bidi_p)
21671 RECORD_MAX_MIN_POS (it);
21673 else
21675 int i, new_x;
21676 struct glyph *glyph;
21678 for (i = 0; i < nglyphs; ++i, x = new_x)
21680 /* Identify the glyphs added by the last call to
21681 PRODUCE_GLYPHS. In R2L rows, they are prepended to
21682 the previous glyphs. */
21683 if (!row->reversed_p)
21684 glyph = row->glyphs[TEXT_AREA] + n_glyphs_before + i;
21685 else
21686 glyph = row->glyphs[TEXT_AREA] + nglyphs - 1 - i;
21687 new_x = x + glyph->pixel_width;
21689 if (/* Lines are continued. */
21690 it->line_wrap != TRUNCATE
21691 && (/* Glyph doesn't fit on the line. */
21692 new_x > it->last_visible_x
21693 /* Or it fits exactly on a window system frame. */
21694 || (new_x == it->last_visible_x
21695 && FRAME_WINDOW_P (it->f)
21696 && (row->reversed_p
21697 ? WINDOW_LEFT_FRINGE_WIDTH (it->w)
21698 : WINDOW_RIGHT_FRINGE_WIDTH (it->w)))))
21700 /* End of a continued line. */
21702 if (it->hpos == 0
21703 || (new_x == it->last_visible_x
21704 && FRAME_WINDOW_P (it->f)
21705 && (row->reversed_p
21706 ? WINDOW_LEFT_FRINGE_WIDTH (it->w)
21707 : WINDOW_RIGHT_FRINGE_WIDTH (it->w))))
21709 /* Current glyph is the only one on the line or
21710 fits exactly on the line. We must continue
21711 the line because we can't draw the cursor
21712 after the glyph. */
21713 row->continued_p = true;
21714 it->current_x = new_x;
21715 it->continuation_lines_width += new_x;
21716 ++it->hpos;
21717 if (i == nglyphs - 1)
21719 /* If line-wrap is on, check if a previous
21720 wrap point was found. */
21721 if (!IT_OVERFLOW_NEWLINE_INTO_FRINGE (it)
21722 && wrap_row_used > 0
21723 /* Even if there is a previous wrap
21724 point, continue the line here as
21725 usual, if (i) the previous character
21726 was a space or tab AND (ii) the
21727 current character is not. */
21728 && (!may_wrap
21729 || IT_DISPLAYING_WHITESPACE (it)))
21730 goto back_to_wrap;
21732 /* Record the maximum and minimum buffer
21733 positions seen so far in glyphs that will be
21734 displayed by this row. */
21735 if (it->bidi_p)
21736 RECORD_MAX_MIN_POS (it);
21737 set_iterator_to_next (it, true);
21738 if (IT_OVERFLOW_NEWLINE_INTO_FRINGE (it))
21740 if (!get_next_display_element (it))
21742 row->exact_window_width_line_p = true;
21743 it->continuation_lines_width = 0;
21744 it->font_height = Qnil;
21745 it->voffset = 0;
21746 row->continued_p = false;
21747 row->ends_at_zv_p = true;
21749 else if (ITERATOR_AT_END_OF_LINE_P (it))
21751 row->continued_p = false;
21752 row->exact_window_width_line_p = true;
21754 /* If line-wrap is on, check if a
21755 previous wrap point was found. */
21756 else if (wrap_row_used > 0
21757 /* Even if there is a previous wrap
21758 point, continue the line here as
21759 usual, if (i) the previous character
21760 was a space or tab AND (ii) the
21761 current character is not. */
21762 && (!may_wrap
21763 || IT_DISPLAYING_WHITESPACE (it)))
21764 goto back_to_wrap;
21768 else if (it->bidi_p)
21769 RECORD_MAX_MIN_POS (it);
21770 if (WINDOW_LEFT_MARGIN_WIDTH (it->w) > 0
21771 || WINDOW_RIGHT_MARGIN_WIDTH (it->w) > 0)
21772 extend_face_to_end_of_line (it);
21774 else if (CHAR_GLYPH_PADDING_P (*glyph)
21775 && !FRAME_WINDOW_P (it->f))
21777 /* A padding glyph that doesn't fit on this line.
21778 This means the whole character doesn't fit
21779 on the line. */
21780 if (row->reversed_p)
21781 unproduce_glyphs (it, row->used[TEXT_AREA]
21782 - n_glyphs_before);
21783 row->used[TEXT_AREA] = n_glyphs_before;
21785 /* Fill the rest of the row with continuation
21786 glyphs like in 20.x. */
21787 while (row->glyphs[TEXT_AREA] + row->used[TEXT_AREA]
21788 < row->glyphs[1 + TEXT_AREA])
21789 produce_special_glyphs (it, IT_CONTINUATION);
21791 row->continued_p = true;
21792 it->current_x = x_before;
21793 it->continuation_lines_width += x_before;
21795 /* Restore the height to what it was before the
21796 element not fitting on the line. */
21797 it->max_ascent = ascent;
21798 it->max_descent = descent;
21799 it->max_phys_ascent = phys_ascent;
21800 it->max_phys_descent = phys_descent;
21801 if (WINDOW_LEFT_MARGIN_WIDTH (it->w) > 0
21802 || WINDOW_RIGHT_MARGIN_WIDTH (it->w) > 0)
21803 extend_face_to_end_of_line (it);
21805 else if (wrap_row_used > 0)
21807 back_to_wrap:
21808 if (row->reversed_p)
21809 unproduce_glyphs (it,
21810 row->used[TEXT_AREA] - wrap_row_used);
21811 RESTORE_IT (it, &wrap_it, wrap_data);
21812 it->continuation_lines_width += wrap_x;
21813 row->used[TEXT_AREA] = wrap_row_used;
21814 row->ascent = wrap_row_ascent;
21815 row->height = wrap_row_height;
21816 row->phys_ascent = wrap_row_phys_ascent;
21817 row->phys_height = wrap_row_phys_height;
21818 row->extra_line_spacing = wrap_row_extra_line_spacing;
21819 min_pos = wrap_row_min_pos;
21820 min_bpos = wrap_row_min_bpos;
21821 max_pos = wrap_row_max_pos;
21822 max_bpos = wrap_row_max_bpos;
21823 row->continued_p = true;
21824 row->ends_at_zv_p = false;
21825 row->exact_window_width_line_p = false;
21827 /* Make sure that a non-default face is extended
21828 up to the right margin of the window. */
21829 extend_face_to_end_of_line (it);
21831 else if ((it->what == IT_CHARACTER
21832 || it->what == IT_STRETCH
21833 || it->what == IT_COMPOSITION)
21834 && it->c == '\t' && FRAME_WINDOW_P (it->f))
21836 /* A TAB that extends past the right edge of the
21837 window. This produces a single glyph on
21838 window system frames. We leave the glyph in
21839 this row and let it fill the row, but don't
21840 consume the TAB. */
21841 if ((row->reversed_p
21842 ? WINDOW_LEFT_FRINGE_WIDTH (it->w)
21843 : WINDOW_RIGHT_FRINGE_WIDTH (it->w)) == 0)
21844 produce_special_glyphs (it, IT_CONTINUATION);
21845 it->continuation_lines_width += it->last_visible_x;
21846 row->ends_in_middle_of_char_p = true;
21847 row->continued_p = true;
21848 glyph->pixel_width = it->last_visible_x - x;
21849 it->starts_in_middle_of_char_p = true;
21850 if (WINDOW_LEFT_MARGIN_WIDTH (it->w) > 0
21851 || WINDOW_RIGHT_MARGIN_WIDTH (it->w) > 0)
21852 extend_face_to_end_of_line (it);
21854 else
21856 /* Something other than a TAB that draws past
21857 the right edge of the window. Restore
21858 positions to values before the element. */
21859 if (row->reversed_p)
21860 unproduce_glyphs (it, row->used[TEXT_AREA]
21861 - (n_glyphs_before + i));
21862 row->used[TEXT_AREA] = n_glyphs_before + i;
21864 /* Display continuation glyphs. */
21865 it->current_x = x_before;
21866 it->continuation_lines_width += x;
21867 if (!FRAME_WINDOW_P (it->f)
21868 || (row->reversed_p
21869 ? WINDOW_LEFT_FRINGE_WIDTH (it->w)
21870 : WINDOW_RIGHT_FRINGE_WIDTH (it->w)) == 0)
21871 produce_special_glyphs (it, IT_CONTINUATION);
21872 row->continued_p = true;
21874 extend_face_to_end_of_line (it);
21876 if (nglyphs > 1 && i > 0)
21878 row->ends_in_middle_of_char_p = true;
21879 it->starts_in_middle_of_char_p = true;
21882 /* Restore the height to what it was before the
21883 element not fitting on the line. */
21884 it->max_ascent = ascent;
21885 it->max_descent = descent;
21886 it->max_phys_ascent = phys_ascent;
21887 it->max_phys_descent = phys_descent;
21890 break;
21892 else if (new_x > it->first_visible_x)
21894 /* Increment number of glyphs actually displayed. */
21895 ++it->hpos;
21897 /* Record the maximum and minimum buffer positions
21898 seen so far in glyphs that will be displayed by
21899 this row. */
21900 if (it->bidi_p)
21901 RECORD_MAX_MIN_POS (it);
21903 if (x < it->first_visible_x && !row->reversed_p
21904 && !line_number_needed)
21905 /* Glyph is partially visible, i.e. row starts at
21906 negative X position. Don't do that in R2L
21907 rows, where we arrange to add a right offset to
21908 the line in extend_face_to_end_of_line, by a
21909 suitable change to the stretch glyph that is
21910 the leftmost glyph of the line. */
21911 row->x = x - it->first_visible_x;
21912 /* When the last glyph of an R2L row only fits
21913 partially on the line, we need to set row->x to a
21914 negative offset, so that the leftmost glyph is
21915 the one that is partially visible. But if we are
21916 going to produce the truncation glyph, this will
21917 be taken care of in produce_special_glyphs. */
21918 if (row->reversed_p
21919 && new_x > it->last_visible_x
21920 && !line_number_needed
21921 && !(it->line_wrap == TRUNCATE
21922 && WINDOW_LEFT_FRINGE_WIDTH (it->w) == 0))
21924 eassert (FRAME_WINDOW_P (it->f));
21925 row->x = it->last_visible_x - new_x;
21928 else
21930 /* Glyph is completely off the left margin of the
21931 window. This should not happen because of the
21932 move_it_in_display_line at the start of this
21933 function, unless the text display area of the
21934 window is empty. */
21935 eassert (it->first_visible_x <= it->last_visible_x);
21938 /* Even if this display element produced no glyphs at all,
21939 we want to record its position. */
21940 if (it->bidi_p && nglyphs == 0)
21941 RECORD_MAX_MIN_POS (it);
21943 row->ascent = max (row->ascent, it->max_ascent);
21944 row->height = max (row->height, it->max_ascent + it->max_descent);
21945 row->phys_ascent = max (row->phys_ascent, it->max_phys_ascent);
21946 row->phys_height = max (row->phys_height,
21947 it->max_phys_ascent + it->max_phys_descent);
21948 row->extra_line_spacing = max (row->extra_line_spacing,
21949 it->max_extra_line_spacing);
21951 /* End of this display line if row is continued. */
21952 if (row->continued_p || row->ends_at_zv_p)
21953 break;
21956 at_end_of_line:
21957 /* Is this a line end? If yes, we're also done, after making
21958 sure that a non-default face is extended up to the right
21959 margin of the window. */
21960 if (ITERATOR_AT_END_OF_LINE_P (it))
21962 int used_before = row->used[TEXT_AREA];
21964 row->ends_in_newline_from_string_p = STRINGP (it->object);
21966 /* Add a space at the end of the line that is used to
21967 display the cursor there. */
21968 if (!IT_OVERFLOW_NEWLINE_INTO_FRINGE (it))
21969 append_space_for_newline (it, false);
21971 /* Extend the face to the end of the line. */
21972 extend_face_to_end_of_line (it);
21974 /* Make sure we have the position. */
21975 if (used_before == 0)
21976 row->glyphs[TEXT_AREA]->charpos = CHARPOS (it->position);
21978 /* Record the position of the newline, for use in
21979 find_row_edges. */
21980 it->eol_pos = it->current.pos;
21982 /* Consume the line end. This skips over invisible lines. */
21983 set_iterator_to_next (it, true);
21984 it->continuation_lines_width = 0;
21985 break;
21988 /* Detect overly-wide wrap-prefixes made of (space ...) display
21989 properties. When such a wrap prefix reaches past the right
21990 margin of the window, we need to avoid the call to
21991 set_iterator_to_next below, so that it->line_wrap is left at
21992 its TRUNCATE value wisely set by handle_line_prefix.
21993 Otherwise, set_iterator_to_next will pop the iterator stack,
21994 restore it->line_wrap, and redisplay might infloop. */
21995 bool overwide_wrap_prefix =
21996 CONSP (it->object) && EQ (XCAR (it->object), Qspace)
21997 && it->sp > 0 && it->method == GET_FROM_STRETCH
21998 && it->current_x >= it->last_visible_x
21999 && it->continuation_lines_width > 0
22000 && it->line_wrap == TRUNCATE && it->stack[0].line_wrap != TRUNCATE;
22002 /* Proceed with next display element. Note that this skips
22003 over lines invisible because of selective display. */
22004 if (!overwide_wrap_prefix)
22005 set_iterator_to_next (it, true);
22007 /* If we truncate lines, we are done when the last displayed
22008 glyphs reach past the right margin of the window. */
22009 if (it->line_wrap == TRUNCATE
22010 && ((FRAME_WINDOW_P (it->f)
22011 /* Images are preprocessed in produce_image_glyph such
22012 that they are cropped at the right edge of the
22013 window, so an image glyph will always end exactly at
22014 last_visible_x, even if there's no right fringe. */
22015 && ((row->reversed_p
22016 ? WINDOW_LEFT_FRINGE_WIDTH (it->w)
22017 : WINDOW_RIGHT_FRINGE_WIDTH (it->w))
22018 || it->what == IT_IMAGE))
22019 ? (it->current_x >= it->last_visible_x)
22020 : (it->current_x > it->last_visible_x)))
22022 /* Maybe add truncation glyphs. */
22023 if (!FRAME_WINDOW_P (it->f)
22024 || (row->reversed_p
22025 ? WINDOW_LEFT_FRINGE_WIDTH (it->w)
22026 : WINDOW_RIGHT_FRINGE_WIDTH (it->w)) == 0)
22028 int i, n;
22030 if (!row->reversed_p)
22032 for (i = row->used[TEXT_AREA] - 1; i > 0; --i)
22033 if (!CHAR_GLYPH_PADDING_P (row->glyphs[TEXT_AREA][i]))
22034 break;
22036 else
22038 for (i = 0; i < row->used[TEXT_AREA]; i++)
22039 if (!CHAR_GLYPH_PADDING_P (row->glyphs[TEXT_AREA][i]))
22040 break;
22041 /* Remove any padding glyphs at the front of ROW, to
22042 make room for the truncation glyphs we will be
22043 adding below. The loop below always inserts at
22044 least one truncation glyph, so also remove the
22045 last glyph added to ROW. */
22046 unproduce_glyphs (it, i + 1);
22047 /* Adjust i for the loop below. */
22048 i = row->used[TEXT_AREA] - (i + 1);
22051 /* produce_special_glyphs overwrites the last glyph, so
22052 we don't want that if we want to keep that last
22053 glyph, which means it's an image. */
22054 if (it->current_x > it->last_visible_x)
22056 it->current_x = x_before;
22057 if (!FRAME_WINDOW_P (it->f))
22059 for (n = row->used[TEXT_AREA]; i < n; ++i)
22061 row->used[TEXT_AREA] = i;
22062 produce_special_glyphs (it, IT_TRUNCATION);
22065 else
22067 row->used[TEXT_AREA] = i;
22068 produce_special_glyphs (it, IT_TRUNCATION);
22070 it->hpos = hpos_before;
22073 else if (IT_OVERFLOW_NEWLINE_INTO_FRINGE (it))
22075 /* Don't truncate if we can overflow newline into fringe. */
22076 if (!get_next_display_element (it))
22078 it->continuation_lines_width = 0;
22079 it->font_height = Qnil;
22080 it->voffset = 0;
22081 row->ends_at_zv_p = true;
22082 row->exact_window_width_line_p = true;
22083 break;
22085 if (ITERATOR_AT_END_OF_LINE_P (it))
22087 row->exact_window_width_line_p = true;
22088 goto at_end_of_line;
22090 it->current_x = x_before;
22091 it->hpos = hpos_before;
22094 row->truncated_on_right_p = true;
22095 it->continuation_lines_width = 0;
22096 reseat_at_next_visible_line_start (it, false);
22097 /* We insist below that IT's position be at ZV because in
22098 bidi-reordered lines the character at visible line start
22099 might not be the character that follows the newline in
22100 the logical order. */
22101 if (IT_BYTEPOS (*it) > BEG_BYTE)
22102 row->ends_at_zv_p =
22103 IT_BYTEPOS (*it) >= ZV_BYTE && FETCH_BYTE (ZV_BYTE - 1) != '\n';
22104 else
22105 row->ends_at_zv_p = false;
22106 break;
22110 if (wrap_data)
22111 bidi_unshelve_cache (wrap_data, true);
22113 /* If line is not empty and hscrolled, maybe insert truncation glyphs
22114 at the left window margin. */
22115 if (it->first_visible_x
22116 && IT_CHARPOS (*it) != CHARPOS (row->start.pos))
22118 if (!FRAME_WINDOW_P (it->f)
22119 || (((row->reversed_p
22120 ? WINDOW_RIGHT_FRINGE_WIDTH (it->w)
22121 : WINDOW_LEFT_FRINGE_WIDTH (it->w)) == 0)
22122 /* Don't let insert_left_trunc_glyphs overwrite the
22123 first glyph of the row if it is an image. */
22124 && row->glyphs[TEXT_AREA]->type != IMAGE_GLYPH))
22125 insert_left_trunc_glyphs (it);
22126 row->truncated_on_left_p = true;
22129 /* Remember the position at which this line ends.
22131 BIDI Note: any code that needs MATRIX_ROW_START/END_CHARPOS
22132 cannot be before the call to find_row_edges below, since that is
22133 where these positions are determined. */
22134 row->end = it->current;
22135 if (!it->bidi_p)
22137 row->minpos = row->start.pos;
22138 row->maxpos = row->end.pos;
22140 else
22142 /* ROW->minpos and ROW->maxpos must be the smallest and
22143 `1 + the largest' buffer positions in ROW. But if ROW was
22144 bidi-reordered, these two positions can be anywhere in the
22145 row, so we must determine them now. */
22146 find_row_edges (it, row, min_pos, min_bpos, max_pos, max_bpos);
22149 /* If the start of this line is the overlay arrow-position, then
22150 mark this glyph row as the one containing the overlay arrow.
22151 This is clearly a mess with variable size fonts. It would be
22152 better to let it be displayed like cursors under X. */
22153 if ((MATRIX_ROW_DISPLAYS_TEXT_P (row) || !overlay_arrow_seen)
22154 && (overlay_arrow_string = overlay_arrow_at_row (it, row),
22155 !NILP (overlay_arrow_string)))
22157 /* Overlay arrow in window redisplay is a fringe bitmap. */
22158 if (STRINGP (overlay_arrow_string))
22160 struct glyph_row *arrow_row
22161 = get_overlay_arrow_glyph_row (it->w, overlay_arrow_string);
22162 struct glyph *glyph = arrow_row->glyphs[TEXT_AREA];
22163 struct glyph *arrow_end = glyph + arrow_row->used[TEXT_AREA];
22164 struct glyph *p = row->glyphs[TEXT_AREA];
22165 struct glyph *p2, *end;
22167 /* Copy the arrow glyphs. */
22168 while (glyph < arrow_end)
22169 *p++ = *glyph++;
22171 /* Throw away padding glyphs. */
22172 p2 = p;
22173 end = row->glyphs[TEXT_AREA] + row->used[TEXT_AREA];
22174 while (p2 < end && CHAR_GLYPH_PADDING_P (*p2))
22175 ++p2;
22176 if (p2 > p)
22178 while (p2 < end)
22179 *p++ = *p2++;
22180 row->used[TEXT_AREA] = p2 - row->glyphs[TEXT_AREA];
22183 else
22185 eassert (INTEGERP (overlay_arrow_string));
22186 row->overlay_arrow_bitmap = XINT (overlay_arrow_string);
22188 overlay_arrow_seen = true;
22191 /* Highlight trailing whitespace. */
22192 if (!NILP (Vshow_trailing_whitespace))
22193 highlight_trailing_whitespace (it->f, it->glyph_row);
22195 /* Compute pixel dimensions of this line. */
22196 compute_line_metrics (it);
22198 /* Implementation note: No changes in the glyphs of ROW or in their
22199 faces can be done past this point, because compute_line_metrics
22200 computes ROW's hash value and stores it within the glyph_row
22201 structure. */
22203 /* Record whether this row ends inside an ellipsis. */
22204 row->ends_in_ellipsis_p
22205 = (it->method == GET_FROM_DISPLAY_VECTOR
22206 && it->ellipsis_p);
22208 /* Save fringe bitmaps in this row. */
22209 row->left_user_fringe_bitmap = it->left_user_fringe_bitmap;
22210 row->left_user_fringe_face_id = it->left_user_fringe_face_id;
22211 row->right_user_fringe_bitmap = it->right_user_fringe_bitmap;
22212 row->right_user_fringe_face_id = it->right_user_fringe_face_id;
22214 it->left_user_fringe_bitmap = 0;
22215 it->left_user_fringe_face_id = 0;
22216 it->right_user_fringe_bitmap = 0;
22217 it->right_user_fringe_face_id = 0;
22219 /* Maybe set the cursor. */
22220 cvpos = it->w->cursor.vpos;
22221 if ((cvpos < 0
22222 /* In bidi-reordered rows, keep checking for proper cursor
22223 position even if one has been found already, because buffer
22224 positions in such rows change non-linearly with ROW->VPOS,
22225 when a line is continued. One exception: when we are at ZV,
22226 display cursor on the first suitable glyph row, since all
22227 the empty rows after that also have their position set to ZV. */
22228 /* FIXME: Revisit this when glyph ``spilling'' in continuation
22229 lines' rows is implemented for bidi-reordered rows. */
22230 || (it->bidi_p
22231 && !MATRIX_ROW (it->w->desired_matrix, cvpos)->ends_at_zv_p))
22232 && PT >= MATRIX_ROW_START_CHARPOS (row)
22233 && PT <= MATRIX_ROW_END_CHARPOS (row)
22234 && cursor_row_p (row))
22235 set_cursor_from_row (it->w, row, it->w->desired_matrix, 0, 0, 0, 0);
22237 /* Prepare for the next line. This line starts horizontally at (X
22238 HPOS) = (0 0). Vertical positions are incremented. As a
22239 convenience for the caller, IT->glyph_row is set to the next
22240 row to be used. */
22241 it->current_x = it->hpos = 0;
22242 it->current_y += row->height;
22243 /* Restore the first and last visible X if we adjusted them for
22244 current-line hscrolling. */
22245 if (hscroll_this_line)
22247 it->first_visible_x = first_visible_x;
22248 it->last_visible_x = last_visible_x;
22250 SET_TEXT_POS (it->eol_pos, 0, 0);
22251 ++it->vpos;
22252 ++it->glyph_row;
22253 /* The next row should by default use the same value of the
22254 reversed_p flag as this one. set_iterator_to_next decides when
22255 it's a new paragraph, and PRODUCE_GLYPHS recomputes the value of
22256 the flag accordingly. */
22257 if (it->glyph_row < MATRIX_BOTTOM_TEXT_ROW (it->w->desired_matrix, it->w))
22258 it->glyph_row->reversed_p = row->reversed_p;
22259 it->start = row->end;
22260 return MATRIX_ROW_DISPLAYS_TEXT_P (row);
22262 #undef RECORD_MAX_MIN_POS
22265 DEFUN ("current-bidi-paragraph-direction", Fcurrent_bidi_paragraph_direction,
22266 Scurrent_bidi_paragraph_direction, 0, 1, 0,
22267 doc: /* Return paragraph direction at point in BUFFER.
22268 Value is either `left-to-right' or `right-to-left'.
22269 If BUFFER is omitted or nil, it defaults to the current buffer.
22271 Paragraph direction determines how the text in the paragraph is displayed.
22272 In left-to-right paragraphs, text begins at the left margin of the window
22273 and the reading direction is generally left to right. In right-to-left
22274 paragraphs, text begins at the right margin and is read from right to left.
22276 See also `bidi-paragraph-direction'. */)
22277 (Lisp_Object buffer)
22279 struct buffer *buf = current_buffer;
22280 struct buffer *old = buf;
22282 if (! NILP (buffer))
22284 CHECK_BUFFER (buffer);
22285 buf = XBUFFER (buffer);
22288 if (NILP (BVAR (buf, bidi_display_reordering))
22289 || NILP (BVAR (buf, enable_multibyte_characters))
22290 /* When we are loading loadup.el, the character property tables
22291 needed for bidi iteration are not yet available. */
22292 || redisplay__inhibit_bidi)
22293 return Qleft_to_right;
22294 else if (!NILP (BVAR (buf, bidi_paragraph_direction)))
22295 return BVAR (buf, bidi_paragraph_direction);
22296 else
22298 /* Determine the direction from buffer text. We could try to
22299 use current_matrix if it is up to date, but this seems fast
22300 enough as it is. */
22301 struct bidi_it itb;
22302 ptrdiff_t pos = BUF_PT (buf);
22303 ptrdiff_t bytepos = BUF_PT_BYTE (buf);
22304 int c;
22305 void *itb_data = bidi_shelve_cache ();
22307 set_buffer_temp (buf);
22308 /* bidi_paragraph_init finds the base direction of the paragraph
22309 by searching forward from paragraph start. We need the base
22310 direction of the current or _previous_ paragraph, so we need
22311 to make sure we are within that paragraph. To that end, find
22312 the previous non-empty line. */
22313 if (pos >= ZV && pos > BEGV)
22314 DEC_BOTH (pos, bytepos);
22315 AUTO_STRING (trailing_white_space, "[\f\t ]*\n");
22316 if (fast_looking_at (trailing_white_space,
22317 pos, bytepos, ZV, ZV_BYTE, Qnil) > 0)
22319 while ((c = FETCH_BYTE (bytepos)) == '\n'
22320 || c == ' ' || c == '\t' || c == '\f')
22322 if (bytepos <= BEGV_BYTE)
22323 break;
22324 bytepos--;
22325 pos--;
22327 while (!CHAR_HEAD_P (FETCH_BYTE (bytepos)))
22328 bytepos--;
22330 bidi_init_it (pos, bytepos, FRAME_WINDOW_P (SELECTED_FRAME ()), &itb);
22331 itb.paragraph_dir = NEUTRAL_DIR;
22332 itb.string.s = NULL;
22333 itb.string.lstring = Qnil;
22334 itb.string.bufpos = 0;
22335 itb.string.from_disp_str = false;
22336 itb.string.unibyte = false;
22337 /* We have no window to use here for ignoring window-specific
22338 overlays. Using NULL for window pointer will cause
22339 compute_display_string_pos to use the current buffer. */
22340 itb.w = NULL;
22341 bidi_paragraph_init (NEUTRAL_DIR, &itb, true);
22342 bidi_unshelve_cache (itb_data, false);
22343 set_buffer_temp (old);
22344 switch (itb.paragraph_dir)
22346 case L2R:
22347 return Qleft_to_right;
22348 break;
22349 case R2L:
22350 return Qright_to_left;
22351 break;
22352 default:
22353 emacs_abort ();
22358 DEFUN ("bidi-find-overridden-directionality",
22359 Fbidi_find_overridden_directionality,
22360 Sbidi_find_overridden_directionality, 2, 3, 0,
22361 doc: /* Return position between FROM and TO where directionality was overridden.
22363 This function returns the first character position in the specified
22364 region of OBJECT where there is a character whose `bidi-class' property
22365 is `L', but which was forced to display as `R' by a directional
22366 override, and likewise with characters whose `bidi-class' is `R'
22367 or `AL' that were forced to display as `L'.
22369 If no such character is found, the function returns nil.
22371 OBJECT is a Lisp string or buffer to search for overridden
22372 directionality, and defaults to the current buffer if nil or omitted.
22373 OBJECT can also be a window, in which case the function will search
22374 the buffer displayed in that window. Passing the window instead of
22375 a buffer is preferable when the buffer is displayed in some window,
22376 because this function will then be able to correctly account for
22377 window-specific overlays, which can affect the results.
22379 Strong directional characters `L', `R', and `AL' can have their
22380 intrinsic directionality overridden by directional override
22381 control characters RLO (u+202e) and LRO (u+202d). See the
22382 function `get-char-code-property' for a way to inquire about
22383 the `bidi-class' property of a character. */)
22384 (Lisp_Object from, Lisp_Object to, Lisp_Object object)
22386 struct buffer *buf = current_buffer;
22387 struct buffer *old = buf;
22388 struct window *w = NULL;
22389 bool frame_window_p = FRAME_WINDOW_P (SELECTED_FRAME ());
22390 struct bidi_it itb;
22391 ptrdiff_t from_pos, to_pos, from_bpos;
22392 void *itb_data;
22394 if (!NILP (object))
22396 if (BUFFERP (object))
22397 buf = XBUFFER (object);
22398 else if (WINDOWP (object))
22400 w = decode_live_window (object);
22401 buf = XBUFFER (w->contents);
22402 frame_window_p = FRAME_WINDOW_P (XFRAME (w->frame));
22404 else
22405 CHECK_STRING (object);
22408 if (STRINGP (object))
22410 /* Characters in unibyte strings are always treated by bidi.c as
22411 strong LTR. */
22412 if (!STRING_MULTIBYTE (object)
22413 /* When we are loading loadup.el, the character property
22414 tables needed for bidi iteration are not yet
22415 available. */
22416 || redisplay__inhibit_bidi)
22417 return Qnil;
22419 validate_subarray (object, from, to, SCHARS (object), &from_pos, &to_pos);
22420 if (from_pos >= SCHARS (object))
22421 return Qnil;
22423 /* Set up the bidi iterator. */
22424 itb_data = bidi_shelve_cache ();
22425 itb.paragraph_dir = NEUTRAL_DIR;
22426 itb.string.lstring = object;
22427 itb.string.s = NULL;
22428 itb.string.schars = SCHARS (object);
22429 itb.string.bufpos = 0;
22430 itb.string.from_disp_str = false;
22431 itb.string.unibyte = false;
22432 itb.w = w;
22433 bidi_init_it (0, 0, frame_window_p, &itb);
22435 else
22437 /* Nothing this fancy can happen in unibyte buffers, or in a
22438 buffer that disabled reordering, or if FROM is at EOB. */
22439 if (NILP (BVAR (buf, bidi_display_reordering))
22440 || NILP (BVAR (buf, enable_multibyte_characters))
22441 /* When we are loading loadup.el, the character property
22442 tables needed for bidi iteration are not yet
22443 available. */
22444 || redisplay__inhibit_bidi)
22445 return Qnil;
22447 set_buffer_temp (buf);
22448 validate_region (&from, &to);
22449 from_pos = XINT (from);
22450 to_pos = XINT (to);
22451 if (from_pos >= ZV)
22452 return Qnil;
22454 /* Set up the bidi iterator. */
22455 itb_data = bidi_shelve_cache ();
22456 from_bpos = CHAR_TO_BYTE (from_pos);
22457 if (from_pos == BEGV)
22459 itb.charpos = BEGV;
22460 itb.bytepos = BEGV_BYTE;
22462 else if (FETCH_CHAR (from_bpos - 1) == '\n')
22464 itb.charpos = from_pos;
22465 itb.bytepos = from_bpos;
22467 else
22468 itb.charpos = find_newline_no_quit (from_pos, CHAR_TO_BYTE (from_pos),
22469 -1, &itb.bytepos);
22470 itb.paragraph_dir = NEUTRAL_DIR;
22471 itb.string.s = NULL;
22472 itb.string.lstring = Qnil;
22473 itb.string.bufpos = 0;
22474 itb.string.from_disp_str = false;
22475 itb.string.unibyte = false;
22476 itb.w = w;
22477 bidi_init_it (itb.charpos, itb.bytepos, frame_window_p, &itb);
22480 ptrdiff_t found;
22481 do {
22482 /* For the purposes of this function, the actual base direction of
22483 the paragraph doesn't matter, so just set it to L2R. */
22484 bidi_paragraph_init (L2R, &itb, false);
22485 while ((found = bidi_find_first_overridden (&itb)) < from_pos)
22487 } while (found == ZV && itb.ch == '\n' && itb.charpos < to_pos);
22489 bidi_unshelve_cache (itb_data, false);
22490 set_buffer_temp (old);
22492 return (from_pos <= found && found < to_pos) ? make_number (found) : Qnil;
22495 DEFUN ("move-point-visually", Fmove_point_visually,
22496 Smove_point_visually, 1, 1, 0,
22497 doc: /* Move point in the visual order in the specified DIRECTION.
22498 DIRECTION can be 1, meaning move to the right, or -1, which moves to the
22499 left.
22501 Value is the new character position of point. */)
22502 (Lisp_Object direction)
22504 struct window *w = XWINDOW (selected_window);
22505 struct buffer *b = XBUFFER (w->contents);
22506 struct glyph_row *row;
22507 int dir;
22508 Lisp_Object paragraph_dir;
22510 #define ROW_GLYPH_NEWLINE_P(ROW,GLYPH) \
22511 (!(ROW)->continued_p \
22512 && NILP ((GLYPH)->object) \
22513 && (GLYPH)->type == CHAR_GLYPH \
22514 && (GLYPH)->u.ch == ' ' \
22515 && (GLYPH)->charpos >= 0 \
22516 && !(GLYPH)->avoid_cursor_p)
22518 CHECK_NUMBER (direction);
22519 dir = XINT (direction);
22520 if (dir > 0)
22521 dir = 1;
22522 else
22523 dir = -1;
22525 /* If current matrix is up-to-date, we can use the information
22526 recorded in the glyphs, at least as long as the goal is on the
22527 screen. */
22528 if (w->window_end_valid
22529 && !windows_or_buffers_changed
22530 && b
22531 && !b->clip_changed
22532 && !b->prevent_redisplay_optimizations_p
22533 && !window_outdated (w)
22534 /* We rely below on the cursor coordinates to be up to date, but
22535 we cannot trust them if some command moved point since the
22536 last complete redisplay. */
22537 && w->last_point == BUF_PT (b)
22538 && w->cursor.vpos >= 0
22539 && w->cursor.vpos < w->current_matrix->nrows
22540 && (row = MATRIX_ROW (w->current_matrix, w->cursor.vpos))->enabled_p)
22542 struct glyph *g = row->glyphs[TEXT_AREA];
22543 struct glyph *e = dir > 0 ? g + row->used[TEXT_AREA] : g - 1;
22544 struct glyph *gpt = g + w->cursor.hpos;
22546 for (g = gpt + dir; (dir > 0 ? g < e : g > e); g += dir)
22548 if (BUFFERP (g->object) && g->charpos != PT)
22550 SET_PT (g->charpos);
22551 w->cursor.vpos = -1;
22552 return make_number (PT);
22554 else if (!NILP (g->object) && !EQ (g->object, gpt->object))
22556 ptrdiff_t new_pos;
22558 if (BUFFERP (gpt->object))
22560 new_pos = PT;
22561 if ((gpt->resolved_level - row->reversed_p) % 2 == 0)
22562 new_pos += (row->reversed_p ? -dir : dir);
22563 else
22564 new_pos -= (row->reversed_p ? -dir : dir);
22565 new_pos = clip_to_bounds (BEGV, new_pos, ZV);
22566 /* If we didn't move, we've hit BEGV or ZV, so we
22567 need to signal a suitable error. */
22568 if (new_pos == PT)
22569 break;
22571 else if (BUFFERP (g->object))
22572 new_pos = g->charpos;
22573 else
22574 break;
22575 SET_PT (new_pos);
22576 w->cursor.vpos = -1;
22577 return make_number (PT);
22579 else if (ROW_GLYPH_NEWLINE_P (row, g))
22581 /* Glyphs inserted at the end of a non-empty line for
22582 positioning the cursor have zero charpos, so we must
22583 deduce the value of point by other means. */
22584 if (g->charpos > 0)
22585 SET_PT (g->charpos);
22586 else if (row->ends_at_zv_p && PT != ZV)
22587 SET_PT (ZV);
22588 else if (PT != MATRIX_ROW_END_CHARPOS (row) - 1)
22589 SET_PT (MATRIX_ROW_END_CHARPOS (row) - 1);
22590 else
22591 break;
22592 w->cursor.vpos = -1;
22593 return make_number (PT);
22596 if (g == e || NILP (g->object))
22598 if (row->truncated_on_left_p || row->truncated_on_right_p)
22599 goto simulate_display;
22600 if (!row->reversed_p)
22601 row += dir;
22602 else
22603 row -= dir;
22604 if (!(MATRIX_FIRST_TEXT_ROW (w->current_matrix) <= row
22605 && row < MATRIX_BOTTOM_TEXT_ROW (w->current_matrix, w)))
22606 goto simulate_display;
22608 if (dir > 0)
22610 if (row->reversed_p && !row->continued_p)
22612 SET_PT (MATRIX_ROW_END_CHARPOS (row) - 1);
22613 w->cursor.vpos = -1;
22614 return make_number (PT);
22616 g = row->glyphs[TEXT_AREA];
22617 e = g + row->used[TEXT_AREA];
22618 for ( ; g < e; g++)
22620 if (BUFFERP (g->object)
22621 /* Empty lines have only one glyph, which stands
22622 for the newline, and whose charpos is the
22623 buffer position of the newline. */
22624 || ROW_GLYPH_NEWLINE_P (row, g)
22625 /* When the buffer ends in a newline, the line at
22626 EOB also has one glyph, but its charpos is -1. */
22627 || (row->ends_at_zv_p
22628 && !row->reversed_p
22629 && NILP (g->object)
22630 && g->type == CHAR_GLYPH
22631 && g->u.ch == ' '))
22633 if (g->charpos > 0)
22634 SET_PT (g->charpos);
22635 else if (!row->reversed_p
22636 && row->ends_at_zv_p
22637 && PT != ZV)
22638 SET_PT (ZV);
22639 else
22640 continue;
22641 w->cursor.vpos = -1;
22642 return make_number (PT);
22646 else
22648 if (!row->reversed_p && !row->continued_p)
22650 SET_PT (MATRIX_ROW_END_CHARPOS (row) - 1);
22651 w->cursor.vpos = -1;
22652 return make_number (PT);
22654 e = row->glyphs[TEXT_AREA];
22655 g = e + row->used[TEXT_AREA] - 1;
22656 for ( ; g >= e; g--)
22658 if (BUFFERP (g->object)
22659 || (ROW_GLYPH_NEWLINE_P (row, g)
22660 && g->charpos > 0)
22661 /* Empty R2L lines on GUI frames have the buffer
22662 position of the newline stored in the stretch
22663 glyph. */
22664 || g->type == STRETCH_GLYPH
22665 || (row->ends_at_zv_p
22666 && row->reversed_p
22667 && NILP (g->object)
22668 && g->type == CHAR_GLYPH
22669 && g->u.ch == ' '))
22671 if (g->charpos > 0)
22672 SET_PT (g->charpos);
22673 else if (row->reversed_p
22674 && row->ends_at_zv_p
22675 && PT != ZV)
22676 SET_PT (ZV);
22677 else
22678 continue;
22679 w->cursor.vpos = -1;
22680 return make_number (PT);
22687 simulate_display:
22689 /* If we wind up here, we failed to move by using the glyphs, so we
22690 need to simulate display instead. */
22692 if (b)
22693 paragraph_dir = Fcurrent_bidi_paragraph_direction (w->contents);
22694 else
22695 paragraph_dir = Qleft_to_right;
22696 if (EQ (paragraph_dir, Qright_to_left))
22697 dir = -dir;
22698 if (PT <= BEGV && dir < 0)
22699 xsignal0 (Qbeginning_of_buffer);
22700 else if (PT >= ZV && dir > 0)
22701 xsignal0 (Qend_of_buffer);
22702 else
22704 struct text_pos pt;
22705 struct it it;
22706 int pt_x, target_x, pixel_width, pt_vpos;
22707 bool at_eol_p;
22708 bool overshoot_expected = false;
22709 bool target_is_eol_p = false;
22711 /* Setup the arena. */
22712 SET_TEXT_POS (pt, PT, PT_BYTE);
22713 start_display (&it, w, pt);
22714 /* When lines are truncated, we could be called with point
22715 outside of the windows edges, in which case move_it_*
22716 functions either prematurely stop at window's edge or jump to
22717 the next screen line, whereas we rely below on our ability to
22718 reach point, in order to start from its X coordinate. So we
22719 need to disregard the window's horizontal extent in that case. */
22720 if (it.line_wrap == TRUNCATE)
22721 it.last_visible_x = DISP_INFINITY;
22723 if (it.cmp_it.id < 0
22724 && it.method == GET_FROM_STRING
22725 && it.area == TEXT_AREA
22726 && it.string_from_display_prop_p
22727 && (it.sp > 0 && it.stack[it.sp - 1].method == GET_FROM_BUFFER))
22728 overshoot_expected = true;
22730 /* Find the X coordinate of point. We start from the beginning
22731 of this or previous line to make sure we are before point in
22732 the logical order (since the move_it_* functions can only
22733 move forward). */
22734 reseat:
22735 reseat_at_previous_visible_line_start (&it);
22736 it.current_x = it.hpos = it.current_y = it.vpos = 0;
22737 if (IT_CHARPOS (it) != PT)
22739 move_it_to (&it, overshoot_expected ? PT - 1 : PT,
22740 -1, -1, -1, MOVE_TO_POS);
22741 /* If we missed point because the character there is
22742 displayed out of a display vector that has more than one
22743 glyph, retry expecting overshoot. */
22744 if (it.method == GET_FROM_DISPLAY_VECTOR
22745 && it.current.dpvec_index > 0
22746 && !overshoot_expected)
22748 overshoot_expected = true;
22749 goto reseat;
22751 else if (IT_CHARPOS (it) != PT && !overshoot_expected)
22752 move_it_in_display_line (&it, PT, -1, MOVE_TO_POS);
22754 pt_x = it.current_x;
22755 pt_vpos = it.vpos;
22756 if (dir > 0 || overshoot_expected)
22758 struct glyph_row *row = it.glyph_row;
22760 /* When point is at beginning of line, we don't have
22761 information about the glyph there loaded into struct
22762 it. Calling get_next_display_element fixes that. */
22763 if (pt_x == 0)
22764 get_next_display_element (&it);
22765 at_eol_p = ITERATOR_AT_END_OF_LINE_P (&it);
22766 it.glyph_row = NULL;
22767 PRODUCE_GLYPHS (&it); /* compute it.pixel_width */
22768 it.glyph_row = row;
22769 /* PRODUCE_GLYPHS advances it.current_x, so we must restore
22770 it, lest it will become out of sync with it's buffer
22771 position. */
22772 it.current_x = pt_x;
22774 else
22775 at_eol_p = ITERATOR_AT_END_OF_LINE_P (&it);
22776 pixel_width = it.pixel_width;
22777 if (overshoot_expected && at_eol_p)
22778 pixel_width = 0;
22779 else if (pixel_width <= 0)
22780 pixel_width = 1;
22782 /* If there's a display string (or something similar) at point,
22783 we are actually at the glyph to the left of point, so we need
22784 to correct the X coordinate. */
22785 if (overshoot_expected)
22787 if (it.bidi_p)
22788 pt_x += pixel_width * it.bidi_it.scan_dir;
22789 else
22790 pt_x += pixel_width;
22793 /* Compute target X coordinate, either to the left or to the
22794 right of point. On TTY frames, all characters have the same
22795 pixel width of 1, so we can use that. On GUI frames we don't
22796 have an easy way of getting at the pixel width of the
22797 character to the left of point, so we use a different method
22798 of getting to that place. */
22799 if (dir > 0)
22800 target_x = pt_x + pixel_width;
22801 else
22802 target_x = pt_x - (!FRAME_WINDOW_P (it.f)) * pixel_width;
22804 /* Target X coordinate could be one line above or below the line
22805 of point, in which case we need to adjust the target X
22806 coordinate. Also, if moving to the left, we need to begin at
22807 the left edge of the point's screen line. */
22808 if (dir < 0)
22810 if (pt_x > 0)
22812 start_display (&it, w, pt);
22813 if (it.line_wrap == TRUNCATE)
22814 it.last_visible_x = DISP_INFINITY;
22815 reseat_at_previous_visible_line_start (&it);
22816 it.current_x = it.current_y = it.hpos = 0;
22817 if (pt_vpos != 0)
22818 move_it_by_lines (&it, pt_vpos);
22820 else
22822 move_it_by_lines (&it, -1);
22823 target_x = it.last_visible_x - !FRAME_WINDOW_P (it.f);
22824 target_is_eol_p = true;
22825 /* Under word-wrap, we don't know the x coordinate of
22826 the last character displayed on the previous line,
22827 which immediately precedes the wrap point. To find
22828 out its x coordinate, we try moving to the right
22829 margin of the window, which will stop at the wrap
22830 point, and then reset target_x to point at the
22831 character that precedes the wrap point. This is not
22832 needed on GUI frames, because (see below) there we
22833 move from the left margin one grapheme cluster at a
22834 time, and stop when we hit the wrap point. */
22835 if (!FRAME_WINDOW_P (it.f) && it.line_wrap == WORD_WRAP)
22837 void *it_data = NULL;
22838 struct it it2;
22840 SAVE_IT (it2, it, it_data);
22841 move_it_in_display_line_to (&it, ZV, target_x,
22842 MOVE_TO_POS | MOVE_TO_X);
22843 /* If we arrived at target_x, that _is_ the last
22844 character on the previous line. */
22845 if (it.current_x != target_x)
22846 target_x = it.current_x - 1;
22847 RESTORE_IT (&it, &it2, it_data);
22851 else
22853 if (at_eol_p
22854 || (target_x >= it.last_visible_x
22855 && it.line_wrap != TRUNCATE))
22857 if (pt_x > 0)
22858 move_it_by_lines (&it, 0);
22859 move_it_by_lines (&it, 1);
22860 target_x = 0;
22864 /* Move to the target X coordinate. */
22865 /* On GUI frames, as we don't know the X coordinate of the
22866 character to the left of point, moving point to the left
22867 requires walking, one grapheme cluster at a time, until we
22868 find ourself at a place immediately to the left of the
22869 character at point. */
22870 if (FRAME_WINDOW_P (it.f) && dir < 0)
22872 struct text_pos new_pos;
22873 enum move_it_result rc = MOVE_X_REACHED;
22875 if (it.current_x == 0)
22876 get_next_display_element (&it);
22877 if (it.what == IT_COMPOSITION)
22879 new_pos.charpos = it.cmp_it.charpos;
22880 new_pos.bytepos = -1;
22882 else
22883 new_pos = it.current.pos;
22885 while (it.current_x + it.pixel_width <= target_x
22886 && (rc == MOVE_X_REACHED
22887 /* Under word-wrap, move_it_in_display_line_to
22888 stops at correct coordinates, but sometimes
22889 returns MOVE_POS_MATCH_OR_ZV. */
22890 || (it.line_wrap == WORD_WRAP
22891 && rc == MOVE_POS_MATCH_OR_ZV)))
22893 int new_x = it.current_x + it.pixel_width;
22895 /* For composed characters, we want the position of the
22896 first character in the grapheme cluster (usually, the
22897 composition's base character), whereas it.current
22898 might give us the position of the _last_ one, e.g. if
22899 the composition is rendered in reverse due to bidi
22900 reordering. */
22901 if (it.what == IT_COMPOSITION)
22903 new_pos.charpos = it.cmp_it.charpos;
22904 new_pos.bytepos = -1;
22906 else
22907 new_pos = it.current.pos;
22908 if (new_x == it.current_x)
22909 new_x++;
22910 rc = move_it_in_display_line_to (&it, ZV, new_x,
22911 MOVE_TO_POS | MOVE_TO_X);
22912 if (ITERATOR_AT_END_OF_LINE_P (&it) && !target_is_eol_p)
22913 break;
22915 /* The previous position we saw in the loop is the one we
22916 want. */
22917 if (new_pos.bytepos == -1)
22918 new_pos.bytepos = CHAR_TO_BYTE (new_pos.charpos);
22919 it.current.pos = new_pos;
22921 else if (it.current_x != target_x)
22922 move_it_in_display_line_to (&it, ZV, target_x, MOVE_TO_POS | MOVE_TO_X);
22924 /* If we ended up in a display string that covers point, move to
22925 buffer position to the right in the visual order. */
22926 if (dir > 0)
22928 while (IT_CHARPOS (it) == PT)
22930 set_iterator_to_next (&it, false);
22931 if (!get_next_display_element (&it))
22932 break;
22936 /* Move point to that position. */
22937 SET_PT_BOTH (IT_CHARPOS (it), IT_BYTEPOS (it));
22940 return make_number (PT);
22942 #undef ROW_GLYPH_NEWLINE_P
22945 DEFUN ("bidi-resolved-levels", Fbidi_resolved_levels,
22946 Sbidi_resolved_levels, 0, 1, 0,
22947 doc: /* Return the resolved bidirectional levels of characters at VPOS.
22949 The resolved levels are produced by the Emacs bidi reordering engine
22950 that implements the UBA, the Unicode Bidirectional Algorithm. Please
22951 read the Unicode Standard Annex 9 (UAX#9) for background information
22952 about these levels.
22954 VPOS is the zero-based number of the current window's screen line
22955 for which to produce the resolved levels. If VPOS is nil or omitted,
22956 it defaults to the screen line of point. If the window displays a
22957 header line, VPOS of zero will report on the header line, and first
22958 line of text in the window will have VPOS of 1.
22960 Value is an array of resolved levels, indexed by glyph number.
22961 Glyphs are numbered from zero starting from the beginning of the
22962 screen line, i.e. the left edge of the window for left-to-right lines
22963 and from the right edge for right-to-left lines. The resolved levels
22964 are produced only for the window's text area; text in display margins
22965 is not included.
22967 If the selected window's display is not up-to-date, or if the specified
22968 screen line does not display text, this function returns nil. It is
22969 highly recommended to bind this function to some simple key, like F8,
22970 in order to avoid these problems.
22972 This function exists mainly for testing the correctness of the
22973 Emacs UBA implementation, in particular with the test suite. */)
22974 (Lisp_Object vpos)
22976 struct window *w = XWINDOW (selected_window);
22977 struct buffer *b = XBUFFER (w->contents);
22978 int nrow;
22979 struct glyph_row *row;
22981 if (NILP (vpos))
22983 int d1, d2, d3, d4, d5;
22985 pos_visible_p (w, PT, &d1, &d2, &d3, &d4, &d5, &nrow);
22987 else
22989 CHECK_NUMBER_COERCE_MARKER (vpos);
22990 nrow = XINT (vpos);
22993 /* We require up-to-date glyph matrix for this window. */
22994 if (w->window_end_valid
22995 && !windows_or_buffers_changed
22996 && b
22997 && !b->clip_changed
22998 && !b->prevent_redisplay_optimizations_p
22999 && !window_outdated (w)
23000 && nrow >= 0
23001 && nrow < w->current_matrix->nrows
23002 && (row = MATRIX_ROW (w->current_matrix, nrow))->enabled_p
23003 && MATRIX_ROW_DISPLAYS_TEXT_P (row))
23005 struct glyph *g, *e, *g1;
23006 int nglyphs, i;
23007 Lisp_Object levels;
23009 if (!row->reversed_p) /* Left-to-right glyph row. */
23011 g = g1 = row->glyphs[TEXT_AREA];
23012 e = g + row->used[TEXT_AREA];
23014 /* Skip over glyphs at the start of the row that was
23015 generated by redisplay for its own needs. */
23016 while (g < e
23017 && NILP (g->object)
23018 && g->charpos < 0)
23019 g++;
23020 g1 = g;
23022 /* Count the "interesting" glyphs in this row. */
23023 for (nglyphs = 0; g < e && !NILP (g->object); g++)
23024 nglyphs++;
23026 /* Create and fill the array. */
23027 levels = make_uninit_vector (nglyphs);
23028 for (i = 0; g1 < g; i++, g1++)
23029 ASET (levels, i, make_number (g1->resolved_level));
23031 else /* Right-to-left glyph row. */
23033 g = row->glyphs[TEXT_AREA] + row->used[TEXT_AREA] - 1;
23034 e = row->glyphs[TEXT_AREA] - 1;
23035 while (g > e
23036 && NILP (g->object)
23037 && g->charpos < 0)
23038 g--;
23039 g1 = g;
23040 for (nglyphs = 0; g > e && !NILP (g->object); g--)
23041 nglyphs++;
23042 levels = make_uninit_vector (nglyphs);
23043 for (i = 0; g1 > g; i++, g1--)
23044 ASET (levels, i, make_number (g1->resolved_level));
23046 return levels;
23048 else
23049 return Qnil;
23054 /***********************************************************************
23055 Menu Bar
23056 ***********************************************************************/
23058 /* Redisplay the menu bar in the frame for window W.
23060 The menu bar of X frames that don't have X toolkit support is
23061 displayed in a special window W->frame->menu_bar_window.
23063 The menu bar of terminal frames is treated specially as far as
23064 glyph matrices are concerned. Menu bar lines are not part of
23065 windows, so the update is done directly on the frame matrix rows
23066 for the menu bar. */
23068 static void
23069 display_menu_bar (struct window *w)
23071 struct frame *f = XFRAME (WINDOW_FRAME (w));
23072 struct it it;
23073 Lisp_Object items;
23074 int i;
23076 /* Don't do all this for graphical frames. */
23077 #ifdef HAVE_NTGUI
23078 if (FRAME_W32_P (f))
23079 return;
23080 #endif
23081 #if defined (USE_X_TOOLKIT) || defined (USE_GTK)
23082 if (FRAME_X_P (f))
23083 return;
23084 #endif
23086 #ifdef HAVE_NS
23087 if (FRAME_NS_P (f))
23088 return;
23089 #endif /* HAVE_NS */
23091 #if defined (USE_X_TOOLKIT) || defined (USE_GTK)
23092 eassert (!FRAME_WINDOW_P (f));
23093 init_iterator (&it, w, -1, -1, f->desired_matrix->rows, MENU_FACE_ID);
23094 it.first_visible_x = 0;
23095 it.last_visible_x = FRAME_PIXEL_WIDTH (f);
23096 #elif defined (HAVE_X_WINDOWS) /* X without toolkit. */
23097 if (FRAME_WINDOW_P (f))
23099 /* Menu bar lines are displayed in the desired matrix of the
23100 dummy window menu_bar_window. */
23101 struct window *menu_w;
23102 menu_w = XWINDOW (f->menu_bar_window);
23103 init_iterator (&it, menu_w, -1, -1, menu_w->desired_matrix->rows,
23104 MENU_FACE_ID);
23105 it.first_visible_x = 0;
23106 it.last_visible_x = FRAME_PIXEL_WIDTH (f);
23108 else
23109 #endif /* not USE_X_TOOLKIT and not USE_GTK */
23111 /* This is a TTY frame, i.e. character hpos/vpos are used as
23112 pixel x/y. */
23113 init_iterator (&it, w, -1, -1, f->desired_matrix->rows,
23114 MENU_FACE_ID);
23115 it.first_visible_x = 0;
23116 it.last_visible_x = FRAME_COLS (f);
23119 /* FIXME: This should be controlled by a user option. See the
23120 comments in redisplay_tool_bar and display_mode_line about
23121 this. */
23122 it.paragraph_embedding = L2R;
23124 /* Clear all rows of the menu bar. */
23125 for (i = 0; i < FRAME_MENU_BAR_LINES (f); ++i)
23127 struct glyph_row *row = it.glyph_row + i;
23128 clear_glyph_row (row);
23129 row->enabled_p = true;
23130 row->full_width_p = true;
23131 row->reversed_p = false;
23134 /* Display all items of the menu bar. */
23135 items = FRAME_MENU_BAR_ITEMS (it.f);
23136 for (i = 0; i < ASIZE (items); i += 4)
23138 Lisp_Object string;
23140 /* Stop at nil string. */
23141 string = AREF (items, i + 1);
23142 if (NILP (string))
23143 break;
23145 /* Remember where item was displayed. */
23146 ASET (items, i + 3, make_number (it.hpos));
23148 /* Display the item, pad with one space. */
23149 if (it.current_x < it.last_visible_x)
23150 display_string (NULL, string, Qnil, 0, 0, &it,
23151 SCHARS (string) + 1, 0, 0, -1);
23154 /* Fill out the line with spaces. */
23155 if (it.current_x < it.last_visible_x)
23156 display_string ("", Qnil, Qnil, 0, 0, &it, -1, 0, 0, -1);
23158 /* Compute the total height of the lines. */
23159 compute_line_metrics (&it);
23162 /* Deep copy of a glyph row, including the glyphs. */
23163 static void
23164 deep_copy_glyph_row (struct glyph_row *to, struct glyph_row *from)
23166 struct glyph *pointers[1 + LAST_AREA];
23167 int to_used = to->used[TEXT_AREA];
23169 /* Save glyph pointers of TO. */
23170 memcpy (pointers, to->glyphs, sizeof to->glyphs);
23172 /* Do a structure assignment. */
23173 *to = *from;
23175 /* Restore original glyph pointers of TO. */
23176 memcpy (to->glyphs, pointers, sizeof to->glyphs);
23178 /* Copy the glyphs. */
23179 memcpy (to->glyphs[TEXT_AREA], from->glyphs[TEXT_AREA],
23180 min (from->used[TEXT_AREA], to_used) * sizeof (struct glyph));
23182 /* If we filled only part of the TO row, fill the rest with
23183 space_glyph (which will display as empty space). */
23184 if (to_used > from->used[TEXT_AREA])
23185 fill_up_frame_row_with_spaces (to, to_used);
23188 /* Display one menu item on a TTY, by overwriting the glyphs in the
23189 frame F's desired glyph matrix with glyphs produced from the menu
23190 item text. Called from term.c to display TTY drop-down menus one
23191 item at a time.
23193 ITEM_TEXT is the menu item text as a C string.
23195 FACE_ID is the face ID to be used for this menu item. FACE_ID
23196 could specify one of 3 faces: a face for an enabled item, a face
23197 for a disabled item, or a face for a selected item.
23199 X and Y are coordinates of the first glyph in the frame's desired
23200 matrix to be overwritten by the menu item. Since this is a TTY, Y
23201 is the zero-based number of the glyph row and X is the zero-based
23202 glyph number in the row, starting from left, where to start
23203 displaying the item.
23205 SUBMENU means this menu item drops down a submenu, which
23206 should be indicated by displaying a proper visual cue after the
23207 item text. */
23209 void
23210 display_tty_menu_item (const char *item_text, int width, int face_id,
23211 int x, int y, bool submenu)
23213 struct it it;
23214 struct frame *f = SELECTED_FRAME ();
23215 struct window *w = XWINDOW (f->selected_window);
23216 struct glyph_row *row;
23217 size_t item_len = strlen (item_text);
23219 eassert (FRAME_TERMCAP_P (f));
23221 /* Don't write beyond the matrix's last row. This can happen for
23222 TTY screens that are not high enough to show the entire menu.
23223 (This is actually a bit of defensive programming, as
23224 tty_menu_display already limits the number of menu items to one
23225 less than the number of screen lines.) */
23226 if (y >= f->desired_matrix->nrows)
23227 return;
23229 init_iterator (&it, w, -1, -1, f->desired_matrix->rows + y, MENU_FACE_ID);
23230 it.first_visible_x = 0;
23231 it.last_visible_x = FRAME_COLS (f) - 1;
23232 row = it.glyph_row;
23233 /* Start with the row contents from the current matrix. */
23234 deep_copy_glyph_row (row, f->current_matrix->rows + y);
23235 bool saved_width = row->full_width_p;
23236 row->full_width_p = true;
23237 bool saved_reversed = row->reversed_p;
23238 row->reversed_p = false;
23239 row->enabled_p = true;
23241 /* Arrange for the menu item glyphs to start at (X,Y) and have the
23242 desired face. */
23243 eassert (x < f->desired_matrix->matrix_w);
23244 it.current_x = it.hpos = x;
23245 it.current_y = it.vpos = y;
23246 int saved_used = row->used[TEXT_AREA];
23247 bool saved_truncated = row->truncated_on_right_p;
23248 row->used[TEXT_AREA] = x;
23249 it.face_id = face_id;
23250 it.line_wrap = TRUNCATE;
23252 /* FIXME: This should be controlled by a user option. See the
23253 comments in redisplay_tool_bar and display_mode_line about this.
23254 Also, if paragraph_embedding could ever be R2L, changes will be
23255 needed to avoid shifting to the right the row characters in
23256 term.c:append_glyph. */
23257 it.paragraph_embedding = L2R;
23259 /* Pad with a space on the left. */
23260 display_string (" ", Qnil, Qnil, 0, 0, &it, 1, 0, FRAME_COLS (f) - 1, -1);
23261 width--;
23262 /* Display the menu item, pad with spaces to WIDTH. */
23263 if (submenu)
23265 display_string (item_text, Qnil, Qnil, 0, 0, &it,
23266 item_len, 0, FRAME_COLS (f) - 1, -1);
23267 width -= item_len;
23268 /* Indicate with " >" that there's a submenu. */
23269 display_string (" >", Qnil, Qnil, 0, 0, &it, width, 0,
23270 FRAME_COLS (f) - 1, -1);
23272 else
23273 display_string (item_text, Qnil, Qnil, 0, 0, &it,
23274 width, 0, FRAME_COLS (f) - 1, -1);
23276 row->used[TEXT_AREA] = max (saved_used, row->used[TEXT_AREA]);
23277 row->truncated_on_right_p = saved_truncated;
23278 row->hash = row_hash (row);
23279 row->full_width_p = saved_width;
23280 row->reversed_p = saved_reversed;
23283 /***********************************************************************
23284 Mode Line
23285 ***********************************************************************/
23287 /* Redisplay mode lines in the window tree whose root is WINDOW.
23288 If FORCE, redisplay mode lines unconditionally.
23289 Otherwise, redisplay only mode lines that are garbaged. Value is
23290 the number of windows whose mode lines were redisplayed. */
23292 static int
23293 redisplay_mode_lines (Lisp_Object window, bool force)
23295 int nwindows = 0;
23297 while (!NILP (window))
23299 struct window *w = XWINDOW (window);
23301 if (WINDOWP (w->contents))
23302 nwindows += redisplay_mode_lines (w->contents, force);
23303 else if (force
23304 || FRAME_GARBAGED_P (XFRAME (w->frame))
23305 || !MATRIX_MODE_LINE_ROW (w->current_matrix)->enabled_p)
23307 struct text_pos lpoint;
23308 struct buffer *old = current_buffer;
23310 /* Set the window's buffer for the mode line display. */
23311 SET_TEXT_POS (lpoint, PT, PT_BYTE);
23312 set_buffer_internal_1 (XBUFFER (w->contents));
23314 /* Point refers normally to the selected window. For any
23315 other window, set up appropriate value. */
23316 if (!EQ (window, selected_window))
23318 struct text_pos pt;
23320 CLIP_TEXT_POS_FROM_MARKER (pt, w->pointm);
23321 TEMP_SET_PT_BOTH (CHARPOS (pt), BYTEPOS (pt));
23324 /* Display mode lines. */
23325 clear_glyph_matrix (w->desired_matrix);
23326 if (display_mode_lines (w))
23327 ++nwindows;
23329 /* Restore old settings. */
23330 set_buffer_internal_1 (old);
23331 TEMP_SET_PT_BOTH (CHARPOS (lpoint), BYTEPOS (lpoint));
23334 window = w->next;
23337 return nwindows;
23341 /* Display the mode and/or header line of window W. Value is the
23342 sum number of mode lines and header lines displayed. */
23344 static int
23345 display_mode_lines (struct window *w)
23347 Lisp_Object old_selected_window = selected_window;
23348 Lisp_Object old_selected_frame = selected_frame;
23349 Lisp_Object new_frame = w->frame;
23350 Lisp_Object old_frame_selected_window = XFRAME (new_frame)->selected_window;
23351 int n = 0;
23353 if (window_wants_mode_line (w))
23355 Lisp_Object window;
23356 Lisp_Object default_help
23357 = buffer_local_value (Qmode_line_default_help_echo, w->contents);
23359 /* Set up mode line help echo. Do this before selecting w so it
23360 can reasonably tell whether a mouse click will select w. */
23361 XSETWINDOW (window, w);
23362 if (FUNCTIONP (default_help))
23363 wset_mode_line_help_echo (w, safe_call1 (default_help, window));
23364 else if (STRINGP (default_help))
23365 wset_mode_line_help_echo (w, default_help);
23366 else
23367 wset_mode_line_help_echo (w, Qnil);
23370 selected_frame = new_frame;
23371 /* FIXME: If we were to allow the mode-line's computation changing the buffer
23372 or window's point, then we'd need select_window_1 here as well. */
23373 XSETWINDOW (selected_window, w);
23374 XFRAME (new_frame)->selected_window = selected_window;
23376 /* These will be set while the mode line specs are processed. */
23377 line_number_displayed = false;
23378 w->column_number_displayed = -1;
23380 if (window_wants_mode_line (w))
23382 Lisp_Object window_mode_line_format
23383 = window_parameter (w, Qmode_line_format);
23384 struct window *sel_w = XWINDOW (old_selected_window);
23386 /* Select mode line face based on the real selected window. */
23387 display_mode_line (w, CURRENT_MODE_LINE_FACE_ID_3 (sel_w, sel_w, w),
23388 NILP (window_mode_line_format)
23389 ? BVAR (current_buffer, mode_line_format)
23390 : window_mode_line_format);
23391 ++n;
23394 if (window_wants_header_line (w))
23396 Lisp_Object window_header_line_format
23397 = window_parameter (w, Qheader_line_format);
23399 display_mode_line (w, HEADER_LINE_FACE_ID,
23400 NILP (window_header_line_format)
23401 ? BVAR (current_buffer, header_line_format)
23402 : window_header_line_format);
23403 ++n;
23406 XFRAME (new_frame)->selected_window = old_frame_selected_window;
23407 selected_frame = old_selected_frame;
23408 selected_window = old_selected_window;
23409 if (n > 0)
23410 w->must_be_updated_p = true;
23411 return n;
23415 /* Display mode or header line of window W. FACE_ID specifies which
23416 line to display; it is either MODE_LINE_FACE_ID or
23417 HEADER_LINE_FACE_ID. FORMAT is the mode/header line format to
23418 display. Value is the pixel height of the mode/header line
23419 displayed. */
23421 static int
23422 display_mode_line (struct window *w, enum face_id face_id, Lisp_Object format)
23424 struct it it;
23425 struct face *face;
23426 ptrdiff_t count = SPECPDL_INDEX ();
23428 init_iterator (&it, w, -1, -1, NULL, face_id);
23429 /* Don't extend on a previously drawn mode-line.
23430 This may happen if called from pos_visible_p. */
23431 it.glyph_row->enabled_p = false;
23432 prepare_desired_row (w, it.glyph_row, true);
23434 it.glyph_row->mode_line_p = true;
23436 /* FIXME: This should be controlled by a user option. But
23437 supporting such an option is not trivial, since the mode line is
23438 made up of many separate strings. */
23439 it.paragraph_embedding = L2R;
23441 record_unwind_protect (unwind_format_mode_line,
23442 format_mode_line_unwind_data (NULL, NULL,
23443 Qnil, false));
23445 mode_line_target = MODE_LINE_DISPLAY;
23447 /* Temporarily make frame's keyboard the current kboard so that
23448 kboard-local variables in the mode_line_format will get the right
23449 values. */
23450 push_kboard (FRAME_KBOARD (it.f));
23451 record_unwind_save_match_data ();
23452 display_mode_element (&it, 0, 0, 0, format, Qnil, false);
23453 pop_kboard ();
23455 unbind_to (count, Qnil);
23457 /* Fill up with spaces. */
23458 display_string (" ", Qnil, Qnil, 0, 0, &it, 10000, -1, -1, 0);
23460 compute_line_metrics (&it);
23461 it.glyph_row->full_width_p = true;
23462 it.glyph_row->continued_p = false;
23463 it.glyph_row->truncated_on_left_p = false;
23464 it.glyph_row->truncated_on_right_p = false;
23466 /* Make a 3D mode-line have a shadow at its right end. */
23467 face = FACE_FROM_ID (it.f, face_id);
23468 extend_face_to_end_of_line (&it);
23469 if (face->box != FACE_NO_BOX)
23471 struct glyph *last = (it.glyph_row->glyphs[TEXT_AREA]
23472 + it.glyph_row->used[TEXT_AREA] - 1);
23473 last->right_box_line_p = true;
23476 return it.glyph_row->height;
23479 /* Move element ELT in LIST to the front of LIST.
23480 Return the updated list. */
23482 static Lisp_Object
23483 move_elt_to_front (Lisp_Object elt, Lisp_Object list)
23485 register Lisp_Object tail, prev;
23486 register Lisp_Object tem;
23488 tail = list;
23489 prev = Qnil;
23490 while (CONSP (tail))
23492 tem = XCAR (tail);
23494 if (EQ (elt, tem))
23496 /* Splice out the link TAIL. */
23497 if (NILP (prev))
23498 list = XCDR (tail);
23499 else
23500 Fsetcdr (prev, XCDR (tail));
23502 /* Now make it the first. */
23503 Fsetcdr (tail, list);
23504 return tail;
23506 else
23507 prev = tail;
23508 tail = XCDR (tail);
23509 maybe_quit ();
23512 /* Not found--return unchanged LIST. */
23513 return list;
23516 /* Contribute ELT to the mode line for window IT->w. How it
23517 translates into text depends on its data type.
23519 IT describes the display environment in which we display, as usual.
23521 DEPTH is the depth in recursion. It is used to prevent
23522 infinite recursion here.
23524 FIELD_WIDTH is the number of characters the display of ELT should
23525 occupy in the mode line, and PRECISION is the maximum number of
23526 characters to display from ELT's representation. See
23527 display_string for details.
23529 Returns the hpos of the end of the text generated by ELT.
23531 PROPS is a property list to add to any string we encounter.
23533 If RISKY, remove (disregard) any properties in any string
23534 we encounter, and ignore :eval and :propertize.
23536 The global variable `mode_line_target' determines whether the
23537 output is passed to `store_mode_line_noprop',
23538 `store_mode_line_string', or `display_string'. */
23540 static int
23541 display_mode_element (struct it *it, int depth, int field_width, int precision,
23542 Lisp_Object elt, Lisp_Object props, bool risky)
23544 int n = 0, field, prec;
23545 bool literal = false;
23547 tail_recurse:
23548 if (depth > 100)
23549 elt = build_string ("*too-deep*");
23551 depth++;
23553 switch (XTYPE (elt))
23555 case Lisp_String:
23557 /* A string: output it and check for %-constructs within it. */
23558 unsigned char c;
23559 ptrdiff_t offset = 0;
23561 if (SCHARS (elt) > 0
23562 && (!NILP (props) || risky))
23564 Lisp_Object oprops, aelt;
23565 oprops = Ftext_properties_at (make_number (0), elt);
23567 /* If the starting string's properties are not what
23568 we want, translate the string. Also, if the string
23569 is risky, do that anyway. */
23571 if (NILP (Fequal (props, oprops)) || risky)
23573 /* If the starting string has properties,
23574 merge the specified ones onto the existing ones. */
23575 if (! NILP (oprops) && !risky)
23577 Lisp_Object tem;
23579 oprops = Fcopy_sequence (oprops);
23580 tem = props;
23581 while (CONSP (tem))
23583 oprops = Fplist_put (oprops, XCAR (tem),
23584 XCAR (XCDR (tem)));
23585 tem = XCDR (XCDR (tem));
23587 props = oprops;
23590 aelt = Fassoc (elt, mode_line_proptrans_alist, Qnil);
23591 if (! NILP (aelt) && !NILP (Fequal (props, XCDR (aelt))))
23593 /* AELT is what we want. Move it to the front
23594 without consing. */
23595 elt = XCAR (aelt);
23596 mode_line_proptrans_alist
23597 = move_elt_to_front (aelt, mode_line_proptrans_alist);
23599 else
23601 Lisp_Object tem;
23603 /* If AELT has the wrong props, it is useless.
23604 so get rid of it. */
23605 if (! NILP (aelt))
23606 mode_line_proptrans_alist
23607 = Fdelq (aelt, mode_line_proptrans_alist);
23609 elt = Fcopy_sequence (elt);
23610 Fset_text_properties (make_number (0), Flength (elt),
23611 props, elt);
23612 /* Add this item to mode_line_proptrans_alist. */
23613 mode_line_proptrans_alist
23614 = Fcons (Fcons (elt, props),
23615 mode_line_proptrans_alist);
23616 /* Truncate mode_line_proptrans_alist
23617 to at most 50 elements. */
23618 tem = Fnthcdr (make_number (50),
23619 mode_line_proptrans_alist);
23620 if (! NILP (tem))
23621 XSETCDR (tem, Qnil);
23626 offset = 0;
23628 if (literal)
23630 prec = precision - n;
23631 switch (mode_line_target)
23633 case MODE_LINE_NOPROP:
23634 case MODE_LINE_TITLE:
23635 n += store_mode_line_noprop (SSDATA (elt), -1, prec);
23636 break;
23637 case MODE_LINE_STRING:
23638 n += store_mode_line_string (NULL, elt, true, 0, prec, Qnil);
23639 break;
23640 case MODE_LINE_DISPLAY:
23641 n += display_string (NULL, elt, Qnil, 0, 0, it,
23642 0, prec, 0, STRING_MULTIBYTE (elt));
23643 break;
23646 break;
23649 /* Handle the non-literal case. */
23651 while ((precision <= 0 || n < precision)
23652 && SREF (elt, offset) != 0
23653 && (mode_line_target != MODE_LINE_DISPLAY
23654 || it->current_x < it->last_visible_x))
23656 ptrdiff_t last_offset = offset;
23658 /* Advance to end of string or next format specifier. */
23659 while ((c = SREF (elt, offset++)) != '\0' && c != '%')
23662 if (offset - 1 != last_offset)
23664 ptrdiff_t nchars, nbytes;
23666 /* Output to end of string or up to '%'. Field width
23667 is length of string. Don't output more than
23668 PRECISION allows us. */
23669 offset--;
23671 prec = c_string_width (SDATA (elt) + last_offset,
23672 offset - last_offset, precision - n,
23673 &nchars, &nbytes);
23675 switch (mode_line_target)
23677 case MODE_LINE_NOPROP:
23678 case MODE_LINE_TITLE:
23679 n += store_mode_line_noprop (SSDATA (elt) + last_offset, 0, prec);
23680 break;
23681 case MODE_LINE_STRING:
23683 ptrdiff_t bytepos = last_offset;
23684 ptrdiff_t charpos = string_byte_to_char (elt, bytepos);
23685 ptrdiff_t endpos = (precision <= 0
23686 ? string_byte_to_char (elt, offset)
23687 : charpos + nchars);
23688 Lisp_Object mode_string
23689 = Fsubstring (elt, make_number (charpos),
23690 make_number (endpos));
23691 n += store_mode_line_string (NULL, mode_string, false,
23692 0, 0, Qnil);
23694 break;
23695 case MODE_LINE_DISPLAY:
23697 ptrdiff_t bytepos = last_offset;
23698 ptrdiff_t charpos = string_byte_to_char (elt, bytepos);
23700 if (precision <= 0)
23701 nchars = string_byte_to_char (elt, offset) - charpos;
23702 n += display_string (NULL, elt, Qnil, 0, charpos,
23703 it, 0, nchars, 0,
23704 STRING_MULTIBYTE (elt));
23706 break;
23709 else /* c == '%' */
23711 ptrdiff_t percent_position = offset;
23713 /* Get the specified minimum width. Zero means
23714 don't pad. */
23715 field = 0;
23716 while ((c = SREF (elt, offset++)) >= '0' && c <= '9')
23717 field = field * 10 + c - '0';
23719 /* Don't pad beyond the total padding allowed. */
23720 if (field_width - n > 0 && field > field_width - n)
23721 field = field_width - n;
23723 /* Note that either PRECISION <= 0 or N < PRECISION. */
23724 prec = precision - n;
23726 if (c == 'M')
23727 n += display_mode_element (it, depth, field, prec,
23728 Vglobal_mode_string, props,
23729 risky);
23730 else if (c != 0)
23732 bool multibyte;
23733 ptrdiff_t bytepos, charpos;
23734 const char *spec;
23735 Lisp_Object string;
23737 bytepos = percent_position;
23738 charpos = (STRING_MULTIBYTE (elt)
23739 ? string_byte_to_char (elt, bytepos)
23740 : bytepos);
23741 spec = decode_mode_spec (it->w, c, field, &string);
23742 multibyte = STRINGP (string) && STRING_MULTIBYTE (string);
23744 switch (mode_line_target)
23746 case MODE_LINE_NOPROP:
23747 case MODE_LINE_TITLE:
23748 n += store_mode_line_noprop (spec, field, prec);
23749 break;
23750 case MODE_LINE_STRING:
23752 Lisp_Object tem = build_string (spec);
23753 props = Ftext_properties_at (make_number (charpos), elt);
23754 /* Should only keep face property in props */
23755 n += store_mode_line_string (NULL, tem, false,
23756 field, prec, props);
23758 break;
23759 case MODE_LINE_DISPLAY:
23761 int nglyphs_before, nwritten;
23763 nglyphs_before = it->glyph_row->used[TEXT_AREA];
23764 nwritten = display_string (spec, string, elt,
23765 charpos, 0, it,
23766 field, prec, 0,
23767 multibyte);
23769 /* Assign to the glyphs written above the
23770 string where the `%x' came from, position
23771 of the `%'. */
23772 if (nwritten > 0)
23774 struct glyph *glyph
23775 = (it->glyph_row->glyphs[TEXT_AREA]
23776 + nglyphs_before);
23777 int i;
23779 for (i = 0; i < nwritten; ++i)
23781 glyph[i].object = elt;
23782 glyph[i].charpos = charpos;
23785 n += nwritten;
23788 break;
23791 else /* c == 0 */
23792 break;
23796 break;
23798 case Lisp_Symbol:
23799 /* A symbol: process the value of the symbol recursively
23800 as if it appeared here directly. Avoid error if symbol void.
23801 Special case: if value of symbol is a string, output the string
23802 literally. */
23804 register Lisp_Object tem;
23806 /* If the variable is not marked as risky to set
23807 then its contents are risky to use. */
23808 if (NILP (Fget (elt, Qrisky_local_variable)))
23809 risky = true;
23811 tem = Fboundp (elt);
23812 if (!NILP (tem))
23814 tem = Fsymbol_value (elt);
23815 /* If value is a string, output that string literally:
23816 don't check for % within it. */
23817 if (STRINGP (tem))
23818 literal = true;
23820 if (!EQ (tem, elt))
23822 /* Give up right away for nil or t. */
23823 elt = tem;
23824 goto tail_recurse;
23828 break;
23830 case Lisp_Cons:
23832 register Lisp_Object car, tem;
23834 /* A cons cell: five distinct cases.
23835 If first element is :eval or :propertize, do something special.
23836 If first element is a string or a cons, process all the elements
23837 and effectively concatenate them.
23838 If first element is a negative number, truncate displaying cdr to
23839 at most that many characters. If positive, pad (with spaces)
23840 to at least that many characters.
23841 If first element is a symbol, process the cadr or caddr recursively
23842 according to whether the symbol's value is non-nil or nil. */
23843 car = XCAR (elt);
23844 if (EQ (car, QCeval))
23846 /* An element of the form (:eval FORM) means evaluate FORM
23847 and use the result as mode line elements. */
23849 if (risky)
23850 break;
23852 if (CONSP (XCDR (elt)))
23854 Lisp_Object spec;
23855 spec = safe__eval (true, XCAR (XCDR (elt)));
23856 /* The :eval form could delete the frame stored in the
23857 iterator, which will cause a crash if we try to
23858 access faces and other fields (e.g., FRAME_KBOARD)
23859 on that frame. This is a nonsensical thing to do,
23860 and signaling an error from redisplay might be
23861 dangerous, but we cannot continue with an invalid frame. */
23862 if (!FRAME_LIVE_P (it->f))
23863 signal_error (":eval deleted the frame being displayed", elt);
23864 n += display_mode_element (it, depth, field_width - n,
23865 precision - n, spec, props,
23866 risky);
23869 else if (EQ (car, QCpropertize))
23871 /* An element of the form (:propertize ELT PROPS...)
23872 means display ELT but applying properties PROPS. */
23874 if (risky)
23875 break;
23877 if (CONSP (XCDR (elt)))
23878 n += display_mode_element (it, depth, field_width - n,
23879 precision - n, XCAR (XCDR (elt)),
23880 XCDR (XCDR (elt)), risky);
23882 else if (SYMBOLP (car))
23884 tem = Fboundp (car);
23885 elt = XCDR (elt);
23886 if (!CONSP (elt))
23887 goto invalid;
23888 /* elt is now the cdr, and we know it is a cons cell.
23889 Use its car if CAR has a non-nil value. */
23890 if (!NILP (tem))
23892 tem = Fsymbol_value (car);
23893 if (!NILP (tem))
23895 elt = XCAR (elt);
23896 goto tail_recurse;
23899 /* Symbol's value is nil (or symbol is unbound)
23900 Get the cddr of the original list
23901 and if possible find the caddr and use that. */
23902 elt = XCDR (elt);
23903 if (NILP (elt))
23904 break;
23905 else if (!CONSP (elt))
23906 goto invalid;
23907 elt = XCAR (elt);
23908 goto tail_recurse;
23910 else if (INTEGERP (car))
23912 register int lim = XINT (car);
23913 elt = XCDR (elt);
23914 if (lim < 0)
23916 /* Negative int means reduce maximum width. */
23917 if (precision <= 0)
23918 precision = -lim;
23919 else
23920 precision = min (precision, -lim);
23922 else if (lim > 0)
23924 /* Padding specified. Don't let it be more than
23925 current maximum. */
23926 if (precision > 0)
23927 lim = min (precision, lim);
23929 /* If that's more padding than already wanted, queue it.
23930 But don't reduce padding already specified even if
23931 that is beyond the current truncation point. */
23932 field_width = max (lim, field_width);
23934 goto tail_recurse;
23936 else if (STRINGP (car) || CONSP (car))
23937 FOR_EACH_TAIL_SAFE (elt)
23939 if (0 < precision && precision <= n)
23940 break;
23941 n += display_mode_element (it, depth,
23942 /* Pad after only the last
23943 list element. */
23944 (! CONSP (XCDR (elt))
23945 ? field_width - n
23946 : 0),
23947 precision - n, XCAR (elt),
23948 props, risky);
23951 break;
23953 default:
23954 invalid:
23955 elt = build_string ("*invalid*");
23956 goto tail_recurse;
23959 /* Pad to FIELD_WIDTH. */
23960 if (field_width > 0 && n < field_width)
23962 switch (mode_line_target)
23964 case MODE_LINE_NOPROP:
23965 case MODE_LINE_TITLE:
23966 n += store_mode_line_noprop ("", field_width - n, 0);
23967 break;
23968 case MODE_LINE_STRING:
23969 n += store_mode_line_string ("", Qnil, false, field_width - n, 0,
23970 Qnil);
23971 break;
23972 case MODE_LINE_DISPLAY:
23973 n += display_string ("", Qnil, Qnil, 0, 0, it, field_width - n,
23974 0, 0, 0);
23975 break;
23979 return n;
23982 /* Store a mode-line string element in mode_line_string_list.
23984 If STRING is non-null, display that C string. Otherwise, the Lisp
23985 string LISP_STRING is displayed.
23987 FIELD_WIDTH is the minimum number of output glyphs to produce.
23988 If STRING has fewer characters than FIELD_WIDTH, pad to the right
23989 with spaces. FIELD_WIDTH <= 0 means don't pad.
23991 PRECISION is the maximum number of characters to output from
23992 STRING. PRECISION <= 0 means don't truncate the string.
23994 If COPY_STRING, make a copy of LISP_STRING before adding
23995 properties to the string.
23997 PROPS are the properties to add to the string.
23998 The mode_line_string_face face property is always added to the string.
24001 static int
24002 store_mode_line_string (const char *string, Lisp_Object lisp_string,
24003 bool copy_string,
24004 int field_width, int precision, Lisp_Object props)
24006 ptrdiff_t len;
24007 int n = 0;
24009 if (string != NULL)
24011 len = strlen (string);
24012 if (precision > 0 && len > precision)
24013 len = precision;
24014 lisp_string = make_string (string, len);
24015 if (NILP (props))
24016 props = mode_line_string_face_prop;
24017 else if (!NILP (mode_line_string_face))
24019 Lisp_Object face = Fplist_get (props, Qface);
24020 props = Fcopy_sequence (props);
24021 if (NILP (face))
24022 face = mode_line_string_face;
24023 else
24024 face = list2 (face, mode_line_string_face);
24025 props = Fplist_put (props, Qface, face);
24027 Fadd_text_properties (make_number (0), make_number (len),
24028 props, lisp_string);
24030 else
24032 len = XFASTINT (Flength (lisp_string));
24033 if (precision > 0 && len > precision)
24035 len = precision;
24036 lisp_string = Fsubstring (lisp_string, make_number (0), make_number (len));
24037 precision = -1;
24039 if (!NILP (mode_line_string_face))
24041 Lisp_Object face;
24042 if (NILP (props))
24043 props = Ftext_properties_at (make_number (0), lisp_string);
24044 face = Fplist_get (props, Qface);
24045 if (NILP (face))
24046 face = mode_line_string_face;
24047 else
24048 face = list2 (face, mode_line_string_face);
24049 props = list2 (Qface, face);
24050 if (copy_string)
24051 lisp_string = Fcopy_sequence (lisp_string);
24053 if (!NILP (props))
24054 Fadd_text_properties (make_number (0), make_number (len),
24055 props, lisp_string);
24058 if (len > 0)
24060 mode_line_string_list = Fcons (lisp_string, mode_line_string_list);
24061 n += len;
24064 if (field_width > len)
24066 field_width -= len;
24067 lisp_string = Fmake_string (make_number (field_width), make_number (' '),
24068 Qnil);
24069 if (!NILP (props))
24070 Fadd_text_properties (make_number (0), make_number (field_width),
24071 props, lisp_string);
24072 mode_line_string_list = Fcons (lisp_string, mode_line_string_list);
24073 n += field_width;
24076 return n;
24080 DEFUN ("format-mode-line", Fformat_mode_line, Sformat_mode_line,
24081 1, 4, 0,
24082 doc: /* Format a string out of a mode line format specification.
24083 First arg FORMAT specifies the mode line format (see `mode-line-format'
24084 for details) to use.
24086 By default, the format is evaluated for the currently selected window.
24088 Optional second arg FACE specifies the face property to put on all
24089 characters for which no face is specified. The value nil means the
24090 default face. The value t means whatever face the window's mode line
24091 currently uses (either `mode-line' or `mode-line-inactive',
24092 depending on whether the window is the selected window or not).
24093 An integer value means the value string has no text
24094 properties.
24096 Optional third and fourth args WINDOW and BUFFER specify the window
24097 and buffer to use as the context for the formatting (defaults
24098 are the selected window and the WINDOW's buffer). */)
24099 (Lisp_Object format, Lisp_Object face,
24100 Lisp_Object window, Lisp_Object buffer)
24102 struct it it;
24103 int len;
24104 struct window *w;
24105 struct buffer *old_buffer = NULL;
24106 int face_id;
24107 bool no_props = INTEGERP (face);
24108 ptrdiff_t count = SPECPDL_INDEX ();
24109 Lisp_Object str;
24110 int string_start = 0;
24112 w = decode_any_window (window);
24113 XSETWINDOW (window, w);
24115 if (NILP (buffer))
24116 buffer = w->contents;
24117 CHECK_BUFFER (buffer);
24119 /* Make formatting the modeline a non-op when noninteractive, otherwise
24120 there will be problems later caused by a partially initialized frame. */
24121 if (NILP (format) || noninteractive)
24122 return empty_unibyte_string;
24124 if (no_props)
24125 face = Qnil;
24127 face_id = (NILP (face) || EQ (face, Qdefault)) ? DEFAULT_FACE_ID
24128 : EQ (face, Qt) ? (EQ (window, selected_window)
24129 ? MODE_LINE_FACE_ID : MODE_LINE_INACTIVE_FACE_ID)
24130 : EQ (face, Qmode_line) ? MODE_LINE_FACE_ID
24131 : EQ (face, Qmode_line_inactive) ? MODE_LINE_INACTIVE_FACE_ID
24132 : EQ (face, Qheader_line) ? HEADER_LINE_FACE_ID
24133 : EQ (face, Qtool_bar) ? TOOL_BAR_FACE_ID
24134 : DEFAULT_FACE_ID;
24136 old_buffer = current_buffer;
24138 /* Save things including mode_line_proptrans_alist,
24139 and set that to nil so that we don't alter the outer value. */
24140 record_unwind_protect (unwind_format_mode_line,
24141 format_mode_line_unwind_data
24142 (XFRAME (WINDOW_FRAME (w)),
24143 old_buffer, selected_window, true));
24144 mode_line_proptrans_alist = Qnil;
24146 Fselect_window (window, Qt);
24147 set_buffer_internal_1 (XBUFFER (buffer));
24149 init_iterator (&it, w, -1, -1, NULL, face_id);
24151 if (no_props)
24153 mode_line_target = MODE_LINE_NOPROP;
24154 mode_line_string_face_prop = Qnil;
24155 mode_line_string_list = Qnil;
24156 string_start = MODE_LINE_NOPROP_LEN (0);
24158 else
24160 mode_line_target = MODE_LINE_STRING;
24161 mode_line_string_list = Qnil;
24162 mode_line_string_face = face;
24163 mode_line_string_face_prop
24164 = NILP (face) ? Qnil : list2 (Qface, face);
24167 push_kboard (FRAME_KBOARD (it.f));
24168 display_mode_element (&it, 0, 0, 0, format, Qnil, false);
24169 pop_kboard ();
24171 if (no_props)
24173 len = MODE_LINE_NOPROP_LEN (string_start);
24174 str = make_string (mode_line_noprop_buf + string_start, len);
24176 else
24178 mode_line_string_list = Fnreverse (mode_line_string_list);
24179 str = Fmapconcat (Qidentity, mode_line_string_list,
24180 empty_unibyte_string);
24183 unbind_to (count, Qnil);
24184 return str;
24187 /* Write a null-terminated, right justified decimal representation of
24188 the positive integer D to BUF using a minimal field width WIDTH. */
24190 static void
24191 pint2str (register char *buf, register int width, register ptrdiff_t d)
24193 register char *p = buf;
24195 if (d <= 0)
24196 *p++ = '0';
24197 else
24199 while (d > 0)
24201 *p++ = d % 10 + '0';
24202 d /= 10;
24206 for (width -= (int) (p - buf); width > 0; --width)
24207 *p++ = ' ';
24208 *p-- = '\0';
24209 while (p > buf)
24211 d = *buf;
24212 *buf++ = *p;
24213 *p-- = d;
24217 /* Write a null-terminated, right justified decimal and "human
24218 readable" representation of the nonnegative integer D to BUF using
24219 a minimal field width WIDTH. D should be smaller than 999.5e24. */
24221 static const char power_letter[] =
24223 0, /* no letter */
24224 'k', /* kilo */
24225 'M', /* mega */
24226 'G', /* giga */
24227 'T', /* tera */
24228 'P', /* peta */
24229 'E', /* exa */
24230 'Z', /* zetta */
24231 'Y' /* yotta */
24234 static void
24235 pint2hrstr (char *buf, int width, ptrdiff_t d)
24237 /* We aim to represent the nonnegative integer D as
24238 QUOTIENT.TENTHS * 10 ^ (3 * EXPONENT). */
24239 ptrdiff_t quotient = d;
24240 int remainder = 0;
24241 /* -1 means: do not use TENTHS. */
24242 int tenths = -1;
24243 int exponent = 0;
24245 /* Length of QUOTIENT.TENTHS as a string. */
24246 int length;
24248 char * psuffix;
24249 char * p;
24251 if (quotient >= 1000)
24253 /* Scale to the appropriate EXPONENT. */
24256 remainder = quotient % 1000;
24257 quotient /= 1000;
24258 exponent++;
24260 while (quotient >= 1000);
24262 /* Round to nearest and decide whether to use TENTHS or not. */
24263 if (quotient <= 9)
24265 tenths = remainder / 100;
24266 if (remainder % 100 >= 50)
24268 if (tenths < 9)
24269 tenths++;
24270 else
24272 quotient++;
24273 if (quotient == 10)
24274 tenths = -1;
24275 else
24276 tenths = 0;
24280 else
24281 if (remainder >= 500)
24283 if (quotient < 999)
24284 quotient++;
24285 else
24287 quotient = 1;
24288 exponent++;
24289 tenths = 0;
24294 /* Calculate the LENGTH of QUOTIENT.TENTHS as a string. */
24295 if (tenths == -1 && quotient <= 99)
24296 if (quotient <= 9)
24297 length = 1;
24298 else
24299 length = 2;
24300 else
24301 length = 3;
24302 p = psuffix = buf + max (width, length);
24304 /* Print EXPONENT. */
24305 *psuffix++ = power_letter[exponent];
24306 *psuffix = '\0';
24308 /* Print TENTHS. */
24309 if (tenths >= 0)
24311 *--p = '0' + tenths;
24312 *--p = '.';
24315 /* Print QUOTIENT. */
24318 int digit = quotient % 10;
24319 *--p = '0' + digit;
24321 while ((quotient /= 10) != 0);
24323 /* Print leading spaces. */
24324 while (buf < p)
24325 *--p = ' ';
24328 /* Set a mnemonic character for coding_system (Lisp symbol) in BUF.
24329 If EOL_FLAG, set also a mnemonic character for end-of-line
24330 type of CODING_SYSTEM. Return updated pointer into BUF. */
24332 static unsigned char invalid_eol_type[] = "(*invalid*)";
24334 static char *
24335 decode_mode_spec_coding (Lisp_Object coding_system, char *buf, bool eol_flag)
24337 Lisp_Object val;
24338 bool multibyte = !NILP (BVAR (current_buffer, enable_multibyte_characters));
24339 const unsigned char *eol_str;
24340 int eol_str_len;
24341 /* The EOL conversion we are using. */
24342 Lisp_Object eoltype;
24344 val = CODING_SYSTEM_SPEC (coding_system);
24345 eoltype = Qnil;
24347 if (!VECTORP (val)) /* Not yet decided. */
24349 *buf++ = multibyte ? '-' : ' ';
24350 if (eol_flag)
24351 eoltype = eol_mnemonic_undecided;
24352 /* Don't mention EOL conversion if it isn't decided. */
24354 else
24356 Lisp_Object attrs;
24357 Lisp_Object eolvalue;
24359 attrs = AREF (val, 0);
24360 eolvalue = AREF (val, 2);
24362 *buf++ = multibyte
24363 ? XFASTINT (CODING_ATTR_MNEMONIC (attrs))
24364 : ' ';
24366 if (eol_flag)
24368 /* The EOL conversion that is normal on this system. */
24370 if (NILP (eolvalue)) /* Not yet decided. */
24371 eoltype = eol_mnemonic_undecided;
24372 else if (VECTORP (eolvalue)) /* Not yet decided. */
24373 eoltype = eol_mnemonic_undecided;
24374 else /* eolvalue is Qunix, Qdos, or Qmac. */
24375 eoltype = (EQ (eolvalue, Qunix)
24376 ? eol_mnemonic_unix
24377 : EQ (eolvalue, Qdos)
24378 ? eol_mnemonic_dos : eol_mnemonic_mac);
24382 if (eol_flag)
24384 /* Mention the EOL conversion if it is not the usual one. */
24385 if (STRINGP (eoltype))
24387 eol_str = SDATA (eoltype);
24388 eol_str_len = SBYTES (eoltype);
24390 else if (CHARACTERP (eoltype))
24392 int c = XFASTINT (eoltype);
24393 return buf + CHAR_STRING (c, (unsigned char *) buf);
24395 else
24397 eol_str = invalid_eol_type;
24398 eol_str_len = sizeof (invalid_eol_type) - 1;
24400 memcpy (buf, eol_str, eol_str_len);
24401 buf += eol_str_len;
24404 return buf;
24407 /* Return the approximate percentage N is of D (rounding upward), or 99,
24408 whichever is less. Assume 0 < D and 0 <= N <= D * INT_MAX / 100. */
24410 static int
24411 percent99 (ptrdiff_t n, ptrdiff_t d)
24413 int percent = (d - 1 + 100.0 * n) / d;
24414 return min (percent, 99);
24417 /* Return a string for the output of a mode line %-spec for window W,
24418 generated by character C. FIELD_WIDTH > 0 means pad the string
24419 returned with spaces to that value. Return a Lisp string in
24420 *STRING if the resulting string is taken from that Lisp string.
24422 Note we operate on the current buffer for most purposes. */
24424 static char lots_of_dashes[] = "--------------------------------------------------------------------------------------------------------------------------------------------";
24426 static const char *
24427 decode_mode_spec (struct window *w, register int c, int field_width,
24428 Lisp_Object *string)
24430 Lisp_Object obj;
24431 struct frame *f = XFRAME (WINDOW_FRAME (w));
24432 char *decode_mode_spec_buf = f->decode_mode_spec_buffer;
24433 /* We are going to use f->decode_mode_spec_buffer as the buffer to
24434 produce strings from numerical values, so limit preposterously
24435 large values of FIELD_WIDTH to avoid overrunning the buffer's
24436 end. The size of the buffer is enough for FRAME_MESSAGE_BUF_SIZE
24437 bytes plus the terminating null. */
24438 int width = min (field_width, FRAME_MESSAGE_BUF_SIZE (f));
24439 struct buffer *b = current_buffer;
24441 obj = Qnil;
24442 *string = Qnil;
24444 switch (c)
24446 case '*':
24447 if (!NILP (BVAR (b, read_only)))
24448 return "%";
24449 if (BUF_MODIFF (b) > BUF_SAVE_MODIFF (b))
24450 return "*";
24451 return "-";
24453 case '+':
24454 /* This differs from %* only for a modified read-only buffer. */
24455 if (BUF_MODIFF (b) > BUF_SAVE_MODIFF (b))
24456 return "*";
24457 if (!NILP (BVAR (b, read_only)))
24458 return "%";
24459 return "-";
24461 case '&':
24462 /* This differs from %* in ignoring read-only-ness. */
24463 if (BUF_MODIFF (b) > BUF_SAVE_MODIFF (b))
24464 return "*";
24465 return "-";
24467 case '%':
24468 return "%";
24470 case '[':
24472 int i;
24473 char *p;
24475 if (command_loop_level > 5)
24476 return "[[[... ";
24477 p = decode_mode_spec_buf;
24478 for (i = 0; i < command_loop_level; i++)
24479 *p++ = '[';
24480 *p = 0;
24481 return decode_mode_spec_buf;
24484 case ']':
24486 int i;
24487 char *p;
24489 if (command_loop_level > 5)
24490 return " ...]]]";
24491 p = decode_mode_spec_buf;
24492 for (i = 0; i < command_loop_level; i++)
24493 *p++ = ']';
24494 *p = 0;
24495 return decode_mode_spec_buf;
24498 case '-':
24500 register int i;
24502 /* Let lots_of_dashes be a string of infinite length. */
24503 if (mode_line_target == MODE_LINE_NOPROP
24504 || mode_line_target == MODE_LINE_STRING)
24505 return "--";
24506 if (field_width <= 0
24507 || field_width > sizeof (lots_of_dashes))
24509 for (i = 0; i < FRAME_MESSAGE_BUF_SIZE (f) - 1; ++i)
24510 decode_mode_spec_buf[i] = '-';
24511 decode_mode_spec_buf[i] = '\0';
24512 return decode_mode_spec_buf;
24514 else
24515 return lots_of_dashes;
24518 case 'b':
24519 obj = BVAR (b, name);
24520 break;
24522 case 'c':
24523 case 'C':
24524 /* %c, %C, and %l are ignored in `frame-title-format'.
24525 (In redisplay_internal, the frame title is drawn _before_ the
24526 windows are updated, so the stuff which depends on actual
24527 window contents (such as %l) may fail to render properly, or
24528 even crash emacs.) */
24529 if (mode_line_target == MODE_LINE_TITLE)
24530 return "";
24531 else
24533 ptrdiff_t col = current_column ();
24534 int disp_col = (c == 'C') ? col + 1 : col;
24535 w->column_number_displayed = col;
24536 pint2str (decode_mode_spec_buf, width, disp_col);
24537 return decode_mode_spec_buf;
24540 case 'e':
24541 #if !defined SYSTEM_MALLOC && !defined HYBRID_MALLOC
24543 if (NILP (Vmemory_full))
24544 return "";
24545 else
24546 return "!MEM FULL! ";
24548 #else
24549 return "";
24550 #endif
24552 case 'F':
24553 /* %F displays the frame name. */
24554 if (!NILP (f->title))
24555 return SSDATA (f->title);
24556 if (f->explicit_name || ! FRAME_WINDOW_P (f))
24557 return SSDATA (f->name);
24558 return "Emacs";
24560 case 'f':
24561 obj = BVAR (b, filename);
24562 break;
24564 case 'i':
24566 ptrdiff_t size = ZV - BEGV;
24567 pint2str (decode_mode_spec_buf, width, size);
24568 return decode_mode_spec_buf;
24571 case 'I':
24573 ptrdiff_t size = ZV - BEGV;
24574 pint2hrstr (decode_mode_spec_buf, width, size);
24575 return decode_mode_spec_buf;
24578 case 'l':
24580 ptrdiff_t startpos, startpos_byte, line, linepos, linepos_byte;
24581 ptrdiff_t topline, nlines, height;
24582 ptrdiff_t junk;
24584 /* %c, %C, and %l are ignored in `frame-title-format'. */
24585 if (mode_line_target == MODE_LINE_TITLE)
24586 return "";
24588 startpos = marker_position (w->start);
24589 startpos_byte = marker_byte_position (w->start);
24590 height = WINDOW_TOTAL_LINES (w);
24592 /* If we decided that this buffer isn't suitable for line numbers,
24593 don't forget that too fast. */
24594 if (w->base_line_pos == -1)
24595 goto no_value;
24597 /* If the buffer is very big, don't waste time. */
24598 if (INTEGERP (Vline_number_display_limit)
24599 && BUF_ZV (b) - BUF_BEGV (b) > XINT (Vline_number_display_limit))
24601 w->base_line_pos = 0;
24602 w->base_line_number = 0;
24603 goto no_value;
24606 if (w->base_line_number > 0
24607 && w->base_line_pos > 0
24608 && w->base_line_pos <= startpos)
24610 line = w->base_line_number;
24611 linepos = w->base_line_pos;
24612 linepos_byte = buf_charpos_to_bytepos (b, linepos);
24614 else
24616 line = 1;
24617 linepos = BUF_BEGV (b);
24618 linepos_byte = BUF_BEGV_BYTE (b);
24621 /* Count lines from base line to window start position. */
24622 nlines = display_count_lines (linepos_byte,
24623 startpos_byte,
24624 startpos, &junk);
24626 topline = nlines + line;
24628 /* Determine a new base line, if the old one is too close
24629 or too far away, or if we did not have one.
24630 "Too close" means it's plausible a scroll-down would
24631 go back past it. */
24632 if (startpos == BUF_BEGV (b))
24634 w->base_line_number = topline;
24635 w->base_line_pos = BUF_BEGV (b);
24637 else if (nlines < height + 25 || nlines > height * 3 + 50
24638 || linepos == BUF_BEGV (b))
24640 ptrdiff_t limit = BUF_BEGV (b);
24641 ptrdiff_t limit_byte = BUF_BEGV_BYTE (b);
24642 ptrdiff_t position;
24643 ptrdiff_t distance =
24644 (height * 2 + 30) * line_number_display_limit_width;
24646 if (startpos - distance > limit)
24648 limit = startpos - distance;
24649 limit_byte = CHAR_TO_BYTE (limit);
24652 nlines = display_count_lines (startpos_byte,
24653 limit_byte,
24654 - (height * 2 + 30),
24655 &position);
24656 /* If we couldn't find the lines we wanted within
24657 line_number_display_limit_width chars per line,
24658 give up on line numbers for this window. */
24659 if (position == limit_byte && limit == startpos - distance)
24661 w->base_line_pos = -1;
24662 w->base_line_number = 0;
24663 goto no_value;
24666 w->base_line_number = topline - nlines;
24667 w->base_line_pos = BYTE_TO_CHAR (position);
24670 /* Now count lines from the start pos to point. */
24671 nlines = display_count_lines (startpos_byte,
24672 PT_BYTE, PT, &junk);
24674 /* Record that we did display the line number. */
24675 line_number_displayed = true;
24677 /* Make the string to show. */
24678 pint2str (decode_mode_spec_buf, width, topline + nlines);
24679 return decode_mode_spec_buf;
24680 no_value:
24682 char *p = decode_mode_spec_buf;
24683 int pad = width - 2;
24684 while (pad-- > 0)
24685 *p++ = ' ';
24686 *p++ = '?';
24687 *p++ = '?';
24688 *p = '\0';
24689 return decode_mode_spec_buf;
24692 break;
24694 case 'm':
24695 obj = BVAR (b, mode_name);
24696 break;
24698 case 'n':
24699 if (BUF_BEGV (b) > BUF_BEG (b) || BUF_ZV (b) < BUF_Z (b))
24700 return " Narrow";
24701 break;
24703 /* Display the "degree of travel" of the window through the buffer. */
24704 case 'o':
24706 ptrdiff_t toppos = marker_position (w->start);
24707 ptrdiff_t botpos = BUF_Z (b) - w->window_end_pos;
24708 ptrdiff_t begv = BUF_BEGV (b);
24709 ptrdiff_t zv = BUF_ZV (b);
24711 if (zv <= botpos)
24712 return toppos <= begv ? "All" : "Bottom";
24713 else if (toppos <= begv)
24714 return "Top";
24715 else
24717 sprintf (decode_mode_spec_buf, "%2d%%",
24718 percent99 (toppos - begv, (toppos - begv) + (zv - botpos)));
24719 return decode_mode_spec_buf;
24723 /* Display percentage of buffer above the top of the screen. */
24724 case 'p':
24726 ptrdiff_t pos = marker_position (w->start);
24727 ptrdiff_t begv = BUF_BEGV (b);
24728 ptrdiff_t zv = BUF_ZV (b);
24730 if (w->window_end_pos <= BUF_Z (b) - zv)
24731 return pos <= begv ? "All" : "Bottom";
24732 else if (pos <= begv)
24733 return "Top";
24734 else
24736 sprintf (decode_mode_spec_buf, "%2d%%",
24737 percent99 (pos - begv, zv - begv));
24738 return decode_mode_spec_buf;
24742 /* Display percentage of size above the bottom of the screen. */
24743 case 'P':
24745 ptrdiff_t toppos = marker_position (w->start);
24746 ptrdiff_t botpos = BUF_Z (b) - w->window_end_pos;
24747 ptrdiff_t begv = BUF_BEGV (b);
24748 ptrdiff_t zv = BUF_ZV (b);
24750 if (zv <= botpos)
24751 return toppos <= begv ? "All" : "Bottom";
24752 else
24754 sprintf (decode_mode_spec_buf,
24755 &"Top%2d%%"[begv < toppos ? sizeof "Top" - 1 : 0],
24756 percent99 (botpos - begv, zv - begv));
24757 return decode_mode_spec_buf;
24761 /* Display percentage offsets of top and bottom of the window,
24762 using "All" (but not "Top" or "Bottom") where appropriate. */
24763 case 'q':
24765 ptrdiff_t toppos = marker_position (w->start);
24766 ptrdiff_t botpos = BUF_Z (b) - w->window_end_pos;
24767 ptrdiff_t begv = BUF_BEGV (b);
24768 ptrdiff_t zv = BUF_ZV (b);
24769 int top_perc, bot_perc;
24771 if ((toppos <= begv) && (zv <= botpos))
24772 return "All ";
24774 top_perc = toppos <= begv ? 0 : percent99 (toppos - begv, zv - begv);
24775 bot_perc = zv <= botpos ? 100 : percent99 (botpos - begv, zv - begv);
24777 if (top_perc == bot_perc)
24778 sprintf (decode_mode_spec_buf, "%d%%", top_perc);
24779 else
24780 sprintf (decode_mode_spec_buf, "%d-%d%%", top_perc, bot_perc);
24782 return decode_mode_spec_buf;
24785 case 's':
24786 /* status of process */
24787 obj = Fget_buffer_process (Fcurrent_buffer ());
24788 if (NILP (obj))
24789 return "no process";
24790 #ifndef MSDOS
24791 obj = Fsymbol_name (Fprocess_status (obj));
24792 #endif
24793 break;
24795 case '@':
24797 ptrdiff_t count = inhibit_garbage_collection ();
24798 Lisp_Object curdir = BVAR (current_buffer, directory);
24799 Lisp_Object val = Qnil;
24801 if (STRINGP (curdir))
24802 val = call1 (intern ("file-remote-p"), curdir);
24804 unbind_to (count, Qnil);
24806 if (NILP (val))
24807 return "-";
24808 else
24809 return "@";
24812 case 'z':
24813 /* coding-system (not including end-of-line format) */
24814 case 'Z':
24815 /* coding-system (including end-of-line type) */
24817 bool eol_flag = (c == 'Z');
24818 char *p = decode_mode_spec_buf;
24820 if (! FRAME_WINDOW_P (f))
24822 /* No need to mention EOL here--the terminal never needs
24823 to do EOL conversion. */
24824 p = decode_mode_spec_coding (CODING_ID_NAME
24825 (FRAME_KEYBOARD_CODING (f)->id),
24826 p, false);
24827 p = decode_mode_spec_coding (CODING_ID_NAME
24828 (FRAME_TERMINAL_CODING (f)->id),
24829 p, false);
24831 p = decode_mode_spec_coding (BVAR (b, buffer_file_coding_system),
24832 p, eol_flag);
24834 #if false /* This proves to be annoying; I think we can do without. -- rms. */
24835 #ifdef subprocesses
24836 obj = Fget_buffer_process (Fcurrent_buffer ());
24837 if (PROCESSP (obj))
24839 p = decode_mode_spec_coding
24840 (XPROCESS (obj)->decode_coding_system, p, eol_flag);
24841 p = decode_mode_spec_coding
24842 (XPROCESS (obj)->encode_coding_system, p, eol_flag);
24844 #endif /* subprocesses */
24845 #endif /* false */
24846 *p = 0;
24847 return decode_mode_spec_buf;
24851 if (STRINGP (obj))
24853 *string = obj;
24854 return SSDATA (obj);
24856 else
24857 return "";
24861 /* Count up to COUNT lines starting from START_BYTE. COUNT negative
24862 means count lines back from START_BYTE. But don't go beyond
24863 LIMIT_BYTE. Return the number of lines thus found (always
24864 nonnegative).
24866 Set *BYTE_POS_PTR to the byte position where we stopped. This is
24867 either the position COUNT lines after/before START_BYTE, if we
24868 found COUNT lines, or LIMIT_BYTE if we hit the limit before finding
24869 COUNT lines. */
24871 static ptrdiff_t
24872 display_count_lines (ptrdiff_t start_byte,
24873 ptrdiff_t limit_byte, ptrdiff_t count,
24874 ptrdiff_t *byte_pos_ptr)
24876 register unsigned char *cursor;
24877 unsigned char *base;
24879 register ptrdiff_t ceiling;
24880 register unsigned char *ceiling_addr;
24881 ptrdiff_t orig_count = count;
24883 /* If we are not in selective display mode,
24884 check only for newlines. */
24885 bool selective_display
24886 = (!NILP (BVAR (current_buffer, selective_display))
24887 && !INTEGERP (BVAR (current_buffer, selective_display)));
24889 if (count > 0)
24891 while (start_byte < limit_byte)
24893 ceiling = BUFFER_CEILING_OF (start_byte);
24894 ceiling = min (limit_byte - 1, ceiling);
24895 ceiling_addr = BYTE_POS_ADDR (ceiling) + 1;
24896 base = (cursor = BYTE_POS_ADDR (start_byte));
24900 if (selective_display)
24902 while (*cursor != '\n' && *cursor != 015
24903 && ++cursor != ceiling_addr)
24904 continue;
24905 if (cursor == ceiling_addr)
24906 break;
24908 else
24910 cursor = memchr (cursor, '\n', ceiling_addr - cursor);
24911 if (! cursor)
24912 break;
24915 cursor++;
24917 if (--count == 0)
24919 start_byte += cursor - base;
24920 *byte_pos_ptr = start_byte;
24921 return orig_count;
24924 while (cursor < ceiling_addr);
24926 start_byte += ceiling_addr - base;
24929 else
24931 while (start_byte > limit_byte)
24933 ceiling = BUFFER_FLOOR_OF (start_byte - 1);
24934 ceiling = max (limit_byte, ceiling);
24935 ceiling_addr = BYTE_POS_ADDR (ceiling);
24936 base = (cursor = BYTE_POS_ADDR (start_byte - 1) + 1);
24937 while (true)
24939 if (selective_display)
24941 while (--cursor >= ceiling_addr
24942 && *cursor != '\n' && *cursor != 015)
24943 continue;
24944 if (cursor < ceiling_addr)
24945 break;
24947 else
24949 cursor = memrchr (ceiling_addr, '\n', cursor - ceiling_addr);
24950 if (! cursor)
24951 break;
24954 if (++count == 0)
24956 start_byte += cursor - base + 1;
24957 *byte_pos_ptr = start_byte;
24958 /* When scanning backwards, we should
24959 not count the newline posterior to which we stop. */
24960 return - orig_count - 1;
24963 start_byte += ceiling_addr - base;
24967 *byte_pos_ptr = limit_byte;
24969 if (count < 0)
24970 return - orig_count + count;
24971 return orig_count - count;
24977 /***********************************************************************
24978 Displaying strings
24979 ***********************************************************************/
24981 /* Display a NUL-terminated string, starting with index START.
24983 If STRING is non-null, display that C string. Otherwise, the Lisp
24984 string LISP_STRING is displayed. There's a case that STRING is
24985 non-null and LISP_STRING is not nil. It means STRING is a string
24986 data of LISP_STRING. In that case, we display LISP_STRING while
24987 ignoring its text properties.
24989 If FACE_STRING is not nil, FACE_STRING_POS is a position in
24990 FACE_STRING. Display STRING or LISP_STRING with the face at
24991 FACE_STRING_POS in FACE_STRING:
24993 Display the string in the environment given by IT, but use the
24994 standard display table, temporarily.
24996 FIELD_WIDTH is the minimum number of output glyphs to produce.
24997 If STRING has fewer characters than FIELD_WIDTH, pad to the right
24998 with spaces. If STRING has more characters, more than FIELD_WIDTH
24999 glyphs will be produced. FIELD_WIDTH <= 0 means don't pad.
25001 PRECISION is the maximum number of characters to output from
25002 STRING. PRECISION < 0 means don't truncate the string.
25004 This is roughly equivalent to printf format specifiers:
25006 FIELD_WIDTH PRECISION PRINTF
25007 ----------------------------------------
25008 -1 -1 %s
25009 -1 10 %.10s
25010 10 -1 %10s
25011 20 10 %20.10s
25013 MULTIBYTE zero means do not display multibyte chars, > 0 means do
25014 display them, and < 0 means obey the current buffer's value of
25015 enable_multibyte_characters.
25017 Value is the number of columns displayed. */
25019 static int
25020 display_string (const char *string, Lisp_Object lisp_string, Lisp_Object face_string,
25021 ptrdiff_t face_string_pos, ptrdiff_t start, struct it *it,
25022 int field_width, int precision, int max_x, int multibyte)
25024 int hpos_at_start = it->hpos;
25025 int saved_face_id = it->face_id;
25026 struct glyph_row *row = it->glyph_row;
25027 ptrdiff_t it_charpos;
25029 /* Initialize the iterator IT for iteration over STRING beginning
25030 with index START. */
25031 reseat_to_string (it, NILP (lisp_string) ? string : NULL, lisp_string, start,
25032 precision, field_width, multibyte);
25033 if (string && STRINGP (lisp_string))
25034 /* LISP_STRING is the one returned by decode_mode_spec. We should
25035 ignore its text properties. */
25036 it->stop_charpos = it->end_charpos;
25038 /* If displaying STRING, set up the face of the iterator from
25039 FACE_STRING, if that's given. */
25040 if (STRINGP (face_string))
25042 ptrdiff_t endptr;
25043 struct face *face;
25045 it->face_id
25046 = face_at_string_position (it->w, face_string, face_string_pos,
25047 0, &endptr, it->base_face_id, false);
25048 face = FACE_FROM_ID (it->f, it->face_id);
25049 it->face_box_p = face->box != FACE_NO_BOX;
25052 /* Set max_x to the maximum allowed X position. Don't let it go
25053 beyond the right edge of the window. */
25054 if (max_x <= 0)
25055 max_x = it->last_visible_x;
25056 else
25057 max_x = min (max_x, it->last_visible_x);
25059 /* Skip over display elements that are not visible. because IT->w is
25060 hscrolled. */
25061 if (it->current_x < it->first_visible_x)
25062 move_it_in_display_line_to (it, 100000, it->first_visible_x,
25063 MOVE_TO_POS | MOVE_TO_X);
25065 row->ascent = it->max_ascent;
25066 row->height = it->max_ascent + it->max_descent;
25067 row->phys_ascent = it->max_phys_ascent;
25068 row->phys_height = it->max_phys_ascent + it->max_phys_descent;
25069 row->extra_line_spacing = it->max_extra_line_spacing;
25071 if (STRINGP (it->string))
25072 it_charpos = IT_STRING_CHARPOS (*it);
25073 else
25074 it_charpos = IT_CHARPOS (*it);
25076 /* This condition is for the case that we are called with current_x
25077 past last_visible_x. */
25078 while (it->current_x < max_x)
25080 int x_before, x, n_glyphs_before, i, nglyphs;
25082 /* Get the next display element. */
25083 if (!get_next_display_element (it))
25084 break;
25086 /* Produce glyphs. */
25087 x_before = it->current_x;
25088 n_glyphs_before = row->used[TEXT_AREA];
25089 PRODUCE_GLYPHS (it);
25091 nglyphs = row->used[TEXT_AREA] - n_glyphs_before;
25092 i = 0;
25093 x = x_before;
25094 while (i < nglyphs)
25096 struct glyph *glyph = row->glyphs[TEXT_AREA] + n_glyphs_before + i;
25098 if (it->line_wrap != TRUNCATE
25099 && x + glyph->pixel_width > max_x)
25101 /* End of continued line or max_x reached. */
25102 if (CHAR_GLYPH_PADDING_P (*glyph))
25104 /* A wide character is unbreakable. */
25105 if (row->reversed_p)
25106 unproduce_glyphs (it, row->used[TEXT_AREA]
25107 - n_glyphs_before);
25108 row->used[TEXT_AREA] = n_glyphs_before;
25109 it->current_x = x_before;
25111 else
25113 if (row->reversed_p)
25114 unproduce_glyphs (it, row->used[TEXT_AREA]
25115 - (n_glyphs_before + i));
25116 row->used[TEXT_AREA] = n_glyphs_before + i;
25117 it->current_x = x;
25119 break;
25121 else if (x + glyph->pixel_width >= it->first_visible_x)
25123 /* Glyph is at least partially visible. */
25124 ++it->hpos;
25125 if (x < it->first_visible_x)
25126 row->x = x - it->first_visible_x;
25128 else
25130 /* Glyph is off the left margin of the display area.
25131 Should not happen. */
25132 emacs_abort ();
25135 row->ascent = max (row->ascent, it->max_ascent);
25136 row->height = max (row->height, it->max_ascent + it->max_descent);
25137 row->phys_ascent = max (row->phys_ascent, it->max_phys_ascent);
25138 row->phys_height = max (row->phys_height,
25139 it->max_phys_ascent + it->max_phys_descent);
25140 row->extra_line_spacing = max (row->extra_line_spacing,
25141 it->max_extra_line_spacing);
25142 x += glyph->pixel_width;
25143 ++i;
25146 /* Stop if max_x reached. */
25147 if (i < nglyphs)
25148 break;
25150 /* Stop at line ends. */
25151 if (ITERATOR_AT_END_OF_LINE_P (it))
25153 it->continuation_lines_width = 0;
25154 break;
25157 set_iterator_to_next (it, true);
25158 if (STRINGP (it->string))
25159 it_charpos = IT_STRING_CHARPOS (*it);
25160 else
25161 it_charpos = IT_CHARPOS (*it);
25163 /* Stop if truncating at the right edge. */
25164 if (it->line_wrap == TRUNCATE
25165 && it->current_x >= it->last_visible_x)
25167 /* Add truncation mark, but don't do it if the line is
25168 truncated at a padding space. */
25169 if (it_charpos < it->string_nchars)
25171 if (!FRAME_WINDOW_P (it->f))
25173 int ii, n;
25175 if (it->current_x > it->last_visible_x)
25177 if (!row->reversed_p)
25179 for (ii = row->used[TEXT_AREA] - 1; ii > 0; --ii)
25180 if (!CHAR_GLYPH_PADDING_P (row->glyphs[TEXT_AREA][ii]))
25181 break;
25183 else
25185 for (ii = 0; ii < row->used[TEXT_AREA]; ii++)
25186 if (!CHAR_GLYPH_PADDING_P (row->glyphs[TEXT_AREA][ii]))
25187 break;
25188 unproduce_glyphs (it, ii + 1);
25189 ii = row->used[TEXT_AREA] - (ii + 1);
25191 for (n = row->used[TEXT_AREA]; ii < n; ++ii)
25193 row->used[TEXT_AREA] = ii;
25194 produce_special_glyphs (it, IT_TRUNCATION);
25197 produce_special_glyphs (it, IT_TRUNCATION);
25199 row->truncated_on_right_p = true;
25201 break;
25205 /* Maybe insert a truncation at the left. */
25206 if (it->first_visible_x
25207 && it_charpos > 0)
25209 if (!FRAME_WINDOW_P (it->f)
25210 || (row->reversed_p
25211 ? WINDOW_RIGHT_FRINGE_WIDTH (it->w)
25212 : WINDOW_LEFT_FRINGE_WIDTH (it->w)) == 0)
25213 insert_left_trunc_glyphs (it);
25214 row->truncated_on_left_p = true;
25217 it->face_id = saved_face_id;
25219 /* Value is number of columns displayed. */
25220 return it->hpos - hpos_at_start;
25225 /* This is like a combination of memq and assq. Return 1/2 if PROPVAL
25226 appears as an element of LIST or as the car of an element of LIST.
25227 If PROPVAL is a list, compare each element against LIST in that
25228 way, and return 1/2 if any element of PROPVAL is found in LIST.
25229 Otherwise return 0. This function cannot quit.
25230 The return value is 2 if the text is invisible but with an ellipsis
25231 and 1 if it's invisible and without an ellipsis. */
25234 invisible_prop (Lisp_Object propval, Lisp_Object list)
25236 Lisp_Object tail, proptail;
25238 for (tail = list; CONSP (tail); tail = XCDR (tail))
25240 register Lisp_Object tem;
25241 tem = XCAR (tail);
25242 if (EQ (propval, tem))
25243 return 1;
25244 if (CONSP (tem) && EQ (propval, XCAR (tem)))
25245 return NILP (XCDR (tem)) ? 1 : 2;
25248 if (CONSP (propval))
25250 for (proptail = propval; CONSP (proptail); proptail = XCDR (proptail))
25252 Lisp_Object propelt;
25253 propelt = XCAR (proptail);
25254 for (tail = list; CONSP (tail); tail = XCDR (tail))
25256 register Lisp_Object tem;
25257 tem = XCAR (tail);
25258 if (EQ (propelt, tem))
25259 return 1;
25260 if (CONSP (tem) && EQ (propelt, XCAR (tem)))
25261 return NILP (XCDR (tem)) ? 1 : 2;
25266 return 0;
25269 DEFUN ("invisible-p", Finvisible_p, Sinvisible_p, 1, 1, 0,
25270 doc: /* Non-nil if text properties at POS cause text there to be currently invisible.
25271 POS should be a marker or a buffer position; the value of the `invisible'
25272 property at that position in the current buffer is examined.
25273 POS can also be the actual value of the `invisible' text or overlay
25274 property of the text of interest, in which case the value itself is
25275 examined.
25277 The non-nil value returned can be t for currently invisible text that is
25278 entirely hidden on display, or some other non-nil, non-t value if the
25279 text is replaced by an ellipsis.
25281 Note that whether text with `invisible' property is actually hidden on
25282 display may depend on `buffer-invisibility-spec', which see. */)
25283 (Lisp_Object pos)
25285 Lisp_Object prop
25286 = (NATNUMP (pos) || MARKERP (pos)
25287 ? Fget_char_property (pos, Qinvisible, Qnil)
25288 : pos);
25289 int invis = TEXT_PROP_MEANS_INVISIBLE (prop);
25290 return (invis == 0 ? Qnil
25291 : invis == 1 ? Qt
25292 : make_number (invis));
25295 /* Calculate a width or height in pixels from a specification using
25296 the following elements:
25298 SPEC ::=
25299 NUM - a (fractional) multiple of the default font width/height
25300 (NUM) - specifies exactly NUM pixels
25301 UNIT - a fixed number of pixels, see below.
25302 ELEMENT - size of a display element in pixels, see below.
25303 (NUM . SPEC) - equals NUM * SPEC
25304 (+ SPEC SPEC ...) - add pixel values
25305 (- SPEC SPEC ...) - subtract pixel values
25306 (- SPEC) - negate pixel value
25308 NUM ::=
25309 INT or FLOAT - a number constant
25310 SYMBOL - use symbol's (buffer local) variable binding.
25312 UNIT ::=
25313 in - pixels per inch *)
25314 mm - pixels per 1/1000 meter *)
25315 cm - pixels per 1/100 meter *)
25316 width - width of current font in pixels.
25317 height - height of current font in pixels.
25319 *) using the ratio(s) defined in display-pixels-per-inch.
25321 ELEMENT ::=
25323 left-fringe - left fringe width in pixels
25324 right-fringe - right fringe width in pixels
25326 left-margin - left margin width in pixels
25327 right-margin - right margin width in pixels
25329 scroll-bar - scroll-bar area width in pixels
25331 Examples:
25333 Pixels corresponding to 5 inches:
25334 (5 . in)
25336 Total width of non-text areas on left side of window (if scroll-bar is on left):
25337 '(space :width (+ left-fringe left-margin scroll-bar))
25339 Align to first text column (in header line):
25340 '(space :align-to 0)
25342 Align to middle of text area minus half the width of variable `my-image'
25343 containing a loaded image:
25344 '(space :align-to (0.5 . (- text my-image)))
25346 Width of left margin minus width of 1 character in the default font:
25347 '(space :width (- left-margin 1))
25349 Width of left margin minus width of 2 characters in the current font:
25350 '(space :width (- left-margin (2 . width)))
25352 Center 1 character over left-margin (in header line):
25353 '(space :align-to (+ left-margin (0.5 . left-margin) -0.5))
25355 Different ways to express width of left fringe plus left margin minus one pixel:
25356 '(space :width (- (+ left-fringe left-margin) (1)))
25357 '(space :width (+ left-fringe left-margin (- (1))))
25358 '(space :width (+ left-fringe left-margin (-1)))
25360 If ALIGN_TO is NULL, returns the result in *RES. If ALIGN_TO is
25361 non-NULL, the value of *ALIGN_TO is a window-relative pixel
25362 coordinate, and *RES is the additional pixel width from that point
25363 till the end of the stretch glyph.
25365 WIDTH_P non-zero means take the width dimension or X coordinate of
25366 the object specified by PROP, WIDTH_P zero means take the height
25367 dimension or the Y coordinate. (Therefore, if ALIGN_TO is
25368 non-NULL, WIDTH_P should be non-zero.)
25370 FONT is the font of the face of the surrounding text.
25372 The return value is non-zero if width or height were successfully
25373 calculated, i.e. if PROP is a valid spec. */
25375 static bool
25376 calc_pixel_width_or_height (double *res, struct it *it, Lisp_Object prop,
25377 struct font *font, bool width_p, int *align_to)
25379 double pixels;
25381 # define OK_PIXELS(val) (*res = (val), true)
25382 # define OK_ALIGN_TO(val) (*align_to = (val), true)
25384 if (NILP (prop))
25385 return OK_PIXELS (0);
25387 eassert (FRAME_LIVE_P (it->f));
25389 if (SYMBOLP (prop))
25391 if (SCHARS (SYMBOL_NAME (prop)) == 2)
25393 char *unit = SSDATA (SYMBOL_NAME (prop));
25395 /* The UNIT expression, e.g. as part of (NUM . UNIT). */
25396 if (unit[0] == 'i' && unit[1] == 'n')
25397 pixels = 1.0;
25398 else if (unit[0] == 'm' && unit[1] == 'm')
25399 pixels = 25.4;
25400 else if (unit[0] == 'c' && unit[1] == 'm')
25401 pixels = 2.54;
25402 else
25403 pixels = 0;
25404 if (pixels > 0)
25406 double ppi = (width_p ? FRAME_RES_X (it->f)
25407 : FRAME_RES_Y (it->f));
25409 if (ppi > 0)
25410 return OK_PIXELS (ppi / pixels);
25411 return false;
25415 #ifdef HAVE_WINDOW_SYSTEM
25416 /* 'height': the height of FONT. */
25417 if (EQ (prop, Qheight))
25418 return OK_PIXELS (font
25419 ? normal_char_height (font, -1)
25420 : FRAME_LINE_HEIGHT (it->f));
25421 /* 'width': the width of FONT. */
25422 if (EQ (prop, Qwidth))
25423 return OK_PIXELS (font
25424 ? FONT_WIDTH (font)
25425 : FRAME_COLUMN_WIDTH (it->f));
25426 #else
25427 if (EQ (prop, Qheight) || EQ (prop, Qwidth))
25428 return OK_PIXELS (1);
25429 #endif
25431 /* 'text': the width or height of the text area. */
25432 if (EQ (prop, Qtext))
25433 return OK_PIXELS (width_p
25434 ? (window_box_width (it->w, TEXT_AREA)
25435 - it->lnum_pixel_width)
25436 : WINDOW_BOX_HEIGHT_NO_MODE_LINE (it->w));
25438 /* ':align_to'. First time we compute the value, window
25439 elements are interpreted as the position of the element's
25440 left edge. */
25441 if (align_to && *align_to < 0)
25443 *res = 0;
25444 /* 'left': left edge of the text area. */
25445 if (EQ (prop, Qleft))
25446 return OK_ALIGN_TO (window_box_left_offset (it->w, TEXT_AREA)
25447 + it->lnum_pixel_width);
25448 /* 'right': right edge of the text area. */
25449 if (EQ (prop, Qright))
25450 return OK_ALIGN_TO (window_box_right_offset (it->w, TEXT_AREA));
25451 /* 'center': the center of the text area. */
25452 if (EQ (prop, Qcenter))
25453 return OK_ALIGN_TO (window_box_left_offset (it->w, TEXT_AREA)
25454 + it->lnum_pixel_width
25455 + window_box_width (it->w, TEXT_AREA) / 2);
25456 /* 'left-fringe': left edge of the left fringe. */
25457 if (EQ (prop, Qleft_fringe))
25458 return OK_ALIGN_TO (WINDOW_HAS_FRINGES_OUTSIDE_MARGINS (it->w)
25459 ? WINDOW_LEFT_SCROLL_BAR_AREA_WIDTH (it->w)
25460 : window_box_right_offset (it->w, LEFT_MARGIN_AREA));
25461 /* 'right-fringe': left edge of the right fringe. */
25462 if (EQ (prop, Qright_fringe))
25463 return OK_ALIGN_TO (WINDOW_HAS_FRINGES_OUTSIDE_MARGINS (it->w)
25464 ? window_box_right_offset (it->w, RIGHT_MARGIN_AREA)
25465 : window_box_right_offset (it->w, TEXT_AREA));
25466 /* 'left-margin': left edge of the left display margin. */
25467 if (EQ (prop, Qleft_margin))
25468 return OK_ALIGN_TO (window_box_left_offset (it->w, LEFT_MARGIN_AREA));
25469 /* 'right-margin': left edge of the right display margin. */
25470 if (EQ (prop, Qright_margin))
25471 return OK_ALIGN_TO (window_box_left_offset (it->w, RIGHT_MARGIN_AREA));
25472 /* 'scroll-bar': left edge of the vertical scroll bar. */
25473 if (EQ (prop, Qscroll_bar))
25474 return OK_ALIGN_TO (WINDOW_HAS_VERTICAL_SCROLL_BAR_ON_LEFT (it->w)
25476 : (window_box_right_offset (it->w, RIGHT_MARGIN_AREA)
25477 + (WINDOW_HAS_FRINGES_OUTSIDE_MARGINS (it->w)
25478 ? WINDOW_RIGHT_FRINGE_WIDTH (it->w)
25479 : 0)));
25481 else
25483 /* Otherwise, the elements stand for their width. */
25484 if (EQ (prop, Qleft_fringe))
25485 return OK_PIXELS (WINDOW_LEFT_FRINGE_WIDTH (it->w));
25486 if (EQ (prop, Qright_fringe))
25487 return OK_PIXELS (WINDOW_RIGHT_FRINGE_WIDTH (it->w));
25488 if (EQ (prop, Qleft_margin))
25489 return OK_PIXELS (WINDOW_LEFT_MARGIN_WIDTH (it->w));
25490 if (EQ (prop, Qright_margin))
25491 return OK_PIXELS (WINDOW_RIGHT_MARGIN_WIDTH (it->w));
25492 if (EQ (prop, Qscroll_bar))
25493 return OK_PIXELS (WINDOW_SCROLL_BAR_AREA_WIDTH (it->w));
25496 prop = buffer_local_value (prop, it->w->contents);
25497 if (EQ (prop, Qunbound))
25498 prop = Qnil;
25501 if (NUMBERP (prop))
25503 int base_unit = (width_p
25504 ? FRAME_COLUMN_WIDTH (it->f)
25505 : FRAME_LINE_HEIGHT (it->f));
25506 if (width_p && align_to && *align_to < 0)
25507 return OK_PIXELS (XFLOATINT (prop) * base_unit + it->lnum_pixel_width);
25508 return OK_PIXELS (XFLOATINT (prop) * base_unit);
25511 if (CONSP (prop))
25513 Lisp_Object car = XCAR (prop);
25514 Lisp_Object cdr = XCDR (prop);
25516 if (SYMBOLP (car))
25518 #ifdef HAVE_WINDOW_SYSTEM
25519 /* '(image PROPS...)': width or height of the specified image. */
25520 if (FRAME_WINDOW_P (it->f)
25521 && valid_image_p (prop))
25523 ptrdiff_t id = lookup_image (it->f, prop);
25524 struct image *img = IMAGE_FROM_ID (it->f, id);
25526 return OK_PIXELS (width_p ? img->width : img->height);
25528 /* '(xwidget PROPS...)': dimensions of the specified xwidget. */
25529 if (FRAME_WINDOW_P (it->f) && valid_xwidget_spec_p (prop))
25531 /* TODO: Don't return dummy size. */
25532 return OK_PIXELS (100);
25534 #endif
25535 /* '(+ EXPR...)' or '(- EXPR...)' add or subtract
25536 recursively calculated values. */
25537 if (EQ (car, Qplus) || EQ (car, Qminus))
25539 bool first = true;
25540 double px;
25542 pixels = 0;
25543 while (CONSP (cdr))
25545 if (!calc_pixel_width_or_height (&px, it, XCAR (cdr),
25546 font, width_p, align_to))
25547 return false;
25548 if (first)
25549 pixels = (EQ (car, Qplus) ? px : -px), first = false;
25550 else
25551 pixels += px;
25552 cdr = XCDR (cdr);
25554 if (EQ (car, Qminus))
25555 pixels = -pixels;
25556 return OK_PIXELS (pixels);
25559 car = buffer_local_value (car, it->w->contents);
25560 if (EQ (car, Qunbound))
25561 car = Qnil;
25564 /* '(NUM)': absolute number of pixels. */
25565 if (NUMBERP (car))
25567 double fact;
25568 int offset =
25569 width_p && align_to && *align_to < 0 ? it->lnum_pixel_width : 0;
25570 pixels = XFLOATINT (car);
25571 if (NILP (cdr))
25572 return OK_PIXELS (pixels + offset);
25573 if (calc_pixel_width_or_height (&fact, it, cdr,
25574 font, width_p, align_to))
25575 return OK_PIXELS (pixels * fact + offset);
25576 return false;
25579 return false;
25582 return false;
25585 void
25586 get_font_ascent_descent (struct font *font, int *ascent, int *descent)
25588 #ifdef HAVE_WINDOW_SYSTEM
25589 normal_char_ascent_descent (font, -1, ascent, descent);
25590 #else
25591 *ascent = 1;
25592 *descent = 0;
25593 #endif
25597 /***********************************************************************
25598 Glyph Display
25599 ***********************************************************************/
25601 #ifdef HAVE_WINDOW_SYSTEM
25603 #ifdef GLYPH_DEBUG
25605 void
25606 dump_glyph_string (struct glyph_string *s)
25608 fprintf (stderr, "glyph string\n");
25609 fprintf (stderr, " x, y, w, h = %d, %d, %d, %d\n",
25610 s->x, s->y, s->width, s->height);
25611 fprintf (stderr, " ybase = %d\n", s->ybase);
25612 fprintf (stderr, " hl = %u\n", s->hl);
25613 fprintf (stderr, " left overhang = %d, right = %d\n",
25614 s->left_overhang, s->right_overhang);
25615 fprintf (stderr, " nchars = %d\n", s->nchars);
25616 fprintf (stderr, " extends to end of line = %d\n",
25617 s->extends_to_end_of_line_p);
25618 fprintf (stderr, " font height = %d\n", FONT_HEIGHT (s->font));
25619 fprintf (stderr, " bg width = %d\n", s->background_width);
25622 #endif /* GLYPH_DEBUG */
25624 /* Initialize glyph string S. CHAR2B is a suitably allocated vector
25625 of XChar2b structures for S; it can't be allocated in
25626 init_glyph_string because it must be allocated via `alloca'. W
25627 is the window on which S is drawn. ROW and AREA are the glyph row
25628 and area within the row from which S is constructed. START is the
25629 index of the first glyph structure covered by S. HL is a
25630 face-override for drawing S. */
25632 #ifdef HAVE_NTGUI
25633 #define OPTIONAL_HDC(hdc) HDC hdc,
25634 #define DECLARE_HDC(hdc) HDC hdc;
25635 #define ALLOCATE_HDC(hdc, f) hdc = get_frame_dc ((f))
25636 #define RELEASE_HDC(hdc, f) release_frame_dc ((f), (hdc))
25637 #endif
25639 #ifndef OPTIONAL_HDC
25640 #define OPTIONAL_HDC(hdc)
25641 #define DECLARE_HDC(hdc)
25642 #define ALLOCATE_HDC(hdc, f)
25643 #define RELEASE_HDC(hdc, f)
25644 #endif
25646 static void
25647 init_glyph_string (struct glyph_string *s,
25648 OPTIONAL_HDC (hdc)
25649 XChar2b *char2b, struct window *w, struct glyph_row *row,
25650 enum glyph_row_area area, int start, enum draw_glyphs_face hl)
25652 memset (s, 0, sizeof *s);
25653 s->w = w;
25654 s->f = XFRAME (w->frame);
25655 #ifdef HAVE_NTGUI
25656 s->hdc = hdc;
25657 #endif
25658 s->display = FRAME_X_DISPLAY (s->f);
25659 s->char2b = char2b;
25660 s->hl = hl;
25661 s->row = row;
25662 s->area = area;
25663 s->first_glyph = row->glyphs[area] + start;
25664 s->height = row->height;
25665 s->y = WINDOW_TO_FRAME_PIXEL_Y (w, row->y);
25666 s->ybase = s->y + row->ascent;
25670 /* Append the list of glyph strings with head H and tail T to the list
25671 with head *HEAD and tail *TAIL. Set *HEAD and *TAIL to the result. */
25673 static void
25674 append_glyph_string_lists (struct glyph_string **head, struct glyph_string **tail,
25675 struct glyph_string *h, struct glyph_string *t)
25677 if (h)
25679 if (*head)
25680 (*tail)->next = h;
25681 else
25682 *head = h;
25683 h->prev = *tail;
25684 *tail = t;
25689 /* Prepend the list of glyph strings with head H and tail T to the
25690 list with head *HEAD and tail *TAIL. Set *HEAD and *TAIL to the
25691 result. */
25693 static void
25694 prepend_glyph_string_lists (struct glyph_string **head, struct glyph_string **tail,
25695 struct glyph_string *h, struct glyph_string *t)
25697 if (h)
25699 if (*head)
25700 (*head)->prev = t;
25701 else
25702 *tail = t;
25703 t->next = *head;
25704 *head = h;
25709 /* Append glyph string S to the list with head *HEAD and tail *TAIL.
25710 Set *HEAD and *TAIL to the resulting list. */
25712 static void
25713 append_glyph_string (struct glyph_string **head, struct glyph_string **tail,
25714 struct glyph_string *s)
25716 s->next = s->prev = NULL;
25717 append_glyph_string_lists (head, tail, s, s);
25721 /* Get face and two-byte form of character C in face FACE_ID on frame F.
25722 The encoding of C is returned in *CHAR2B. DISPLAY_P means
25723 make sure that X resources for the face returned are allocated.
25724 Value is a pointer to a realized face that is ready for display if
25725 DISPLAY_P. */
25727 static struct face *
25728 get_char_face_and_encoding (struct frame *f, int c, int face_id,
25729 XChar2b *char2b, bool display_p)
25731 struct face *face = FACE_FROM_ID (f, face_id);
25732 unsigned code = 0;
25734 if (face->font)
25736 code = face->font->driver->encode_char (face->font, c);
25738 if (code == FONT_INVALID_CODE)
25739 code = 0;
25741 STORE_XCHAR2B (char2b, (code >> 8), (code & 0xFF));
25743 /* Make sure X resources of the face are allocated. */
25744 #ifdef HAVE_X_WINDOWS
25745 if (display_p)
25746 #endif
25748 eassert (face != NULL);
25749 prepare_face_for_display (f, face);
25752 return face;
25756 /* Get face and two-byte form of character glyph GLYPH on frame F.
25757 The encoding of GLYPH->u.ch is returned in *CHAR2B. Value is
25758 a pointer to a realized face that is ready for display. */
25760 static struct face *
25761 get_glyph_face_and_encoding (struct frame *f, struct glyph *glyph,
25762 XChar2b *char2b)
25764 struct face *face;
25765 unsigned code = 0;
25767 eassert (glyph->type == CHAR_GLYPH);
25768 face = FACE_FROM_ID (f, glyph->face_id);
25770 /* Make sure X resources of the face are allocated. */
25771 prepare_face_for_display (f, face);
25773 if (face->font)
25775 if (CHAR_BYTE8_P (glyph->u.ch))
25776 code = CHAR_TO_BYTE8 (glyph->u.ch);
25777 else
25778 code = face->font->driver->encode_char (face->font, glyph->u.ch);
25780 if (code == FONT_INVALID_CODE)
25781 code = 0;
25784 STORE_XCHAR2B (char2b, (code >> 8), (code & 0xFF));
25785 return face;
25789 /* Get glyph code of character C in FONT in the two-byte form CHAR2B.
25790 Return true iff FONT has a glyph for C. */
25792 static bool
25793 get_char_glyph_code (int c, struct font *font, XChar2b *char2b)
25795 unsigned code;
25797 if (CHAR_BYTE8_P (c))
25798 code = CHAR_TO_BYTE8 (c);
25799 else
25800 code = font->driver->encode_char (font, c);
25802 if (code == FONT_INVALID_CODE)
25803 return false;
25804 STORE_XCHAR2B (char2b, (code >> 8), (code & 0xFF));
25805 return true;
25809 /* Fill glyph string S with composition components specified by S->cmp.
25811 BASE_FACE is the base face of the composition.
25812 S->cmp_from is the index of the first component for S.
25814 OVERLAPS non-zero means S should draw the foreground only, and use
25815 its physical height for clipping. See also draw_glyphs.
25817 Value is the index of a component not in S. */
25819 static int
25820 fill_composite_glyph_string (struct glyph_string *s, struct face *base_face,
25821 int overlaps)
25823 int i;
25824 /* For all glyphs of this composition, starting at the offset
25825 S->cmp_from, until we reach the end of the definition or encounter a
25826 glyph that requires the different face, add it to S. */
25827 struct face *face;
25829 eassert (s);
25831 s->for_overlaps = overlaps;
25832 s->face = NULL;
25833 s->font = NULL;
25834 for (i = s->cmp_from; i < s->cmp->glyph_len; i++)
25836 int c = COMPOSITION_GLYPH (s->cmp, i);
25838 /* TAB in a composition means display glyphs with padding space
25839 on the left or right. */
25840 if (c != '\t')
25842 int face_id = FACE_FOR_CHAR (s->f, base_face->ascii_face, c,
25843 -1, Qnil);
25845 face = get_char_face_and_encoding (s->f, c, face_id,
25846 s->char2b + i, true);
25847 if (face)
25849 if (! s->face)
25851 s->face = face;
25852 s->font = s->face->font;
25854 else if (s->face != face)
25855 break;
25858 ++s->nchars;
25860 s->cmp_to = i;
25862 if (s->face == NULL)
25864 s->face = base_face->ascii_face;
25865 s->font = s->face->font;
25868 /* All glyph strings for the same composition has the same width,
25869 i.e. the width set for the first component of the composition. */
25870 s->width = s->first_glyph->pixel_width;
25872 /* If the specified font could not be loaded, use the frame's
25873 default font, but record the fact that we couldn't load it in
25874 the glyph string so that we can draw rectangles for the
25875 characters of the glyph string. */
25876 if (s->font == NULL)
25878 s->font_not_found_p = true;
25879 s->font = FRAME_FONT (s->f);
25882 /* Adjust base line for subscript/superscript text. */
25883 s->ybase += s->first_glyph->voffset;
25885 return s->cmp_to;
25888 static int
25889 fill_gstring_glyph_string (struct glyph_string *s, int face_id,
25890 int start, int end, int overlaps)
25892 struct glyph *glyph, *last;
25893 Lisp_Object lgstring;
25894 int i;
25896 s->for_overlaps = overlaps;
25897 glyph = s->row->glyphs[s->area] + start;
25898 last = s->row->glyphs[s->area] + end;
25899 s->cmp_id = glyph->u.cmp.id;
25900 s->cmp_from = glyph->slice.cmp.from;
25901 s->cmp_to = glyph->slice.cmp.to + 1;
25902 s->face = FACE_FROM_ID (s->f, face_id);
25903 lgstring = composition_gstring_from_id (s->cmp_id);
25904 s->font = XFONT_OBJECT (LGSTRING_FONT (lgstring));
25905 glyph++;
25906 while (glyph < last
25907 && glyph->u.cmp.automatic
25908 && glyph->u.cmp.id == s->cmp_id
25909 && s->cmp_to == glyph->slice.cmp.from)
25910 s->cmp_to = (glyph++)->slice.cmp.to + 1;
25912 for (i = s->cmp_from; i < s->cmp_to; i++)
25914 Lisp_Object lglyph = LGSTRING_GLYPH (lgstring, i);
25915 unsigned code = LGLYPH_CODE (lglyph);
25917 STORE_XCHAR2B ((s->char2b + i), code >> 8, code & 0xFF);
25919 s->width = composition_gstring_width (lgstring, s->cmp_from, s->cmp_to, NULL);
25920 return glyph - s->row->glyphs[s->area];
25924 /* Fill glyph string S from a sequence glyphs for glyphless characters.
25925 See the comment of fill_glyph_string for arguments.
25926 Value is the index of the first glyph not in S. */
25929 static int
25930 fill_glyphless_glyph_string (struct glyph_string *s, int face_id,
25931 int start, int end, int overlaps)
25933 struct glyph *glyph, *last;
25934 int voffset;
25936 eassert (s->first_glyph->type == GLYPHLESS_GLYPH);
25937 s->for_overlaps = overlaps;
25938 glyph = s->row->glyphs[s->area] + start;
25939 last = s->row->glyphs[s->area] + end;
25940 voffset = glyph->voffset;
25941 s->face = FACE_FROM_ID (s->f, face_id);
25942 s->font = s->face->font ? s->face->font : FRAME_FONT (s->f);
25943 s->nchars = 1;
25944 s->width = glyph->pixel_width;
25945 glyph++;
25946 while (glyph < last
25947 && glyph->type == GLYPHLESS_GLYPH
25948 && glyph->voffset == voffset
25949 && glyph->face_id == face_id)
25951 s->nchars++;
25952 s->width += glyph->pixel_width;
25953 glyph++;
25955 s->ybase += voffset;
25956 return glyph - s->row->glyphs[s->area];
25960 /* Fill glyph string S from a sequence of character glyphs.
25962 FACE_ID is the face id of the string. START is the index of the
25963 first glyph to consider, END is the index of the last + 1.
25964 OVERLAPS non-zero means S should draw the foreground only, and use
25965 its physical height for clipping. See also draw_glyphs.
25967 Value is the index of the first glyph not in S. */
25969 static int
25970 fill_glyph_string (struct glyph_string *s, int face_id,
25971 int start, int end, int overlaps)
25973 struct glyph *glyph, *last;
25974 int voffset;
25975 bool glyph_not_available_p;
25977 eassert (s->f == XFRAME (s->w->frame));
25978 eassert (s->nchars == 0);
25979 eassert (start >= 0 && end > start);
25981 s->for_overlaps = overlaps;
25982 glyph = s->row->glyphs[s->area] + start;
25983 last = s->row->glyphs[s->area] + end;
25984 voffset = glyph->voffset;
25985 s->padding_p = glyph->padding_p;
25986 glyph_not_available_p = glyph->glyph_not_available_p;
25988 while (glyph < last
25989 && glyph->type == CHAR_GLYPH
25990 && glyph->voffset == voffset
25991 /* Same face id implies same font, nowadays. */
25992 && glyph->face_id == face_id
25993 && glyph->glyph_not_available_p == glyph_not_available_p)
25995 s->face = get_glyph_face_and_encoding (s->f, glyph,
25996 s->char2b + s->nchars);
25997 ++s->nchars;
25998 eassert (s->nchars <= end - start);
25999 s->width += glyph->pixel_width;
26000 if (glyph++->padding_p != s->padding_p)
26001 break;
26004 s->font = s->face->font;
26006 /* If the specified font could not be loaded, use the frame's font,
26007 but record the fact that we couldn't load it in
26008 S->font_not_found_p so that we can draw rectangles for the
26009 characters of the glyph string. */
26010 if (s->font == NULL || glyph_not_available_p)
26012 s->font_not_found_p = true;
26013 s->font = FRAME_FONT (s->f);
26016 /* Adjust base line for subscript/superscript text. */
26017 s->ybase += voffset;
26019 eassert (s->face && s->face->gc);
26020 return glyph - s->row->glyphs[s->area];
26024 /* Fill glyph string S from image glyph S->first_glyph. */
26026 static void
26027 fill_image_glyph_string (struct glyph_string *s)
26029 eassert (s->first_glyph->type == IMAGE_GLYPH);
26030 s->img = IMAGE_FROM_ID (s->f, s->first_glyph->u.img_id);
26031 eassert (s->img);
26032 s->slice = s->first_glyph->slice.img;
26033 s->face = FACE_FROM_ID (s->f, s->first_glyph->face_id);
26034 s->font = s->face->font;
26035 s->width = s->first_glyph->pixel_width;
26037 /* Adjust base line for subscript/superscript text. */
26038 s->ybase += s->first_glyph->voffset;
26042 #ifdef HAVE_XWIDGETS
26043 static void
26044 fill_xwidget_glyph_string (struct glyph_string *s)
26046 eassert (s->first_glyph->type == XWIDGET_GLYPH);
26047 s->face = FACE_FROM_ID (s->f, s->first_glyph->face_id);
26048 s->font = s->face->font;
26049 s->width = s->first_glyph->pixel_width;
26050 s->ybase += s->first_glyph->voffset;
26051 s->xwidget = s->first_glyph->u.xwidget;
26053 #endif
26054 /* Fill glyph string S from a sequence of stretch glyphs.
26056 START is the index of the first glyph to consider,
26057 END is the index of the last + 1.
26059 Value is the index of the first glyph not in S. */
26061 static int
26062 fill_stretch_glyph_string (struct glyph_string *s, int start, int end)
26064 struct glyph *glyph, *last;
26065 int voffset, face_id;
26067 eassert (s->first_glyph->type == STRETCH_GLYPH);
26069 glyph = s->row->glyphs[s->area] + start;
26070 last = s->row->glyphs[s->area] + end;
26071 face_id = glyph->face_id;
26072 s->face = FACE_FROM_ID (s->f, face_id);
26073 s->font = s->face->font;
26074 s->width = glyph->pixel_width;
26075 s->nchars = 1;
26076 voffset = glyph->voffset;
26078 for (++glyph;
26079 (glyph < last
26080 && glyph->type == STRETCH_GLYPH
26081 && glyph->voffset == voffset
26082 && glyph->face_id == face_id);
26083 ++glyph)
26084 s->width += glyph->pixel_width;
26086 /* Adjust base line for subscript/superscript text. */
26087 s->ybase += voffset;
26089 /* The case that face->gc == 0 is handled when drawing the glyph
26090 string by calling prepare_face_for_display. */
26091 eassert (s->face);
26092 return glyph - s->row->glyphs[s->area];
26095 static struct font_metrics *
26096 get_per_char_metric (struct font *font, XChar2b *char2b)
26098 static struct font_metrics metrics;
26099 unsigned code;
26101 if (! font)
26102 return NULL;
26103 code = (XCHAR2B_BYTE1 (char2b) << 8) | XCHAR2B_BYTE2 (char2b);
26104 if (code == FONT_INVALID_CODE)
26105 return NULL;
26106 font->driver->text_extents (font, &code, 1, &metrics);
26107 return &metrics;
26110 /* A subroutine that computes "normal" values of ASCENT and DESCENT
26111 for FONT. Values are taken from font-global ones, except for fonts
26112 that claim preposterously large values, but whose glyphs actually
26113 have reasonable dimensions. C is the character to use for metrics
26114 if the font-global values are too large; if C is negative, the
26115 function selects a default character. */
26116 static void
26117 normal_char_ascent_descent (struct font *font, int c, int *ascent, int *descent)
26119 *ascent = FONT_BASE (font);
26120 *descent = FONT_DESCENT (font);
26122 if (FONT_TOO_HIGH (font))
26124 XChar2b char2b;
26126 /* Get metrics of C, defaulting to a reasonably sized ASCII
26127 character. */
26128 if (get_char_glyph_code (c >= 0 ? c : '{', font, &char2b))
26130 struct font_metrics *pcm = get_per_char_metric (font, &char2b);
26132 if (!(pcm->width == 0 && pcm->rbearing == 0 && pcm->lbearing == 0))
26134 /* We add 1 pixel to character dimensions as heuristics
26135 that produces nicer display, e.g. when the face has
26136 the box attribute. */
26137 *ascent = pcm->ascent + 1;
26138 *descent = pcm->descent + 1;
26144 /* A subroutine that computes a reasonable "normal character height"
26145 for fonts that claim preposterously large vertical dimensions, but
26146 whose glyphs are actually reasonably sized. C is the character
26147 whose metrics to use for those fonts, or -1 for default
26148 character. */
26149 static int
26150 normal_char_height (struct font *font, int c)
26152 int ascent, descent;
26154 normal_char_ascent_descent (font, c, &ascent, &descent);
26156 return ascent + descent;
26159 /* EXPORT for RIF:
26160 Set *LEFT and *RIGHT to the left and right overhang of GLYPH on
26161 frame F. Overhangs of glyphs other than type CHAR_GLYPH are
26162 assumed to be zero. */
26164 void
26165 x_get_glyph_overhangs (struct glyph *glyph, struct frame *f, int *left, int *right)
26167 *left = *right = 0;
26169 if (glyph->type == CHAR_GLYPH)
26171 XChar2b char2b;
26172 struct face *face = get_glyph_face_and_encoding (f, glyph, &char2b);
26173 if (face->font)
26175 struct font_metrics *pcm = get_per_char_metric (face->font, &char2b);
26176 if (pcm)
26178 if (pcm->rbearing > pcm->width)
26179 *right = pcm->rbearing - pcm->width;
26180 if (pcm->lbearing < 0)
26181 *left = -pcm->lbearing;
26185 else if (glyph->type == COMPOSITE_GLYPH)
26187 if (! glyph->u.cmp.automatic)
26189 struct composition *cmp = composition_table[glyph->u.cmp.id];
26191 if (cmp->rbearing > cmp->pixel_width)
26192 *right = cmp->rbearing - cmp->pixel_width;
26193 if (cmp->lbearing < 0)
26194 *left = - cmp->lbearing;
26196 else
26198 Lisp_Object gstring = composition_gstring_from_id (glyph->u.cmp.id);
26199 struct font_metrics metrics;
26201 composition_gstring_width (gstring, glyph->slice.cmp.from,
26202 glyph->slice.cmp.to + 1, &metrics);
26203 if (metrics.rbearing > metrics.width)
26204 *right = metrics.rbearing - metrics.width;
26205 if (metrics.lbearing < 0)
26206 *left = - metrics.lbearing;
26212 /* Return the index of the first glyph preceding glyph string S that
26213 is overwritten by S because of S's left overhang. Value is -1
26214 if no glyphs are overwritten. */
26216 static int
26217 left_overwritten (struct glyph_string *s)
26219 int k;
26221 if (s->left_overhang)
26223 int x = 0, i;
26224 struct glyph *glyphs = s->row->glyphs[s->area];
26225 int first = s->first_glyph - glyphs;
26227 for (i = first - 1; i >= 0 && x > -s->left_overhang; --i)
26228 x -= glyphs[i].pixel_width;
26230 k = i + 1;
26232 else
26233 k = -1;
26235 return k;
26239 /* Return the index of the first glyph preceding glyph string S that
26240 is overwriting S because of its right overhang. Value is -1 if no
26241 glyph in front of S overwrites S. */
26243 static int
26244 left_overwriting (struct glyph_string *s)
26246 int i, k, x;
26247 struct glyph *glyphs = s->row->glyphs[s->area];
26248 int first = s->first_glyph - glyphs;
26250 k = -1;
26251 x = 0;
26252 for (i = first - 1; i >= 0; --i)
26254 int left, right;
26255 x_get_glyph_overhangs (glyphs + i, s->f, &left, &right);
26256 if (x + right > 0)
26257 k = i;
26258 x -= glyphs[i].pixel_width;
26261 return k;
26265 /* Return the index of the last glyph following glyph string S that is
26266 overwritten by S because of S's right overhang. Value is -1 if
26267 no such glyph is found. */
26269 static int
26270 right_overwritten (struct glyph_string *s)
26272 int k = -1;
26274 if (s->right_overhang)
26276 int x = 0, i;
26277 struct glyph *glyphs = s->row->glyphs[s->area];
26278 int first = (s->first_glyph - glyphs
26279 + (s->first_glyph->type == COMPOSITE_GLYPH ? 1 : s->nchars));
26280 int end = s->row->used[s->area];
26282 for (i = first; i < end && s->right_overhang > x; ++i)
26283 x += glyphs[i].pixel_width;
26285 k = i;
26288 return k;
26292 /* Return the index of the last glyph following glyph string S that
26293 overwrites S because of its left overhang. Value is negative
26294 if no such glyph is found. */
26296 static int
26297 right_overwriting (struct glyph_string *s)
26299 int i, k, x;
26300 int end = s->row->used[s->area];
26301 struct glyph *glyphs = s->row->glyphs[s->area];
26302 int first = (s->first_glyph - glyphs
26303 + (s->first_glyph->type == COMPOSITE_GLYPH ? 1 : s->nchars));
26305 k = -1;
26306 x = 0;
26307 for (i = first; i < end; ++i)
26309 int left, right;
26310 x_get_glyph_overhangs (glyphs + i, s->f, &left, &right);
26311 if (x - left < 0)
26312 k = i;
26313 x += glyphs[i].pixel_width;
26316 return k;
26320 /* Set background width of glyph string S. START is the index of the
26321 first glyph following S. LAST_X is the right-most x-position + 1
26322 in the drawing area. */
26324 static void
26325 set_glyph_string_background_width (struct glyph_string *s, int start, int last_x)
26327 /* If the face of this glyph string has to be drawn to the end of
26328 the drawing area, set S->extends_to_end_of_line_p. */
26330 if (start == s->row->used[s->area]
26331 && ((s->row->fill_line_p
26332 && (s->hl == DRAW_NORMAL_TEXT
26333 || s->hl == DRAW_IMAGE_RAISED
26334 || s->hl == DRAW_IMAGE_SUNKEN))
26335 || s->hl == DRAW_MOUSE_FACE))
26336 s->extends_to_end_of_line_p = true;
26338 /* If S extends its face to the end of the line, set its
26339 background_width to the distance to the right edge of the drawing
26340 area. */
26341 if (s->extends_to_end_of_line_p)
26342 s->background_width = last_x - s->x + 1;
26343 else
26344 s->background_width = s->width;
26348 /* Return glyph string that shares background with glyph string S and
26349 whose `background_width' member has been set. */
26351 static struct glyph_string *
26352 glyph_string_containing_background_width (struct glyph_string *s)
26354 if (s->cmp)
26355 while (s->cmp_from)
26356 s = s->prev;
26358 return s;
26362 /* Compute overhangs and x-positions for glyph string S and its
26363 predecessors, or successors. X is the starting x-position for S.
26364 BACKWARD_P means process predecessors. */
26366 static void
26367 compute_overhangs_and_x (struct glyph_string *s, int x, bool backward_p)
26369 if (backward_p)
26371 while (s)
26373 if (FRAME_RIF (s->f)->compute_glyph_string_overhangs)
26374 FRAME_RIF (s->f)->compute_glyph_string_overhangs (s);
26375 if (!s->cmp || s->cmp_to == s->cmp->glyph_len)
26376 x -= s->width;
26377 s->x = x;
26378 s = s->prev;
26381 else
26383 while (s)
26385 if (FRAME_RIF (s->f)->compute_glyph_string_overhangs)
26386 FRAME_RIF (s->f)->compute_glyph_string_overhangs (s);
26387 s->x = x;
26388 if (!s->cmp || s->cmp_to == s->cmp->glyph_len)
26389 x += s->width;
26390 s = s->next;
26397 /* The following macros are only called from draw_glyphs below.
26398 They reference the following parameters of that function directly:
26399 `w', `row', `area', and `overlap_p'
26400 as well as the following local variables:
26401 `s', `f', and `hdc' (in W32) */
26403 #ifdef HAVE_NTGUI
26404 /* On W32, silently add local `hdc' variable to argument list of
26405 init_glyph_string. */
26406 #define INIT_GLYPH_STRING(s, char2b, w, row, area, start, hl) \
26407 init_glyph_string (s, hdc, char2b, w, row, area, start, hl)
26408 #else
26409 #define INIT_GLYPH_STRING(s, char2b, w, row, area, start, hl) \
26410 init_glyph_string (s, char2b, w, row, area, start, hl)
26411 #endif
26413 /* Add a glyph string for a stretch glyph to the list of strings
26414 between HEAD and TAIL. START is the index of the stretch glyph in
26415 row area AREA of glyph row ROW. END is the index of the last glyph
26416 in that glyph row area. X is the current output position assigned
26417 to the new glyph string constructed. HL overrides that face of the
26418 glyph; e.g. it is DRAW_CURSOR if a cursor has to be drawn. LAST_X
26419 is the right-most x-position of the drawing area. */
26421 /* SunOS 4 bundled cc, barfed on continuations in the arg lists here
26422 and below -- keep them on one line. */
26423 #define BUILD_STRETCH_GLYPH_STRING(START, END, HEAD, TAIL, HL, X, LAST_X) \
26424 do \
26426 s = alloca (sizeof *s); \
26427 INIT_GLYPH_STRING (s, NULL, w, row, area, START, HL); \
26428 START = fill_stretch_glyph_string (s, START, END); \
26429 append_glyph_string (&HEAD, &TAIL, s); \
26430 s->x = (X); \
26432 while (false)
26435 /* Add a glyph string for an image glyph to the list of strings
26436 between HEAD and TAIL. START is the index of the image glyph in
26437 row area AREA of glyph row ROW. END is the index of the last glyph
26438 in that glyph row area. X is the current output position assigned
26439 to the new glyph string constructed. HL overrides that face of the
26440 glyph; e.g. it is DRAW_CURSOR if a cursor has to be drawn. LAST_X
26441 is the right-most x-position of the drawing area. */
26443 #define BUILD_IMAGE_GLYPH_STRING(START, END, HEAD, TAIL, HL, X, LAST_X) \
26444 do \
26446 s = alloca (sizeof *s); \
26447 INIT_GLYPH_STRING (s, NULL, w, row, area, START, HL); \
26448 fill_image_glyph_string (s); \
26449 append_glyph_string (&HEAD, &TAIL, s); \
26450 ++START; \
26451 s->x = (X); \
26453 while (false)
26455 #ifndef HAVE_XWIDGETS
26456 # define BUILD_XWIDGET_GLYPH_STRING(START, END, HEAD, TAIL, HL, X, LAST_X) \
26457 eassume (false)
26458 #else
26459 # define BUILD_XWIDGET_GLYPH_STRING(START, END, HEAD, TAIL, HL, X, LAST_X) \
26460 do \
26462 s = alloca (sizeof *s); \
26463 INIT_GLYPH_STRING (s, NULL, w, row, area, START, HL); \
26464 fill_xwidget_glyph_string (s); \
26465 append_glyph_string (&(HEAD), &(TAIL), s); \
26466 ++(START); \
26467 s->x = (X); \
26469 while (false)
26470 #endif
26472 /* Add a glyph string for a sequence of character glyphs to the list
26473 of strings between HEAD and TAIL. START is the index of the first
26474 glyph in row area AREA of glyph row ROW that is part of the new
26475 glyph string. END is the index of the last glyph in that glyph row
26476 area. X is the current output position assigned to the new glyph
26477 string constructed. HL overrides that face of the glyph; e.g. it
26478 is DRAW_CURSOR if a cursor has to be drawn. LAST_X is the
26479 right-most x-position of the drawing area. */
26481 #define BUILD_CHAR_GLYPH_STRINGS(START, END, HEAD, TAIL, HL, X, LAST_X) \
26482 do \
26484 int face_id; \
26485 XChar2b *char2b; \
26487 face_id = (row)->glyphs[area][START].face_id; \
26489 s = alloca (sizeof *s); \
26490 SAFE_NALLOCA (char2b, 1, (END) - (START)); \
26491 INIT_GLYPH_STRING (s, char2b, w, row, area, START, HL); \
26492 append_glyph_string (&HEAD, &TAIL, s); \
26493 s->x = (X); \
26494 START = fill_glyph_string (s, face_id, START, END, overlaps); \
26496 while (false)
26499 /* Add a glyph string for a composite sequence to the list of strings
26500 between HEAD and TAIL. START is the index of the first glyph in
26501 row area AREA of glyph row ROW that is part of the new glyph
26502 string. END is the index of the last glyph in that glyph row area.
26503 X is the current output position assigned to the new glyph string
26504 constructed. HL overrides that face of the glyph; e.g. it is
26505 DRAW_CURSOR if a cursor has to be drawn. LAST_X is the right-most
26506 x-position of the drawing area. */
26508 #define BUILD_COMPOSITE_GLYPH_STRING(START, END, HEAD, TAIL, HL, X, LAST_X) \
26509 do { \
26510 int face_id = (row)->glyphs[area][START].face_id; \
26511 struct face *base_face = FACE_FROM_ID (f, face_id); \
26512 ptrdiff_t cmp_id = (row)->glyphs[area][START].u.cmp.id; \
26513 struct composition *cmp = composition_table[cmp_id]; \
26514 XChar2b *char2b; \
26515 struct glyph_string *first_s = NULL; \
26516 int n; \
26518 SAFE_NALLOCA (char2b, 1, cmp->glyph_len); \
26520 /* Make glyph_strings for each glyph sequence that is drawable by \
26521 the same face, and append them to HEAD/TAIL. */ \
26522 for (n = 0; n < cmp->glyph_len;) \
26524 s = alloca (sizeof *s); \
26525 INIT_GLYPH_STRING (s, char2b, w, row, area, START, HL); \
26526 append_glyph_string (&(HEAD), &(TAIL), s); \
26527 s->cmp = cmp; \
26528 s->cmp_from = n; \
26529 s->x = (X); \
26530 if (n == 0) \
26531 first_s = s; \
26532 n = fill_composite_glyph_string (s, base_face, overlaps); \
26535 ++START; \
26536 s = first_s; \
26537 } while (false)
26540 /* Add a glyph string for a glyph-string sequence to the list of strings
26541 between HEAD and TAIL. */
26543 #define BUILD_GSTRING_GLYPH_STRING(START, END, HEAD, TAIL, HL, X, LAST_X) \
26544 do { \
26545 int face_id; \
26546 XChar2b *char2b; \
26547 Lisp_Object gstring; \
26549 face_id = (row)->glyphs[area][START].face_id; \
26550 gstring = (composition_gstring_from_id \
26551 ((row)->glyphs[area][START].u.cmp.id)); \
26552 s = alloca (sizeof *s); \
26553 SAFE_NALLOCA (char2b, 1, LGSTRING_GLYPH_LEN (gstring)); \
26554 INIT_GLYPH_STRING (s, char2b, w, row, area, START, HL); \
26555 append_glyph_string (&(HEAD), &(TAIL), s); \
26556 s->x = (X); \
26557 START = fill_gstring_glyph_string (s, face_id, START, END, overlaps); \
26558 } while (false)
26561 /* Add a glyph string for a sequence of glyphless character's glyphs
26562 to the list of strings between HEAD and TAIL. The meanings of
26563 arguments are the same as those of BUILD_CHAR_GLYPH_STRINGS. */
26565 #define BUILD_GLYPHLESS_GLYPH_STRING(START, END, HEAD, TAIL, HL, X, LAST_X) \
26566 do \
26568 int face_id; \
26570 face_id = (row)->glyphs[area][START].face_id; \
26572 s = alloca (sizeof *s); \
26573 INIT_GLYPH_STRING (s, NULL, w, row, area, START, HL); \
26574 append_glyph_string (&HEAD, &TAIL, s); \
26575 s->x = (X); \
26576 START = fill_glyphless_glyph_string (s, face_id, START, END, \
26577 overlaps); \
26579 while (false)
26582 /* Build a list of glyph strings between HEAD and TAIL for the glyphs
26583 of AREA of glyph row ROW on window W between indices START and END.
26584 HL overrides the face for drawing glyph strings, e.g. it is
26585 DRAW_CURSOR to draw a cursor. X and LAST_X are start and end
26586 x-positions of the drawing area.
26588 This is an ugly monster macro construct because we must use alloca
26589 to allocate glyph strings (because draw_glyphs can be called
26590 asynchronously). */
26592 #define BUILD_GLYPH_STRINGS_1(START, END, HEAD, TAIL, HL, X, LAST_X) \
26593 do \
26595 HEAD = TAIL = NULL; \
26596 while (START < END) \
26598 struct glyph *first_glyph = (row)->glyphs[area] + START; \
26599 switch (first_glyph->type) \
26601 case CHAR_GLYPH: \
26602 BUILD_CHAR_GLYPH_STRINGS (START, END, HEAD, TAIL, \
26603 HL, X, LAST_X); \
26604 break; \
26606 case COMPOSITE_GLYPH: \
26607 if (first_glyph->u.cmp.automatic) \
26608 BUILD_GSTRING_GLYPH_STRING (START, END, HEAD, TAIL, \
26609 HL, X, LAST_X); \
26610 else \
26611 BUILD_COMPOSITE_GLYPH_STRING (START, END, HEAD, TAIL, \
26612 HL, X, LAST_X); \
26613 break; \
26615 case STRETCH_GLYPH: \
26616 BUILD_STRETCH_GLYPH_STRING (START, END, HEAD, TAIL, \
26617 HL, X, LAST_X); \
26618 break; \
26620 case IMAGE_GLYPH: \
26621 BUILD_IMAGE_GLYPH_STRING (START, END, HEAD, TAIL, \
26622 HL, X, LAST_X); \
26623 break;
26625 #define BUILD_GLYPH_STRINGS_XW(START, END, HEAD, TAIL, HL, X, LAST_X) \
26626 case XWIDGET_GLYPH: \
26627 BUILD_XWIDGET_GLYPH_STRING (START, END, HEAD, TAIL, \
26628 HL, X, LAST_X); \
26629 break;
26631 #define BUILD_GLYPH_STRINGS_2(START, END, HEAD, TAIL, HL, X, LAST_X) \
26632 case GLYPHLESS_GLYPH: \
26633 BUILD_GLYPHLESS_GLYPH_STRING (START, END, HEAD, TAIL, \
26634 HL, X, LAST_X); \
26635 break; \
26637 default: \
26638 emacs_abort (); \
26641 if (s) \
26643 set_glyph_string_background_width (s, START, LAST_X); \
26644 (X) += s->width; \
26647 } while (false)
26650 #define BUILD_GLYPH_STRINGS(START, END, HEAD, TAIL, HL, X, LAST_X) \
26651 BUILD_GLYPH_STRINGS_1(START, END, HEAD, TAIL, HL, X, LAST_X) \
26652 BUILD_GLYPH_STRINGS_XW(START, END, HEAD, TAIL, HL, X, LAST_X) \
26653 BUILD_GLYPH_STRINGS_2(START, END, HEAD, TAIL, HL, X, LAST_X)
26656 /* Draw glyphs between START and END in AREA of ROW on window W,
26657 starting at x-position X. X is relative to AREA in W. HL is a
26658 face-override with the following meaning:
26660 DRAW_NORMAL_TEXT draw normally
26661 DRAW_CURSOR draw in cursor face
26662 DRAW_MOUSE_FACE draw in mouse face.
26663 DRAW_INVERSE_VIDEO draw in mode line face
26664 DRAW_IMAGE_SUNKEN draw an image with a sunken relief around it
26665 DRAW_IMAGE_RAISED draw an image with a raised relief around it
26667 If OVERLAPS is non-zero, draw only the foreground of characters and
26668 clip to the physical height of ROW. Non-zero value also defines
26669 the overlapping part to be drawn:
26671 OVERLAPS_PRED overlap with preceding rows
26672 OVERLAPS_SUCC overlap with succeeding rows
26673 OVERLAPS_BOTH overlap with both preceding/succeeding rows
26674 OVERLAPS_ERASED_CURSOR overlap with erased cursor area
26676 Value is the x-position reached, relative to AREA of W. */
26678 static int
26679 draw_glyphs (struct window *w, int x, struct glyph_row *row,
26680 enum glyph_row_area area, ptrdiff_t start, ptrdiff_t end,
26681 enum draw_glyphs_face hl, int overlaps)
26683 struct glyph_string *head, *tail;
26684 struct glyph_string *s;
26685 struct glyph_string *clip_head = NULL, *clip_tail = NULL;
26686 int i, j, x_reached, last_x, area_left = 0;
26687 struct frame *f = XFRAME (WINDOW_FRAME (w));
26688 DECLARE_HDC (hdc);
26690 ALLOCATE_HDC (hdc, f);
26692 /* Let's rather be paranoid than getting a SEGV. */
26693 end = min (end, row->used[area]);
26694 start = clip_to_bounds (0, start, end);
26696 /* Translate X to frame coordinates. Set last_x to the right
26697 end of the drawing area. */
26698 if (row->full_width_p)
26700 /* X is relative to the left edge of W, without scroll bars
26701 or fringes. */
26702 area_left = WINDOW_LEFT_EDGE_X (w);
26703 last_x = (WINDOW_LEFT_EDGE_X (w) + WINDOW_PIXEL_WIDTH (w)
26704 - (row->mode_line_p ? WINDOW_RIGHT_DIVIDER_WIDTH (w) : 0));
26706 else
26708 area_left = window_box_left (w, area);
26709 last_x = area_left + window_box_width (w, area);
26711 x += area_left;
26713 /* Build a doubly-linked list of glyph_string structures between
26714 head and tail from what we have to draw. Note that the macro
26715 BUILD_GLYPH_STRINGS will modify its start parameter. That's
26716 the reason we use a separate variable `i'. */
26717 i = start;
26718 USE_SAFE_ALLOCA;
26719 BUILD_GLYPH_STRINGS (i, end, head, tail, hl, x, last_x);
26720 if (tail)
26722 s = glyph_string_containing_background_width (tail);
26723 x_reached = s->x + s->background_width;
26725 else
26726 x_reached = x;
26728 /* If there are any glyphs with lbearing < 0 or rbearing > width in
26729 the row, redraw some glyphs in front or following the glyph
26730 strings built above. */
26731 if (head && !overlaps && row->contains_overlapping_glyphs_p)
26733 struct glyph_string *h, *t;
26734 Mouse_HLInfo *hlinfo = MOUSE_HL_INFO (f);
26735 int mouse_beg_col UNINIT, mouse_end_col UNINIT;
26736 bool check_mouse_face = false;
26737 int dummy_x = 0;
26739 /* If mouse highlighting is on, we may need to draw adjacent
26740 glyphs using mouse-face highlighting. */
26741 if (area == TEXT_AREA && row->mouse_face_p
26742 && hlinfo->mouse_face_beg_row >= 0
26743 && hlinfo->mouse_face_end_row >= 0)
26745 ptrdiff_t row_vpos = MATRIX_ROW_VPOS (row, w->current_matrix);
26747 if (row_vpos >= hlinfo->mouse_face_beg_row
26748 && row_vpos <= hlinfo->mouse_face_end_row)
26750 check_mouse_face = true;
26751 mouse_beg_col = (row_vpos == hlinfo->mouse_face_beg_row)
26752 ? hlinfo->mouse_face_beg_col : 0;
26753 mouse_end_col = (row_vpos == hlinfo->mouse_face_end_row)
26754 ? hlinfo->mouse_face_end_col
26755 : row->used[TEXT_AREA];
26759 /* Compute overhangs for all glyph strings. */
26760 if (FRAME_RIF (f)->compute_glyph_string_overhangs)
26761 for (s = head; s; s = s->next)
26762 FRAME_RIF (f)->compute_glyph_string_overhangs (s);
26764 /* Prepend glyph strings for glyphs in front of the first glyph
26765 string that are overwritten because of the first glyph
26766 string's left overhang. The background of all strings
26767 prepended must be drawn because the first glyph string
26768 draws over it. */
26769 i = left_overwritten (head);
26770 if (i >= 0)
26772 enum draw_glyphs_face overlap_hl;
26774 /* If this row contains mouse highlighting, attempt to draw
26775 the overlapped glyphs with the correct highlight. This
26776 code fails if the overlap encompasses more than one glyph
26777 and mouse-highlight spans only some of these glyphs.
26778 However, making it work perfectly involves a lot more
26779 code, and I don't know if the pathological case occurs in
26780 practice, so we'll stick to this for now. --- cyd */
26781 if (check_mouse_face
26782 && mouse_beg_col < start && mouse_end_col > i)
26783 overlap_hl = DRAW_MOUSE_FACE;
26784 else
26785 overlap_hl = DRAW_NORMAL_TEXT;
26787 if (hl != overlap_hl)
26788 clip_head = head;
26789 j = i;
26790 BUILD_GLYPH_STRINGS (j, start, h, t,
26791 overlap_hl, dummy_x, last_x);
26792 start = i;
26793 compute_overhangs_and_x (t, head->x, true);
26794 prepend_glyph_string_lists (&head, &tail, h, t);
26795 if (clip_head == NULL)
26796 clip_head = head;
26799 /* Prepend glyph strings for glyphs in front of the first glyph
26800 string that overwrite that glyph string because of their
26801 right overhang. For these strings, only the foreground must
26802 be drawn, because it draws over the glyph string at `head'.
26803 The background must not be drawn because this would overwrite
26804 right overhangs of preceding glyphs for which no glyph
26805 strings exist. */
26806 i = left_overwriting (head);
26807 if (i >= 0)
26809 enum draw_glyphs_face overlap_hl;
26811 if (check_mouse_face
26812 && mouse_beg_col < start && mouse_end_col > i)
26813 overlap_hl = DRAW_MOUSE_FACE;
26814 else
26815 overlap_hl = DRAW_NORMAL_TEXT;
26817 if (hl == overlap_hl || clip_head == NULL)
26818 clip_head = head;
26819 BUILD_GLYPH_STRINGS (i, start, h, t,
26820 overlap_hl, dummy_x, last_x);
26821 for (s = h; s; s = s->next)
26822 s->background_filled_p = true;
26823 compute_overhangs_and_x (t, head->x, true);
26824 prepend_glyph_string_lists (&head, &tail, h, t);
26827 /* Append glyphs strings for glyphs following the last glyph
26828 string tail that are overwritten by tail. The background of
26829 these strings has to be drawn because tail's foreground draws
26830 over it. */
26831 i = right_overwritten (tail);
26832 if (i >= 0)
26834 enum draw_glyphs_face overlap_hl;
26836 if (check_mouse_face
26837 && mouse_beg_col < i && mouse_end_col > end)
26838 overlap_hl = DRAW_MOUSE_FACE;
26839 else
26840 overlap_hl = DRAW_NORMAL_TEXT;
26842 if (hl != overlap_hl)
26843 clip_tail = tail;
26844 BUILD_GLYPH_STRINGS (end, i, h, t,
26845 overlap_hl, x, last_x);
26846 /* Because BUILD_GLYPH_STRINGS updates the first argument,
26847 we don't have `end = i;' here. */
26848 compute_overhangs_and_x (h, tail->x + tail->width, false);
26849 append_glyph_string_lists (&head, &tail, h, t);
26850 if (clip_tail == NULL)
26851 clip_tail = tail;
26854 /* Append glyph strings for glyphs following the last glyph
26855 string tail that overwrite tail. The foreground of such
26856 glyphs has to be drawn because it writes into the background
26857 of tail. The background must not be drawn because it could
26858 paint over the foreground of following glyphs. */
26859 i = right_overwriting (tail);
26860 if (i >= 0)
26862 enum draw_glyphs_face overlap_hl;
26863 if (check_mouse_face
26864 && mouse_beg_col < i && mouse_end_col > end)
26865 overlap_hl = DRAW_MOUSE_FACE;
26866 else
26867 overlap_hl = DRAW_NORMAL_TEXT;
26869 if (hl == overlap_hl || clip_tail == NULL)
26870 clip_tail = tail;
26871 i++; /* We must include the Ith glyph. */
26872 BUILD_GLYPH_STRINGS (end, i, h, t,
26873 overlap_hl, x, last_x);
26874 for (s = h; s; s = s->next)
26875 s->background_filled_p = true;
26876 compute_overhangs_and_x (h, tail->x + tail->width, false);
26877 append_glyph_string_lists (&head, &tail, h, t);
26879 tail = glyph_string_containing_background_width (tail);
26880 if (clip_tail)
26881 clip_tail = glyph_string_containing_background_width (clip_tail);
26882 if (clip_head || clip_tail)
26883 for (s = head; s; s = s->next)
26885 s->clip_head = clip_head;
26886 s->clip_tail = clip_tail;
26890 /* Draw all strings. */
26891 for (s = head; s; s = s->next)
26892 FRAME_RIF (f)->draw_glyph_string (s);
26894 #ifndef HAVE_NS
26895 /* When focus a sole frame and move horizontally, this clears on_p
26896 causing a failure to erase prev cursor position. */
26897 if (area == TEXT_AREA
26898 && !row->full_width_p
26899 /* When drawing overlapping rows, only the glyph strings'
26900 foreground is drawn, which doesn't erase a cursor
26901 completely. */
26902 && !overlaps)
26904 int x0 = clip_head ? clip_head->x : (head ? head->x : x);
26905 int x1 = (clip_tail ? clip_tail->x + clip_tail->background_width
26906 : (tail ? tail->x + tail->background_width : x));
26907 x0 -= area_left;
26908 x1 -= area_left;
26910 notice_overwritten_cursor (w, TEXT_AREA, x0, x1,
26911 row->y, MATRIX_ROW_BOTTOM_Y (row));
26913 #endif
26915 /* Value is the x-position up to which drawn, relative to AREA of W.
26916 This doesn't include parts drawn because of overhangs. */
26917 if (row->full_width_p)
26918 x_reached = FRAME_TO_WINDOW_PIXEL_X (w, x_reached);
26919 else
26920 x_reached -= area_left;
26922 RELEASE_HDC (hdc, f);
26924 SAFE_FREE ();
26925 return x_reached;
26928 /* Find the first glyph in the run of underlined glyphs preceding the
26929 beginning of glyph string S, and return its font (which could be
26930 NULL). This is needed because that font determines the underline
26931 position and thickness for the entire run of the underlined glyphs.
26932 This function is called from the draw_glyph_string method of GUI
26933 frame's redisplay interface (RIF) when it needs to draw in an
26934 underlined face. */
26935 struct font *
26936 font_for_underline_metrics (struct glyph_string *s)
26938 struct glyph *g0 = s->row->glyphs[s->area], *g;
26940 for (g = s->first_glyph - 1; g >= g0; g--)
26942 struct face *prev_face = FACE_FROM_ID (s->f, g->face_id);
26943 if (!(prev_face && prev_face->underline_p))
26944 break;
26947 /* If preceding glyphs are not underlined, use the font of S. */
26948 if (g == s->first_glyph - 1)
26949 return s->font;
26950 else
26952 /* Otherwise use the font of the last glyph we saw in the above
26953 loop whose face had the underline_p flag set. */
26954 return FACE_FROM_ID (s->f, g[1].face_id)->font;
26958 /* Expand row matrix if too narrow. Don't expand if area
26959 is not present. */
26961 #define IT_EXPAND_MATRIX_WIDTH(it, area) \
26963 if (!it->f->fonts_changed \
26964 && (it->glyph_row->glyphs[area] \
26965 < it->glyph_row->glyphs[area + 1])) \
26967 it->w->ncols_scale_factor++; \
26968 it->f->fonts_changed = true; \
26972 /* Store one glyph for IT->char_to_display in IT->glyph_row.
26973 Called from x_produce_glyphs when IT->glyph_row is non-null. */
26975 static void
26976 append_glyph (struct it *it)
26978 struct glyph *glyph;
26979 enum glyph_row_area area = it->area;
26981 eassert (it->glyph_row);
26982 eassert (it->char_to_display != '\n' && it->char_to_display != '\t');
26984 glyph = it->glyph_row->glyphs[area] + it->glyph_row->used[area];
26985 if (glyph < it->glyph_row->glyphs[area + 1])
26987 /* If the glyph row is reversed, we need to prepend the glyph
26988 rather than append it. */
26989 if (it->glyph_row->reversed_p && area == TEXT_AREA)
26991 struct glyph *g;
26993 /* Make room for the additional glyph. */
26994 for (g = glyph - 1; g >= it->glyph_row->glyphs[area]; g--)
26995 g[1] = *g;
26996 glyph = it->glyph_row->glyphs[area];
26998 glyph->charpos = CHARPOS (it->position);
26999 glyph->object = it->object;
27000 if (it->pixel_width > 0)
27002 eassert (it->pixel_width <= SHRT_MAX);
27003 glyph->pixel_width = it->pixel_width;
27004 glyph->padding_p = false;
27006 else
27008 /* Assure at least 1-pixel width. Otherwise, cursor can't
27009 be displayed correctly. */
27010 glyph->pixel_width = 1;
27011 glyph->padding_p = true;
27013 glyph->ascent = it->ascent;
27014 glyph->descent = it->descent;
27015 glyph->voffset = it->voffset;
27016 glyph->type = CHAR_GLYPH;
27017 glyph->avoid_cursor_p = it->avoid_cursor_p;
27018 glyph->multibyte_p = it->multibyte_p;
27019 if (it->glyph_row->reversed_p && area == TEXT_AREA)
27021 /* In R2L rows, the left and the right box edges need to be
27022 drawn in reverse direction. */
27023 glyph->right_box_line_p = it->start_of_box_run_p;
27024 glyph->left_box_line_p = it->end_of_box_run_p;
27026 else
27028 glyph->left_box_line_p = it->start_of_box_run_p;
27029 glyph->right_box_line_p = it->end_of_box_run_p;
27031 glyph->overlaps_vertically_p = (it->phys_ascent > it->ascent
27032 || it->phys_descent > it->descent);
27033 glyph->glyph_not_available_p = it->glyph_not_available_p;
27034 glyph->face_id = it->face_id;
27035 glyph->u.ch = it->char_to_display;
27036 glyph->slice.img = null_glyph_slice;
27037 glyph->font_type = FONT_TYPE_UNKNOWN;
27038 if (it->bidi_p)
27040 glyph->resolved_level = it->bidi_it.resolved_level;
27041 eassert ((it->bidi_it.type & 7) == it->bidi_it.type);
27042 glyph->bidi_type = it->bidi_it.type;
27044 else
27046 glyph->resolved_level = 0;
27047 glyph->bidi_type = UNKNOWN_BT;
27049 ++it->glyph_row->used[area];
27051 else
27052 IT_EXPAND_MATRIX_WIDTH (it, area);
27055 /* Store one glyph for the composition IT->cmp_it.id in
27056 IT->glyph_row. Called from x_produce_glyphs when IT->glyph_row is
27057 non-null. */
27059 static void
27060 append_composite_glyph (struct it *it)
27062 struct glyph *glyph;
27063 enum glyph_row_area area = it->area;
27065 eassert (it->glyph_row);
27067 glyph = it->glyph_row->glyphs[area] + it->glyph_row->used[area];
27068 if (glyph < it->glyph_row->glyphs[area + 1])
27070 /* If the glyph row is reversed, we need to prepend the glyph
27071 rather than append it. */
27072 if (it->glyph_row->reversed_p && it->area == TEXT_AREA)
27074 struct glyph *g;
27076 /* Make room for the new glyph. */
27077 for (g = glyph - 1; g >= it->glyph_row->glyphs[it->area]; g--)
27078 g[1] = *g;
27079 glyph = it->glyph_row->glyphs[it->area];
27081 glyph->charpos = it->cmp_it.charpos;
27082 glyph->object = it->object;
27083 eassert (it->pixel_width <= SHRT_MAX);
27084 glyph->pixel_width = it->pixel_width;
27085 glyph->ascent = it->ascent;
27086 glyph->descent = it->descent;
27087 glyph->voffset = it->voffset;
27088 glyph->type = COMPOSITE_GLYPH;
27089 if (it->cmp_it.ch < 0)
27091 glyph->u.cmp.automatic = false;
27092 glyph->u.cmp.id = it->cmp_it.id;
27093 glyph->slice.cmp.from = glyph->slice.cmp.to = 0;
27095 else
27097 glyph->u.cmp.automatic = true;
27098 glyph->u.cmp.id = it->cmp_it.id;
27099 glyph->slice.cmp.from = it->cmp_it.from;
27100 glyph->slice.cmp.to = it->cmp_it.to - 1;
27102 glyph->avoid_cursor_p = it->avoid_cursor_p;
27103 glyph->multibyte_p = it->multibyte_p;
27104 if (it->glyph_row->reversed_p && area == TEXT_AREA)
27106 /* In R2L rows, the left and the right box edges need to be
27107 drawn in reverse direction. */
27108 glyph->right_box_line_p = it->start_of_box_run_p;
27109 glyph->left_box_line_p = it->end_of_box_run_p;
27111 else
27113 glyph->left_box_line_p = it->start_of_box_run_p;
27114 glyph->right_box_line_p = it->end_of_box_run_p;
27116 glyph->overlaps_vertically_p = (it->phys_ascent > it->ascent
27117 || it->phys_descent > it->descent);
27118 glyph->padding_p = false;
27119 glyph->glyph_not_available_p = false;
27120 glyph->face_id = it->face_id;
27121 glyph->font_type = FONT_TYPE_UNKNOWN;
27122 if (it->bidi_p)
27124 glyph->resolved_level = it->bidi_it.resolved_level;
27125 eassert ((it->bidi_it.type & 7) == it->bidi_it.type);
27126 glyph->bidi_type = it->bidi_it.type;
27128 ++it->glyph_row->used[area];
27130 else
27131 IT_EXPAND_MATRIX_WIDTH (it, area);
27135 /* Change IT->ascent and IT->height according to the setting of
27136 IT->voffset. */
27138 static void
27139 take_vertical_position_into_account (struct it *it)
27141 if (it->voffset)
27143 if (it->voffset < 0)
27144 /* Increase the ascent so that we can display the text higher
27145 in the line. */
27146 it->ascent -= it->voffset;
27147 else
27148 /* Increase the descent so that we can display the text lower
27149 in the line. */
27150 it->descent += it->voffset;
27155 /* Produce glyphs/get display metrics for the image IT is loaded with.
27156 See the description of struct display_iterator in dispextern.h for
27157 an overview of struct display_iterator. */
27159 static void
27160 produce_image_glyph (struct it *it)
27162 struct image *img;
27163 struct face *face;
27164 int glyph_ascent, crop;
27165 struct glyph_slice slice;
27167 eassert (it->what == IT_IMAGE);
27169 face = FACE_FROM_ID (it->f, it->face_id);
27170 /* Make sure X resources of the face is loaded. */
27171 prepare_face_for_display (it->f, face);
27173 if (it->image_id < 0)
27175 /* Fringe bitmap. */
27176 it->ascent = it->phys_ascent = 0;
27177 it->descent = it->phys_descent = 0;
27178 it->pixel_width = 0;
27179 it->nglyphs = 0;
27180 return;
27183 img = IMAGE_FROM_ID (it->f, it->image_id);
27184 /* Make sure X resources of the image is loaded. */
27185 prepare_image_for_display (it->f, img);
27187 slice.x = slice.y = 0;
27188 slice.width = img->width;
27189 slice.height = img->height;
27191 if (INTEGERP (it->slice.x))
27192 slice.x = XINT (it->slice.x);
27193 else if (FLOATP (it->slice.x))
27194 slice.x = XFLOAT_DATA (it->slice.x) * img->width;
27196 if (INTEGERP (it->slice.y))
27197 slice.y = XINT (it->slice.y);
27198 else if (FLOATP (it->slice.y))
27199 slice.y = XFLOAT_DATA (it->slice.y) * img->height;
27201 if (INTEGERP (it->slice.width))
27202 slice.width = XINT (it->slice.width);
27203 else if (FLOATP (it->slice.width))
27204 slice.width = XFLOAT_DATA (it->slice.width) * img->width;
27206 if (INTEGERP (it->slice.height))
27207 slice.height = XINT (it->slice.height);
27208 else if (FLOATP (it->slice.height))
27209 slice.height = XFLOAT_DATA (it->slice.height) * img->height;
27211 if (slice.x >= img->width)
27212 slice.x = img->width;
27213 if (slice.y >= img->height)
27214 slice.y = img->height;
27215 if (slice.x + slice.width >= img->width)
27216 slice.width = img->width - slice.x;
27217 if (slice.y + slice.height > img->height)
27218 slice.height = img->height - slice.y;
27220 if (slice.width == 0 || slice.height == 0)
27221 return;
27223 it->ascent = it->phys_ascent = glyph_ascent = image_ascent (img, face, &slice);
27225 it->descent = slice.height - glyph_ascent;
27226 if (slice.y == 0)
27227 it->descent += img->vmargin;
27228 if (slice.y + slice.height == img->height)
27229 it->descent += img->vmargin;
27230 it->phys_descent = it->descent;
27232 it->pixel_width = slice.width;
27233 if (slice.x == 0)
27234 it->pixel_width += img->hmargin;
27235 if (slice.x + slice.width == img->width)
27236 it->pixel_width += img->hmargin;
27238 /* It's quite possible for images to have an ascent greater than
27239 their height, so don't get confused in that case. */
27240 if (it->descent < 0)
27241 it->descent = 0;
27243 it->nglyphs = 1;
27245 if (face->box != FACE_NO_BOX)
27247 if (face->box_line_width > 0)
27249 if (slice.y == 0)
27250 it->ascent += face->box_line_width;
27251 if (slice.y + slice.height == img->height)
27252 it->descent += face->box_line_width;
27255 if (it->start_of_box_run_p && slice.x == 0)
27256 it->pixel_width += eabs (face->box_line_width);
27257 if (it->end_of_box_run_p && slice.x + slice.width == img->width)
27258 it->pixel_width += eabs (face->box_line_width);
27261 take_vertical_position_into_account (it);
27263 /* Automatically crop wide image glyphs at right edge so we can
27264 draw the cursor on same display row. */
27265 if ((crop = it->pixel_width - (it->last_visible_x - it->current_x), crop > 0)
27266 && (it->hpos == 0 || it->pixel_width > it->last_visible_x / 4))
27268 it->pixel_width -= crop;
27269 slice.width -= crop;
27272 if (it->glyph_row)
27274 struct glyph *glyph;
27275 enum glyph_row_area area = it->area;
27277 glyph = it->glyph_row->glyphs[area] + it->glyph_row->used[area];
27278 if (it->glyph_row->reversed_p)
27280 struct glyph *g;
27282 /* Make room for the new glyph. */
27283 for (g = glyph - 1; g >= it->glyph_row->glyphs[it->area]; g--)
27284 g[1] = *g;
27285 glyph = it->glyph_row->glyphs[it->area];
27287 if (glyph < it->glyph_row->glyphs[area + 1])
27289 glyph->charpos = CHARPOS (it->position);
27290 glyph->object = it->object;
27291 glyph->pixel_width = clip_to_bounds (-1, it->pixel_width, SHRT_MAX);
27292 glyph->ascent = glyph_ascent;
27293 glyph->descent = it->descent;
27294 glyph->voffset = it->voffset;
27295 glyph->type = IMAGE_GLYPH;
27296 glyph->avoid_cursor_p = it->avoid_cursor_p;
27297 glyph->multibyte_p = it->multibyte_p;
27298 if (it->glyph_row->reversed_p && area == TEXT_AREA)
27300 /* In R2L rows, the left and the right box edges need to be
27301 drawn in reverse direction. */
27302 glyph->right_box_line_p = it->start_of_box_run_p;
27303 glyph->left_box_line_p = it->end_of_box_run_p;
27305 else
27307 glyph->left_box_line_p = it->start_of_box_run_p;
27308 glyph->right_box_line_p = it->end_of_box_run_p;
27310 glyph->overlaps_vertically_p = false;
27311 glyph->padding_p = false;
27312 glyph->glyph_not_available_p = false;
27313 glyph->face_id = it->face_id;
27314 glyph->u.img_id = img->id;
27315 glyph->slice.img = slice;
27316 glyph->font_type = FONT_TYPE_UNKNOWN;
27317 if (it->bidi_p)
27319 glyph->resolved_level = it->bidi_it.resolved_level;
27320 eassert ((it->bidi_it.type & 7) == it->bidi_it.type);
27321 glyph->bidi_type = it->bidi_it.type;
27323 ++it->glyph_row->used[area];
27325 else
27326 IT_EXPAND_MATRIX_WIDTH (it, area);
27330 static void
27331 produce_xwidget_glyph (struct it *it)
27333 #ifdef HAVE_XWIDGETS
27334 struct xwidget *xw;
27335 int glyph_ascent, crop;
27336 eassert (it->what == IT_XWIDGET);
27338 struct face *face = FACE_FROM_ID (it->f, it->face_id);
27339 /* Make sure X resources of the face is loaded. */
27340 prepare_face_for_display (it->f, face);
27342 xw = it->xwidget;
27343 it->ascent = it->phys_ascent = glyph_ascent = xw->height/2;
27344 it->descent = xw->height/2;
27345 it->phys_descent = it->descent;
27346 it->pixel_width = xw->width;
27347 /* It's quite possible for images to have an ascent greater than
27348 their height, so don't get confused in that case. */
27349 if (it->descent < 0)
27350 it->descent = 0;
27352 it->nglyphs = 1;
27354 if (face->box != FACE_NO_BOX)
27356 if (face->box_line_width > 0)
27358 it->ascent += face->box_line_width;
27359 it->descent += face->box_line_width;
27362 if (it->start_of_box_run_p)
27363 it->pixel_width += eabs (face->box_line_width);
27364 it->pixel_width += eabs (face->box_line_width);
27367 take_vertical_position_into_account (it);
27369 /* Automatically crop wide image glyphs at right edge so we can
27370 draw the cursor on same display row. */
27371 crop = it->pixel_width - (it->last_visible_x - it->current_x);
27372 if (crop > 0 && (it->hpos == 0 || it->pixel_width > it->last_visible_x / 4))
27373 it->pixel_width -= crop;
27375 if (it->glyph_row)
27377 enum glyph_row_area area = it->area;
27378 struct glyph *glyph
27379 = it->glyph_row->glyphs[area] + it->glyph_row->used[area];
27381 if (it->glyph_row->reversed_p)
27383 struct glyph *g;
27385 /* Make room for the new glyph. */
27386 for (g = glyph - 1; g >= it->glyph_row->glyphs[it->area]; g--)
27387 g[1] = *g;
27388 glyph = it->glyph_row->glyphs[it->area];
27390 if (glyph < it->glyph_row->glyphs[area + 1])
27392 glyph->charpos = CHARPOS (it->position);
27393 glyph->object = it->object;
27394 glyph->pixel_width = clip_to_bounds (-1, it->pixel_width, SHRT_MAX);
27395 glyph->ascent = glyph_ascent;
27396 glyph->descent = it->descent;
27397 glyph->voffset = it->voffset;
27398 glyph->type = XWIDGET_GLYPH;
27399 glyph->avoid_cursor_p = it->avoid_cursor_p;
27400 glyph->multibyte_p = it->multibyte_p;
27401 if (it->glyph_row->reversed_p && area == TEXT_AREA)
27403 /* In R2L rows, the left and the right box edges need to be
27404 drawn in reverse direction. */
27405 glyph->right_box_line_p = it->start_of_box_run_p;
27406 glyph->left_box_line_p = it->end_of_box_run_p;
27408 else
27410 glyph->left_box_line_p = it->start_of_box_run_p;
27411 glyph->right_box_line_p = it->end_of_box_run_p;
27413 glyph->overlaps_vertically_p = 0;
27414 glyph->padding_p = 0;
27415 glyph->glyph_not_available_p = 0;
27416 glyph->face_id = it->face_id;
27417 glyph->u.xwidget = it->xwidget;
27418 glyph->font_type = FONT_TYPE_UNKNOWN;
27419 if (it->bidi_p)
27421 glyph->resolved_level = it->bidi_it.resolved_level;
27422 eassert ((it->bidi_it.type & 7) == it->bidi_it.type);
27423 glyph->bidi_type = it->bidi_it.type;
27425 ++it->glyph_row->used[area];
27427 else
27428 IT_EXPAND_MATRIX_WIDTH (it, area);
27430 #endif
27433 /* Append a stretch glyph to IT->glyph_row. OBJECT is the source
27434 of the glyph, WIDTH and HEIGHT are the width and height of the
27435 stretch. ASCENT is the ascent of the glyph (0 <= ASCENT <= HEIGHT). */
27437 static void
27438 append_stretch_glyph (struct it *it, Lisp_Object object,
27439 int width, int height, int ascent)
27441 struct glyph *glyph;
27442 enum glyph_row_area area = it->area;
27444 eassert (ascent >= 0 && ascent <= height);
27446 glyph = it->glyph_row->glyphs[area] + it->glyph_row->used[area];
27447 if (glyph < it->glyph_row->glyphs[area + 1])
27449 /* If the glyph row is reversed, we need to prepend the glyph
27450 rather than append it. */
27451 if (it->glyph_row->reversed_p && area == TEXT_AREA)
27453 struct glyph *g;
27455 /* Make room for the additional glyph. */
27456 for (g = glyph - 1; g >= it->glyph_row->glyphs[area]; g--)
27457 g[1] = *g;
27458 glyph = it->glyph_row->glyphs[area];
27460 /* Decrease the width of the first glyph of the row that
27461 begins before first_visible_x (e.g., due to hscroll).
27462 This is so the overall width of the row becomes smaller
27463 by the scroll amount, and the stretch glyph appended by
27464 extend_face_to_end_of_line will be wider, to shift the
27465 row glyphs to the right. (In L2R rows, the corresponding
27466 left-shift effect is accomplished by setting row->x to a
27467 negative value, which won't work with R2L rows.)
27469 This must leave us with a positive value of WIDTH, since
27470 otherwise the call to move_it_in_display_line_to at the
27471 beginning of display_line would have got past the entire
27472 first glyph, and then it->current_x would have been
27473 greater or equal to it->first_visible_x. */
27474 if (it->current_x < it->first_visible_x)
27475 width -= it->first_visible_x - it->current_x;
27476 eassert (width > 0);
27478 glyph->charpos = CHARPOS (it->position);
27479 glyph->object = object;
27480 /* FIXME: It would be better to use TYPE_MAX here, but
27481 __typeof__ is not portable enough... */
27482 glyph->pixel_width = clip_to_bounds (-1, width, SHRT_MAX);
27483 glyph->ascent = ascent;
27484 glyph->descent = height - ascent;
27485 glyph->voffset = it->voffset;
27486 glyph->type = STRETCH_GLYPH;
27487 glyph->avoid_cursor_p = it->avoid_cursor_p;
27488 glyph->multibyte_p = it->multibyte_p;
27489 if (it->glyph_row->reversed_p && area == TEXT_AREA)
27491 /* In R2L rows, the left and the right box edges need to be
27492 drawn in reverse direction. */
27493 glyph->right_box_line_p = it->start_of_box_run_p;
27494 glyph->left_box_line_p = it->end_of_box_run_p;
27496 else
27498 glyph->left_box_line_p = it->start_of_box_run_p;
27499 glyph->right_box_line_p = it->end_of_box_run_p;
27501 glyph->overlaps_vertically_p = false;
27502 glyph->padding_p = false;
27503 glyph->glyph_not_available_p = false;
27504 glyph->face_id = it->face_id;
27505 glyph->u.stretch.ascent = ascent;
27506 glyph->u.stretch.height = height;
27507 glyph->slice.img = null_glyph_slice;
27508 glyph->font_type = FONT_TYPE_UNKNOWN;
27509 if (it->bidi_p)
27511 glyph->resolved_level = it->bidi_it.resolved_level;
27512 eassert ((it->bidi_it.type & 7) == it->bidi_it.type);
27513 glyph->bidi_type = it->bidi_it.type;
27515 else
27517 glyph->resolved_level = 0;
27518 glyph->bidi_type = UNKNOWN_BT;
27520 ++it->glyph_row->used[area];
27522 else
27523 IT_EXPAND_MATRIX_WIDTH (it, area);
27526 #endif /* HAVE_WINDOW_SYSTEM */
27528 /* Produce a stretch glyph for iterator IT. IT->object is the value
27529 of the glyph property displayed. The value must be a list
27530 `(space KEYWORD VALUE ...)' with the following KEYWORD/VALUE pairs
27531 being recognized:
27533 1. `:width WIDTH' specifies that the space should be WIDTH *
27534 canonical char width wide. WIDTH may be an integer or floating
27535 point number.
27537 2. `:relative-width FACTOR' specifies that the width of the stretch
27538 should be computed from the width of the first character having the
27539 `glyph' property, and should be FACTOR times that width.
27541 3. `:align-to HPOS' specifies that the space should be wide enough
27542 to reach HPOS, a value in canonical character units.
27544 Exactly one of the above pairs must be present.
27546 4. `:height HEIGHT' specifies that the height of the stretch produced
27547 should be HEIGHT, measured in canonical character units.
27549 5. `:relative-height FACTOR' specifies that the height of the
27550 stretch should be FACTOR times the height of the characters having
27551 the glyph property.
27553 Either none or exactly one of 4 or 5 must be present.
27555 6. `:ascent ASCENT' specifies that ASCENT percent of the height
27556 of the stretch should be used for the ascent of the stretch.
27557 ASCENT must be in the range 0 <= ASCENT <= 100. */
27559 void
27560 produce_stretch_glyph (struct it *it)
27562 /* (space :width WIDTH :height HEIGHT ...) */
27563 Lisp_Object prop, plist;
27564 int width = 0, height = 0, align_to = -1;
27565 bool zero_width_ok_p = false;
27566 double tem;
27567 struct font *font = NULL;
27569 #ifdef HAVE_WINDOW_SYSTEM
27570 int ascent = 0;
27571 bool zero_height_ok_p = false;
27573 if (FRAME_WINDOW_P (it->f))
27575 struct face *face = FACE_FROM_ID (it->f, it->face_id);
27576 font = face->font ? face->font : FRAME_FONT (it->f);
27577 prepare_face_for_display (it->f, face);
27579 #endif
27581 /* List should start with `space'. */
27582 eassert (CONSP (it->object) && EQ (XCAR (it->object), Qspace));
27583 plist = XCDR (it->object);
27585 /* Compute the width of the stretch. */
27586 if ((prop = Fplist_get (plist, QCwidth), !NILP (prop))
27587 && calc_pixel_width_or_height (&tem, it, prop, font, true, 0))
27589 /* Absolute width `:width WIDTH' specified and valid. */
27590 zero_width_ok_p = true;
27591 width = (int)tem;
27593 else if (prop = Fplist_get (plist, QCrelative_width), NUMVAL (prop) > 0)
27595 /* Relative width `:relative-width FACTOR' specified and valid.
27596 Compute the width of the characters having the `glyph'
27597 property. */
27598 struct it it2;
27599 unsigned char *p = BYTE_POS_ADDR (IT_BYTEPOS (*it));
27601 it2 = *it;
27602 if (it->multibyte_p)
27603 it2.c = it2.char_to_display = STRING_CHAR_AND_LENGTH (p, it2.len);
27604 else
27606 it2.c = it2.char_to_display = *p, it2.len = 1;
27607 if (! ASCII_CHAR_P (it2.c))
27608 it2.char_to_display = BYTE8_TO_CHAR (it2.c);
27611 it2.glyph_row = NULL;
27612 it2.what = IT_CHARACTER;
27613 PRODUCE_GLYPHS (&it2);
27614 width = NUMVAL (prop) * it2.pixel_width;
27616 else if ((prop = Fplist_get (plist, QCalign_to), !NILP (prop))
27617 && calc_pixel_width_or_height (&tem, it, prop, font, true,
27618 &align_to))
27620 if (it->glyph_row == NULL || !it->glyph_row->mode_line_p)
27621 align_to = (align_to < 0
27623 : align_to - window_box_left_offset (it->w, TEXT_AREA));
27624 else if (align_to < 0)
27625 align_to = window_box_left_offset (it->w, TEXT_AREA);
27626 width = max (0, (int)tem + align_to - it->current_x);
27627 zero_width_ok_p = true;
27629 else
27630 /* Nothing specified -> width defaults to canonical char width. */
27631 width = FRAME_COLUMN_WIDTH (it->f);
27633 if (width <= 0 && (width < 0 || !zero_width_ok_p))
27634 width = 1;
27636 #ifdef HAVE_WINDOW_SYSTEM
27637 /* Compute height. */
27638 if (FRAME_WINDOW_P (it->f))
27640 int default_height = normal_char_height (font, ' ');
27642 if ((prop = Fplist_get (plist, QCheight), !NILP (prop))
27643 && calc_pixel_width_or_height (&tem, it, prop, font, false, 0))
27645 height = (int)tem;
27646 zero_height_ok_p = true;
27648 else if (prop = Fplist_get (plist, QCrelative_height),
27649 NUMVAL (prop) > 0)
27650 height = default_height * NUMVAL (prop);
27651 else
27652 height = default_height;
27654 if (height <= 0 && (height < 0 || !zero_height_ok_p))
27655 height = 1;
27657 /* Compute percentage of height used for ascent. If
27658 `:ascent ASCENT' is present and valid, use that. Otherwise,
27659 derive the ascent from the font in use. */
27660 if (prop = Fplist_get (plist, QCascent),
27661 NUMVAL (prop) > 0 && NUMVAL (prop) <= 100)
27662 ascent = height * NUMVAL (prop) / 100.0;
27663 else if (!NILP (prop)
27664 && calc_pixel_width_or_height (&tem, it, prop, font, false, 0))
27665 ascent = min (max (0, (int)tem), height);
27666 else
27667 ascent = (height * FONT_BASE (font)) / FONT_HEIGHT (font);
27669 else
27670 #endif /* HAVE_WINDOW_SYSTEM */
27671 height = 1;
27673 if (width > 0 && it->line_wrap != TRUNCATE
27674 && it->current_x + width > it->last_visible_x)
27676 width = it->last_visible_x - it->current_x;
27677 #ifdef HAVE_WINDOW_SYSTEM
27678 /* Subtract one more pixel from the stretch width, but only on
27679 GUI frames, since on a TTY each glyph is one "pixel" wide. */
27680 width -= FRAME_WINDOW_P (it->f);
27681 #endif
27684 if (width > 0 && height > 0 && it->glyph_row)
27686 Lisp_Object o_object = it->object;
27687 Lisp_Object object = it->stack[it->sp - 1].string;
27688 int n = width;
27690 if (!STRINGP (object))
27691 object = it->w->contents;
27692 #ifdef HAVE_WINDOW_SYSTEM
27693 if (FRAME_WINDOW_P (it->f))
27694 append_stretch_glyph (it, object, width, height, ascent);
27695 else
27696 #endif
27698 it->object = object;
27699 it->char_to_display = ' ';
27700 it->pixel_width = it->len = 1;
27701 while (n--)
27702 tty_append_glyph (it);
27703 it->object = o_object;
27707 it->pixel_width = width;
27708 #ifdef HAVE_WINDOW_SYSTEM
27709 if (FRAME_WINDOW_P (it->f))
27711 it->ascent = it->phys_ascent = ascent;
27712 it->descent = it->phys_descent = height - it->ascent;
27713 it->nglyphs = width > 0 && height > 0;
27714 take_vertical_position_into_account (it);
27716 else
27717 #endif
27718 it->nglyphs = width;
27721 /* Get information about special display element WHAT in an
27722 environment described by IT. WHAT is one of IT_TRUNCATION or
27723 IT_CONTINUATION. Maybe produce glyphs for WHAT if IT has a
27724 non-null glyph_row member. This function ensures that fields like
27725 face_id, c, len of IT are left untouched. */
27727 static void
27728 produce_special_glyphs (struct it *it, enum display_element_type what)
27730 struct it temp_it;
27731 Lisp_Object gc;
27732 GLYPH glyph;
27734 temp_it = *it;
27735 temp_it.object = Qnil;
27736 memset (&temp_it.current, 0, sizeof temp_it.current);
27738 if (what == IT_CONTINUATION)
27740 /* Continuation glyph. For R2L lines, we mirror it by hand. */
27741 if (it->bidi_it.paragraph_dir == R2L)
27742 SET_GLYPH_FROM_CHAR (glyph, '/');
27743 else
27744 SET_GLYPH_FROM_CHAR (glyph, '\\');
27745 if (it->dp
27746 && (gc = DISP_CONTINUE_GLYPH (it->dp), GLYPH_CODE_P (gc)))
27748 /* FIXME: Should we mirror GC for R2L lines? */
27749 SET_GLYPH_FROM_GLYPH_CODE (glyph, gc);
27750 spec_glyph_lookup_face (XWINDOW (it->window), &glyph);
27753 else if (what == IT_TRUNCATION)
27755 /* Truncation glyph. */
27756 SET_GLYPH_FROM_CHAR (glyph, '$');
27757 if (it->dp
27758 && (gc = DISP_TRUNC_GLYPH (it->dp), GLYPH_CODE_P (gc)))
27760 /* FIXME: Should we mirror GC for R2L lines? */
27761 SET_GLYPH_FROM_GLYPH_CODE (glyph, gc);
27762 spec_glyph_lookup_face (XWINDOW (it->window), &glyph);
27765 else
27766 emacs_abort ();
27768 #ifdef HAVE_WINDOW_SYSTEM
27769 /* On a GUI frame, when the right fringe (left fringe for R2L rows)
27770 is turned off, we precede the truncation/continuation glyphs by a
27771 stretch glyph whose width is computed such that these special
27772 glyphs are aligned at the window margin, even when very different
27773 fonts are used in different glyph rows. */
27774 if (FRAME_WINDOW_P (temp_it.f)
27775 /* init_iterator calls this with it->glyph_row == NULL, and it
27776 wants only the pixel width of the truncation/continuation
27777 glyphs. */
27778 && temp_it.glyph_row
27779 /* insert_left_trunc_glyphs calls us at the beginning of the
27780 row, and it has its own calculation of the stretch glyph
27781 width. */
27782 && temp_it.glyph_row->used[TEXT_AREA] > 0
27783 && (temp_it.glyph_row->reversed_p
27784 ? WINDOW_LEFT_FRINGE_WIDTH (temp_it.w)
27785 : WINDOW_RIGHT_FRINGE_WIDTH (temp_it.w)) == 0)
27787 int stretch_width = temp_it.last_visible_x - temp_it.current_x;
27789 if (stretch_width > 0)
27791 struct face *face = FACE_FROM_ID (temp_it.f, temp_it.face_id);
27792 struct font *font =
27793 face->font ? face->font : FRAME_FONT (temp_it.f);
27794 int stretch_ascent =
27795 (((temp_it.ascent + temp_it.descent)
27796 * FONT_BASE (font)) / FONT_HEIGHT (font));
27798 append_stretch_glyph (&temp_it, Qnil, stretch_width,
27799 temp_it.ascent + temp_it.descent,
27800 stretch_ascent);
27803 #endif
27805 temp_it.dp = NULL;
27806 temp_it.what = IT_CHARACTER;
27807 temp_it.c = temp_it.char_to_display = GLYPH_CHAR (glyph);
27808 temp_it.face_id = GLYPH_FACE (glyph);
27809 temp_it.len = CHAR_BYTES (temp_it.c);
27811 PRODUCE_GLYPHS (&temp_it);
27812 it->pixel_width = temp_it.pixel_width;
27813 it->nglyphs = temp_it.nglyphs;
27816 #ifdef HAVE_WINDOW_SYSTEM
27818 /* Calculate line-height and line-spacing properties.
27819 An integer value specifies explicit pixel value.
27820 A float value specifies relative value to current face height.
27821 A cons (float . face-name) specifies relative value to
27822 height of specified face font.
27824 Returns height in pixels, or nil. */
27826 static Lisp_Object
27827 calc_line_height_property (struct it *it, Lisp_Object val, struct font *font,
27828 int boff, bool override)
27830 Lisp_Object face_name = Qnil;
27831 int ascent, descent, height;
27833 if (NILP (val) || INTEGERP (val) || (override && EQ (val, Qt)))
27834 return val;
27836 if (CONSP (val))
27838 face_name = XCAR (val);
27839 val = XCDR (val);
27840 if (!NUMBERP (val))
27841 val = make_number (1);
27842 if (NILP (face_name))
27844 height = it->ascent + it->descent;
27845 goto scale;
27849 if (NILP (face_name))
27851 font = FRAME_FONT (it->f);
27852 boff = FRAME_BASELINE_OFFSET (it->f);
27854 else if (EQ (face_name, Qt))
27856 override = false;
27858 else
27860 int face_id;
27861 struct face *face;
27863 face_id = lookup_named_face (it->f, face_name, false);
27864 face = FACE_FROM_ID_OR_NULL (it->f, face_id);
27865 if (face == NULL || ((font = face->font) == NULL))
27866 return make_number (-1);
27867 boff = font->baseline_offset;
27868 if (font->vertical_centering)
27869 boff = VCENTER_BASELINE_OFFSET (font, it->f) - boff;
27872 normal_char_ascent_descent (font, -1, &ascent, &descent);
27874 if (override)
27876 it->override_ascent = ascent;
27877 it->override_descent = descent;
27878 it->override_boff = boff;
27881 height = ascent + descent;
27883 scale:
27884 if (FLOATP (val))
27885 height = (int)(XFLOAT_DATA (val) * height);
27886 else if (INTEGERP (val))
27887 height *= XINT (val);
27889 return make_number (height);
27893 /* Append a glyph for a glyphless character to IT->glyph_row. FACE_ID
27894 is a face ID to be used for the glyph. FOR_NO_FONT is true if
27895 and only if this is for a character for which no font was found.
27897 If the display method (it->glyphless_method) is
27898 GLYPHLESS_DISPLAY_ACRONYM or GLYPHLESS_DISPLAY_HEX_CODE, LEN is a
27899 length of the acronym or the hexadecimal string, UPPER_XOFF and
27900 UPPER_YOFF are pixel offsets for the upper part of the string,
27901 LOWER_XOFF and LOWER_YOFF are for the lower part.
27903 For the other display methods, LEN through LOWER_YOFF are zero. */
27905 static void
27906 append_glyphless_glyph (struct it *it, int face_id, bool for_no_font, int len,
27907 short upper_xoff, short upper_yoff,
27908 short lower_xoff, short lower_yoff)
27910 struct glyph *glyph;
27911 enum glyph_row_area area = it->area;
27913 glyph = it->glyph_row->glyphs[area] + it->glyph_row->used[area];
27914 if (glyph < it->glyph_row->glyphs[area + 1])
27916 /* If the glyph row is reversed, we need to prepend the glyph
27917 rather than append it. */
27918 if (it->glyph_row->reversed_p && area == TEXT_AREA)
27920 struct glyph *g;
27922 /* Make room for the additional glyph. */
27923 for (g = glyph - 1; g >= it->glyph_row->glyphs[area]; g--)
27924 g[1] = *g;
27925 glyph = it->glyph_row->glyphs[area];
27927 glyph->charpos = CHARPOS (it->position);
27928 glyph->object = it->object;
27929 eassert (it->pixel_width <= SHRT_MAX);
27930 glyph->pixel_width = it->pixel_width;
27931 glyph->ascent = it->ascent;
27932 glyph->descent = it->descent;
27933 glyph->voffset = it->voffset;
27934 glyph->type = GLYPHLESS_GLYPH;
27935 glyph->u.glyphless.method = it->glyphless_method;
27936 glyph->u.glyphless.for_no_font = for_no_font;
27937 glyph->u.glyphless.len = len;
27938 glyph->u.glyphless.ch = it->c;
27939 glyph->slice.glyphless.upper_xoff = upper_xoff;
27940 glyph->slice.glyphless.upper_yoff = upper_yoff;
27941 glyph->slice.glyphless.lower_xoff = lower_xoff;
27942 glyph->slice.glyphless.lower_yoff = lower_yoff;
27943 glyph->avoid_cursor_p = it->avoid_cursor_p;
27944 glyph->multibyte_p = it->multibyte_p;
27945 if (it->glyph_row->reversed_p && area == TEXT_AREA)
27947 /* In R2L rows, the left and the right box edges need to be
27948 drawn in reverse direction. */
27949 glyph->right_box_line_p = it->start_of_box_run_p;
27950 glyph->left_box_line_p = it->end_of_box_run_p;
27952 else
27954 glyph->left_box_line_p = it->start_of_box_run_p;
27955 glyph->right_box_line_p = it->end_of_box_run_p;
27957 glyph->overlaps_vertically_p = (it->phys_ascent > it->ascent
27958 || it->phys_descent > it->descent);
27959 glyph->padding_p = false;
27960 glyph->glyph_not_available_p = false;
27961 glyph->face_id = face_id;
27962 glyph->font_type = FONT_TYPE_UNKNOWN;
27963 if (it->bidi_p)
27965 glyph->resolved_level = it->bidi_it.resolved_level;
27966 eassert ((it->bidi_it.type & 7) == it->bidi_it.type);
27967 glyph->bidi_type = it->bidi_it.type;
27969 ++it->glyph_row->used[area];
27971 else
27972 IT_EXPAND_MATRIX_WIDTH (it, area);
27976 /* Produce a glyph for a glyphless character for iterator IT.
27977 IT->glyphless_method specifies which method to use for displaying
27978 the character. See the description of enum
27979 glyphless_display_method in dispextern.h for the detail.
27981 FOR_NO_FONT is true if and only if this is for a character for
27982 which no font was found. ACRONYM, if non-nil, is an acronym string
27983 for the character. */
27985 static void
27986 produce_glyphless_glyph (struct it *it, bool for_no_font, Lisp_Object acronym)
27988 int face_id;
27989 struct face *face;
27990 struct font *font;
27991 int base_width, base_height, width, height;
27992 short upper_xoff, upper_yoff, lower_xoff, lower_yoff;
27993 int len;
27995 /* Get the metrics of the base font. We always refer to the current
27996 ASCII face. */
27997 face = FACE_FROM_ID (it->f, it->face_id)->ascii_face;
27998 font = face->font ? face->font : FRAME_FONT (it->f);
27999 normal_char_ascent_descent (font, -1, &it->ascent, &it->descent);
28000 it->ascent += font->baseline_offset;
28001 it->descent -= font->baseline_offset;
28002 base_height = it->ascent + it->descent;
28003 base_width = font->average_width;
28005 face_id = merge_glyphless_glyph_face (it);
28007 if (it->glyphless_method == GLYPHLESS_DISPLAY_THIN_SPACE)
28009 it->pixel_width = THIN_SPACE_WIDTH;
28010 len = 0;
28011 upper_xoff = upper_yoff = lower_xoff = lower_yoff = 0;
28013 else if (it->glyphless_method == GLYPHLESS_DISPLAY_EMPTY_BOX)
28015 width = CHARACTER_WIDTH (it->c);
28016 if (width == 0)
28017 width = 1;
28018 else if (width > 4)
28019 width = 4;
28020 it->pixel_width = base_width * width;
28021 len = 0;
28022 upper_xoff = upper_yoff = lower_xoff = lower_yoff = 0;
28024 else
28026 char buf[7];
28027 const char *str;
28028 unsigned int code[6];
28029 int upper_len;
28030 int ascent, descent;
28031 struct font_metrics metrics_upper, metrics_lower;
28033 face = FACE_FROM_ID (it->f, face_id);
28034 font = face->font ? face->font : FRAME_FONT (it->f);
28035 prepare_face_for_display (it->f, face);
28037 if (it->glyphless_method == GLYPHLESS_DISPLAY_ACRONYM)
28039 if (! STRINGP (acronym) && CHAR_TABLE_P (Vglyphless_char_display))
28040 acronym = CHAR_TABLE_REF (Vglyphless_char_display, it->c);
28041 if (CONSP (acronym))
28042 acronym = XCAR (acronym);
28043 str = STRINGP (acronym) ? SSDATA (acronym) : "";
28045 else
28047 eassert (it->glyphless_method == GLYPHLESS_DISPLAY_HEX_CODE);
28048 sprintf (buf, "%0*X", it->c < 0x10000 ? 4 : 6, it->c + 0u);
28049 str = buf;
28051 for (len = 0; str[len] && ASCII_CHAR_P (str[len]) && len < 6; len++)
28052 code[len] = font->driver->encode_char (font, str[len]);
28053 upper_len = (len + 1) / 2;
28054 font->driver->text_extents (font, code, upper_len,
28055 &metrics_upper);
28056 font->driver->text_extents (font, code + upper_len, len - upper_len,
28057 &metrics_lower);
28061 /* +4 is for vertical bars of a box plus 1-pixel spaces at both side. */
28062 width = max (metrics_upper.width, metrics_lower.width) + 4;
28063 upper_xoff = upper_yoff = 2; /* the typical case */
28064 if (base_width >= width)
28066 /* Align the upper to the left, the lower to the right. */
28067 it->pixel_width = base_width;
28068 lower_xoff = base_width - 2 - metrics_lower.width;
28070 else
28072 /* Center the shorter one. */
28073 it->pixel_width = width;
28074 if (metrics_upper.width >= metrics_lower.width)
28075 lower_xoff = (width - metrics_lower.width) / 2;
28076 else
28078 /* FIXME: This code doesn't look right. It formerly was
28079 missing the "lower_xoff = 0;", which couldn't have
28080 been right since it left lower_xoff uninitialized. */
28081 lower_xoff = 0;
28082 upper_xoff = (width - metrics_upper.width) / 2;
28086 /* +5 is for horizontal bars of a box plus 1-pixel spaces at
28087 top, bottom, and between upper and lower strings. */
28088 height = (metrics_upper.ascent + metrics_upper.descent
28089 + metrics_lower.ascent + metrics_lower.descent) + 5;
28090 /* Center vertically.
28091 H:base_height, D:base_descent
28092 h:height, ld:lower_descent, la:lower_ascent, ud:upper_descent
28094 ascent = - (D - H/2 - h/2 + 1); "+ 1" for rounding up
28095 descent = D - H/2 + h/2;
28096 lower_yoff = descent - 2 - ld;
28097 upper_yoff = lower_yoff - la - 1 - ud; */
28098 ascent = - (it->descent - (base_height + height + 1) / 2);
28099 descent = it->descent - (base_height - height) / 2;
28100 lower_yoff = descent - 2 - metrics_lower.descent;
28101 upper_yoff = (lower_yoff - metrics_lower.ascent - 1
28102 - metrics_upper.descent);
28103 /* Don't make the height shorter than the base height. */
28104 if (height > base_height)
28106 it->ascent = ascent;
28107 it->descent = descent;
28111 it->phys_ascent = it->ascent;
28112 it->phys_descent = it->descent;
28113 if (it->glyph_row)
28114 append_glyphless_glyph (it, face_id, for_no_font, len,
28115 upper_xoff, upper_yoff,
28116 lower_xoff, lower_yoff);
28117 it->nglyphs = 1;
28118 take_vertical_position_into_account (it);
28122 /* RIF:
28123 Produce glyphs/get display metrics for the display element IT is
28124 loaded with. See the description of struct it in dispextern.h
28125 for an overview of struct it. */
28127 void
28128 x_produce_glyphs (struct it *it)
28130 int extra_line_spacing = it->extra_line_spacing;
28132 it->glyph_not_available_p = false;
28134 if (it->what == IT_CHARACTER)
28136 XChar2b char2b;
28137 struct face *face = FACE_FROM_ID (it->f, it->face_id);
28138 struct font *font = face->font;
28139 struct font_metrics *pcm = NULL;
28140 int boff; /* Baseline offset. */
28142 if (font == NULL)
28144 /* When no suitable font is found, display this character by
28145 the method specified in the first extra slot of
28146 Vglyphless_char_display. */
28147 Lisp_Object acronym = lookup_glyphless_char_display (-1, it);
28149 eassert (it->what == IT_GLYPHLESS);
28150 produce_glyphless_glyph (it, true,
28151 STRINGP (acronym) ? acronym : Qnil);
28152 goto done;
28155 boff = font->baseline_offset;
28156 if (font->vertical_centering)
28157 boff = VCENTER_BASELINE_OFFSET (font, it->f) - boff;
28159 if (it->char_to_display != '\n' && it->char_to_display != '\t')
28161 it->nglyphs = 1;
28163 if (it->override_ascent >= 0)
28165 it->ascent = it->override_ascent;
28166 it->descent = it->override_descent;
28167 boff = it->override_boff;
28169 else
28171 it->ascent = FONT_BASE (font) + boff;
28172 it->descent = FONT_DESCENT (font) - boff;
28175 if (get_char_glyph_code (it->char_to_display, font, &char2b))
28177 pcm = get_per_char_metric (font, &char2b);
28178 if (pcm->width == 0
28179 && pcm->rbearing == 0 && pcm->lbearing == 0)
28180 pcm = NULL;
28183 if (pcm)
28185 it->phys_ascent = pcm->ascent + boff;
28186 it->phys_descent = pcm->descent - boff;
28187 it->pixel_width = pcm->width;
28188 /* Don't use font-global values for ascent and descent
28189 if they result in an exceedingly large line height. */
28190 if (it->override_ascent < 0)
28192 if (FONT_TOO_HIGH (font))
28194 it->ascent = it->phys_ascent;
28195 it->descent = it->phys_descent;
28196 /* These limitations are enforced by an
28197 assertion near the end of this function. */
28198 if (it->ascent < 0)
28199 it->ascent = 0;
28200 if (it->descent < 0)
28201 it->descent = 0;
28205 else
28207 it->glyph_not_available_p = true;
28208 it->phys_ascent = it->ascent;
28209 it->phys_descent = it->descent;
28210 it->pixel_width = font->space_width;
28213 if (it->constrain_row_ascent_descent_p)
28215 if (it->descent > it->max_descent)
28217 it->ascent += it->descent - it->max_descent;
28218 it->descent = it->max_descent;
28220 if (it->ascent > it->max_ascent)
28222 it->descent = min (it->max_descent, it->descent + it->ascent - it->max_ascent);
28223 it->ascent = it->max_ascent;
28225 it->phys_ascent = min (it->phys_ascent, it->ascent);
28226 it->phys_descent = min (it->phys_descent, it->descent);
28227 extra_line_spacing = 0;
28230 /* If this is a space inside a region of text with
28231 `space-width' property, change its width. */
28232 bool stretched_p
28233 = it->char_to_display == ' ' && !NILP (it->space_width);
28234 if (stretched_p)
28235 it->pixel_width *= XFLOATINT (it->space_width);
28237 /* If face has a box, add the box thickness to the character
28238 height. If character has a box line to the left and/or
28239 right, add the box line width to the character's width. */
28240 if (face->box != FACE_NO_BOX)
28242 int thick = face->box_line_width;
28244 if (thick > 0)
28246 it->ascent += thick;
28247 it->descent += thick;
28249 else
28250 thick = -thick;
28252 if (it->start_of_box_run_p)
28253 it->pixel_width += thick;
28254 if (it->end_of_box_run_p)
28255 it->pixel_width += thick;
28258 /* If face has an overline, add the height of the overline
28259 (1 pixel) and a 1 pixel margin to the character height. */
28260 if (face->overline_p)
28261 it->ascent += overline_margin;
28263 if (it->constrain_row_ascent_descent_p)
28265 if (it->ascent > it->max_ascent)
28266 it->ascent = it->max_ascent;
28267 if (it->descent > it->max_descent)
28268 it->descent = it->max_descent;
28271 take_vertical_position_into_account (it);
28273 /* If we have to actually produce glyphs, do it. */
28274 if (it->glyph_row)
28276 if (stretched_p)
28278 /* Translate a space with a `space-width' property
28279 into a stretch glyph. */
28280 int ascent = (((it->ascent + it->descent) * FONT_BASE (font))
28281 / FONT_HEIGHT (font));
28282 append_stretch_glyph (it, it->object, it->pixel_width,
28283 it->ascent + it->descent, ascent);
28285 else
28286 append_glyph (it);
28288 /* If characters with lbearing or rbearing are displayed
28289 in this line, record that fact in a flag of the
28290 glyph row. This is used to optimize X output code. */
28291 if (pcm && (pcm->lbearing < 0 || pcm->rbearing > pcm->width))
28292 it->glyph_row->contains_overlapping_glyphs_p = true;
28294 if (! stretched_p && it->pixel_width == 0)
28295 /* We assure that all visible glyphs have at least 1-pixel
28296 width. */
28297 it->pixel_width = 1;
28299 else if (it->char_to_display == '\n')
28301 /* A newline has no width, but we need the height of the
28302 line. But if previous part of the line sets a height,
28303 don't increase that height. */
28305 Lisp_Object height;
28306 Lisp_Object total_height = Qnil;
28308 it->override_ascent = -1;
28309 it->pixel_width = 0;
28310 it->nglyphs = 0;
28312 height = get_it_property (it, Qline_height);
28313 /* Split (line-height total-height) list. */
28314 if (CONSP (height)
28315 && CONSP (XCDR (height))
28316 && NILP (XCDR (XCDR (height))))
28318 total_height = XCAR (XCDR (height));
28319 height = XCAR (height);
28321 height = calc_line_height_property (it, height, font, boff, true);
28323 if (it->override_ascent >= 0)
28325 it->ascent = it->override_ascent;
28326 it->descent = it->override_descent;
28327 boff = it->override_boff;
28329 else
28331 if (FONT_TOO_HIGH (font))
28333 it->ascent = font->pixel_size + boff - 1;
28334 it->descent = -boff + 1;
28335 if (it->descent < 0)
28336 it->descent = 0;
28338 else
28340 it->ascent = FONT_BASE (font) + boff;
28341 it->descent = FONT_DESCENT (font) - boff;
28345 if (EQ (height, Qt))
28347 if (it->descent > it->max_descent)
28349 it->ascent += it->descent - it->max_descent;
28350 it->descent = it->max_descent;
28352 if (it->ascent > it->max_ascent)
28354 it->descent = min (it->max_descent, it->descent + it->ascent - it->max_ascent);
28355 it->ascent = it->max_ascent;
28357 it->phys_ascent = min (it->phys_ascent, it->ascent);
28358 it->phys_descent = min (it->phys_descent, it->descent);
28359 it->constrain_row_ascent_descent_p = true;
28360 extra_line_spacing = 0;
28362 else
28364 Lisp_Object spacing;
28366 it->phys_ascent = it->ascent;
28367 it->phys_descent = it->descent;
28369 if ((it->max_ascent > 0 || it->max_descent > 0)
28370 && face->box != FACE_NO_BOX
28371 && face->box_line_width > 0)
28373 it->ascent += face->box_line_width;
28374 it->descent += face->box_line_width;
28376 if (!NILP (height)
28377 && XINT (height) > it->ascent + it->descent)
28378 it->ascent = XINT (height) - it->descent;
28380 if (!NILP (total_height))
28381 spacing = calc_line_height_property (it, total_height, font,
28382 boff, false);
28383 else
28385 spacing = get_it_property (it, Qline_spacing);
28386 spacing = calc_line_height_property (it, spacing, font,
28387 boff, false);
28389 if (INTEGERP (spacing))
28391 extra_line_spacing = XINT (spacing);
28392 if (!NILP (total_height))
28393 extra_line_spacing -= (it->phys_ascent + it->phys_descent);
28397 else /* i.e. (it->char_to_display == '\t') */
28399 if (font->space_width > 0)
28401 int tab_width = it->tab_width * font->space_width;
28402 int x = it->current_x + it->continuation_lines_width;
28403 int x0 = x;
28404 /* Adjust for line numbers, if needed. */
28405 if (!NILP (Vdisplay_line_numbers) && it->line_number_produced_p)
28407 x -= it->lnum_pixel_width;
28408 /* Restore the original TAB width, if required. */
28409 if (x + it->tab_offset >= it->first_visible_x)
28410 x += it->tab_offset;
28413 int next_tab_x = ((1 + x + tab_width - 1) / tab_width) * tab_width;
28415 /* If the distance from the current position to the next tab
28416 stop is less than a space character width, use the
28417 tab stop after that. */
28418 if (next_tab_x - x < font->space_width)
28419 next_tab_x += tab_width;
28420 if (!NILP (Vdisplay_line_numbers) && it->line_number_produced_p)
28422 next_tab_x += it->lnum_pixel_width;
28423 /* If the line is hscrolled, and the TAB starts before
28424 the first visible pixel, simulate negative row->x. */
28425 if (x < it->first_visible_x)
28427 next_tab_x -= it->first_visible_x - x;
28428 it->tab_offset = it->first_visible_x - x;
28430 else
28431 next_tab_x -= it->tab_offset;
28434 it->pixel_width = next_tab_x - x0;
28435 it->nglyphs = 1;
28436 if (FONT_TOO_HIGH (font))
28438 if (get_char_glyph_code (' ', font, &char2b))
28440 pcm = get_per_char_metric (font, &char2b);
28441 if (pcm->width == 0
28442 && pcm->rbearing == 0 && pcm->lbearing == 0)
28443 pcm = NULL;
28446 if (pcm)
28448 it->ascent = pcm->ascent + boff;
28449 it->descent = pcm->descent - boff;
28451 else
28453 it->ascent = font->pixel_size + boff - 1;
28454 it->descent = -boff + 1;
28456 if (it->ascent < 0)
28457 it->ascent = 0;
28458 if (it->descent < 0)
28459 it->descent = 0;
28461 else
28463 it->ascent = FONT_BASE (font) + boff;
28464 it->descent = FONT_DESCENT (font) - boff;
28466 it->phys_ascent = it->ascent;
28467 it->phys_descent = it->descent;
28469 if (it->glyph_row)
28471 append_stretch_glyph (it, it->object, it->pixel_width,
28472 it->ascent + it->descent, it->ascent);
28475 else
28477 it->pixel_width = 0;
28478 it->nglyphs = 1;
28482 if (FONT_TOO_HIGH (font))
28484 int font_ascent, font_descent;
28486 /* For very large fonts, where we ignore the declared font
28487 dimensions, and go by per-character metrics instead,
28488 don't let the row ascent and descent values (and the row
28489 height computed from them) be smaller than the "normal"
28490 character metrics. This avoids unpleasant effects
28491 whereby lines on display would change their height
28492 depending on which characters are shown. */
28493 normal_char_ascent_descent (font, -1, &font_ascent, &font_descent);
28494 it->max_ascent = max (it->max_ascent, font_ascent);
28495 it->max_descent = max (it->max_descent, font_descent);
28498 else if (it->what == IT_COMPOSITION && it->cmp_it.ch < 0)
28500 /* A static composition.
28502 Note: A composition is represented as one glyph in the
28503 glyph matrix. There are no padding glyphs.
28505 Important note: pixel_width, ascent, and descent are the
28506 values of what is drawn by draw_glyphs (i.e. the values of
28507 the overall glyphs composed). */
28508 struct face *face = FACE_FROM_ID (it->f, it->face_id);
28509 int boff; /* baseline offset */
28510 struct composition *cmp = composition_table[it->cmp_it.id];
28511 int glyph_len = cmp->glyph_len;
28512 struct font *font = face->font;
28514 it->nglyphs = 1;
28516 /* If we have not yet calculated pixel size data of glyphs of
28517 the composition for the current face font, calculate them
28518 now. Theoretically, we have to check all fonts for the
28519 glyphs, but that requires much time and memory space. So,
28520 here we check only the font of the first glyph. This may
28521 lead to incorrect display, but it's very rare, and C-l
28522 (recenter-top-bottom) can correct the display anyway. */
28523 if (! cmp->font || cmp->font != font)
28525 /* Ascent and descent of the font of the first character
28526 of this composition (adjusted by baseline offset).
28527 Ascent and descent of overall glyphs should not be less
28528 than these, respectively. */
28529 int font_ascent, font_descent, font_height;
28530 /* Bounding box of the overall glyphs. */
28531 int leftmost, rightmost, lowest, highest;
28532 int lbearing, rbearing;
28533 int i, width, ascent, descent;
28534 int c;
28535 XChar2b char2b;
28536 struct font_metrics *pcm;
28537 ptrdiff_t pos;
28539 eassume (0 < glyph_len); /* See Bug#8512. */
28541 c = COMPOSITION_GLYPH (cmp, glyph_len - 1);
28542 while (c == '\t' && 0 < --glyph_len);
28544 bool right_padded = glyph_len < cmp->glyph_len;
28545 for (i = 0; i < glyph_len; i++)
28547 c = COMPOSITION_GLYPH (cmp, i);
28548 if (c != '\t')
28549 break;
28550 cmp->offsets[i * 2] = cmp->offsets[i * 2 + 1] = 0;
28552 bool left_padded = i > 0;
28554 pos = (STRINGP (it->string) ? IT_STRING_CHARPOS (*it)
28555 : IT_CHARPOS (*it));
28556 /* If no suitable font is found, use the default font. */
28557 bool font_not_found_p = font == NULL;
28558 if (font_not_found_p)
28560 face = face->ascii_face;
28561 font = face->font;
28563 boff = font->baseline_offset;
28564 if (font->vertical_centering)
28565 boff = VCENTER_BASELINE_OFFSET (font, it->f) - boff;
28566 normal_char_ascent_descent (font, -1, &font_ascent, &font_descent);
28567 font_ascent += boff;
28568 font_descent -= boff;
28569 font_height = font_ascent + font_descent;
28571 cmp->font = font;
28573 pcm = NULL;
28574 if (! font_not_found_p)
28576 get_char_face_and_encoding (it->f, c, it->face_id,
28577 &char2b, false);
28578 pcm = get_per_char_metric (font, &char2b);
28581 /* Initialize the bounding box. */
28582 if (pcm)
28584 width = cmp->glyph_len > 0 ? pcm->width : 0;
28585 ascent = pcm->ascent;
28586 descent = pcm->descent;
28587 lbearing = pcm->lbearing;
28588 rbearing = pcm->rbearing;
28590 else
28592 width = cmp->glyph_len > 0 ? font->space_width : 0;
28593 ascent = FONT_BASE (font);
28594 descent = FONT_DESCENT (font);
28595 lbearing = 0;
28596 rbearing = width;
28599 rightmost = width;
28600 leftmost = 0;
28601 lowest = - descent + boff;
28602 highest = ascent + boff;
28604 if (! font_not_found_p
28605 && font->default_ascent
28606 && CHAR_TABLE_P (Vuse_default_ascent)
28607 && !NILP (Faref (Vuse_default_ascent,
28608 make_number (it->char_to_display))))
28609 highest = font->default_ascent + boff;
28611 /* Draw the first glyph at the normal position. It may be
28612 shifted to right later if some other glyphs are drawn
28613 at the left. */
28614 cmp->offsets[i * 2] = 0;
28615 cmp->offsets[i * 2 + 1] = boff;
28616 cmp->lbearing = lbearing;
28617 cmp->rbearing = rbearing;
28619 /* Set cmp->offsets for the remaining glyphs. */
28620 for (i++; i < glyph_len; i++)
28622 int left, right, btm, top;
28623 int ch = COMPOSITION_GLYPH (cmp, i);
28624 int face_id;
28625 struct face *this_face;
28627 if (ch == '\t')
28628 ch = ' ';
28629 face_id = FACE_FOR_CHAR (it->f, face, ch, pos, it->string);
28630 this_face = FACE_FROM_ID (it->f, face_id);
28631 font = this_face->font;
28633 if (font == NULL)
28634 pcm = NULL;
28635 else
28637 get_char_face_and_encoding (it->f, ch, face_id,
28638 &char2b, false);
28639 pcm = get_per_char_metric (font, &char2b);
28641 if (! pcm)
28642 cmp->offsets[i * 2] = cmp->offsets[i * 2 + 1] = 0;
28643 else
28645 width = pcm->width;
28646 ascent = pcm->ascent;
28647 descent = pcm->descent;
28648 lbearing = pcm->lbearing;
28649 rbearing = pcm->rbearing;
28650 if (cmp->method != COMPOSITION_WITH_RULE_ALTCHARS)
28652 /* Relative composition with or without
28653 alternate chars. */
28654 left = (leftmost + rightmost - width) / 2;
28655 btm = - descent + boff;
28656 if (font->relative_compose
28657 && (! CHAR_TABLE_P (Vignore_relative_composition)
28658 || NILP (Faref (Vignore_relative_composition,
28659 make_number (ch)))))
28662 if (- descent >= font->relative_compose)
28663 /* One extra pixel between two glyphs. */
28664 btm = highest + 1;
28665 else if (ascent <= 0)
28666 /* One extra pixel between two glyphs. */
28667 btm = lowest - 1 - ascent - descent;
28670 else
28672 /* A composition rule is specified by an integer
28673 value that encodes global and new reference
28674 points (GREF and NREF). GREF and NREF are
28675 specified by numbers as below:
28677 0---1---2 -- ascent
28681 9--10--11 -- center
28683 ---3---4---5--- baseline
28685 6---7---8 -- descent
28687 int rule = COMPOSITION_RULE (cmp, i);
28688 int gref, nref, grefx, grefy, nrefx, nrefy, xoff, yoff;
28690 COMPOSITION_DECODE_RULE (rule, gref, nref, xoff, yoff);
28691 grefx = gref % 3, nrefx = nref % 3;
28692 grefy = gref / 3, nrefy = nref / 3;
28693 if (xoff)
28694 xoff = font_height * (xoff - 128) / 256;
28695 if (yoff)
28696 yoff = font_height * (yoff - 128) / 256;
28698 left = (leftmost
28699 + grefx * (rightmost - leftmost) / 2
28700 - nrefx * width / 2
28701 + xoff);
28703 btm = ((grefy == 0 ? highest
28704 : grefy == 1 ? 0
28705 : grefy == 2 ? lowest
28706 : (highest + lowest) / 2)
28707 - (nrefy == 0 ? ascent + descent
28708 : nrefy == 1 ? descent - boff
28709 : nrefy == 2 ? 0
28710 : (ascent + descent) / 2)
28711 + yoff);
28714 cmp->offsets[i * 2] = left;
28715 cmp->offsets[i * 2 + 1] = btm + descent;
28717 /* Update the bounding box of the overall glyphs. */
28718 if (width > 0)
28720 right = left + width;
28721 if (left < leftmost)
28722 leftmost = left;
28723 if (right > rightmost)
28724 rightmost = right;
28726 top = btm + descent + ascent;
28727 if (top > highest)
28728 highest = top;
28729 if (btm < lowest)
28730 lowest = btm;
28732 if (cmp->lbearing > left + lbearing)
28733 cmp->lbearing = left + lbearing;
28734 if (cmp->rbearing < left + rbearing)
28735 cmp->rbearing = left + rbearing;
28739 /* If there are glyphs whose x-offsets are negative,
28740 shift all glyphs to the right and make all x-offsets
28741 non-negative. */
28742 if (leftmost < 0)
28744 for (i = 0; i < cmp->glyph_len; i++)
28745 cmp->offsets[i * 2] -= leftmost;
28746 rightmost -= leftmost;
28747 cmp->lbearing -= leftmost;
28748 cmp->rbearing -= leftmost;
28751 if (left_padded && cmp->lbearing < 0)
28753 for (i = 0; i < cmp->glyph_len; i++)
28754 cmp->offsets[i * 2] -= cmp->lbearing;
28755 rightmost -= cmp->lbearing;
28756 cmp->rbearing -= cmp->lbearing;
28757 cmp->lbearing = 0;
28759 if (right_padded && rightmost < cmp->rbearing)
28761 rightmost = cmp->rbearing;
28764 cmp->pixel_width = rightmost;
28765 cmp->ascent = highest;
28766 cmp->descent = - lowest;
28767 if (cmp->ascent < font_ascent)
28768 cmp->ascent = font_ascent;
28769 if (cmp->descent < font_descent)
28770 cmp->descent = font_descent;
28773 if (it->glyph_row
28774 && (cmp->lbearing < 0
28775 || cmp->rbearing > cmp->pixel_width))
28776 it->glyph_row->contains_overlapping_glyphs_p = true;
28778 it->pixel_width = cmp->pixel_width;
28779 it->ascent = it->phys_ascent = cmp->ascent;
28780 it->descent = it->phys_descent = cmp->descent;
28781 if (face->box != FACE_NO_BOX)
28783 int thick = face->box_line_width;
28785 if (thick > 0)
28787 it->ascent += thick;
28788 it->descent += thick;
28790 else
28791 thick = - thick;
28793 if (it->start_of_box_run_p)
28794 it->pixel_width += thick;
28795 if (it->end_of_box_run_p)
28796 it->pixel_width += thick;
28799 /* If face has an overline, add the height of the overline
28800 (1 pixel) and a 1 pixel margin to the character height. */
28801 if (face->overline_p)
28802 it->ascent += overline_margin;
28804 take_vertical_position_into_account (it);
28805 if (it->ascent < 0)
28806 it->ascent = 0;
28807 if (it->descent < 0)
28808 it->descent = 0;
28810 if (it->glyph_row && cmp->glyph_len > 0)
28811 append_composite_glyph (it);
28813 else if (it->what == IT_COMPOSITION)
28815 /* A dynamic (automatic) composition. */
28816 struct face *face = FACE_FROM_ID (it->f, it->face_id);
28817 Lisp_Object gstring;
28818 struct font_metrics metrics;
28820 it->nglyphs = 1;
28822 gstring = composition_gstring_from_id (it->cmp_it.id);
28823 it->pixel_width
28824 = composition_gstring_width (gstring, it->cmp_it.from, it->cmp_it.to,
28825 &metrics);
28826 if (it->glyph_row
28827 && (metrics.lbearing < 0 || metrics.rbearing > metrics.width))
28828 it->glyph_row->contains_overlapping_glyphs_p = true;
28829 it->ascent = it->phys_ascent = metrics.ascent;
28830 it->descent = it->phys_descent = metrics.descent;
28831 if (face->box != FACE_NO_BOX)
28833 int thick = face->box_line_width;
28835 if (thick > 0)
28837 it->ascent += thick;
28838 it->descent += thick;
28840 else
28841 thick = - thick;
28843 if (it->start_of_box_run_p)
28844 it->pixel_width += thick;
28845 if (it->end_of_box_run_p)
28846 it->pixel_width += thick;
28848 /* If face has an overline, add the height of the overline
28849 (1 pixel) and a 1 pixel margin to the character height. */
28850 if (face->overline_p)
28851 it->ascent += overline_margin;
28852 take_vertical_position_into_account (it);
28853 if (it->ascent < 0)
28854 it->ascent = 0;
28855 if (it->descent < 0)
28856 it->descent = 0;
28858 if (it->glyph_row)
28859 append_composite_glyph (it);
28861 else if (it->what == IT_GLYPHLESS)
28862 produce_glyphless_glyph (it, false, Qnil);
28863 else if (it->what == IT_IMAGE)
28864 produce_image_glyph (it);
28865 else if (it->what == IT_STRETCH)
28866 produce_stretch_glyph (it);
28867 else if (it->what == IT_XWIDGET)
28868 produce_xwidget_glyph (it);
28870 done:
28871 /* Accumulate dimensions. Note: can't assume that it->descent > 0
28872 because this isn't true for images with `:ascent 100'. */
28873 eassert (it->ascent >= 0 && it->descent >= 0);
28874 if (it->area == TEXT_AREA)
28875 it->current_x += it->pixel_width;
28877 if (extra_line_spacing > 0)
28879 it->descent += extra_line_spacing;
28880 if (extra_line_spacing > it->max_extra_line_spacing)
28881 it->max_extra_line_spacing = extra_line_spacing;
28884 it->max_ascent = max (it->max_ascent, it->ascent);
28885 it->max_descent = max (it->max_descent, it->descent);
28886 it->max_phys_ascent = max (it->max_phys_ascent, it->phys_ascent);
28887 it->max_phys_descent = max (it->max_phys_descent, it->phys_descent);
28890 /* EXPORT for RIF:
28891 Output LEN glyphs starting at START at the nominal cursor position.
28892 Advance the nominal cursor over the text. UPDATED_ROW is the glyph row
28893 being updated, and UPDATED_AREA is the area of that row being updated. */
28895 void
28896 x_write_glyphs (struct window *w, struct glyph_row *updated_row,
28897 struct glyph *start, enum glyph_row_area updated_area, int len)
28899 int x, hpos, chpos = w->phys_cursor.hpos;
28901 eassert (updated_row);
28902 /* When the window is hscrolled, cursor hpos can legitimately be out
28903 of bounds, but we draw the cursor at the corresponding window
28904 margin in that case. */
28905 if (!updated_row->reversed_p && chpos < 0)
28906 chpos = 0;
28907 if (updated_row->reversed_p && chpos >= updated_row->used[TEXT_AREA])
28908 chpos = updated_row->used[TEXT_AREA] - 1;
28910 block_input ();
28912 /* Write glyphs. */
28914 hpos = start - updated_row->glyphs[updated_area];
28915 x = draw_glyphs (w, w->output_cursor.x,
28916 updated_row, updated_area,
28917 hpos, hpos + len,
28918 DRAW_NORMAL_TEXT, 0);
28920 /* Invalidate old phys cursor if the glyph at its hpos is redrawn. */
28921 if (updated_area == TEXT_AREA
28922 && w->phys_cursor_on_p
28923 && w->phys_cursor.vpos == w->output_cursor.vpos
28924 && chpos >= hpos
28925 && chpos < hpos + len)
28926 w->phys_cursor_on_p = false;
28928 unblock_input ();
28930 /* Advance the output cursor. */
28931 w->output_cursor.hpos += len;
28932 w->output_cursor.x = x;
28936 /* EXPORT for RIF:
28937 Insert LEN glyphs from START at the nominal cursor position. */
28939 void
28940 x_insert_glyphs (struct window *w, struct glyph_row *updated_row,
28941 struct glyph *start, enum glyph_row_area updated_area, int len)
28943 struct frame *f;
28944 int line_height, shift_by_width, shifted_region_width;
28945 struct glyph_row *row;
28946 struct glyph *glyph;
28947 int frame_x, frame_y;
28948 ptrdiff_t hpos;
28950 eassert (updated_row);
28951 block_input ();
28952 f = XFRAME (WINDOW_FRAME (w));
28954 /* Get the height of the line we are in. */
28955 row = updated_row;
28956 line_height = row->height;
28958 /* Get the width of the glyphs to insert. */
28959 shift_by_width = 0;
28960 for (glyph = start; glyph < start + len; ++glyph)
28961 shift_by_width += glyph->pixel_width;
28963 /* Get the width of the region to shift right. */
28964 shifted_region_width = (window_box_width (w, updated_area)
28965 - w->output_cursor.x
28966 - shift_by_width);
28968 /* Shift right. */
28969 frame_x = window_box_left (w, updated_area) + w->output_cursor.x;
28970 frame_y = WINDOW_TO_FRAME_PIXEL_Y (w, w->output_cursor.y);
28972 FRAME_RIF (f)->shift_glyphs_for_insert (f, frame_x, frame_y, shifted_region_width,
28973 line_height, shift_by_width);
28975 /* Write the glyphs. */
28976 hpos = start - row->glyphs[updated_area];
28977 draw_glyphs (w, w->output_cursor.x, row, updated_area,
28978 hpos, hpos + len,
28979 DRAW_NORMAL_TEXT, 0);
28981 /* Advance the output cursor. */
28982 w->output_cursor.hpos += len;
28983 w->output_cursor.x += shift_by_width;
28984 unblock_input ();
28988 /* EXPORT for RIF:
28989 Erase the current text line from the nominal cursor position
28990 (inclusive) to pixel column TO_X (exclusive). The idea is that
28991 everything from TO_X onward is already erased.
28993 TO_X is a pixel position relative to UPDATED_AREA of currently
28994 updated window W. TO_X == -1 means clear to the end of this area. */
28996 void
28997 x_clear_end_of_line (struct window *w, struct glyph_row *updated_row,
28998 enum glyph_row_area updated_area, int to_x)
29000 struct frame *f;
29001 int max_x, min_y, max_y;
29002 int from_x, from_y, to_y;
29004 eassert (updated_row);
29005 f = XFRAME (w->frame);
29007 if (updated_row->full_width_p)
29008 max_x = (WINDOW_PIXEL_WIDTH (w)
29009 - (updated_row->mode_line_p ? WINDOW_RIGHT_DIVIDER_WIDTH (w) : 0));
29010 else
29011 max_x = window_box_width (w, updated_area);
29012 max_y = window_text_bottom_y (w);
29014 /* TO_X == 0 means don't do anything. TO_X < 0 means clear to end
29015 of window. For TO_X > 0, truncate to end of drawing area. */
29016 if (to_x == 0)
29017 return;
29018 else if (to_x < 0)
29019 to_x = max_x;
29020 else
29021 to_x = min (to_x, max_x);
29023 to_y = min (max_y, w->output_cursor.y + updated_row->height);
29025 /* Notice if the cursor will be cleared by this operation. */
29026 if (!updated_row->full_width_p)
29027 notice_overwritten_cursor (w, updated_area,
29028 w->output_cursor.x, -1,
29029 updated_row->y,
29030 MATRIX_ROW_BOTTOM_Y (updated_row));
29032 from_x = w->output_cursor.x;
29034 /* Translate to frame coordinates. */
29035 if (updated_row->full_width_p)
29037 from_x = WINDOW_TO_FRAME_PIXEL_X (w, from_x);
29038 to_x = WINDOW_TO_FRAME_PIXEL_X (w, to_x);
29040 else
29042 int area_left = window_box_left (w, updated_area);
29043 from_x += area_left;
29044 to_x += area_left;
29047 min_y = WINDOW_HEADER_LINE_HEIGHT (w);
29048 from_y = WINDOW_TO_FRAME_PIXEL_Y (w, max (min_y, w->output_cursor.y));
29049 to_y = WINDOW_TO_FRAME_PIXEL_Y (w, to_y);
29051 /* Prevent inadvertently clearing to end of the X window. */
29052 if (to_x > from_x && to_y > from_y)
29054 block_input ();
29055 FRAME_RIF (f)->clear_frame_area (f, from_x, from_y,
29056 to_x - from_x, to_y - from_y);
29057 unblock_input ();
29061 #endif /* HAVE_WINDOW_SYSTEM */
29065 /***********************************************************************
29066 Cursor types
29067 ***********************************************************************/
29069 /* Value is the internal representation of the specified cursor type
29070 ARG. If type is BAR_CURSOR, return in *WIDTH the specified width
29071 of the bar cursor. */
29073 static enum text_cursor_kinds
29074 get_specified_cursor_type (Lisp_Object arg, int *width)
29076 enum text_cursor_kinds type;
29078 if (NILP (arg))
29079 return NO_CURSOR;
29081 if (EQ (arg, Qbox))
29082 return FILLED_BOX_CURSOR;
29084 if (EQ (arg, Qhollow))
29085 return HOLLOW_BOX_CURSOR;
29087 if (EQ (arg, Qbar))
29089 *width = 2;
29090 return BAR_CURSOR;
29093 if (CONSP (arg)
29094 && EQ (XCAR (arg), Qbar)
29095 && RANGED_INTEGERP (0, XCDR (arg), INT_MAX))
29097 *width = XINT (XCDR (arg));
29098 return BAR_CURSOR;
29101 if (EQ (arg, Qhbar))
29103 *width = 2;
29104 return HBAR_CURSOR;
29107 if (CONSP (arg)
29108 && EQ (XCAR (arg), Qhbar)
29109 && RANGED_INTEGERP (0, XCDR (arg), INT_MAX))
29111 *width = XINT (XCDR (arg));
29112 return HBAR_CURSOR;
29115 /* Treat anything unknown as "hollow box cursor".
29116 It was bad to signal an error; people have trouble fixing
29117 .Xdefaults with Emacs, when it has something bad in it. */
29118 type = HOLLOW_BOX_CURSOR;
29120 return type;
29123 /* Set the default cursor types for specified frame. */
29124 void
29125 set_frame_cursor_types (struct frame *f, Lisp_Object arg)
29127 int width = 1;
29128 Lisp_Object tem;
29130 FRAME_DESIRED_CURSOR (f) = get_specified_cursor_type (arg, &width);
29131 FRAME_CURSOR_WIDTH (f) = width;
29133 /* By default, set up the blink-off state depending on the on-state. */
29135 tem = Fassoc (arg, Vblink_cursor_alist, Qnil);
29136 if (!NILP (tem))
29138 FRAME_BLINK_OFF_CURSOR (f)
29139 = get_specified_cursor_type (XCDR (tem), &width);
29140 FRAME_BLINK_OFF_CURSOR_WIDTH (f) = width;
29142 else
29143 FRAME_BLINK_OFF_CURSOR (f) = DEFAULT_CURSOR;
29145 /* Make sure the cursor gets redrawn. */
29146 f->cursor_type_changed = true;
29150 #ifdef HAVE_WINDOW_SYSTEM
29152 /* Return the cursor we want to be displayed in window W. Return
29153 width of bar/hbar cursor through WIDTH arg. Return with
29154 ACTIVE_CURSOR arg set to true if cursor in window W is `active'
29155 (i.e. if the `system caret' should track this cursor).
29157 In a mini-buffer window, we want the cursor only to appear if we
29158 are reading input from this window. For the selected window, we
29159 want the cursor type given by the frame parameter or buffer local
29160 setting of cursor-type. If explicitly marked off, draw no cursor.
29161 In all other cases, we want a hollow box cursor. */
29163 static enum text_cursor_kinds
29164 get_window_cursor_type (struct window *w, struct glyph *glyph, int *width,
29165 bool *active_cursor)
29167 struct frame *f = XFRAME (w->frame);
29168 struct buffer *b = XBUFFER (w->contents);
29169 int cursor_type = DEFAULT_CURSOR;
29170 Lisp_Object alt_cursor;
29171 bool non_selected = false;
29173 *active_cursor = true;
29175 /* Echo area */
29176 if (cursor_in_echo_area
29177 && FRAME_HAS_MINIBUF_P (f)
29178 && EQ (FRAME_MINIBUF_WINDOW (f), echo_area_window))
29180 if (w == XWINDOW (echo_area_window))
29182 if (EQ (BVAR (b, cursor_type), Qt) || NILP (BVAR (b, cursor_type)))
29184 *width = FRAME_CURSOR_WIDTH (f);
29185 return FRAME_DESIRED_CURSOR (f);
29187 else
29188 return get_specified_cursor_type (BVAR (b, cursor_type), width);
29191 *active_cursor = false;
29192 non_selected = true;
29195 /* Detect a nonselected window or nonselected frame. */
29196 else if (w != XWINDOW (f->selected_window)
29197 || f != FRAME_DISPLAY_INFO (f)->x_highlight_frame)
29199 *active_cursor = false;
29201 if (MINI_WINDOW_P (w) && minibuf_level == 0)
29202 return NO_CURSOR;
29204 non_selected = true;
29207 /* Never display a cursor in a window in which cursor-type is nil. */
29208 if (NILP (BVAR (b, cursor_type)))
29209 return NO_CURSOR;
29211 /* Get the normal cursor type for this window. */
29212 if (EQ (BVAR (b, cursor_type), Qt))
29214 cursor_type = FRAME_DESIRED_CURSOR (f);
29215 *width = FRAME_CURSOR_WIDTH (f);
29217 else
29218 cursor_type = get_specified_cursor_type (BVAR (b, cursor_type), width);
29220 /* Use cursor-in-non-selected-windows instead
29221 for non-selected window or frame. */
29222 if (non_selected)
29224 alt_cursor = BVAR (b, cursor_in_non_selected_windows);
29225 if (!EQ (Qt, alt_cursor))
29226 return get_specified_cursor_type (alt_cursor, width);
29227 /* t means modify the normal cursor type. */
29228 if (cursor_type == FILLED_BOX_CURSOR)
29229 cursor_type = HOLLOW_BOX_CURSOR;
29230 else if (cursor_type == BAR_CURSOR && *width > 1)
29231 --*width;
29232 return cursor_type;
29235 /* Use normal cursor if not blinked off. */
29236 if (!w->cursor_off_p)
29238 if (glyph != NULL && glyph->type == XWIDGET_GLYPH)
29239 return NO_CURSOR;
29240 if (glyph != NULL && glyph->type == IMAGE_GLYPH)
29242 if (cursor_type == FILLED_BOX_CURSOR)
29244 /* Using a block cursor on large images can be very annoying.
29245 So use a hollow cursor for "large" images.
29246 If image is not transparent (no mask), also use hollow cursor. */
29247 struct image *img = IMAGE_OPT_FROM_ID (f, glyph->u.img_id);
29248 if (img != NULL && IMAGEP (img->spec))
29250 /* Arbitrarily, interpret "Large" as >32x32 and >NxN
29251 where N = size of default frame font size.
29252 This should cover most of the "tiny" icons people may use. */
29253 if (!img->mask
29254 || img->width > max (32, WINDOW_FRAME_COLUMN_WIDTH (w))
29255 || img->height > max (32, WINDOW_FRAME_LINE_HEIGHT (w)))
29256 cursor_type = HOLLOW_BOX_CURSOR;
29259 else if (cursor_type != NO_CURSOR)
29261 /* Display current only supports BOX and HOLLOW cursors for images.
29262 So for now, unconditionally use a HOLLOW cursor when cursor is
29263 not a solid box cursor. */
29264 cursor_type = HOLLOW_BOX_CURSOR;
29267 return cursor_type;
29270 /* Cursor is blinked off, so determine how to "toggle" it. */
29272 /* First look for an entry matching the buffer's cursor-type in blink-cursor-alist. */
29273 if ((alt_cursor = Fassoc (BVAR (b, cursor_type), Vblink_cursor_alist, Qnil), !NILP (alt_cursor)))
29274 return get_specified_cursor_type (XCDR (alt_cursor), width);
29276 /* Then see if frame has specified a specific blink off cursor type. */
29277 if (FRAME_BLINK_OFF_CURSOR (f) != DEFAULT_CURSOR)
29279 *width = FRAME_BLINK_OFF_CURSOR_WIDTH (f);
29280 return FRAME_BLINK_OFF_CURSOR (f);
29283 #if false
29284 /* Some people liked having a permanently visible blinking cursor,
29285 while others had very strong opinions against it. So it was
29286 decided to remove it. KFS 2003-09-03 */
29288 /* Finally perform built-in cursor blinking:
29289 filled box <-> hollow box
29290 wide [h]bar <-> narrow [h]bar
29291 narrow [h]bar <-> no cursor
29292 other type <-> no cursor */
29294 if (cursor_type == FILLED_BOX_CURSOR)
29295 return HOLLOW_BOX_CURSOR;
29297 if ((cursor_type == BAR_CURSOR || cursor_type == HBAR_CURSOR) && *width > 1)
29299 *width = 1;
29300 return cursor_type;
29302 #endif
29304 return NO_CURSOR;
29308 /* Notice when the text cursor of window W has been completely
29309 overwritten by a drawing operation that outputs glyphs in AREA
29310 starting at X0 and ending at X1 in the line starting at Y0 and
29311 ending at Y1. X coordinates are area-relative. X1 < 0 means all
29312 the rest of the line after X0 has been written. Y coordinates
29313 are window-relative. */
29315 static void
29316 notice_overwritten_cursor (struct window *w, enum glyph_row_area area,
29317 int x0, int x1, int y0, int y1)
29319 int cx0, cx1, cy0, cy1;
29320 struct glyph_row *row;
29322 if (!w->phys_cursor_on_p)
29323 return;
29324 if (area != TEXT_AREA)
29325 return;
29327 if (w->phys_cursor.vpos < 0
29328 || w->phys_cursor.vpos >= w->current_matrix->nrows
29329 || (row = w->current_matrix->rows + w->phys_cursor.vpos,
29330 !(row->enabled_p && MATRIX_ROW_DISPLAYS_TEXT_P (row))))
29331 return;
29333 if (row->cursor_in_fringe_p)
29335 row->cursor_in_fringe_p = false;
29336 draw_fringe_bitmap (w, row, row->reversed_p);
29337 w->phys_cursor_on_p = false;
29338 return;
29341 cx0 = w->phys_cursor.x;
29342 cx1 = cx0 + w->phys_cursor_width;
29343 if (x0 > cx0 || (x1 >= 0 && x1 < cx1))
29344 return;
29346 /* The cursor image will be completely removed from the
29347 screen if the output area intersects the cursor area in
29348 y-direction. When we draw in [y0 y1[, and some part of
29349 the cursor is at y < y0, that part must have been drawn
29350 before. When scrolling, the cursor is erased before
29351 actually scrolling, so we don't come here. When not
29352 scrolling, the rows above the old cursor row must have
29353 changed, and in this case these rows must have written
29354 over the cursor image.
29356 Likewise if part of the cursor is below y1, with the
29357 exception of the cursor being in the first blank row at
29358 the buffer and window end because update_text_area
29359 doesn't draw that row. (Except when it does, but
29360 that's handled in update_text_area.) */
29362 cy0 = w->phys_cursor.y;
29363 cy1 = cy0 + w->phys_cursor_height;
29364 if ((y0 < cy0 || y0 >= cy1) && (y1 <= cy0 || y1 >= cy1))
29365 return;
29367 w->phys_cursor_on_p = false;
29370 #endif /* HAVE_WINDOW_SYSTEM */
29373 /************************************************************************
29374 Mouse Face
29375 ************************************************************************/
29377 #ifdef HAVE_WINDOW_SYSTEM
29379 /* EXPORT for RIF:
29380 Fix the display of area AREA of overlapping row ROW in window W
29381 with respect to the overlapping part OVERLAPS. */
29383 void
29384 x_fix_overlapping_area (struct window *w, struct glyph_row *row,
29385 enum glyph_row_area area, int overlaps)
29387 int i, x;
29389 block_input ();
29391 x = 0;
29392 for (i = 0; i < row->used[area];)
29394 if (row->glyphs[area][i].overlaps_vertically_p)
29396 int start = i, start_x = x;
29400 x += row->glyphs[area][i].pixel_width;
29401 ++i;
29403 while (i < row->used[area]
29404 && row->glyphs[area][i].overlaps_vertically_p);
29406 draw_glyphs (w, start_x, row, area,
29407 start, i,
29408 DRAW_NORMAL_TEXT, overlaps);
29410 else
29412 x += row->glyphs[area][i].pixel_width;
29413 ++i;
29417 unblock_input ();
29421 /* EXPORT:
29422 Draw the cursor glyph of window W in glyph row ROW. See the
29423 comment of draw_glyphs for the meaning of HL. */
29425 void
29426 draw_phys_cursor_glyph (struct window *w, struct glyph_row *row,
29427 enum draw_glyphs_face hl)
29429 /* If cursor hpos is out of bounds, don't draw garbage. This can
29430 happen in mini-buffer windows when switching between echo area
29431 glyphs and mini-buffer. */
29432 if ((row->reversed_p
29433 ? (w->phys_cursor.hpos >= 0)
29434 : (w->phys_cursor.hpos < row->used[TEXT_AREA])))
29436 bool on_p = w->phys_cursor_on_p;
29437 int x1;
29438 int hpos = w->phys_cursor.hpos;
29440 /* When the window is hscrolled, cursor hpos can legitimately be
29441 out of bounds, but we draw the cursor at the corresponding
29442 window margin in that case. */
29443 if (!row->reversed_p && hpos < 0)
29444 hpos = 0;
29445 if (row->reversed_p && hpos >= row->used[TEXT_AREA])
29446 hpos = row->used[TEXT_AREA] - 1;
29448 x1 = draw_glyphs (w, w->phys_cursor.x, row, TEXT_AREA, hpos, hpos + 1,
29449 hl, 0);
29450 w->phys_cursor_on_p = on_p;
29452 if (hl == DRAW_CURSOR)
29453 w->phys_cursor_width = x1 - w->phys_cursor.x;
29454 /* When we erase the cursor, and ROW is overlapped by other
29455 rows, make sure that these overlapping parts of other rows
29456 are redrawn. */
29457 else if (hl == DRAW_NORMAL_TEXT && row->overlapped_p)
29459 w->phys_cursor_width = x1 - w->phys_cursor.x;
29461 if (row > w->current_matrix->rows
29462 && MATRIX_ROW_OVERLAPS_SUCC_P (row - 1))
29463 x_fix_overlapping_area (w, row - 1, TEXT_AREA,
29464 OVERLAPS_ERASED_CURSOR);
29466 if (MATRIX_ROW_BOTTOM_Y (row) < window_text_bottom_y (w)
29467 && MATRIX_ROW_OVERLAPS_PRED_P (row + 1))
29468 x_fix_overlapping_area (w, row + 1, TEXT_AREA,
29469 OVERLAPS_ERASED_CURSOR);
29475 /* Erase the image of a cursor of window W from the screen. */
29477 void
29478 erase_phys_cursor (struct window *w)
29480 struct frame *f = XFRAME (w->frame);
29481 Mouse_HLInfo *hlinfo = MOUSE_HL_INFO (f);
29482 int hpos = w->phys_cursor.hpos;
29483 int vpos = w->phys_cursor.vpos;
29484 bool mouse_face_here_p = false;
29485 struct glyph_matrix *active_glyphs = w->current_matrix;
29486 struct glyph_row *cursor_row;
29487 struct glyph *cursor_glyph;
29488 enum draw_glyphs_face hl;
29490 /* No cursor displayed or row invalidated => nothing to do on the
29491 screen. */
29492 if (w->phys_cursor_type == NO_CURSOR)
29493 goto mark_cursor_off;
29495 /* VPOS >= active_glyphs->nrows means that window has been resized.
29496 Don't bother to erase the cursor. */
29497 if (vpos >= active_glyphs->nrows)
29498 goto mark_cursor_off;
29500 /* If row containing cursor is marked invalid, there is nothing we
29501 can do. */
29502 cursor_row = MATRIX_ROW (active_glyphs, vpos);
29503 if (!cursor_row->enabled_p)
29504 goto mark_cursor_off;
29506 /* If line spacing is > 0, old cursor may only be partially visible in
29507 window after split-window. So adjust visible height. */
29508 cursor_row->visible_height = min (cursor_row->visible_height,
29509 window_text_bottom_y (w) - cursor_row->y);
29511 /* If row is completely invisible, don't attempt to delete a cursor which
29512 isn't there. This can happen if cursor is at top of a window, and
29513 we switch to a buffer with a header line in that window. */
29514 if (cursor_row->visible_height <= 0)
29515 goto mark_cursor_off;
29517 /* If cursor is in the fringe, erase by drawing actual bitmap there. */
29518 if (cursor_row->cursor_in_fringe_p)
29520 cursor_row->cursor_in_fringe_p = false;
29521 draw_fringe_bitmap (w, cursor_row, cursor_row->reversed_p);
29522 goto mark_cursor_off;
29525 /* This can happen when the new row is shorter than the old one.
29526 In this case, either draw_glyphs or clear_end_of_line
29527 should have cleared the cursor. Note that we wouldn't be
29528 able to erase the cursor in this case because we don't have a
29529 cursor glyph at hand. */
29530 if ((cursor_row->reversed_p
29531 ? (w->phys_cursor.hpos < 0)
29532 : (w->phys_cursor.hpos >= cursor_row->used[TEXT_AREA])))
29533 goto mark_cursor_off;
29535 /* When the window is hscrolled, cursor hpos can legitimately be out
29536 of bounds, but we draw the cursor at the corresponding window
29537 margin in that case. */
29538 if (!cursor_row->reversed_p && hpos < 0)
29539 hpos = 0;
29540 if (cursor_row->reversed_p && hpos >= cursor_row->used[TEXT_AREA])
29541 hpos = cursor_row->used[TEXT_AREA] - 1;
29543 /* If the cursor is in the mouse face area, redisplay that when
29544 we clear the cursor. */
29545 if (! NILP (hlinfo->mouse_face_window)
29546 && coords_in_mouse_face_p (w, hpos, vpos)
29547 /* Don't redraw the cursor's spot in mouse face if it is at the
29548 end of a line (on a newline). The cursor appears there, but
29549 mouse highlighting does not. */
29550 && cursor_row->used[TEXT_AREA] > hpos && hpos >= 0)
29551 mouse_face_here_p = true;
29553 /* Maybe clear the display under the cursor. */
29554 if (w->phys_cursor_type == HOLLOW_BOX_CURSOR)
29556 int x, y;
29557 int header_line_height = WINDOW_HEADER_LINE_HEIGHT (w);
29558 int width;
29560 cursor_glyph = get_phys_cursor_glyph (w);
29561 if (cursor_glyph == NULL)
29562 goto mark_cursor_off;
29564 width = cursor_glyph->pixel_width;
29565 x = w->phys_cursor.x;
29566 if (x < 0)
29568 width += x;
29569 x = 0;
29571 width = min (width, window_box_width (w, TEXT_AREA) - x);
29572 y = WINDOW_TO_FRAME_PIXEL_Y (w, max (header_line_height, cursor_row->y));
29573 x = WINDOW_TEXT_TO_FRAME_PIXEL_X (w, x);
29575 if (width > 0)
29576 FRAME_RIF (f)->clear_frame_area (f, x, y, width, cursor_row->visible_height);
29579 /* Erase the cursor by redrawing the character underneath it. */
29580 if (mouse_face_here_p)
29581 hl = DRAW_MOUSE_FACE;
29582 else
29583 hl = DRAW_NORMAL_TEXT;
29584 draw_phys_cursor_glyph (w, cursor_row, hl);
29586 mark_cursor_off:
29587 w->phys_cursor_on_p = false;
29588 w->phys_cursor_type = NO_CURSOR;
29592 /* Display or clear cursor of window W. If !ON, clear the cursor.
29593 If ON, display the cursor; where to put the cursor is specified by
29594 HPOS, VPOS, X and Y. */
29596 void
29597 display_and_set_cursor (struct window *w, bool on,
29598 int hpos, int vpos, int x, int y)
29600 struct frame *f = XFRAME (w->frame);
29601 int new_cursor_type;
29602 int new_cursor_width;
29603 bool active_cursor;
29604 struct glyph_row *glyph_row;
29605 struct glyph *glyph;
29607 /* This is pointless on invisible frames, and dangerous on garbaged
29608 windows and frames; in the latter case, the frame or window may
29609 be in the midst of changing its size, and x and y may be off the
29610 window. */
29611 if (! FRAME_VISIBLE_P (f)
29612 || vpos >= w->current_matrix->nrows
29613 || hpos >= w->current_matrix->matrix_w)
29614 return;
29616 /* If cursor is off and we want it off, return quickly. */
29617 if (!on && !w->phys_cursor_on_p)
29618 return;
29620 glyph_row = MATRIX_ROW (w->current_matrix, vpos);
29621 /* If cursor row is not enabled, we don't really know where to
29622 display the cursor. */
29623 if (!glyph_row->enabled_p)
29625 w->phys_cursor_on_p = false;
29626 return;
29629 /* A frame might be marked garbaged even though its cursor position
29630 is correct, and will not change upon subsequent redisplay. This
29631 happens in some rare situations, like toggling the sort order in
29632 Dired windows. We've already established that VPOS is valid, so
29633 it shouldn't do any harm to record the cursor position, as we are
29634 going to return without acting on it anyway. Otherwise, expose
29635 events might come in and call update_window_cursor, which will
29636 blindly use outdated values in w->phys_cursor. */
29637 if (FRAME_GARBAGED_P (f))
29639 if (on)
29641 w->phys_cursor.x = x;
29642 w->phys_cursor.y = glyph_row->y;
29643 w->phys_cursor.hpos = hpos;
29644 w->phys_cursor.vpos = vpos;
29646 return;
29649 glyph = NULL;
29650 if (0 <= hpos && hpos < glyph_row->used[TEXT_AREA])
29651 glyph = glyph_row->glyphs[TEXT_AREA] + hpos;
29653 eassert (input_blocked_p ());
29655 /* Set new_cursor_type to the cursor we want to be displayed. */
29656 new_cursor_type = get_window_cursor_type (w, glyph,
29657 &new_cursor_width, &active_cursor);
29659 /* If cursor is currently being shown and we don't want it to be or
29660 it is in the wrong place, or the cursor type is not what we want,
29661 erase it. */
29662 if (w->phys_cursor_on_p
29663 && (!on
29664 || w->phys_cursor.x != x
29665 || w->phys_cursor.y != y
29666 /* HPOS can be negative in R2L rows whose
29667 exact_window_width_line_p flag is set (i.e. their newline
29668 would "overflow into the fringe"). */
29669 || hpos < 0
29670 || new_cursor_type != w->phys_cursor_type
29671 || ((new_cursor_type == BAR_CURSOR || new_cursor_type == HBAR_CURSOR)
29672 && new_cursor_width != w->phys_cursor_width)))
29673 erase_phys_cursor (w);
29675 /* Don't check phys_cursor_on_p here because that flag is only set
29676 to false in some cases where we know that the cursor has been
29677 completely erased, to avoid the extra work of erasing the cursor
29678 twice. In other words, phys_cursor_on_p can be true and the cursor
29679 still not be visible, or it has only been partly erased. */
29680 if (on)
29682 w->phys_cursor_ascent = glyph_row->ascent;
29683 w->phys_cursor_height = glyph_row->height;
29685 /* Set phys_cursor_.* before x_draw_.* is called because some
29686 of them may need the information. */
29687 w->phys_cursor.x = x;
29688 w->phys_cursor.y = glyph_row->y;
29689 w->phys_cursor.hpos = hpos;
29690 w->phys_cursor.vpos = vpos;
29693 FRAME_RIF (f)->draw_window_cursor (w, glyph_row, x, y,
29694 new_cursor_type, new_cursor_width,
29695 on, active_cursor);
29699 /* Switch the display of W's cursor on or off, according to the value
29700 of ON. */
29702 static void
29703 update_window_cursor (struct window *w, bool on)
29705 /* Don't update cursor in windows whose frame is in the process
29706 of being deleted. */
29707 if (w->current_matrix)
29709 int hpos = w->phys_cursor.hpos;
29710 int vpos = w->phys_cursor.vpos;
29711 struct glyph_row *row;
29713 if (vpos >= w->current_matrix->nrows
29714 || hpos >= w->current_matrix->matrix_w)
29715 return;
29717 row = MATRIX_ROW (w->current_matrix, vpos);
29719 /* When the window is hscrolled, cursor hpos can legitimately be
29720 out of bounds, but we draw the cursor at the corresponding
29721 window margin in that case. */
29722 if (!row->reversed_p && hpos < 0)
29723 hpos = 0;
29724 if (row->reversed_p && hpos >= row->used[TEXT_AREA])
29725 hpos = row->used[TEXT_AREA] - 1;
29727 block_input ();
29728 display_and_set_cursor (w, on, hpos, vpos,
29729 w->phys_cursor.x, w->phys_cursor.y);
29730 unblock_input ();
29735 /* Call update_window_cursor with parameter ON_P on all leaf windows
29736 in the window tree rooted at W. */
29738 static void
29739 update_cursor_in_window_tree (struct window *w, bool on_p)
29741 while (w)
29743 if (WINDOWP (w->contents))
29744 update_cursor_in_window_tree (XWINDOW (w->contents), on_p);
29745 else
29746 update_window_cursor (w, on_p);
29748 w = NILP (w->next) ? 0 : XWINDOW (w->next);
29753 /* EXPORT:
29754 Display the cursor on window W, or clear it, according to ON_P.
29755 Don't change the cursor's position. */
29757 void
29758 x_update_cursor (struct frame *f, bool on_p)
29760 update_cursor_in_window_tree (XWINDOW (f->root_window), on_p);
29764 /* EXPORT:
29765 Clear the cursor of window W to background color, and mark the
29766 cursor as not shown. This is used when the text where the cursor
29767 is about to be rewritten. */
29769 void
29770 x_clear_cursor (struct window *w)
29772 if (FRAME_VISIBLE_P (XFRAME (w->frame)) && w->phys_cursor_on_p)
29773 update_window_cursor (w, false);
29776 #endif /* HAVE_WINDOW_SYSTEM */
29778 /* Implementation of draw_row_with_mouse_face for GUI sessions, GPM,
29779 and MSDOS. */
29780 static void
29781 draw_row_with_mouse_face (struct window *w, int start_x, struct glyph_row *row,
29782 int start_hpos, int end_hpos,
29783 enum draw_glyphs_face draw)
29785 #ifdef HAVE_WINDOW_SYSTEM
29786 if (FRAME_WINDOW_P (XFRAME (w->frame)))
29788 draw_glyphs (w, start_x, row, TEXT_AREA, start_hpos, end_hpos, draw, 0);
29789 return;
29791 #endif
29792 #if defined (HAVE_GPM) || defined (MSDOS) || defined (WINDOWSNT)
29793 tty_draw_row_with_mouse_face (w, row, start_hpos, end_hpos, draw);
29794 #endif
29797 /* Display the active region described by mouse_face_* according to DRAW. */
29799 static void
29800 show_mouse_face (Mouse_HLInfo *hlinfo, enum draw_glyphs_face draw)
29802 struct window *w = XWINDOW (hlinfo->mouse_face_window);
29803 struct frame *f = XFRAME (WINDOW_FRAME (w));
29805 if (/* If window is in the process of being destroyed, don't bother
29806 to do anything. */
29807 w->current_matrix != NULL
29808 /* Don't update mouse highlight if hidden. */
29809 && (draw != DRAW_MOUSE_FACE || !hlinfo->mouse_face_hidden)
29810 /* Recognize when we are called to operate on rows that don't exist
29811 anymore. This can happen when a window is split. */
29812 && hlinfo->mouse_face_end_row < w->current_matrix->nrows)
29814 bool phys_cursor_on_p = w->phys_cursor_on_p;
29815 struct glyph_row *row, *first, *last;
29817 first = MATRIX_ROW (w->current_matrix, hlinfo->mouse_face_beg_row);
29818 last = MATRIX_ROW (w->current_matrix, hlinfo->mouse_face_end_row);
29820 for (row = first; row <= last && row->enabled_p; ++row)
29822 int start_hpos, end_hpos, start_x;
29824 /* For all but the first row, the highlight starts at column 0. */
29825 if (row == first)
29827 /* R2L rows have BEG and END in reversed order, but the
29828 screen drawing geometry is always left to right. So
29829 we need to mirror the beginning and end of the
29830 highlighted area in R2L rows. */
29831 if (!row->reversed_p)
29833 start_hpos = hlinfo->mouse_face_beg_col;
29834 start_x = hlinfo->mouse_face_beg_x;
29836 else if (row == last)
29838 start_hpos = hlinfo->mouse_face_end_col;
29839 start_x = hlinfo->mouse_face_end_x;
29841 else
29843 start_hpos = 0;
29844 start_x = 0;
29847 else if (row->reversed_p && row == last)
29849 start_hpos = hlinfo->mouse_face_end_col;
29850 start_x = hlinfo->mouse_face_end_x;
29852 else
29854 start_hpos = 0;
29855 start_x = 0;
29858 if (row == last)
29860 if (!row->reversed_p)
29861 end_hpos = hlinfo->mouse_face_end_col;
29862 else if (row == first)
29863 end_hpos = hlinfo->mouse_face_beg_col;
29864 else
29866 end_hpos = row->used[TEXT_AREA];
29867 if (draw == DRAW_NORMAL_TEXT)
29868 row->fill_line_p = true; /* Clear to end of line. */
29871 else if (row->reversed_p && row == first)
29872 end_hpos = hlinfo->mouse_face_beg_col;
29873 else
29875 end_hpos = row->used[TEXT_AREA];
29876 if (draw == DRAW_NORMAL_TEXT)
29877 row->fill_line_p = true; /* Clear to end of line. */
29880 if (end_hpos > start_hpos)
29882 draw_row_with_mouse_face (w, start_x, row,
29883 start_hpos, end_hpos, draw);
29885 row->mouse_face_p
29886 = draw == DRAW_MOUSE_FACE || draw == DRAW_IMAGE_RAISED;
29890 /* When we've written over the cursor, arrange for it to
29891 be displayed again. */
29892 if (FRAME_WINDOW_P (f)
29893 && phys_cursor_on_p && !w->phys_cursor_on_p)
29895 #ifdef HAVE_WINDOW_SYSTEM
29896 int hpos = w->phys_cursor.hpos;
29898 /* When the window is hscrolled, cursor hpos can legitimately be
29899 out of bounds, but we draw the cursor at the corresponding
29900 window margin in that case. */
29901 if (!row->reversed_p && hpos < 0)
29902 hpos = 0;
29903 if (row->reversed_p && hpos >= row->used[TEXT_AREA])
29904 hpos = row->used[TEXT_AREA] - 1;
29906 block_input ();
29907 display_and_set_cursor (w, true, hpos, w->phys_cursor.vpos,
29908 w->phys_cursor.x, w->phys_cursor.y);
29909 unblock_input ();
29910 #endif /* HAVE_WINDOW_SYSTEM */
29914 #ifdef HAVE_WINDOW_SYSTEM
29915 /* Change the mouse cursor. */
29916 if (FRAME_WINDOW_P (f) && NILP (do_mouse_tracking))
29918 #if ! defined (USE_GTK) && ! defined (HAVE_NS)
29919 if (draw == DRAW_NORMAL_TEXT
29920 && !EQ (hlinfo->mouse_face_window, f->tool_bar_window))
29921 FRAME_RIF (f)->define_frame_cursor (f, FRAME_X_OUTPUT (f)->text_cursor);
29922 else
29923 #endif
29924 if (draw == DRAW_MOUSE_FACE)
29925 FRAME_RIF (f)->define_frame_cursor (f, FRAME_X_OUTPUT (f)->hand_cursor);
29926 else
29927 FRAME_RIF (f)->define_frame_cursor (f, FRAME_X_OUTPUT (f)->nontext_cursor);
29929 #endif /* HAVE_WINDOW_SYSTEM */
29932 /* EXPORT:
29933 Clear out the mouse-highlighted active region.
29934 Redraw it un-highlighted first. Value is true if mouse
29935 face was actually drawn unhighlighted. */
29937 bool
29938 clear_mouse_face (Mouse_HLInfo *hlinfo)
29940 bool cleared
29941 = !hlinfo->mouse_face_hidden && !NILP (hlinfo->mouse_face_window);
29942 if (cleared)
29943 show_mouse_face (hlinfo, DRAW_NORMAL_TEXT);
29944 hlinfo->mouse_face_beg_row = hlinfo->mouse_face_beg_col = -1;
29945 hlinfo->mouse_face_end_row = hlinfo->mouse_face_end_col = -1;
29946 hlinfo->mouse_face_window = Qnil;
29947 hlinfo->mouse_face_overlay = Qnil;
29948 return cleared;
29951 /* Return true if the coordinates HPOS and VPOS on windows W are
29952 within the mouse face on that window. */
29953 static bool
29954 coords_in_mouse_face_p (struct window *w, int hpos, int vpos)
29956 Mouse_HLInfo *hlinfo = MOUSE_HL_INFO (XFRAME (w->frame));
29958 /* Quickly resolve the easy cases. */
29959 if (!(WINDOWP (hlinfo->mouse_face_window)
29960 && XWINDOW (hlinfo->mouse_face_window) == w))
29961 return false;
29962 if (vpos < hlinfo->mouse_face_beg_row
29963 || vpos > hlinfo->mouse_face_end_row)
29964 return false;
29965 if (vpos > hlinfo->mouse_face_beg_row
29966 && vpos < hlinfo->mouse_face_end_row)
29967 return true;
29969 if (!MATRIX_ROW (w->current_matrix, vpos)->reversed_p)
29971 if (hlinfo->mouse_face_beg_row == hlinfo->mouse_face_end_row)
29973 if (hlinfo->mouse_face_beg_col <= hpos && hpos < hlinfo->mouse_face_end_col)
29974 return true;
29976 else if ((vpos == hlinfo->mouse_face_beg_row
29977 && hpos >= hlinfo->mouse_face_beg_col)
29978 || (vpos == hlinfo->mouse_face_end_row
29979 && hpos < hlinfo->mouse_face_end_col))
29980 return true;
29982 else
29984 if (hlinfo->mouse_face_beg_row == hlinfo->mouse_face_end_row)
29986 if (hlinfo->mouse_face_end_col < hpos && hpos <= hlinfo->mouse_face_beg_col)
29987 return true;
29989 else if ((vpos == hlinfo->mouse_face_beg_row
29990 && hpos <= hlinfo->mouse_face_beg_col)
29991 || (vpos == hlinfo->mouse_face_end_row
29992 && hpos > hlinfo->mouse_face_end_col))
29993 return true;
29995 return false;
29999 /* EXPORT:
30000 True if physical cursor of window W is within mouse face. */
30002 bool
30003 cursor_in_mouse_face_p (struct window *w)
30005 int hpos = w->phys_cursor.hpos;
30006 int vpos = w->phys_cursor.vpos;
30007 struct glyph_row *row = MATRIX_ROW (w->current_matrix, vpos);
30009 /* When the window is hscrolled, cursor hpos can legitimately be out
30010 of bounds, but we draw the cursor at the corresponding window
30011 margin in that case. */
30012 if (!row->reversed_p && hpos < 0)
30013 hpos = 0;
30014 if (row->reversed_p && hpos >= row->used[TEXT_AREA])
30015 hpos = row->used[TEXT_AREA] - 1;
30017 return coords_in_mouse_face_p (w, hpos, vpos);
30022 /* Find the glyph rows START_ROW and END_ROW of window W that display
30023 characters between buffer positions START_CHARPOS and END_CHARPOS
30024 (excluding END_CHARPOS). DISP_STRING is a display string that
30025 covers these buffer positions. This is similar to
30026 row_containing_pos, but is more accurate when bidi reordering makes
30027 buffer positions change non-linearly with glyph rows. */
30028 static void
30029 rows_from_pos_range (struct window *w,
30030 ptrdiff_t start_charpos, ptrdiff_t end_charpos,
30031 Lisp_Object disp_string,
30032 struct glyph_row **start, struct glyph_row **end)
30034 struct glyph_row *first = MATRIX_FIRST_TEXT_ROW (w->current_matrix);
30035 int last_y = window_text_bottom_y (w);
30036 struct glyph_row *row;
30038 *start = NULL;
30039 *end = NULL;
30041 while (!first->enabled_p
30042 && first < MATRIX_BOTTOM_TEXT_ROW (w->current_matrix, w))
30043 first++;
30045 /* Find the START row. */
30046 for (row = first;
30047 row->enabled_p && MATRIX_ROW_BOTTOM_Y (row) <= last_y;
30048 row++)
30050 /* A row can potentially be the START row if the range of the
30051 characters it displays intersects the range
30052 [START_CHARPOS..END_CHARPOS). */
30053 if (! ((start_charpos < MATRIX_ROW_START_CHARPOS (row)
30054 && end_charpos < MATRIX_ROW_START_CHARPOS (row))
30055 /* See the commentary in row_containing_pos, for the
30056 explanation of the complicated way to check whether
30057 some position is beyond the end of the characters
30058 displayed by a row. */
30059 || ((start_charpos > MATRIX_ROW_END_CHARPOS (row)
30060 || (start_charpos == MATRIX_ROW_END_CHARPOS (row)
30061 && !row->ends_at_zv_p
30062 && !MATRIX_ROW_ENDS_IN_MIDDLE_OF_CHAR_P (row)))
30063 && (end_charpos > MATRIX_ROW_END_CHARPOS (row)
30064 || (end_charpos == MATRIX_ROW_END_CHARPOS (row)
30065 && !row->ends_at_zv_p
30066 && !MATRIX_ROW_ENDS_IN_MIDDLE_OF_CHAR_P (row))))))
30068 /* Found a candidate row. Now make sure at least one of the
30069 glyphs it displays has a charpos from the range
30070 [START_CHARPOS..END_CHARPOS).
30072 This is not obvious because bidi reordering could make
30073 buffer positions of a row be 1,2,3,102,101,100, and if we
30074 want to highlight characters in [50..60), we don't want
30075 this row, even though [50..60) does intersect [1..103),
30076 the range of character positions given by the row's start
30077 and end positions. */
30078 struct glyph *g = row->glyphs[TEXT_AREA];
30079 struct glyph *e = g + row->used[TEXT_AREA];
30081 while (g < e)
30083 if (((BUFFERP (g->object) || NILP (g->object))
30084 && start_charpos <= g->charpos && g->charpos < end_charpos)
30085 /* A glyph that comes from DISP_STRING is by
30086 definition to be highlighted. */
30087 || EQ (g->object, disp_string))
30088 *start = row;
30089 g++;
30091 if (*start)
30092 break;
30096 /* Find the END row. */
30097 if (!*start
30098 /* If the last row is partially visible, start looking for END
30099 from that row, instead of starting from FIRST. */
30100 && !(row->enabled_p
30101 && row->y < last_y && MATRIX_ROW_BOTTOM_Y (row) > last_y))
30102 row = first;
30103 for ( ; row->enabled_p && MATRIX_ROW_BOTTOM_Y (row) <= last_y; row++)
30105 struct glyph_row *next = row + 1;
30106 ptrdiff_t next_start = MATRIX_ROW_START_CHARPOS (next);
30108 if (!next->enabled_p
30109 || next >= MATRIX_BOTTOM_TEXT_ROW (w->current_matrix, w)
30110 /* The first row >= START whose range of displayed characters
30111 does NOT intersect the range [START_CHARPOS..END_CHARPOS]
30112 is the row END + 1. */
30113 || (start_charpos < next_start
30114 && end_charpos < next_start)
30115 || ((start_charpos > MATRIX_ROW_END_CHARPOS (next)
30116 || (start_charpos == MATRIX_ROW_END_CHARPOS (next)
30117 && !next->ends_at_zv_p
30118 && !MATRIX_ROW_ENDS_IN_MIDDLE_OF_CHAR_P (next)))
30119 && (end_charpos > MATRIX_ROW_END_CHARPOS (next)
30120 || (end_charpos == MATRIX_ROW_END_CHARPOS (next)
30121 && !next->ends_at_zv_p
30122 && !MATRIX_ROW_ENDS_IN_MIDDLE_OF_CHAR_P (next)))))
30124 *end = row;
30125 break;
30127 else
30129 /* If the next row's edges intersect [START_CHARPOS..END_CHARPOS],
30130 but none of the characters it displays are in the range, it is
30131 also END + 1. */
30132 struct glyph *g = next->glyphs[TEXT_AREA];
30133 struct glyph *s = g;
30134 struct glyph *e = g + next->used[TEXT_AREA];
30136 while (g < e)
30138 if (((BUFFERP (g->object) || NILP (g->object))
30139 && ((start_charpos <= g->charpos && g->charpos < end_charpos)
30140 /* If the buffer position of the first glyph in
30141 the row is equal to END_CHARPOS, it means
30142 the last character to be highlighted is the
30143 newline of ROW, and we must consider NEXT as
30144 END, not END+1. */
30145 || (((!next->reversed_p && g == s)
30146 || (next->reversed_p && g == e - 1))
30147 && (g->charpos == end_charpos
30148 /* Special case for when NEXT is an
30149 empty line at ZV. */
30150 || (g->charpos == -1
30151 && !row->ends_at_zv_p
30152 && next_start == end_charpos)))))
30153 /* A glyph that comes from DISP_STRING is by
30154 definition to be highlighted. */
30155 || EQ (g->object, disp_string))
30156 break;
30157 g++;
30159 if (g == e)
30161 *end = row;
30162 break;
30164 /* The first row that ends at ZV must be the last to be
30165 highlighted. */
30166 else if (next->ends_at_zv_p)
30168 *end = next;
30169 break;
30175 /* This function sets the mouse_face_* elements of HLINFO, assuming
30176 the mouse cursor is on a glyph with buffer charpos MOUSE_CHARPOS in
30177 window WINDOW. START_CHARPOS and END_CHARPOS are buffer positions
30178 for the overlay or run of text properties specifying the mouse
30179 face. BEFORE_STRING and AFTER_STRING, if non-nil, are a
30180 before-string and after-string that must also be highlighted.
30181 DISP_STRING, if non-nil, is a display string that may cover some
30182 or all of the highlighted text. */
30184 static void
30185 mouse_face_from_buffer_pos (Lisp_Object window,
30186 Mouse_HLInfo *hlinfo,
30187 ptrdiff_t mouse_charpos,
30188 ptrdiff_t start_charpos,
30189 ptrdiff_t end_charpos,
30190 Lisp_Object before_string,
30191 Lisp_Object after_string,
30192 Lisp_Object disp_string)
30194 struct window *w = XWINDOW (window);
30195 struct glyph_row *first = MATRIX_FIRST_TEXT_ROW (w->current_matrix);
30196 struct glyph_row *r1, *r2;
30197 struct glyph *glyph, *end;
30198 ptrdiff_t ignore, pos;
30199 int x;
30201 eassert (NILP (disp_string) || STRINGP (disp_string));
30202 eassert (NILP (before_string) || STRINGP (before_string));
30203 eassert (NILP (after_string) || STRINGP (after_string));
30205 /* Find the rows corresponding to START_CHARPOS and END_CHARPOS. */
30206 rows_from_pos_range (w, start_charpos, end_charpos, disp_string, &r1, &r2);
30207 if (r1 == NULL)
30208 r1 = MATRIX_ROW (w->current_matrix, w->window_end_vpos);
30209 /* If the before-string or display-string contains newlines,
30210 rows_from_pos_range skips to its last row. Move back. */
30211 if (!NILP (before_string) || !NILP (disp_string))
30213 struct glyph_row *prev;
30214 while ((prev = r1 - 1, prev >= first)
30215 && MATRIX_ROW_END_CHARPOS (prev) == start_charpos
30216 && prev->used[TEXT_AREA] > 0)
30218 struct glyph *beg = prev->glyphs[TEXT_AREA];
30219 glyph = beg + prev->used[TEXT_AREA];
30220 while (--glyph >= beg && NILP (glyph->object));
30221 if (glyph < beg
30222 || !(EQ (glyph->object, before_string)
30223 || EQ (glyph->object, disp_string)))
30224 break;
30225 r1 = prev;
30228 if (r2 == NULL)
30230 r2 = MATRIX_ROW (w->current_matrix, w->window_end_vpos);
30231 hlinfo->mouse_face_past_end = true;
30233 else if (!NILP (after_string))
30235 /* If the after-string has newlines, advance to its last row. */
30236 struct glyph_row *next;
30237 struct glyph_row *last
30238 = MATRIX_ROW (w->current_matrix, w->window_end_vpos);
30240 for (next = r2 + 1;
30241 next <= last
30242 && next->used[TEXT_AREA] > 0
30243 && EQ (next->glyphs[TEXT_AREA]->object, after_string);
30244 ++next)
30245 r2 = next;
30247 /* The rest of the display engine assumes that mouse_face_beg_row is
30248 either above mouse_face_end_row or identical to it. But with
30249 bidi-reordered continued lines, the row for START_CHARPOS could
30250 be below the row for END_CHARPOS. If so, swap the rows and store
30251 them in correct order. */
30252 if (r1->y > r2->y)
30254 struct glyph_row *tem = r2;
30256 r2 = r1;
30257 r1 = tem;
30260 hlinfo->mouse_face_beg_row = MATRIX_ROW_VPOS (r1, w->current_matrix);
30261 hlinfo->mouse_face_end_row = MATRIX_ROW_VPOS (r2, w->current_matrix);
30263 /* For a bidi-reordered row, the positions of BEFORE_STRING,
30264 AFTER_STRING, DISP_STRING, START_CHARPOS, and END_CHARPOS
30265 could be anywhere in the row and in any order. The strategy
30266 below is to find the leftmost and the rightmost glyph that
30267 belongs to either of these 3 strings, or whose position is
30268 between START_CHARPOS and END_CHARPOS, and highlight all the
30269 glyphs between those two. This may cover more than just the text
30270 between START_CHARPOS and END_CHARPOS if the range of characters
30271 strides the bidi level boundary, e.g. if the beginning is in R2L
30272 text while the end is in L2R text or vice versa. */
30273 if (!r1->reversed_p)
30275 /* This row is in a left to right paragraph. Scan it left to
30276 right. */
30277 glyph = r1->glyphs[TEXT_AREA];
30278 end = glyph + r1->used[TEXT_AREA];
30279 x = r1->x;
30281 /* Skip truncation glyphs at the start of the glyph row. */
30282 if (MATRIX_ROW_DISPLAYS_TEXT_P (r1))
30283 for (; glyph < end
30284 && NILP (glyph->object)
30285 && glyph->charpos < 0;
30286 ++glyph)
30287 x += glyph->pixel_width;
30289 /* Scan the glyph row, looking for BEFORE_STRING, AFTER_STRING,
30290 or DISP_STRING, and the first glyph from buffer whose
30291 position is between START_CHARPOS and END_CHARPOS. */
30292 for (; glyph < end
30293 && !NILP (glyph->object)
30294 && !EQ (glyph->object, disp_string)
30295 && !(BUFFERP (glyph->object)
30296 && (glyph->charpos >= start_charpos
30297 && glyph->charpos < end_charpos));
30298 ++glyph)
30300 /* BEFORE_STRING or AFTER_STRING are only relevant if they
30301 are present at buffer positions between START_CHARPOS and
30302 END_CHARPOS, or if they come from an overlay. */
30303 if (EQ (glyph->object, before_string))
30305 pos = string_buffer_position (before_string,
30306 start_charpos);
30307 /* If pos == 0, it means before_string came from an
30308 overlay, not from a buffer position. */
30309 if (!pos || (pos >= start_charpos && pos < end_charpos))
30310 break;
30312 else if (EQ (glyph->object, after_string))
30314 pos = string_buffer_position (after_string, end_charpos);
30315 if (!pos || (pos >= start_charpos && pos < end_charpos))
30316 break;
30318 x += glyph->pixel_width;
30320 hlinfo->mouse_face_beg_x = x;
30321 hlinfo->mouse_face_beg_col = glyph - r1->glyphs[TEXT_AREA];
30323 else
30325 /* This row is in a right to left paragraph. Scan it right to
30326 left. */
30327 struct glyph *g;
30329 end = r1->glyphs[TEXT_AREA] - 1;
30330 glyph = end + r1->used[TEXT_AREA];
30332 /* Skip truncation glyphs at the start of the glyph row. */
30333 if (MATRIX_ROW_DISPLAYS_TEXT_P (r1))
30334 for (; glyph > end
30335 && NILP (glyph->object)
30336 && glyph->charpos < 0;
30337 --glyph)
30340 /* Scan the glyph row, looking for BEFORE_STRING, AFTER_STRING,
30341 or DISP_STRING, and the first glyph from buffer whose
30342 position is between START_CHARPOS and END_CHARPOS. */
30343 for (; glyph > end
30344 && !NILP (glyph->object)
30345 && !EQ (glyph->object, disp_string)
30346 && !(BUFFERP (glyph->object)
30347 && (glyph->charpos >= start_charpos
30348 && glyph->charpos < end_charpos));
30349 --glyph)
30351 /* BEFORE_STRING or AFTER_STRING are only relevant if they
30352 are present at buffer positions between START_CHARPOS and
30353 END_CHARPOS, or if they come from an overlay. */
30354 if (EQ (glyph->object, before_string))
30356 pos = string_buffer_position (before_string, start_charpos);
30357 /* If pos == 0, it means before_string came from an
30358 overlay, not from a buffer position. */
30359 if (!pos || (pos >= start_charpos && pos < end_charpos))
30360 break;
30362 else if (EQ (glyph->object, after_string))
30364 pos = string_buffer_position (after_string, end_charpos);
30365 if (!pos || (pos >= start_charpos && pos < end_charpos))
30366 break;
30370 glyph++; /* first glyph to the right of the highlighted area */
30371 for (g = r1->glyphs[TEXT_AREA], x = r1->x; g < glyph; g++)
30372 x += g->pixel_width;
30373 hlinfo->mouse_face_beg_x = x;
30374 hlinfo->mouse_face_beg_col = glyph - r1->glyphs[TEXT_AREA];
30377 /* If the highlight ends in a different row, compute GLYPH and END
30378 for the end row. Otherwise, reuse the values computed above for
30379 the row where the highlight begins. */
30380 if (r2 != r1)
30382 if (!r2->reversed_p)
30384 glyph = r2->glyphs[TEXT_AREA];
30385 end = glyph + r2->used[TEXT_AREA];
30386 x = r2->x;
30388 else
30390 end = r2->glyphs[TEXT_AREA] - 1;
30391 glyph = end + r2->used[TEXT_AREA];
30395 if (!r2->reversed_p)
30397 /* Skip truncation and continuation glyphs near the end of the
30398 row, and also blanks and stretch glyphs inserted by
30399 extend_face_to_end_of_line. */
30400 while (end > glyph
30401 && NILP ((end - 1)->object))
30402 --end;
30403 /* Scan the rest of the glyph row from the end, looking for the
30404 first glyph that comes from BEFORE_STRING, AFTER_STRING, or
30405 DISP_STRING, or whose position is between START_CHARPOS
30406 and END_CHARPOS */
30407 for (--end;
30408 end > glyph
30409 && !NILP (end->object)
30410 && !EQ (end->object, disp_string)
30411 && !(BUFFERP (end->object)
30412 && (end->charpos >= start_charpos
30413 && end->charpos < end_charpos));
30414 --end)
30416 /* BEFORE_STRING or AFTER_STRING are only relevant if they
30417 are present at buffer positions between START_CHARPOS and
30418 END_CHARPOS, or if they come from an overlay. */
30419 if (EQ (end->object, before_string))
30421 pos = string_buffer_position (before_string, start_charpos);
30422 if (!pos || (pos >= start_charpos && pos < end_charpos))
30423 break;
30425 else if (EQ (end->object, after_string))
30427 pos = string_buffer_position (after_string, end_charpos);
30428 if (!pos || (pos >= start_charpos && pos < end_charpos))
30429 break;
30432 /* Find the X coordinate of the last glyph to be highlighted. */
30433 for (; glyph <= end; ++glyph)
30434 x += glyph->pixel_width;
30436 hlinfo->mouse_face_end_x = x;
30437 hlinfo->mouse_face_end_col = glyph - r2->glyphs[TEXT_AREA];
30439 else
30441 /* Skip truncation and continuation glyphs near the end of the
30442 row, and also blanks and stretch glyphs inserted by
30443 extend_face_to_end_of_line. */
30444 x = r2->x;
30445 end++;
30446 while (end < glyph
30447 && NILP (end->object))
30449 x += end->pixel_width;
30450 ++end;
30452 /* Scan the rest of the glyph row from the end, looking for the
30453 first glyph that comes from BEFORE_STRING, AFTER_STRING, or
30454 DISP_STRING, or whose position is between START_CHARPOS
30455 and END_CHARPOS */
30456 for ( ;
30457 end < glyph
30458 && !NILP (end->object)
30459 && !EQ (end->object, disp_string)
30460 && !(BUFFERP (end->object)
30461 && (end->charpos >= start_charpos
30462 && end->charpos < end_charpos));
30463 ++end)
30465 /* BEFORE_STRING or AFTER_STRING are only relevant if they
30466 are present at buffer positions between START_CHARPOS and
30467 END_CHARPOS, or if they come from an overlay. */
30468 if (EQ (end->object, before_string))
30470 pos = string_buffer_position (before_string, start_charpos);
30471 if (!pos || (pos >= start_charpos && pos < end_charpos))
30472 break;
30474 else if (EQ (end->object, after_string))
30476 pos = string_buffer_position (after_string, end_charpos);
30477 if (!pos || (pos >= start_charpos && pos < end_charpos))
30478 break;
30480 x += end->pixel_width;
30482 /* If we exited the above loop because we arrived at the last
30483 glyph of the row, and its buffer position is still not in
30484 range, it means the last character in range is the preceding
30485 newline. Bump the end column and x values to get past the
30486 last glyph. */
30487 if (end == glyph
30488 && BUFFERP (end->object)
30489 && (end->charpos < start_charpos
30490 || end->charpos >= end_charpos))
30492 x += end->pixel_width;
30493 ++end;
30495 hlinfo->mouse_face_end_x = x;
30496 hlinfo->mouse_face_end_col = end - r2->glyphs[TEXT_AREA];
30499 hlinfo->mouse_face_window = window;
30500 hlinfo->mouse_face_face_id
30501 = face_at_buffer_position (w, mouse_charpos, &ignore,
30502 mouse_charpos + 1,
30503 !hlinfo->mouse_face_hidden, -1);
30504 show_mouse_face (hlinfo, DRAW_MOUSE_FACE);
30507 /* The following function is not used anymore (replaced with
30508 mouse_face_from_string_pos), but I leave it here for the time
30509 being, in case someone would. */
30511 #if false /* not used */
30513 /* Find the position of the glyph for position POS in OBJECT in
30514 window W's current matrix, and return in *X, *Y the pixel
30515 coordinates, and return in *HPOS, *VPOS the column/row of the glyph.
30517 RIGHT_P means return the position of the right edge of the glyph.
30518 !RIGHT_P means return the left edge position.
30520 If no glyph for POS exists in the matrix, return the position of
30521 the glyph with the next smaller position that is in the matrix, if
30522 RIGHT_P is false. If RIGHT_P, and no glyph for POS
30523 exists in the matrix, return the position of the glyph with the
30524 next larger position in OBJECT.
30526 Value is true if a glyph was found. */
30528 static bool
30529 fast_find_string_pos (struct window *w, ptrdiff_t pos, Lisp_Object object,
30530 int *hpos, int *vpos, int *x, int *y, bool right_p)
30532 int yb = window_text_bottom_y (w);
30533 struct glyph_row *r;
30534 struct glyph *best_glyph = NULL;
30535 struct glyph_row *best_row = NULL;
30536 int best_x = 0;
30538 for (r = MATRIX_FIRST_TEXT_ROW (w->current_matrix);
30539 r->enabled_p && r->y < yb;
30540 ++r)
30542 struct glyph *g = r->glyphs[TEXT_AREA];
30543 struct glyph *e = g + r->used[TEXT_AREA];
30544 int gx;
30546 for (gx = r->x; g < e; gx += g->pixel_width, ++g)
30547 if (EQ (g->object, object))
30549 if (g->charpos == pos)
30551 best_glyph = g;
30552 best_x = gx;
30553 best_row = r;
30554 goto found;
30556 else if (best_glyph == NULL
30557 || ((eabs (g->charpos - pos)
30558 < eabs (best_glyph->charpos - pos))
30559 && (right_p
30560 ? g->charpos < pos
30561 : g->charpos > pos)))
30563 best_glyph = g;
30564 best_x = gx;
30565 best_row = r;
30570 found:
30572 if (best_glyph)
30574 *x = best_x;
30575 *hpos = best_glyph - best_row->glyphs[TEXT_AREA];
30577 if (right_p)
30579 *x += best_glyph->pixel_width;
30580 ++*hpos;
30583 *y = best_row->y;
30584 *vpos = MATRIX_ROW_VPOS (best_row, w->current_matrix);
30587 return best_glyph != NULL;
30589 #endif /* not used */
30591 /* Find the positions of the first and the last glyphs in window W's
30592 current matrix that occlude positions [STARTPOS..ENDPOS) in OBJECT
30593 (assumed to be a string), and return in HLINFO's mouse_face_*
30594 members the pixel and column/row coordinates of those glyphs. */
30596 static void
30597 mouse_face_from_string_pos (struct window *w, Mouse_HLInfo *hlinfo,
30598 Lisp_Object object,
30599 ptrdiff_t startpos, ptrdiff_t endpos)
30601 int yb = window_text_bottom_y (w);
30602 struct glyph_row *r;
30603 struct glyph *g, *e;
30604 int gx;
30605 bool found = false;
30607 /* Find the glyph row with at least one position in the range
30608 [STARTPOS..ENDPOS), and the first glyph in that row whose
30609 position belongs to that range. */
30610 for (r = MATRIX_FIRST_TEXT_ROW (w->current_matrix);
30611 r->enabled_p && r->y < yb;
30612 ++r)
30614 if (!r->reversed_p)
30616 g = r->glyphs[TEXT_AREA];
30617 e = g + r->used[TEXT_AREA];
30618 for (gx = r->x; g < e; gx += g->pixel_width, ++g)
30619 if (EQ (g->object, object)
30620 && startpos <= g->charpos && g->charpos < endpos)
30622 hlinfo->mouse_face_beg_row
30623 = MATRIX_ROW_VPOS (r, w->current_matrix);
30624 hlinfo->mouse_face_beg_col = g - r->glyphs[TEXT_AREA];
30625 hlinfo->mouse_face_beg_x = gx;
30626 found = true;
30627 break;
30630 else
30632 struct glyph *g1;
30634 e = r->glyphs[TEXT_AREA];
30635 g = e + r->used[TEXT_AREA];
30636 for ( ; g > e; --g)
30637 if (EQ ((g-1)->object, object)
30638 && startpos <= (g-1)->charpos && (g-1)->charpos < endpos)
30640 hlinfo->mouse_face_beg_row
30641 = MATRIX_ROW_VPOS (r, w->current_matrix);
30642 hlinfo->mouse_face_beg_col = g - r->glyphs[TEXT_AREA];
30643 for (gx = r->x, g1 = r->glyphs[TEXT_AREA]; g1 < g; ++g1)
30644 gx += g1->pixel_width;
30645 hlinfo->mouse_face_beg_x = gx;
30646 found = true;
30647 break;
30650 if (found)
30651 break;
30654 if (!found)
30655 return;
30657 /* Starting with the next row, look for the first row which does NOT
30658 include any glyphs whose positions are in the range. */
30659 for (++r; r->enabled_p && r->y < yb; ++r)
30661 g = r->glyphs[TEXT_AREA];
30662 e = g + r->used[TEXT_AREA];
30663 found = false;
30664 for ( ; g < e; ++g)
30665 if (EQ (g->object, object)
30666 && startpos <= g->charpos && g->charpos < endpos)
30668 found = true;
30669 break;
30671 if (!found)
30672 break;
30675 /* The highlighted region ends on the previous row. */
30676 r--;
30678 /* Set the end row. */
30679 hlinfo->mouse_face_end_row = MATRIX_ROW_VPOS (r, w->current_matrix);
30681 /* Compute and set the end column and the end column's horizontal
30682 pixel coordinate. */
30683 if (!r->reversed_p)
30685 g = r->glyphs[TEXT_AREA];
30686 e = g + r->used[TEXT_AREA];
30687 for ( ; e > g; --e)
30688 if (EQ ((e-1)->object, object)
30689 && startpos <= (e-1)->charpos && (e-1)->charpos < endpos)
30690 break;
30691 hlinfo->mouse_face_end_col = e - g;
30693 for (gx = r->x; g < e; ++g)
30694 gx += g->pixel_width;
30695 hlinfo->mouse_face_end_x = gx;
30697 else
30699 e = r->glyphs[TEXT_AREA];
30700 g = e + r->used[TEXT_AREA];
30701 for (gx = r->x ; e < g; ++e)
30703 if (EQ (e->object, object)
30704 && startpos <= e->charpos && e->charpos < endpos)
30705 break;
30706 gx += e->pixel_width;
30708 hlinfo->mouse_face_end_col = e - r->glyphs[TEXT_AREA];
30709 hlinfo->mouse_face_end_x = gx;
30713 #ifdef HAVE_WINDOW_SYSTEM
30715 /* See if position X, Y is within a hot-spot of an image. */
30717 static bool
30718 on_hot_spot_p (Lisp_Object hot_spot, int x, int y)
30720 if (!CONSP (hot_spot))
30721 return false;
30723 if (EQ (XCAR (hot_spot), Qrect))
30725 /* CDR is (Top-Left . Bottom-Right) = ((x0 . y0) . (x1 . y1)) */
30726 Lisp_Object rect = XCDR (hot_spot);
30727 Lisp_Object tem;
30728 if (!CONSP (rect))
30729 return false;
30730 if (!CONSP (XCAR (rect)))
30731 return false;
30732 if (!CONSP (XCDR (rect)))
30733 return false;
30734 if (!(tem = XCAR (XCAR (rect)), INTEGERP (tem) && x >= XINT (tem)))
30735 return false;
30736 if (!(tem = XCDR (XCAR (rect)), INTEGERP (tem) && y >= XINT (tem)))
30737 return false;
30738 if (!(tem = XCAR (XCDR (rect)), INTEGERP (tem) && x <= XINT (tem)))
30739 return false;
30740 if (!(tem = XCDR (XCDR (rect)), INTEGERP (tem) && y <= XINT (tem)))
30741 return false;
30742 return true;
30744 else if (EQ (XCAR (hot_spot), Qcircle))
30746 /* CDR is (Center . Radius) = ((x0 . y0) . r) */
30747 Lisp_Object circ = XCDR (hot_spot);
30748 Lisp_Object lr, lx0, ly0;
30749 if (CONSP (circ)
30750 && CONSP (XCAR (circ))
30751 && (lr = XCDR (circ), NUMBERP (lr))
30752 && (lx0 = XCAR (XCAR (circ)), INTEGERP (lx0))
30753 && (ly0 = XCDR (XCAR (circ)), INTEGERP (ly0)))
30755 double r = XFLOATINT (lr);
30756 double dx = XINT (lx0) - x;
30757 double dy = XINT (ly0) - y;
30758 return (dx * dx + dy * dy <= r * r);
30761 else if (EQ (XCAR (hot_spot), Qpoly))
30763 /* CDR is [x0 y0 x1 y1 x2 y2 ...x(n-1) y(n-1)] */
30764 if (VECTORP (XCDR (hot_spot)))
30766 struct Lisp_Vector *v = XVECTOR (XCDR (hot_spot));
30767 Lisp_Object *poly = v->contents;
30768 ptrdiff_t n = v->header.size;
30769 ptrdiff_t i;
30770 bool inside = false;
30771 Lisp_Object lx, ly;
30772 int x0, y0;
30774 /* Need an even number of coordinates, and at least 3 edges. */
30775 if (n < 6 || n & 1)
30776 return false;
30778 /* Count edge segments intersecting line from (X,Y) to (X,infinity).
30779 If count is odd, we are inside polygon. Pixels on edges
30780 may or may not be included depending on actual geometry of the
30781 polygon. */
30782 if ((lx = poly[n-2], !INTEGERP (lx))
30783 || (ly = poly[n-1], !INTEGERP (lx)))
30784 return false;
30785 x0 = XINT (lx), y0 = XINT (ly);
30786 for (i = 0; i < n; i += 2)
30788 int x1 = x0, y1 = y0;
30789 if ((lx = poly[i], !INTEGERP (lx))
30790 || (ly = poly[i+1], !INTEGERP (ly)))
30791 return false;
30792 x0 = XINT (lx), y0 = XINT (ly);
30794 /* Does this segment cross the X line? */
30795 if (x0 >= x)
30797 if (x1 >= x)
30798 continue;
30800 else if (x1 < x)
30801 continue;
30802 if (y > y0 && y > y1)
30803 continue;
30804 if (y < y0 + ((y1 - y0) * (x - x0)) / (x1 - x0))
30805 inside = !inside;
30807 return inside;
30810 return false;
30813 Lisp_Object
30814 find_hot_spot (Lisp_Object map, int x, int y)
30816 while (CONSP (map))
30818 if (CONSP (XCAR (map))
30819 && on_hot_spot_p (XCAR (XCAR (map)), x, y))
30820 return XCAR (map);
30821 map = XCDR (map);
30824 return Qnil;
30827 DEFUN ("lookup-image-map", Flookup_image_map, Slookup_image_map,
30828 3, 3, 0,
30829 doc: /* Lookup in image map MAP coordinates X and Y.
30830 An image map is an alist where each element has the format (AREA ID PLIST).
30831 An AREA is specified as either a rectangle, a circle, or a polygon:
30832 A rectangle is a cons (rect . ((x0 . y0) . (x1 . y1))) specifying the
30833 pixel coordinates of the upper left and bottom right corners.
30834 A circle is a cons (circle . ((x0 . y0) . r)) specifying the center
30835 and the radius of the circle; r may be a float or integer.
30836 A polygon is a cons (poly . [x0 y0 x1 y1 ...]) where each pair in the
30837 vector describes one corner in the polygon.
30838 Returns the alist element for the first matching AREA in MAP. */)
30839 (Lisp_Object map, Lisp_Object x, Lisp_Object y)
30841 if (NILP (map))
30842 return Qnil;
30844 CHECK_NUMBER (x);
30845 CHECK_NUMBER (y);
30847 return find_hot_spot (map,
30848 clip_to_bounds (INT_MIN, XINT (x), INT_MAX),
30849 clip_to_bounds (INT_MIN, XINT (y), INT_MAX));
30851 #endif /* HAVE_WINDOW_SYSTEM */
30854 /* Display frame CURSOR, optionally using shape defined by POINTER. */
30855 static void
30856 define_frame_cursor1 (struct frame *f, Cursor cursor, Lisp_Object pointer)
30858 #ifdef HAVE_WINDOW_SYSTEM
30859 if (!FRAME_WINDOW_P (f))
30860 return;
30862 /* Do not change cursor shape while dragging mouse. */
30863 if (EQ (do_mouse_tracking, Qdragging))
30864 return;
30866 if (!NILP (pointer))
30868 if (EQ (pointer, Qarrow))
30869 cursor = FRAME_X_OUTPUT (f)->nontext_cursor;
30870 else if (EQ (pointer, Qhand))
30871 cursor = FRAME_X_OUTPUT (f)->hand_cursor;
30872 else if (EQ (pointer, Qtext))
30873 cursor = FRAME_X_OUTPUT (f)->text_cursor;
30874 else if (EQ (pointer, intern ("hdrag")))
30875 cursor = FRAME_X_OUTPUT (f)->horizontal_drag_cursor;
30876 else if (EQ (pointer, intern ("nhdrag")))
30877 cursor = FRAME_X_OUTPUT (f)->vertical_drag_cursor;
30878 # ifdef HAVE_X_WINDOWS
30879 else if (EQ (pointer, intern ("vdrag")))
30880 cursor = FRAME_DISPLAY_INFO (f)->vertical_scroll_bar_cursor;
30881 # endif
30882 else if (EQ (pointer, intern ("hourglass")))
30883 cursor = FRAME_X_OUTPUT (f)->hourglass_cursor;
30884 else if (EQ (pointer, Qmodeline))
30885 cursor = FRAME_X_OUTPUT (f)->modeline_cursor;
30886 else
30887 cursor = FRAME_X_OUTPUT (f)->nontext_cursor;
30890 if (cursor != No_Cursor)
30891 FRAME_RIF (f)->define_frame_cursor (f, cursor);
30892 #endif
30895 /* Take proper action when mouse has moved to the mode or header line
30896 or marginal area AREA of window W, x-position X and y-position Y.
30897 X is relative to the start of the text display area of W, so the
30898 width of bitmap areas and scroll bars must be subtracted to get a
30899 position relative to the start of the mode line. */
30901 static void
30902 note_mode_line_or_margin_highlight (Lisp_Object window, int x, int y,
30903 enum window_part area)
30905 struct window *w = XWINDOW (window);
30906 struct frame *f = XFRAME (w->frame);
30907 Mouse_HLInfo *hlinfo = MOUSE_HL_INFO (f);
30908 Cursor cursor = No_Cursor;
30909 Lisp_Object pointer = Qnil;
30910 int dx, dy, width, height;
30911 ptrdiff_t charpos;
30912 Lisp_Object string, object = Qnil;
30913 Lisp_Object pos UNINIT;
30914 Lisp_Object mouse_face;
30915 int original_x_pixel = x;
30916 struct glyph * glyph = NULL, * row_start_glyph = NULL;
30917 struct glyph_row *row UNINIT;
30919 if (area == ON_MODE_LINE || area == ON_HEADER_LINE)
30921 int x0;
30922 struct glyph *end;
30924 /* Kludge alert: mode_line_string takes X/Y in pixels, but
30925 returns them in row/column units! */
30926 string = mode_line_string (w, area, &x, &y, &charpos,
30927 &object, &dx, &dy, &width, &height);
30929 row = (area == ON_MODE_LINE
30930 ? MATRIX_MODE_LINE_ROW (w->current_matrix)
30931 : MATRIX_HEADER_LINE_ROW (w->current_matrix));
30933 /* Find the glyph under the mouse pointer. */
30934 if (row->mode_line_p && row->enabled_p)
30936 glyph = row_start_glyph = row->glyphs[TEXT_AREA];
30937 end = glyph + row->used[TEXT_AREA];
30939 for (x0 = original_x_pixel;
30940 glyph < end && x0 >= glyph->pixel_width;
30941 ++glyph)
30942 x0 -= glyph->pixel_width;
30944 if (glyph >= end)
30945 glyph = NULL;
30948 else
30950 x -= WINDOW_LEFT_SCROLL_BAR_AREA_WIDTH (w);
30951 /* Kludge alert: marginal_area_string takes X/Y in pixels, but
30952 returns them in row/column units! */
30953 string = marginal_area_string (w, area, &x, &y, &charpos,
30954 &object, &dx, &dy, &width, &height);
30957 Lisp_Object help = Qnil;
30959 #ifdef HAVE_WINDOW_SYSTEM
30960 if (IMAGEP (object))
30962 Lisp_Object image_map, hotspot;
30963 if ((image_map = Fplist_get (XCDR (object), QCmap),
30964 !NILP (image_map))
30965 && (hotspot = find_hot_spot (image_map, dx, dy),
30966 CONSP (hotspot))
30967 && (hotspot = XCDR (hotspot), CONSP (hotspot)))
30969 Lisp_Object plist;
30971 /* Could check XCAR (hotspot) to see if we enter/leave this hot-spot.
30972 If so, we could look for mouse-enter, mouse-leave
30973 properties in PLIST (and do something...). */
30974 hotspot = XCDR (hotspot);
30975 if (CONSP (hotspot)
30976 && (plist = XCAR (hotspot), CONSP (plist)))
30978 pointer = Fplist_get (plist, Qpointer);
30979 if (NILP (pointer))
30980 pointer = Qhand;
30981 help = Fplist_get (plist, Qhelp_echo);
30982 if (!NILP (help))
30984 help_echo_string = help;
30985 XSETWINDOW (help_echo_window, w);
30986 help_echo_object = w->contents;
30987 help_echo_pos = charpos;
30991 if (NILP (pointer))
30992 pointer = Fplist_get (XCDR (object), QCpointer);
30994 #endif /* HAVE_WINDOW_SYSTEM */
30996 if (STRINGP (string))
30997 pos = make_number (charpos);
30999 /* Set the help text and mouse pointer. If the mouse is on a part
31000 of the mode line without any text (e.g. past the right edge of
31001 the mode line text), use that windows's mode line help echo if it
31002 has been set. */
31003 if (STRINGP (string) || area == ON_MODE_LINE)
31005 /* Arrange to display the help by setting the global variables
31006 help_echo_string, help_echo_object, and help_echo_pos. */
31007 if (NILP (help))
31009 if (STRINGP (string))
31010 help = Fget_text_property (pos, Qhelp_echo, string);
31012 if (!NILP (help))
31014 help_echo_string = help;
31015 XSETWINDOW (help_echo_window, w);
31016 help_echo_object = string;
31017 help_echo_pos = charpos;
31019 else if (area == ON_MODE_LINE
31020 && !NILP (w->mode_line_help_echo))
31022 help_echo_string = w->mode_line_help_echo;
31023 XSETWINDOW (help_echo_window, w);
31024 help_echo_object = Qnil;
31025 help_echo_pos = -1;
31029 #ifdef HAVE_WINDOW_SYSTEM
31030 /* Change the mouse pointer according to what is under it. */
31031 if (FRAME_WINDOW_P (f))
31033 bool draggable = (! WINDOW_BOTTOMMOST_P (w)
31034 || minibuf_level
31035 || NILP (Vresize_mini_windows));
31037 if (STRINGP (string))
31039 cursor = FRAME_X_OUTPUT (f)->nontext_cursor;
31041 if (NILP (pointer))
31042 pointer = Fget_text_property (pos, Qpointer, string);
31044 /* Change the mouse pointer according to what is under X/Y. */
31045 if (NILP (pointer)
31046 && (area == ON_MODE_LINE || area == ON_HEADER_LINE))
31048 Lisp_Object map;
31050 map = Fget_text_property (pos, Qlocal_map, string);
31051 if (!KEYMAPP (map))
31052 map = Fget_text_property (pos, Qkeymap, string);
31053 if (!KEYMAPP (map) && draggable && area == ON_MODE_LINE)
31054 cursor = FRAME_X_OUTPUT (f)->vertical_drag_cursor;
31057 else if (draggable && area == ON_MODE_LINE)
31058 cursor = FRAME_X_OUTPUT (f)->vertical_drag_cursor;
31059 else
31060 cursor = FRAME_X_OUTPUT (f)->nontext_cursor;
31062 #endif
31065 /* Change the mouse face according to what is under X/Y. */
31066 bool mouse_face_shown = false;
31068 if (STRINGP (string))
31070 mouse_face = Fget_text_property (pos, Qmouse_face, string);
31071 if (!NILP (Vmouse_highlight) && !NILP (mouse_face)
31072 && ((area == ON_MODE_LINE) || (area == ON_HEADER_LINE))
31073 && glyph)
31075 Lisp_Object b, e;
31077 struct glyph * tmp_glyph;
31079 int gpos;
31080 int gseq_length;
31081 int total_pixel_width;
31082 ptrdiff_t begpos, endpos, ignore;
31084 int vpos, hpos;
31086 b = Fprevious_single_property_change (make_number (charpos + 1),
31087 Qmouse_face, string, Qnil);
31088 if (NILP (b))
31089 begpos = 0;
31090 else
31091 begpos = XINT (b);
31093 e = Fnext_single_property_change (pos, Qmouse_face, string, Qnil);
31094 if (NILP (e))
31095 endpos = SCHARS (string);
31096 else
31097 endpos = XINT (e);
31099 /* Calculate the glyph position GPOS of GLYPH in the
31100 displayed string, relative to the beginning of the
31101 highlighted part of the string.
31103 Note: GPOS is different from CHARPOS. CHARPOS is the
31104 position of GLYPH in the internal string object. A mode
31105 line string format has structures which are converted to
31106 a flattened string by the Emacs Lisp interpreter. The
31107 internal string is an element of those structures. The
31108 displayed string is the flattened string. */
31109 tmp_glyph = row_start_glyph;
31110 while (tmp_glyph < glyph
31111 && (!(EQ (tmp_glyph->object, glyph->object)
31112 && begpos <= tmp_glyph->charpos
31113 && tmp_glyph->charpos < endpos)))
31114 tmp_glyph++;
31115 gpos = glyph - tmp_glyph;
31117 /* Calculate the length GSEQ_LENGTH of the glyph sequence of
31118 the highlighted part of the displayed string to which
31119 GLYPH belongs. Note: GSEQ_LENGTH is different from
31120 SCHARS (STRING), because the latter returns the length of
31121 the internal string. */
31122 for (tmp_glyph = row->glyphs[TEXT_AREA] + row->used[TEXT_AREA] - 1;
31123 tmp_glyph > glyph
31124 && (!(EQ (tmp_glyph->object, glyph->object)
31125 && begpos <= tmp_glyph->charpos
31126 && tmp_glyph->charpos < endpos));
31127 tmp_glyph--)
31129 gseq_length = gpos + (tmp_glyph - glyph) + 1;
31131 /* Calculate the total pixel width of all the glyphs between
31132 the beginning of the highlighted area and GLYPH. */
31133 total_pixel_width = 0;
31134 for (tmp_glyph = glyph - gpos; tmp_glyph != glyph; tmp_glyph++)
31135 total_pixel_width += tmp_glyph->pixel_width;
31137 /* Pre calculation of re-rendering position. Note: X is in
31138 column units here, after the call to mode_line_string or
31139 marginal_area_string. */
31140 hpos = x - gpos;
31141 vpos = (area == ON_MODE_LINE
31142 ? (w->current_matrix)->nrows - 1
31143 : 0);
31145 /* If GLYPH's position is included in the region that is
31146 already drawn in mouse face, we have nothing to do. */
31147 if ( EQ (window, hlinfo->mouse_face_window)
31148 && (!row->reversed_p
31149 ? (hlinfo->mouse_face_beg_col <= hpos
31150 && hpos < hlinfo->mouse_face_end_col)
31151 /* In R2L rows we swap BEG and END, see below. */
31152 : (hlinfo->mouse_face_end_col <= hpos
31153 && hpos < hlinfo->mouse_face_beg_col))
31154 && hlinfo->mouse_face_beg_row == vpos )
31155 return;
31157 if (clear_mouse_face (hlinfo))
31158 cursor = No_Cursor;
31160 if (!row->reversed_p)
31162 hlinfo->mouse_face_beg_col = hpos;
31163 hlinfo->mouse_face_beg_x = original_x_pixel
31164 - (total_pixel_width + dx);
31165 hlinfo->mouse_face_end_col = hpos + gseq_length;
31166 hlinfo->mouse_face_end_x = 0;
31168 else
31170 /* In R2L rows, show_mouse_face expects BEG and END
31171 coordinates to be swapped. */
31172 hlinfo->mouse_face_end_col = hpos;
31173 hlinfo->mouse_face_end_x = original_x_pixel
31174 - (total_pixel_width + dx);
31175 hlinfo->mouse_face_beg_col = hpos + gseq_length;
31176 hlinfo->mouse_face_beg_x = 0;
31179 hlinfo->mouse_face_beg_row = vpos;
31180 hlinfo->mouse_face_end_row = hlinfo->mouse_face_beg_row;
31181 hlinfo->mouse_face_past_end = false;
31182 hlinfo->mouse_face_window = window;
31184 hlinfo->mouse_face_face_id = face_at_string_position (w, string,
31185 charpos,
31186 0, &ignore,
31187 glyph->face_id,
31188 true);
31189 show_mouse_face (hlinfo, DRAW_MOUSE_FACE);
31190 mouse_face_shown = true;
31192 if (NILP (pointer))
31193 pointer = Qhand;
31197 /* If mouse-face doesn't need to be shown, clear any existing
31198 mouse-face. */
31199 if ((area == ON_MODE_LINE || area == ON_HEADER_LINE) && !mouse_face_shown)
31200 clear_mouse_face (hlinfo);
31202 define_frame_cursor1 (f, cursor, pointer);
31206 /* EXPORT:
31207 Take proper action when the mouse has moved to position X, Y on
31208 frame F with regards to highlighting portions of display that have
31209 mouse-face properties. Also de-highlight portions of display where
31210 the mouse was before, set the mouse pointer shape as appropriate
31211 for the mouse coordinates, and activate help echo (tooltips).
31212 X and Y can be negative or out of range. */
31214 void
31215 note_mouse_highlight (struct frame *f, int x, int y)
31217 Mouse_HLInfo *hlinfo = MOUSE_HL_INFO (f);
31218 enum window_part part = ON_NOTHING;
31219 Lisp_Object window;
31220 struct window *w;
31221 Cursor cursor = No_Cursor;
31222 Lisp_Object pointer = Qnil; /* Takes precedence over cursor! */
31223 struct buffer *b;
31225 /* When a menu is active, don't highlight because this looks odd. */
31226 #if defined (USE_X_TOOLKIT) || defined (USE_GTK) || defined (HAVE_NS) || defined (MSDOS)
31227 if (popup_activated ())
31228 return;
31229 #endif
31231 if (!f->glyphs_initialized_p
31232 || f->pointer_invisible)
31233 return;
31235 hlinfo->mouse_face_mouse_x = x;
31236 hlinfo->mouse_face_mouse_y = y;
31237 hlinfo->mouse_face_mouse_frame = f;
31239 if (hlinfo->mouse_face_defer)
31240 return;
31242 /* Which window is that in? */
31243 window = window_from_coordinates (f, x, y, &part, true);
31245 /* If displaying active text in another window, clear that. */
31246 if (! EQ (window, hlinfo->mouse_face_window)
31247 /* Also clear if we move out of text area in same window. */
31248 || (!NILP (hlinfo->mouse_face_window)
31249 && !NILP (window)
31250 && part != ON_TEXT
31251 && part != ON_MODE_LINE
31252 && part != ON_HEADER_LINE))
31253 clear_mouse_face (hlinfo);
31255 /* Reset help_echo_string. It will get recomputed below. */
31256 help_echo_string = Qnil;
31258 #ifdef HAVE_WINDOW_SYSTEM
31259 /* If the cursor is on the internal border of FRAME and FRAME's
31260 internal border is draggable, provide some visual feedback. */
31261 if (FRAME_INTERNAL_BORDER_WIDTH (f) > 0
31262 && !NILP (get_frame_param (f, Qdrag_internal_border)))
31264 enum internal_border_part part = frame_internal_border_part (f, x, y);
31266 switch (part)
31268 case INTERNAL_BORDER_NONE:
31269 if (cursor != FRAME_X_OUTPUT (f)->nontext_cursor)
31270 /* Reset cursor. */
31271 cursor = FRAME_X_OUTPUT (f)->nontext_cursor;
31272 break;
31273 case INTERNAL_BORDER_LEFT_EDGE:
31274 cursor = FRAME_X_OUTPUT (f)->left_edge_cursor;
31275 break;
31276 case INTERNAL_BORDER_TOP_LEFT_CORNER:
31277 cursor = FRAME_X_OUTPUT (f)->top_left_corner_cursor;
31278 break;
31279 case INTERNAL_BORDER_TOP_EDGE:
31280 cursor = FRAME_X_OUTPUT (f)->top_edge_cursor;
31281 break;
31282 case INTERNAL_BORDER_TOP_RIGHT_CORNER:
31283 cursor = FRAME_X_OUTPUT (f)->top_right_corner_cursor;
31284 break;
31285 case INTERNAL_BORDER_RIGHT_EDGE:
31286 cursor = FRAME_X_OUTPUT (f)->right_edge_cursor;
31287 break;
31288 case INTERNAL_BORDER_BOTTOM_RIGHT_CORNER:
31289 cursor = FRAME_X_OUTPUT (f)->bottom_right_corner_cursor;
31290 break;
31291 case INTERNAL_BORDER_BOTTOM_EDGE:
31292 cursor = FRAME_X_OUTPUT (f)->bottom_edge_cursor;
31293 break;
31294 case INTERNAL_BORDER_BOTTOM_LEFT_CORNER:
31295 cursor = FRAME_X_OUTPUT (f)->bottom_left_corner_cursor;
31296 break;
31297 default:
31298 /* This should not happen. */
31299 if (cursor != FRAME_X_OUTPUT (f)->nontext_cursor)
31300 cursor = FRAME_X_OUTPUT (f)->nontext_cursor;
31303 if (cursor != FRAME_X_OUTPUT (f)->nontext_cursor)
31305 /* Do we really want a help echo here? */
31306 help_echo_string = build_string ("drag-mouse-1: resize frame");
31307 goto set_cursor;
31310 #endif /* HAVE_WINDOW_SYSTEM */
31312 /* Not on a window -> return. */
31313 if (!WINDOWP (window))
31314 return;
31316 /* Convert to window-relative pixel coordinates. */
31317 w = XWINDOW (window);
31318 frame_to_window_pixel_xy (w, &x, &y);
31320 #if defined (HAVE_WINDOW_SYSTEM) && ! defined (USE_GTK) && ! defined (HAVE_NS)
31321 /* Handle tool-bar window differently since it doesn't display a
31322 buffer. */
31323 if (EQ (window, f->tool_bar_window))
31325 note_tool_bar_highlight (f, x, y);
31326 return;
31328 #endif
31330 /* Mouse is on the mode, header line or margin? */
31331 if (part == ON_MODE_LINE || part == ON_HEADER_LINE
31332 || part == ON_LEFT_MARGIN || part == ON_RIGHT_MARGIN)
31334 note_mode_line_or_margin_highlight (window, x, y, part);
31336 #ifdef HAVE_WINDOW_SYSTEM
31337 if (part == ON_LEFT_MARGIN || part == ON_RIGHT_MARGIN)
31339 cursor = FRAME_X_OUTPUT (f)->nontext_cursor;
31340 /* Show non-text cursor (Bug#16647). */
31341 goto set_cursor;
31343 else
31344 #endif
31345 return;
31348 #ifdef HAVE_WINDOW_SYSTEM
31349 if (part == ON_VERTICAL_BORDER)
31351 cursor = FRAME_X_OUTPUT (f)->horizontal_drag_cursor;
31352 help_echo_string = build_string ("drag-mouse-1: resize");
31353 goto set_cursor;
31355 else if (part == ON_RIGHT_DIVIDER)
31357 cursor = FRAME_X_OUTPUT (f)->horizontal_drag_cursor;
31358 help_echo_string = build_string ("drag-mouse-1: resize");
31359 goto set_cursor;
31361 else if (part == ON_BOTTOM_DIVIDER)
31362 if (! WINDOW_BOTTOMMOST_P (w)
31363 || minibuf_level
31364 || NILP (Vresize_mini_windows))
31366 cursor = FRAME_X_OUTPUT (f)->vertical_drag_cursor;
31367 help_echo_string = build_string ("drag-mouse-1: resize");
31368 goto set_cursor;
31370 else
31371 cursor = FRAME_X_OUTPUT (f)->nontext_cursor;
31372 else if (part == ON_LEFT_FRINGE || part == ON_RIGHT_FRINGE
31373 || part == ON_VERTICAL_SCROLL_BAR
31374 || part == ON_HORIZONTAL_SCROLL_BAR)
31375 cursor = FRAME_X_OUTPUT (f)->nontext_cursor;
31376 else
31377 cursor = FRAME_X_OUTPUT (f)->text_cursor;
31378 #endif
31380 /* Are we in a window whose display is up to date?
31381 And verify the buffer's text has not changed. */
31382 b = XBUFFER (w->contents);
31383 if (part == ON_TEXT && w->window_end_valid && !window_outdated (w))
31385 int hpos, vpos, dx, dy, area = LAST_AREA;
31386 ptrdiff_t pos;
31387 struct glyph *glyph;
31388 Lisp_Object object;
31389 Lisp_Object mouse_face = Qnil, position;
31390 Lisp_Object *overlay_vec = NULL;
31391 ptrdiff_t i, noverlays;
31392 struct buffer *obuf;
31393 ptrdiff_t obegv, ozv;
31394 bool same_region;
31396 /* Find the glyph under X/Y. */
31397 glyph = x_y_to_hpos_vpos (w, x, y, &hpos, &vpos, &dx, &dy, &area);
31399 #ifdef HAVE_WINDOW_SYSTEM
31400 /* Look for :pointer property on image. */
31401 if (glyph != NULL && glyph->type == IMAGE_GLYPH)
31403 struct image *img = IMAGE_OPT_FROM_ID (f, glyph->u.img_id);
31404 if (img != NULL && IMAGEP (img->spec))
31406 Lisp_Object image_map, hotspot;
31407 if ((image_map = Fplist_get (XCDR (img->spec), QCmap),
31408 !NILP (image_map))
31409 && (hotspot = find_hot_spot (image_map,
31410 glyph->slice.img.x + dx,
31411 glyph->slice.img.y + dy),
31412 CONSP (hotspot))
31413 && (hotspot = XCDR (hotspot), CONSP (hotspot)))
31415 Lisp_Object plist;
31417 /* Could check XCAR (hotspot) to see if we enter/leave
31418 this hot-spot.
31419 If so, we could look for mouse-enter, mouse-leave
31420 properties in PLIST (and do something...). */
31421 hotspot = XCDR (hotspot);
31422 if (CONSP (hotspot)
31423 && (plist = XCAR (hotspot), CONSP (plist)))
31425 pointer = Fplist_get (plist, Qpointer);
31426 if (NILP (pointer))
31427 pointer = Qhand;
31428 help_echo_string = Fplist_get (plist, Qhelp_echo);
31429 if (!NILP (help_echo_string))
31431 help_echo_window = window;
31432 help_echo_object = glyph->object;
31433 help_echo_pos = glyph->charpos;
31437 if (NILP (pointer))
31438 pointer = Fplist_get (XCDR (img->spec), QCpointer);
31441 #endif /* HAVE_WINDOW_SYSTEM */
31443 /* Clear mouse face if X/Y not over text. */
31444 if (glyph == NULL
31445 || area != TEXT_AREA
31446 || !MATRIX_ROW_DISPLAYS_TEXT_P (MATRIX_ROW (w->current_matrix, vpos))
31447 /* Glyph's OBJECT is nil for glyphs inserted by the
31448 display engine for its internal purposes, like truncation
31449 and continuation glyphs and blanks beyond the end of
31450 line's text on text terminals. If we are over such a
31451 glyph, we are not over any text. */
31452 || NILP (glyph->object)
31453 /* R2L rows have a stretch glyph at their front, which
31454 stands for no text, whereas L2R rows have no glyphs at
31455 all beyond the end of text. Treat such stretch glyphs
31456 like we do with NULL glyphs in L2R rows. */
31457 || (MATRIX_ROW (w->current_matrix, vpos)->reversed_p
31458 && glyph == MATRIX_ROW_GLYPH_START (w->current_matrix, vpos)
31459 && glyph->type == STRETCH_GLYPH
31460 && glyph->avoid_cursor_p))
31462 if (clear_mouse_face (hlinfo))
31463 cursor = No_Cursor;
31464 if (FRAME_WINDOW_P (f) && NILP (pointer))
31466 #ifdef HAVE_WINDOW_SYSTEM
31467 if (area != TEXT_AREA)
31468 cursor = FRAME_X_OUTPUT (f)->nontext_cursor;
31469 else
31470 pointer = Vvoid_text_area_pointer;
31471 #endif
31473 goto set_cursor;
31476 pos = glyph->charpos;
31477 object = glyph->object;
31478 if (!STRINGP (object) && !BUFFERP (object))
31479 goto set_cursor;
31481 /* If we get an out-of-range value, return now; avoid an error. */
31482 if (BUFFERP (object) && pos > BUF_Z (b))
31483 goto set_cursor;
31485 /* Make the window's buffer temporarily current for
31486 overlays_at and compute_char_face. */
31487 obuf = current_buffer;
31488 current_buffer = b;
31489 obegv = BEGV;
31490 ozv = ZV;
31491 BEGV = BEG;
31492 ZV = Z;
31494 /* Is this char mouse-active or does it have help-echo? */
31495 position = make_number (pos);
31497 USE_SAFE_ALLOCA;
31499 if (BUFFERP (object))
31501 /* Put all the overlays we want in a vector in overlay_vec. */
31502 GET_OVERLAYS_AT (pos, overlay_vec, noverlays, NULL, false);
31503 /* Sort overlays into increasing priority order. */
31504 noverlays = sort_overlays (overlay_vec, noverlays, w);
31506 else
31507 noverlays = 0;
31509 if (NILP (Vmouse_highlight))
31511 clear_mouse_face (hlinfo);
31512 goto check_help_echo;
31515 same_region = coords_in_mouse_face_p (w, hpos, vpos);
31517 if (same_region)
31518 cursor = No_Cursor;
31520 /* Check mouse-face highlighting. */
31521 if (! same_region
31522 /* If there exists an overlay with mouse-face overlapping
31523 the one we are currently highlighting, we have to check
31524 if we enter the overlapping overlay, and then highlight
31525 only that. Skip the check when mouse-face highlighting
31526 is currently hidden to avoid Bug#30519. */
31527 || (!hlinfo->mouse_face_hidden
31528 && OVERLAYP (hlinfo->mouse_face_overlay)
31529 && mouse_face_overlay_overlaps (hlinfo->mouse_face_overlay)))
31531 /* Find the highest priority overlay with a mouse-face. */
31532 Lisp_Object overlay = Qnil;
31533 for (i = noverlays - 1; i >= 0 && NILP (overlay); --i)
31535 mouse_face = Foverlay_get (overlay_vec[i], Qmouse_face);
31536 if (!NILP (mouse_face))
31537 overlay = overlay_vec[i];
31540 /* If we're highlighting the same overlay as before, there's
31541 no need to do that again. */
31542 if (!NILP (overlay) && EQ (overlay, hlinfo->mouse_face_overlay))
31543 goto check_help_echo;
31545 /* Clear the display of the old active region, if any. */
31546 if (clear_mouse_face (hlinfo))
31547 cursor = No_Cursor;
31549 /* Record the overlay, if any, to be highlighted. */
31550 hlinfo->mouse_face_overlay = overlay;
31552 /* If no overlay applies, get a text property. */
31553 if (NILP (overlay))
31554 mouse_face = Fget_text_property (position, Qmouse_face, object);
31556 /* Next, compute the bounds of the mouse highlighting and
31557 display it. */
31558 if (!NILP (mouse_face) && STRINGP (object))
31560 /* The mouse-highlighting comes from a display string
31561 with a mouse-face. */
31562 Lisp_Object s, e;
31563 ptrdiff_t ignore;
31565 s = Fprevious_single_property_change
31566 (make_number (pos + 1), Qmouse_face, object, Qnil);
31567 e = Fnext_single_property_change
31568 (position, Qmouse_face, object, Qnil);
31569 if (NILP (s))
31570 s = make_number (0);
31571 if (NILP (e))
31572 e = make_number (SCHARS (object));
31573 mouse_face_from_string_pos (w, hlinfo, object,
31574 XINT (s), XINT (e));
31575 hlinfo->mouse_face_past_end = false;
31576 hlinfo->mouse_face_window = window;
31577 hlinfo->mouse_face_face_id
31578 = face_at_string_position (w, object, pos, 0, &ignore,
31579 glyph->face_id, true);
31580 show_mouse_face (hlinfo, DRAW_MOUSE_FACE);
31581 cursor = No_Cursor;
31583 else
31585 /* The mouse-highlighting, if any, comes from an overlay
31586 or text property in the buffer. */
31587 Lisp_Object buffer UNINIT;
31588 Lisp_Object disp_string UNINIT;
31590 if (STRINGP (object))
31592 /* If we are on a display string with no mouse-face,
31593 check if the text under it has one. */
31594 struct glyph_row *r = MATRIX_ROW (w->current_matrix, vpos);
31595 ptrdiff_t start = MATRIX_ROW_START_CHARPOS (r);
31596 pos = string_buffer_position (object, start);
31597 if (pos > 0)
31599 mouse_face = get_char_property_and_overlay
31600 (make_number (pos), Qmouse_face, w->contents, &overlay);
31601 buffer = w->contents;
31602 disp_string = object;
31605 else
31607 buffer = object;
31608 disp_string = Qnil;
31611 if (!NILP (mouse_face))
31613 Lisp_Object before, after;
31614 Lisp_Object before_string, after_string;
31615 /* To correctly find the limits of mouse highlight
31616 in a bidi-reordered buffer, we must not use the
31617 optimization of limiting the search in
31618 previous-single-property-change and
31619 next-single-property-change, because
31620 rows_from_pos_range needs the real start and end
31621 positions to DTRT in this case. That's because
31622 the first row visible in a window does not
31623 necessarily display the character whose position
31624 is the smallest. */
31625 Lisp_Object lim1
31626 = NILP (BVAR (XBUFFER (buffer), bidi_display_reordering))
31627 ? Fmarker_position (w->start)
31628 : Qnil;
31629 Lisp_Object lim2
31630 = NILP (BVAR (XBUFFER (buffer), bidi_display_reordering))
31631 ? make_number (BUF_Z (XBUFFER (buffer))
31632 - w->window_end_pos)
31633 : Qnil;
31635 if (NILP (overlay))
31637 /* Handle the text property case. */
31638 before = Fprevious_single_property_change
31639 (make_number (pos + 1), Qmouse_face, buffer, lim1);
31640 after = Fnext_single_property_change
31641 (make_number (pos), Qmouse_face, buffer, lim2);
31642 before_string = after_string = Qnil;
31644 else
31646 /* Handle the overlay case. */
31647 before = Foverlay_start (overlay);
31648 after = Foverlay_end (overlay);
31649 before_string = Foverlay_get (overlay, Qbefore_string);
31650 after_string = Foverlay_get (overlay, Qafter_string);
31652 if (!STRINGP (before_string)) before_string = Qnil;
31653 if (!STRINGP (after_string)) after_string = Qnil;
31656 mouse_face_from_buffer_pos (window, hlinfo, pos,
31657 NILP (before)
31659 : XFASTINT (before),
31660 NILP (after)
31661 ? BUF_Z (XBUFFER (buffer))
31662 : XFASTINT (after),
31663 before_string, after_string,
31664 disp_string);
31665 cursor = No_Cursor;
31670 check_help_echo:
31672 /* Look for a `help-echo' property. */
31673 if (NILP (help_echo_string)) {
31674 Lisp_Object help, overlay;
31676 /* Check overlays first. */
31677 help = overlay = Qnil;
31678 for (i = noverlays - 1; i >= 0 && NILP (help); --i)
31680 overlay = overlay_vec[i];
31681 help = Foverlay_get (overlay, Qhelp_echo);
31684 if (!NILP (help))
31686 help_echo_string = help;
31687 help_echo_window = window;
31688 help_echo_object = overlay;
31689 help_echo_pos = pos;
31691 else
31693 Lisp_Object obj = glyph->object;
31694 ptrdiff_t charpos = glyph->charpos;
31696 /* Try text properties. */
31697 if (STRINGP (obj)
31698 && charpos >= 0
31699 && charpos < SCHARS (obj))
31701 help = Fget_text_property (make_number (charpos),
31702 Qhelp_echo, obj);
31703 if (NILP (help))
31705 /* If the string itself doesn't specify a help-echo,
31706 see if the buffer text ``under'' it does. */
31707 struct glyph_row *r
31708 = MATRIX_ROW (w->current_matrix, vpos);
31709 ptrdiff_t start = MATRIX_ROW_START_CHARPOS (r);
31710 ptrdiff_t p = string_buffer_position (obj, start);
31711 if (p > 0)
31713 help = Fget_char_property (make_number (p),
31714 Qhelp_echo, w->contents);
31715 if (!NILP (help))
31717 charpos = p;
31718 obj = w->contents;
31723 else if (BUFFERP (obj)
31724 && charpos >= BEGV
31725 && charpos < ZV)
31726 help = Fget_text_property (make_number (charpos), Qhelp_echo,
31727 obj);
31729 if (!NILP (help))
31731 help_echo_string = help;
31732 help_echo_window = window;
31733 help_echo_object = obj;
31734 help_echo_pos = charpos;
31739 #ifdef HAVE_WINDOW_SYSTEM
31740 /* Look for a `pointer' property. */
31741 if (FRAME_WINDOW_P (f) && NILP (pointer))
31743 /* Check overlays first. */
31744 for (i = noverlays - 1; i >= 0 && NILP (pointer); --i)
31745 pointer = Foverlay_get (overlay_vec[i], Qpointer);
31747 if (NILP (pointer))
31749 Lisp_Object obj = glyph->object;
31750 ptrdiff_t charpos = glyph->charpos;
31752 /* Try text properties. */
31753 if (STRINGP (obj)
31754 && charpos >= 0
31755 && charpos < SCHARS (obj))
31757 pointer = Fget_text_property (make_number (charpos),
31758 Qpointer, obj);
31759 if (NILP (pointer))
31761 /* If the string itself doesn't specify a pointer,
31762 see if the buffer text ``under'' it does. */
31763 struct glyph_row *r
31764 = MATRIX_ROW (w->current_matrix, vpos);
31765 ptrdiff_t start = MATRIX_ROW_START_CHARPOS (r);
31766 ptrdiff_t p = string_buffer_position (obj, start);
31767 if (p > 0)
31768 pointer = Fget_char_property (make_number (p),
31769 Qpointer, w->contents);
31772 else if (BUFFERP (obj)
31773 && charpos >= BEGV
31774 && charpos < ZV)
31775 pointer = Fget_text_property (make_number (charpos),
31776 Qpointer, obj);
31779 #endif /* HAVE_WINDOW_SYSTEM */
31781 BEGV = obegv;
31782 ZV = ozv;
31783 current_buffer = obuf;
31784 SAFE_FREE ();
31787 set_cursor:
31788 define_frame_cursor1 (f, cursor, pointer);
31792 /* EXPORT for RIF:
31793 Clear any mouse-face on window W. This function is part of the
31794 redisplay interface, and is called from try_window_id and similar
31795 functions to ensure the mouse-highlight is off. */
31797 void
31798 x_clear_window_mouse_face (struct window *w)
31800 Mouse_HLInfo *hlinfo = MOUSE_HL_INFO (XFRAME (w->frame));
31801 Lisp_Object window;
31803 block_input ();
31804 XSETWINDOW (window, w);
31805 if (EQ (window, hlinfo->mouse_face_window))
31806 clear_mouse_face (hlinfo);
31807 unblock_input ();
31811 /* EXPORT:
31812 Just discard the mouse face information for frame F, if any.
31813 This is used when the size of F is changed. */
31815 void
31816 cancel_mouse_face (struct frame *f)
31818 Lisp_Object window;
31819 Mouse_HLInfo *hlinfo = MOUSE_HL_INFO (f);
31821 window = hlinfo->mouse_face_window;
31822 if (! NILP (window) && XFRAME (XWINDOW (window)->frame) == f)
31823 reset_mouse_highlight (hlinfo);
31828 /***********************************************************************
31829 Exposure Events
31830 ***********************************************************************/
31832 #ifdef HAVE_WINDOW_SYSTEM
31834 /* Redraw the part of glyph row area AREA of glyph row ROW on window W
31835 which intersects rectangle R. R is in window-relative coordinates. */
31837 static void
31838 expose_area (struct window *w, struct glyph_row *row, XRectangle *r,
31839 enum glyph_row_area area)
31841 struct glyph *first = row->glyphs[area];
31842 struct glyph *end = row->glyphs[area] + row->used[area];
31843 struct glyph *last;
31844 int first_x, start_x, x;
31846 if (area == TEXT_AREA && row->fill_line_p)
31847 /* If row extends face to end of line write the whole line. */
31848 draw_glyphs (w, 0, row, area,
31849 0, row->used[area],
31850 DRAW_NORMAL_TEXT, 0);
31851 else
31853 /* Set START_X to the window-relative start position for drawing glyphs of
31854 AREA. The first glyph of the text area can be partially visible.
31855 The first glyphs of other areas cannot. */
31856 start_x = window_box_left_offset (w, area);
31857 x = start_x;
31858 if (area == TEXT_AREA)
31859 x += row->x;
31861 /* Find the first glyph that must be redrawn. */
31862 while (first < end
31863 && x + first->pixel_width < r->x)
31865 x += first->pixel_width;
31866 ++first;
31869 /* Find the last one. */
31870 last = first;
31871 first_x = x;
31872 /* Use a signed int intermediate value to avoid catastrophic
31873 failures due to comparison between signed and unsigned, when
31874 x is negative (can happen for wide images that are hscrolled). */
31875 int r_end = r->x + r->width;
31876 while (last < end && x < r_end)
31878 x += last->pixel_width;
31879 ++last;
31882 /* Repaint. */
31883 if (last > first)
31884 draw_glyphs (w, first_x - start_x, row, area,
31885 first - row->glyphs[area], last - row->glyphs[area],
31886 DRAW_NORMAL_TEXT, 0);
31891 /* Redraw the parts of the glyph row ROW on window W intersecting
31892 rectangle R. R is in window-relative coordinates. Value is
31893 true if mouse-face was overwritten. */
31895 static bool
31896 expose_line (struct window *w, struct glyph_row *row, XRectangle *r)
31898 eassert (row->enabled_p);
31900 if (row->mode_line_p || w->pseudo_window_p)
31901 draw_glyphs (w, 0, row, TEXT_AREA,
31902 0, row->used[TEXT_AREA],
31903 DRAW_NORMAL_TEXT, 0);
31904 else
31906 if (row->used[LEFT_MARGIN_AREA])
31907 expose_area (w, row, r, LEFT_MARGIN_AREA);
31908 if (row->used[TEXT_AREA])
31909 expose_area (w, row, r, TEXT_AREA);
31910 if (row->used[RIGHT_MARGIN_AREA])
31911 expose_area (w, row, r, RIGHT_MARGIN_AREA);
31912 draw_row_fringe_bitmaps (w, row);
31915 return row->mouse_face_p;
31919 /* Redraw those parts of glyphs rows during expose event handling that
31920 overlap other rows. Redrawing of an exposed line writes over parts
31921 of lines overlapping that exposed line; this function fixes that.
31923 W is the window being exposed. FIRST_OVERLAPPING_ROW is the first
31924 row in W's current matrix that is exposed and overlaps other rows.
31925 LAST_OVERLAPPING_ROW is the last such row. */
31927 static void
31928 expose_overlaps (struct window *w,
31929 struct glyph_row *first_overlapping_row,
31930 struct glyph_row *last_overlapping_row,
31931 XRectangle *r)
31933 struct glyph_row *row;
31935 for (row = first_overlapping_row; row <= last_overlapping_row; ++row)
31936 if (row->overlapping_p)
31938 eassert (row->enabled_p && !row->mode_line_p);
31940 row->clip = r;
31941 if (row->used[LEFT_MARGIN_AREA])
31942 x_fix_overlapping_area (w, row, LEFT_MARGIN_AREA, OVERLAPS_BOTH);
31944 if (row->used[TEXT_AREA])
31945 x_fix_overlapping_area (w, row, TEXT_AREA, OVERLAPS_BOTH);
31947 if (row->used[RIGHT_MARGIN_AREA])
31948 x_fix_overlapping_area (w, row, RIGHT_MARGIN_AREA, OVERLAPS_BOTH);
31949 row->clip = NULL;
31954 /* Return true if W's cursor intersects rectangle R. */
31956 static bool
31957 phys_cursor_in_rect_p (struct window *w, XRectangle *r)
31959 XRectangle cr, result;
31960 struct glyph *cursor_glyph;
31961 struct glyph_row *row;
31963 if (w->phys_cursor.vpos >= 0
31964 && w->phys_cursor.vpos < w->current_matrix->nrows
31965 && (row = MATRIX_ROW (w->current_matrix, w->phys_cursor.vpos),
31966 row->enabled_p)
31967 && row->cursor_in_fringe_p)
31969 /* Cursor is in the fringe. */
31970 cr.x = window_box_right_offset (w,
31971 (WINDOW_HAS_FRINGES_OUTSIDE_MARGINS (w)
31972 ? RIGHT_MARGIN_AREA
31973 : TEXT_AREA));
31974 cr.y = row->y;
31975 cr.width = WINDOW_RIGHT_FRINGE_WIDTH (w);
31976 cr.height = row->height;
31977 return x_intersect_rectangles (&cr, r, &result);
31980 cursor_glyph = get_phys_cursor_glyph (w);
31981 if (cursor_glyph)
31983 /* r is relative to W's box, but w->phys_cursor.x is relative
31984 to left edge of W's TEXT area. Adjust it. */
31985 cr.x = window_box_left_offset (w, TEXT_AREA) + w->phys_cursor.x;
31986 cr.y = w->phys_cursor.y;
31987 cr.width = cursor_glyph->pixel_width;
31988 cr.height = w->phys_cursor_height;
31989 /* ++KFS: W32 version used W32-specific IntersectRect here, but
31990 I assume the effect is the same -- and this is portable. */
31991 return x_intersect_rectangles (&cr, r, &result);
31993 /* If we don't understand the format, pretend we're not in the hot-spot. */
31994 return false;
31998 /* EXPORT:
31999 Draw a vertical window border to the right of window W if W doesn't
32000 have vertical scroll bars. */
32002 void
32003 x_draw_vertical_border (struct window *w)
32005 struct frame *f = XFRAME (WINDOW_FRAME (w));
32007 /* We could do better, if we knew what type of scroll-bar the adjacent
32008 windows (on either side) have... But we don't :-(
32009 However, I think this works ok. ++KFS 2003-04-25 */
32011 /* Redraw borders between horizontally adjacent windows. Don't
32012 do it for frames with vertical scroll bars because either the
32013 right scroll bar of a window, or the left scroll bar of its
32014 neighbor will suffice as a border. */
32015 if (FRAME_HAS_VERTICAL_SCROLL_BARS (f) || FRAME_RIGHT_DIVIDER_WIDTH (f))
32016 return;
32018 /* Note: It is necessary to redraw both the left and the right
32019 borders, for when only this single window W is being
32020 redisplayed. */
32021 if (!WINDOW_RIGHTMOST_P (w)
32022 && !WINDOW_HAS_VERTICAL_SCROLL_BAR_ON_RIGHT (w))
32024 int x0, x1, y0, y1;
32026 window_box_edges (w, &x0, &y0, &x1, &y1);
32027 y1 -= 1;
32029 if (WINDOW_LEFT_FRINGE_WIDTH (w) == 0)
32030 x1 -= 1;
32032 FRAME_RIF (f)->draw_vertical_window_border (w, x1, y0, y1);
32035 if (!WINDOW_LEFTMOST_P (w)
32036 && !WINDOW_HAS_VERTICAL_SCROLL_BAR_ON_LEFT (w))
32038 int x0, x1, y0, y1;
32040 window_box_edges (w, &x0, &y0, &x1, &y1);
32041 y1 -= 1;
32043 if (WINDOW_LEFT_FRINGE_WIDTH (w) == 0)
32044 x0 -= 1;
32046 FRAME_RIF (f)->draw_vertical_window_border (w, x0, y0, y1);
32051 /* Draw window dividers for window W. */
32053 void
32054 x_draw_right_divider (struct window *w)
32056 struct frame *f = WINDOW_XFRAME (w);
32058 if (w->mini || w->pseudo_window_p)
32059 return;
32060 else if (WINDOW_RIGHT_DIVIDER_WIDTH (w))
32062 int x0 = WINDOW_RIGHT_EDGE_X (w) - WINDOW_RIGHT_DIVIDER_WIDTH (w);
32063 int x1 = WINDOW_RIGHT_EDGE_X (w);
32064 int y0 = WINDOW_TOP_EDGE_Y (w);
32065 int y1 = WINDOW_BOTTOM_EDGE_Y (w);
32067 /* If W is horizontally combined and has a right sibling, don't
32068 draw over any bottom divider. */
32069 if (WINDOW_BOTTOM_DIVIDER_WIDTH (w)
32070 && !NILP (w->parent)
32071 && WINDOW_HORIZONTAL_COMBINATION_P (XWINDOW (w->parent))
32072 && !NILP (w->next))
32073 y1 -= WINDOW_BOTTOM_DIVIDER_WIDTH (w);
32075 FRAME_RIF (f)->draw_window_divider (w, x0, x1, y0, y1);
32079 static void
32080 x_draw_bottom_divider (struct window *w)
32082 struct frame *f = XFRAME (WINDOW_FRAME (w));
32084 if (w->mini || w->pseudo_window_p)
32085 return;
32086 else if (WINDOW_BOTTOM_DIVIDER_WIDTH (w))
32088 int x0 = WINDOW_LEFT_EDGE_X (w);
32089 int x1 = WINDOW_RIGHT_EDGE_X (w);
32090 int y0 = WINDOW_BOTTOM_EDGE_Y (w) - WINDOW_BOTTOM_DIVIDER_WIDTH (w);
32091 int y1 = WINDOW_BOTTOM_EDGE_Y (w);
32092 struct window *p = !NILP (w->parent) ? XWINDOW (w->parent) : NULL;
32094 /* If W is vertically combined and has a sibling below, don't draw
32095 over any right divider. */
32096 if (WINDOW_RIGHT_DIVIDER_WIDTH (w)
32097 && p
32098 && ((WINDOW_VERTICAL_COMBINATION_P (p)
32099 && !NILP (w->next))
32100 || (WINDOW_HORIZONTAL_COMBINATION_P (p)
32101 && NILP (w->next)
32102 && !NILP (p->parent)
32103 && WINDOW_VERTICAL_COMBINATION_P (XWINDOW (p->parent))
32104 && !NILP (XWINDOW (p->parent)->next))))
32105 x1 -= WINDOW_RIGHT_DIVIDER_WIDTH (w);
32107 FRAME_RIF (f)->draw_window_divider (w, x0, x1, y0, y1);
32111 /* Redraw the part of window W intersection rectangle FR. Pixel
32112 coordinates in FR are frame-relative. Call this function with
32113 input blocked. Value is true if the exposure overwrites
32114 mouse-face. */
32116 static bool
32117 expose_window (struct window *w, XRectangle *fr)
32119 struct frame *f = XFRAME (w->frame);
32120 XRectangle wr, r;
32121 bool mouse_face_overwritten_p = false;
32123 /* If window is not yet fully initialized, do nothing. This can
32124 happen when toolkit scroll bars are used and a window is split.
32125 Reconfiguring the scroll bar will generate an expose for a newly
32126 created window. */
32127 if (w->current_matrix == NULL)
32128 return false;
32130 /* When we're currently updating the window, display and current
32131 matrix usually don't agree. Arrange for a thorough display
32132 later. */
32133 if (w->must_be_updated_p)
32135 SET_FRAME_GARBAGED (f);
32136 return false;
32139 /* Frame-relative pixel rectangle of W. */
32140 wr.x = WINDOW_LEFT_EDGE_X (w);
32141 wr.y = WINDOW_TOP_EDGE_Y (w);
32142 wr.width = WINDOW_PIXEL_WIDTH (w);
32143 wr.height = WINDOW_PIXEL_HEIGHT (w);
32145 if (x_intersect_rectangles (fr, &wr, &r))
32147 int yb = window_text_bottom_y (w);
32148 struct glyph_row *row;
32149 struct glyph_row *first_overlapping_row, *last_overlapping_row;
32151 TRACE ((stderr, "expose_window (%d, %d, %d, %d)\n",
32152 r.x, r.y, r.width, r.height));
32154 /* Convert to window coordinates. */
32155 r.x -= WINDOW_LEFT_EDGE_X (w);
32156 r.y -= WINDOW_TOP_EDGE_Y (w);
32158 /* Turn off the cursor. */
32159 bool cursor_cleared_p = (!w->pseudo_window_p
32160 && phys_cursor_in_rect_p (w, &r));
32161 if (cursor_cleared_p)
32162 x_clear_cursor (w);
32164 /* If the row containing the cursor extends face to end of line,
32165 then expose_area might overwrite the cursor outside the
32166 rectangle and thus notice_overwritten_cursor might clear
32167 w->phys_cursor_on_p. We remember the original value and
32168 check later if it is changed. */
32169 bool phys_cursor_on_p = w->phys_cursor_on_p;
32171 /* Use a signed int intermediate value to avoid catastrophic
32172 failures due to comparison between signed and unsigned, when
32173 y0 or y1 is negative (can happen for tall images). */
32174 int r_bottom = r.y + r.height;
32176 /* Update lines intersecting rectangle R. */
32177 first_overlapping_row = last_overlapping_row = NULL;
32178 for (row = w->current_matrix->rows;
32179 row->enabled_p;
32180 ++row)
32182 int y0 = row->y;
32183 int y1 = MATRIX_ROW_BOTTOM_Y (row);
32185 if ((y0 >= r.y && y0 < r_bottom)
32186 || (y1 > r.y && y1 < r_bottom)
32187 || (r.y >= y0 && r.y < y1)
32188 || (r_bottom > y0 && r_bottom < y1))
32190 /* A header line may be overlapping, but there is no need
32191 to fix overlapping areas for them. KFS 2005-02-12 */
32192 if (row->overlapping_p && !row->mode_line_p)
32194 if (first_overlapping_row == NULL)
32195 first_overlapping_row = row;
32196 last_overlapping_row = row;
32199 row->clip = fr;
32200 if (expose_line (w, row, &r))
32201 mouse_face_overwritten_p = true;
32202 row->clip = NULL;
32204 else if (row->overlapping_p)
32206 /* We must redraw a row overlapping the exposed area. */
32207 if (y0 < r.y
32208 ? y0 + row->phys_height > r.y
32209 : y0 + row->ascent - row->phys_ascent < r.y +r.height)
32211 if (first_overlapping_row == NULL)
32212 first_overlapping_row = row;
32213 last_overlapping_row = row;
32217 if (y1 >= yb)
32218 break;
32221 /* Display the mode line if there is one. */
32222 if (window_wants_mode_line (w)
32223 && (row = MATRIX_MODE_LINE_ROW (w->current_matrix),
32224 row->enabled_p)
32225 && row->y < r_bottom)
32227 if (expose_line (w, row, &r))
32228 mouse_face_overwritten_p = true;
32231 if (!w->pseudo_window_p)
32233 /* Fix the display of overlapping rows. */
32234 if (first_overlapping_row)
32235 expose_overlaps (w, first_overlapping_row, last_overlapping_row,
32236 fr);
32238 /* Draw border between windows. */
32239 if (WINDOW_RIGHT_DIVIDER_WIDTH (w))
32240 x_draw_right_divider (w);
32241 else
32242 x_draw_vertical_border (w);
32244 if (WINDOW_BOTTOM_DIVIDER_WIDTH (w))
32245 x_draw_bottom_divider (w);
32247 /* Turn the cursor on again. */
32248 if (cursor_cleared_p
32249 || (phys_cursor_on_p && !w->phys_cursor_on_p))
32250 update_window_cursor (w, true);
32254 return mouse_face_overwritten_p;
32259 /* Redraw (parts) of all windows in the window tree rooted at W that
32260 intersect R. R contains frame pixel coordinates. Value is
32261 true if the exposure overwrites mouse-face. */
32263 static bool
32264 expose_window_tree (struct window *w, XRectangle *r)
32266 struct frame *f = XFRAME (w->frame);
32267 bool mouse_face_overwritten_p = false;
32269 while (w && !FRAME_GARBAGED_P (f))
32271 mouse_face_overwritten_p
32272 |= (WINDOWP (w->contents)
32273 ? expose_window_tree (XWINDOW (w->contents), r)
32274 : expose_window (w, r));
32276 w = NILP (w->next) ? NULL : XWINDOW (w->next);
32279 return mouse_face_overwritten_p;
32283 /* EXPORT:
32284 Redisplay an exposed area of frame F. X and Y are the upper-left
32285 corner of the exposed rectangle. W and H are width and height of
32286 the exposed area. All are pixel values. W or H zero means redraw
32287 the entire frame. */
32289 void
32290 expose_frame (struct frame *f, int x, int y, int w, int h)
32292 XRectangle r;
32293 bool mouse_face_overwritten_p = false;
32295 TRACE ((stderr, "expose_frame "));
32297 /* No need to redraw if frame will be redrawn soon. */
32298 if (FRAME_GARBAGED_P (f))
32300 TRACE ((stderr, " garbaged\n"));
32301 return;
32304 /* If basic faces haven't been realized yet, there is no point in
32305 trying to redraw anything. This can happen when we get an expose
32306 event while Emacs is starting, e.g. by moving another window. */
32307 if (FRAME_FACE_CACHE (f) == NULL
32308 || FRAME_FACE_CACHE (f)->used < BASIC_FACE_ID_SENTINEL)
32310 TRACE ((stderr, " no faces\n"));
32311 return;
32314 if (w == 0 || h == 0)
32316 r.x = r.y = 0;
32317 r.width = FRAME_TEXT_WIDTH (f);
32318 r.height = FRAME_TEXT_HEIGHT (f);
32320 else
32322 r.x = x;
32323 r.y = y;
32324 r.width = w;
32325 r.height = h;
32328 TRACE ((stderr, "(%d, %d, %d, %d)\n", r.x, r.y, r.width, r.height));
32329 mouse_face_overwritten_p = expose_window_tree (XWINDOW (f->root_window), &r);
32331 #if ! defined (USE_GTK) && ! defined (HAVE_NS)
32332 if (WINDOWP (f->tool_bar_window))
32333 mouse_face_overwritten_p
32334 |= expose_window (XWINDOW (f->tool_bar_window), &r);
32335 #endif
32337 #ifdef HAVE_X_WINDOWS
32338 #ifndef MSDOS
32339 #if ! defined (USE_X_TOOLKIT) && ! defined (USE_GTK)
32340 if (WINDOWP (f->menu_bar_window))
32341 mouse_face_overwritten_p
32342 |= expose_window (XWINDOW (f->menu_bar_window), &r);
32343 #endif /* not USE_X_TOOLKIT and not USE_GTK */
32344 #endif
32345 #endif
32347 /* Some window managers support a focus-follows-mouse style with
32348 delayed raising of frames. Imagine a partially obscured frame,
32349 and moving the mouse into partially obscured mouse-face on that
32350 frame. The visible part of the mouse-face will be highlighted,
32351 then the WM raises the obscured frame. With at least one WM, KDE
32352 2.1, Emacs is not getting any event for the raising of the frame
32353 (even tried with SubstructureRedirectMask), only Expose events.
32354 These expose events will draw text normally, i.e. not
32355 highlighted. Which means we must redo the highlight here.
32356 Subsume it under ``we love X''. --gerd 2001-08-15 */
32357 /* Included in Windows version because Windows most likely does not
32358 do the right thing if any third party tool offers
32359 focus-follows-mouse with delayed raise. --jason 2001-10-12 */
32360 if (mouse_face_overwritten_p && !FRAME_GARBAGED_P (f))
32362 Mouse_HLInfo *hlinfo = MOUSE_HL_INFO (f);
32363 if (f == hlinfo->mouse_face_mouse_frame)
32365 int mouse_x = hlinfo->mouse_face_mouse_x;
32366 int mouse_y = hlinfo->mouse_face_mouse_y;
32367 clear_mouse_face (hlinfo);
32368 note_mouse_highlight (f, mouse_x, mouse_y);
32374 /* EXPORT:
32375 Determine the intersection of two rectangles R1 and R2. Return
32376 the intersection in *RESULT. Value is true if RESULT is not
32377 empty. */
32379 bool
32380 x_intersect_rectangles (XRectangle *r1, XRectangle *r2, XRectangle *result)
32382 XRectangle *left, *right;
32383 XRectangle *upper, *lower;
32384 bool intersection_p = false;
32386 /* Rearrange so that R1 is the left-most rectangle. */
32387 if (r1->x < r2->x)
32388 left = r1, right = r2;
32389 else
32390 left = r2, right = r1;
32392 /* X0 of the intersection is right.x0, if this is inside R1,
32393 otherwise there is no intersection. */
32394 if (right->x <= left->x + left->width)
32396 result->x = right->x;
32398 /* The right end of the intersection is the minimum of
32399 the right ends of left and right. */
32400 result->width = (min (left->x + left->width, right->x + right->width)
32401 - result->x);
32403 /* Same game for Y. */
32404 if (r1->y < r2->y)
32405 upper = r1, lower = r2;
32406 else
32407 upper = r2, lower = r1;
32409 /* The upper end of the intersection is lower.y0, if this is inside
32410 of upper. Otherwise, there is no intersection. */
32411 if (lower->y <= upper->y + upper->height)
32413 result->y = lower->y;
32415 /* The lower end of the intersection is the minimum of the lower
32416 ends of upper and lower. */
32417 result->height = (min (lower->y + lower->height,
32418 upper->y + upper->height)
32419 - result->y);
32420 intersection_p = true;
32424 return intersection_p;
32427 #endif /* HAVE_WINDOW_SYSTEM */
32430 /***********************************************************************
32431 Initialization
32432 ***********************************************************************/
32434 void
32435 syms_of_xdisp (void)
32437 Vwith_echo_area_save_vector = Qnil;
32438 staticpro (&Vwith_echo_area_save_vector);
32440 Vmessage_stack = Qnil;
32441 staticpro (&Vmessage_stack);
32443 /* Non-nil means don't actually do any redisplay. */
32444 DEFSYM (Qinhibit_redisplay, "inhibit-redisplay");
32446 DEFSYM (Qredisplay_internal_xC_functionx, "redisplay_internal (C function)");
32448 DEFVAR_BOOL("inhibit-message", inhibit_message,
32449 doc: /* Non-nil means calls to `message' are not displayed.
32450 They are still logged to the *Messages* buffer. */);
32451 inhibit_message = 0;
32453 message_dolog_marker1 = Fmake_marker ();
32454 staticpro (&message_dolog_marker1);
32455 message_dolog_marker2 = Fmake_marker ();
32456 staticpro (&message_dolog_marker2);
32457 message_dolog_marker3 = Fmake_marker ();
32458 staticpro (&message_dolog_marker3);
32460 defsubr (&Sset_buffer_redisplay);
32461 #ifdef GLYPH_DEBUG
32462 defsubr (&Sdump_frame_glyph_matrix);
32463 defsubr (&Sdump_glyph_matrix);
32464 defsubr (&Sdump_glyph_row);
32465 defsubr (&Sdump_tool_bar_row);
32466 defsubr (&Strace_redisplay);
32467 defsubr (&Strace_to_stderr);
32468 #endif
32469 #ifdef HAVE_WINDOW_SYSTEM
32470 defsubr (&Stool_bar_height);
32471 defsubr (&Slookup_image_map);
32472 #endif
32473 defsubr (&Sline_pixel_height);
32474 defsubr (&Sformat_mode_line);
32475 defsubr (&Sinvisible_p);
32476 defsubr (&Scurrent_bidi_paragraph_direction);
32477 defsubr (&Swindow_text_pixel_size);
32478 defsubr (&Smove_point_visually);
32479 defsubr (&Sbidi_find_overridden_directionality);
32481 DEFSYM (Qmenu_bar_update_hook, "menu-bar-update-hook");
32482 DEFSYM (Qoverriding_terminal_local_map, "overriding-terminal-local-map");
32483 DEFSYM (Qoverriding_local_map, "overriding-local-map");
32484 DEFSYM (Qwindow_scroll_functions, "window-scroll-functions");
32485 DEFSYM (Qredisplay_end_trigger_functions, "redisplay-end-trigger-functions");
32486 DEFSYM (Qinhibit_point_motion_hooks, "inhibit-point-motion-hooks");
32487 DEFSYM (Qeval, "eval");
32488 DEFSYM (QCdata, ":data");
32490 /* Names of text properties relevant for redisplay. */
32491 DEFSYM (Qdisplay, "display");
32492 DEFSYM (Qspace_width, "space-width");
32493 DEFSYM (Qraise, "raise");
32494 DEFSYM (Qslice, "slice");
32495 DEFSYM (Qspace, "space");
32496 DEFSYM (Qmargin, "margin");
32497 DEFSYM (Qpointer, "pointer");
32498 DEFSYM (Qleft_margin, "left-margin");
32499 DEFSYM (Qright_margin, "right-margin");
32500 DEFSYM (Qcenter, "center");
32501 DEFSYM (Qline_height, "line-height");
32502 DEFSYM (QCalign_to, ":align-to");
32503 DEFSYM (QCrelative_width, ":relative-width");
32504 DEFSYM (QCrelative_height, ":relative-height");
32505 DEFSYM (QCeval, ":eval");
32506 DEFSYM (QCpropertize, ":propertize");
32507 DEFSYM (QCfile, ":file");
32508 DEFSYM (Qfontified, "fontified");
32509 DEFSYM (Qfontification_functions, "fontification-functions");
32511 /* Name of the symbol which disables Lisp evaluation in 'display'
32512 properties. This is used by enriched.el. */
32513 DEFSYM (Qdisable_eval, "disable-eval");
32515 /* Name of the face used to highlight trailing whitespace. */
32516 DEFSYM (Qtrailing_whitespace, "trailing-whitespace");
32518 /* Names of the faces used to display line numbers. */
32519 DEFSYM (Qline_number, "line-number");
32520 DEFSYM (Qline_number_current_line, "line-number-current-line");
32521 /* Name of a text property which disables line-number display. */
32522 DEFSYM (Qdisplay_line_numbers_disable, "display-line-numbers-disable");
32524 /* Name and number of the face used to highlight escape glyphs. */
32525 DEFSYM (Qescape_glyph, "escape-glyph");
32527 /* Name and number of the face used to highlight non-breaking
32528 spaces/hyphens. */
32529 DEFSYM (Qnobreak_space, "nobreak-space");
32530 DEFSYM (Qnobreak_hyphen, "nobreak-hyphen");
32532 /* The symbol 'image' which is the car of the lists used to represent
32533 images in Lisp. Also a tool bar style. */
32534 DEFSYM (Qimage, "image");
32536 /* Tool bar styles. */
32537 DEFSYM (Qtext, "text");
32538 DEFSYM (Qboth, "both");
32539 DEFSYM (Qboth_horiz, "both-horiz");
32540 DEFSYM (Qtext_image_horiz, "text-image-horiz");
32542 /* The image map types. */
32543 DEFSYM (QCmap, ":map");
32544 DEFSYM (QCpointer, ":pointer");
32545 DEFSYM (Qrect, "rect");
32546 DEFSYM (Qcircle, "circle");
32547 DEFSYM (Qpoly, "poly");
32549 DEFSYM (Qinhibit_menubar_update, "inhibit-menubar-update");
32551 DEFSYM (Qgrow_only, "grow-only");
32552 DEFSYM (Qinhibit_eval_during_redisplay, "inhibit-eval-during-redisplay");
32553 DEFSYM (Qposition, "position");
32554 DEFSYM (Qbuffer_position, "buffer-position");
32555 DEFSYM (Qobject, "object");
32557 /* Cursor shapes. */
32558 DEFSYM (Qbar, "bar");
32559 DEFSYM (Qhbar, "hbar");
32560 DEFSYM (Qbox, "box");
32561 DEFSYM (Qhollow, "hollow");
32563 /* Pointer shapes. */
32564 DEFSYM (Qhand, "hand");
32565 DEFSYM (Qarrow, "arrow");
32566 /* also Qtext */
32568 DEFSYM (Qdragging, "dragging");
32570 DEFSYM (Qinhibit_free_realized_faces, "inhibit-free-realized-faces");
32572 list_of_error = list1 (list2 (Qerror, Qvoid_variable));
32573 staticpro (&list_of_error);
32575 /* Values of those variables at last redisplay are stored as
32576 properties on 'overlay-arrow-position' symbol. However, if
32577 Voverlay_arrow_position is a marker, last-arrow-position is its
32578 numerical position. */
32579 DEFSYM (Qlast_arrow_position, "last-arrow-position");
32580 DEFSYM (Qlast_arrow_string, "last-arrow-string");
32582 /* Alternative overlay-arrow-string and overlay-arrow-bitmap
32583 properties on a symbol in overlay-arrow-variable-list. */
32584 DEFSYM (Qoverlay_arrow_string, "overlay-arrow-string");
32585 DEFSYM (Qoverlay_arrow_bitmap, "overlay-arrow-bitmap");
32587 echo_buffer[0] = echo_buffer[1] = Qnil;
32588 staticpro (&echo_buffer[0]);
32589 staticpro (&echo_buffer[1]);
32591 echo_area_buffer[0] = echo_area_buffer[1] = Qnil;
32592 staticpro (&echo_area_buffer[0]);
32593 staticpro (&echo_area_buffer[1]);
32595 Vmessages_buffer_name = build_pure_c_string ("*Messages*");
32596 staticpro (&Vmessages_buffer_name);
32598 mode_line_proptrans_alist = Qnil;
32599 staticpro (&mode_line_proptrans_alist);
32600 mode_line_string_list = Qnil;
32601 staticpro (&mode_line_string_list);
32602 mode_line_string_face = Qnil;
32603 staticpro (&mode_line_string_face);
32604 mode_line_string_face_prop = Qnil;
32605 staticpro (&mode_line_string_face_prop);
32606 Vmode_line_unwind_vector = Qnil;
32607 staticpro (&Vmode_line_unwind_vector);
32609 DEFSYM (Qmode_line_default_help_echo, "mode-line-default-help-echo");
32611 help_echo_string = Qnil;
32612 staticpro (&help_echo_string);
32613 help_echo_object = Qnil;
32614 staticpro (&help_echo_object);
32615 help_echo_window = Qnil;
32616 staticpro (&help_echo_window);
32617 previous_help_echo_string = Qnil;
32618 staticpro (&previous_help_echo_string);
32619 help_echo_pos = -1;
32621 DEFSYM (Qright_to_left, "right-to-left");
32622 DEFSYM (Qleft_to_right, "left-to-right");
32623 defsubr (&Sbidi_resolved_levels);
32625 #ifdef HAVE_WINDOW_SYSTEM
32626 DEFVAR_BOOL ("x-stretch-cursor", x_stretch_cursor_p,
32627 doc: /* Non-nil means draw block cursor as wide as the glyph under it.
32628 For example, if a block cursor is over a tab, it will be drawn as
32629 wide as that tab on the display. */);
32630 x_stretch_cursor_p = 0;
32631 #endif
32633 DEFVAR_LISP ("show-trailing-whitespace", Vshow_trailing_whitespace,
32634 doc: /* Non-nil means highlight trailing whitespace.
32635 The face used for trailing whitespace is `trailing-whitespace'. */);
32636 Vshow_trailing_whitespace = Qnil;
32638 DEFVAR_LISP ("nobreak-char-display", Vnobreak_char_display,
32639 doc: /* Control highlighting of non-ASCII space and hyphen chars.
32640 If the value is t, Emacs highlights non-ASCII chars which have the
32641 same appearance as an ASCII space or hyphen, using the `nobreak-space'
32642 or `nobreak-hyphen' face respectively.
32644 U+00A0 (no-break space), U+00AD (soft hyphen), U+2010 (hyphen), and
32645 U+2011 (non-breaking hyphen) are affected.
32647 Any other non-nil value means to display these characters as an escape
32648 glyph followed by an ordinary space or hyphen.
32650 A value of nil means no special handling of these characters. */);
32651 Vnobreak_char_display = Qt;
32653 DEFVAR_LISP ("void-text-area-pointer", Vvoid_text_area_pointer,
32654 doc: /* The pointer shape to show in void text areas.
32655 A value of nil means to show the text pointer. Other options are
32656 `arrow', `text', `hand', `vdrag', `hdrag', `nhdrag', `modeline', and
32657 `hourglass'. */);
32658 Vvoid_text_area_pointer = Qarrow;
32660 DEFVAR_LISP ("inhibit-redisplay", Vinhibit_redisplay,
32661 doc: /* Non-nil means don't actually do any redisplay.
32662 This is used for internal purposes. */);
32663 Vinhibit_redisplay = Qnil;
32665 DEFVAR_LISP ("global-mode-string", Vglobal_mode_string,
32666 doc: /* String (or mode line construct) included (normally) in `mode-line-format'. */);
32667 Vglobal_mode_string = Qnil;
32669 DEFVAR_LISP ("overlay-arrow-position", Voverlay_arrow_position,
32670 doc: /* Marker for where to display an arrow on top of the buffer text.
32671 This must be the beginning of a line in order to work.
32672 See also `overlay-arrow-string'. */);
32673 Voverlay_arrow_position = Qnil;
32675 DEFVAR_LISP ("overlay-arrow-string", Voverlay_arrow_string,
32676 doc: /* String to display as an arrow in non-window frames.
32677 See also `overlay-arrow-position'. */);
32678 Voverlay_arrow_string = build_pure_c_string ("=>");
32680 DEFVAR_LISP ("overlay-arrow-variable-list", Voverlay_arrow_variable_list,
32681 doc: /* List of variables (symbols) which hold markers for overlay arrows.
32682 The symbols on this list are examined during redisplay to determine
32683 where to display overlay arrows. */);
32684 Voverlay_arrow_variable_list
32685 = list1 (intern_c_string ("overlay-arrow-position"));
32687 DEFVAR_INT ("scroll-step", emacs_scroll_step,
32688 doc: /* The number of lines to try scrolling a window by when point moves out.
32689 If that fails to bring point back on frame, point is centered instead.
32690 If this is zero, point is always centered after it moves off frame.
32691 If you want scrolling to always be a line at a time, you should set
32692 `scroll-conservatively' to a large value rather than set this to 1. */);
32694 DEFVAR_INT ("scroll-conservatively", scroll_conservatively,
32695 doc: /* Scroll up to this many lines, to bring point back on screen.
32696 If point moves off-screen, redisplay will scroll by up to
32697 `scroll-conservatively' lines in order to bring point just barely
32698 onto the screen again. If that cannot be done, then redisplay
32699 recenters point as usual.
32701 If the value is greater than 100, redisplay will never recenter point,
32702 but will always scroll just enough text to bring point into view, even
32703 if you move far away.
32705 A value of zero means always recenter point if it moves off screen. */);
32706 scroll_conservatively = 0;
32708 DEFVAR_INT ("scroll-margin", scroll_margin,
32709 doc: /* Number of lines of margin at the top and bottom of a window.
32710 Trigger automatic scrolling whenever point gets within this many lines
32711 of the top or bottom of the window (see info node `Auto Scrolling'). */);
32712 scroll_margin = 0;
32714 DEFVAR_LISP ("maximum-scroll-margin", Vmaximum_scroll_margin,
32715 doc: /* Maximum effective value of `scroll-margin'.
32716 Given as a fraction of the current window's lines. The value should
32717 be a floating point number between 0.0 and 0.5. The effective maximum
32718 is limited to (/ (1- window-lines) 2). Non-float values for this
32719 variable are ignored and the default 0.25 is used instead. */);
32720 Vmaximum_scroll_margin = make_float (0.25);
32722 DEFVAR_LISP ("display-pixels-per-inch", Vdisplay_pixels_per_inch,
32723 doc: /* Pixels per inch value for non-window system displays.
32724 Value is a number or a cons (WIDTH-DPI . HEIGHT-DPI). */);
32725 Vdisplay_pixels_per_inch = make_float (72.0);
32727 #ifdef GLYPH_DEBUG
32728 DEFVAR_INT ("debug-end-pos", debug_end_pos, doc: /* Don't ask. */);
32729 #endif
32731 DEFVAR_LISP ("truncate-partial-width-windows",
32732 Vtruncate_partial_width_windows,
32733 doc: /* Non-nil means truncate lines in windows narrower than the frame.
32734 For an integer value, truncate lines in each window narrower than the
32735 full frame width, provided the total window width in column units is less
32736 than that integer; otherwise, respect the value of `truncate-lines'.
32737 The total width of the window is as returned by `window-total-width', it
32738 includes the fringes, the continuation and truncation glyphs, the
32739 display margins (if any), and the scroll bar
32741 For any other non-nil value, truncate lines in all windows that do
32742 not span the full frame width.
32744 A value of nil means to respect the value of `truncate-lines'.
32746 If `word-wrap' is enabled, you might want to reduce this. */);
32747 Vtruncate_partial_width_windows = make_number (50);
32749 DEFVAR_LISP ("line-number-display-limit", Vline_number_display_limit,
32750 doc: /* Maximum buffer size for which line number should be displayed.
32751 If the buffer is bigger than this, the line number does not appear
32752 in the mode line. A value of nil means no limit. */);
32753 Vline_number_display_limit = Qnil;
32755 DEFVAR_INT ("line-number-display-limit-width",
32756 line_number_display_limit_width,
32757 doc: /* Maximum line width (in characters) for line number display.
32758 If the average length of the lines near point is bigger than this, then the
32759 line number may be omitted from the mode line. */);
32760 line_number_display_limit_width = 200;
32762 DEFVAR_BOOL ("highlight-nonselected-windows", highlight_nonselected_windows,
32763 doc: /* Non-nil means highlight region even in nonselected windows. */);
32764 highlight_nonselected_windows = false;
32766 DEFVAR_BOOL ("multiple-frames", multiple_frames,
32767 doc: /* Non-nil if more than one frame is visible on this display.
32768 Minibuffer-only frames don't count, but iconified frames do.
32769 This variable is not guaranteed to be accurate except while processing
32770 `frame-title-format' and `icon-title-format'. */);
32772 DEFVAR_LISP ("frame-title-format", Vframe_title_format,
32773 doc: /* Template for displaying the title bar of visible frames.
32774 \(Assuming the window manager supports this feature.)
32776 This variable has the same structure as `mode-line-format', except that
32777 the %c, %C, and %l constructs are ignored. It is used only on frames for
32778 which no explicit name has been set (see `modify-frame-parameters'). */);
32780 DEFVAR_LISP ("icon-title-format", Vicon_title_format,
32781 doc: /* Template for displaying the title bar of an iconified frame.
32782 \(Assuming the window manager supports this feature.)
32783 This variable has the same structure as `mode-line-format' (which see),
32784 and is used only on frames for which no explicit name has been set
32785 \(see `modify-frame-parameters'). */);
32786 Vicon_title_format
32787 = Vframe_title_format
32788 = listn (CONSTYPE_PURE, 3,
32789 intern_c_string ("multiple-frames"),
32790 build_pure_c_string ("%b"),
32791 listn (CONSTYPE_PURE, 4,
32792 empty_unibyte_string,
32793 intern_c_string ("invocation-name"),
32794 build_pure_c_string ("@"),
32795 intern_c_string ("system-name")));
32797 DEFVAR_LISP ("message-log-max", Vmessage_log_max,
32798 doc: /* Maximum number of lines to keep in the message log buffer.
32799 If nil, disable message logging. If t, log messages but don't truncate
32800 the buffer when it becomes large. */);
32801 Vmessage_log_max = make_number (1000);
32803 DEFVAR_LISP ("window-scroll-functions", Vwindow_scroll_functions,
32804 doc: /* List of functions to call before redisplaying a window with scrolling.
32805 Each function is called with two arguments, the window and its new
32806 display-start position.
32807 These functions are called whenever the `window-start' marker is modified,
32808 either to point into another buffer (e.g. via `set-window-buffer') or another
32809 place in the same buffer.
32810 When each function is called, the `window-start' marker of its window
32811 argument has been already set to the new value, and the buffer which that
32812 window will display is set to be the current buffer.
32813 Note that the value of `window-end' is not valid when these functions are
32814 called.
32816 Warning: Do not use this feature to alter the way the window
32817 is scrolled. It is not designed for that, and such use probably won't
32818 work. */);
32819 Vwindow_scroll_functions = Qnil;
32821 DEFVAR_LISP ("redisplay-end-trigger-functions", Vredisplay_end_trigger_functions,
32822 doc: /* Functions called when redisplay of a window reaches the end trigger.
32823 Each function is called with two arguments, the window and the end trigger value.
32824 See `set-window-redisplay-end-trigger'. */);
32825 Vredisplay_end_trigger_functions = Qnil;
32827 DEFVAR_LISP ("mouse-autoselect-window", Vmouse_autoselect_window,
32828 doc: /* Non-nil means autoselect window with mouse pointer.
32829 If nil, do not autoselect windows.
32830 A positive number means delay autoselection by that many seconds: a
32831 window is autoselected only after the mouse has remained in that
32832 window for the duration of the delay.
32833 A negative number has a similar effect, but causes windows to be
32834 autoselected only after the mouse has stopped moving. (Because of
32835 the way Emacs compares mouse events, you will occasionally wait twice
32836 that time before the window gets selected.)
32837 Any other value means to autoselect window instantaneously when the
32838 mouse pointer enters it.
32840 Autoselection selects the minibuffer only if it is active, and never
32841 unselects the minibuffer if it is active.
32843 When customizing this variable make sure that the actual value of
32844 `focus-follows-mouse' matches the behavior of your window manager. */);
32845 Vmouse_autoselect_window = Qnil;
32847 DEFVAR_LISP ("auto-resize-tool-bars", Vauto_resize_tool_bars,
32848 doc: /* Non-nil means automatically resize tool-bars.
32849 This dynamically changes the tool-bar's height to the minimum height
32850 that is needed to make all tool-bar items visible.
32851 If value is `grow-only', the tool-bar's height is only increased
32852 automatically; to decrease the tool-bar height, use \\[recenter]. */);
32853 Vauto_resize_tool_bars = Qt;
32855 DEFVAR_BOOL ("auto-raise-tool-bar-buttons", auto_raise_tool_bar_buttons_p,
32856 doc: /* Non-nil means raise tool-bar buttons when the mouse moves over them. */);
32857 auto_raise_tool_bar_buttons_p = true;
32859 DEFVAR_BOOL ("make-cursor-line-fully-visible", make_cursor_line_fully_visible_p,
32860 doc: /* Non-nil means to scroll (recenter) cursor line if it is not fully visible. */);
32861 make_cursor_line_fully_visible_p = true;
32863 DEFVAR_LISP ("tool-bar-border", Vtool_bar_border,
32864 doc: /* Border below tool-bar in pixels.
32865 If an integer, use it as the height of the border.
32866 If it is one of `internal-border-width' or `border-width', use the
32867 value of the corresponding frame parameter.
32868 Otherwise, no border is added below the tool-bar. */);
32869 Vtool_bar_border = Qinternal_border_width;
32871 DEFVAR_LISP ("tool-bar-button-margin", Vtool_bar_button_margin,
32872 doc: /* Margin around tool-bar buttons in pixels.
32873 If an integer, use that for both horizontal and vertical margins.
32874 Otherwise, value should be a pair of integers `(HORZ . VERT)' with
32875 HORZ specifying the horizontal margin, and VERT specifying the
32876 vertical margin. */);
32877 Vtool_bar_button_margin = make_number (DEFAULT_TOOL_BAR_BUTTON_MARGIN);
32879 DEFVAR_INT ("tool-bar-button-relief", tool_bar_button_relief,
32880 doc: /* Relief thickness of tool-bar buttons. */);
32881 tool_bar_button_relief = DEFAULT_TOOL_BAR_BUTTON_RELIEF;
32883 DEFVAR_LISP ("tool-bar-style", Vtool_bar_style,
32884 doc: /* Tool bar style to use.
32885 It can be one of
32886 image - show images only
32887 text - show text only
32888 both - show both, text below image
32889 both-horiz - show text to the right of the image
32890 text-image-horiz - show text to the left of the image
32891 any other - use system default or image if no system default.
32893 This variable only affects the GTK+ toolkit version of Emacs. */);
32894 Vtool_bar_style = Qnil;
32896 DEFVAR_INT ("tool-bar-max-label-size", tool_bar_max_label_size,
32897 doc: /* Maximum number of characters a label can have to be shown.
32898 The tool bar style must also show labels for this to have any effect, see
32899 `tool-bar-style'. */);
32900 tool_bar_max_label_size = DEFAULT_TOOL_BAR_LABEL_SIZE;
32902 DEFVAR_LISP ("fontification-functions", Vfontification_functions,
32903 doc: /* List of functions to call to fontify regions of text.
32904 Each function is called with one argument POS. Functions must
32905 fontify a region starting at POS in the current buffer, and give
32906 fontified regions the property `fontified'. */);
32907 Vfontification_functions = Qnil;
32908 Fmake_variable_buffer_local (Qfontification_functions);
32910 DEFVAR_BOOL ("unibyte-display-via-language-environment",
32911 unibyte_display_via_language_environment,
32912 doc: /* Non-nil means display unibyte text according to language environment.
32913 Specifically, this means that raw bytes in the range 160-255 decimal
32914 are displayed by converting them to the equivalent multibyte characters
32915 according to the current language environment. As a result, they are
32916 displayed according to the current fontset.
32918 Note that this variable affects only how these bytes are displayed,
32919 but does not change the fact they are interpreted as raw bytes. */);
32920 unibyte_display_via_language_environment = false;
32922 DEFVAR_LISP ("max-mini-window-height", Vmax_mini_window_height,
32923 doc: /* Maximum height for resizing mini-windows (the minibuffer and the echo area).
32924 If a float, it specifies a fraction of the mini-window frame's height.
32925 If an integer, it specifies a number of lines. */);
32926 Vmax_mini_window_height = make_float (0.25);
32928 DEFVAR_LISP ("resize-mini-windows", Vresize_mini_windows,
32929 doc: /* How to resize mini-windows (the minibuffer and the echo area).
32930 A value of nil means don't automatically resize mini-windows.
32931 A value of t means resize them to fit the text displayed in them.
32932 A value of `grow-only', the default, means let mini-windows grow only;
32933 they return to their normal size when the minibuffer is closed, or the
32934 echo area becomes empty. */);
32935 /* Contrary to the doc string, we initialize this to nil, so that
32936 loading loadup.el won't try to resize windows before loading
32937 window.el, where some functions we need to call for this live.
32938 We assign the 'grow-only' value right after loading window.el
32939 during loadup. */
32940 Vresize_mini_windows = Qnil;
32942 DEFVAR_LISP ("blink-cursor-alist", Vblink_cursor_alist,
32943 doc: /* Alist specifying how to blink the cursor off.
32944 Each element has the form (ON-STATE . OFF-STATE). Whenever the
32945 `cursor-type' frame-parameter or variable equals ON-STATE,
32946 comparing using `equal', Emacs uses OFF-STATE to specify
32947 how to blink it off. ON-STATE and OFF-STATE are values for
32948 the `cursor-type' frame parameter.
32950 If a frame's ON-STATE has no entry in this list,
32951 the frame's other specifications determine how to blink the cursor off. */);
32952 Vblink_cursor_alist = Qnil;
32954 DEFVAR_LISP ("auto-hscroll-mode", automatic_hscrolling,
32955 doc: /* Allow or disallow automatic horizontal scrolling of windows.
32956 The value `current-line' means the line displaying point in each window
32957 is automatically scrolled horizontally to make point visible.
32958 Any other non-nil value means all the lines in a window are automatically
32959 scrolled horizontally to make point visible. */);
32960 automatic_hscrolling = Qt;
32961 DEFSYM (Qauto_hscroll_mode, "auto-hscroll-mode");
32962 DEFSYM (Qcurrent_line, "current-line");
32964 DEFVAR_INT ("hscroll-margin", hscroll_margin,
32965 doc: /* How many columns away from the window edge point is allowed to get
32966 before automatic hscrolling will horizontally scroll the window. */);
32967 hscroll_margin = 5;
32969 DEFVAR_LISP ("hscroll-step", Vhscroll_step,
32970 doc: /* How many columns to scroll the window when point gets too close to the edge.
32971 When point is less than `hscroll-margin' columns from the window
32972 edge, automatic hscrolling will scroll the window by the amount of columns
32973 determined by this variable. If its value is a positive integer, scroll that
32974 many columns. If it's a positive floating-point number, it specifies the
32975 fraction of the window's width to scroll. If it's nil or zero, point will be
32976 centered horizontally after the scroll. Any other value, including negative
32977 numbers, are treated as if the value were zero.
32979 Automatic hscrolling always moves point outside the scroll margin, so if
32980 point was more than scroll step columns inside the margin, the window will
32981 scroll more than the value given by the scroll step.
32983 Note that the lower bound for automatic hscrolling specified by `scroll-left'
32984 and `scroll-right' overrides this variable's effect. */);
32985 Vhscroll_step = make_number (0);
32987 DEFVAR_BOOL ("message-truncate-lines", message_truncate_lines,
32988 doc: /* If non-nil, messages are truncated instead of resizing the echo area.
32989 Bind this around calls to `message' to let it take effect. */);
32990 message_truncate_lines = false;
32992 DEFVAR_LISP ("menu-bar-update-hook", Vmenu_bar_update_hook,
32993 doc: /* Normal hook run to update the menu bar definitions.
32994 Redisplay runs this hook before it redisplays the menu bar.
32995 This is used to update menus such as Buffers, whose contents depend on
32996 various data. */);
32997 Vmenu_bar_update_hook = Qnil;
32999 DEFVAR_LISP ("menu-updating-frame", Vmenu_updating_frame,
33000 doc: /* Frame for which we are updating a menu.
33001 The enable predicate for a menu binding should check this variable. */);
33002 Vmenu_updating_frame = Qnil;
33004 DEFVAR_BOOL ("inhibit-menubar-update", inhibit_menubar_update,
33005 doc: /* Non-nil means don't update menu bars. Internal use only. */);
33006 inhibit_menubar_update = false;
33008 DEFVAR_LISP ("wrap-prefix", Vwrap_prefix,
33009 doc: /* Prefix prepended to all continuation lines at display time.
33010 The value may be a string, an image, or a stretch-glyph; it is
33011 interpreted in the same way as the value of a `display' text property.
33013 This variable is overridden by any `wrap-prefix' text or overlay
33014 property.
33016 To add a prefix to non-continuation lines, use `line-prefix'. */);
33017 Vwrap_prefix = Qnil;
33018 DEFSYM (Qwrap_prefix, "wrap-prefix");
33019 Fmake_variable_buffer_local (Qwrap_prefix);
33021 DEFVAR_LISP ("line-prefix", Vline_prefix,
33022 doc: /* Prefix prepended to all non-continuation lines at display time.
33023 The value may be a string, an image, or a stretch-glyph; it is
33024 interpreted in the same way as the value of a `display' text property.
33026 This variable is overridden by any `line-prefix' text or overlay
33027 property.
33029 To add a prefix to continuation lines, use `wrap-prefix'. */);
33030 Vline_prefix = Qnil;
33031 DEFSYM (Qline_prefix, "line-prefix");
33032 Fmake_variable_buffer_local (Qline_prefix);
33034 DEFVAR_LISP ("display-line-numbers", Vdisplay_line_numbers,
33035 doc: /* Non-nil means display line numbers.
33036 If the value is t, display the absolute number of each line of a buffer
33037 shown in a window. Absolute line numbers count from the beginning of
33038 the current narrowing, or from buffer beginning. If the value is
33039 `relative', display for each line not containing the window's point its
33040 relative number instead, i.e. the number of the line relative to the
33041 line showing the window's point.
33043 In either case, line numbers are displayed at the beginning of each
33044 non-continuation line that displays buffer text, i.e. after each newline
33045 character that comes from the buffer. The value `visual' is like
33046 `relative' but counts screen lines instead of buffer lines. In practice
33047 this means that continuation lines count as well when calculating the
33048 relative number of a line.
33050 Lisp programs can disable display of a line number of a particular
33051 buffer line by putting the `display-line-numbers-disable' text property
33052 or overlay property on the first visible character of that line. */);
33053 Vdisplay_line_numbers = Qnil;
33054 DEFSYM (Qdisplay_line_numbers, "display-line-numbers");
33055 Fmake_variable_buffer_local (Qdisplay_line_numbers);
33056 DEFSYM (Qrelative, "relative");
33057 DEFSYM (Qvisual, "visual");
33059 DEFVAR_LISP ("display-line-numbers-width", Vdisplay_line_numbers_width,
33060 doc: /* Minimum width of space reserved for line number display.
33061 A positive number means reserve that many columns for line numbers,
33062 even if the actual number needs less space.
33063 The default value of nil means compute the space dynamically.
33064 Any other value is treated as nil. */);
33065 Vdisplay_line_numbers_width = Qnil;
33066 DEFSYM (Qdisplay_line_numbers_width, "display-line-numbers-width");
33067 Fmake_variable_buffer_local (Qdisplay_line_numbers_width);
33069 DEFVAR_LISP ("display-line-numbers-current-absolute",
33070 Vdisplay_line_numbers_current_absolute,
33071 doc: /* Non-nil means display absolute number of current line.
33072 This variable has effect only when `display-line-numbers' is
33073 either `relative' or `visual'. */);
33074 Vdisplay_line_numbers_current_absolute = Qt;
33076 DEFVAR_BOOL ("display-line-numbers-widen", display_line_numbers_widen,
33077 doc: /* Non-nil means display line numbers disregarding any narrowing. */);
33078 display_line_numbers_widen = false;
33079 DEFSYM (Qdisplay_line_numbers_widen, "display-line-numbers-widen");
33080 Fmake_variable_buffer_local (Qdisplay_line_numbers_widen);
33082 DEFVAR_BOOL ("inhibit-eval-during-redisplay", inhibit_eval_during_redisplay,
33083 doc: /* Non-nil means don't eval Lisp during redisplay. */);
33084 inhibit_eval_during_redisplay = false;
33086 DEFVAR_BOOL ("inhibit-free-realized-faces", inhibit_free_realized_faces,
33087 doc: /* Non-nil means don't free realized faces. Internal use only. */);
33088 inhibit_free_realized_faces = false;
33090 DEFVAR_BOOL ("inhibit-bidi-mirroring", inhibit_bidi_mirroring,
33091 doc: /* Non-nil means don't mirror characters even when bidi context requires that.
33092 Intended for use during debugging and for testing bidi display;
33093 see biditest.el in the test suite. */);
33094 inhibit_bidi_mirroring = false;
33096 #ifdef GLYPH_DEBUG
33097 DEFVAR_BOOL ("inhibit-try-window-id", inhibit_try_window_id,
33098 doc: /* Inhibit try_window_id display optimization. */);
33099 inhibit_try_window_id = false;
33101 DEFVAR_BOOL ("inhibit-try-window-reusing", inhibit_try_window_reusing,
33102 doc: /* Inhibit try_window_reusing display optimization. */);
33103 inhibit_try_window_reusing = false;
33105 DEFVAR_BOOL ("inhibit-try-cursor-movement", inhibit_try_cursor_movement,
33106 doc: /* Inhibit try_cursor_movement display optimization. */);
33107 inhibit_try_cursor_movement = false;
33108 #endif /* GLYPH_DEBUG */
33110 DEFVAR_INT ("overline-margin", overline_margin,
33111 doc: /* Space between overline and text, in pixels.
33112 The default value is 2: the height of the overline (1 pixel) plus 1 pixel
33113 margin to the character height. */);
33114 overline_margin = 2;
33116 DEFVAR_INT ("underline-minimum-offset",
33117 underline_minimum_offset,
33118 doc: /* Minimum distance between baseline and underline.
33119 This can improve legibility of underlined text at small font sizes,
33120 particularly when using variable `x-use-underline-position-properties'
33121 with fonts that specify an UNDERLINE_POSITION relatively close to the
33122 baseline. The default value is 1. */);
33123 underline_minimum_offset = 1;
33124 DEFSYM (Qunderline_minimum_offset, "underline-minimum-offset");
33126 DEFVAR_BOOL ("display-hourglass", display_hourglass_p,
33127 doc: /* Non-nil means show an hourglass pointer, when Emacs is busy.
33128 This feature only works when on a window system that can change
33129 cursor shapes. */);
33130 display_hourglass_p = true;
33132 DEFVAR_LISP ("hourglass-delay", Vhourglass_delay,
33133 doc: /* Seconds to wait before displaying an hourglass pointer when Emacs is busy. */);
33134 Vhourglass_delay = make_number (DEFAULT_HOURGLASS_DELAY);
33136 #ifdef HAVE_WINDOW_SYSTEM
33137 hourglass_atimer = NULL;
33138 hourglass_shown_p = false;
33139 #endif /* HAVE_WINDOW_SYSTEM */
33141 /* Name of the face used to display glyphless characters. */
33142 DEFSYM (Qglyphless_char, "glyphless-char");
33144 /* Method symbols for Vglyphless_char_display. */
33145 DEFSYM (Qhex_code, "hex-code");
33146 DEFSYM (Qempty_box, "empty-box");
33147 DEFSYM (Qthin_space, "thin-space");
33148 DEFSYM (Qzero_width, "zero-width");
33150 DEFVAR_LISP ("pre-redisplay-function", Vpre_redisplay_function,
33151 doc: /* Function run just before redisplay.
33152 It is called with one argument, which is the set of windows that are to
33153 be redisplayed. This set can be nil (meaning, only the selected window),
33154 or t (meaning all windows). */);
33155 Vpre_redisplay_function = intern ("ignore");
33157 /* Symbol for the purpose of Vglyphless_char_display. */
33158 DEFSYM (Qglyphless_char_display, "glyphless-char-display");
33159 Fput (Qglyphless_char_display, Qchar_table_extra_slots, make_number (1));
33161 DEFVAR_LISP ("glyphless-char-display", Vglyphless_char_display,
33162 doc: /* Char-table defining glyphless characters.
33163 Each element, if non-nil, should be one of the following:
33164 an ASCII acronym string: display this string in a box
33165 `hex-code': display the hexadecimal code of a character in a box
33166 `empty-box': display as an empty box
33167 `thin-space': display as 1-pixel width space
33168 `zero-width': don't display
33169 An element may also be a cons cell (GRAPHICAL . TEXT), which specifies the
33170 display method for graphical terminals and text terminals respectively.
33171 GRAPHICAL and TEXT should each have one of the values listed above.
33173 The char-table has one extra slot to control the display of a character for
33174 which no font is found. This slot only takes effect on graphical terminals.
33175 Its value should be an ASCII acronym string, `hex-code', `empty-box', or
33176 `thin-space'. The default is `empty-box'.
33178 If a character has a non-nil entry in an active display table, the
33179 display table takes effect; in this case, Emacs does not consult
33180 `glyphless-char-display' at all. */);
33181 Vglyphless_char_display = Fmake_char_table (Qglyphless_char_display, Qnil);
33182 Fset_char_table_extra_slot (Vglyphless_char_display, make_number (0),
33183 Qempty_box);
33185 DEFVAR_LISP ("debug-on-message", Vdebug_on_message,
33186 doc: /* If non-nil, debug if a message matching this regexp is displayed. */);
33187 Vdebug_on_message = Qnil;
33189 DEFVAR_LISP ("redisplay--all-windows-cause", Vredisplay__all_windows_cause,
33190 doc: /* */);
33191 Vredisplay__all_windows_cause = Fmake_hash_table (0, NULL);
33193 DEFVAR_LISP ("redisplay--mode-lines-cause", Vredisplay__mode_lines_cause,
33194 doc: /* */);
33195 Vredisplay__mode_lines_cause = Fmake_hash_table (0, NULL);
33197 DEFVAR_BOOL ("redisplay--inhibit-bidi", redisplay__inhibit_bidi,
33198 doc: /* Non-nil means it is not safe to attempt bidi reordering for display. */);
33199 /* Initialize to t, since we need to disable reordering until
33200 loadup.el successfully loads charprop.el. */
33201 redisplay__inhibit_bidi = true;
33203 DEFVAR_BOOL ("display-raw-bytes-as-hex", display_raw_bytes_as_hex,
33204 doc: /* Non-nil means display raw bytes in hexadecimal format.
33205 The default is to use octal format (\200) whereas hexadecimal (\x80)
33206 may be more familiar to users. */);
33207 display_raw_bytes_as_hex = false;
33212 /* Initialize this module when Emacs starts. */
33214 void
33215 init_xdisp (void)
33217 CHARPOS (this_line_start_pos) = 0;
33219 if (!noninteractive)
33221 struct window *m = XWINDOW (minibuf_window);
33222 Lisp_Object frame = m->frame;
33223 struct frame *f = XFRAME (frame);
33224 Lisp_Object root = FRAME_ROOT_WINDOW (f);
33225 struct window *r = XWINDOW (root);
33226 int i;
33228 echo_area_window = minibuf_window;
33230 r->top_line = FRAME_TOP_MARGIN (f);
33231 r->pixel_top = r->top_line * FRAME_LINE_HEIGHT (f);
33232 r->total_cols = FRAME_COLS (f);
33233 r->pixel_width = r->total_cols * FRAME_COLUMN_WIDTH (f);
33234 r->total_lines = FRAME_TOTAL_LINES (f) - 1 - FRAME_TOP_MARGIN (f);
33235 r->pixel_height = r->total_lines * FRAME_LINE_HEIGHT (f);
33237 m->top_line = FRAME_TOTAL_LINES (f) - 1;
33238 m->pixel_top = m->top_line * FRAME_LINE_HEIGHT (f);
33239 m->total_cols = FRAME_COLS (f);
33240 m->pixel_width = m->total_cols * FRAME_COLUMN_WIDTH (f);
33241 m->total_lines = 1;
33242 m->pixel_height = m->total_lines * FRAME_LINE_HEIGHT (f);
33244 scratch_glyph_row.glyphs[TEXT_AREA] = scratch_glyphs;
33245 scratch_glyph_row.glyphs[TEXT_AREA + 1]
33246 = scratch_glyphs + MAX_SCRATCH_GLYPHS;
33248 /* The default ellipsis glyphs `...'. */
33249 for (i = 0; i < 3; ++i)
33250 default_invis_vector[i] = make_number ('.');
33254 /* Allocate the buffer for frame titles.
33255 Also used for `format-mode-line'. */
33256 int size = 100;
33257 mode_line_noprop_buf = xmalloc (size);
33258 mode_line_noprop_buf_end = mode_line_noprop_buf + size;
33259 mode_line_noprop_ptr = mode_line_noprop_buf;
33260 mode_line_target = MODE_LINE_DISPLAY;
33263 help_echo_showing_p = false;
33266 #ifdef HAVE_WINDOW_SYSTEM
33268 /* Platform-independent portion of hourglass implementation. */
33270 /* Timer function of hourglass_atimer. */
33272 static void
33273 show_hourglass (struct atimer *timer)
33275 /* The timer implementation will cancel this timer automatically
33276 after this function has run. Set hourglass_atimer to null
33277 so that we know the timer doesn't have to be canceled. */
33278 hourglass_atimer = NULL;
33280 if (!hourglass_shown_p)
33282 Lisp_Object tail, frame;
33284 block_input ();
33286 FOR_EACH_FRAME (tail, frame)
33288 struct frame *f = XFRAME (frame);
33290 if (FRAME_LIVE_P (f) && FRAME_WINDOW_P (f)
33291 && FRAME_RIF (f)->show_hourglass)
33292 FRAME_RIF (f)->show_hourglass (f);
33295 hourglass_shown_p = true;
33296 unblock_input ();
33300 /* Cancel a currently active hourglass timer, and start a new one. */
33302 void
33303 start_hourglass (void)
33305 struct timespec delay;
33307 cancel_hourglass ();
33309 if (INTEGERP (Vhourglass_delay)
33310 && XINT (Vhourglass_delay) > 0)
33311 delay = make_timespec (min (XINT (Vhourglass_delay),
33312 TYPE_MAXIMUM (time_t)),
33314 else if (FLOATP (Vhourglass_delay)
33315 && XFLOAT_DATA (Vhourglass_delay) > 0)
33316 delay = dtotimespec (XFLOAT_DATA (Vhourglass_delay));
33317 else
33318 delay = make_timespec (DEFAULT_HOURGLASS_DELAY, 0);
33320 hourglass_atimer = start_atimer (ATIMER_RELATIVE, delay,
33321 show_hourglass, NULL);
33324 /* Cancel the hourglass cursor timer if active, hide a busy cursor if
33325 shown. */
33327 void
33328 cancel_hourglass (void)
33330 if (hourglass_atimer)
33332 cancel_atimer (hourglass_atimer);
33333 hourglass_atimer = NULL;
33336 if (hourglass_shown_p)
33338 Lisp_Object tail, frame;
33340 block_input ();
33342 FOR_EACH_FRAME (tail, frame)
33344 struct frame *f = XFRAME (frame);
33346 if (FRAME_LIVE_P (f) && FRAME_WINDOW_P (f)
33347 && FRAME_RIF (f)->hide_hourglass)
33348 FRAME_RIF (f)->hide_hourglass (f);
33349 #ifdef HAVE_NTGUI
33350 /* No cursors on non GUI frames - restore to stock arrow cursor. */
33351 else if (!FRAME_W32_P (f))
33352 w32_arrow_cursor ();
33353 #endif
33356 hourglass_shown_p = false;
33357 unblock_input ();
33361 #endif /* HAVE_WINDOW_SYSTEM */