Improve responsiveness while in 'replace-buffer-contents'
[emacs.git] / src / xdisp.c
blob5bce05c219e702457952d4562f1b71cb0499cbc4
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 /* List of pairs (MESSAGE . MULTIBYTE). The function save_message
444 pushes the current message and the value of
445 message_enable_multibyte on the stack, the function restore_message
446 pops the stack and displays MESSAGE again. */
448 static Lisp_Object Vmessage_stack;
450 /* True means multibyte characters were enabled when the echo area
451 message was specified. */
453 static bool message_enable_multibyte;
455 /* At each redisplay cycle, we should refresh everything there is to refresh.
456 To do that efficiently, we use many optimizations that try to make sure we
457 don't waste too much time updating things that haven't changed.
458 The coarsest such optimization is that, in the most common cases, we only
459 look at the selected-window.
461 To know whether other windows should be considered for redisplay, we use the
462 variable windows_or_buffers_changed: as long as it is 0, it means that we
463 have not noticed anything that should require updating anything else than
464 the selected-window. If it is set to REDISPLAY_SOME, it means that since
465 last redisplay, some changes have been made which could impact other
466 windows. To know which ones need redisplay, every buffer, window, and frame
467 has a `redisplay' bit, which (if true) means that this object needs to be
468 redisplayed. If windows_or_buffers_changed is 0, we know there's no point
469 looking for those `redisplay' bits (actually, there might be some such bits
470 set, but then only on objects which aren't displayed anyway).
472 OTOH if it's non-zero we wil have to loop through all windows and then check
473 the `redisplay' bit of the corresponding window, frame, and buffer, in order
474 to decide whether that window needs attention or not. Note that we can't
475 just look at the frame's redisplay bit to decide that the whole frame can be
476 skipped, since even if the frame's redisplay bit is unset, some of its
477 windows's redisplay bits may be set.
479 Mostly for historical reasons, windows_or_buffers_changed can also take
480 other non-zero values. In that case, the precise value doesn't matter (it
481 encodes the cause of the setting but is only used for debugging purposes),
482 and what it means is that we shouldn't pay attention to any `redisplay' bits
483 and we should simply try and redisplay every window out there. */
485 int windows_or_buffers_changed;
487 /* Nonzero if we should redraw the mode lines on the next redisplay.
488 Similarly to `windows_or_buffers_changed', If it has value REDISPLAY_SOME,
489 then only redisplay the mode lines in those buffers/windows/frames where the
490 `redisplay' bit has been set.
491 For any other value, redisplay all mode lines (the number used is then only
492 used to track down the cause for this full-redisplay).
494 Since the frame title uses the same %-constructs as the mode line
495 (except %c, %C, and %l), if this variable is non-zero, we also consider
496 redisplaying the title of each frame, see x_consider_frame_title.
498 The `redisplay' bits are the same as those used for
499 windows_or_buffers_changed, and setting windows_or_buffers_changed also
500 causes recomputation of the mode lines of all those windows. IOW this
501 variable only has an effect if windows_or_buffers_changed is zero, in which
502 case we should only need to redisplay the mode-line of those objects with
503 a `redisplay' bit set but not the window's text content (tho we may still
504 need to refresh the text content of the selected-window). */
506 int update_mode_lines;
508 /* True after display_mode_line if %l was used and it displayed a
509 line number. */
511 static bool line_number_displayed;
513 /* The name of the *Messages* buffer, a string. */
515 static Lisp_Object Vmessages_buffer_name;
517 /* Current, index 0, and last displayed echo area message. Either
518 buffers from echo_buffers, or nil to indicate no message. */
520 Lisp_Object echo_area_buffer[2];
522 /* The buffers referenced from echo_area_buffer. */
524 static Lisp_Object echo_buffer[2];
526 /* A vector saved used in with_area_buffer to reduce consing. */
528 static Lisp_Object Vwith_echo_area_save_vector;
530 /* True means display_echo_area should display the last echo area
531 message again. Set by redisplay_preserve_echo_area. */
533 static bool display_last_displayed_message_p;
535 /* True if echo area is being used by print; false if being used by
536 message. */
538 static bool message_buf_print;
540 /* Set to true in clear_message to make redisplay_internal aware
541 of an emptied echo area. */
543 static bool message_cleared_p;
545 /* A scratch glyph row with contents used for generating truncation
546 glyphs. Also used in direct_output_for_insert. */
548 #define MAX_SCRATCH_GLYPHS 100
549 static struct glyph_row scratch_glyph_row;
550 static struct glyph scratch_glyphs[MAX_SCRATCH_GLYPHS];
552 /* Ascent and height of the last line processed by move_it_to. */
554 static int last_height;
556 /* True if there's a help-echo in the echo area. */
558 bool help_echo_showing_p;
560 /* The maximum distance to look ahead for text properties. Values
561 that are too small let us call compute_char_face and similar
562 functions too often which is expensive. Values that are too large
563 let us call compute_char_face and alike too often because we
564 might not be interested in text properties that far away. */
566 #define TEXT_PROP_DISTANCE_LIMIT 100
568 /* SAVE_IT and RESTORE_IT are called when we save a snapshot of the
569 iterator state and later restore it. This is needed because the
570 bidi iterator on bidi.c keeps a stacked cache of its states, which
571 is really a singleton. When we use scratch iterator objects to
572 move around the buffer, we can cause the bidi cache to be pushed or
573 popped, and therefore we need to restore the cache state when we
574 return to the original iterator. */
575 #define SAVE_IT(ITCOPY, ITORIG, CACHE) \
576 do { \
577 if (CACHE) \
578 bidi_unshelve_cache (CACHE, true); \
579 ITCOPY = ITORIG; \
580 CACHE = bidi_shelve_cache (); \
581 } while (false)
583 #define RESTORE_IT(pITORIG, pITCOPY, CACHE) \
584 do { \
585 if (pITORIG != pITCOPY) \
586 *(pITORIG) = *(pITCOPY); \
587 bidi_unshelve_cache (CACHE, false); \
588 CACHE = NULL; \
589 } while (false)
591 /* Functions to mark elements as needing redisplay. */
592 enum { REDISPLAY_SOME = 2}; /* Arbitrary choice. */
594 void
595 redisplay_other_windows (void)
597 if (!windows_or_buffers_changed)
598 windows_or_buffers_changed = REDISPLAY_SOME;
601 void
602 wset_redisplay (struct window *w)
604 /* Beware: selected_window can be nil during early stages. */
605 if (!EQ (make_lisp_ptr (w, Lisp_Vectorlike), selected_window))
606 redisplay_other_windows ();
607 w->redisplay = true;
610 void
611 fset_redisplay (struct frame *f)
613 redisplay_other_windows ();
614 f->redisplay = true;
617 void
618 bset_redisplay (struct buffer *b)
620 int count = buffer_window_count (b);
621 if (count > 0)
623 /* ... it's visible in other window than selected, */
624 if (count > 1 || b != XBUFFER (XWINDOW (selected_window)->contents))
625 redisplay_other_windows ();
626 /* Even if we don't set windows_or_buffers_changed, do set `redisplay'
627 so that if we later set windows_or_buffers_changed, this buffer will
628 not be omitted. */
629 b->text->redisplay = true;
633 void
634 bset_update_mode_line (struct buffer *b)
636 if (!update_mode_lines)
637 update_mode_lines = REDISPLAY_SOME;
638 b->text->redisplay = true;
641 DEFUN ("set-buffer-redisplay", Fset_buffer_redisplay,
642 Sset_buffer_redisplay, 4, 4, 0,
643 doc: /* Mark the current buffer for redisplay.
644 This function may be passed to `add-variable-watcher'. */)
645 (Lisp_Object symbol, Lisp_Object newval, Lisp_Object op, Lisp_Object where)
647 bset_update_mode_line (current_buffer);
648 current_buffer->prevent_redisplay_optimizations_p = true;
649 return Qnil;
652 #ifdef GLYPH_DEBUG
654 /* True means print traces of redisplay if compiled with
655 GLYPH_DEBUG defined. */
657 bool trace_redisplay_p;
659 #endif /* GLYPH_DEBUG */
661 #ifdef DEBUG_TRACE_MOVE
662 /* True means trace with TRACE_MOVE to stderr. */
663 static bool trace_move;
665 #define TRACE_MOVE(x) if (trace_move) fprintf x; else (void) 0
666 #else
667 #define TRACE_MOVE(x) (void) 0
668 #endif
670 /* Buffer being redisplayed -- for redisplay_window_error. */
672 static struct buffer *displayed_buffer;
674 /* Value returned from text property handlers (see below). */
676 enum prop_handled
678 HANDLED_NORMALLY,
679 HANDLED_RECOMPUTE_PROPS,
680 HANDLED_OVERLAY_STRING_CONSUMED,
681 HANDLED_RETURN
684 /* A description of text properties that redisplay is interested
685 in. */
687 struct props
689 /* The symbol index of the name of the property. */
690 short name;
692 /* A unique index for the property. */
693 enum prop_idx idx;
695 /* A handler function called to set up iterator IT from the property
696 at IT's current position. Value is used to steer handle_stop. */
697 enum prop_handled (*handler) (struct it *it);
700 static enum prop_handled handle_face_prop (struct it *);
701 static enum prop_handled handle_invisible_prop (struct it *);
702 static enum prop_handled handle_display_prop (struct it *);
703 static enum prop_handled handle_composition_prop (struct it *);
704 static enum prop_handled handle_overlay_change (struct it *);
705 static enum prop_handled handle_fontified_prop (struct it *);
707 /* Properties handled by iterators. */
709 static struct props it_props[] =
711 {SYMBOL_INDEX (Qfontified), FONTIFIED_PROP_IDX, handle_fontified_prop},
712 /* Handle `face' before `display' because some sub-properties of
713 `display' need to know the face. */
714 {SYMBOL_INDEX (Qface), FACE_PROP_IDX, handle_face_prop},
715 {SYMBOL_INDEX (Qdisplay), DISPLAY_PROP_IDX, handle_display_prop},
716 {SYMBOL_INDEX (Qinvisible), INVISIBLE_PROP_IDX, handle_invisible_prop},
717 {SYMBOL_INDEX (Qcomposition), COMPOSITION_PROP_IDX, handle_composition_prop},
718 {0, 0, NULL}
721 /* Value is the position described by X. If X is a marker, value is
722 the marker_position of X. Otherwise, value is X. */
724 #define COERCE_MARKER(X) (MARKERP ((X)) ? Fmarker_position (X) : (X))
726 /* Enumeration returned by some move_it_.* functions internally. */
728 enum move_it_result
730 /* Not used. Undefined value. */
731 MOVE_UNDEFINED,
733 /* Move ended at the requested buffer position or ZV. */
734 MOVE_POS_MATCH_OR_ZV,
736 /* Move ended at the requested X pixel position. */
737 MOVE_X_REACHED,
739 /* Move within a line ended at the end of a line that must be
740 continued. */
741 MOVE_LINE_CONTINUED,
743 /* Move within a line ended at the end of a line that would
744 be displayed truncated. */
745 MOVE_LINE_TRUNCATED,
747 /* Move within a line ended at a line end. */
748 MOVE_NEWLINE_OR_CR
751 /* This counter is used to clear the face cache every once in a while
752 in redisplay_internal. It is incremented for each redisplay.
753 Every CLEAR_FACE_CACHE_COUNT full redisplays, the face cache is
754 cleared. */
756 #define CLEAR_FACE_CACHE_COUNT 500
757 static int clear_face_cache_count;
759 /* Similarly for the image cache. */
761 #ifdef HAVE_WINDOW_SYSTEM
762 #define CLEAR_IMAGE_CACHE_COUNT 101
763 static int clear_image_cache_count;
765 /* Null glyph slice */
766 static struct glyph_slice null_glyph_slice = { 0, 0, 0, 0 };
767 #endif
769 /* True while redisplay_internal is in progress. */
771 bool redisplaying_p;
773 /* If a string, XTread_socket generates an event to display that string.
774 (The display is done in read_char.) */
776 Lisp_Object help_echo_string;
777 Lisp_Object help_echo_window;
778 Lisp_Object help_echo_object;
779 ptrdiff_t help_echo_pos;
781 /* Temporary variable for XTread_socket. */
783 Lisp_Object previous_help_echo_string;
785 /* Platform-independent portion of hourglass implementation. */
787 #ifdef HAVE_WINDOW_SYSTEM
789 /* True means an hourglass cursor is currently shown. */
790 static bool hourglass_shown_p;
792 /* If non-null, an asynchronous timer that, when it expires, displays
793 an hourglass cursor on all frames. */
794 static struct atimer *hourglass_atimer;
796 #endif /* HAVE_WINDOW_SYSTEM */
798 /* Default number of seconds to wait before displaying an hourglass
799 cursor. */
800 #define DEFAULT_HOURGLASS_DELAY 1
802 #ifdef HAVE_WINDOW_SYSTEM
804 /* Default pixel width of `thin-space' display method. */
805 #define THIN_SPACE_WIDTH 1
807 #endif /* HAVE_WINDOW_SYSTEM */
809 /* Function prototypes. */
811 static void setup_for_ellipsis (struct it *, int);
812 static void set_iterator_to_next (struct it *, bool);
813 static void mark_window_display_accurate_1 (struct window *, bool);
814 static bool row_for_charpos_p (struct glyph_row *, ptrdiff_t);
815 static bool cursor_row_p (struct glyph_row *);
816 static int redisplay_mode_lines (Lisp_Object, bool);
818 static void handle_line_prefix (struct it *);
820 static void handle_stop_backwards (struct it *, ptrdiff_t);
821 static void unwind_with_echo_area_buffer (Lisp_Object);
822 static Lisp_Object with_echo_area_buffer_unwind_data (struct window *);
823 static bool current_message_1 (ptrdiff_t, Lisp_Object);
824 static bool truncate_message_1 (ptrdiff_t, Lisp_Object);
825 static void set_message (Lisp_Object);
826 static bool set_message_1 (ptrdiff_t, Lisp_Object);
827 static bool display_echo_area_1 (ptrdiff_t, Lisp_Object);
828 static bool resize_mini_window_1 (ptrdiff_t, Lisp_Object);
829 static void unwind_redisplay (void);
830 static void extend_face_to_end_of_line (struct it *);
831 static intmax_t message_log_check_duplicate (ptrdiff_t, ptrdiff_t);
832 static void push_it (struct it *, struct text_pos *);
833 static void iterate_out_of_display_property (struct it *);
834 static void pop_it (struct it *);
835 static void redisplay_internal (void);
836 static void echo_area_display (bool);
837 static void block_buffer_flips (void);
838 static void unblock_buffer_flips (void);
839 static void redisplay_windows (Lisp_Object);
840 static void redisplay_window (Lisp_Object, bool);
841 static Lisp_Object redisplay_window_error (Lisp_Object);
842 static Lisp_Object redisplay_window_0 (Lisp_Object);
843 static Lisp_Object redisplay_window_1 (Lisp_Object);
844 static bool set_cursor_from_row (struct window *, struct glyph_row *,
845 struct glyph_matrix *, ptrdiff_t, ptrdiff_t,
846 int, int);
847 static bool cursor_row_fully_visible_p (struct window *, bool, bool);
848 static bool update_menu_bar (struct frame *, bool, bool);
849 static bool try_window_reusing_current_matrix (struct window *);
850 static int try_window_id (struct window *);
851 static void maybe_produce_line_number (struct it *);
852 static bool should_produce_line_number (struct it *);
853 static bool display_line (struct it *, int);
854 static int display_mode_lines (struct window *);
855 static int display_mode_line (struct window *, enum face_id, Lisp_Object);
856 static int display_mode_element (struct it *, int, int, int, Lisp_Object,
857 Lisp_Object, bool);
858 static int store_mode_line_string (const char *, Lisp_Object, bool, int, int,
859 Lisp_Object);
860 static const char *decode_mode_spec (struct window *, int, int, Lisp_Object *);
861 static void display_menu_bar (struct window *);
862 static ptrdiff_t display_count_lines (ptrdiff_t, ptrdiff_t, ptrdiff_t,
863 ptrdiff_t *);
864 static void pint2str (register char *, register int, register ptrdiff_t);
866 static int display_string (const char *, Lisp_Object, Lisp_Object,
867 ptrdiff_t, ptrdiff_t, struct it *, int, int, int, int);
868 static void compute_line_metrics (struct it *);
869 static void run_redisplay_end_trigger_hook (struct it *);
870 static bool get_overlay_strings (struct it *, ptrdiff_t);
871 static bool get_overlay_strings_1 (struct it *, ptrdiff_t, bool);
872 static void next_overlay_string (struct it *);
873 static void reseat (struct it *, struct text_pos, bool);
874 static void reseat_1 (struct it *, struct text_pos, bool);
875 static bool next_element_from_display_vector (struct it *);
876 static bool next_element_from_string (struct it *);
877 static bool next_element_from_c_string (struct it *);
878 static bool next_element_from_buffer (struct it *);
879 static bool next_element_from_composition (struct it *);
880 static bool next_element_from_image (struct it *);
881 static bool next_element_from_stretch (struct it *);
882 static bool next_element_from_xwidget (struct it *);
883 static void load_overlay_strings (struct it *, ptrdiff_t);
884 static bool get_next_display_element (struct it *);
885 static enum move_it_result
886 move_it_in_display_line_to (struct it *, ptrdiff_t, int,
887 enum move_operation_enum);
888 static void get_visually_first_element (struct it *);
889 static void compute_stop_pos (struct it *);
890 static int face_before_or_after_it_pos (struct it *, bool);
891 static ptrdiff_t next_overlay_change (ptrdiff_t);
892 static int handle_display_spec (struct it *, Lisp_Object, Lisp_Object,
893 Lisp_Object, struct text_pos *, ptrdiff_t, bool);
894 static int handle_single_display_spec (struct it *, Lisp_Object, Lisp_Object,
895 Lisp_Object, struct text_pos *,
896 ptrdiff_t, int, bool, bool);
897 static int underlying_face_id (struct it *);
899 #define face_before_it_pos(IT) face_before_or_after_it_pos (IT, true)
900 #define face_after_it_pos(IT) face_before_or_after_it_pos (IT, false)
902 #ifdef HAVE_WINDOW_SYSTEM
904 static void update_tool_bar (struct frame *, bool);
905 static void x_draw_bottom_divider (struct window *w);
906 static void notice_overwritten_cursor (struct window *,
907 enum glyph_row_area,
908 int, int, int, int);
909 static int normal_char_height (struct font *, int);
910 static void normal_char_ascent_descent (struct font *, int, int *, int *);
912 static void append_stretch_glyph (struct it *, Lisp_Object,
913 int, int, int);
915 static Lisp_Object get_it_property (struct it *, Lisp_Object);
916 static Lisp_Object calc_line_height_property (struct it *, Lisp_Object,
917 struct font *, int, bool);
919 #endif /* HAVE_WINDOW_SYSTEM */
921 static void produce_special_glyphs (struct it *, enum display_element_type);
922 static void show_mouse_face (Mouse_HLInfo *, enum draw_glyphs_face);
923 static bool coords_in_mouse_face_p (struct window *, int, int);
927 /***********************************************************************
928 Window display dimensions
929 ***********************************************************************/
931 /* Return the bottom boundary y-position for text lines in window W.
932 This is the first y position at which a line cannot start.
933 It is relative to the top of the window.
935 This is the height of W minus the height of a mode line, if any. */
938 window_text_bottom_y (struct window *w)
940 int height = WINDOW_PIXEL_HEIGHT (w);
942 height -= WINDOW_BOTTOM_DIVIDER_WIDTH (w);
944 if (window_wants_mode_line (w))
945 height -= CURRENT_MODE_LINE_HEIGHT (w);
947 height -= WINDOW_SCROLL_BAR_AREA_HEIGHT (w);
949 return height;
952 /* Return the pixel width of display area AREA of window W.
953 ANY_AREA means return the total width of W, not including
954 fringes to the left and right of the window. */
957 window_box_width (struct window *w, enum glyph_row_area area)
959 int width = w->pixel_width;
961 if (!w->pseudo_window_p)
963 width -= WINDOW_SCROLL_BAR_AREA_WIDTH (w);
964 width -= WINDOW_RIGHT_DIVIDER_WIDTH (w);
966 if (area == TEXT_AREA)
967 width -= (WINDOW_MARGINS_WIDTH (w)
968 + WINDOW_FRINGES_WIDTH (w));
969 else if (area == LEFT_MARGIN_AREA)
970 width = WINDOW_LEFT_MARGIN_WIDTH (w);
971 else if (area == RIGHT_MARGIN_AREA)
972 width = WINDOW_RIGHT_MARGIN_WIDTH (w);
975 /* With wide margins, fringes, etc. we might end up with a negative
976 width, correct that here. */
977 return max (0, width);
981 /* Return the pixel height of the display area of window W, not
982 including mode lines of W, if any. */
985 window_box_height (struct window *w)
987 struct frame *f = XFRAME (w->frame);
988 int height = WINDOW_PIXEL_HEIGHT (w);
990 eassert (height >= 0);
992 height -= WINDOW_BOTTOM_DIVIDER_WIDTH (w);
993 height -= WINDOW_SCROLL_BAR_AREA_HEIGHT (w);
995 /* Note: the code below that determines the mode-line/header-line
996 height is essentially the same as that contained in the macro
997 CURRENT_{MODE,HEADER}_LINE_HEIGHT, except that it checks whether
998 the appropriate glyph row has its `mode_line_p' flag set,
999 and if it doesn't, uses estimate_mode_line_height instead. */
1001 if (window_wants_mode_line (w))
1003 struct glyph_row *ml_row
1004 = (w->current_matrix && w->current_matrix->rows
1005 ? MATRIX_MODE_LINE_ROW (w->current_matrix)
1006 : 0);
1007 if (ml_row && ml_row->mode_line_p)
1008 height -= ml_row->height;
1009 else
1010 height -= estimate_mode_line_height (f, CURRENT_MODE_LINE_FACE_ID (w));
1013 if (window_wants_header_line (w))
1015 struct glyph_row *hl_row
1016 = (w->current_matrix && w->current_matrix->rows
1017 ? MATRIX_HEADER_LINE_ROW (w->current_matrix)
1018 : 0);
1019 if (hl_row && hl_row->mode_line_p)
1020 height -= hl_row->height;
1021 else
1022 height -= estimate_mode_line_height (f, HEADER_LINE_FACE_ID);
1025 /* With a very small font and a mode-line that's taller than
1026 default, we might end up with a negative height. */
1027 return max (0, height);
1030 /* Return the window-relative coordinate of the left edge of display
1031 area AREA of window W. ANY_AREA means return the left edge of the
1032 whole window, to the right of the left fringe of W. */
1035 window_box_left_offset (struct window *w, enum glyph_row_area area)
1037 int x;
1039 if (w->pseudo_window_p)
1040 return 0;
1042 x = WINDOW_LEFT_SCROLL_BAR_AREA_WIDTH (w);
1044 if (area == TEXT_AREA)
1045 x += (WINDOW_LEFT_FRINGE_WIDTH (w)
1046 + window_box_width (w, LEFT_MARGIN_AREA));
1047 else if (area == RIGHT_MARGIN_AREA)
1048 x += (WINDOW_LEFT_FRINGE_WIDTH (w)
1049 + window_box_width (w, LEFT_MARGIN_AREA)
1050 + window_box_width (w, TEXT_AREA)
1051 + (WINDOW_HAS_FRINGES_OUTSIDE_MARGINS (w)
1053 : WINDOW_RIGHT_FRINGE_WIDTH (w)));
1054 else if (area == LEFT_MARGIN_AREA
1055 && WINDOW_HAS_FRINGES_OUTSIDE_MARGINS (w))
1056 x += WINDOW_LEFT_FRINGE_WIDTH (w);
1058 /* Don't return more than the window's pixel width. */
1059 return min (x, w->pixel_width);
1063 /* Return the window-relative coordinate of the right edge of display
1064 area AREA of window W. ANY_AREA means return the right edge of the
1065 whole window, to the left of the right fringe of W. */
1067 static int
1068 window_box_right_offset (struct window *w, enum glyph_row_area area)
1070 /* Don't return more than the window's pixel width. */
1071 return min (window_box_left_offset (w, area) + window_box_width (w, area),
1072 w->pixel_width);
1075 /* Return the frame-relative coordinate of the left edge of display
1076 area AREA of window W. ANY_AREA means return the left edge of the
1077 whole window, to the right of the left fringe of W. */
1080 window_box_left (struct window *w, enum glyph_row_area area)
1082 struct frame *f = XFRAME (w->frame);
1083 int x;
1085 if (w->pseudo_window_p)
1086 return FRAME_INTERNAL_BORDER_WIDTH (f);
1088 x = (WINDOW_LEFT_EDGE_X (w)
1089 + window_box_left_offset (w, area));
1091 return x;
1095 /* Return the frame-relative coordinate of the right edge of display
1096 area AREA of window W. ANY_AREA means return the right edge of the
1097 whole window, to the left of the right fringe of W. */
1100 window_box_right (struct window *w, enum glyph_row_area area)
1102 return window_box_left (w, area) + window_box_width (w, area);
1105 /* Get the bounding box of the display area AREA of window W, without
1106 mode lines, in frame-relative coordinates. ANY_AREA means the
1107 whole window, not including the left and right fringes of
1108 the window. Return in *BOX_X and *BOX_Y the frame-relative pixel
1109 coordinates of the upper-left corner of the box. Return in
1110 *BOX_WIDTH, and *BOX_HEIGHT the pixel width and height of the box. */
1112 void
1113 window_box (struct window *w, enum glyph_row_area area, int *box_x,
1114 int *box_y, int *box_width, int *box_height)
1116 if (box_width)
1117 *box_width = window_box_width (w, area);
1118 if (box_height)
1119 *box_height = window_box_height (w);
1120 if (box_x)
1121 *box_x = window_box_left (w, area);
1122 if (box_y)
1124 *box_y = WINDOW_TOP_EDGE_Y (w);
1125 if (window_wants_header_line (w))
1126 *box_y += CURRENT_HEADER_LINE_HEIGHT (w);
1130 #ifdef HAVE_WINDOW_SYSTEM
1132 /* Get the bounding box of the display area AREA of window W, without
1133 mode lines and both fringes of the window. Return in *TOP_LEFT_X
1134 and TOP_LEFT_Y the frame-relative pixel coordinates of the
1135 upper-left corner of the box. Return in *BOTTOM_RIGHT_X, and
1136 *BOTTOM_RIGHT_Y the coordinates of the bottom-right corner of the
1137 box. */
1139 static void
1140 window_box_edges (struct window *w, int *top_left_x, int *top_left_y,
1141 int *bottom_right_x, int *bottom_right_y)
1143 window_box (w, ANY_AREA, top_left_x, top_left_y,
1144 bottom_right_x, bottom_right_y);
1145 *bottom_right_x += *top_left_x;
1146 *bottom_right_y += *top_left_y;
1149 #endif /* HAVE_WINDOW_SYSTEM */
1151 /***********************************************************************
1152 Utilities
1153 ***********************************************************************/
1155 /* Return the bottom y-position of the line the iterator IT is in.
1156 This can modify IT's settings. */
1159 line_bottom_y (struct it *it)
1161 int line_height = it->max_ascent + it->max_descent;
1162 int line_top_y = it->current_y;
1164 if (line_height == 0)
1166 if (last_height)
1167 line_height = last_height;
1168 else if (IT_CHARPOS (*it) < ZV)
1170 move_it_by_lines (it, 1);
1171 line_height = (it->max_ascent || it->max_descent
1172 ? it->max_ascent + it->max_descent
1173 : last_height);
1175 else
1177 struct glyph_row *row = it->glyph_row;
1179 /* Use the default character height. */
1180 it->glyph_row = NULL;
1181 it->what = IT_CHARACTER;
1182 it->c = ' ';
1183 it->len = 1;
1184 PRODUCE_GLYPHS (it);
1185 line_height = it->ascent + it->descent;
1186 it->glyph_row = row;
1190 return line_top_y + line_height;
1193 DEFUN ("line-pixel-height", Fline_pixel_height,
1194 Sline_pixel_height, 0, 0, 0,
1195 doc: /* Return height in pixels of text line in the selected window.
1197 Value is the height in pixels of the line at point. */)
1198 (void)
1200 struct it it;
1201 struct text_pos pt;
1202 struct window *w = XWINDOW (selected_window);
1203 struct buffer *old_buffer = NULL;
1204 Lisp_Object result;
1206 if (XBUFFER (w->contents) != current_buffer)
1208 old_buffer = current_buffer;
1209 set_buffer_internal_1 (XBUFFER (w->contents));
1211 SET_TEXT_POS (pt, PT, PT_BYTE);
1212 start_display (&it, w, pt);
1213 /* Start from the beginning of the screen line, to make sure we
1214 traverse all of its display elements, and thus capture the
1215 correct metrics. */
1216 move_it_by_lines (&it, 0);
1217 it.vpos = it.current_y = 0;
1218 last_height = 0;
1219 result = make_number (line_bottom_y (&it));
1220 if (old_buffer)
1221 set_buffer_internal_1 (old_buffer);
1223 return result;
1226 /* Return the default pixel height of text lines in window W. The
1227 value is the canonical height of the W frame's default font, plus
1228 any extra space required by the line-spacing variable or frame
1229 parameter.
1231 Implementation note: this ignores any line-spacing text properties
1232 put on the newline characters. This is because those properties
1233 only affect the _screen_ line ending in the newline (i.e., in a
1234 continued line, only the last screen line will be affected), which
1235 means only a small number of lines in a buffer can ever use this
1236 feature. Since this function is used to compute the default pixel
1237 equivalent of text lines in a window, we can safely ignore those
1238 few lines. For the same reasons, we ignore the line-height
1239 properties. */
1241 default_line_pixel_height (struct window *w)
1243 struct frame *f = WINDOW_XFRAME (w);
1244 int height = FRAME_LINE_HEIGHT (f);
1246 if (!FRAME_INITIAL_P (f) && BUFFERP (w->contents))
1248 struct buffer *b = XBUFFER (w->contents);
1249 Lisp_Object val = BVAR (b, extra_line_spacing);
1251 if (NILP (val))
1252 val = BVAR (&buffer_defaults, extra_line_spacing);
1253 if (!NILP (val))
1255 if (RANGED_INTEGERP (0, val, INT_MAX))
1256 height += XFASTINT (val);
1257 else if (FLOATP (val))
1259 int addon = XFLOAT_DATA (val) * height + 0.5;
1261 if (addon >= 0)
1262 height += addon;
1265 else
1266 height += f->extra_line_spacing;
1269 return height;
1272 /* Subroutine of pos_visible_p below. Extracts a display string, if
1273 any, from the display spec given as its argument. */
1274 static Lisp_Object
1275 string_from_display_spec (Lisp_Object spec)
1277 if (VECTORP (spec))
1279 for (ptrdiff_t i = 0; i < ASIZE (spec); i++)
1280 if (STRINGP (AREF (spec, i)))
1281 return AREF (spec, i);
1283 else
1285 for (; CONSP (spec); spec = XCDR (spec))
1286 if (STRINGP (XCAR (spec)))
1287 return XCAR (spec);
1289 return spec;
1293 /* Limit insanely large values of W->hscroll on frame F to the largest
1294 value that will still prevent first_visible_x and last_visible_x of
1295 'struct it' from overflowing an int. */
1296 static int
1297 window_hscroll_limited (struct window *w, struct frame *f)
1299 ptrdiff_t window_hscroll = w->hscroll;
1300 int window_text_width = window_box_width (w, TEXT_AREA);
1301 int colwidth = FRAME_COLUMN_WIDTH (f);
1303 if (window_hscroll > (INT_MAX - window_text_width) / colwidth - 1)
1304 window_hscroll = (INT_MAX - window_text_width) / colwidth - 1;
1306 return window_hscroll;
1309 /* Return true if position CHARPOS is visible in window W.
1310 CHARPOS < 0 means return info about WINDOW_END position.
1311 If visible, set *X and *Y to pixel coordinates of top left corner.
1312 Set *RTOP and *RBOT to pixel height of an invisible area of glyph at POS.
1313 Set *ROWH and *VPOS to row's visible height and VPOS (row number). */
1315 bool
1316 pos_visible_p (struct window *w, ptrdiff_t charpos, int *x, int *y,
1317 int *rtop, int *rbot, int *rowh, int *vpos)
1319 struct it it;
1320 void *itdata = bidi_shelve_cache ();
1321 struct text_pos top;
1322 bool visible_p = false;
1323 struct buffer *old_buffer = NULL;
1324 bool r2l = false;
1326 if (FRAME_INITIAL_P (XFRAME (WINDOW_FRAME (w))))
1327 return visible_p;
1329 if (XBUFFER (w->contents) != current_buffer)
1331 old_buffer = current_buffer;
1332 set_buffer_internal_1 (XBUFFER (w->contents));
1335 SET_TEXT_POS_FROM_MARKER (top, w->start);
1336 /* Scrolling a minibuffer window via scroll bar when the echo area
1337 shows long text sometimes resets the minibuffer contents behind
1338 our backs. Also, someone might narrow-to-region and immediately
1339 call a scroll function. */
1340 if (CHARPOS (top) > ZV || CHARPOS (top) < BEGV)
1341 SET_TEXT_POS (top, BEGV, BEGV_BYTE);
1343 /* If the top of the window is after CHARPOS, the latter is surely
1344 not visible. */
1345 if (charpos >= 0 && CHARPOS (top) > charpos)
1346 return visible_p;
1348 /* Some Lisp hook could call us in the middle of redisplaying this
1349 very window. If, by some bad luck, we are retrying redisplay
1350 because we found that the mode-line height and/or header-line
1351 height needs to be updated, the assignment of mode_line_height
1352 and header_line_height below could disrupt that, due to the
1353 selected/nonselected window dance during mode-line display, and
1354 we could infloop. Avoid that. */
1355 int prev_mode_line_height = w->mode_line_height;
1356 int prev_header_line_height = w->header_line_height;
1357 /* Compute exact mode line heights. */
1358 if (window_wants_mode_line (w))
1360 Lisp_Object window_mode_line_format
1361 = window_parameter (w, Qmode_line_format);
1363 w->mode_line_height
1364 = display_mode_line (w, CURRENT_MODE_LINE_FACE_ID (w),
1365 NILP (window_mode_line_format)
1366 ? BVAR (current_buffer, mode_line_format)
1367 : window_mode_line_format);
1370 if (window_wants_header_line (w))
1372 Lisp_Object window_header_line_format
1373 = window_parameter (w, Qheader_line_format);
1375 w->header_line_height
1376 = display_mode_line (w, HEADER_LINE_FACE_ID,
1377 NILP (window_header_line_format)
1378 ? BVAR (current_buffer, header_line_format)
1379 : window_header_line_format);
1382 start_display (&it, w, top);
1383 move_it_to (&it, charpos, -1, it.last_visible_y - 1, -1,
1384 (charpos >= 0 ? MOVE_TO_POS : 0) | MOVE_TO_Y);
1386 /* Adjust for line numbers, if CHARPOS is at or beyond first_visible_x,
1387 but we didn't yet produce the line-number glyphs. */
1388 if (!NILP (Vdisplay_line_numbers)
1389 && it.current_x >= it.first_visible_x
1390 && IT_CHARPOS (it) == charpos
1391 && !it.line_number_produced_p)
1393 /* If the pixel width of line numbers was not yet known, compute
1394 it now. This usually happens in the first display line of a
1395 window. */
1396 if (!it.lnum_pixel_width)
1398 struct it it2;
1399 void *it2data = NULL;
1401 SAVE_IT (it2, it, it2data);
1402 move_it_by_lines (&it, 1);
1403 it2.lnum_pixel_width = it.lnum_pixel_width;
1404 RESTORE_IT (&it, &it2, it2data);
1406 it.current_x += it.lnum_pixel_width;
1409 if (charpos >= 0
1410 && (((!it.bidi_p || it.bidi_it.scan_dir != -1)
1411 && IT_CHARPOS (it) >= charpos)
1412 /* When scanning backwards under bidi iteration, move_it_to
1413 stops at or _before_ CHARPOS, because it stops at or to
1414 the _right_ of the character at CHARPOS. */
1415 || (it.bidi_p && it.bidi_it.scan_dir == -1
1416 && IT_CHARPOS (it) <= charpos)))
1418 /* We have reached CHARPOS, or passed it. How the call to
1419 move_it_to can overshoot: (i) If CHARPOS is on invisible text
1420 or covered by a display property, move_it_to stops at the end
1421 of the invisible text, to the right of CHARPOS. (ii) If
1422 CHARPOS is in a display vector, move_it_to stops on its last
1423 glyph. */
1424 int top_x = it.current_x;
1425 int top_y = it.current_y;
1426 int window_top_y = WINDOW_HEADER_LINE_HEIGHT (w);
1427 int bottom_y;
1428 struct it save_it;
1429 void *save_it_data = NULL;
1431 /* Calling line_bottom_y may change it.method, it.position, etc. */
1432 SAVE_IT (save_it, it, save_it_data);
1433 last_height = 0;
1434 bottom_y = line_bottom_y (&it);
1435 if (top_y < window_top_y)
1436 visible_p = bottom_y > window_top_y;
1437 else if (top_y < it.last_visible_y)
1438 visible_p = true;
1439 if (bottom_y >= it.last_visible_y
1440 && it.bidi_p && it.bidi_it.scan_dir == -1
1441 && IT_CHARPOS (it) < charpos)
1443 /* When the last line of the window is scanned backwards
1444 under bidi iteration, we could be duped into thinking
1445 that we have passed CHARPOS, when in fact move_it_to
1446 simply stopped short of CHARPOS because it reached
1447 last_visible_y. To see if that's what happened, we call
1448 move_it_to again with a slightly larger vertical limit,
1449 and see if it actually moved vertically; if it did, we
1450 didn't really reach CHARPOS, which is beyond window end. */
1451 /* Why 10? because we don't know how many canonical lines
1452 will the height of the next line(s) be. So we guess. */
1453 int ten_more_lines = 10 * default_line_pixel_height (w);
1455 move_it_to (&it, charpos, -1, bottom_y + ten_more_lines, -1,
1456 MOVE_TO_POS | MOVE_TO_Y);
1457 if (it.current_y > top_y)
1458 visible_p = false;
1461 RESTORE_IT (&it, &save_it, save_it_data);
1462 if (visible_p)
1464 if (it.method == GET_FROM_DISPLAY_VECTOR)
1466 /* We stopped on the last glyph of a display vector.
1467 Try and recompute. Hack alert! */
1468 if (charpos < 2 || top.charpos >= charpos)
1469 top_x = it.glyph_row->x;
1470 else
1472 struct it it2, it2_prev;
1473 /* The idea is to get to the previous buffer
1474 position, consume the character there, and use
1475 the pixel coordinates we get after that. But if
1476 the previous buffer position is also displayed
1477 from a display vector, we need to consume all of
1478 the glyphs from that display vector. */
1479 start_display (&it2, w, top);
1480 move_it_to (&it2, charpos - 1, -1, -1, -1, MOVE_TO_POS);
1481 /* If we didn't get to CHARPOS - 1, there's some
1482 replacing display property at that position, and
1483 we stopped after it. That is exactly the place
1484 whose coordinates we want. */
1485 if (IT_CHARPOS (it2) != charpos - 1)
1486 it2_prev = it2;
1487 else
1489 /* Iterate until we get out of the display
1490 vector that displays the character at
1491 CHARPOS - 1. */
1492 do {
1493 get_next_display_element (&it2);
1494 PRODUCE_GLYPHS (&it2);
1495 it2_prev = it2;
1496 set_iterator_to_next (&it2, true);
1497 } while (it2.method == GET_FROM_DISPLAY_VECTOR
1498 && IT_CHARPOS (it2) < charpos);
1500 if (ITERATOR_AT_END_OF_LINE_P (&it2_prev)
1501 || it2_prev.current_x > it2_prev.last_visible_x)
1502 top_x = it.glyph_row->x;
1503 else
1505 top_x = it2_prev.current_x;
1506 top_y = it2_prev.current_y;
1510 else if (IT_CHARPOS (it) != charpos)
1512 Lisp_Object cpos = make_number (charpos);
1513 Lisp_Object spec = Fget_char_property (cpos, Qdisplay, Qnil);
1514 Lisp_Object string = string_from_display_spec (spec);
1515 struct text_pos tpos;
1516 bool newline_in_string
1517 = (STRINGP (string)
1518 && memchr (SDATA (string), '\n', SBYTES (string)));
1520 SET_TEXT_POS (tpos, charpos, CHAR_TO_BYTE (charpos));
1521 bool replacing_spec_p
1522 = (!NILP (spec)
1523 && handle_display_spec (NULL, spec, Qnil, Qnil, &tpos,
1524 charpos, FRAME_WINDOW_P (it.f)));
1525 /* The tricky code below is needed because there's a
1526 discrepancy between move_it_to and how we set cursor
1527 when PT is at the beginning of a portion of text
1528 covered by a display property or an overlay with a
1529 display property, or the display line ends in a
1530 newline from a display string. move_it_to will stop
1531 _after_ such display strings, whereas
1532 set_cursor_from_row conspires with cursor_row_p to
1533 place the cursor on the first glyph produced from the
1534 display string. */
1536 /* We have overshoot PT because it is covered by a
1537 display property that replaces the text it covers.
1538 If the string includes embedded newlines, we are also
1539 in the wrong display line. Backtrack to the correct
1540 line, where the display property begins. */
1541 if (replacing_spec_p)
1543 Lisp_Object startpos, endpos;
1544 EMACS_INT start, end;
1545 struct it it3;
1547 /* Find the first and the last buffer positions
1548 covered by the display string. */
1549 endpos =
1550 Fnext_single_char_property_change (cpos, Qdisplay,
1551 Qnil, Qnil);
1552 startpos =
1553 Fprevious_single_char_property_change (endpos, Qdisplay,
1554 Qnil, Qnil);
1555 start = XFASTINT (startpos);
1556 end = XFASTINT (endpos);
1557 /* Move to the last buffer position before the
1558 display property. */
1559 start_display (&it3, w, top);
1560 if (start > CHARPOS (top))
1561 move_it_to (&it3, start - 1, -1, -1, -1, MOVE_TO_POS);
1562 /* Move forward one more line if the position before
1563 the display string is a newline or if it is the
1564 rightmost character on a line that is
1565 continued or word-wrapped. */
1566 if (it3.method == GET_FROM_BUFFER
1567 && (it3.c == '\n'
1568 || FETCH_BYTE (IT_BYTEPOS (it3)) == '\n'))
1569 move_it_by_lines (&it3, 1);
1570 else if (move_it_in_display_line_to (&it3, -1,
1571 it3.current_x
1572 + it3.pixel_width,
1573 MOVE_TO_X)
1574 == MOVE_LINE_CONTINUED)
1576 move_it_by_lines (&it3, 1);
1577 /* When we are under word-wrap, the #$@%!
1578 move_it_by_lines moves 2 lines, so we need to
1579 fix that up. */
1580 if (it3.line_wrap == WORD_WRAP)
1581 move_it_by_lines (&it3, -1);
1584 /* Record the vertical coordinate of the display
1585 line where we wound up. */
1586 top_y = it3.current_y;
1587 if (it3.bidi_p)
1589 /* When characters are reordered for display,
1590 the character displayed to the left of the
1591 display string could be _after_ the display
1592 property in the logical order. Use the
1593 smallest vertical position of these two. */
1594 start_display (&it3, w, top);
1595 move_it_to (&it3, end + 1, -1, -1, -1, MOVE_TO_POS);
1596 if (it3.current_y < top_y)
1597 top_y = it3.current_y;
1599 /* Move from the top of the window to the beginning
1600 of the display line where the display string
1601 begins. */
1602 start_display (&it3, w, top);
1603 move_it_to (&it3, -1, 0, top_y, -1, MOVE_TO_X | MOVE_TO_Y);
1604 /* If it3_moved stays false after the 'while' loop
1605 below, that means we already were at a newline
1606 before the loop (e.g., the display string begins
1607 with a newline), so we don't need to (and cannot)
1608 inspect the glyphs of it3.glyph_row, because
1609 PRODUCE_GLYPHS will not produce anything for a
1610 newline, and thus it3.glyph_row stays at its
1611 stale content it got at top of the window. */
1612 bool it3_moved = false;
1613 /* Finally, advance the iterator until we hit the
1614 first display element whose character position is
1615 CHARPOS, or until the first newline from the
1616 display string, which signals the end of the
1617 display line. */
1618 while (get_next_display_element (&it3))
1620 PRODUCE_GLYPHS (&it3);
1621 if (IT_CHARPOS (it3) == charpos
1622 || ITERATOR_AT_END_OF_LINE_P (&it3))
1623 break;
1624 it3_moved = true;
1625 set_iterator_to_next (&it3, false);
1627 top_x = it3.current_x - it3.pixel_width;
1628 /* Normally, we would exit the above loop because we
1629 found the display element whose character
1630 position is CHARPOS. For the contingency that we
1631 didn't, and stopped at the first newline from the
1632 display string, move back over the glyphs
1633 produced from the string, until we find the
1634 rightmost glyph not from the string. */
1635 if (it3_moved
1636 && newline_in_string
1637 && IT_CHARPOS (it3) != charpos && EQ (it3.object, string))
1639 struct glyph *g = it3.glyph_row->glyphs[TEXT_AREA]
1640 + it3.glyph_row->used[TEXT_AREA];
1642 while (EQ ((g - 1)->object, string))
1644 --g;
1645 top_x -= g->pixel_width;
1647 eassert (g < it3.glyph_row->glyphs[TEXT_AREA]
1648 + it3.glyph_row->used[TEXT_AREA]);
1653 *x = top_x;
1654 *y = max (top_y + max (0, it.max_ascent - it.ascent), window_top_y);
1655 *rtop = max (0, window_top_y - top_y);
1656 *rbot = max (0, bottom_y - it.last_visible_y);
1657 *rowh = max (0, (min (bottom_y, it.last_visible_y)
1658 - max (top_y, window_top_y)));
1659 *vpos = it.vpos;
1660 if (it.bidi_it.paragraph_dir == R2L)
1661 r2l = true;
1664 else
1666 /* Either we were asked to provide info about WINDOW_END, or
1667 CHARPOS is in the partially visible glyph row at end of
1668 window. */
1669 struct it it2;
1670 void *it2data = NULL;
1672 SAVE_IT (it2, it, it2data);
1673 if (IT_CHARPOS (it) < ZV && FETCH_BYTE (IT_BYTEPOS (it)) != '\n')
1674 move_it_by_lines (&it, 1);
1675 if (charpos < IT_CHARPOS (it)
1676 || (it.what == IT_EOB && charpos == IT_CHARPOS (it)))
1678 visible_p = true;
1679 RESTORE_IT (&it2, &it2, it2data);
1680 move_it_to (&it2, charpos, -1, -1, -1, MOVE_TO_POS);
1681 *x = it2.current_x;
1682 *y = it2.current_y + it2.max_ascent - it2.ascent;
1683 *rtop = max (0, -it2.current_y);
1684 *rbot = max (0, ((it2.current_y + it2.max_ascent + it2.max_descent)
1685 - it.last_visible_y));
1686 *rowh = max (0, (min (it2.current_y + it2.max_ascent + it2.max_descent,
1687 it.last_visible_y)
1688 - max (it2.current_y,
1689 WINDOW_HEADER_LINE_HEIGHT (w))));
1690 *vpos = it2.vpos;
1691 if (it2.bidi_it.paragraph_dir == R2L)
1692 r2l = true;
1694 else
1695 bidi_unshelve_cache (it2data, true);
1697 bidi_unshelve_cache (itdata, false);
1699 if (old_buffer)
1700 set_buffer_internal_1 (old_buffer);
1702 if (visible_p)
1704 if (w->hscroll > 0)
1705 *x -=
1706 window_hscroll_limited (w, WINDOW_XFRAME (w))
1707 * WINDOW_FRAME_COLUMN_WIDTH (w);
1708 /* For lines in an R2L paragraph, we need to mirror the X pixel
1709 coordinate wrt the text area. For the reasons, see the
1710 commentary in buffer_posn_from_coords and the explanation of
1711 the geometry used by the move_it_* functions at the end of
1712 the large commentary near the beginning of this file. */
1713 if (r2l)
1714 *x = window_box_width (w, TEXT_AREA) - *x - 1;
1717 #if false
1718 /* Debugging code. */
1719 if (visible_p)
1720 fprintf (stderr, "+pv pt=%d vs=%d --> x=%d y=%d rt=%d rb=%d rh=%d vp=%d\n",
1721 charpos, w->vscroll, *x, *y, *rtop, *rbot, *rowh, *vpos);
1722 else
1723 fprintf (stderr, "-pv pt=%d vs=%d\n", charpos, w->vscroll);
1724 #endif
1726 /* Restore potentially overwritten values. */
1727 w->mode_line_height = prev_mode_line_height;
1728 w->header_line_height = prev_header_line_height;
1730 return visible_p;
1734 /* Return the next character from STR. Return in *LEN the length of
1735 the character. This is like STRING_CHAR_AND_LENGTH but never
1736 returns an invalid character. If we find one, we return a `?', but
1737 with the length of the invalid character. */
1739 static int
1740 string_char_and_length (const unsigned char *str, int *len)
1742 int c;
1744 c = STRING_CHAR_AND_LENGTH (str, *len);
1745 if (!CHAR_VALID_P (c))
1746 /* We may not change the length here because other places in Emacs
1747 don't use this function, i.e. they silently accept invalid
1748 characters. */
1749 c = '?';
1751 return c;
1756 /* Given a position POS containing a valid character and byte position
1757 in STRING, return the position NCHARS ahead (NCHARS >= 0). */
1759 static struct text_pos
1760 string_pos_nchars_ahead (struct text_pos pos, Lisp_Object string, ptrdiff_t nchars)
1762 eassert (STRINGP (string) && nchars >= 0);
1764 if (STRING_MULTIBYTE (string))
1766 const unsigned char *p = SDATA (string) + BYTEPOS (pos);
1767 int len;
1769 while (nchars--)
1771 string_char_and_length (p, &len);
1772 p += len;
1773 CHARPOS (pos) += 1;
1774 BYTEPOS (pos) += len;
1777 else
1778 SET_TEXT_POS (pos, CHARPOS (pos) + nchars, BYTEPOS (pos) + nchars);
1780 return pos;
1784 /* Value is the text position, i.e. character and byte position,
1785 for character position CHARPOS in STRING. */
1787 static struct text_pos
1788 string_pos (ptrdiff_t charpos, Lisp_Object string)
1790 struct text_pos pos;
1791 eassert (STRINGP (string));
1792 eassert (charpos >= 0);
1793 SET_TEXT_POS (pos, charpos, string_char_to_byte (string, charpos));
1794 return pos;
1798 /* Value is a text position, i.e. character and byte position, for
1799 character position CHARPOS in C string S. MULTIBYTE_P
1800 means recognize multibyte characters. */
1802 static struct text_pos
1803 c_string_pos (ptrdiff_t charpos, const char *s, bool multibyte_p)
1805 struct text_pos pos;
1807 eassert (s != NULL);
1808 eassert (charpos >= 0);
1810 if (multibyte_p)
1812 int len;
1814 SET_TEXT_POS (pos, 0, 0);
1815 while (charpos--)
1817 string_char_and_length ((const unsigned char *) s, &len);
1818 s += len;
1819 CHARPOS (pos) += 1;
1820 BYTEPOS (pos) += len;
1823 else
1824 SET_TEXT_POS (pos, charpos, charpos);
1826 return pos;
1830 /* Value is the number of characters in C string S. MULTIBYTE_P
1831 means recognize multibyte characters. */
1833 static ptrdiff_t
1834 number_of_chars (const char *s, bool multibyte_p)
1836 ptrdiff_t nchars;
1838 if (multibyte_p)
1840 ptrdiff_t rest = strlen (s);
1841 int len;
1842 const unsigned char *p = (const unsigned char *) s;
1844 for (nchars = 0; rest > 0; ++nchars)
1846 string_char_and_length (p, &len);
1847 rest -= len, p += len;
1850 else
1851 nchars = strlen (s);
1853 return nchars;
1857 /* Compute byte position NEWPOS->bytepos corresponding to
1858 NEWPOS->charpos. POS is a known position in string STRING.
1859 NEWPOS->charpos must be >= POS.charpos. */
1861 static void
1862 compute_string_pos (struct text_pos *newpos, struct text_pos pos, Lisp_Object string)
1864 eassert (STRINGP (string));
1865 eassert (CHARPOS (*newpos) >= CHARPOS (pos));
1867 if (STRING_MULTIBYTE (string))
1868 *newpos = string_pos_nchars_ahead (pos, string,
1869 CHARPOS (*newpos) - CHARPOS (pos));
1870 else
1871 BYTEPOS (*newpos) = CHARPOS (*newpos);
1874 /* EXPORT:
1875 Return an estimation of the pixel height of mode or header lines on
1876 frame F. FACE_ID specifies what line's height to estimate. */
1879 estimate_mode_line_height (struct frame *f, enum face_id face_id)
1881 #ifdef HAVE_WINDOW_SYSTEM
1882 if (FRAME_WINDOW_P (f))
1884 int height = FONT_HEIGHT (FRAME_FONT (f));
1886 /* This function is called so early when Emacs starts that the face
1887 cache and mode line face are not yet initialized. */
1888 if (FRAME_FACE_CACHE (f))
1890 struct face *face = FACE_FROM_ID_OR_NULL (f, face_id);
1891 if (face)
1893 if (face->font)
1894 height = normal_char_height (face->font, -1);
1895 if (face->box_line_width > 0)
1896 height += 2 * face->box_line_width;
1900 return height;
1902 #endif
1904 return 1;
1907 /* Given a pixel position (PIX_X, PIX_Y) on frame F, return glyph
1908 co-ordinates in (*X, *Y). Set *BOUNDS to the rectangle that the
1909 glyph at X, Y occupies, if BOUNDS != 0. If NOCLIP, do
1910 not force the value into range. */
1912 void
1913 pixel_to_glyph_coords (struct frame *f, int pix_x, int pix_y, int *x, int *y,
1914 NativeRectangle *bounds, bool noclip)
1917 #ifdef HAVE_WINDOW_SYSTEM
1918 if (FRAME_WINDOW_P (f))
1920 /* Arrange for the division in FRAME_PIXEL_X_TO_COL etc. to round down
1921 even for negative values. */
1922 if (pix_x < 0)
1923 pix_x -= FRAME_COLUMN_WIDTH (f) - 1;
1924 if (pix_y < 0)
1925 pix_y -= FRAME_LINE_HEIGHT (f) - 1;
1927 pix_x = FRAME_PIXEL_X_TO_COL (f, pix_x);
1928 pix_y = FRAME_PIXEL_Y_TO_LINE (f, pix_y);
1930 if (bounds)
1931 STORE_NATIVE_RECT (*bounds,
1932 FRAME_COL_TO_PIXEL_X (f, pix_x),
1933 FRAME_LINE_TO_PIXEL_Y (f, pix_y),
1934 FRAME_COLUMN_WIDTH (f) - 1,
1935 FRAME_LINE_HEIGHT (f) - 1);
1937 /* PXW: Should we clip pixels before converting to columns/lines? */
1938 if (!noclip)
1940 if (pix_x < 0)
1941 pix_x = 0;
1942 else if (pix_x > FRAME_TOTAL_COLS (f))
1943 pix_x = FRAME_TOTAL_COLS (f);
1945 if (pix_y < 0)
1946 pix_y = 0;
1947 else if (pix_y > FRAME_TOTAL_LINES (f))
1948 pix_y = FRAME_TOTAL_LINES (f);
1951 #endif
1953 *x = pix_x;
1954 *y = pix_y;
1958 /* Find the glyph under window-relative coordinates X/Y in window W.
1959 Consider only glyphs from buffer text, i.e. no glyphs from overlay
1960 strings. Return in *HPOS and *VPOS the row and column number of
1961 the glyph found. Return in *AREA the glyph area containing X.
1962 Value is a pointer to the glyph found or null if X/Y is not on
1963 text, or we can't tell because W's current matrix is not up to
1964 date. */
1966 static struct glyph *
1967 x_y_to_hpos_vpos (struct window *w, int x, int y, int *hpos, int *vpos,
1968 int *dx, int *dy, int *area)
1970 struct glyph *glyph, *end;
1971 struct glyph_row *row = NULL;
1972 int x0, i;
1974 /* Find row containing Y. Give up if some row is not enabled. */
1975 for (i = 0; i < w->current_matrix->nrows; ++i)
1977 row = MATRIX_ROW (w->current_matrix, i);
1978 if (!row->enabled_p)
1979 return NULL;
1980 if (y >= row->y && y < MATRIX_ROW_BOTTOM_Y (row))
1981 break;
1984 *vpos = i;
1985 *hpos = 0;
1987 /* Give up if Y is not in the window. */
1988 if (i == w->current_matrix->nrows)
1989 return NULL;
1991 /* Get the glyph area containing X. */
1992 if (w->pseudo_window_p)
1994 *area = TEXT_AREA;
1995 x0 = 0;
1997 else
1999 if (x < window_box_left_offset (w, TEXT_AREA))
2001 *area = LEFT_MARGIN_AREA;
2002 x0 = window_box_left_offset (w, LEFT_MARGIN_AREA);
2004 else if (x < window_box_right_offset (w, TEXT_AREA))
2006 *area = TEXT_AREA;
2007 x0 = window_box_left_offset (w, TEXT_AREA) + min (row->x, 0);
2009 else
2011 *area = RIGHT_MARGIN_AREA;
2012 x0 = window_box_left_offset (w, RIGHT_MARGIN_AREA);
2016 /* Find glyph containing X. */
2017 glyph = row->glyphs[*area];
2018 end = glyph + row->used[*area];
2019 x -= x0;
2020 while (glyph < end && x >= glyph->pixel_width)
2022 x -= glyph->pixel_width;
2023 ++glyph;
2026 if (glyph == end)
2027 return NULL;
2029 if (dx)
2031 *dx = x;
2032 *dy = y - (row->y + row->ascent - glyph->ascent);
2035 *hpos = glyph - row->glyphs[*area];
2036 return glyph;
2039 /* Convert frame-relative x/y to coordinates relative to window W.
2040 Takes pseudo-windows into account. */
2042 static void
2043 frame_to_window_pixel_xy (struct window *w, int *x, int *y)
2045 if (w->pseudo_window_p)
2047 /* A pseudo-window is always full-width, and starts at the
2048 left edge of the frame, plus a frame border. */
2049 struct frame *f = XFRAME (w->frame);
2050 *x -= FRAME_INTERNAL_BORDER_WIDTH (f);
2051 *y = FRAME_TO_WINDOW_PIXEL_Y (w, *y);
2053 else
2055 *x -= WINDOW_LEFT_EDGE_X (w);
2056 *y = FRAME_TO_WINDOW_PIXEL_Y (w, *y);
2060 #ifdef HAVE_WINDOW_SYSTEM
2062 /* EXPORT:
2063 Return in RECTS[] at most N clipping rectangles for glyph string S.
2064 Return the number of stored rectangles. */
2067 get_glyph_string_clip_rects (struct glyph_string *s, NativeRectangle *rects, int n)
2069 XRectangle r;
2071 if (n <= 0)
2072 return 0;
2074 if (s->row->full_width_p)
2076 /* Draw full-width. X coordinates are relative to S->w->left_col. */
2077 r.x = WINDOW_LEFT_EDGE_X (s->w);
2078 if (s->row->mode_line_p)
2079 r.width = WINDOW_PIXEL_WIDTH (s->w) - WINDOW_RIGHT_DIVIDER_WIDTH (s->w);
2080 else
2081 r.width = WINDOW_PIXEL_WIDTH (s->w);
2083 /* Unless displaying a mode or menu bar line, which are always
2084 fully visible, clip to the visible part of the row. */
2085 if (s->w->pseudo_window_p)
2086 r.height = s->row->visible_height;
2087 else
2088 r.height = s->height;
2090 else
2092 /* This is a text line that may be partially visible. */
2093 r.x = window_box_left (s->w, s->area);
2094 r.width = window_box_width (s->w, s->area);
2095 r.height = s->row->visible_height;
2098 if (s->clip_head)
2099 if (r.x < s->clip_head->x)
2101 if (r.width >= s->clip_head->x - r.x)
2102 r.width -= s->clip_head->x - r.x;
2103 else
2104 r.width = 0;
2105 r.x = s->clip_head->x;
2107 if (s->clip_tail)
2108 if (r.x + r.width > s->clip_tail->x + s->clip_tail->background_width)
2110 if (s->clip_tail->x + s->clip_tail->background_width >= r.x)
2111 r.width = s->clip_tail->x + s->clip_tail->background_width - r.x;
2112 else
2113 r.width = 0;
2116 /* If S draws overlapping rows, it's sufficient to use the top and
2117 bottom of the window for clipping because this glyph string
2118 intentionally draws over other lines. */
2119 if (s->for_overlaps)
2121 r.y = WINDOW_HEADER_LINE_HEIGHT (s->w);
2122 r.height = window_text_bottom_y (s->w) - r.y;
2124 /* Alas, the above simple strategy does not work for the
2125 environments with anti-aliased text: if the same text is
2126 drawn onto the same place multiple times, it gets thicker.
2127 If the overlap we are processing is for the erased cursor, we
2128 take the intersection with the rectangle of the cursor. */
2129 if (s->for_overlaps & OVERLAPS_ERASED_CURSOR)
2131 XRectangle rc, r_save = r;
2133 rc.x = WINDOW_TEXT_TO_FRAME_PIXEL_X (s->w, s->w->phys_cursor.x);
2134 rc.y = s->w->phys_cursor.y;
2135 rc.width = s->w->phys_cursor_width;
2136 rc.height = s->w->phys_cursor_height;
2138 x_intersect_rectangles (&r_save, &rc, &r);
2141 else
2143 /* Don't use S->y for clipping because it doesn't take partially
2144 visible lines into account. For example, it can be negative for
2145 partially visible lines at the top of a window. */
2146 if (!s->row->full_width_p
2147 && MATRIX_ROW_PARTIALLY_VISIBLE_AT_TOP_P (s->w, s->row))
2148 r.y = WINDOW_HEADER_LINE_HEIGHT (s->w);
2149 else
2150 r.y = max (0, s->row->y);
2153 r.y = WINDOW_TO_FRAME_PIXEL_Y (s->w, r.y);
2155 /* If drawing the cursor, don't let glyph draw outside its
2156 advertised boundaries. Cleartype does this under some circumstances. */
2157 if (s->hl == DRAW_CURSOR)
2159 struct glyph *glyph = s->first_glyph;
2160 int height, max_y;
2162 if (s->x > r.x)
2164 if (r.width >= s->x - r.x)
2165 r.width -= s->x - r.x;
2166 else /* R2L hscrolled row with cursor outside text area */
2167 r.width = 0;
2168 r.x = s->x;
2170 r.width = min (r.width, glyph->pixel_width);
2172 /* If r.y is below window bottom, ensure that we still see a cursor. */
2173 height = min (glyph->ascent + glyph->descent,
2174 min (FRAME_LINE_HEIGHT (s->f), s->row->visible_height));
2175 max_y = window_text_bottom_y (s->w) - height;
2176 max_y = WINDOW_TO_FRAME_PIXEL_Y (s->w, max_y);
2177 if (s->ybase - glyph->ascent > max_y)
2179 r.y = max_y;
2180 r.height = height;
2182 else
2184 /* Don't draw cursor glyph taller than our actual glyph. */
2185 height = max (FRAME_LINE_HEIGHT (s->f), glyph->ascent + glyph->descent);
2186 if (height < r.height)
2188 max_y = r.y + r.height;
2189 r.y = min (max_y, max (r.y, s->ybase + glyph->descent - height));
2190 r.height = min (max_y - r.y, height);
2195 if (s->row->clip)
2197 XRectangle r_save = r;
2199 if (! x_intersect_rectangles (&r_save, s->row->clip, &r))
2200 r.width = 0;
2203 if ((s->for_overlaps & OVERLAPS_BOTH) == 0
2204 || ((s->for_overlaps & OVERLAPS_BOTH) == OVERLAPS_BOTH && n == 1))
2206 #ifdef CONVERT_FROM_XRECT
2207 CONVERT_FROM_XRECT (r, *rects);
2208 #else
2209 *rects = r;
2210 #endif
2211 return 1;
2213 else
2215 /* If we are processing overlapping and allowed to return
2216 multiple clipping rectangles, we exclude the row of the glyph
2217 string from the clipping rectangle. This is to avoid drawing
2218 the same text on the environment with anti-aliasing. */
2219 #ifdef CONVERT_FROM_XRECT
2220 XRectangle rs[2];
2221 #else
2222 XRectangle *rs = rects;
2223 #endif
2224 int i = 0, row_y = WINDOW_TO_FRAME_PIXEL_Y (s->w, s->row->y);
2226 if (s->for_overlaps & OVERLAPS_PRED)
2228 rs[i] = r;
2229 if (r.y + r.height > row_y)
2231 if (r.y < row_y)
2232 rs[i].height = row_y - r.y;
2233 else
2234 rs[i].height = 0;
2236 i++;
2238 if (s->for_overlaps & OVERLAPS_SUCC)
2240 rs[i] = r;
2241 if (r.y < row_y + s->row->visible_height)
2243 if (r.y + r.height > row_y + s->row->visible_height)
2245 rs[i].y = row_y + s->row->visible_height;
2246 rs[i].height = r.y + r.height - rs[i].y;
2248 else
2249 rs[i].height = 0;
2251 i++;
2254 n = i;
2255 #ifdef CONVERT_FROM_XRECT
2256 for (i = 0; i < n; i++)
2257 CONVERT_FROM_XRECT (rs[i], rects[i]);
2258 #endif
2259 return n;
2263 /* EXPORT:
2264 Return in *NR the clipping rectangle for glyph string S. */
2266 void
2267 get_glyph_string_clip_rect (struct glyph_string *s, NativeRectangle *nr)
2269 get_glyph_string_clip_rects (s, nr, 1);
2273 /* EXPORT:
2274 Return the position and height of the phys cursor in window W.
2275 Set w->phys_cursor_width to width of phys cursor.
2278 void
2279 get_phys_cursor_geometry (struct window *w, struct glyph_row *row,
2280 struct glyph *glyph, int *xp, int *yp, int *heightp)
2282 struct frame *f = XFRAME (WINDOW_FRAME (w));
2283 int x, y, wd, h, h0, y0, ascent;
2285 /* Compute the width of the rectangle to draw. If on a stretch
2286 glyph, and `x-stretch-block-cursor' is nil, don't draw a
2287 rectangle as wide as the glyph, but use a canonical character
2288 width instead. */
2289 wd = glyph->pixel_width;
2291 x = w->phys_cursor.x;
2292 if (x < 0)
2294 wd += x;
2295 x = 0;
2298 if (glyph->type == STRETCH_GLYPH
2299 && !x_stretch_cursor_p)
2300 wd = min (FRAME_COLUMN_WIDTH (f), wd);
2301 w->phys_cursor_width = wd;
2303 /* Don't let the hollow cursor glyph descend below the glyph row's
2304 ascent value, lest the hollow cursor looks funny. */
2305 y = w->phys_cursor.y;
2306 ascent = row->ascent;
2307 if (row->ascent < glyph->ascent)
2309 y -= glyph->ascent - row->ascent;
2310 ascent = glyph->ascent;
2313 /* If y is below window bottom, ensure that we still see a cursor. */
2314 h0 = min (FRAME_LINE_HEIGHT (f), row->visible_height);
2316 h = max (h0, ascent + glyph->descent);
2317 h0 = min (h0, ascent + glyph->descent);
2319 y0 = WINDOW_HEADER_LINE_HEIGHT (w);
2320 if (y < y0)
2322 h = max (h - (y0 - y) + 1, h0);
2323 y = y0 - 1;
2325 else
2327 y0 = window_text_bottom_y (w) - h0;
2328 if (y > y0)
2330 h += y - y0;
2331 y = y0;
2335 *xp = WINDOW_TEXT_TO_FRAME_PIXEL_X (w, x);
2336 *yp = WINDOW_TO_FRAME_PIXEL_Y (w, y);
2337 *heightp = h;
2341 * Remember which glyph the mouse is over.
2344 void
2345 remember_mouse_glyph (struct frame *f, int gx, int gy, NativeRectangle *rect)
2347 Lisp_Object window;
2348 struct window *w;
2349 struct glyph_row *r, *gr, *end_row;
2350 enum window_part part;
2351 enum glyph_row_area area;
2352 int x, y, width, height;
2354 /* Try to determine frame pixel position and size of the glyph under
2355 frame pixel coordinates X/Y on frame F. */
2357 if (window_resize_pixelwise)
2359 width = height = 1;
2360 goto virtual_glyph;
2362 else if (!f->glyphs_initialized_p
2363 || (window = window_from_coordinates (f, gx, gy, &part, false),
2364 NILP (window)))
2366 width = FRAME_SMALLEST_CHAR_WIDTH (f);
2367 height = FRAME_SMALLEST_FONT_HEIGHT (f);
2368 goto virtual_glyph;
2371 w = XWINDOW (window);
2372 width = WINDOW_FRAME_COLUMN_WIDTH (w);
2373 height = WINDOW_FRAME_LINE_HEIGHT (w);
2375 x = window_relative_x_coord (w, part, gx);
2376 y = gy - WINDOW_TOP_EDGE_Y (w);
2378 r = MATRIX_FIRST_TEXT_ROW (w->current_matrix);
2379 end_row = MATRIX_BOTTOM_TEXT_ROW (w->current_matrix, w);
2381 if (w->pseudo_window_p)
2383 area = TEXT_AREA;
2384 part = ON_MODE_LINE; /* Don't adjust margin. */
2385 goto text_glyph;
2388 switch (part)
2390 case ON_LEFT_MARGIN:
2391 area = LEFT_MARGIN_AREA;
2392 goto text_glyph;
2394 case ON_RIGHT_MARGIN:
2395 area = RIGHT_MARGIN_AREA;
2396 goto text_glyph;
2398 case ON_HEADER_LINE:
2399 case ON_MODE_LINE:
2400 gr = (part == ON_HEADER_LINE
2401 ? MATRIX_HEADER_LINE_ROW (w->current_matrix)
2402 : MATRIX_MODE_LINE_ROW (w->current_matrix));
2403 gy = gr->y;
2404 area = TEXT_AREA;
2405 goto text_glyph_row_found;
2407 case ON_TEXT:
2408 area = TEXT_AREA;
2410 text_glyph:
2411 gr = 0; gy = 0;
2412 for (; r <= end_row && r->enabled_p; ++r)
2413 if (r->y + r->height > y)
2415 gr = r; gy = r->y;
2416 break;
2419 text_glyph_row_found:
2420 if (gr && gy <= y)
2422 struct glyph *g = gr->glyphs[area];
2423 struct glyph *end = g + gr->used[area];
2425 height = gr->height;
2426 for (gx = gr->x; g < end; gx += g->pixel_width, ++g)
2427 if (gx + g->pixel_width > x)
2428 break;
2430 if (g < end)
2432 if (g->type == IMAGE_GLYPH)
2434 /* Don't remember when mouse is over image, as
2435 image may have hot-spots. */
2436 STORE_NATIVE_RECT (*rect, 0, 0, 0, 0);
2437 return;
2439 width = g->pixel_width;
2441 else
2443 /* Use nominal char spacing at end of line. */
2444 x -= gx;
2445 gx += (x / width) * width;
2448 if (part != ON_MODE_LINE && part != ON_HEADER_LINE)
2450 gx += window_box_left_offset (w, area);
2451 /* Don't expand over the modeline to make sure the vertical
2452 drag cursor is shown early enough. */
2453 height = min (height,
2454 max (0, WINDOW_BOX_HEIGHT_NO_MODE_LINE (w) - gy));
2457 else
2459 /* Use nominal line height at end of window. */
2460 gx = (x / width) * width;
2461 y -= gy;
2462 gy += (y / height) * height;
2463 if (part != ON_MODE_LINE && part != ON_HEADER_LINE)
2464 /* See comment above. */
2465 height = min (height,
2466 max (0, WINDOW_BOX_HEIGHT_NO_MODE_LINE (w) - gy));
2468 break;
2470 case ON_LEFT_FRINGE:
2471 gx = (WINDOW_HAS_FRINGES_OUTSIDE_MARGINS (w)
2472 ? WINDOW_LEFT_SCROLL_BAR_AREA_WIDTH (w)
2473 : window_box_right_offset (w, LEFT_MARGIN_AREA));
2474 width = WINDOW_LEFT_FRINGE_WIDTH (w);
2475 goto row_glyph;
2477 case ON_RIGHT_FRINGE:
2478 gx = (WINDOW_HAS_FRINGES_OUTSIDE_MARGINS (w)
2479 ? window_box_right_offset (w, RIGHT_MARGIN_AREA)
2480 : window_box_right_offset (w, TEXT_AREA));
2481 if (WINDOW_RIGHT_DIVIDER_WIDTH (w) == 0
2482 && !WINDOW_HAS_VERTICAL_SCROLL_BAR (w)
2483 && !WINDOW_RIGHTMOST_P (w))
2484 if (gx < WINDOW_PIXEL_WIDTH (w) - width)
2485 /* Make sure the vertical border can get her own glyph to the
2486 right of the one we build here. */
2487 width = WINDOW_RIGHT_FRINGE_WIDTH (w) - width;
2488 else
2489 width = WINDOW_PIXEL_WIDTH (w) - gx;
2490 else
2491 width = WINDOW_RIGHT_FRINGE_WIDTH (w);
2493 goto row_glyph;
2495 case ON_VERTICAL_BORDER:
2496 gx = WINDOW_PIXEL_WIDTH (w) - width;
2497 goto row_glyph;
2499 case ON_VERTICAL_SCROLL_BAR:
2500 gx = (WINDOW_HAS_VERTICAL_SCROLL_BAR_ON_LEFT (w)
2502 : (window_box_right_offset (w, RIGHT_MARGIN_AREA)
2503 + (WINDOW_HAS_FRINGES_OUTSIDE_MARGINS (w)
2504 ? WINDOW_RIGHT_FRINGE_WIDTH (w)
2505 : 0)));
2506 width = WINDOW_SCROLL_BAR_AREA_WIDTH (w);
2508 row_glyph:
2509 gr = 0, gy = 0;
2510 for (; r <= end_row && r->enabled_p; ++r)
2511 if (r->y + r->height > y)
2513 gr = r; gy = r->y;
2514 break;
2517 if (gr && gy <= y)
2518 height = gr->height;
2519 else
2521 /* Use nominal line height at end of window. */
2522 y -= gy;
2523 gy += (y / height) * height;
2525 break;
2527 case ON_RIGHT_DIVIDER:
2528 gx = WINDOW_PIXEL_WIDTH (w) - WINDOW_RIGHT_DIVIDER_WIDTH (w);
2529 width = WINDOW_RIGHT_DIVIDER_WIDTH (w);
2530 gy = 0;
2531 /* The bottom divider prevails. */
2532 height = WINDOW_PIXEL_HEIGHT (w) - WINDOW_BOTTOM_DIVIDER_WIDTH (w);
2533 goto add_edge;
2535 case ON_BOTTOM_DIVIDER:
2536 gx = 0;
2537 width = WINDOW_PIXEL_WIDTH (w);
2538 gy = WINDOW_PIXEL_HEIGHT (w) - WINDOW_BOTTOM_DIVIDER_WIDTH (w);
2539 height = WINDOW_BOTTOM_DIVIDER_WIDTH (w);
2540 goto add_edge;
2542 default:
2544 virtual_glyph:
2545 /* If there is no glyph under the mouse, then we divide the screen
2546 into a grid of the smallest glyph in the frame, and use that
2547 as our "glyph". */
2549 /* Arrange for the division in FRAME_PIXEL_X_TO_COL etc. to
2550 round down even for negative values. */
2551 if (gx < 0)
2552 gx -= width - 1;
2553 if (gy < 0)
2554 gy -= height - 1;
2556 gx = (gx / width) * width;
2557 gy = (gy / height) * height;
2559 goto store_rect;
2562 add_edge:
2563 gx += WINDOW_LEFT_EDGE_X (w);
2564 gy += WINDOW_TOP_EDGE_Y (w);
2566 store_rect:
2567 STORE_NATIVE_RECT (*rect, gx, gy, width, height);
2569 /* Visible feedback for debugging. */
2570 #if false && defined HAVE_X_WINDOWS
2571 XDrawRectangle (FRAME_X_DISPLAY (f), FRAME_X_DRAWABLE (f),
2572 f->output_data.x->normal_gc,
2573 gx, gy, width, height);
2574 #endif
2578 #endif /* HAVE_WINDOW_SYSTEM */
2580 static void
2581 adjust_window_ends (struct window *w, struct glyph_row *row, bool current)
2583 eassert (w);
2584 w->window_end_pos = Z - MATRIX_ROW_END_CHARPOS (row);
2585 w->window_end_bytepos = Z_BYTE - MATRIX_ROW_END_BYTEPOS (row);
2586 w->window_end_vpos
2587 = MATRIX_ROW_VPOS (row, current ? w->current_matrix : w->desired_matrix);
2590 static bool
2591 hscrolling_current_line_p (struct window *w)
2593 return (!w->suspend_auto_hscroll
2594 && EQ (Fbuffer_local_value (Qauto_hscroll_mode, w->contents),
2595 Qcurrent_line));
2598 /***********************************************************************
2599 Lisp form evaluation
2600 ***********************************************************************/
2602 /* Error handler for safe_eval and safe_call. */
2604 static Lisp_Object
2605 safe_eval_handler (Lisp_Object arg, ptrdiff_t nargs, Lisp_Object *args)
2607 add_to_log ("Error during redisplay: %S signaled %S",
2608 Flist (nargs, args), arg);
2609 return Qnil;
2612 /* Call function FUNC with the rest of NARGS - 1 arguments
2613 following. Return the result, or nil if something went
2614 wrong. Prevent redisplay during the evaluation. */
2616 static Lisp_Object
2617 safe__call (bool inhibit_quit, ptrdiff_t nargs, Lisp_Object func, va_list ap)
2619 Lisp_Object val;
2621 if (inhibit_eval_during_redisplay)
2622 val = Qnil;
2623 else
2625 ptrdiff_t i;
2626 ptrdiff_t count = SPECPDL_INDEX ();
2627 Lisp_Object *args;
2628 USE_SAFE_ALLOCA;
2629 SAFE_ALLOCA_LISP (args, nargs);
2631 args[0] = func;
2632 for (i = 1; i < nargs; i++)
2633 args[i] = va_arg (ap, Lisp_Object);
2635 specbind (Qinhibit_redisplay, Qt);
2636 if (inhibit_quit)
2637 specbind (Qinhibit_quit, Qt);
2638 /* Use Qt to ensure debugger does not run,
2639 so there is no possibility of wanting to redisplay. */
2640 val = internal_condition_case_n (Ffuncall, nargs, args, Qt,
2641 safe_eval_handler);
2642 SAFE_FREE ();
2643 val = unbind_to (count, val);
2646 return val;
2649 Lisp_Object
2650 safe_call (ptrdiff_t nargs, Lisp_Object func, ...)
2652 Lisp_Object retval;
2653 va_list ap;
2655 va_start (ap, func);
2656 retval = safe__call (false, nargs, func, ap);
2657 va_end (ap);
2658 return retval;
2661 /* Call function FN with one argument ARG.
2662 Return the result, or nil if something went wrong. */
2664 Lisp_Object
2665 safe_call1 (Lisp_Object fn, Lisp_Object arg)
2667 return safe_call (2, fn, arg);
2670 static Lisp_Object
2671 safe__call1 (bool inhibit_quit, Lisp_Object fn, ...)
2673 Lisp_Object retval;
2674 va_list ap;
2676 va_start (ap, fn);
2677 retval = safe__call (inhibit_quit, 2, fn, ap);
2678 va_end (ap);
2679 return retval;
2682 Lisp_Object
2683 safe_eval (Lisp_Object sexpr)
2685 return safe__call1 (false, Qeval, sexpr);
2688 static Lisp_Object
2689 safe__eval (bool inhibit_quit, Lisp_Object sexpr)
2691 return safe__call1 (inhibit_quit, Qeval, sexpr);
2694 /* Call function FN with two arguments ARG1 and ARG2.
2695 Return the result, or nil if something went wrong. */
2697 Lisp_Object
2698 safe_call2 (Lisp_Object fn, Lisp_Object arg1, Lisp_Object arg2)
2700 return safe_call (3, fn, arg1, arg2);
2705 /***********************************************************************
2706 Debugging
2707 ***********************************************************************/
2709 /* Define CHECK_IT to perform sanity checks on iterators.
2710 This is for debugging. It is too slow to do unconditionally. */
2712 static void
2713 CHECK_IT (struct it *it)
2715 #if false
2716 if (it->method == GET_FROM_STRING)
2718 eassert (STRINGP (it->string));
2719 eassert (IT_STRING_CHARPOS (*it) >= 0);
2721 else
2723 eassert (IT_STRING_CHARPOS (*it) < 0);
2724 if (it->method == GET_FROM_BUFFER)
2726 /* Check that character and byte positions agree. */
2727 eassert (IT_CHARPOS (*it) == BYTE_TO_CHAR (IT_BYTEPOS (*it)));
2731 if (it->dpvec)
2732 eassert (it->current.dpvec_index >= 0);
2733 else
2734 eassert (it->current.dpvec_index < 0);
2735 #endif
2739 /* Check that the window end of window W is what we expect it
2740 to be---the last row in the current matrix displaying text. */
2742 static void
2743 CHECK_WINDOW_END (struct window *w)
2745 #if defined GLYPH_DEBUG && defined ENABLE_CHECKING
2746 if (!MINI_WINDOW_P (w) && w->window_end_valid)
2748 struct glyph_row *row;
2749 eassert ((row = MATRIX_ROW (w->current_matrix, w->window_end_vpos),
2750 !row->enabled_p
2751 || MATRIX_ROW_DISPLAYS_TEXT_P (row)
2752 || MATRIX_ROW_VPOS (row, w->current_matrix) == 0));
2754 #endif
2757 /***********************************************************************
2758 Iterator initialization
2759 ***********************************************************************/
2761 /* Initialize IT for displaying current_buffer in window W, starting
2762 at character position CHARPOS. CHARPOS < 0 means that no buffer
2763 position is specified which is useful when the iterator is assigned
2764 a position later. BYTEPOS is the byte position corresponding to
2765 CHARPOS.
2767 If ROW is not null, calls to produce_glyphs with IT as parameter
2768 will produce glyphs in that row.
2770 BASE_FACE_ID is the id of a base face to use. It must be one of
2771 DEFAULT_FACE_ID for normal text, MODE_LINE_FACE_ID,
2772 MODE_LINE_INACTIVE_FACE_ID, or HEADER_LINE_FACE_ID for displaying
2773 mode lines, or TOOL_BAR_FACE_ID for displaying the tool-bar.
2775 If ROW is null and BASE_FACE_ID is equal to MODE_LINE_FACE_ID,
2776 MODE_LINE_INACTIVE_FACE_ID, or HEADER_LINE_FACE_ID, the iterator
2777 will be initialized to use the corresponding mode line glyph row of
2778 the desired matrix of W. */
2780 void
2781 init_iterator (struct it *it, struct window *w,
2782 ptrdiff_t charpos, ptrdiff_t bytepos,
2783 struct glyph_row *row, enum face_id base_face_id)
2785 enum face_id remapped_base_face_id = base_face_id;
2787 /* Some precondition checks. */
2788 eassert (w != NULL && it != NULL);
2789 eassert (charpos < 0 || (charpos >= BUF_BEG (current_buffer)
2790 && charpos <= ZV));
2792 /* If face attributes have been changed since the last redisplay,
2793 free realized faces now because they depend on face definitions
2794 that might have changed. Don't free faces while there might be
2795 desired matrices pending which reference these faces. */
2796 if (!inhibit_free_realized_faces)
2798 if (face_change)
2800 face_change = false;
2801 XFRAME (w->frame)->face_change = 0;
2802 free_all_realized_faces (Qnil);
2804 else if (XFRAME (w->frame)->face_change)
2806 XFRAME (w->frame)->face_change = 0;
2807 free_all_realized_faces (w->frame);
2811 /* Perhaps remap BASE_FACE_ID to a user-specified alternative. */
2812 if (! NILP (Vface_remapping_alist))
2813 remapped_base_face_id
2814 = lookup_basic_face (XFRAME (w->frame), base_face_id);
2816 /* Use one of the mode line rows of W's desired matrix if
2817 appropriate. */
2818 if (row == NULL)
2820 if (base_face_id == MODE_LINE_FACE_ID
2821 || base_face_id == MODE_LINE_INACTIVE_FACE_ID)
2822 row = MATRIX_MODE_LINE_ROW (w->desired_matrix);
2823 else if (base_face_id == HEADER_LINE_FACE_ID)
2824 row = MATRIX_HEADER_LINE_ROW (w->desired_matrix);
2827 /* Clear IT, and set it->object and other IT's Lisp objects to Qnil.
2828 Other parts of redisplay rely on that. */
2829 memclear (it, sizeof *it);
2830 it->current.overlay_string_index = -1;
2831 it->current.dpvec_index = -1;
2832 it->base_face_id = remapped_base_face_id;
2833 IT_STRING_CHARPOS (*it) = IT_STRING_BYTEPOS (*it) = -1;
2834 it->paragraph_embedding = L2R;
2835 it->bidi_it.w = w;
2837 /* The window in which we iterate over current_buffer: */
2838 XSETWINDOW (it->window, w);
2839 it->w = w;
2840 it->f = XFRAME (w->frame);
2842 it->cmp_it.id = -1;
2844 /* Extra space between lines (on window systems only). */
2845 if (base_face_id == DEFAULT_FACE_ID
2846 && FRAME_WINDOW_P (it->f))
2848 if (NATNUMP (BVAR (current_buffer, extra_line_spacing)))
2849 it->extra_line_spacing = XFASTINT (BVAR (current_buffer, extra_line_spacing));
2850 else if (FLOATP (BVAR (current_buffer, extra_line_spacing)))
2851 it->extra_line_spacing = (XFLOAT_DATA (BVAR (current_buffer, extra_line_spacing))
2852 * FRAME_LINE_HEIGHT (it->f));
2853 else if (it->f->extra_line_spacing > 0)
2854 it->extra_line_spacing = it->f->extra_line_spacing;
2857 /* If realized faces have been removed, e.g. because of face
2858 attribute changes of named faces, recompute them. When running
2859 in batch mode, the face cache of the initial frame is null. If
2860 we happen to get called, make a dummy face cache. */
2861 if (FRAME_FACE_CACHE (it->f) == NULL)
2862 init_frame_faces (it->f);
2863 if (FRAME_FACE_CACHE (it->f)->used == 0)
2864 recompute_basic_faces (it->f);
2866 it->override_ascent = -1;
2868 /* Are control characters displayed as `^C'? */
2869 it->ctl_arrow_p = !NILP (BVAR (current_buffer, ctl_arrow));
2871 /* -1 means everything between a CR and the following line end
2872 is invisible. >0 means lines indented more than this value are
2873 invisible. */
2874 it->selective = (INTEGERP (BVAR (current_buffer, selective_display))
2875 ? (clip_to_bounds
2876 (-1, XINT (BVAR (current_buffer, selective_display)),
2877 PTRDIFF_MAX))
2878 : (!NILP (BVAR (current_buffer, selective_display))
2879 ? -1 : 0));
2880 it->selective_display_ellipsis_p
2881 = !NILP (BVAR (current_buffer, selective_display_ellipses));
2883 /* Display table to use. */
2884 it->dp = window_display_table (w);
2886 /* Are multibyte characters enabled in current_buffer? */
2887 it->multibyte_p = !NILP (BVAR (current_buffer, enable_multibyte_characters));
2889 /* Get the position at which the redisplay_end_trigger hook should
2890 be run, if it is to be run at all. */
2891 if (MARKERP (w->redisplay_end_trigger)
2892 && XMARKER (w->redisplay_end_trigger)->buffer != 0)
2893 it->redisplay_end_trigger_charpos
2894 = marker_position (w->redisplay_end_trigger);
2895 else if (INTEGERP (w->redisplay_end_trigger))
2896 it->redisplay_end_trigger_charpos
2897 = clip_to_bounds (PTRDIFF_MIN, XINT (w->redisplay_end_trigger),
2898 PTRDIFF_MAX);
2900 it->tab_width = SANE_TAB_WIDTH (current_buffer);
2902 /* Are lines in the display truncated? */
2903 if (TRUNCATE != 0)
2904 it->line_wrap = TRUNCATE;
2905 if (base_face_id == DEFAULT_FACE_ID
2906 && !it->w->hscroll
2907 && (WINDOW_FULL_WIDTH_P (it->w)
2908 || NILP (Vtruncate_partial_width_windows)
2909 || (INTEGERP (Vtruncate_partial_width_windows)
2910 /* PXW: Shall we do something about this? */
2911 && (XINT (Vtruncate_partial_width_windows)
2912 <= WINDOW_TOTAL_COLS (it->w))))
2913 && NILP (BVAR (current_buffer, truncate_lines)))
2914 it->line_wrap = NILP (BVAR (current_buffer, word_wrap))
2915 ? WINDOW_WRAP : WORD_WRAP;
2917 /* Get dimensions of truncation and continuation glyphs. These are
2918 displayed as fringe bitmaps under X, but we need them for such
2919 frames when the fringes are turned off. The no_special_glyphs slot
2920 of the iterator's frame, when set, suppresses their display - by
2921 default for tooltip frames and when set via the 'no-special-glyphs'
2922 frame parameter. */
2923 #ifdef HAVE_WINDOW_SYSTEM
2924 if (!(FRAME_WINDOW_P (it->f) && it->f->no_special_glyphs))
2925 #endif
2927 if (it->line_wrap == TRUNCATE)
2929 /* We will need the truncation glyph. */
2930 eassert (it->glyph_row == NULL);
2931 produce_special_glyphs (it, IT_TRUNCATION);
2932 it->truncation_pixel_width = it->pixel_width;
2934 else
2936 /* We will need the continuation glyph. */
2937 eassert (it->glyph_row == NULL);
2938 produce_special_glyphs (it, IT_CONTINUATION);
2939 it->continuation_pixel_width = it->pixel_width;
2943 /* Reset these values to zero because the produce_special_glyphs
2944 above has changed them. */
2945 it->pixel_width = it->ascent = it->descent = 0;
2946 it->phys_ascent = it->phys_descent = 0;
2948 /* Set this after getting the dimensions of truncation and
2949 continuation glyphs, so that we don't produce glyphs when calling
2950 produce_special_glyphs, above. */
2951 it->glyph_row = row;
2952 it->area = TEXT_AREA;
2954 /* Get the dimensions of the display area. The display area
2955 consists of the visible window area plus a horizontally scrolled
2956 part to the left of the window. All x-values are relative to the
2957 start of this total display area. */
2958 if (base_face_id != DEFAULT_FACE_ID)
2960 /* Mode lines, menu bar in terminal frames. */
2961 it->first_visible_x = 0;
2962 it->last_visible_x = WINDOW_PIXEL_WIDTH (w);
2964 else
2966 /* When hscrolling only the current line, don't apply the
2967 hscroll here, it will be applied by display_line when it gets
2968 to laying out the line showing point. However, if the
2969 window's min_hscroll is positive, the user specified a lower
2970 bound for automatic hscrolling, so they expect the
2971 non-current lines to obey that hscroll amount. */
2972 if (hscrolling_current_line_p (w))
2974 if (w->min_hscroll > 0)
2975 it->first_visible_x = w->min_hscroll * FRAME_COLUMN_WIDTH (it->f);
2976 else
2977 it->first_visible_x = 0;
2979 else
2980 it->first_visible_x =
2981 window_hscroll_limited (w, it->f) * FRAME_COLUMN_WIDTH (it->f);
2982 it->last_visible_x = (it->first_visible_x
2983 + window_box_width (w, TEXT_AREA));
2985 /* If we truncate lines, leave room for the truncation glyph(s) at
2986 the right margin. Otherwise, leave room for the continuation
2987 glyph(s). Done only if the window has no right fringe. */
2988 if (WINDOW_RIGHT_FRINGE_WIDTH (it->w) == 0)
2990 if (it->line_wrap == TRUNCATE)
2991 it->last_visible_x -= it->truncation_pixel_width;
2992 else
2993 it->last_visible_x -= it->continuation_pixel_width;
2996 it->header_line_p = window_wants_header_line (w);
2997 it->current_y = WINDOW_HEADER_LINE_HEIGHT (w) + w->vscroll;
3000 /* Leave room for a border glyph. */
3001 if (!FRAME_WINDOW_P (it->f)
3002 && !WINDOW_RIGHTMOST_P (it->w))
3003 it->last_visible_x -= 1;
3005 it->last_visible_y = window_text_bottom_y (w);
3007 /* For mode lines and alike, arrange for the first glyph having a
3008 left box line if the face specifies a box. */
3009 if (base_face_id != DEFAULT_FACE_ID)
3011 struct face *face;
3013 it->face_id = remapped_base_face_id;
3015 /* If we have a boxed mode line, make the first character appear
3016 with a left box line. */
3017 face = FACE_FROM_ID_OR_NULL (it->f, remapped_base_face_id);
3018 if (face && face->box != FACE_NO_BOX)
3019 it->start_of_box_run_p = true;
3022 /* If a buffer position was specified, set the iterator there,
3023 getting overlays and face properties from that position. */
3024 if (charpos >= BUF_BEG (current_buffer))
3026 it->stop_charpos = charpos;
3027 it->end_charpos = ZV;
3028 eassert (charpos == BYTE_TO_CHAR (bytepos));
3029 IT_CHARPOS (*it) = charpos;
3030 IT_BYTEPOS (*it) = bytepos;
3032 /* We will rely on `reseat' to set this up properly, via
3033 handle_face_prop. */
3034 it->face_id = it->base_face_id;
3036 it->start = it->current;
3037 /* Do we need to reorder bidirectional text? Not if this is a
3038 unibyte buffer: by definition, none of the single-byte
3039 characters are strong R2L, so no reordering is needed. And
3040 bidi.c doesn't support unibyte buffers anyway. Also, don't
3041 reorder while we are loading loadup.el, since the tables of
3042 character properties needed for reordering are not yet
3043 available. */
3044 it->bidi_p =
3045 !redisplay__inhibit_bidi
3046 && !NILP (BVAR (current_buffer, bidi_display_reordering))
3047 && it->multibyte_p;
3049 /* If we are to reorder bidirectional text, init the bidi
3050 iterator. */
3051 if (it->bidi_p)
3053 /* Since we don't know at this point whether there will be
3054 any R2L lines in the window, we reserve space for
3055 truncation/continuation glyphs even if only the left
3056 fringe is absent. */
3057 if (base_face_id == DEFAULT_FACE_ID
3058 && WINDOW_LEFT_FRINGE_WIDTH (it->w) == 0
3059 && WINDOW_RIGHT_FRINGE_WIDTH (it->w) != 0)
3061 if (it->line_wrap == TRUNCATE)
3062 it->last_visible_x -= it->truncation_pixel_width;
3063 else
3064 it->last_visible_x -= it->continuation_pixel_width;
3066 /* Note the paragraph direction that this buffer wants to
3067 use. */
3068 if (EQ (BVAR (current_buffer, bidi_paragraph_direction),
3069 Qleft_to_right))
3070 it->paragraph_embedding = L2R;
3071 else if (EQ (BVAR (current_buffer, bidi_paragraph_direction),
3072 Qright_to_left))
3073 it->paragraph_embedding = R2L;
3074 else
3075 it->paragraph_embedding = NEUTRAL_DIR;
3076 bidi_unshelve_cache (NULL, false);
3077 bidi_init_it (charpos, IT_BYTEPOS (*it), FRAME_WINDOW_P (it->f),
3078 &it->bidi_it);
3081 /* Compute faces etc. */
3082 reseat (it, it->current.pos, true);
3085 CHECK_IT (it);
3089 /* Initialize IT for the display of window W with window start POS. */
3091 void
3092 start_display (struct it *it, struct window *w, struct text_pos pos)
3094 struct glyph_row *row;
3095 bool first_vpos = window_wants_header_line (w);
3097 row = w->desired_matrix->rows + first_vpos;
3098 init_iterator (it, w, CHARPOS (pos), BYTEPOS (pos), row, DEFAULT_FACE_ID);
3099 it->first_vpos = first_vpos;
3101 /* Don't reseat to previous visible line start if current start
3102 position is in a string or image. */
3103 if (it->method == GET_FROM_BUFFER && it->line_wrap != TRUNCATE)
3105 int first_y = it->current_y;
3107 /* If window start is not at a line start, skip forward to POS to
3108 get the correct continuation lines width. */
3109 bool start_at_line_beg_p = (CHARPOS (pos) == BEGV
3110 || FETCH_BYTE (BYTEPOS (pos) - 1) == '\n');
3111 if (!start_at_line_beg_p)
3113 int new_x;
3115 reseat_at_previous_visible_line_start (it);
3116 move_it_to (it, CHARPOS (pos), -1, -1, -1, MOVE_TO_POS);
3118 new_x = it->current_x + it->pixel_width;
3120 /* If lines are continued, this line may end in the middle
3121 of a multi-glyph character (e.g. a control character
3122 displayed as \003, or in the middle of an overlay
3123 string). In this case move_it_to above will not have
3124 taken us to the start of the continuation line but to the
3125 end of the continued line. */
3126 if (it->current_x > 0
3127 && it->line_wrap != TRUNCATE /* Lines are continued. */
3128 && (/* And glyph doesn't fit on the line. */
3129 new_x > it->last_visible_x
3130 /* Or it fits exactly and we're on a window
3131 system frame. */
3132 || (new_x == it->last_visible_x
3133 && FRAME_WINDOW_P (it->f)
3134 && ((it->bidi_p && it->bidi_it.paragraph_dir == R2L)
3135 ? WINDOW_LEFT_FRINGE_WIDTH (it->w)
3136 : WINDOW_RIGHT_FRINGE_WIDTH (it->w)))))
3138 if ((it->current.dpvec_index >= 0
3139 || it->current.overlay_string_index >= 0)
3140 /* If we are on a newline from a display vector or
3141 overlay string, then we are already at the end of
3142 a screen line; no need to go to the next line in
3143 that case, as this line is not really continued.
3144 (If we do go to the next line, C-e will not DTRT.) */
3145 && it->c != '\n')
3147 set_iterator_to_next (it, true);
3148 move_it_in_display_line_to (it, -1, -1, 0);
3151 it->continuation_lines_width += it->current_x;
3153 /* If the character at POS is displayed via a display
3154 vector, move_it_to above stops at the final glyph of
3155 IT->dpvec. To make the caller redisplay that character
3156 again (a.k.a. start at POS), we need to reset the
3157 dpvec_index to the beginning of IT->dpvec. */
3158 else if (it->current.dpvec_index >= 0)
3159 it->current.dpvec_index = 0;
3161 /* We're starting a new display line, not affected by the
3162 height of the continued line, so clear the appropriate
3163 fields in the iterator structure. */
3164 it->max_ascent = it->max_descent = 0;
3165 it->max_phys_ascent = it->max_phys_descent = 0;
3167 it->current_y = first_y;
3168 it->vpos = 0;
3169 it->current_x = it->hpos = 0;
3175 /* Return true if POS is a position in ellipses displayed for invisible
3176 text. W is the window we display, for text property lookup. */
3178 static bool
3179 in_ellipses_for_invisible_text_p (struct display_pos *pos, struct window *w)
3181 Lisp_Object prop, window;
3182 bool ellipses_p = false;
3183 ptrdiff_t charpos = CHARPOS (pos->pos);
3185 /* If POS specifies a position in a display vector, this might
3186 be for an ellipsis displayed for invisible text. We won't
3187 get the iterator set up for delivering that ellipsis unless
3188 we make sure that it gets aware of the invisible text. */
3189 if (pos->dpvec_index >= 0
3190 && pos->overlay_string_index < 0
3191 && CHARPOS (pos->string_pos) < 0
3192 && charpos > BEGV
3193 && (XSETWINDOW (window, w),
3194 prop = Fget_char_property (make_number (charpos),
3195 Qinvisible, window),
3196 TEXT_PROP_MEANS_INVISIBLE (prop) == 0))
3198 prop = Fget_char_property (make_number (charpos - 1), Qinvisible,
3199 window);
3200 ellipses_p = 2 == TEXT_PROP_MEANS_INVISIBLE (prop);
3203 return ellipses_p;
3207 /* Initialize IT for stepping through current_buffer in window W,
3208 starting at position POS that includes overlay string and display
3209 vector/ control character translation position information. Value
3210 is false if there are overlay strings with newlines at POS. */
3212 static bool
3213 init_from_display_pos (struct it *it, struct window *w, struct display_pos *pos)
3215 ptrdiff_t charpos = CHARPOS (pos->pos), bytepos = BYTEPOS (pos->pos);
3216 int i;
3217 bool overlay_strings_with_newlines = false;
3219 /* If POS specifies a position in a display vector, this might
3220 be for an ellipsis displayed for invisible text. We won't
3221 get the iterator set up for delivering that ellipsis unless
3222 we make sure that it gets aware of the invisible text. */
3223 if (in_ellipses_for_invisible_text_p (pos, w))
3225 --charpos;
3226 bytepos = 0;
3229 /* Keep in mind: the call to reseat in init_iterator skips invisible
3230 text, so we might end up at a position different from POS. This
3231 is only a problem when POS is a row start after a newline and an
3232 overlay starts there with an after-string, and the overlay has an
3233 invisible property. Since we don't skip invisible text in
3234 display_line and elsewhere immediately after consuming the
3235 newline before the row start, such a POS will not be in a string,
3236 but the call to init_iterator below will move us to the
3237 after-string. */
3238 init_iterator (it, w, charpos, bytepos, NULL, DEFAULT_FACE_ID);
3240 /* This only scans the current chunk -- it should scan all chunks.
3241 However, OVERLAY_STRING_CHUNK_SIZE has been increased from 3 in 21.1
3242 to 16 in 22.1 to make this a lesser problem. */
3243 for (i = 0; i < it->n_overlay_strings && i < OVERLAY_STRING_CHUNK_SIZE; ++i)
3245 const char *s = SSDATA (it->overlay_strings[i]);
3246 const char *e = s + SBYTES (it->overlay_strings[i]);
3248 while (s < e && *s != '\n')
3249 ++s;
3251 if (s < e)
3253 overlay_strings_with_newlines = true;
3254 break;
3258 /* If position is within an overlay string, set up IT to the right
3259 overlay string. */
3260 if (pos->overlay_string_index >= 0)
3262 int relative_index;
3264 /* If the first overlay string happens to have a `display'
3265 property for an image, the iterator will be set up for that
3266 image, and we have to undo that setup first before we can
3267 correct the overlay string index. */
3268 if (it->method == GET_FROM_IMAGE)
3269 pop_it (it);
3271 /* We already have the first chunk of overlay strings in
3272 IT->overlay_strings. Load more until the one for
3273 pos->overlay_string_index is in IT->overlay_strings. */
3274 if (pos->overlay_string_index >= OVERLAY_STRING_CHUNK_SIZE)
3276 ptrdiff_t n = pos->overlay_string_index / OVERLAY_STRING_CHUNK_SIZE;
3277 it->current.overlay_string_index = 0;
3278 while (n--)
3280 load_overlay_strings (it, 0);
3281 it->current.overlay_string_index += OVERLAY_STRING_CHUNK_SIZE;
3285 it->current.overlay_string_index = pos->overlay_string_index;
3286 relative_index = (it->current.overlay_string_index
3287 % OVERLAY_STRING_CHUNK_SIZE);
3288 it->string = it->overlay_strings[relative_index];
3289 eassert (STRINGP (it->string));
3290 it->current.string_pos = pos->string_pos;
3291 it->method = GET_FROM_STRING;
3292 it->end_charpos = SCHARS (it->string);
3293 /* Set up the bidi iterator for this overlay string. */
3294 if (it->bidi_p)
3296 it->bidi_it.string.lstring = it->string;
3297 it->bidi_it.string.s = NULL;
3298 it->bidi_it.string.schars = SCHARS (it->string);
3299 it->bidi_it.string.bufpos = it->overlay_strings_charpos;
3300 it->bidi_it.string.from_disp_str = it->string_from_display_prop_p;
3301 it->bidi_it.string.unibyte = !it->multibyte_p;
3302 it->bidi_it.w = it->w;
3303 bidi_init_it (IT_STRING_CHARPOS (*it), IT_STRING_BYTEPOS (*it),
3304 FRAME_WINDOW_P (it->f), &it->bidi_it);
3306 /* Synchronize the state of the bidi iterator with
3307 pos->string_pos. For any string position other than
3308 zero, this will be done automagically when we resume
3309 iteration over the string and get_visually_first_element
3310 is called. But if string_pos is zero, and the string is
3311 to be reordered for display, we need to resync manually,
3312 since it could be that the iteration state recorded in
3313 pos ended at string_pos of 0 moving backwards in string. */
3314 if (CHARPOS (pos->string_pos) == 0)
3316 get_visually_first_element (it);
3317 if (IT_STRING_CHARPOS (*it) != 0)
3318 do {
3319 /* Paranoia. */
3320 eassert (it->bidi_it.charpos < it->bidi_it.string.schars);
3321 bidi_move_to_visually_next (&it->bidi_it);
3322 } while (it->bidi_it.charpos != 0);
3324 eassert (IT_STRING_CHARPOS (*it) == it->bidi_it.charpos
3325 && IT_STRING_BYTEPOS (*it) == it->bidi_it.bytepos);
3329 if (CHARPOS (pos->string_pos) >= 0)
3331 /* Recorded position is not in an overlay string, but in another
3332 string. This can only be a string from a `display' property.
3333 IT should already be filled with that string. */
3334 it->current.string_pos = pos->string_pos;
3335 eassert (STRINGP (it->string));
3336 if (it->bidi_p)
3337 bidi_init_it (IT_STRING_CHARPOS (*it), IT_STRING_BYTEPOS (*it),
3338 FRAME_WINDOW_P (it->f), &it->bidi_it);
3341 /* Restore position in display vector translations, control
3342 character translations or ellipses. */
3343 if (pos->dpvec_index >= 0)
3345 if (it->dpvec == NULL)
3346 get_next_display_element (it);
3347 eassert (it->dpvec && it->current.dpvec_index == 0);
3348 it->current.dpvec_index = pos->dpvec_index;
3351 CHECK_IT (it);
3352 return !overlay_strings_with_newlines;
3356 /* Initialize IT for stepping through current_buffer in window W
3357 starting at ROW->start. */
3359 static void
3360 init_to_row_start (struct it *it, struct window *w, struct glyph_row *row)
3362 init_from_display_pos (it, w, &row->start);
3363 it->start = row->start;
3364 it->continuation_lines_width = row->continuation_lines_width;
3365 CHECK_IT (it);
3369 /* Initialize IT for stepping through current_buffer in window W
3370 starting in the line following ROW, i.e. starting at ROW->end.
3371 Value is false if there are overlay strings with newlines at ROW's
3372 end position. */
3374 static bool
3375 init_to_row_end (struct it *it, struct window *w, struct glyph_row *row)
3377 bool success = false;
3379 if (init_from_display_pos (it, w, &row->end))
3381 if (row->continued_p)
3382 it->continuation_lines_width
3383 = row->continuation_lines_width + row->pixel_width;
3384 CHECK_IT (it);
3385 success = true;
3388 return success;
3394 /***********************************************************************
3395 Text properties
3396 ***********************************************************************/
3398 /* Called when IT reaches IT->stop_charpos. Handle text property and
3399 overlay changes. Set IT->stop_charpos to the next position where
3400 to stop. */
3402 static void
3403 handle_stop (struct it *it)
3405 enum prop_handled handled;
3406 bool handle_overlay_change_p;
3407 struct props *p;
3409 it->dpvec = NULL;
3410 it->current.dpvec_index = -1;
3411 handle_overlay_change_p = !it->ignore_overlay_strings_at_pos_p;
3412 it->ellipsis_p = false;
3414 /* Use face of preceding text for ellipsis (if invisible) */
3415 if (it->selective_display_ellipsis_p)
3416 it->saved_face_id = it->face_id;
3418 /* Here's the description of the semantics of, and the logic behind,
3419 the various HANDLED_* statuses:
3421 HANDLED_NORMALLY means the handler did its job, and the loop
3422 should proceed to calling the next handler in order.
3424 HANDLED_RECOMPUTE_PROPS means the handler caused a significant
3425 change in the properties and overlays at current position, so the
3426 loop should be restarted, to re-invoke the handlers that were
3427 already called. This happens when fontification-functions were
3428 called by handle_fontified_prop, and actually fontified
3429 something. Another case where HANDLED_RECOMPUTE_PROPS is
3430 returned is when we discover overlay strings that need to be
3431 displayed right away. The loop below will continue for as long
3432 as the status is HANDLED_RECOMPUTE_PROPS.
3434 HANDLED_RETURN means return immediately to the caller, to
3435 continue iteration without calling any further handlers. This is
3436 used when we need to act on some property right away, for example
3437 when we need to display the ellipsis or a replacing display
3438 property, such as display string or image.
3440 HANDLED_OVERLAY_STRING_CONSUMED means an overlay string was just
3441 consumed, and the handler switched to the next overlay string.
3442 This signals the loop below to refrain from looking for more
3443 overlays before all the overlay strings of the current overlay
3444 are processed.
3446 Some of the handlers called by the loop push the iterator state
3447 onto the stack (see 'push_it'), and arrange for the iteration to
3448 continue with another object, such as an image, a display string,
3449 or an overlay string. In most such cases, it->stop_charpos is
3450 set to the first character of the string, so that when the
3451 iteration resumes, this function will immediately be called
3452 again, to examine the properties at the beginning of the string.
3454 When a display or overlay string is exhausted, the iterator state
3455 is popped (see 'pop_it'), and iteration continues with the
3456 previous object. Again, in many such cases this function is
3457 called again to find the next position where properties might
3458 change. */
3462 handled = HANDLED_NORMALLY;
3464 /* Call text property handlers. */
3465 for (p = it_props; p->handler; ++p)
3467 handled = p->handler (it);
3469 if (handled == HANDLED_RECOMPUTE_PROPS)
3470 break;
3471 else if (handled == HANDLED_RETURN)
3473 /* We still want to show before and after strings from
3474 overlays even if the actual buffer text is replaced. */
3475 if (!handle_overlay_change_p
3476 || it->sp > 1
3477 /* Don't call get_overlay_strings_1 if we already
3478 have overlay strings loaded, because doing so
3479 will load them again and push the iterator state
3480 onto the stack one more time, which is not
3481 expected by the rest of the code that processes
3482 overlay strings. */
3483 || (it->current.overlay_string_index < 0
3484 && !get_overlay_strings_1 (it, 0, false)))
3486 if (it->ellipsis_p)
3487 setup_for_ellipsis (it, 0);
3488 /* When handling a display spec, we might load an
3489 empty string. In that case, discard it here. We
3490 used to discard it in handle_single_display_spec,
3491 but that causes get_overlay_strings_1, above, to
3492 ignore overlay strings that we must check. */
3493 if (STRINGP (it->string) && !SCHARS (it->string))
3494 pop_it (it);
3495 return;
3497 else if (STRINGP (it->string) && !SCHARS (it->string))
3498 pop_it (it);
3499 else
3501 it->string_from_display_prop_p = false;
3502 it->from_disp_prop_p = false;
3503 handle_overlay_change_p = false;
3505 handled = HANDLED_RECOMPUTE_PROPS;
3506 break;
3508 else if (handled == HANDLED_OVERLAY_STRING_CONSUMED)
3509 handle_overlay_change_p = false;
3512 if (handled != HANDLED_RECOMPUTE_PROPS)
3514 /* Don't check for overlay strings below when set to deliver
3515 characters from a display vector. */
3516 if (it->method == GET_FROM_DISPLAY_VECTOR)
3517 handle_overlay_change_p = false;
3519 /* Handle overlay changes.
3520 This sets HANDLED to HANDLED_RECOMPUTE_PROPS
3521 if it finds overlays. */
3522 if (handle_overlay_change_p)
3523 handled = handle_overlay_change (it);
3526 if (it->ellipsis_p)
3528 setup_for_ellipsis (it, 0);
3529 break;
3532 while (handled == HANDLED_RECOMPUTE_PROPS);
3534 /* Determine where to stop next. */
3535 if (handled == HANDLED_NORMALLY)
3536 compute_stop_pos (it);
3540 /* Compute IT->stop_charpos from text property and overlay change
3541 information for IT's current position. */
3543 static void
3544 compute_stop_pos (struct it *it)
3546 register INTERVAL iv, next_iv;
3547 Lisp_Object object, limit, position;
3548 ptrdiff_t charpos, bytepos;
3550 if (STRINGP (it->string))
3552 /* Strings are usually short, so don't limit the search for
3553 properties. */
3554 it->stop_charpos = it->end_charpos;
3555 object = it->string;
3556 limit = Qnil;
3557 charpos = IT_STRING_CHARPOS (*it);
3558 bytepos = IT_STRING_BYTEPOS (*it);
3560 else
3562 ptrdiff_t pos;
3564 /* If end_charpos is out of range for some reason, such as a
3565 misbehaving display function, rationalize it (Bug#5984). */
3566 if (it->end_charpos > ZV)
3567 it->end_charpos = ZV;
3568 it->stop_charpos = it->end_charpos;
3570 /* If next overlay change is in front of the current stop pos
3571 (which is IT->end_charpos), stop there. Note: value of
3572 next_overlay_change is point-max if no overlay change
3573 follows. */
3574 charpos = IT_CHARPOS (*it);
3575 bytepos = IT_BYTEPOS (*it);
3576 pos = next_overlay_change (charpos);
3577 if (pos < it->stop_charpos)
3578 it->stop_charpos = pos;
3580 /* Set up variables for computing the stop position from text
3581 property changes. */
3582 XSETBUFFER (object, current_buffer);
3583 limit = make_number (IT_CHARPOS (*it) + TEXT_PROP_DISTANCE_LIMIT);
3586 /* Get the interval containing IT's position. Value is a null
3587 interval if there isn't such an interval. */
3588 position = make_number (charpos);
3589 iv = validate_interval_range (object, &position, &position, false);
3590 if (iv)
3592 Lisp_Object values_here[LAST_PROP_IDX];
3593 struct props *p;
3595 /* Get properties here. */
3596 for (p = it_props; p->handler; ++p)
3597 values_here[p->idx] = textget (iv->plist,
3598 builtin_lisp_symbol (p->name));
3600 /* Look for an interval following iv that has different
3601 properties. */
3602 for (next_iv = next_interval (iv);
3603 (next_iv
3604 && (NILP (limit)
3605 || XFASTINT (limit) > next_iv->position));
3606 next_iv = next_interval (next_iv))
3608 for (p = it_props; p->handler; ++p)
3610 Lisp_Object new_value = textget (next_iv->plist,
3611 builtin_lisp_symbol (p->name));
3612 if (!EQ (values_here[p->idx], new_value))
3613 break;
3616 if (p->handler)
3617 break;
3620 if (next_iv)
3622 if (INTEGERP (limit)
3623 && next_iv->position >= XFASTINT (limit))
3624 /* No text property change up to limit. */
3625 it->stop_charpos = min (XFASTINT (limit), it->stop_charpos);
3626 else
3627 /* Text properties change in next_iv. */
3628 it->stop_charpos = min (it->stop_charpos, next_iv->position);
3632 if (it->cmp_it.id < 0)
3634 ptrdiff_t stoppos = it->end_charpos;
3636 if (it->bidi_p && it->bidi_it.scan_dir < 0)
3637 stoppos = -1;
3638 composition_compute_stop_pos (&it->cmp_it, charpos, bytepos,
3639 stoppos, it->string);
3642 eassert (STRINGP (it->string)
3643 || (it->stop_charpos >= BEGV
3644 && it->stop_charpos >= IT_CHARPOS (*it)));
3648 /* Return the position of the next overlay change after POS in
3649 current_buffer. Value is point-max if no overlay change
3650 follows. This is like `next-overlay-change' but doesn't use
3651 xmalloc. */
3653 static ptrdiff_t
3654 next_overlay_change (ptrdiff_t pos)
3656 ptrdiff_t i, noverlays;
3657 ptrdiff_t endpos;
3658 Lisp_Object *overlays;
3659 USE_SAFE_ALLOCA;
3661 /* Get all overlays at the given position. */
3662 GET_OVERLAYS_AT (pos, overlays, noverlays, &endpos, true);
3664 /* If any of these overlays ends before endpos,
3665 use its ending point instead. */
3666 for (i = 0; i < noverlays; ++i)
3668 Lisp_Object oend;
3669 ptrdiff_t oendpos;
3671 oend = OVERLAY_END (overlays[i]);
3672 oendpos = OVERLAY_POSITION (oend);
3673 endpos = min (endpos, oendpos);
3676 SAFE_FREE ();
3677 return endpos;
3680 /* How many characters forward to search for a display property or
3681 display string. Searching too far forward makes the bidi display
3682 sluggish, especially in small windows. */
3683 #define MAX_DISP_SCAN 250
3685 /* Return the character position of a display string at or after
3686 position specified by POSITION. If no display string exists at or
3687 after POSITION, return ZV. A display string is either an overlay
3688 with `display' property whose value is a string, or a `display'
3689 text property whose value is a string. STRING is data about the
3690 string to iterate; if STRING->lstring is nil, we are iterating a
3691 buffer. FRAME_WINDOW_P is true when we are displaying a window
3692 on a GUI frame. DISP_PROP is set to zero if we searched
3693 MAX_DISP_SCAN characters forward without finding any display
3694 strings, non-zero otherwise. It is set to 2 if the display string
3695 uses any kind of `(space ...)' spec that will produce a stretch of
3696 white space in the text area. */
3697 ptrdiff_t
3698 compute_display_string_pos (struct text_pos *position,
3699 struct bidi_string_data *string,
3700 struct window *w,
3701 bool frame_window_p, int *disp_prop)
3703 /* OBJECT = nil means current buffer. */
3704 Lisp_Object object, object1;
3705 Lisp_Object pos, spec, limpos;
3706 bool string_p = string && (STRINGP (string->lstring) || string->s);
3707 ptrdiff_t eob = string_p ? string->schars : ZV;
3708 ptrdiff_t begb = string_p ? 0 : BEGV;
3709 ptrdiff_t bufpos, charpos = CHARPOS (*position);
3710 ptrdiff_t lim =
3711 (charpos < eob - MAX_DISP_SCAN) ? charpos + MAX_DISP_SCAN : eob;
3712 struct text_pos tpos;
3713 int rv = 0;
3715 if (string && STRINGP (string->lstring))
3716 object1 = object = string->lstring;
3717 else if (w && !string_p)
3719 XSETWINDOW (object, w);
3720 object1 = Qnil;
3722 else
3723 object1 = object = Qnil;
3725 *disp_prop = 1;
3727 if (charpos >= eob
3728 /* We don't support display properties whose values are strings
3729 that have display string properties. */
3730 || string->from_disp_str
3731 /* C strings cannot have display properties. */
3732 || (string->s && !STRINGP (object)))
3734 *disp_prop = 0;
3735 return eob;
3738 /* If the character at CHARPOS is where the display string begins,
3739 return CHARPOS. */
3740 pos = make_number (charpos);
3741 if (STRINGP (object))
3742 bufpos = string->bufpos;
3743 else
3744 bufpos = charpos;
3745 tpos = *position;
3746 if (!NILP (spec = Fget_char_property (pos, Qdisplay, object))
3747 && (charpos <= begb
3748 || !EQ (Fget_char_property (make_number (charpos - 1), Qdisplay,
3749 object),
3750 spec))
3751 && (rv = handle_display_spec (NULL, spec, object, Qnil, &tpos, bufpos,
3752 frame_window_p)))
3754 if (rv == 2)
3755 *disp_prop = 2;
3756 return charpos;
3759 /* Look forward for the first character with a `display' property
3760 that will replace the underlying text when displayed. */
3761 limpos = make_number (lim);
3762 do {
3763 pos = Fnext_single_char_property_change (pos, Qdisplay, object1, limpos);
3764 CHARPOS (tpos) = XFASTINT (pos);
3765 if (CHARPOS (tpos) >= lim)
3767 *disp_prop = 0;
3768 break;
3770 if (STRINGP (object))
3771 BYTEPOS (tpos) = string_char_to_byte (object, CHARPOS (tpos));
3772 else
3773 BYTEPOS (tpos) = CHAR_TO_BYTE (CHARPOS (tpos));
3774 spec = Fget_char_property (pos, Qdisplay, object);
3775 if (!STRINGP (object))
3776 bufpos = CHARPOS (tpos);
3777 } while (NILP (spec)
3778 || !(rv = handle_display_spec (NULL, spec, object, Qnil, &tpos,
3779 bufpos, frame_window_p)));
3780 if (rv == 2)
3781 *disp_prop = 2;
3783 return CHARPOS (tpos);
3786 /* Return the character position of the end of the display string that
3787 started at CHARPOS. If there's no display string at CHARPOS,
3788 return -1. A display string is either an overlay with `display'
3789 property whose value is a string or a `display' text property whose
3790 value is a string. */
3791 ptrdiff_t
3792 compute_display_string_end (ptrdiff_t charpos, struct bidi_string_data *string)
3794 /* OBJECT = nil means current buffer. */
3795 Lisp_Object object =
3796 (string && STRINGP (string->lstring)) ? string->lstring : Qnil;
3797 Lisp_Object pos = make_number (charpos);
3798 ptrdiff_t eob =
3799 (STRINGP (object) || (string && string->s)) ? string->schars : ZV;
3801 if (charpos >= eob || (string->s && !STRINGP (object)))
3802 return eob;
3804 /* It could happen that the display property or overlay was removed
3805 since we found it in compute_display_string_pos above. One way
3806 this can happen is if JIT font-lock was called (through
3807 handle_fontified_prop), and jit-lock-functions remove text
3808 properties or overlays from the portion of buffer that includes
3809 CHARPOS. Muse mode is known to do that, for example. In this
3810 case, we return -1 to the caller, to signal that no display
3811 string is actually present at CHARPOS. See bidi_fetch_char for
3812 how this is handled.
3814 An alternative would be to never look for display properties past
3815 it->stop_charpos. But neither compute_display_string_pos nor
3816 bidi_fetch_char that calls it know or care where the next
3817 stop_charpos is. */
3818 if (NILP (Fget_char_property (pos, Qdisplay, object)))
3819 return -1;
3821 /* Look forward for the first character where the `display' property
3822 changes. */
3823 pos = Fnext_single_char_property_change (pos, Qdisplay, object, Qnil);
3825 return XFASTINT (pos);
3830 /***********************************************************************
3831 Fontification
3832 ***********************************************************************/
3834 /* Handle changes in the `fontified' property of the current buffer by
3835 calling hook functions from Qfontification_functions to fontify
3836 regions of text. */
3838 static enum prop_handled
3839 handle_fontified_prop (struct it *it)
3841 Lisp_Object prop, pos;
3842 enum prop_handled handled = HANDLED_NORMALLY;
3844 if (!NILP (Vmemory_full))
3845 return handled;
3847 /* Get the value of the `fontified' property at IT's current buffer
3848 position. (The `fontified' property doesn't have a special
3849 meaning in strings.) If the value is nil, call functions from
3850 Qfontification_functions. */
3851 if (!STRINGP (it->string)
3852 && it->s == NULL
3853 && !NILP (Vfontification_functions)
3854 && !NILP (Vrun_hooks)
3855 && (pos = make_number (IT_CHARPOS (*it)),
3856 prop = Fget_char_property (pos, Qfontified, Qnil),
3857 /* Ignore the special cased nil value always present at EOB since
3858 no amount of fontifying will be able to change it. */
3859 NILP (prop) && IT_CHARPOS (*it) < Z))
3861 ptrdiff_t count = SPECPDL_INDEX ();
3862 Lisp_Object val;
3863 struct buffer *obuf = current_buffer;
3864 ptrdiff_t begv = BEGV, zv = ZV;
3865 bool old_clip_changed = current_buffer->clip_changed;
3867 val = Vfontification_functions;
3868 specbind (Qfontification_functions, Qnil);
3870 eassert (it->end_charpos == ZV);
3872 if (!CONSP (val) || EQ (XCAR (val), Qlambda))
3873 safe_call1 (val, pos);
3874 else
3876 Lisp_Object fns, fn;
3878 fns = Qnil;
3880 for (; CONSP (val); val = XCDR (val))
3882 fn = XCAR (val);
3884 if (EQ (fn, Qt))
3886 /* A value of t indicates this hook has a local
3887 binding; it means to run the global binding too.
3888 In a global value, t should not occur. If it
3889 does, we must ignore it to avoid an endless
3890 loop. */
3891 for (fns = Fdefault_value (Qfontification_functions);
3892 CONSP (fns);
3893 fns = XCDR (fns))
3895 fn = XCAR (fns);
3896 if (!EQ (fn, Qt))
3897 safe_call1 (fn, pos);
3900 else
3901 safe_call1 (fn, pos);
3905 unbind_to (count, Qnil);
3907 /* Fontification functions routinely call `save-restriction'.
3908 Normally, this tags clip_changed, which can confuse redisplay
3909 (see discussion in Bug#6671). Since we don't perform any
3910 special handling of fontification changes in the case where
3911 `save-restriction' isn't called, there's no point doing so in
3912 this case either. So, if the buffer's restrictions are
3913 actually left unchanged, reset clip_changed. */
3914 if (obuf == current_buffer)
3916 if (begv == BEGV && zv == ZV)
3917 current_buffer->clip_changed = old_clip_changed;
3919 /* There isn't much we can reasonably do to protect against
3920 misbehaving fontification, but here's a fig leaf. */
3921 else if (BUFFER_LIVE_P (obuf))
3922 set_buffer_internal_1 (obuf);
3924 /* The fontification code may have added/removed text.
3925 It could do even a lot worse, but let's at least protect against
3926 the most obvious case where only the text past `pos' gets changed',
3927 as is/was done in grep.el where some escapes sequences are turned
3928 into face properties (bug#7876). */
3929 it->end_charpos = ZV;
3931 /* Return HANDLED_RECOMPUTE_PROPS only if function fontified
3932 something. This avoids an endless loop if they failed to
3933 fontify the text for which reason ever. */
3934 if (!NILP (Fget_char_property (pos, Qfontified, Qnil)))
3935 handled = HANDLED_RECOMPUTE_PROPS;
3938 return handled;
3943 /***********************************************************************
3944 Faces
3945 ***********************************************************************/
3947 /* Set up iterator IT from face properties at its current position.
3948 Called from handle_stop. */
3950 static enum prop_handled
3951 handle_face_prop (struct it *it)
3953 int new_face_id;
3954 ptrdiff_t next_stop;
3956 if (!STRINGP (it->string))
3958 new_face_id
3959 = face_at_buffer_position (it->w,
3960 IT_CHARPOS (*it),
3961 &next_stop,
3962 (IT_CHARPOS (*it)
3963 + TEXT_PROP_DISTANCE_LIMIT),
3964 false, it->base_face_id);
3966 /* Is this a start of a run of characters with box face?
3967 Caveat: this can be called for a freshly initialized
3968 iterator; face_id is -1 in this case. We know that the new
3969 face will not change until limit, i.e. if the new face has a
3970 box, all characters up to limit will have one. But, as
3971 usual, we don't know whether limit is really the end. */
3972 if (new_face_id != it->face_id)
3974 struct face *new_face = FACE_FROM_ID (it->f, new_face_id);
3975 /* If it->face_id is -1, old_face below will be NULL, see
3976 the definition of FACE_FROM_ID_OR_NULL. This will happen
3977 if this is the initial call that gets the face. */
3978 struct face *old_face = FACE_FROM_ID_OR_NULL (it->f, it->face_id);
3980 /* If the value of face_id of the iterator is -1, we have to
3981 look in front of IT's position and see whether there is a
3982 face there that's different from new_face_id. */
3983 if (!old_face && IT_CHARPOS (*it) > BEG)
3985 int prev_face_id = face_before_it_pos (it);
3987 old_face = FACE_FROM_ID_OR_NULL (it->f, prev_face_id);
3990 /* If the new face has a box, but the old face does not,
3991 this is the start of a run of characters with box face,
3992 i.e. this character has a shadow on the left side. */
3993 it->start_of_box_run_p = (new_face->box != FACE_NO_BOX
3994 && (old_face == NULL || !old_face->box));
3995 it->face_box_p = new_face->box != FACE_NO_BOX;
3998 else
4000 int base_face_id;
4001 ptrdiff_t bufpos;
4002 int i;
4003 Lisp_Object from_overlay
4004 = (it->current.overlay_string_index >= 0
4005 ? it->string_overlays[it->current.overlay_string_index
4006 % OVERLAY_STRING_CHUNK_SIZE]
4007 : Qnil);
4009 /* See if we got to this string directly or indirectly from
4010 an overlay property. That includes the before-string or
4011 after-string of an overlay, strings in display properties
4012 provided by an overlay, their text properties, etc.
4014 FROM_OVERLAY is the overlay that brought us here, or nil if none. */
4015 if (! NILP (from_overlay))
4016 for (i = it->sp - 1; i >= 0; i--)
4018 if (it->stack[i].current.overlay_string_index >= 0)
4019 from_overlay
4020 = it->string_overlays[it->stack[i].current.overlay_string_index
4021 % OVERLAY_STRING_CHUNK_SIZE];
4022 else if (! NILP (it->stack[i].from_overlay))
4023 from_overlay = it->stack[i].from_overlay;
4025 if (!NILP (from_overlay))
4026 break;
4029 if (! NILP (from_overlay))
4031 bufpos = IT_CHARPOS (*it);
4032 /* For a string from an overlay, the base face depends
4033 only on text properties and ignores overlays. */
4034 base_face_id
4035 = face_for_overlay_string (it->w,
4036 IT_CHARPOS (*it),
4037 &next_stop,
4038 (IT_CHARPOS (*it)
4039 + TEXT_PROP_DISTANCE_LIMIT),
4040 false,
4041 from_overlay);
4043 else
4045 bufpos = 0;
4047 /* For strings from a `display' property, use the face at
4048 IT's current buffer position as the base face to merge
4049 with, so that overlay strings appear in the same face as
4050 surrounding text, unless they specify their own faces.
4051 For strings from wrap-prefix and line-prefix properties,
4052 use the default face, possibly remapped via
4053 Vface_remapping_alist. */
4054 /* Note that the fact that we use the face at _buffer_
4055 position means that a 'display' property on an overlay
4056 string will not inherit the face of that overlay string,
4057 but will instead revert to the face of buffer text
4058 covered by the overlay. This is visible, e.g., when the
4059 overlay specifies a box face, but neither the buffer nor
4060 the display string do. This sounds like a design bug,
4061 but Emacs always did that since v21.1, so changing that
4062 might be a big deal. */
4063 base_face_id = it->string_from_prefix_prop_p
4064 ? (!NILP (Vface_remapping_alist)
4065 ? lookup_basic_face (it->f, DEFAULT_FACE_ID)
4066 : DEFAULT_FACE_ID)
4067 : underlying_face_id (it);
4070 new_face_id = face_at_string_position (it->w,
4071 it->string,
4072 IT_STRING_CHARPOS (*it),
4073 bufpos,
4074 &next_stop,
4075 base_face_id, false);
4077 /* Is this a start of a run of characters with box? Caveat:
4078 this can be called for a freshly allocated iterator; face_id
4079 is -1 is this case. We know that the new face will not
4080 change until the next check pos, i.e. if the new face has a
4081 box, all characters up to that position will have a
4082 box. But, as usual, we don't know whether that position
4083 is really the end. */
4084 if (new_face_id != it->face_id)
4086 struct face *new_face = FACE_FROM_ID (it->f, new_face_id);
4087 struct face *old_face = FACE_FROM_ID_OR_NULL (it->f, it->face_id);
4089 /* If new face has a box but old face hasn't, this is the
4090 start of a run of characters with box, i.e. it has a
4091 shadow on the left side. */
4092 it->start_of_box_run_p
4093 = new_face->box && (old_face == NULL || !old_face->box);
4094 it->face_box_p = new_face->box != FACE_NO_BOX;
4098 it->face_id = new_face_id;
4099 return HANDLED_NORMALLY;
4103 /* Return the ID of the face ``underlying'' IT's current position,
4104 which is in a string. If the iterator is associated with a
4105 buffer, return the face at IT's current buffer position.
4106 Otherwise, use the iterator's base_face_id. */
4108 static int
4109 underlying_face_id (struct it *it)
4111 int face_id = it->base_face_id, i;
4113 eassert (STRINGP (it->string));
4115 for (i = it->sp - 1; i >= 0; --i)
4116 if (NILP (it->stack[i].string))
4117 face_id = it->stack[i].face_id;
4119 return face_id;
4123 /* Compute the face one character before or after the current position
4124 of IT, in the visual order. BEFORE_P means get the face
4125 in front (to the left in L2R paragraphs, to the right in R2L
4126 paragraphs) of IT's screen position. Value is the ID of the face. */
4128 static int
4129 face_before_or_after_it_pos (struct it *it, bool before_p)
4131 int face_id, limit;
4132 ptrdiff_t next_check_charpos;
4133 struct it it_copy;
4134 void *it_copy_data = NULL;
4136 eassert (it->s == NULL);
4138 if (STRINGP (it->string))
4140 ptrdiff_t bufpos, charpos;
4141 int base_face_id;
4143 /* No face change past the end of the string (for the case
4144 we are padding with spaces). No face change before the
4145 string start. */
4146 if (IT_STRING_CHARPOS (*it) >= SCHARS (it->string)
4147 || (IT_STRING_CHARPOS (*it) == 0 && before_p))
4148 return it->face_id;
4150 if (!it->bidi_p)
4152 /* Set charpos to the position before or after IT's current
4153 position, in the logical order, which in the non-bidi
4154 case is the same as the visual order. */
4155 if (before_p)
4156 charpos = IT_STRING_CHARPOS (*it) - 1;
4157 else if (it->what == IT_COMPOSITION)
4158 /* For composition, we must check the character after the
4159 composition. */
4160 charpos = IT_STRING_CHARPOS (*it) + it->cmp_it.nchars;
4161 else
4162 charpos = IT_STRING_CHARPOS (*it) + 1;
4164 else
4166 if (before_p)
4168 /* With bidi iteration, the character before the current
4169 in the visual order cannot be found by simple
4170 iteration, because "reverse" reordering is not
4171 supported. Instead, we need to start from the string
4172 beginning and go all the way to the current string
4173 position, remembering the previous position. */
4174 /* Ignore face changes before the first visible
4175 character on this display line. */
4176 if (it->current_x <= it->first_visible_x)
4177 return it->face_id;
4178 SAVE_IT (it_copy, *it, it_copy_data);
4179 IT_STRING_CHARPOS (it_copy) = 0;
4180 bidi_init_it (0, 0, FRAME_WINDOW_P (it_copy.f), &it_copy.bidi_it);
4184 charpos = IT_STRING_CHARPOS (it_copy);
4185 if (charpos >= SCHARS (it->string))
4186 break;
4187 bidi_move_to_visually_next (&it_copy.bidi_it);
4189 while (IT_STRING_CHARPOS (it_copy) != IT_STRING_CHARPOS (*it));
4191 RESTORE_IT (it, it, it_copy_data);
4193 else
4195 /* Set charpos to the string position of the character
4196 that comes after IT's current position in the visual
4197 order. */
4198 int n = (it->what == IT_COMPOSITION ? it->cmp_it.nchars : 1);
4200 it_copy = *it;
4201 while (n--)
4202 bidi_move_to_visually_next (&it_copy.bidi_it);
4204 charpos = it_copy.bidi_it.charpos;
4207 eassert (0 <= charpos && charpos <= SCHARS (it->string));
4209 if (it->current.overlay_string_index >= 0)
4210 bufpos = IT_CHARPOS (*it);
4211 else
4212 bufpos = 0;
4214 base_face_id = underlying_face_id (it);
4216 /* Get the face for ASCII, or unibyte. */
4217 face_id = face_at_string_position (it->w,
4218 it->string,
4219 charpos,
4220 bufpos,
4221 &next_check_charpos,
4222 base_face_id, false);
4224 /* Correct the face for charsets different from ASCII. Do it
4225 for the multibyte case only. The face returned above is
4226 suitable for unibyte text if IT->string is unibyte. */
4227 if (STRING_MULTIBYTE (it->string))
4229 struct text_pos pos1 = string_pos (charpos, it->string);
4230 const unsigned char *p = SDATA (it->string) + BYTEPOS (pos1);
4231 int c, len;
4232 struct face *face = FACE_FROM_ID (it->f, face_id);
4234 c = string_char_and_length (p, &len);
4235 face_id = FACE_FOR_CHAR (it->f, face, c, charpos, it->string);
4238 else
4240 struct text_pos pos;
4242 if ((IT_CHARPOS (*it) >= ZV && !before_p)
4243 || (IT_CHARPOS (*it) <= BEGV && before_p))
4244 return it->face_id;
4246 limit = IT_CHARPOS (*it) + TEXT_PROP_DISTANCE_LIMIT;
4247 pos = it->current.pos;
4249 if (!it->bidi_p)
4251 if (before_p)
4252 DEC_TEXT_POS (pos, it->multibyte_p);
4253 else
4255 if (it->what == IT_COMPOSITION)
4257 /* For composition, we must check the position after
4258 the composition. */
4259 pos.charpos += it->cmp_it.nchars;
4260 pos.bytepos += it->len;
4262 else
4263 INC_TEXT_POS (pos, it->multibyte_p);
4266 else
4268 if (before_p)
4270 int current_x;
4272 /* With bidi iteration, the character before the current
4273 in the visual order cannot be found by simple
4274 iteration, because "reverse" reordering is not
4275 supported. Instead, we need to use the move_it_*
4276 family of functions, and move to the previous
4277 character starting from the beginning of the visual
4278 line. */
4279 /* Ignore face changes before the first visible
4280 character on this display line. */
4281 if (it->current_x <= it->first_visible_x)
4282 return it->face_id;
4283 SAVE_IT (it_copy, *it, it_copy_data);
4284 /* Implementation note: Since move_it_in_display_line
4285 works in the iterator geometry, and thinks the first
4286 character is always the leftmost, even in R2L lines,
4287 we don't need to distinguish between the R2L and L2R
4288 cases here. */
4289 current_x = it_copy.current_x;
4290 move_it_vertically_backward (&it_copy, 0);
4291 move_it_in_display_line (&it_copy, ZV, current_x - 1, MOVE_TO_X);
4292 pos = it_copy.current.pos;
4293 RESTORE_IT (it, it, it_copy_data);
4295 else
4297 /* Set charpos to the buffer position of the character
4298 that comes after IT's current position in the visual
4299 order. */
4300 int n = (it->what == IT_COMPOSITION ? it->cmp_it.nchars : 1);
4302 it_copy = *it;
4303 while (n--)
4304 bidi_move_to_visually_next (&it_copy.bidi_it);
4306 SET_TEXT_POS (pos,
4307 it_copy.bidi_it.charpos, it_copy.bidi_it.bytepos);
4310 eassert (BEGV <= CHARPOS (pos) && CHARPOS (pos) <= ZV);
4312 /* Determine face for CHARSET_ASCII, or unibyte. */
4313 face_id = face_at_buffer_position (it->w,
4314 CHARPOS (pos),
4315 &next_check_charpos,
4316 limit, false, -1);
4318 /* Correct the face for charsets different from ASCII. Do it
4319 for the multibyte case only. The face returned above is
4320 suitable for unibyte text if current_buffer is unibyte. */
4321 if (it->multibyte_p)
4323 int c = FETCH_MULTIBYTE_CHAR (BYTEPOS (pos));
4324 struct face *face = FACE_FROM_ID (it->f, face_id);
4325 face_id = FACE_FOR_CHAR (it->f, face, c, CHARPOS (pos), Qnil);
4329 return face_id;
4334 /***********************************************************************
4335 Invisible text
4336 ***********************************************************************/
4338 /* Set up iterator IT from invisible properties at its current
4339 position. Called from handle_stop. */
4341 static enum prop_handled
4342 handle_invisible_prop (struct it *it)
4344 enum prop_handled handled = HANDLED_NORMALLY;
4345 int invis;
4346 Lisp_Object prop;
4348 if (STRINGP (it->string))
4350 Lisp_Object end_charpos, limit;
4352 /* Get the value of the invisible text property at the
4353 current position. Value will be nil if there is no such
4354 property. */
4355 end_charpos = make_number (IT_STRING_CHARPOS (*it));
4356 prop = Fget_text_property (end_charpos, Qinvisible, it->string);
4357 invis = TEXT_PROP_MEANS_INVISIBLE (prop);
4359 if (invis != 0 && IT_STRING_CHARPOS (*it) < it->end_charpos)
4361 /* Record whether we have to display an ellipsis for the
4362 invisible text. */
4363 bool display_ellipsis_p = (invis == 2);
4364 ptrdiff_t len, endpos;
4366 handled = HANDLED_RECOMPUTE_PROPS;
4368 /* Get the position at which the next visible text can be
4369 found in IT->string, if any. */
4370 endpos = len = SCHARS (it->string);
4371 XSETINT (limit, len);
4374 end_charpos
4375 = Fnext_single_property_change (end_charpos, Qinvisible,
4376 it->string, limit);
4377 /* Since LIMIT is always an integer, so should be the
4378 value returned by Fnext_single_property_change. */
4379 eassert (INTEGERP (end_charpos));
4380 if (INTEGERP (end_charpos))
4382 endpos = XFASTINT (end_charpos);
4383 prop = Fget_text_property (end_charpos, Qinvisible, it->string);
4384 invis = TEXT_PROP_MEANS_INVISIBLE (prop);
4385 if (invis == 2)
4386 display_ellipsis_p = true;
4388 else /* Should never happen; but if it does, exit the loop. */
4389 endpos = len;
4391 while (invis != 0 && endpos < len);
4393 if (display_ellipsis_p)
4394 it->ellipsis_p = true;
4396 if (endpos < len)
4398 /* Text at END_CHARPOS is visible. Move IT there. */
4399 struct text_pos old;
4400 ptrdiff_t oldpos;
4402 old = it->current.string_pos;
4403 oldpos = CHARPOS (old);
4404 if (it->bidi_p)
4406 if (it->bidi_it.first_elt
4407 && it->bidi_it.charpos < SCHARS (it->string))
4408 bidi_paragraph_init (it->paragraph_embedding,
4409 &it->bidi_it, true);
4410 /* Bidi-iterate out of the invisible text. */
4413 bidi_move_to_visually_next (&it->bidi_it);
4415 while (oldpos <= it->bidi_it.charpos
4416 && it->bidi_it.charpos < endpos
4417 && it->bidi_it.charpos < it->bidi_it.string.schars);
4419 IT_STRING_CHARPOS (*it) = it->bidi_it.charpos;
4420 IT_STRING_BYTEPOS (*it) = it->bidi_it.bytepos;
4421 if (IT_CHARPOS (*it) >= endpos)
4422 it->prev_stop = endpos;
4424 else
4426 IT_STRING_CHARPOS (*it) = endpos;
4427 compute_string_pos (&it->current.string_pos, old, it->string);
4430 else
4432 /* The rest of the string is invisible. If this is an
4433 overlay string, proceed with the next overlay string
4434 or whatever comes and return a character from there. */
4435 if (it->current.overlay_string_index >= 0
4436 && !display_ellipsis_p)
4438 next_overlay_string (it);
4439 /* Don't check for overlay strings when we just
4440 finished processing them. */
4441 handled = HANDLED_OVERLAY_STRING_CONSUMED;
4443 else
4445 IT_STRING_CHARPOS (*it) = SCHARS (it->string);
4446 IT_STRING_BYTEPOS (*it) = SBYTES (it->string);
4451 else
4453 ptrdiff_t newpos, next_stop, start_charpos, tem;
4454 Lisp_Object pos, overlay;
4456 /* First of all, is there invisible text at this position? */
4457 tem = start_charpos = IT_CHARPOS (*it);
4458 pos = make_number (tem);
4459 prop = get_char_property_and_overlay (pos, Qinvisible, it->window,
4460 &overlay);
4461 invis = TEXT_PROP_MEANS_INVISIBLE (prop);
4463 /* If we are on invisible text, skip over it. */
4464 if (invis != 0 && start_charpos < it->end_charpos)
4466 /* Record whether we have to display an ellipsis for the
4467 invisible text. */
4468 bool display_ellipsis_p = invis == 2;
4470 handled = HANDLED_RECOMPUTE_PROPS;
4472 /* Loop skipping over invisible text. The loop is left at
4473 ZV or with IT on the first char being visible again. */
4476 /* Try to skip some invisible text. Return value is the
4477 position reached which can be equal to where we start
4478 if there is nothing invisible there. This skips both
4479 over invisible text properties and overlays with
4480 invisible property. */
4481 newpos = skip_invisible (tem, &next_stop, ZV, it->window);
4483 /* If we skipped nothing at all we weren't at invisible
4484 text in the first place. If everything to the end of
4485 the buffer was skipped, end the loop. */
4486 if (newpos == tem || newpos >= ZV)
4487 invis = 0;
4488 else
4490 /* We skipped some characters but not necessarily
4491 all there are. Check if we ended up on visible
4492 text. Fget_char_property returns the property of
4493 the char before the given position, i.e. if we
4494 get invis = 0, this means that the char at
4495 newpos is visible. */
4496 pos = make_number (newpos);
4497 prop = Fget_char_property (pos, Qinvisible, it->window);
4498 invis = TEXT_PROP_MEANS_INVISIBLE (prop);
4501 /* If we ended up on invisible text, proceed to
4502 skip starting with next_stop. */
4503 if (invis != 0)
4504 tem = next_stop;
4506 /* If there are adjacent invisible texts, don't lose the
4507 second one's ellipsis. */
4508 if (invis == 2)
4509 display_ellipsis_p = true;
4511 while (invis != 0);
4513 /* The position newpos is now either ZV or on visible text. */
4514 if (it->bidi_p)
4516 ptrdiff_t bpos = CHAR_TO_BYTE (newpos);
4517 bool on_newline
4518 = bpos == ZV_BYTE || FETCH_BYTE (bpos) == '\n';
4519 bool after_newline
4520 = newpos <= BEGV || FETCH_BYTE (bpos - 1) == '\n';
4522 /* If the invisible text ends on a newline or on a
4523 character after a newline, we can avoid the costly,
4524 character by character, bidi iteration to NEWPOS, and
4525 instead simply reseat the iterator there. That's
4526 because all bidi reordering information is tossed at
4527 the newline. This is a big win for modes that hide
4528 complete lines, like Outline, Org, etc. */
4529 if (on_newline || after_newline)
4531 struct text_pos tpos;
4532 bidi_dir_t pdir = it->bidi_it.paragraph_dir;
4534 SET_TEXT_POS (tpos, newpos, bpos);
4535 reseat_1 (it, tpos, false);
4536 /* If we reseat on a newline/ZV, we need to prep the
4537 bidi iterator for advancing to the next character
4538 after the newline/EOB, keeping the current paragraph
4539 direction (so that PRODUCE_GLYPHS does TRT wrt
4540 prepending/appending glyphs to a glyph row). */
4541 if (on_newline)
4543 it->bidi_it.first_elt = false;
4544 it->bidi_it.paragraph_dir = pdir;
4545 it->bidi_it.ch = (bpos == ZV_BYTE) ? -1 : '\n';
4546 it->bidi_it.nchars = 1;
4547 it->bidi_it.ch_len = 1;
4550 else /* Must use the slow method. */
4552 /* With bidi iteration, the region of invisible text
4553 could start and/or end in the middle of a
4554 non-base embedding level. Therefore, we need to
4555 skip invisible text using the bidi iterator,
4556 starting at IT's current position, until we find
4557 ourselves outside of the invisible text.
4558 Skipping invisible text _after_ bidi iteration
4559 avoids affecting the visual order of the
4560 displayed text when invisible properties are
4561 added or removed. */
4562 if (it->bidi_it.first_elt && it->bidi_it.charpos < ZV)
4564 /* If we were `reseat'ed to a new paragraph,
4565 determine the paragraph base direction. We
4566 need to do it now because
4567 next_element_from_buffer may not have a
4568 chance to do it, if we are going to skip any
4569 text at the beginning, which resets the
4570 FIRST_ELT flag. */
4571 bidi_paragraph_init (it->paragraph_embedding,
4572 &it->bidi_it, true);
4576 bidi_move_to_visually_next (&it->bidi_it);
4578 while (it->stop_charpos <= it->bidi_it.charpos
4579 && it->bidi_it.charpos < newpos);
4580 IT_CHARPOS (*it) = it->bidi_it.charpos;
4581 IT_BYTEPOS (*it) = it->bidi_it.bytepos;
4582 /* If we overstepped NEWPOS, record its position in
4583 the iterator, so that we skip invisible text if
4584 later the bidi iteration lands us in the
4585 invisible region again. */
4586 if (IT_CHARPOS (*it) >= newpos)
4587 it->prev_stop = newpos;
4590 else
4592 IT_CHARPOS (*it) = newpos;
4593 IT_BYTEPOS (*it) = CHAR_TO_BYTE (newpos);
4596 if (display_ellipsis_p)
4598 /* Make sure that the glyphs of the ellipsis will get
4599 correct `charpos' values. If we would not update
4600 it->position here, the glyphs would belong to the
4601 last visible character _before_ the invisible
4602 text, which confuses `set_cursor_from_row'.
4604 We use the last invisible position instead of the
4605 first because this way the cursor is always drawn on
4606 the first "." of the ellipsis, whenever PT is inside
4607 the invisible text. Otherwise the cursor would be
4608 placed _after_ the ellipsis when the point is after the
4609 first invisible character. */
4610 if (!STRINGP (it->object))
4612 it->position.charpos = newpos - 1;
4613 it->position.bytepos = CHAR_TO_BYTE (it->position.charpos);
4617 /* If there are before-strings at the start of invisible
4618 text, and the text is invisible because of a text
4619 property, arrange to show before-strings because 20.x did
4620 it that way. (If the text is invisible because of an
4621 overlay property instead of a text property, this is
4622 already handled in the overlay code.) */
4623 if (NILP (overlay)
4624 && get_overlay_strings (it, it->stop_charpos))
4626 handled = HANDLED_RECOMPUTE_PROPS;
4627 if (it->sp > 0)
4629 it->stack[it->sp - 1].display_ellipsis_p = display_ellipsis_p;
4630 /* The call to get_overlay_strings above recomputes
4631 it->stop_charpos, but it only considers changes
4632 in properties and overlays beyond iterator's
4633 current position. This causes us to miss changes
4634 that happen exactly where the invisible property
4635 ended. So we play it safe here and force the
4636 iterator to check for potential stop positions
4637 immediately after the invisible text. Note that
4638 if get_overlay_strings returns true, it
4639 normally also pushed the iterator stack, so we
4640 need to update the stop position in the slot
4641 below the current one. */
4642 it->stack[it->sp - 1].stop_charpos
4643 = CHARPOS (it->stack[it->sp - 1].current.pos);
4646 else if (display_ellipsis_p)
4648 it->ellipsis_p = true;
4649 /* Let the ellipsis display before
4650 considering any properties of the following char.
4651 Fixes jasonr@gnu.org 01 Oct 07 bug. */
4652 handled = HANDLED_RETURN;
4657 return handled;
4661 /* Make iterator IT return `...' next.
4662 Replaces LEN characters from buffer. */
4664 static void
4665 setup_for_ellipsis (struct it *it, int len)
4667 /* Use the display table definition for `...'. Invalid glyphs
4668 will be handled by the method returning elements from dpvec. */
4669 if (it->dp && VECTORP (DISP_INVIS_VECTOR (it->dp)))
4671 struct Lisp_Vector *v = XVECTOR (DISP_INVIS_VECTOR (it->dp));
4672 it->dpvec = v->contents;
4673 it->dpend = v->contents + v->header.size;
4675 else
4677 /* Default `...'. */
4678 it->dpvec = default_invis_vector;
4679 it->dpend = default_invis_vector + 3;
4682 it->dpvec_char_len = len;
4683 it->current.dpvec_index = 0;
4684 it->dpvec_face_id = -1;
4686 /* Use IT->saved_face_id for the ellipsis, so that it has the same
4687 face as the preceding text. IT->saved_face_id was set in
4688 handle_stop to the face of the preceding character, and will be
4689 different from IT->face_id only if the invisible text skipped in
4690 handle_invisible_prop has some non-default face on its first
4691 character. We thus ignore the face of the invisible text when we
4692 display the ellipsis. IT's face is restored in set_iterator_to_next. */
4693 if (it->saved_face_id >= 0)
4694 it->face_id = it->saved_face_id;
4696 /* If the ellipsis represents buffer text, it means we advanced in
4697 the buffer, so we should no longer ignore overlay strings. */
4698 if (it->method == GET_FROM_BUFFER)
4699 it->ignore_overlay_strings_at_pos_p = false;
4701 it->method = GET_FROM_DISPLAY_VECTOR;
4702 it->ellipsis_p = true;
4707 /***********************************************************************
4708 'display' property
4709 ***********************************************************************/
4711 /* Set up iterator IT from `display' property at its current position.
4712 Called from handle_stop.
4713 We return HANDLED_RETURN if some part of the display property
4714 overrides the display of the buffer text itself.
4715 Otherwise we return HANDLED_NORMALLY. */
4717 static enum prop_handled
4718 handle_display_prop (struct it *it)
4720 Lisp_Object propval, object, overlay;
4721 struct text_pos *position;
4722 ptrdiff_t bufpos;
4723 /* Nonzero if some property replaces the display of the text itself. */
4724 int display_replaced = 0;
4726 if (STRINGP (it->string))
4728 object = it->string;
4729 position = &it->current.string_pos;
4730 bufpos = CHARPOS (it->current.pos);
4732 else
4734 XSETWINDOW (object, it->w);
4735 position = &it->current.pos;
4736 bufpos = CHARPOS (*position);
4739 /* Reset those iterator values set from display property values. */
4740 it->slice.x = it->slice.y = it->slice.width = it->slice.height = Qnil;
4741 it->space_width = Qnil;
4742 it->font_height = Qnil;
4743 it->voffset = 0;
4745 /* We don't support recursive `display' properties, i.e. string
4746 values that have a string `display' property, that have a string
4747 `display' property etc. */
4748 if (!it->string_from_display_prop_p)
4749 it->area = TEXT_AREA;
4751 propval = get_char_property_and_overlay (make_number (position->charpos),
4752 Qdisplay, object, &overlay);
4753 if (NILP (propval))
4754 return HANDLED_NORMALLY;
4755 /* Now OVERLAY is the overlay that gave us this property, or nil
4756 if it was a text property. */
4758 if (!STRINGP (it->string))
4759 object = it->w->contents;
4761 display_replaced = handle_display_spec (it, propval, object, overlay,
4762 position, bufpos,
4763 FRAME_WINDOW_P (it->f));
4764 return display_replaced != 0 ? HANDLED_RETURN : HANDLED_NORMALLY;
4767 /* Subroutine of handle_display_prop. Returns non-zero if the display
4768 specification in SPEC is a replacing specification, i.e. it would
4769 replace the text covered by `display' property with something else,
4770 such as an image or a display string. If SPEC includes any kind or
4771 `(space ...) specification, the value is 2; this is used by
4772 compute_display_string_pos, which see.
4774 See handle_single_display_spec for documentation of arguments.
4775 FRAME_WINDOW_P is true if the window being redisplayed is on a
4776 GUI frame; this argument is used only if IT is NULL, see below.
4778 IT can be NULL, if this is called by the bidi reordering code
4779 through compute_display_string_pos, which see. In that case, this
4780 function only examines SPEC, but does not otherwise "handle" it, in
4781 the sense that it doesn't set up members of IT from the display
4782 spec. */
4783 static int
4784 handle_display_spec (struct it *it, Lisp_Object spec, Lisp_Object object,
4785 Lisp_Object overlay, struct text_pos *position,
4786 ptrdiff_t bufpos, bool frame_window_p)
4788 int replacing = 0;
4789 bool enable_eval = true;
4791 /* Support (disable-eval PROP) which is used by enriched.el. */
4792 if (CONSP (spec) && EQ (XCAR (spec), Qdisable_eval))
4794 enable_eval = false;
4795 spec = XCAR (XCDR (spec));
4798 if (CONSP (spec)
4799 /* Simple specifications. */
4800 && !EQ (XCAR (spec), Qimage)
4801 #ifdef HAVE_XWIDGETS
4802 && !EQ (XCAR (spec), Qxwidget)
4803 #endif
4804 && !EQ (XCAR (spec), Qspace)
4805 && !EQ (XCAR (spec), Qwhen)
4806 && !EQ (XCAR (spec), Qslice)
4807 && !EQ (XCAR (spec), Qspace_width)
4808 && !EQ (XCAR (spec), Qheight)
4809 && !EQ (XCAR (spec), Qraise)
4810 /* Marginal area specifications. */
4811 && !(CONSP (XCAR (spec)) && EQ (XCAR (XCAR (spec)), Qmargin))
4812 && !EQ (XCAR (spec), Qleft_fringe)
4813 && !EQ (XCAR (spec), Qright_fringe)
4814 && !NILP (XCAR (spec)))
4816 for (; CONSP (spec); spec = XCDR (spec))
4818 int rv = handle_single_display_spec (it, XCAR (spec), object,
4819 overlay, position, bufpos,
4820 replacing, frame_window_p,
4821 enable_eval);
4822 if (rv != 0)
4824 replacing = rv;
4825 /* If some text in a string is replaced, `position' no
4826 longer points to the position of `object'. */
4827 if (!it || STRINGP (object))
4828 break;
4832 else if (VECTORP (spec))
4834 ptrdiff_t i;
4835 for (i = 0; i < ASIZE (spec); ++i)
4837 int rv = handle_single_display_spec (it, AREF (spec, i), object,
4838 overlay, position, bufpos,
4839 replacing, frame_window_p,
4840 enable_eval);
4841 if (rv != 0)
4843 replacing = rv;
4844 /* If some text in a string is replaced, `position' no
4845 longer points to the position of `object'. */
4846 if (!it || STRINGP (object))
4847 break;
4851 else
4852 replacing = handle_single_display_spec (it, spec, object, overlay, position,
4853 bufpos, 0, frame_window_p,
4854 enable_eval);
4855 return replacing;
4858 /* Value is the position of the end of the `display' property starting
4859 at START_POS in OBJECT. */
4861 static struct text_pos
4862 display_prop_end (struct it *it, Lisp_Object object, struct text_pos start_pos)
4864 Lisp_Object end;
4865 struct text_pos end_pos;
4867 end = Fnext_single_char_property_change (make_number (CHARPOS (start_pos)),
4868 Qdisplay, object, Qnil);
4869 CHARPOS (end_pos) = XFASTINT (end);
4870 if (STRINGP (object))
4871 compute_string_pos (&end_pos, start_pos, it->string);
4872 else
4873 BYTEPOS (end_pos) = CHAR_TO_BYTE (XFASTINT (end));
4875 return end_pos;
4879 /* Set up IT from a single `display' property specification SPEC. OBJECT
4880 is the object in which the `display' property was found. *POSITION
4881 is the position in OBJECT at which the `display' property was found.
4882 BUFPOS is the buffer position of OBJECT (different from POSITION if
4883 OBJECT is not a buffer). DISPLAY_REPLACED non-zero means that we
4884 previously saw a display specification which already replaced text
4885 display with something else, for example an image; we ignore such
4886 properties after the first one has been processed.
4888 OVERLAY is the overlay this `display' property came from,
4889 or nil if it was a text property.
4891 If SPEC is a `space' or `image' specification, and in some other
4892 cases too, set *POSITION to the position where the `display'
4893 property ends.
4895 If IT is NULL, only examine the property specification in SPEC, but
4896 don't set up IT. In that case, FRAME_WINDOW_P means SPEC
4897 is intended to be displayed in a window on a GUI frame.
4899 Enable evaluation of Lisp forms only if ENABLE_EVAL_P is true.
4901 Value is non-zero if something was found which replaces the display
4902 of buffer or string text. */
4904 static int
4905 handle_single_display_spec (struct it *it, Lisp_Object spec, Lisp_Object object,
4906 Lisp_Object overlay, struct text_pos *position,
4907 ptrdiff_t bufpos, int display_replaced,
4908 bool frame_window_p, bool enable_eval_p)
4910 Lisp_Object form;
4911 Lisp_Object location, value;
4912 struct text_pos start_pos = *position;
4914 /* If SPEC is a list of the form `(when FORM . VALUE)', evaluate FORM.
4915 If the result is non-nil, use VALUE instead of SPEC. */
4916 form = Qt;
4917 if (CONSP (spec) && EQ (XCAR (spec), Qwhen))
4919 spec = XCDR (spec);
4920 if (!CONSP (spec))
4921 return 0;
4922 form = XCAR (spec);
4923 spec = XCDR (spec);
4926 if (!NILP (form) && !EQ (form, Qt) && !enable_eval_p)
4927 form = Qnil;
4928 if (!NILP (form) && !EQ (form, Qt))
4930 ptrdiff_t count = SPECPDL_INDEX ();
4932 /* Bind `object' to the object having the `display' property, a
4933 buffer or string. Bind `position' to the position in the
4934 object where the property was found, and `buffer-position'
4935 to the current position in the buffer. */
4937 if (NILP (object))
4938 XSETBUFFER (object, current_buffer);
4939 specbind (Qobject, object);
4940 specbind (Qposition, make_number (CHARPOS (*position)));
4941 specbind (Qbuffer_position, make_number (bufpos));
4942 form = safe_eval (form);
4943 unbind_to (count, Qnil);
4946 if (NILP (form))
4947 return 0;
4949 /* Handle `(height HEIGHT)' specifications. */
4950 if (CONSP (spec)
4951 && EQ (XCAR (spec), Qheight)
4952 && CONSP (XCDR (spec)))
4954 if (it)
4956 if (!FRAME_WINDOW_P (it->f))
4957 return 0;
4959 it->font_height = XCAR (XCDR (spec));
4960 if (!NILP (it->font_height))
4962 int new_height = -1;
4964 if (CONSP (it->font_height)
4965 && (EQ (XCAR (it->font_height), Qplus)
4966 || EQ (XCAR (it->font_height), Qminus))
4967 && CONSP (XCDR (it->font_height))
4968 && RANGED_INTEGERP (0, XCAR (XCDR (it->font_height)), INT_MAX))
4970 /* `(+ N)' or `(- N)' where N is an integer. */
4971 int steps = XINT (XCAR (XCDR (it->font_height)));
4972 if (EQ (XCAR (it->font_height), Qplus))
4973 steps = - steps;
4974 it->face_id = smaller_face (it->f, it->face_id, steps);
4976 else if (FUNCTIONP (it->font_height) && enable_eval_p)
4978 /* Call function with current height as argument.
4979 Value is the new height. */
4980 struct face *face = FACE_FROM_ID (it->f, it->face_id);
4981 Lisp_Object height;
4982 height = safe_call1 (it->font_height,
4983 face->lface[LFACE_HEIGHT_INDEX]);
4984 if (NUMBERP (height))
4985 new_height = XFLOATINT (height);
4987 else if (NUMBERP (it->font_height))
4989 /* Value is a multiple of the canonical char height. */
4990 struct face *f;
4992 f = FACE_FROM_ID (it->f,
4993 lookup_basic_face (it->f, DEFAULT_FACE_ID));
4994 new_height = (XFLOATINT (it->font_height)
4995 * XINT (f->lface[LFACE_HEIGHT_INDEX]));
4997 else if (enable_eval_p)
4999 /* Evaluate IT->font_height with `height' bound to the
5000 current specified height to get the new height. */
5001 ptrdiff_t count = SPECPDL_INDEX ();
5002 struct face *face = FACE_FROM_ID (it->f, it->face_id);
5004 specbind (Qheight, face->lface[LFACE_HEIGHT_INDEX]);
5005 value = safe_eval (it->font_height);
5006 unbind_to (count, Qnil);
5008 if (NUMBERP (value))
5009 new_height = XFLOATINT (value);
5012 if (new_height > 0)
5013 it->face_id = face_with_height (it->f, it->face_id, new_height);
5017 return 0;
5020 /* Handle `(space-width WIDTH)'. */
5021 if (CONSP (spec)
5022 && EQ (XCAR (spec), Qspace_width)
5023 && CONSP (XCDR (spec)))
5025 if (it)
5027 if (!FRAME_WINDOW_P (it->f))
5028 return 0;
5030 value = XCAR (XCDR (spec));
5031 if (NUMBERP (value) && XFLOATINT (value) > 0)
5032 it->space_width = value;
5035 return 0;
5038 /* Handle `(slice X Y WIDTH HEIGHT)'. */
5039 if (CONSP (spec)
5040 && EQ (XCAR (spec), Qslice))
5042 Lisp_Object tem;
5044 if (it)
5046 if (!FRAME_WINDOW_P (it->f))
5047 return 0;
5049 if (tem = XCDR (spec), CONSP (tem))
5051 it->slice.x = XCAR (tem);
5052 if (tem = XCDR (tem), CONSP (tem))
5054 it->slice.y = XCAR (tem);
5055 if (tem = XCDR (tem), CONSP (tem))
5057 it->slice.width = XCAR (tem);
5058 if (tem = XCDR (tem), CONSP (tem))
5059 it->slice.height = XCAR (tem);
5065 return 0;
5068 /* Handle `(raise FACTOR)'. */
5069 if (CONSP (spec)
5070 && EQ (XCAR (spec), Qraise)
5071 && CONSP (XCDR (spec)))
5073 if (it)
5075 if (!FRAME_WINDOW_P (it->f))
5076 return 0;
5078 #ifdef HAVE_WINDOW_SYSTEM
5079 value = XCAR (XCDR (spec));
5080 if (NUMBERP (value))
5082 struct face *face = FACE_FROM_ID (it->f, it->face_id);
5083 it->voffset = - (XFLOATINT (value)
5084 * (normal_char_height (face->font, -1)));
5086 #endif /* HAVE_WINDOW_SYSTEM */
5089 return 0;
5092 /* Don't handle the other kinds of display specifications
5093 inside a string that we got from a `display' property. */
5094 if (it && it->string_from_display_prop_p)
5095 return 0;
5097 /* Characters having this form of property are not displayed, so
5098 we have to find the end of the property. */
5099 if (it)
5101 start_pos = *position;
5102 *position = display_prop_end (it, object, start_pos);
5103 /* If the display property comes from an overlay, don't consider
5104 any potential stop_charpos values before the end of that
5105 overlay. Since display_prop_end will happily find another
5106 'display' property coming from some other overlay or text
5107 property on buffer positions before this overlay's end, we
5108 need to ignore them, or else we risk displaying this
5109 overlay's display string/image twice. */
5110 if (!NILP (overlay))
5112 ptrdiff_t ovendpos = OVERLAY_POSITION (OVERLAY_END (overlay));
5114 /* Some borderline-sane Lisp might call us with the current
5115 buffer narrowed so that overlay-end is outside the
5116 POINT_MIN..POINT_MAX region, which will then cause
5117 various assertion violations and crashes down the road,
5118 starting with pop_it when it will attempt to use POSITION
5119 set below. Prevent that. */
5120 ovendpos = clip_to_bounds (BEGV, ovendpos, ZV);
5122 if (ovendpos > CHARPOS (*position))
5123 SET_TEXT_POS (*position, ovendpos, CHAR_TO_BYTE (ovendpos));
5126 value = Qnil;
5128 /* Stop the scan at that end position--we assume that all
5129 text properties change there. */
5130 if (it)
5131 it->stop_charpos = position->charpos;
5133 /* Handle `(left-fringe BITMAP [FACE])'
5134 and `(right-fringe BITMAP [FACE])'. */
5135 if (CONSP (spec)
5136 && (EQ (XCAR (spec), Qleft_fringe)
5137 || EQ (XCAR (spec), Qright_fringe))
5138 && CONSP (XCDR (spec)))
5140 if (it)
5142 if (!FRAME_WINDOW_P (it->f))
5143 /* If we return here, POSITION has been advanced
5144 across the text with this property. */
5146 /* Synchronize the bidi iterator with POSITION. This is
5147 needed because we are not going to push the iterator
5148 on behalf of this display property, so there will be
5149 no pop_it call to do this synchronization for us. */
5150 if (it->bidi_p)
5152 it->position = *position;
5153 iterate_out_of_display_property (it);
5154 *position = it->position;
5156 return 1;
5159 else if (!frame_window_p)
5160 return 1;
5162 #ifdef HAVE_WINDOW_SYSTEM
5163 value = XCAR (XCDR (spec));
5164 int fringe_bitmap = SYMBOLP (value) ? lookup_fringe_bitmap (value) : 0;
5165 if (! fringe_bitmap)
5166 /* If we return here, POSITION has been advanced
5167 across the text with this property. */
5169 if (it && it->bidi_p)
5171 it->position = *position;
5172 iterate_out_of_display_property (it);
5173 *position = it->position;
5175 return 1;
5178 if (it)
5180 int face_id = lookup_basic_face (it->f, DEFAULT_FACE_ID);
5182 if (CONSP (XCDR (XCDR (spec))))
5184 Lisp_Object face_name = XCAR (XCDR (XCDR (spec)));
5185 int face_id2 = lookup_derived_face (it->f, face_name,
5186 FRINGE_FACE_ID, false);
5187 if (face_id2 >= 0)
5188 face_id = face_id2;
5191 /* Save current settings of IT so that we can restore them
5192 when we are finished with the glyph property value. */
5193 push_it (it, position);
5195 it->area = TEXT_AREA;
5196 it->what = IT_IMAGE;
5197 it->image_id = -1; /* no image */
5198 it->position = start_pos;
5199 it->object = NILP (object) ? it->w->contents : object;
5200 it->method = GET_FROM_IMAGE;
5201 it->from_overlay = Qnil;
5202 it->face_id = face_id;
5203 it->from_disp_prop_p = true;
5205 /* Say that we haven't consumed the characters with
5206 `display' property yet. The call to pop_it in
5207 set_iterator_to_next will clean this up. */
5208 *position = start_pos;
5210 if (EQ (XCAR (spec), Qleft_fringe))
5212 it->left_user_fringe_bitmap = fringe_bitmap;
5213 it->left_user_fringe_face_id = face_id;
5215 else
5217 it->right_user_fringe_bitmap = fringe_bitmap;
5218 it->right_user_fringe_face_id = face_id;
5221 #endif /* HAVE_WINDOW_SYSTEM */
5222 return 1;
5225 /* Prepare to handle `((margin left-margin) ...)',
5226 `((margin right-margin) ...)' and `((margin nil) ...)'
5227 prefixes for display specifications. */
5228 location = Qunbound;
5229 if (CONSP (spec) && CONSP (XCAR (spec)))
5231 Lisp_Object tem;
5233 value = XCDR (spec);
5234 if (CONSP (value))
5235 value = XCAR (value);
5237 tem = XCAR (spec);
5238 if (EQ (XCAR (tem), Qmargin)
5239 && (tem = XCDR (tem),
5240 tem = CONSP (tem) ? XCAR (tem) : Qnil,
5241 (NILP (tem)
5242 || EQ (tem, Qleft_margin)
5243 || EQ (tem, Qright_margin))))
5244 location = tem;
5247 if (EQ (location, Qunbound))
5249 location = Qnil;
5250 value = spec;
5253 /* After this point, VALUE is the property after any
5254 margin prefix has been stripped. It must be a string,
5255 an image specification, or `(space ...)'.
5257 LOCATION specifies where to display: `left-margin',
5258 `right-margin' or nil. */
5260 bool valid_p = (STRINGP (value)
5261 #ifdef HAVE_WINDOW_SYSTEM
5262 || ((it ? FRAME_WINDOW_P (it->f) : frame_window_p)
5263 && valid_image_p (value))
5264 #endif /* not HAVE_WINDOW_SYSTEM */
5265 || (CONSP (value) && EQ (XCAR (value), Qspace))
5266 || ((it ? FRAME_WINDOW_P (it->f) : frame_window_p)
5267 && valid_xwidget_spec_p (value)));
5269 if (valid_p && display_replaced == 0)
5271 int retval = 1;
5273 if (!it)
5275 /* Callers need to know whether the display spec is any kind
5276 of `(space ...)' spec that is about to affect text-area
5277 display. */
5278 if (CONSP (value) && EQ (XCAR (value), Qspace) && NILP (location))
5279 retval = 2;
5280 return retval;
5283 /* Save current settings of IT so that we can restore them
5284 when we are finished with the glyph property value. */
5285 push_it (it, position);
5286 it->from_overlay = overlay;
5287 it->from_disp_prop_p = true;
5289 if (NILP (location))
5290 it->area = TEXT_AREA;
5291 else if (EQ (location, Qleft_margin))
5292 it->area = LEFT_MARGIN_AREA;
5293 else
5294 it->area = RIGHT_MARGIN_AREA;
5296 if (STRINGP (value))
5298 it->string = value;
5299 it->multibyte_p = STRING_MULTIBYTE (it->string);
5300 it->current.overlay_string_index = -1;
5301 IT_STRING_CHARPOS (*it) = IT_STRING_BYTEPOS (*it) = 0;
5302 it->end_charpos = it->string_nchars = SCHARS (it->string);
5303 it->method = GET_FROM_STRING;
5304 it->stop_charpos = 0;
5305 it->prev_stop = 0;
5306 it->base_level_stop = 0;
5307 it->string_from_display_prop_p = true;
5308 it->cmp_it.id = -1;
5309 /* Say that we haven't consumed the characters with
5310 `display' property yet. The call to pop_it in
5311 set_iterator_to_next will clean this up. */
5312 if (BUFFERP (object))
5313 *position = start_pos;
5315 /* Force paragraph direction to be that of the parent
5316 object. If the parent object's paragraph direction is
5317 not yet determined, default to L2R. */
5318 if (it->bidi_p && it->bidi_it.paragraph_dir == R2L)
5319 it->paragraph_embedding = it->bidi_it.paragraph_dir;
5320 else
5321 it->paragraph_embedding = L2R;
5323 /* Set up the bidi iterator for this display string. */
5324 if (it->bidi_p)
5326 it->bidi_it.string.lstring = it->string;
5327 it->bidi_it.string.s = NULL;
5328 it->bidi_it.string.schars = it->end_charpos;
5329 it->bidi_it.string.bufpos = bufpos;
5330 it->bidi_it.string.from_disp_str = true;
5331 it->bidi_it.string.unibyte = !it->multibyte_p;
5332 it->bidi_it.w = it->w;
5333 bidi_init_it (0, 0, FRAME_WINDOW_P (it->f), &it->bidi_it);
5336 else if (CONSP (value) && EQ (XCAR (value), Qspace))
5338 it->method = GET_FROM_STRETCH;
5339 it->object = value;
5340 *position = it->position = start_pos;
5341 retval = 1 + (it->area == TEXT_AREA);
5343 else if (valid_xwidget_spec_p (value))
5345 it->what = IT_XWIDGET;
5346 it->method = GET_FROM_XWIDGET;
5347 it->position = start_pos;
5348 it->object = NILP (object) ? it->w->contents : object;
5349 *position = start_pos;
5350 it->xwidget = lookup_xwidget (value);
5352 #ifdef HAVE_WINDOW_SYSTEM
5353 else
5355 it->what = IT_IMAGE;
5356 it->image_id = lookup_image (it->f, value);
5357 it->position = start_pos;
5358 it->object = NILP (object) ? it->w->contents : object;
5359 it->method = GET_FROM_IMAGE;
5361 /* Say that we haven't consumed the characters with
5362 `display' property yet. The call to pop_it in
5363 set_iterator_to_next will clean this up. */
5364 *position = start_pos;
5366 #endif /* HAVE_WINDOW_SYSTEM */
5368 return retval;
5371 /* Invalid property or property not supported. Restore
5372 POSITION to what it was before. */
5373 *position = start_pos;
5374 return 0;
5377 /* Check if PROP is a display property value whose text should be
5378 treated as intangible. OVERLAY is the overlay from which PROP
5379 came, or nil if it came from a text property. CHARPOS and BYTEPOS
5380 specify the buffer position covered by PROP. */
5382 bool
5383 display_prop_intangible_p (Lisp_Object prop, Lisp_Object overlay,
5384 ptrdiff_t charpos, ptrdiff_t bytepos)
5386 bool frame_window_p = FRAME_WINDOW_P (XFRAME (selected_frame));
5387 struct text_pos position;
5389 SET_TEXT_POS (position, charpos, bytepos);
5390 return (handle_display_spec (NULL, prop, Qnil, overlay,
5391 &position, charpos, frame_window_p)
5392 != 0);
5396 /* Return true if PROP is a display sub-property value containing STRING.
5398 Implementation note: this and the following function are really
5399 special cases of handle_display_spec and
5400 handle_single_display_spec, and should ideally use the same code.
5401 Until they do, these two pairs must be consistent and must be
5402 modified in sync. */
5404 static bool
5405 single_display_spec_string_p (Lisp_Object prop, Lisp_Object string)
5407 if (EQ (string, prop))
5408 return true;
5410 /* Skip over `when FORM'. */
5411 if (CONSP (prop) && EQ (XCAR (prop), Qwhen))
5413 prop = XCDR (prop);
5414 if (!CONSP (prop))
5415 return false;
5416 /* Actually, the condition following `when' should be eval'ed,
5417 like handle_single_display_spec does, and we should return
5418 false if it evaluates to nil. However, this function is
5419 called only when the buffer was already displayed and some
5420 glyph in the glyph matrix was found to come from a display
5421 string. Therefore, the condition was already evaluated, and
5422 the result was non-nil, otherwise the display string wouldn't
5423 have been displayed and we would have never been called for
5424 this property. Thus, we can skip the evaluation and assume
5425 its result is non-nil. */
5426 prop = XCDR (prop);
5429 if (CONSP (prop))
5430 /* Skip over `margin LOCATION'. */
5431 if (EQ (XCAR (prop), Qmargin))
5433 prop = XCDR (prop);
5434 if (!CONSP (prop))
5435 return false;
5437 prop = XCDR (prop);
5438 if (!CONSP (prop))
5439 return false;
5442 return EQ (prop, string) || (CONSP (prop) && EQ (XCAR (prop), string));
5446 /* Return true if STRING appears in the `display' property PROP. */
5448 static bool
5449 display_prop_string_p (Lisp_Object prop, Lisp_Object string)
5451 if (CONSP (prop)
5452 && !EQ (XCAR (prop), Qwhen)
5453 && !(CONSP (XCAR (prop)) && EQ (Qmargin, XCAR (XCAR (prop)))))
5455 /* A list of sub-properties. */
5456 while (CONSP (prop))
5458 if (single_display_spec_string_p (XCAR (prop), string))
5459 return true;
5460 prop = XCDR (prop);
5463 else if (VECTORP (prop))
5465 /* A vector of sub-properties. */
5466 ptrdiff_t i;
5467 for (i = 0; i < ASIZE (prop); ++i)
5468 if (single_display_spec_string_p (AREF (prop, i), string))
5469 return true;
5471 else
5472 return single_display_spec_string_p (prop, string);
5474 return false;
5477 /* Look for STRING in overlays and text properties in the current
5478 buffer, between character positions FROM and TO (excluding TO).
5479 BACK_P means look back (in this case, TO is supposed to be
5480 less than FROM).
5481 Value is the first character position where STRING was found, or
5482 zero if it wasn't found before hitting TO.
5484 This function may only use code that doesn't eval because it is
5485 called asynchronously from note_mouse_highlight. */
5487 static ptrdiff_t
5488 string_buffer_position_lim (Lisp_Object string,
5489 ptrdiff_t from, ptrdiff_t to, bool back_p)
5491 Lisp_Object limit, prop, pos;
5492 bool found = false;
5494 pos = make_number (max (from, BEGV));
5496 if (!back_p) /* looking forward */
5498 limit = make_number (min (to, ZV));
5499 while (!found && !EQ (pos, limit))
5501 prop = Fget_char_property (pos, Qdisplay, Qnil);
5502 if (!NILP (prop) && display_prop_string_p (prop, string))
5503 found = true;
5504 else
5505 pos = Fnext_single_char_property_change (pos, Qdisplay, Qnil,
5506 limit);
5509 else /* looking back */
5511 limit = make_number (max (to, BEGV));
5512 while (!found && !EQ (pos, limit))
5514 prop = Fget_char_property (pos, Qdisplay, Qnil);
5515 if (!NILP (prop) && display_prop_string_p (prop, string))
5516 found = true;
5517 else
5518 pos = Fprevious_single_char_property_change (pos, Qdisplay, Qnil,
5519 limit);
5523 return found ? XINT (pos) : 0;
5526 /* Determine which buffer position in current buffer STRING comes from.
5527 AROUND_CHARPOS is an approximate position where it could come from.
5528 Value is the buffer position or 0 if it couldn't be determined.
5530 This function is necessary because we don't record buffer positions
5531 in glyphs generated from strings (to keep struct glyph small).
5532 This function may only use code that doesn't eval because it is
5533 called asynchronously from note_mouse_highlight. */
5535 static ptrdiff_t
5536 string_buffer_position (Lisp_Object string, ptrdiff_t around_charpos)
5538 const int MAX_DISTANCE = 1000;
5539 ptrdiff_t found = string_buffer_position_lim (string, around_charpos,
5540 around_charpos + MAX_DISTANCE,
5541 false);
5543 if (!found)
5544 found = string_buffer_position_lim (string, around_charpos,
5545 around_charpos - MAX_DISTANCE, true);
5546 return found;
5551 /***********************************************************************
5552 `composition' property
5553 ***********************************************************************/
5555 /* Set up iterator IT from `composition' property at its current
5556 position. Called from handle_stop. */
5558 static enum prop_handled
5559 handle_composition_prop (struct it *it)
5561 Lisp_Object prop, string;
5562 ptrdiff_t pos, pos_byte, start, end;
5564 if (STRINGP (it->string))
5566 unsigned char *s;
5568 pos = IT_STRING_CHARPOS (*it);
5569 pos_byte = IT_STRING_BYTEPOS (*it);
5570 string = it->string;
5571 s = SDATA (string) + pos_byte;
5572 it->c = STRING_CHAR (s);
5574 else
5576 pos = IT_CHARPOS (*it);
5577 pos_byte = IT_BYTEPOS (*it);
5578 string = Qnil;
5579 it->c = FETCH_CHAR (pos_byte);
5582 /* If there's a valid composition and point is not inside of the
5583 composition (in the case that the composition is from the current
5584 buffer), draw a glyph composed from the composition components. */
5585 if (find_composition (pos, -1, &start, &end, &prop, string)
5586 && composition_valid_p (start, end, prop)
5587 && (STRINGP (it->string) || (PT <= start || PT >= end)))
5589 if (start < pos)
5590 /* As we can't handle this situation (perhaps font-lock added
5591 a new composition), we just return here hoping that next
5592 redisplay will detect this composition much earlier. */
5593 return HANDLED_NORMALLY;
5594 if (start != pos)
5596 if (STRINGP (it->string))
5597 pos_byte = string_char_to_byte (it->string, start);
5598 else
5599 pos_byte = CHAR_TO_BYTE (start);
5601 it->cmp_it.id = get_composition_id (start, pos_byte, end - start,
5602 prop, string);
5604 if (it->cmp_it.id >= 0)
5606 it->cmp_it.ch = -1;
5607 it->cmp_it.nchars = COMPOSITION_LENGTH (prop);
5608 it->cmp_it.nglyphs = -1;
5612 return HANDLED_NORMALLY;
5617 /***********************************************************************
5618 Overlay strings
5619 ***********************************************************************/
5621 /* The following structure is used to record overlay strings for
5622 later sorting in load_overlay_strings. */
5624 struct overlay_entry
5626 Lisp_Object overlay;
5627 Lisp_Object string;
5628 EMACS_INT priority;
5629 bool after_string_p;
5633 /* Set up iterator IT from overlay strings at its current position.
5634 Called from handle_stop. */
5636 static enum prop_handled
5637 handle_overlay_change (struct it *it)
5639 if (!STRINGP (it->string) && get_overlay_strings (it, 0))
5640 return HANDLED_RECOMPUTE_PROPS;
5641 else
5642 return HANDLED_NORMALLY;
5646 /* Set up the next overlay string for delivery by IT, if there is an
5647 overlay string to deliver. Called by set_iterator_to_next when the
5648 end of the current overlay string is reached. If there are more
5649 overlay strings to display, IT->string and
5650 IT->current.overlay_string_index are set appropriately here.
5651 Otherwise IT->string is set to nil. */
5653 static void
5654 next_overlay_string (struct it *it)
5656 ++it->current.overlay_string_index;
5657 if (it->current.overlay_string_index == it->n_overlay_strings)
5659 /* No more overlay strings. Restore IT's settings to what
5660 they were before overlay strings were processed, and
5661 continue to deliver from current_buffer. */
5663 it->ellipsis_p = it->stack[it->sp - 1].display_ellipsis_p;
5664 pop_it (it);
5665 eassert (it->sp > 0
5666 || (NILP (it->string)
5667 && it->method == GET_FROM_BUFFER
5668 && it->stop_charpos >= BEGV
5669 && it->stop_charpos <= it->end_charpos));
5670 it->current.overlay_string_index = -1;
5671 it->n_overlay_strings = 0;
5672 /* If there's an empty display string on the stack, pop the
5673 stack, to resync the bidi iterator with IT's position. Such
5674 empty strings are pushed onto the stack in
5675 get_overlay_strings_1. */
5676 if (it->sp > 0 && STRINGP (it->string) && !SCHARS (it->string))
5677 pop_it (it);
5679 /* Since we've exhausted overlay strings at this buffer
5680 position, set the flag to ignore overlays until we move to
5681 another position. (The flag will be reset in
5682 next_element_from_buffer.) But don't do that if the overlay
5683 strings were loaded at position other than the current one,
5684 which could happen if we called pop_it above, or if the
5685 overlay strings were loaded by handle_invisible_prop at the
5686 beginning of invisible text. */
5687 if (it->overlay_strings_charpos == IT_CHARPOS (*it))
5688 it->ignore_overlay_strings_at_pos_p = true;
5690 /* If we're at the end of the buffer, record that we have
5691 processed the overlay strings there already, so that
5692 next_element_from_buffer doesn't try it again. */
5693 if (NILP (it->string)
5694 && IT_CHARPOS (*it) >= it->end_charpos
5695 && it->overlay_strings_charpos >= it->end_charpos)
5696 it->overlay_strings_at_end_processed_p = true;
5697 /* Note: we reset overlay_strings_charpos only here, to make
5698 sure the just-processed overlays were indeed at EOB.
5699 Otherwise, overlays on text with invisible text property,
5700 which are processed with IT's position past the invisible
5701 text, might fool us into thinking the overlays at EOB were
5702 already processed (linum-mode can cause this, for
5703 example). */
5704 it->overlay_strings_charpos = -1;
5706 else
5708 /* There are more overlay strings to process. If
5709 IT->current.overlay_string_index has advanced to a position
5710 where we must load IT->overlay_strings with more strings, do
5711 it. We must load at the IT->overlay_strings_charpos where
5712 IT->n_overlay_strings was originally computed; when invisible
5713 text is present, this might not be IT_CHARPOS (Bug#7016). */
5714 int i = it->current.overlay_string_index % OVERLAY_STRING_CHUNK_SIZE;
5716 if (it->current.overlay_string_index && i == 0)
5717 load_overlay_strings (it, it->overlay_strings_charpos);
5719 /* Initialize IT to deliver display elements from the overlay
5720 string. */
5721 it->string = it->overlay_strings[i];
5722 it->multibyte_p = STRING_MULTIBYTE (it->string);
5723 SET_TEXT_POS (it->current.string_pos, 0, 0);
5724 it->method = GET_FROM_STRING;
5725 it->stop_charpos = 0;
5726 it->end_charpos = SCHARS (it->string);
5727 if (it->cmp_it.stop_pos >= 0)
5728 it->cmp_it.stop_pos = 0;
5729 it->prev_stop = 0;
5730 it->base_level_stop = 0;
5732 /* Set up the bidi iterator for this overlay string. */
5733 if (it->bidi_p)
5735 it->bidi_it.string.lstring = it->string;
5736 it->bidi_it.string.s = NULL;
5737 it->bidi_it.string.schars = SCHARS (it->string);
5738 it->bidi_it.string.bufpos = it->overlay_strings_charpos;
5739 it->bidi_it.string.from_disp_str = it->string_from_display_prop_p;
5740 it->bidi_it.string.unibyte = !it->multibyte_p;
5741 it->bidi_it.w = it->w;
5742 bidi_init_it (0, 0, FRAME_WINDOW_P (it->f), &it->bidi_it);
5746 CHECK_IT (it);
5750 /* Compare two overlay_entry structures E1 and E2. Used as a
5751 comparison function for qsort in load_overlay_strings. Overlay
5752 strings for the same position are sorted so that
5754 1. All after-strings come in front of before-strings, except
5755 when they come from the same overlay.
5757 2. Within after-strings, strings are sorted so that overlay strings
5758 from overlays with higher priorities come first.
5760 2. Within before-strings, strings are sorted so that overlay
5761 strings from overlays with higher priorities come last.
5763 Value is analogous to strcmp. */
5766 static int
5767 compare_overlay_entries (const void *e1, const void *e2)
5769 struct overlay_entry const *entry1 = e1;
5770 struct overlay_entry const *entry2 = e2;
5771 int result;
5773 if (entry1->after_string_p != entry2->after_string_p)
5775 /* Let after-strings appear in front of before-strings if
5776 they come from different overlays. */
5777 if (EQ (entry1->overlay, entry2->overlay))
5778 result = entry1->after_string_p ? 1 : -1;
5779 else
5780 result = entry1->after_string_p ? -1 : 1;
5782 else if (entry1->priority != entry2->priority)
5784 if (entry1->after_string_p)
5785 /* After-strings sorted in order of decreasing priority. */
5786 result = entry2->priority < entry1->priority ? -1 : 1;
5787 else
5788 /* Before-strings sorted in order of increasing priority. */
5789 result = entry1->priority < entry2->priority ? -1 : 1;
5791 else
5792 result = 0;
5794 return result;
5798 /* Load the vector IT->overlay_strings with overlay strings from IT's
5799 current buffer position, or from CHARPOS if that is > 0. Set
5800 IT->n_overlays to the total number of overlay strings found.
5802 Overlay strings are processed OVERLAY_STRING_CHUNK_SIZE strings at
5803 a time. On entry into load_overlay_strings,
5804 IT->current.overlay_string_index gives the number of overlay
5805 strings that have already been loaded by previous calls to this
5806 function.
5808 IT->add_overlay_start contains an additional overlay start
5809 position to consider for taking overlay strings from, if non-zero.
5810 This position comes into play when the overlay has an `invisible'
5811 property, and both before and after-strings. When we've skipped to
5812 the end of the overlay, because of its `invisible' property, we
5813 nevertheless want its before-string to appear.
5814 IT->add_overlay_start will contain the overlay start position
5815 in this case.
5817 Overlay strings are sorted so that after-string strings come in
5818 front of before-string strings. Within before and after-strings,
5819 strings are sorted by overlay priority. See also function
5820 compare_overlay_entries. */
5822 static void
5823 load_overlay_strings (struct it *it, ptrdiff_t charpos)
5825 Lisp_Object overlay, window, str, invisible;
5826 struct Lisp_Overlay *ov;
5827 ptrdiff_t start, end;
5828 ptrdiff_t n = 0, i, j;
5829 int invis;
5830 struct overlay_entry entriesbuf[20];
5831 ptrdiff_t size = ARRAYELTS (entriesbuf);
5832 struct overlay_entry *entries = entriesbuf;
5833 USE_SAFE_ALLOCA;
5835 if (charpos <= 0)
5836 charpos = IT_CHARPOS (*it);
5838 /* Append the overlay string STRING of overlay OVERLAY to vector
5839 `entries' which has size `size' and currently contains `n'
5840 elements. AFTER_P means STRING is an after-string of
5841 OVERLAY. */
5842 #define RECORD_OVERLAY_STRING(OVERLAY, STRING, AFTER_P) \
5843 do \
5845 Lisp_Object priority; \
5847 if (n == size) \
5849 struct overlay_entry *old = entries; \
5850 SAFE_NALLOCA (entries, 2, size); \
5851 memcpy (entries, old, size * sizeof *entries); \
5852 size *= 2; \
5855 entries[n].string = (STRING); \
5856 entries[n].overlay = (OVERLAY); \
5857 priority = Foverlay_get ((OVERLAY), Qpriority); \
5858 entries[n].priority = INTEGERP (priority) ? XINT (priority) : 0; \
5859 entries[n].after_string_p = (AFTER_P); \
5860 ++n; \
5862 while (false)
5864 /* Process overlay before the overlay center. */
5865 for (ov = current_buffer->overlays_before; ov; ov = ov->next)
5867 XSETMISC (overlay, ov);
5868 eassert (OVERLAYP (overlay));
5869 start = OVERLAY_POSITION (OVERLAY_START (overlay));
5870 end = OVERLAY_POSITION (OVERLAY_END (overlay));
5872 if (end < charpos)
5873 break;
5875 /* Skip this overlay if it doesn't start or end at IT's current
5876 position. */
5877 if (end != charpos && start != charpos)
5878 continue;
5880 /* Skip this overlay if it doesn't apply to IT->w. */
5881 window = Foverlay_get (overlay, Qwindow);
5882 if (WINDOWP (window) && XWINDOW (window) != it->w)
5883 continue;
5885 /* If the text ``under'' the overlay is invisible, both before-
5886 and after-strings from this overlay are visible; start and
5887 end position are indistinguishable. */
5888 invisible = Foverlay_get (overlay, Qinvisible);
5889 invis = TEXT_PROP_MEANS_INVISIBLE (invisible);
5891 /* If overlay has a non-empty before-string, record it. */
5892 if ((start == charpos || (end == charpos && invis != 0))
5893 && (str = Foverlay_get (overlay, Qbefore_string), STRINGP (str))
5894 && SCHARS (str))
5895 RECORD_OVERLAY_STRING (overlay, str, false);
5897 /* If overlay has a non-empty after-string, record it. */
5898 if ((end == charpos || (start == charpos && invis != 0))
5899 && (str = Foverlay_get (overlay, Qafter_string), STRINGP (str))
5900 && SCHARS (str))
5901 RECORD_OVERLAY_STRING (overlay, str, true);
5904 /* Process overlays after the overlay center. */
5905 for (ov = current_buffer->overlays_after; ov; ov = ov->next)
5907 XSETMISC (overlay, ov);
5908 eassert (OVERLAYP (overlay));
5909 start = OVERLAY_POSITION (OVERLAY_START (overlay));
5910 end = OVERLAY_POSITION (OVERLAY_END (overlay));
5912 if (start > charpos)
5913 break;
5915 /* Skip this overlay if it doesn't start or end at IT's current
5916 position. */
5917 if (end != charpos && start != charpos)
5918 continue;
5920 /* Skip this overlay if it doesn't apply to IT->w. */
5921 window = Foverlay_get (overlay, Qwindow);
5922 if (WINDOWP (window) && XWINDOW (window) != it->w)
5923 continue;
5925 /* If the text ``under'' the overlay is invisible, it has a zero
5926 dimension, and both before- and after-strings apply. */
5927 invisible = Foverlay_get (overlay, Qinvisible);
5928 invis = TEXT_PROP_MEANS_INVISIBLE (invisible);
5930 /* If overlay has a non-empty before-string, record it. */
5931 if ((start == charpos || (end == charpos && invis != 0))
5932 && (str = Foverlay_get (overlay, Qbefore_string), STRINGP (str))
5933 && SCHARS (str))
5934 RECORD_OVERLAY_STRING (overlay, str, false);
5936 /* If overlay has a non-empty after-string, record it. */
5937 if ((end == charpos || (start == charpos && invis != 0))
5938 && (str = Foverlay_get (overlay, Qafter_string), STRINGP (str))
5939 && SCHARS (str))
5940 RECORD_OVERLAY_STRING (overlay, str, true);
5943 #undef RECORD_OVERLAY_STRING
5945 /* Sort entries. */
5946 if (n > 1)
5947 qsort (entries, n, sizeof *entries, compare_overlay_entries);
5949 /* Record number of overlay strings, and where we computed it. */
5950 it->n_overlay_strings = n;
5951 it->overlay_strings_charpos = charpos;
5953 /* IT->current.overlay_string_index is the number of overlay strings
5954 that have already been consumed by IT. Copy some of the
5955 remaining overlay strings to IT->overlay_strings. */
5956 i = 0;
5957 j = it->current.overlay_string_index;
5958 while (i < OVERLAY_STRING_CHUNK_SIZE && j < n)
5960 it->overlay_strings[i] = entries[j].string;
5961 it->string_overlays[i++] = entries[j++].overlay;
5964 CHECK_IT (it);
5965 SAFE_FREE ();
5969 /* Get the first chunk of overlay strings at IT's current buffer
5970 position, or at CHARPOS if that is > 0. Value is true if at
5971 least one overlay string was found. */
5973 static bool
5974 get_overlay_strings_1 (struct it *it, ptrdiff_t charpos, bool compute_stop_p)
5976 /* Get the first OVERLAY_STRING_CHUNK_SIZE overlay strings to
5977 process. This fills IT->overlay_strings with strings, and sets
5978 IT->n_overlay_strings to the total number of strings to process.
5979 IT->pos.overlay_string_index has to be set temporarily to zero
5980 because load_overlay_strings needs this; it must be set to -1
5981 when no overlay strings are found because a zero value would
5982 indicate a position in the first overlay string. */
5983 it->current.overlay_string_index = 0;
5984 load_overlay_strings (it, charpos);
5986 /* If we found overlay strings, set up IT to deliver display
5987 elements from the first one. Otherwise set up IT to deliver
5988 from current_buffer. */
5989 if (it->n_overlay_strings)
5991 /* Make sure we know settings in current_buffer, so that we can
5992 restore meaningful values when we're done with the overlay
5993 strings. */
5994 if (compute_stop_p)
5995 compute_stop_pos (it);
5996 eassert (it->face_id >= 0);
5998 /* Save IT's settings. They are restored after all overlay
5999 strings have been processed. */
6000 eassert (!compute_stop_p || it->sp == 0);
6002 /* When called from handle_stop, there might be an empty display
6003 string loaded. In that case, don't bother saving it. But
6004 don't use this optimization with the bidi iterator, since we
6005 need the corresponding pop_it call to resync the bidi
6006 iterator's position with IT's position, after we are done
6007 with the overlay strings. (The corresponding call to pop_it
6008 in case of an empty display string is in
6009 next_overlay_string.) */
6010 if (!(!it->bidi_p
6011 && STRINGP (it->string) && !SCHARS (it->string)))
6012 push_it (it, NULL);
6014 /* Set up IT to deliver display elements from the first overlay
6015 string. */
6016 IT_STRING_CHARPOS (*it) = IT_STRING_BYTEPOS (*it) = 0;
6017 it->string = it->overlay_strings[0];
6018 it->from_overlay = Qnil;
6019 it->stop_charpos = 0;
6020 eassert (STRINGP (it->string));
6021 it->end_charpos = SCHARS (it->string);
6022 it->prev_stop = 0;
6023 it->base_level_stop = 0;
6024 it->multibyte_p = STRING_MULTIBYTE (it->string);
6025 it->method = GET_FROM_STRING;
6026 it->from_disp_prop_p = 0;
6027 it->cmp_it.id = -1;
6029 /* Force paragraph direction to be that of the parent
6030 buffer. */
6031 if (it->bidi_p && it->bidi_it.paragraph_dir == R2L)
6032 it->paragraph_embedding = it->bidi_it.paragraph_dir;
6033 else
6034 it->paragraph_embedding = L2R;
6036 /* Set up the bidi iterator for this overlay string. */
6037 if (it->bidi_p)
6039 ptrdiff_t pos = (charpos > 0 ? charpos : IT_CHARPOS (*it));
6041 it->bidi_it.string.lstring = it->string;
6042 it->bidi_it.string.s = NULL;
6043 it->bidi_it.string.schars = SCHARS (it->string);
6044 it->bidi_it.string.bufpos = pos;
6045 it->bidi_it.string.from_disp_str = it->string_from_display_prop_p;
6046 it->bidi_it.string.unibyte = !it->multibyte_p;
6047 it->bidi_it.w = it->w;
6048 bidi_init_it (0, 0, FRAME_WINDOW_P (it->f), &it->bidi_it);
6050 return true;
6053 it->current.overlay_string_index = -1;
6054 return false;
6057 static bool
6058 get_overlay_strings (struct it *it, ptrdiff_t charpos)
6060 it->string = Qnil;
6061 it->method = GET_FROM_BUFFER;
6063 get_overlay_strings_1 (it, charpos, true);
6065 CHECK_IT (it);
6067 /* Value is true if we found at least one overlay string. */
6068 return STRINGP (it->string);
6073 /***********************************************************************
6074 Saving and restoring state
6075 ***********************************************************************/
6077 /* Save current settings of IT on IT->stack. Called, for example,
6078 before setting up IT for an overlay string, to be able to restore
6079 IT's settings to what they were after the overlay string has been
6080 processed. If POSITION is non-NULL, it is the position to save on
6081 the stack instead of IT->position. */
6083 static void
6084 push_it (struct it *it, struct text_pos *position)
6086 struct iterator_stack_entry *p;
6088 eassert (it->sp < IT_STACK_SIZE);
6089 p = it->stack + it->sp;
6091 p->stop_charpos = it->stop_charpos;
6092 p->prev_stop = it->prev_stop;
6093 p->base_level_stop = it->base_level_stop;
6094 p->cmp_it = it->cmp_it;
6095 eassert (it->face_id >= 0);
6096 p->face_id = it->face_id;
6097 p->string = it->string;
6098 p->method = it->method;
6099 p->from_overlay = it->from_overlay;
6100 switch (p->method)
6102 case GET_FROM_IMAGE:
6103 p->u.image.object = it->object;
6104 p->u.image.image_id = it->image_id;
6105 p->u.image.slice = it->slice;
6106 break;
6107 case GET_FROM_STRETCH:
6108 p->u.stretch.object = it->object;
6109 break;
6110 case GET_FROM_XWIDGET:
6111 p->u.xwidget.object = it->object;
6112 break;
6113 case GET_FROM_BUFFER:
6114 case GET_FROM_DISPLAY_VECTOR:
6115 case GET_FROM_STRING:
6116 case GET_FROM_C_STRING:
6117 break;
6118 default:
6119 emacs_abort ();
6121 p->position = position ? *position : it->position;
6122 p->current = it->current;
6123 p->end_charpos = it->end_charpos;
6124 p->string_nchars = it->string_nchars;
6125 p->area = it->area;
6126 p->multibyte_p = it->multibyte_p;
6127 p->avoid_cursor_p = it->avoid_cursor_p;
6128 p->space_width = it->space_width;
6129 p->font_height = it->font_height;
6130 p->voffset = it->voffset;
6131 p->string_from_display_prop_p = it->string_from_display_prop_p;
6132 p->string_from_prefix_prop_p = it->string_from_prefix_prop_p;
6133 p->display_ellipsis_p = false;
6134 p->line_wrap = it->line_wrap;
6135 p->bidi_p = it->bidi_p;
6136 p->paragraph_embedding = it->paragraph_embedding;
6137 p->from_disp_prop_p = it->from_disp_prop_p;
6138 ++it->sp;
6140 /* Save the state of the bidi iterator as well. */
6141 if (it->bidi_p)
6142 bidi_push_it (&it->bidi_it);
6145 static void
6146 iterate_out_of_display_property (struct it *it)
6148 bool buffer_p = !STRINGP (it->string);
6149 ptrdiff_t eob = (buffer_p ? ZV : it->end_charpos);
6150 ptrdiff_t bob = (buffer_p ? BEGV : 0);
6152 eassert (eob >= CHARPOS (it->position) && CHARPOS (it->position) >= bob);
6154 /* Maybe initialize paragraph direction. If we are at the beginning
6155 of a new paragraph, next_element_from_buffer may not have a
6156 chance to do that. */
6157 if (it->bidi_it.first_elt && it->bidi_it.charpos < eob)
6158 bidi_paragraph_init (it->paragraph_embedding, &it->bidi_it, true);
6159 /* prev_stop can be zero, so check against BEGV as well. */
6160 while (it->bidi_it.charpos >= bob
6161 && it->prev_stop <= it->bidi_it.charpos
6162 && it->bidi_it.charpos < CHARPOS (it->position)
6163 && it->bidi_it.charpos < eob)
6164 bidi_move_to_visually_next (&it->bidi_it);
6165 /* Record the stop_pos we just crossed, for when we cross it
6166 back, maybe. */
6167 if (it->bidi_it.charpos > CHARPOS (it->position))
6168 it->prev_stop = CHARPOS (it->position);
6169 /* If we ended up not where pop_it put us, resync IT's
6170 positional members with the bidi iterator. */
6171 if (it->bidi_it.charpos != CHARPOS (it->position))
6172 SET_TEXT_POS (it->position, it->bidi_it.charpos, it->bidi_it.bytepos);
6173 if (buffer_p)
6174 it->current.pos = it->position;
6175 else
6176 it->current.string_pos = it->position;
6179 /* Restore IT's settings from IT->stack. Called, for example, when no
6180 more overlay strings must be processed, and we return to delivering
6181 display elements from a buffer, or when the end of a string from a
6182 `display' property is reached and we return to delivering display
6183 elements from an overlay string, or from a buffer. */
6185 static void
6186 pop_it (struct it *it)
6188 struct iterator_stack_entry *p;
6189 bool from_display_prop = it->from_disp_prop_p;
6190 ptrdiff_t prev_pos = IT_CHARPOS (*it);
6192 eassert (it->sp > 0);
6193 --it->sp;
6194 p = it->stack + it->sp;
6195 it->stop_charpos = p->stop_charpos;
6196 it->prev_stop = p->prev_stop;
6197 it->base_level_stop = p->base_level_stop;
6198 it->cmp_it = p->cmp_it;
6199 it->face_id = p->face_id;
6200 it->current = p->current;
6201 it->position = p->position;
6202 it->string = p->string;
6203 it->from_overlay = p->from_overlay;
6204 if (NILP (it->string))
6205 SET_TEXT_POS (it->current.string_pos, -1, -1);
6206 it->method = p->method;
6207 switch (it->method)
6209 case GET_FROM_IMAGE:
6210 it->image_id = p->u.image.image_id;
6211 it->object = p->u.image.object;
6212 it->slice = p->u.image.slice;
6213 break;
6214 case GET_FROM_XWIDGET:
6215 it->object = p->u.xwidget.object;
6216 break;
6217 case GET_FROM_STRETCH:
6218 it->object = p->u.stretch.object;
6219 break;
6220 case GET_FROM_BUFFER:
6221 it->object = it->w->contents;
6222 break;
6223 case GET_FROM_STRING:
6225 struct face *face = FACE_FROM_ID_OR_NULL (it->f, it->face_id);
6227 /* Restore the face_box_p flag, since it could have been
6228 overwritten by the face of the object that we just finished
6229 displaying. */
6230 if (face)
6231 it->face_box_p = face->box != FACE_NO_BOX;
6232 it->object = it->string;
6234 break;
6235 case GET_FROM_DISPLAY_VECTOR:
6236 if (it->s)
6237 it->method = GET_FROM_C_STRING;
6238 else if (STRINGP (it->string))
6239 it->method = GET_FROM_STRING;
6240 else
6242 it->method = GET_FROM_BUFFER;
6243 it->object = it->w->contents;
6245 break;
6246 case GET_FROM_C_STRING:
6247 break;
6248 default:
6249 emacs_abort ();
6251 it->end_charpos = p->end_charpos;
6252 it->string_nchars = p->string_nchars;
6253 it->area = p->area;
6254 it->multibyte_p = p->multibyte_p;
6255 it->avoid_cursor_p = p->avoid_cursor_p;
6256 it->space_width = p->space_width;
6257 it->font_height = p->font_height;
6258 it->voffset = p->voffset;
6259 it->string_from_display_prop_p = p->string_from_display_prop_p;
6260 it->string_from_prefix_prop_p = p->string_from_prefix_prop_p;
6261 it->line_wrap = p->line_wrap;
6262 it->bidi_p = p->bidi_p;
6263 it->paragraph_embedding = p->paragraph_embedding;
6264 it->from_disp_prop_p = p->from_disp_prop_p;
6265 if (it->bidi_p)
6267 bidi_pop_it (&it->bidi_it);
6268 /* Bidi-iterate until we get out of the portion of text, if any,
6269 covered by a `display' text property or by an overlay with
6270 `display' property. (We cannot just jump there, because the
6271 internal coherency of the bidi iterator state can not be
6272 preserved across such jumps.) We also must determine the
6273 paragraph base direction if the overlay we just processed is
6274 at the beginning of a new paragraph. */
6275 if (from_display_prop
6276 && (it->method == GET_FROM_BUFFER || it->method == GET_FROM_STRING))
6277 iterate_out_of_display_property (it);
6279 eassert ((BUFFERP (it->object)
6280 && IT_CHARPOS (*it) == it->bidi_it.charpos
6281 && IT_BYTEPOS (*it) == it->bidi_it.bytepos)
6282 || (STRINGP (it->object)
6283 && IT_STRING_CHARPOS (*it) == it->bidi_it.charpos
6284 && IT_STRING_BYTEPOS (*it) == it->bidi_it.bytepos)
6285 || (CONSP (it->object) && it->method == GET_FROM_STRETCH));
6287 /* If we move the iterator over text covered by a display property
6288 to a new buffer position, any info about previously seen overlays
6289 is no longer valid. */
6290 if (from_display_prop && it->sp == 0 && CHARPOS (it->position) != prev_pos)
6291 it->ignore_overlay_strings_at_pos_p = false;
6296 /***********************************************************************
6297 Moving over lines
6298 ***********************************************************************/
6300 /* Set IT's current position to the previous line start. */
6302 static void
6303 back_to_previous_line_start (struct it *it)
6305 ptrdiff_t cp = IT_CHARPOS (*it), bp = IT_BYTEPOS (*it);
6307 DEC_BOTH (cp, bp);
6308 IT_CHARPOS (*it) = find_newline_no_quit (cp, bp, -1, &IT_BYTEPOS (*it));
6312 /* Move IT to the next line start.
6314 Value is true if a newline was found. Set *SKIPPED_P to true if
6315 we skipped over part of the text (as opposed to moving the iterator
6316 continuously over the text). Otherwise, don't change the value
6317 of *SKIPPED_P.
6319 If BIDI_IT_PREV is non-NULL, store into it the state of the bidi
6320 iterator on the newline, if it was found.
6322 Newlines may come from buffer text, overlay strings, or strings
6323 displayed via the `display' property. That's the reason we can't
6324 simply use find_newline_no_quit.
6326 Note that this function may not skip over invisible text that is so
6327 because of text properties and immediately follows a newline. If
6328 it would, function reseat_at_next_visible_line_start, when called
6329 from set_iterator_to_next, would effectively make invisible
6330 characters following a newline part of the wrong glyph row, which
6331 leads to wrong cursor motion. */
6333 static bool
6334 forward_to_next_line_start (struct it *it, bool *skipped_p,
6335 struct bidi_it *bidi_it_prev)
6337 ptrdiff_t old_selective;
6338 bool newline_found_p = false;
6339 int n;
6340 const int MAX_NEWLINE_DISTANCE = 500;
6342 /* If already on a newline, just consume it to avoid unintended
6343 skipping over invisible text below. */
6344 if (it->what == IT_CHARACTER
6345 && it->c == '\n'
6346 && CHARPOS (it->position) == IT_CHARPOS (*it))
6348 if (it->bidi_p && bidi_it_prev)
6349 *bidi_it_prev = it->bidi_it;
6350 set_iterator_to_next (it, false);
6351 it->c = 0;
6352 return true;
6355 /* Don't handle selective display in the following. It's (a)
6356 unnecessary because it's done by the caller, and (b) leads to an
6357 infinite recursion because next_element_from_ellipsis indirectly
6358 calls this function. */
6359 old_selective = it->selective;
6360 it->selective = 0;
6362 /* Scan for a newline within MAX_NEWLINE_DISTANCE display elements
6363 from buffer text. */
6364 for (n = 0;
6365 !newline_found_p && n < MAX_NEWLINE_DISTANCE;
6366 n += !STRINGP (it->string))
6368 if (!get_next_display_element (it))
6369 return false;
6370 newline_found_p = it->what == IT_CHARACTER && it->c == '\n';
6371 if (newline_found_p && it->bidi_p && bidi_it_prev)
6372 *bidi_it_prev = it->bidi_it;
6373 set_iterator_to_next (it, false);
6376 /* If we didn't find a newline near enough, see if we can use a
6377 short-cut. */
6378 if (!newline_found_p)
6380 ptrdiff_t bytepos, start = IT_CHARPOS (*it);
6381 ptrdiff_t limit = find_newline_no_quit (start, IT_BYTEPOS (*it),
6382 1, &bytepos);
6383 Lisp_Object pos;
6385 eassert (!STRINGP (it->string));
6387 /* If there isn't any `display' property in sight, and no
6388 overlays, we can just use the position of the newline in
6389 buffer text. */
6390 if (it->stop_charpos >= limit
6391 || ((pos = Fnext_single_property_change (make_number (start),
6392 Qdisplay, Qnil,
6393 make_number (limit)),
6394 NILP (pos))
6395 && next_overlay_change (start) == ZV))
6397 if (!it->bidi_p)
6399 IT_CHARPOS (*it) = limit;
6400 IT_BYTEPOS (*it) = bytepos;
6402 else
6404 struct bidi_it bprev;
6406 /* Help bidi.c avoid expensive searches for display
6407 properties and overlays, by telling it that there are
6408 none up to `limit'. */
6409 if (it->bidi_it.disp_pos < limit)
6411 it->bidi_it.disp_pos = limit;
6412 it->bidi_it.disp_prop = 0;
6414 do {
6415 bprev = it->bidi_it;
6416 bidi_move_to_visually_next (&it->bidi_it);
6417 } while (it->bidi_it.charpos != limit);
6418 IT_CHARPOS (*it) = limit;
6419 IT_BYTEPOS (*it) = it->bidi_it.bytepos;
6420 if (bidi_it_prev)
6421 *bidi_it_prev = bprev;
6423 *skipped_p = newline_found_p = true;
6425 else
6427 while (!newline_found_p)
6429 if (!get_next_display_element (it))
6430 break;
6431 newline_found_p = ITERATOR_AT_END_OF_LINE_P (it);
6432 if (newline_found_p && it->bidi_p && bidi_it_prev)
6433 *bidi_it_prev = it->bidi_it;
6434 set_iterator_to_next (it, false);
6439 it->selective = old_selective;
6440 return newline_found_p;
6444 /* Set IT's current position to the previous visible line start. Skip
6445 invisible text that is so either due to text properties or due to
6446 selective display. Caution: this does not change IT->current_x and
6447 IT->hpos. */
6449 static void
6450 back_to_previous_visible_line_start (struct it *it)
6452 while (IT_CHARPOS (*it) > BEGV)
6454 back_to_previous_line_start (it);
6456 if (IT_CHARPOS (*it) <= BEGV)
6457 break;
6459 /* If selective > 0, then lines indented more than its value are
6460 invisible. */
6461 if (it->selective > 0
6462 && indented_beyond_p (IT_CHARPOS (*it), IT_BYTEPOS (*it),
6463 it->selective))
6464 continue;
6466 /* Check the newline before point for invisibility. */
6468 Lisp_Object prop;
6469 prop = Fget_char_property (make_number (IT_CHARPOS (*it) - 1),
6470 Qinvisible, it->window);
6471 if (TEXT_PROP_MEANS_INVISIBLE (prop) != 0)
6472 continue;
6475 if (IT_CHARPOS (*it) <= BEGV)
6476 break;
6479 struct it it2;
6480 void *it2data = NULL;
6481 ptrdiff_t pos;
6482 ptrdiff_t beg, end;
6483 Lisp_Object val, overlay;
6485 SAVE_IT (it2, *it, it2data);
6487 /* If newline is part of a composition, continue from start of composition */
6488 if (find_composition (IT_CHARPOS (*it), -1, &beg, &end, &val, Qnil)
6489 && beg < IT_CHARPOS (*it))
6490 goto replaced;
6492 /* If newline is replaced by a display property, find start of overlay
6493 or interval and continue search from that point. */
6494 pos = --IT_CHARPOS (it2);
6495 --IT_BYTEPOS (it2);
6496 it2.sp = 0;
6497 bidi_unshelve_cache (NULL, false);
6498 it2.string_from_display_prop_p = false;
6499 it2.from_disp_prop_p = false;
6500 if (handle_display_prop (&it2) == HANDLED_RETURN
6501 && !NILP (val = get_char_property_and_overlay
6502 (make_number (pos), Qdisplay, Qnil, &overlay))
6503 && (OVERLAYP (overlay)
6504 ? (beg = OVERLAY_POSITION (OVERLAY_START (overlay)))
6505 : get_property_and_range (pos, Qdisplay, &val, &beg, &end, Qnil)))
6507 RESTORE_IT (it, it, it2data);
6508 goto replaced;
6511 /* Newline is not replaced by anything -- so we are done. */
6512 RESTORE_IT (it, it, it2data);
6513 break;
6515 replaced:
6516 if (beg < BEGV)
6517 beg = BEGV;
6518 IT_CHARPOS (*it) = beg;
6519 IT_BYTEPOS (*it) = buf_charpos_to_bytepos (current_buffer, beg);
6523 it->continuation_lines_width = 0;
6525 eassert (IT_CHARPOS (*it) >= BEGV);
6526 eassert (IT_CHARPOS (*it) == BEGV
6527 || FETCH_BYTE (IT_BYTEPOS (*it) - 1) == '\n');
6528 CHECK_IT (it);
6532 /* Reseat iterator IT at the previous visible line start. Skip
6533 invisible text that is so either due to text properties or due to
6534 selective display. At the end, update IT's overlay information,
6535 face information etc. */
6537 void
6538 reseat_at_previous_visible_line_start (struct it *it)
6540 back_to_previous_visible_line_start (it);
6541 reseat (it, it->current.pos, true);
6542 CHECK_IT (it);
6546 /* Reseat iterator IT on the next visible line start in the current
6547 buffer. ON_NEWLINE_P means position IT on the newline
6548 preceding the line start. Skip over invisible text that is so
6549 because of selective display. Compute faces, overlays etc at the
6550 new position. Note that this function does not skip over text that
6551 is invisible because of text properties. */
6553 static void
6554 reseat_at_next_visible_line_start (struct it *it, bool on_newline_p)
6556 bool skipped_p = false;
6557 struct bidi_it bidi_it_prev;
6558 bool newline_found_p
6559 = forward_to_next_line_start (it, &skipped_p, &bidi_it_prev);
6561 /* Skip over lines that are invisible because they are indented
6562 more than the value of IT->selective. */
6563 if (it->selective > 0)
6564 while (IT_CHARPOS (*it) < ZV
6565 && indented_beyond_p (IT_CHARPOS (*it), IT_BYTEPOS (*it),
6566 it->selective))
6568 eassert (IT_BYTEPOS (*it) == BEGV
6569 || FETCH_BYTE (IT_BYTEPOS (*it) - 1) == '\n');
6570 newline_found_p =
6571 forward_to_next_line_start (it, &skipped_p, &bidi_it_prev);
6574 /* Position on the newline if that's what's requested. */
6575 if (on_newline_p && newline_found_p)
6577 if (STRINGP (it->string))
6579 if (IT_STRING_CHARPOS (*it) > 0)
6581 if (!it->bidi_p)
6583 --IT_STRING_CHARPOS (*it);
6584 --IT_STRING_BYTEPOS (*it);
6586 else
6588 /* We need to restore the bidi iterator to the state
6589 it had on the newline, and resync the IT's
6590 position with that. */
6591 it->bidi_it = bidi_it_prev;
6592 IT_STRING_CHARPOS (*it) = it->bidi_it.charpos;
6593 IT_STRING_BYTEPOS (*it) = it->bidi_it.bytepos;
6597 else if (IT_CHARPOS (*it) > BEGV)
6599 if (!it->bidi_p)
6601 --IT_CHARPOS (*it);
6602 --IT_BYTEPOS (*it);
6604 else
6606 /* We need to restore the bidi iterator to the state it
6607 had on the newline and resync IT with that. */
6608 it->bidi_it = bidi_it_prev;
6609 IT_CHARPOS (*it) = it->bidi_it.charpos;
6610 IT_BYTEPOS (*it) = it->bidi_it.bytepos;
6612 reseat (it, it->current.pos, false);
6615 else if (skipped_p)
6616 reseat (it, it->current.pos, false);
6618 CHECK_IT (it);
6623 /***********************************************************************
6624 Changing an iterator's position
6625 ***********************************************************************/
6627 /* Change IT's current position to POS in current_buffer.
6628 If FORCE_P, always check for text properties at the new position.
6629 Otherwise, text properties are only looked up if POS >=
6630 IT->check_charpos of a property. */
6632 static void
6633 reseat (struct it *it, struct text_pos pos, bool force_p)
6635 ptrdiff_t original_pos = IT_CHARPOS (*it);
6637 reseat_1 (it, pos, false);
6639 /* Determine where to check text properties. Avoid doing it
6640 where possible because text property lookup is very expensive. */
6641 if (force_p
6642 || CHARPOS (pos) > it->stop_charpos
6643 || CHARPOS (pos) < original_pos)
6645 if (it->bidi_p)
6647 /* For bidi iteration, we need to prime prev_stop and
6648 base_level_stop with our best estimations. */
6649 /* Implementation note: Of course, POS is not necessarily a
6650 stop position, so assigning prev_pos to it is a lie; we
6651 should have called compute_stop_backwards. However, if
6652 the current buffer does not include any R2L characters,
6653 that call would be a waste of cycles, because the
6654 iterator will never move back, and thus never cross this
6655 "fake" stop position. So we delay that backward search
6656 until the time we really need it, in next_element_from_buffer. */
6657 if (CHARPOS (pos) != it->prev_stop)
6658 it->prev_stop = CHARPOS (pos);
6659 if (CHARPOS (pos) < it->base_level_stop)
6660 it->base_level_stop = 0; /* meaning it's unknown */
6661 handle_stop (it);
6663 else
6665 handle_stop (it);
6666 it->prev_stop = it->base_level_stop = 0;
6671 CHECK_IT (it);
6675 /* Change IT's buffer position to POS. SET_STOP_P means set
6676 IT->stop_pos to POS, also. */
6678 static void
6679 reseat_1 (struct it *it, struct text_pos pos, bool set_stop_p)
6681 /* Don't call this function when scanning a C string. */
6682 eassert (it->s == NULL);
6684 /* POS must be a reasonable value. */
6685 eassert (CHARPOS (pos) >= BEGV && CHARPOS (pos) <= ZV);
6687 it->current.pos = it->position = pos;
6688 it->end_charpos = ZV;
6689 it->dpvec = NULL;
6690 it->current.dpvec_index = -1;
6691 it->current.overlay_string_index = -1;
6692 IT_STRING_CHARPOS (*it) = -1;
6693 IT_STRING_BYTEPOS (*it) = -1;
6694 it->string = Qnil;
6695 it->method = GET_FROM_BUFFER;
6696 it->object = it->w->contents;
6697 it->area = TEXT_AREA;
6698 it->multibyte_p = !NILP (BVAR (current_buffer, enable_multibyte_characters));
6699 it->sp = 0;
6700 it->string_from_display_prop_p = false;
6701 it->string_from_prefix_prop_p = false;
6703 it->from_disp_prop_p = false;
6704 it->face_before_selective_p = false;
6705 if (it->bidi_p)
6707 bidi_init_it (IT_CHARPOS (*it), IT_BYTEPOS (*it), FRAME_WINDOW_P (it->f),
6708 &it->bidi_it);
6709 bidi_unshelve_cache (NULL, false);
6710 it->bidi_it.paragraph_dir = NEUTRAL_DIR;
6711 it->bidi_it.string.s = NULL;
6712 it->bidi_it.string.lstring = Qnil;
6713 it->bidi_it.string.bufpos = 0;
6714 it->bidi_it.string.from_disp_str = false;
6715 it->bidi_it.string.unibyte = false;
6716 it->bidi_it.w = it->w;
6719 if (set_stop_p)
6721 it->stop_charpos = CHARPOS (pos);
6722 it->base_level_stop = CHARPOS (pos);
6724 /* This make the information stored in it->cmp_it invalidate. */
6725 it->cmp_it.id = -1;
6729 /* Set up IT for displaying a string, starting at CHARPOS in window W.
6730 If S is non-null, it is a C string to iterate over. Otherwise,
6731 STRING gives a Lisp string to iterate over.
6733 If PRECISION > 0, don't return more then PRECISION number of
6734 characters from the string.
6736 If FIELD_WIDTH > 0, return padding spaces until FIELD_WIDTH
6737 characters have been returned. FIELD_WIDTH < 0 means an infinite
6738 field width.
6740 MULTIBYTE = 0 means disable processing of multibyte characters,
6741 MULTIBYTE > 0 means enable it,
6742 MULTIBYTE < 0 means use IT->multibyte_p.
6744 IT must be initialized via a prior call to init_iterator before
6745 calling this function. */
6747 static void
6748 reseat_to_string (struct it *it, const char *s, Lisp_Object string,
6749 ptrdiff_t charpos, ptrdiff_t precision, int field_width,
6750 int multibyte)
6752 /* No text property checks performed by default, but see below. */
6753 it->stop_charpos = -1;
6755 /* Set iterator position and end position. */
6756 memset (&it->current, 0, sizeof it->current);
6757 it->current.overlay_string_index = -1;
6758 it->current.dpvec_index = -1;
6759 eassert (charpos >= 0);
6761 /* If STRING is specified, use its multibyteness, otherwise use the
6762 setting of MULTIBYTE, if specified. */
6763 if (multibyte >= 0)
6764 it->multibyte_p = multibyte > 0;
6766 /* Bidirectional reordering of strings is controlled by the default
6767 value of bidi-display-reordering. Don't try to reorder while
6768 loading loadup.el, as the necessary character property tables are
6769 not yet available. */
6770 it->bidi_p =
6771 !redisplay__inhibit_bidi
6772 && !NILP (BVAR (&buffer_defaults, bidi_display_reordering));
6774 if (s == NULL)
6776 eassert (STRINGP (string));
6777 it->string = string;
6778 it->s = NULL;
6779 it->end_charpos = it->string_nchars = SCHARS (string);
6780 it->method = GET_FROM_STRING;
6781 it->current.string_pos = string_pos (charpos, string);
6783 if (it->bidi_p)
6785 it->bidi_it.string.lstring = string;
6786 it->bidi_it.string.s = NULL;
6787 it->bidi_it.string.schars = it->end_charpos;
6788 it->bidi_it.string.bufpos = 0;
6789 it->bidi_it.string.from_disp_str = false;
6790 it->bidi_it.string.unibyte = !it->multibyte_p;
6791 it->bidi_it.w = it->w;
6792 bidi_init_it (charpos, IT_STRING_BYTEPOS (*it),
6793 FRAME_WINDOW_P (it->f), &it->bidi_it);
6796 else
6798 it->s = (const unsigned char *) s;
6799 it->string = Qnil;
6801 /* Note that we use IT->current.pos, not it->current.string_pos,
6802 for displaying C strings. */
6803 IT_STRING_CHARPOS (*it) = IT_STRING_BYTEPOS (*it) = -1;
6804 if (it->multibyte_p)
6806 it->current.pos = c_string_pos (charpos, s, true);
6807 it->end_charpos = it->string_nchars = number_of_chars (s, true);
6809 else
6811 IT_CHARPOS (*it) = IT_BYTEPOS (*it) = charpos;
6812 it->end_charpos = it->string_nchars = strlen (s);
6815 if (it->bidi_p)
6817 it->bidi_it.string.lstring = Qnil;
6818 it->bidi_it.string.s = (const unsigned char *) s;
6819 it->bidi_it.string.schars = it->end_charpos;
6820 it->bidi_it.string.bufpos = 0;
6821 it->bidi_it.string.from_disp_str = false;
6822 it->bidi_it.string.unibyte = !it->multibyte_p;
6823 it->bidi_it.w = it->w;
6824 bidi_init_it (charpos, IT_BYTEPOS (*it), FRAME_WINDOW_P (it->f),
6825 &it->bidi_it);
6827 it->method = GET_FROM_C_STRING;
6830 /* PRECISION > 0 means don't return more than PRECISION characters
6831 from the string. */
6832 if (precision > 0 && it->end_charpos - charpos > precision)
6834 it->end_charpos = it->string_nchars = charpos + precision;
6835 if (it->bidi_p)
6836 it->bidi_it.string.schars = it->end_charpos;
6839 /* FIELD_WIDTH > 0 means pad with spaces until FIELD_WIDTH
6840 characters have been returned. FIELD_WIDTH == 0 means don't pad,
6841 FIELD_WIDTH < 0 means infinite field width. This is useful for
6842 padding with `-' at the end of a mode line. */
6843 if (field_width < 0)
6844 field_width = DISP_INFINITY;
6845 /* Implementation note: We deliberately don't enlarge
6846 it->bidi_it.string.schars here to fit it->end_charpos, because
6847 the bidi iterator cannot produce characters out of thin air. */
6848 if (field_width > it->end_charpos - charpos)
6849 it->end_charpos = charpos + field_width;
6851 /* Use the standard display table for displaying strings. */
6852 if (DISP_TABLE_P (Vstandard_display_table))
6853 it->dp = XCHAR_TABLE (Vstandard_display_table);
6855 it->stop_charpos = charpos;
6856 it->prev_stop = charpos;
6857 it->base_level_stop = 0;
6858 if (it->bidi_p)
6860 it->bidi_it.first_elt = true;
6861 it->bidi_it.paragraph_dir = NEUTRAL_DIR;
6862 it->bidi_it.disp_pos = -1;
6864 if (s == NULL && it->multibyte_p)
6866 ptrdiff_t endpos = SCHARS (it->string);
6867 if (endpos > it->end_charpos)
6868 endpos = it->end_charpos;
6869 composition_compute_stop_pos (&it->cmp_it, charpos, -1, endpos,
6870 it->string);
6872 CHECK_IT (it);
6877 /***********************************************************************
6878 Iteration
6879 ***********************************************************************/
6881 /* Map enum it_method value to corresponding next_element_from_* function. */
6883 typedef bool (*next_element_function) (struct it *);
6885 static next_element_function const get_next_element[NUM_IT_METHODS] =
6887 next_element_from_buffer,
6888 next_element_from_display_vector,
6889 next_element_from_string,
6890 next_element_from_c_string,
6891 next_element_from_image,
6892 next_element_from_stretch,
6893 next_element_from_xwidget,
6896 #define GET_NEXT_DISPLAY_ELEMENT(it) (*get_next_element[(it)->method]) (it)
6899 /* Return true iff a character at CHARPOS (and BYTEPOS) is composed
6900 (possibly with the following characters). */
6902 #define CHAR_COMPOSED_P(IT,CHARPOS,BYTEPOS,END_CHARPOS) \
6903 ((IT)->cmp_it.id >= 0 \
6904 || ((IT)->cmp_it.stop_pos == (CHARPOS) \
6905 && composition_reseat_it (&(IT)->cmp_it, CHARPOS, BYTEPOS, \
6906 END_CHARPOS, (IT)->w, \
6907 FACE_FROM_ID_OR_NULL ((IT)->f, \
6908 (IT)->face_id), \
6909 (IT)->string)))
6912 /* Lookup the char-table Vglyphless_char_display for character C (-1
6913 if we want information for no-font case), and return the display
6914 method symbol. By side-effect, update it->what and
6915 it->glyphless_method. This function is called from
6916 get_next_display_element for each character element, and from
6917 x_produce_glyphs when no suitable font was found. */
6919 Lisp_Object
6920 lookup_glyphless_char_display (int c, struct it *it)
6922 Lisp_Object glyphless_method = Qnil;
6924 if (CHAR_TABLE_P (Vglyphless_char_display)
6925 && CHAR_TABLE_EXTRA_SLOTS (XCHAR_TABLE (Vglyphless_char_display)) >= 1)
6927 if (c >= 0)
6929 glyphless_method = CHAR_TABLE_REF (Vglyphless_char_display, c);
6930 if (CONSP (glyphless_method))
6931 glyphless_method = FRAME_WINDOW_P (it->f)
6932 ? XCAR (glyphless_method)
6933 : XCDR (glyphless_method);
6935 else
6936 glyphless_method = XCHAR_TABLE (Vglyphless_char_display)->extras[0];
6939 retry:
6940 if (NILP (glyphless_method))
6942 if (c >= 0)
6943 /* The default is to display the character by a proper font. */
6944 return Qnil;
6945 /* The default for the no-font case is to display an empty box. */
6946 glyphless_method = Qempty_box;
6948 if (EQ (glyphless_method, Qzero_width))
6950 if (c >= 0)
6951 return glyphless_method;
6952 /* This method can't be used for the no-font case. */
6953 glyphless_method = Qempty_box;
6955 if (EQ (glyphless_method, Qthin_space))
6956 it->glyphless_method = GLYPHLESS_DISPLAY_THIN_SPACE;
6957 else if (EQ (glyphless_method, Qempty_box))
6958 it->glyphless_method = GLYPHLESS_DISPLAY_EMPTY_BOX;
6959 else if (EQ (glyphless_method, Qhex_code))
6960 it->glyphless_method = GLYPHLESS_DISPLAY_HEX_CODE;
6961 else if (STRINGP (glyphless_method))
6962 it->glyphless_method = GLYPHLESS_DISPLAY_ACRONYM;
6963 else
6965 /* Invalid value. We use the default method. */
6966 glyphless_method = Qnil;
6967 goto retry;
6969 it->what = IT_GLYPHLESS;
6970 return glyphless_method;
6973 /* Merge escape glyph face and cache the result. */
6975 static struct frame *last_escape_glyph_frame = NULL;
6976 static int last_escape_glyph_face_id = (1 << FACE_ID_BITS);
6977 static int last_escape_glyph_merged_face_id = 0;
6979 static int
6980 merge_escape_glyph_face (struct it *it)
6982 int face_id;
6984 if (it->f == last_escape_glyph_frame
6985 && it->face_id == last_escape_glyph_face_id)
6986 face_id = last_escape_glyph_merged_face_id;
6987 else
6989 /* Merge the `escape-glyph' face into the current face. */
6990 face_id = merge_faces (it->f, Qescape_glyph, 0, it->face_id);
6991 last_escape_glyph_frame = it->f;
6992 last_escape_glyph_face_id = it->face_id;
6993 last_escape_glyph_merged_face_id = face_id;
6995 return face_id;
6998 /* Likewise for glyphless glyph face. */
7000 static struct frame *last_glyphless_glyph_frame = NULL;
7001 static int last_glyphless_glyph_face_id = (1 << FACE_ID_BITS);
7002 static int last_glyphless_glyph_merged_face_id = 0;
7005 merge_glyphless_glyph_face (struct it *it)
7007 int face_id;
7009 if (it->f == last_glyphless_glyph_frame
7010 && it->face_id == last_glyphless_glyph_face_id)
7011 face_id = last_glyphless_glyph_merged_face_id;
7012 else
7014 /* Merge the `glyphless-char' face into the current face. */
7015 face_id = merge_faces (it->f, Qglyphless_char, 0, it->face_id);
7016 last_glyphless_glyph_frame = it->f;
7017 last_glyphless_glyph_face_id = it->face_id;
7018 last_glyphless_glyph_merged_face_id = face_id;
7020 return face_id;
7023 /* Forget the `escape-glyph' and `glyphless-char' faces. This should
7024 be called before redisplaying windows, and when the frame's face
7025 cache is freed. */
7026 void
7027 forget_escape_and_glyphless_faces (void)
7029 last_escape_glyph_frame = NULL;
7030 last_escape_glyph_face_id = (1 << FACE_ID_BITS);
7031 last_glyphless_glyph_frame = NULL;
7032 last_glyphless_glyph_face_id = (1 << FACE_ID_BITS);
7035 /* Load IT's display element fields with information about the next
7036 display element from the current position of IT. Value is false if
7037 end of buffer (or C string) is reached. */
7039 static bool
7040 get_next_display_element (struct it *it)
7042 /* True means that we found a display element. False means that
7043 we hit the end of what we iterate over. Performance note: the
7044 function pointer `method' used here turns out to be faster than
7045 using a sequence of if-statements. */
7046 bool success_p;
7048 get_next:
7049 success_p = GET_NEXT_DISPLAY_ELEMENT (it);
7051 if (it->what == IT_CHARACTER)
7053 /* UAX#9, L4: "A character is depicted by a mirrored glyph if
7054 and only if (a) the resolved directionality of that character
7055 is R..." */
7056 /* FIXME: Do we need an exception for characters from display
7057 tables? */
7058 if (it->bidi_p && it->bidi_it.type == STRONG_R
7059 && !inhibit_bidi_mirroring)
7060 it->c = bidi_mirror_char (it->c);
7061 /* Map via display table or translate control characters.
7062 IT->c, IT->len etc. have been set to the next character by
7063 the function call above. If we have a display table, and it
7064 contains an entry for IT->c, translate it. Don't do this if
7065 IT->c itself comes from a display table, otherwise we could
7066 end up in an infinite recursion. (An alternative could be to
7067 count the recursion depth of this function and signal an
7068 error when a certain maximum depth is reached.) Is it worth
7069 it? */
7070 if (success_p && it->dpvec == NULL)
7072 Lisp_Object dv;
7073 struct charset *unibyte = CHARSET_FROM_ID (charset_unibyte);
7074 bool nonascii_space_p = false;
7075 bool nonascii_hyphen_p = false;
7076 int c = it->c; /* This is the character to display. */
7078 if (! it->multibyte_p && ! ASCII_CHAR_P (c))
7080 eassert (SINGLE_BYTE_CHAR_P (c));
7081 if (unibyte_display_via_language_environment)
7083 c = DECODE_CHAR (unibyte, c);
7084 if (c < 0)
7085 c = BYTE8_TO_CHAR (it->c);
7087 else
7088 c = BYTE8_TO_CHAR (it->c);
7091 if (it->dp
7092 && (dv = DISP_CHAR_VECTOR (it->dp, c),
7093 VECTORP (dv)))
7095 struct Lisp_Vector *v = XVECTOR (dv);
7097 /* Return the first character from the display table
7098 entry, if not empty. If empty, don't display the
7099 current character. */
7100 if (v->header.size)
7102 it->dpvec_char_len = it->len;
7103 it->dpvec = v->contents;
7104 it->dpend = v->contents + v->header.size;
7105 it->current.dpvec_index = 0;
7106 it->dpvec_face_id = -1;
7107 it->saved_face_id = it->face_id;
7108 it->method = GET_FROM_DISPLAY_VECTOR;
7109 it->ellipsis_p = false;
7111 else
7113 set_iterator_to_next (it, false);
7115 goto get_next;
7118 if (! NILP (lookup_glyphless_char_display (c, it)))
7120 if (it->what == IT_GLYPHLESS)
7121 goto done;
7122 /* Don't display this character. */
7123 set_iterator_to_next (it, false);
7124 goto get_next;
7127 /* If `nobreak-char-display' is non-nil, we display
7128 non-ASCII spaces and hyphens specially. */
7129 if (! ASCII_CHAR_P (c) && ! NILP (Vnobreak_char_display))
7131 if (c == NO_BREAK_SPACE)
7132 nonascii_space_p = true;
7133 else if (c == SOFT_HYPHEN || c == HYPHEN
7134 || c == NON_BREAKING_HYPHEN)
7135 nonascii_hyphen_p = true;
7138 /* Translate control characters into `\003' or `^C' form.
7139 Control characters coming from a display table entry are
7140 currently not translated because we use IT->dpvec to hold
7141 the translation. This could easily be changed but I
7142 don't believe that it is worth doing.
7144 The characters handled by `nobreak-char-display' must be
7145 translated too.
7147 Non-printable characters and raw-byte characters are also
7148 translated to octal or hexadecimal form. */
7149 if (((c < ' ' || c == 127) /* ASCII control chars. */
7150 ? (it->area != TEXT_AREA
7151 /* In mode line, treat \n, \t like other crl chars. */
7152 || (c != '\t'
7153 && it->glyph_row
7154 && (it->glyph_row->mode_line_p || it->avoid_cursor_p))
7155 || (c != '\n' && c != '\t'))
7156 : (nonascii_space_p
7157 || nonascii_hyphen_p
7158 || CHAR_BYTE8_P (c)
7159 || ! CHAR_PRINTABLE_P (c))))
7161 /* C is a control character, non-ASCII space/hyphen,
7162 raw-byte, or a non-printable character which must be
7163 displayed either as '\003' or as `^C' where the '\\'
7164 and '^' can be defined in the display table. Fill
7165 IT->ctl_chars with glyphs for what we have to
7166 display. Then, set IT->dpvec to these glyphs. */
7167 Lisp_Object gc;
7168 int ctl_len;
7169 int face_id;
7170 int lface_id = 0;
7171 int escape_glyph;
7173 /* Handle control characters with ^. */
7175 if (ASCII_CHAR_P (c) && it->ctl_arrow_p)
7177 int g;
7179 g = '^'; /* default glyph for Control */
7180 /* Set IT->ctl_chars[0] to the glyph for `^'. */
7181 if (it->dp
7182 && (gc = DISP_CTRL_GLYPH (it->dp), GLYPH_CODE_P (gc)))
7184 g = GLYPH_CODE_CHAR (gc);
7185 lface_id = GLYPH_CODE_FACE (gc);
7188 face_id = (lface_id
7189 ? merge_faces (it->f, Qt, lface_id, it->face_id)
7190 : merge_escape_glyph_face (it));
7192 XSETINT (it->ctl_chars[0], g);
7193 XSETINT (it->ctl_chars[1], c ^ 0100);
7194 ctl_len = 2;
7195 goto display_control;
7198 /* Handle non-ascii space in the mode where it only gets
7199 highlighting. */
7201 if (nonascii_space_p && EQ (Vnobreak_char_display, Qt))
7203 /* Merge `nobreak-space' into the current face. */
7204 face_id = merge_faces (it->f, Qnobreak_space, 0,
7205 it->face_id);
7206 XSETINT (it->ctl_chars[0], ' ');
7207 ctl_len = 1;
7208 goto display_control;
7211 /* Handle non-ascii hyphens in the mode where it only
7212 gets highlighting. */
7214 if (nonascii_hyphen_p && EQ (Vnobreak_char_display, Qt))
7216 /* Merge `nobreak-space' into the current face. */
7217 face_id = merge_faces (it->f, Qnobreak_hyphen, 0,
7218 it->face_id);
7219 XSETINT (it->ctl_chars[0], '-');
7220 ctl_len = 1;
7221 goto display_control;
7224 /* Handle sequences that start with the "escape glyph". */
7226 /* the default escape glyph is \. */
7227 escape_glyph = '\\';
7229 if (it->dp
7230 && (gc = DISP_ESCAPE_GLYPH (it->dp), GLYPH_CODE_P (gc)))
7232 escape_glyph = GLYPH_CODE_CHAR (gc);
7233 lface_id = GLYPH_CODE_FACE (gc);
7236 face_id = (lface_id
7237 ? merge_faces (it->f, Qt, lface_id, it->face_id)
7238 : merge_escape_glyph_face (it));
7240 /* Draw non-ASCII space/hyphen with escape glyph: */
7242 if (nonascii_space_p || nonascii_hyphen_p)
7244 XSETINT (it->ctl_chars[0], escape_glyph);
7245 XSETINT (it->ctl_chars[1], nonascii_space_p ? ' ' : '-');
7246 ctl_len = 2;
7247 goto display_control;
7251 char str[10];
7252 int len, i;
7254 if (CHAR_BYTE8_P (c))
7255 /* Display \200 or \x80 instead of \17777600. */
7256 c = CHAR_TO_BYTE8 (c);
7257 const char *format_string = display_raw_bytes_as_hex
7258 ? "x%02x"
7259 : "%03o";
7260 len = sprintf (str, format_string, c + 0u);
7262 XSETINT (it->ctl_chars[0], escape_glyph);
7263 for (i = 0; i < len; i++)
7264 XSETINT (it->ctl_chars[i + 1], str[i]);
7265 ctl_len = len + 1;
7268 display_control:
7269 /* Set up IT->dpvec and return first character from it. */
7270 it->dpvec_char_len = it->len;
7271 it->dpvec = it->ctl_chars;
7272 it->dpend = it->dpvec + ctl_len;
7273 it->current.dpvec_index = 0;
7274 it->dpvec_face_id = face_id;
7275 it->saved_face_id = it->face_id;
7276 it->method = GET_FROM_DISPLAY_VECTOR;
7277 it->ellipsis_p = false;
7278 goto get_next;
7280 it->char_to_display = c;
7282 else if (success_p)
7284 it->char_to_display = it->c;
7288 #ifdef HAVE_WINDOW_SYSTEM
7289 /* Adjust face id for a multibyte character. There are no multibyte
7290 character in unibyte text. */
7291 if ((it->what == IT_CHARACTER || it->what == IT_COMPOSITION)
7292 && it->multibyte_p
7293 && success_p
7294 && FRAME_WINDOW_P (it->f))
7296 struct face *face = FACE_FROM_ID (it->f, it->face_id);
7298 if (it->what == IT_COMPOSITION && it->cmp_it.ch >= 0)
7300 /* Automatic composition with glyph-string. */
7301 Lisp_Object gstring = composition_gstring_from_id (it->cmp_it.id);
7303 it->face_id = face_for_font (it->f, LGSTRING_FONT (gstring), face);
7305 else
7307 ptrdiff_t pos = (it->s ? -1
7308 : STRINGP (it->string) ? IT_STRING_CHARPOS (*it)
7309 : IT_CHARPOS (*it));
7310 int c;
7312 if (it->what == IT_CHARACTER)
7313 c = it->char_to_display;
7314 else
7316 struct composition *cmp = composition_table[it->cmp_it.id];
7317 int i;
7319 c = ' ';
7320 for (i = 0; i < cmp->glyph_len; i++)
7321 /* TAB in a composition means display glyphs with
7322 padding space on the left or right. */
7323 if ((c = COMPOSITION_GLYPH (cmp, i)) != '\t')
7324 break;
7326 it->face_id = FACE_FOR_CHAR (it->f, face, c, pos, it->string);
7329 #endif /* HAVE_WINDOW_SYSTEM */
7331 done:
7332 /* Is this character the last one of a run of characters with
7333 box? If yes, set IT->end_of_box_run_p to true. */
7334 if (it->face_box_p
7335 && it->s == NULL)
7337 if (it->method == GET_FROM_STRING && it->sp)
7339 int face_id = underlying_face_id (it);
7340 struct face *face = FACE_FROM_ID_OR_NULL (it->f, face_id);
7342 if (face)
7344 if (face->box == FACE_NO_BOX)
7346 /* If the box comes from face properties in a
7347 display string, check faces in that string. */
7348 int string_face_id = face_after_it_pos (it);
7349 it->end_of_box_run_p
7350 = (FACE_FROM_ID (it->f, string_face_id)->box
7351 == FACE_NO_BOX);
7353 /* Otherwise, the box comes from the underlying face.
7354 If this is the last string character displayed, check
7355 the next buffer location. */
7356 else if ((IT_STRING_CHARPOS (*it) >= SCHARS (it->string) - 1)
7357 /* n_overlay_strings is unreliable unless
7358 overlay_string_index is non-negative. */
7359 && ((it->current.overlay_string_index >= 0
7360 && (it->current.overlay_string_index
7361 == it->n_overlay_strings - 1))
7362 /* A string from display property. */
7363 || it->from_disp_prop_p))
7365 ptrdiff_t ignore;
7366 int next_face_id;
7367 bool text_from_string = false;
7368 /* Normally, the next buffer location is stored in
7369 IT->current.pos... */
7370 struct text_pos pos = it->current.pos;
7372 /* ...but for a string from a display property, the
7373 next buffer position is stored in the 'position'
7374 member of the iteration stack slot below the
7375 current one, see handle_single_display_spec. By
7376 contrast, it->current.pos was not yet updated to
7377 point to that buffer position; that will happen
7378 in pop_it, after we finish displaying the current
7379 string. Note that we already checked above that
7380 it->sp is positive, so subtracting one from it is
7381 safe. */
7382 if (it->from_disp_prop_p)
7384 int stackp = it->sp - 1;
7386 /* Find the stack level with data from buffer. */
7387 while (stackp >= 0
7388 && STRINGP ((it->stack + stackp)->string))
7389 stackp--;
7390 if (stackp < 0)
7392 /* If no stack slot was found for iterating
7393 a buffer, we are displaying text from a
7394 string, most probably the mode line or
7395 the header line, and that string has a
7396 display string on some of its
7397 characters. */
7398 text_from_string = true;
7399 pos = it->stack[it->sp - 1].position;
7401 else
7402 pos = (it->stack + stackp)->position;
7404 else
7405 INC_TEXT_POS (pos, it->multibyte_p);
7407 if (text_from_string)
7409 Lisp_Object base_string = it->stack[it->sp - 1].string;
7411 if (CHARPOS (pos) >= SCHARS (base_string) - 1)
7412 it->end_of_box_run_p = true;
7413 else
7415 next_face_id
7416 = face_at_string_position (it->w, base_string,
7417 CHARPOS (pos), 0,
7418 &ignore, face_id, false);
7419 it->end_of_box_run_p
7420 = (FACE_FROM_ID (it->f, next_face_id)->box
7421 == FACE_NO_BOX);
7424 else if (CHARPOS (pos) >= ZV)
7425 it->end_of_box_run_p = true;
7426 else
7428 next_face_id =
7429 face_at_buffer_position (it->w, CHARPOS (pos), &ignore,
7430 CHARPOS (pos)
7431 + TEXT_PROP_DISTANCE_LIMIT,
7432 false, -1);
7433 it->end_of_box_run_p
7434 = (FACE_FROM_ID (it->f, next_face_id)->box
7435 == FACE_NO_BOX);
7440 /* next_element_from_display_vector sets this flag according to
7441 faces of the display vector glyphs, see there. */
7442 else if (it->method != GET_FROM_DISPLAY_VECTOR)
7444 int face_id = face_after_it_pos (it);
7445 it->end_of_box_run_p
7446 = (face_id != it->face_id
7447 && FACE_FROM_ID (it->f, face_id)->box == FACE_NO_BOX);
7450 /* If we reached the end of the object we've been iterating (e.g., a
7451 display string or an overlay string), and there's something on
7452 IT->stack, proceed with what's on the stack. It doesn't make
7453 sense to return false if there's unprocessed stuff on the stack,
7454 because otherwise that stuff will never be displayed. */
7455 if (!success_p && it->sp > 0)
7457 set_iterator_to_next (it, false);
7458 success_p = get_next_display_element (it);
7461 /* Value is false if end of buffer or string reached. */
7462 return success_p;
7466 /* Move IT to the next display element.
7468 RESEAT_P means if called on a newline in buffer text,
7469 skip to the next visible line start.
7471 Functions get_next_display_element and set_iterator_to_next are
7472 separate because I find this arrangement easier to handle than a
7473 get_next_display_element function that also increments IT's
7474 position. The way it is we can first look at an iterator's current
7475 display element, decide whether it fits on a line, and if it does,
7476 increment the iterator position. The other way around we probably
7477 would either need a flag indicating whether the iterator has to be
7478 incremented the next time, or we would have to implement a
7479 decrement position function which would not be easy to write. */
7481 void
7482 set_iterator_to_next (struct it *it, bool reseat_p)
7484 /* Reset flags indicating start and end of a sequence of characters
7485 with box. Reset them at the start of this function because
7486 moving the iterator to a new position might set them. */
7487 it->start_of_box_run_p = it->end_of_box_run_p = false;
7489 switch (it->method)
7491 case GET_FROM_BUFFER:
7492 /* The current display element of IT is a character from
7493 current_buffer. Advance in the buffer, and maybe skip over
7494 invisible lines that are so because of selective display. */
7495 if (ITERATOR_AT_END_OF_LINE_P (it) && reseat_p)
7496 reseat_at_next_visible_line_start (it, false);
7497 else if (it->cmp_it.id >= 0)
7499 /* We are currently getting glyphs from a composition. */
7500 if (! it->bidi_p)
7502 IT_CHARPOS (*it) += it->cmp_it.nchars;
7503 IT_BYTEPOS (*it) += it->cmp_it.nbytes;
7505 else
7507 int i;
7509 /* Update IT's char/byte positions to point to the first
7510 character of the next grapheme cluster, or to the
7511 character visually after the current composition. */
7512 for (i = 0; i < it->cmp_it.nchars; i++)
7513 bidi_move_to_visually_next (&it->bidi_it);
7514 IT_BYTEPOS (*it) = it->bidi_it.bytepos;
7515 IT_CHARPOS (*it) = it->bidi_it.charpos;
7518 if ((! it->bidi_p || ! it->cmp_it.reversed_p)
7519 && it->cmp_it.to < it->cmp_it.nglyphs)
7521 /* Composition created while scanning forward. Proceed
7522 to the next grapheme cluster. */
7523 it->cmp_it.from = it->cmp_it.to;
7525 else if ((it->bidi_p && it->cmp_it.reversed_p)
7526 && it->cmp_it.from > 0)
7528 /* Composition created while scanning backward. Proceed
7529 to the previous grapheme cluster. */
7530 it->cmp_it.to = it->cmp_it.from;
7532 else
7534 /* No more grapheme clusters in this composition.
7535 Find the next stop position. */
7536 ptrdiff_t stop = it->end_charpos;
7538 if (it->bidi_it.scan_dir < 0)
7539 /* Now we are scanning backward and don't know
7540 where to stop. */
7541 stop = -1;
7542 composition_compute_stop_pos (&it->cmp_it, IT_CHARPOS (*it),
7543 IT_BYTEPOS (*it), stop, Qnil);
7546 else
7548 eassert (it->len != 0);
7550 if (!it->bidi_p)
7552 IT_BYTEPOS (*it) += it->len;
7553 IT_CHARPOS (*it) += 1;
7555 else
7557 int prev_scan_dir = it->bidi_it.scan_dir;
7558 /* If this is a new paragraph, determine its base
7559 direction (a.k.a. its base embedding level). */
7560 if (it->bidi_it.new_paragraph)
7561 bidi_paragraph_init (it->paragraph_embedding, &it->bidi_it,
7562 false);
7563 bidi_move_to_visually_next (&it->bidi_it);
7564 IT_BYTEPOS (*it) = it->bidi_it.bytepos;
7565 IT_CHARPOS (*it) = it->bidi_it.charpos;
7566 if (prev_scan_dir != it->bidi_it.scan_dir)
7568 /* As the scan direction was changed, we must
7569 re-compute the stop position for composition. */
7570 ptrdiff_t stop = it->end_charpos;
7571 if (it->bidi_it.scan_dir < 0)
7572 stop = -1;
7573 composition_compute_stop_pos (&it->cmp_it, IT_CHARPOS (*it),
7574 IT_BYTEPOS (*it), stop, Qnil);
7577 eassert (IT_BYTEPOS (*it) == CHAR_TO_BYTE (IT_CHARPOS (*it)));
7579 break;
7581 case GET_FROM_C_STRING:
7582 /* Current display element of IT is from a C string. */
7583 if (!it->bidi_p
7584 /* If the string position is beyond string's end, it means
7585 next_element_from_c_string is padding the string with
7586 blanks, in which case we bypass the bidi iterator,
7587 because it cannot deal with such virtual characters. */
7588 || IT_CHARPOS (*it) >= it->bidi_it.string.schars)
7590 IT_BYTEPOS (*it) += it->len;
7591 IT_CHARPOS (*it) += 1;
7593 else
7595 bidi_move_to_visually_next (&it->bidi_it);
7596 IT_BYTEPOS (*it) = it->bidi_it.bytepos;
7597 IT_CHARPOS (*it) = it->bidi_it.charpos;
7599 break;
7601 case GET_FROM_DISPLAY_VECTOR:
7602 /* Current display element of IT is from a display table entry.
7603 Advance in the display table definition. Reset it to null if
7604 end reached, and continue with characters from buffers/
7605 strings. */
7606 ++it->current.dpvec_index;
7608 /* Restore face of the iterator to what they were before the
7609 display vector entry (these entries may contain faces). */
7610 it->face_id = it->saved_face_id;
7612 if (it->dpvec + it->current.dpvec_index >= it->dpend)
7614 bool recheck_faces = it->ellipsis_p;
7616 if (it->s)
7617 it->method = GET_FROM_C_STRING;
7618 else if (STRINGP (it->string))
7619 it->method = GET_FROM_STRING;
7620 else
7622 it->method = GET_FROM_BUFFER;
7623 it->object = it->w->contents;
7626 it->dpvec = NULL;
7627 it->current.dpvec_index = -1;
7629 /* Skip over characters which were displayed via IT->dpvec. */
7630 if (it->dpvec_char_len < 0)
7631 reseat_at_next_visible_line_start (it, true);
7632 else if (it->dpvec_char_len > 0)
7634 it->len = it->dpvec_char_len;
7635 set_iterator_to_next (it, reseat_p);
7638 /* Maybe recheck faces after display vector. */
7639 if (recheck_faces)
7641 if (it->method == GET_FROM_STRING)
7642 it->stop_charpos = IT_STRING_CHARPOS (*it);
7643 else
7644 it->stop_charpos = IT_CHARPOS (*it);
7647 break;
7649 case GET_FROM_STRING:
7650 /* Current display element is a character from a Lisp string. */
7651 eassert (it->s == NULL && STRINGP (it->string));
7652 /* Don't advance past string end. These conditions are true
7653 when set_iterator_to_next is called at the end of
7654 get_next_display_element, in which case the Lisp string is
7655 already exhausted, and all we want is pop the iterator
7656 stack. */
7657 if (it->current.overlay_string_index >= 0)
7659 /* This is an overlay string, so there's no padding with
7660 spaces, and the number of characters in the string is
7661 where the string ends. */
7662 if (IT_STRING_CHARPOS (*it) >= SCHARS (it->string))
7663 goto consider_string_end;
7665 else
7667 /* Not an overlay string. There could be padding, so test
7668 against it->end_charpos. */
7669 if (IT_STRING_CHARPOS (*it) >= it->end_charpos)
7670 goto consider_string_end;
7672 if (it->cmp_it.id >= 0)
7674 /* We are delivering display elements from a composition.
7675 Update the string position past the grapheme cluster
7676 we've just processed. */
7677 if (! it->bidi_p)
7679 IT_STRING_CHARPOS (*it) += it->cmp_it.nchars;
7680 IT_STRING_BYTEPOS (*it) += it->cmp_it.nbytes;
7682 else
7684 int i;
7686 for (i = 0; i < it->cmp_it.nchars; i++)
7687 bidi_move_to_visually_next (&it->bidi_it);
7688 IT_STRING_BYTEPOS (*it) = it->bidi_it.bytepos;
7689 IT_STRING_CHARPOS (*it) = it->bidi_it.charpos;
7692 /* Did we exhaust all the grapheme clusters of this
7693 composition? */
7694 if ((! it->bidi_p || ! it->cmp_it.reversed_p)
7695 && (it->cmp_it.to < it->cmp_it.nglyphs))
7697 /* Not all the grapheme clusters were processed yet;
7698 advance to the next cluster. */
7699 it->cmp_it.from = it->cmp_it.to;
7701 else if ((it->bidi_p && it->cmp_it.reversed_p)
7702 && it->cmp_it.from > 0)
7704 /* Likewise: advance to the next cluster, but going in
7705 the reverse direction. */
7706 it->cmp_it.to = it->cmp_it.from;
7708 else
7710 /* This composition was fully processed; find the next
7711 candidate place for checking for composed
7712 characters. */
7713 /* Always limit string searches to the string length;
7714 any padding spaces are not part of the string, and
7715 there cannot be any compositions in that padding. */
7716 ptrdiff_t stop = SCHARS (it->string);
7718 if (it->bidi_p && it->bidi_it.scan_dir < 0)
7719 stop = -1;
7720 else if (it->end_charpos < stop)
7722 /* Cf. PRECISION in reseat_to_string: we might be
7723 limited in how many of the string characters we
7724 need to deliver. */
7725 stop = it->end_charpos;
7727 composition_compute_stop_pos (&it->cmp_it,
7728 IT_STRING_CHARPOS (*it),
7729 IT_STRING_BYTEPOS (*it), stop,
7730 it->string);
7733 else
7735 if (!it->bidi_p
7736 /* If the string position is beyond string's end, it
7737 means next_element_from_string is padding the string
7738 with blanks, in which case we bypass the bidi
7739 iterator, because it cannot deal with such virtual
7740 characters. */
7741 || IT_STRING_CHARPOS (*it) >= it->bidi_it.string.schars)
7743 IT_STRING_BYTEPOS (*it) += it->len;
7744 IT_STRING_CHARPOS (*it) += 1;
7746 else
7748 int prev_scan_dir = it->bidi_it.scan_dir;
7750 bidi_move_to_visually_next (&it->bidi_it);
7751 IT_STRING_BYTEPOS (*it) = it->bidi_it.bytepos;
7752 IT_STRING_CHARPOS (*it) = it->bidi_it.charpos;
7753 /* If the scan direction changes, we may need to update
7754 the place where to check for composed characters. */
7755 if (prev_scan_dir != it->bidi_it.scan_dir)
7757 ptrdiff_t stop = SCHARS (it->string);
7759 if (it->bidi_it.scan_dir < 0)
7760 stop = -1;
7761 else if (it->end_charpos < stop)
7762 stop = it->end_charpos;
7764 composition_compute_stop_pos (&it->cmp_it,
7765 IT_STRING_CHARPOS (*it),
7766 IT_STRING_BYTEPOS (*it), stop,
7767 it->string);
7772 consider_string_end:
7774 if (it->current.overlay_string_index >= 0)
7776 /* IT->string is an overlay string. Advance to the
7777 next, if there is one. */
7778 if (IT_STRING_CHARPOS (*it) >= SCHARS (it->string))
7780 it->ellipsis_p = false;
7781 next_overlay_string (it);
7782 if (it->ellipsis_p)
7783 setup_for_ellipsis (it, 0);
7786 else
7788 /* IT->string is not an overlay string. If we reached
7789 its end, and there is something on IT->stack, proceed
7790 with what is on the stack. This can be either another
7791 string, this time an overlay string, or a buffer. */
7792 if (IT_STRING_CHARPOS (*it) == SCHARS (it->string)
7793 && it->sp > 0)
7795 pop_it (it);
7796 if (it->method == GET_FROM_STRING)
7797 goto consider_string_end;
7800 break;
7802 case GET_FROM_IMAGE:
7803 case GET_FROM_STRETCH:
7804 case GET_FROM_XWIDGET:
7806 /* The position etc with which we have to proceed are on
7807 the stack. The position may be at the end of a string,
7808 if the `display' property takes up the whole string. */
7809 eassert (it->sp > 0);
7810 pop_it (it);
7811 if (it->method == GET_FROM_STRING)
7812 goto consider_string_end;
7813 break;
7815 default:
7816 /* There are no other methods defined, so this should be a bug. */
7817 emacs_abort ();
7820 eassert (it->method != GET_FROM_STRING
7821 || (STRINGP (it->string)
7822 && IT_STRING_CHARPOS (*it) >= 0));
7825 /* Load IT's display element fields with information about the next
7826 display element which comes from a display table entry or from the
7827 result of translating a control character to one of the forms `^C'
7828 or `\003'.
7830 IT->dpvec holds the glyphs to return as characters.
7831 IT->saved_face_id holds the face id before the display vector--it
7832 is restored into IT->face_id in set_iterator_to_next. */
7834 static bool
7835 next_element_from_display_vector (struct it *it)
7837 Lisp_Object gc;
7838 int prev_face_id = it->face_id;
7839 int next_face_id;
7841 /* Precondition. */
7842 eassert (it->dpvec && it->current.dpvec_index >= 0);
7844 it->face_id = it->saved_face_id;
7846 /* KFS: This code used to check ip->dpvec[0] instead of the current element.
7847 That seemed totally bogus - so I changed it... */
7848 if (it->dpend - it->dpvec > 0 /* empty dpvec[] is invalid */
7849 && (gc = it->dpvec[it->current.dpvec_index], GLYPH_CODE_P (gc)))
7851 struct face *this_face, *prev_face, *next_face;
7853 it->c = GLYPH_CODE_CHAR (gc);
7854 it->len = CHAR_BYTES (it->c);
7856 /* The entry may contain a face id to use. Such a face id is
7857 the id of a Lisp face, not a realized face. A face id of
7858 zero means no face is specified. */
7859 if (it->dpvec_face_id >= 0)
7860 it->face_id = it->dpvec_face_id;
7861 else
7863 int lface_id = GLYPH_CODE_FACE (gc);
7864 if (lface_id > 0)
7865 it->face_id = merge_faces (it->f, Qt, lface_id,
7866 it->saved_face_id);
7869 /* Glyphs in the display vector could have the box face, so we
7870 need to set the related flags in the iterator, as
7871 appropriate. */
7872 this_face = FACE_FROM_ID_OR_NULL (it->f, it->face_id);
7873 prev_face = FACE_FROM_ID_OR_NULL (it->f, prev_face_id);
7875 /* Is this character the first character of a box-face run? */
7876 it->start_of_box_run_p = (this_face && this_face->box != FACE_NO_BOX
7877 && (!prev_face
7878 || prev_face->box == FACE_NO_BOX));
7880 /* For the last character of the box-face run, we need to look
7881 either at the next glyph from the display vector, or at the
7882 face we saw before the display vector. */
7883 next_face_id = it->saved_face_id;
7884 if (it->current.dpvec_index < it->dpend - it->dpvec - 1)
7886 if (it->dpvec_face_id >= 0)
7887 next_face_id = it->dpvec_face_id;
7888 else
7890 int lface_id =
7891 GLYPH_CODE_FACE (it->dpvec[it->current.dpvec_index + 1]);
7893 if (lface_id > 0)
7894 next_face_id = merge_faces (it->f, Qt, lface_id,
7895 it->saved_face_id);
7898 next_face = FACE_FROM_ID_OR_NULL (it->f, next_face_id);
7899 it->end_of_box_run_p = (this_face && this_face->box != FACE_NO_BOX
7900 && (!next_face
7901 || next_face->box == FACE_NO_BOX));
7902 it->face_box_p = this_face && this_face->box != FACE_NO_BOX;
7904 else
7905 /* Display table entry is invalid. Return a space. */
7906 it->c = ' ', it->len = 1;
7908 /* Don't change position and object of the iterator here. They are
7909 still the values of the character that had this display table
7910 entry or was translated, and that's what we want. */
7911 it->what = IT_CHARACTER;
7912 return true;
7915 /* Get the first element of string/buffer in the visual order, after
7916 being reseated to a new position in a string or a buffer. */
7917 static void
7918 get_visually_first_element (struct it *it)
7920 bool string_p = STRINGP (it->string) || it->s;
7921 ptrdiff_t eob = (string_p ? it->bidi_it.string.schars : ZV);
7922 ptrdiff_t bob = (string_p ? 0 : BEGV);
7924 if (STRINGP (it->string))
7926 it->bidi_it.charpos = IT_STRING_CHARPOS (*it);
7927 it->bidi_it.bytepos = IT_STRING_BYTEPOS (*it);
7929 else
7931 it->bidi_it.charpos = IT_CHARPOS (*it);
7932 it->bidi_it.bytepos = IT_BYTEPOS (*it);
7935 if (it->bidi_it.charpos == eob)
7937 /* Nothing to do, but reset the FIRST_ELT flag, like
7938 bidi_paragraph_init does, because we are not going to
7939 call it. */
7940 it->bidi_it.first_elt = false;
7942 else if (it->bidi_it.charpos == bob
7943 || (!string_p
7944 && (FETCH_CHAR (it->bidi_it.bytepos - 1) == '\n'
7945 || FETCH_CHAR (it->bidi_it.bytepos) == '\n')))
7947 /* If we are at the beginning of a line/string, we can produce
7948 the next element right away. */
7949 bidi_paragraph_init (it->paragraph_embedding, &it->bidi_it, true);
7950 bidi_move_to_visually_next (&it->bidi_it);
7952 else
7954 ptrdiff_t orig_bytepos = it->bidi_it.bytepos;
7956 /* We need to prime the bidi iterator starting at the line's or
7957 string's beginning, before we will be able to produce the
7958 next element. */
7959 if (string_p)
7960 it->bidi_it.charpos = it->bidi_it.bytepos = 0;
7961 else
7962 it->bidi_it.charpos = find_newline_no_quit (IT_CHARPOS (*it),
7963 IT_BYTEPOS (*it), -1,
7964 &it->bidi_it.bytepos);
7965 bidi_paragraph_init (it->paragraph_embedding, &it->bidi_it, true);
7968 /* Now return to buffer/string position where we were asked
7969 to get the next display element, and produce that. */
7970 bidi_move_to_visually_next (&it->bidi_it);
7972 while (it->bidi_it.bytepos != orig_bytepos
7973 && it->bidi_it.charpos < eob);
7976 /* Adjust IT's position information to where we ended up. */
7977 if (STRINGP (it->string))
7979 IT_STRING_CHARPOS (*it) = it->bidi_it.charpos;
7980 IT_STRING_BYTEPOS (*it) = it->bidi_it.bytepos;
7982 else
7984 IT_CHARPOS (*it) = it->bidi_it.charpos;
7985 IT_BYTEPOS (*it) = it->bidi_it.bytepos;
7988 if (STRINGP (it->string) || !it->s)
7990 ptrdiff_t stop, charpos, bytepos;
7992 if (STRINGP (it->string))
7994 eassert (!it->s);
7995 stop = SCHARS (it->string);
7996 if (stop > it->end_charpos)
7997 stop = it->end_charpos;
7998 charpos = IT_STRING_CHARPOS (*it);
7999 bytepos = IT_STRING_BYTEPOS (*it);
8001 else
8003 stop = it->end_charpos;
8004 charpos = IT_CHARPOS (*it);
8005 bytepos = IT_BYTEPOS (*it);
8007 if (it->bidi_it.scan_dir < 0)
8008 stop = -1;
8009 composition_compute_stop_pos (&it->cmp_it, charpos, bytepos, stop,
8010 it->string);
8014 /* Load IT with the next display element from Lisp string IT->string.
8015 IT->current.string_pos is the current position within the string.
8016 If IT->current.overlay_string_index >= 0, the Lisp string is an
8017 overlay string. */
8019 static bool
8020 next_element_from_string (struct it *it)
8022 struct text_pos position;
8024 eassert (STRINGP (it->string));
8025 eassert (!it->bidi_p || EQ (it->string, it->bidi_it.string.lstring));
8026 eassert (IT_STRING_CHARPOS (*it) >= 0);
8027 position = it->current.string_pos;
8029 /* With bidi reordering, the character to display might not be the
8030 character at IT_STRING_CHARPOS. BIDI_IT.FIRST_ELT means
8031 that we were reseat()ed to a new string, whose paragraph
8032 direction is not known. */
8033 if (it->bidi_p && it->bidi_it.first_elt)
8035 get_visually_first_element (it);
8036 SET_TEXT_POS (position, IT_STRING_CHARPOS (*it), IT_STRING_BYTEPOS (*it));
8039 /* Time to check for invisible text? */
8040 if (IT_STRING_CHARPOS (*it) < it->end_charpos)
8042 if (IT_STRING_CHARPOS (*it) >= it->stop_charpos)
8044 if (!(!it->bidi_p
8045 || BIDI_AT_BASE_LEVEL (it->bidi_it)
8046 || IT_STRING_CHARPOS (*it) == it->stop_charpos))
8048 /* With bidi non-linear iteration, we could find
8049 ourselves far beyond the last computed stop_charpos,
8050 with several other stop positions in between that we
8051 missed. Scan them all now, in buffer's logical
8052 order, until we find and handle the last stop_charpos
8053 that precedes our current position. */
8054 handle_stop_backwards (it, it->stop_charpos);
8055 return GET_NEXT_DISPLAY_ELEMENT (it);
8057 else
8059 if (it->bidi_p)
8061 /* Take note of the stop position we just moved
8062 across, for when we will move back across it. */
8063 it->prev_stop = it->stop_charpos;
8064 /* If we are at base paragraph embedding level, take
8065 note of the last stop position seen at this
8066 level. */
8067 if (BIDI_AT_BASE_LEVEL (it->bidi_it))
8068 it->base_level_stop = it->stop_charpos;
8070 handle_stop (it);
8072 /* Since a handler may have changed IT->method, we must
8073 recurse here. */
8074 return GET_NEXT_DISPLAY_ELEMENT (it);
8077 else if (it->bidi_p
8078 /* If we are before prev_stop, we may have overstepped
8079 on our way backwards a stop_pos, and if so, we need
8080 to handle that stop_pos. */
8081 && IT_STRING_CHARPOS (*it) < it->prev_stop
8082 /* We can sometimes back up for reasons that have nothing
8083 to do with bidi reordering. E.g., compositions. The
8084 code below is only needed when we are above the base
8085 embedding level, so test for that explicitly. */
8086 && !BIDI_AT_BASE_LEVEL (it->bidi_it))
8088 /* If we lost track of base_level_stop, we have no better
8089 place for handle_stop_backwards to start from than string
8090 beginning. This happens, e.g., when we were reseated to
8091 the previous screenful of text by vertical-motion. */
8092 if (it->base_level_stop <= 0
8093 || IT_STRING_CHARPOS (*it) < it->base_level_stop)
8094 it->base_level_stop = 0;
8095 handle_stop_backwards (it, it->base_level_stop);
8096 return GET_NEXT_DISPLAY_ELEMENT (it);
8100 if (it->current.overlay_string_index >= 0)
8102 /* Get the next character from an overlay string. In overlay
8103 strings, there is no field width or padding with spaces to
8104 do. */
8105 if (IT_STRING_CHARPOS (*it) >= SCHARS (it->string))
8107 it->what = IT_EOB;
8108 return false;
8110 else if (CHAR_COMPOSED_P (it, IT_STRING_CHARPOS (*it),
8111 IT_STRING_BYTEPOS (*it),
8112 it->bidi_it.scan_dir < 0
8113 ? -1
8114 : SCHARS (it->string))
8115 && next_element_from_composition (it))
8117 return true;
8119 else if (STRING_MULTIBYTE (it->string))
8121 const unsigned char *s = (SDATA (it->string)
8122 + IT_STRING_BYTEPOS (*it));
8123 it->c = string_char_and_length (s, &it->len);
8125 else
8127 it->c = SREF (it->string, IT_STRING_BYTEPOS (*it));
8128 it->len = 1;
8131 else
8133 /* Get the next character from a Lisp string that is not an
8134 overlay string. Such strings come from the mode line, for
8135 example. We may have to pad with spaces, or truncate the
8136 string. See also next_element_from_c_string. */
8137 if (IT_STRING_CHARPOS (*it) >= it->end_charpos)
8139 it->what = IT_EOB;
8140 return false;
8142 else if (IT_STRING_CHARPOS (*it) >= it->string_nchars)
8144 /* Pad with spaces. */
8145 it->c = ' ', it->len = 1;
8146 CHARPOS (position) = BYTEPOS (position) = -1;
8148 else if (CHAR_COMPOSED_P (it, IT_STRING_CHARPOS (*it),
8149 IT_STRING_BYTEPOS (*it),
8150 it->bidi_it.scan_dir < 0
8151 ? -1
8152 : it->string_nchars)
8153 && next_element_from_composition (it))
8155 return true;
8157 else if (STRING_MULTIBYTE (it->string))
8159 const unsigned char *s = (SDATA (it->string)
8160 + IT_STRING_BYTEPOS (*it));
8161 it->c = string_char_and_length (s, &it->len);
8163 else
8165 it->c = SREF (it->string, IT_STRING_BYTEPOS (*it));
8166 it->len = 1;
8170 /* Record what we have and where it came from. */
8171 it->what = IT_CHARACTER;
8172 it->object = it->string;
8173 it->position = position;
8174 return true;
8178 /* Load IT with next display element from C string IT->s.
8179 IT->string_nchars is the maximum number of characters to return
8180 from the string. IT->end_charpos may be greater than
8181 IT->string_nchars when this function is called, in which case we
8182 may have to return padding spaces. Value is false if end of string
8183 reached, including padding spaces. */
8185 static bool
8186 next_element_from_c_string (struct it *it)
8188 bool success_p = true;
8190 eassert (it->s);
8191 eassert (!it->bidi_p || it->s == it->bidi_it.string.s);
8192 it->what = IT_CHARACTER;
8193 BYTEPOS (it->position) = CHARPOS (it->position) = 0;
8194 it->object = make_number (0);
8196 /* With bidi reordering, the character to display might not be the
8197 character at IT_CHARPOS. BIDI_IT.FIRST_ELT means that
8198 we were reseated to a new string, whose paragraph direction is
8199 not known. */
8200 if (it->bidi_p && it->bidi_it.first_elt)
8201 get_visually_first_element (it);
8203 /* IT's position can be greater than IT->string_nchars in case a
8204 field width or precision has been specified when the iterator was
8205 initialized. */
8206 if (IT_CHARPOS (*it) >= it->end_charpos)
8208 /* End of the game. */
8209 it->what = IT_EOB;
8210 success_p = false;
8212 else if (IT_CHARPOS (*it) >= it->string_nchars)
8214 /* Pad with spaces. */
8215 it->c = ' ', it->len = 1;
8216 BYTEPOS (it->position) = CHARPOS (it->position) = -1;
8218 else if (it->multibyte_p)
8219 it->c = string_char_and_length (it->s + IT_BYTEPOS (*it), &it->len);
8220 else
8221 it->c = it->s[IT_BYTEPOS (*it)], it->len = 1;
8223 return success_p;
8227 /* Set up IT to return characters from an ellipsis, if appropriate.
8228 The definition of the ellipsis glyphs may come from a display table
8229 entry. This function fills IT with the first glyph from the
8230 ellipsis if an ellipsis is to be displayed. */
8232 static bool
8233 next_element_from_ellipsis (struct it *it)
8235 if (it->selective_display_ellipsis_p)
8236 setup_for_ellipsis (it, it->len);
8237 else
8239 /* The face at the current position may be different from the
8240 face we find after the invisible text. Remember what it
8241 was in IT->saved_face_id, and signal that it's there by
8242 setting face_before_selective_p. */
8243 it->saved_face_id = it->face_id;
8244 it->method = GET_FROM_BUFFER;
8245 it->object = it->w->contents;
8246 reseat_at_next_visible_line_start (it, true);
8247 it->face_before_selective_p = true;
8250 return GET_NEXT_DISPLAY_ELEMENT (it);
8254 /* Deliver an image display element. The iterator IT is already
8255 filled with image information (done in handle_display_prop). Value
8256 is always true. */
8259 static bool
8260 next_element_from_image (struct it *it)
8262 it->what = IT_IMAGE;
8263 return true;
8266 static bool
8267 next_element_from_xwidget (struct it *it)
8269 it->what = IT_XWIDGET;
8270 return true;
8274 /* Fill iterator IT with next display element from a stretch glyph
8275 property. IT->object is the value of the text property. Value is
8276 always true. */
8278 static bool
8279 next_element_from_stretch (struct it *it)
8281 it->what = IT_STRETCH;
8282 return true;
8285 /* Scan backwards from IT's current position until we find a stop
8286 position, or until BEGV. This is called when we find ourself
8287 before both the last known prev_stop and base_level_stop while
8288 reordering bidirectional text. */
8290 static void
8291 compute_stop_pos_backwards (struct it *it)
8293 const int SCAN_BACK_LIMIT = 1000;
8294 struct text_pos pos;
8295 struct display_pos save_current = it->current;
8296 struct text_pos save_position = it->position;
8297 ptrdiff_t charpos = IT_CHARPOS (*it);
8298 ptrdiff_t where_we_are = charpos;
8299 ptrdiff_t save_stop_pos = it->stop_charpos;
8300 ptrdiff_t save_end_pos = it->end_charpos;
8302 eassert (NILP (it->string) && !it->s);
8303 eassert (it->bidi_p);
8304 it->bidi_p = false;
8307 it->end_charpos = min (charpos + 1, ZV);
8308 charpos = max (charpos - SCAN_BACK_LIMIT, BEGV);
8309 SET_TEXT_POS (pos, charpos, CHAR_TO_BYTE (charpos));
8310 reseat_1 (it, pos, false);
8311 compute_stop_pos (it);
8312 /* We must advance forward, right? */
8313 if (it->stop_charpos <= charpos)
8314 emacs_abort ();
8316 while (charpos > BEGV && it->stop_charpos >= it->end_charpos);
8318 if (it->stop_charpos <= where_we_are)
8319 it->prev_stop = it->stop_charpos;
8320 else
8321 it->prev_stop = BEGV;
8322 it->bidi_p = true;
8323 it->current = save_current;
8324 it->position = save_position;
8325 it->stop_charpos = save_stop_pos;
8326 it->end_charpos = save_end_pos;
8329 /* Scan forward from CHARPOS in the current buffer/string, until we
8330 find a stop position > current IT's position. Then handle the stop
8331 position before that. This is called when we bump into a stop
8332 position while reordering bidirectional text. CHARPOS should be
8333 the last previously processed stop_pos (or BEGV/0, if none were
8334 processed yet) whose position is less that IT's current
8335 position. */
8337 static void
8338 handle_stop_backwards (struct it *it, ptrdiff_t charpos)
8340 bool bufp = !STRINGP (it->string);
8341 ptrdiff_t where_we_are = (bufp ? IT_CHARPOS (*it) : IT_STRING_CHARPOS (*it));
8342 struct display_pos save_current = it->current;
8343 struct text_pos save_position = it->position;
8344 struct text_pos pos1;
8345 ptrdiff_t next_stop;
8347 /* Scan in strict logical order. */
8348 eassert (it->bidi_p);
8349 it->bidi_p = false;
8352 it->prev_stop = charpos;
8353 if (bufp)
8355 SET_TEXT_POS (pos1, charpos, CHAR_TO_BYTE (charpos));
8356 reseat_1 (it, pos1, false);
8358 else
8359 it->current.string_pos = string_pos (charpos, it->string);
8360 compute_stop_pos (it);
8361 /* We must advance forward, right? */
8362 if (it->stop_charpos <= it->prev_stop)
8363 emacs_abort ();
8364 charpos = it->stop_charpos;
8366 while (charpos <= where_we_are);
8368 it->bidi_p = true;
8369 it->current = save_current;
8370 it->position = save_position;
8371 next_stop = it->stop_charpos;
8372 it->stop_charpos = it->prev_stop;
8373 handle_stop (it);
8374 it->stop_charpos = next_stop;
8377 /* Load IT with the next display element from current_buffer. Value
8378 is false if end of buffer reached. IT->stop_charpos is the next
8379 position at which to stop and check for text properties or buffer
8380 end. */
8382 static bool
8383 next_element_from_buffer (struct it *it)
8385 bool success_p = true;
8387 eassert (IT_CHARPOS (*it) >= BEGV);
8388 eassert (NILP (it->string) && !it->s);
8389 eassert (!it->bidi_p
8390 || (EQ (it->bidi_it.string.lstring, Qnil)
8391 && it->bidi_it.string.s == NULL));
8393 /* With bidi reordering, the character to display might not be the
8394 character at IT_CHARPOS. BIDI_IT.FIRST_ELT means that
8395 we were reseat()ed to a new buffer position, which is potentially
8396 a different paragraph. */
8397 if (it->bidi_p && it->bidi_it.first_elt)
8399 get_visually_first_element (it);
8400 SET_TEXT_POS (it->position, IT_CHARPOS (*it), IT_BYTEPOS (*it));
8403 if (IT_CHARPOS (*it) >= it->stop_charpos)
8405 if (IT_CHARPOS (*it) >= it->end_charpos)
8407 bool overlay_strings_follow_p;
8409 /* End of the game, except when overlay strings follow that
8410 haven't been returned yet. */
8411 if (it->overlay_strings_at_end_processed_p)
8412 overlay_strings_follow_p = false;
8413 else
8415 it->overlay_strings_at_end_processed_p = true;
8416 overlay_strings_follow_p = get_overlay_strings (it, 0);
8419 if (overlay_strings_follow_p)
8420 success_p = GET_NEXT_DISPLAY_ELEMENT (it);
8421 else
8423 it->what = IT_EOB;
8424 it->position = it->current.pos;
8425 success_p = false;
8428 else if (!(!it->bidi_p
8429 || BIDI_AT_BASE_LEVEL (it->bidi_it)
8430 || IT_CHARPOS (*it) == it->stop_charpos))
8432 /* With bidi non-linear iteration, we could find ourselves
8433 far beyond the last computed stop_charpos, with several
8434 other stop positions in between that we missed. Scan
8435 them all now, in buffer's logical order, until we find
8436 and handle the last stop_charpos that precedes our
8437 current position. */
8438 handle_stop_backwards (it, it->stop_charpos);
8439 it->ignore_overlay_strings_at_pos_p = false;
8440 return GET_NEXT_DISPLAY_ELEMENT (it);
8442 else
8444 if (it->bidi_p)
8446 /* Take note of the stop position we just moved across,
8447 for when we will move back across it. */
8448 it->prev_stop = it->stop_charpos;
8449 /* If we are at base paragraph embedding level, take
8450 note of the last stop position seen at this
8451 level. */
8452 if (BIDI_AT_BASE_LEVEL (it->bidi_it))
8453 it->base_level_stop = it->stop_charpos;
8455 handle_stop (it);
8456 it->ignore_overlay_strings_at_pos_p = false;
8457 return GET_NEXT_DISPLAY_ELEMENT (it);
8460 else if (it->bidi_p
8461 /* If we are before prev_stop, we may have overstepped on
8462 our way backwards a stop_pos, and if so, we need to
8463 handle that stop_pos. */
8464 && IT_CHARPOS (*it) < it->prev_stop
8465 /* We can sometimes back up for reasons that have nothing
8466 to do with bidi reordering. E.g., compositions. The
8467 code below is only needed when we are above the base
8468 embedding level, so test for that explicitly. */
8469 && !BIDI_AT_BASE_LEVEL (it->bidi_it))
8471 if (it->base_level_stop <= 0
8472 || IT_CHARPOS (*it) < it->base_level_stop)
8474 /* If we lost track of base_level_stop, we need to find
8475 prev_stop by looking backwards. This happens, e.g., when
8476 we were reseated to the previous screenful of text by
8477 vertical-motion. */
8478 it->base_level_stop = BEGV;
8479 compute_stop_pos_backwards (it);
8480 handle_stop_backwards (it, it->prev_stop);
8482 else
8483 handle_stop_backwards (it, it->base_level_stop);
8484 it->ignore_overlay_strings_at_pos_p = false;
8485 return GET_NEXT_DISPLAY_ELEMENT (it);
8487 else
8489 /* No face changes, overlays etc. in sight, so just return a
8490 character from current_buffer. */
8491 unsigned char *p;
8492 ptrdiff_t stop;
8494 /* We moved to the next buffer position, so any info about
8495 previously seen overlays is no longer valid. */
8496 it->ignore_overlay_strings_at_pos_p = false;
8498 /* Maybe run the redisplay end trigger hook. Performance note:
8499 This doesn't seem to cost measurable time. */
8500 if (it->redisplay_end_trigger_charpos
8501 && it->glyph_row
8502 && IT_CHARPOS (*it) >= it->redisplay_end_trigger_charpos)
8503 run_redisplay_end_trigger_hook (it);
8505 stop = it->bidi_it.scan_dir < 0 ? -1 : it->end_charpos;
8506 if (CHAR_COMPOSED_P (it, IT_CHARPOS (*it), IT_BYTEPOS (*it),
8507 stop)
8508 && next_element_from_composition (it))
8510 return true;
8513 /* Get the next character, maybe multibyte. */
8514 p = BYTE_POS_ADDR (IT_BYTEPOS (*it));
8515 if (it->multibyte_p && !ASCII_CHAR_P (*p))
8516 it->c = STRING_CHAR_AND_LENGTH (p, it->len);
8517 else
8518 it->c = *p, it->len = 1;
8520 /* Record what we have and where it came from. */
8521 it->what = IT_CHARACTER;
8522 it->object = it->w->contents;
8523 it->position = it->current.pos;
8525 /* Normally we return the character found above, except when we
8526 really want to return an ellipsis for selective display. */
8527 if (it->selective)
8529 if (it->c == '\n')
8531 /* A value of selective > 0 means hide lines indented more
8532 than that number of columns. */
8533 if (it->selective > 0
8534 && IT_CHARPOS (*it) + 1 < ZV
8535 && indented_beyond_p (IT_CHARPOS (*it) + 1,
8536 IT_BYTEPOS (*it) + 1,
8537 it->selective))
8539 success_p = next_element_from_ellipsis (it);
8540 it->dpvec_char_len = -1;
8543 else if (it->c == '\r' && it->selective == -1)
8545 /* A value of selective == -1 means that everything from the
8546 CR to the end of the line is invisible, with maybe an
8547 ellipsis displayed for it. */
8548 success_p = next_element_from_ellipsis (it);
8549 it->dpvec_char_len = -1;
8554 /* Value is false if end of buffer reached. */
8555 eassert (!success_p || it->what != IT_CHARACTER || it->len > 0);
8556 return success_p;
8560 /* Run the redisplay end trigger hook for IT. */
8562 static void
8563 run_redisplay_end_trigger_hook (struct it *it)
8565 /* IT->glyph_row should be non-null, i.e. we should be actually
8566 displaying something, or otherwise we should not run the hook. */
8567 eassert (it->glyph_row);
8569 ptrdiff_t charpos = it->redisplay_end_trigger_charpos;
8570 it->redisplay_end_trigger_charpos = 0;
8572 /* Since we are *trying* to run these functions, don't try to run
8573 them again, even if they get an error. */
8574 wset_redisplay_end_trigger (it->w, Qnil);
8575 CALLN (Frun_hook_with_args, Qredisplay_end_trigger_functions, it->window,
8576 make_number (charpos));
8578 /* Notice if it changed the face of the character we are on. */
8579 handle_face_prop (it);
8583 /* Deliver a composition display element. Unlike the other
8584 next_element_from_XXX, this function is not registered in the array
8585 get_next_element[]. It is called from next_element_from_buffer and
8586 next_element_from_string when necessary. */
8588 static bool
8589 next_element_from_composition (struct it *it)
8591 it->what = IT_COMPOSITION;
8592 it->len = it->cmp_it.nbytes;
8593 if (STRINGP (it->string))
8595 if (it->c < 0)
8597 IT_STRING_CHARPOS (*it) += it->cmp_it.nchars;
8598 IT_STRING_BYTEPOS (*it) += it->cmp_it.nbytes;
8599 return false;
8601 it->position = it->current.string_pos;
8602 it->object = it->string;
8603 it->c = composition_update_it (&it->cmp_it, IT_STRING_CHARPOS (*it),
8604 IT_STRING_BYTEPOS (*it), it->string);
8606 else
8608 if (it->c < 0)
8610 IT_CHARPOS (*it) += it->cmp_it.nchars;
8611 IT_BYTEPOS (*it) += it->cmp_it.nbytes;
8612 if (it->bidi_p)
8614 if (it->bidi_it.new_paragraph)
8615 bidi_paragraph_init (it->paragraph_embedding, &it->bidi_it,
8616 false);
8617 /* Resync the bidi iterator with IT's new position.
8618 FIXME: this doesn't support bidirectional text. */
8619 while (it->bidi_it.charpos < IT_CHARPOS (*it))
8620 bidi_move_to_visually_next (&it->bidi_it);
8622 return false;
8624 it->position = it->current.pos;
8625 it->object = it->w->contents;
8626 it->c = composition_update_it (&it->cmp_it, IT_CHARPOS (*it),
8627 IT_BYTEPOS (*it), Qnil);
8629 return true;
8634 /***********************************************************************
8635 Moving an iterator without producing glyphs
8636 ***********************************************************************/
8638 /* Check if iterator is at a position corresponding to a valid buffer
8639 position after some move_it_ call. */
8641 #define IT_POS_VALID_AFTER_MOVE_P(it) \
8642 ((it)->method != GET_FROM_STRING || IT_STRING_CHARPOS (*it) == 0)
8645 /* Move iterator IT to a specified buffer or X position within one
8646 line on the display without producing glyphs.
8648 OP should be a bit mask including some or all of these bits:
8649 MOVE_TO_X: Stop upon reaching x-position TO_X.
8650 MOVE_TO_POS: Stop upon reaching buffer or string position TO_CHARPOS.
8651 Regardless of OP's value, stop upon reaching the end of the display line.
8653 TO_X is normally a value 0 <= TO_X <= IT->last_visible_x.
8654 This means, in particular, that TO_X includes window's horizontal
8655 scroll amount.
8657 The return value has several possible values that
8658 say what condition caused the scan to stop:
8660 MOVE_POS_MATCH_OR_ZV
8661 - when TO_POS or ZV was reached.
8663 MOVE_X_REACHED
8664 -when TO_X was reached before TO_POS or ZV were reached.
8666 MOVE_LINE_CONTINUED
8667 - when we reached the end of the display area and the line must
8668 be continued.
8670 MOVE_LINE_TRUNCATED
8671 - when we reached the end of the display area and the line is
8672 truncated.
8674 MOVE_NEWLINE_OR_CR
8675 - when we stopped at a line end, i.e. a newline or a CR and selective
8676 display is on. */
8678 static enum move_it_result
8679 move_it_in_display_line_to (struct it *it,
8680 ptrdiff_t to_charpos, int to_x,
8681 enum move_operation_enum op)
8683 enum move_it_result result = MOVE_UNDEFINED;
8684 struct glyph_row *saved_glyph_row;
8685 struct it wrap_it, atpos_it, atx_it, ppos_it;
8686 void *wrap_data = NULL, *atpos_data = NULL, *atx_data = NULL;
8687 void *ppos_data = NULL;
8688 bool may_wrap = false;
8689 enum it_method prev_method = it->method;
8690 ptrdiff_t closest_pos UNINIT;
8691 ptrdiff_t prev_pos = IT_CHARPOS (*it);
8692 bool saw_smaller_pos = prev_pos < to_charpos;
8693 bool line_number_pending = false;
8695 /* Don't produce glyphs in produce_glyphs. */
8696 saved_glyph_row = it->glyph_row;
8697 it->glyph_row = NULL;
8699 /* Use wrap_it to save a copy of IT wherever a word wrap could
8700 occur. Use atpos_it to save a copy of IT at the desired buffer
8701 position, if found, so that we can scan ahead and check if the
8702 word later overshoots the window edge. Use atx_it similarly, for
8703 pixel positions. */
8704 wrap_it.sp = -1;
8705 atpos_it.sp = -1;
8706 atx_it.sp = -1;
8708 /* Use ppos_it under bidi reordering to save a copy of IT for the
8709 initial position. We restore that position in IT when we have
8710 scanned the entire display line without finding a match for
8711 TO_CHARPOS and all the character positions are greater than
8712 TO_CHARPOS. We then restart the scan from the initial position,
8713 and stop at CLOSEST_POS, which is a position > TO_CHARPOS that is
8714 the closest to TO_CHARPOS. */
8715 if (it->bidi_p)
8717 if ((op & MOVE_TO_POS) && IT_CHARPOS (*it) >= to_charpos)
8719 SAVE_IT (ppos_it, *it, ppos_data);
8720 closest_pos = IT_CHARPOS (*it);
8722 else
8723 closest_pos = ZV;
8726 #define BUFFER_POS_REACHED_P() \
8727 ((op & MOVE_TO_POS) != 0 \
8728 && BUFFERP (it->object) \
8729 && (IT_CHARPOS (*it) == to_charpos \
8730 || ((!it->bidi_p \
8731 || BIDI_AT_BASE_LEVEL (it->bidi_it)) \
8732 && IT_CHARPOS (*it) > to_charpos) \
8733 || (it->what == IT_COMPOSITION \
8734 && ((IT_CHARPOS (*it) > to_charpos \
8735 && to_charpos >= it->cmp_it.charpos) \
8736 || (IT_CHARPOS (*it) < to_charpos \
8737 && to_charpos <= it->cmp_it.charpos)))) \
8738 && (it->method == GET_FROM_BUFFER \
8739 || (it->method == GET_FROM_DISPLAY_VECTOR \
8740 && it->dpvec + it->current.dpvec_index + 1 >= it->dpend)))
8742 if (it->hpos == 0)
8744 /* If line numbers are being displayed, produce a line number.
8745 But don't do that if we are to reach first_visible_x, because
8746 line numbers are not relevant to stuff that is not visible on
8747 display. */
8748 if (!((op && MOVE_TO_X) && to_x == it->first_visible_x)
8749 && should_produce_line_number (it))
8751 if (it->current_x == it->first_visible_x)
8752 maybe_produce_line_number (it);
8753 else
8754 line_number_pending = true;
8756 /* If there's a line-/wrap-prefix, handle it. */
8757 if (it->method == GET_FROM_BUFFER)
8758 handle_line_prefix (it);
8761 if (IT_CHARPOS (*it) < CHARPOS (this_line_min_pos))
8762 SET_TEXT_POS (this_line_min_pos, IT_CHARPOS (*it), IT_BYTEPOS (*it));
8764 while (true)
8766 int x, i, ascent = 0, descent = 0;
8768 /* Utility macro to reset an iterator with x, ascent, and descent. */
8769 #define IT_RESET_X_ASCENT_DESCENT(IT) \
8770 ((IT)->current_x = x, (IT)->max_ascent = ascent, \
8771 (IT)->max_descent = descent)
8773 /* Stop if we move beyond TO_CHARPOS (after an image or a
8774 display string or stretch glyph). */
8775 if ((op & MOVE_TO_POS) != 0
8776 && BUFFERP (it->object)
8777 && it->method == GET_FROM_BUFFER
8778 && (((!it->bidi_p
8779 /* When the iterator is at base embedding level, we
8780 are guaranteed that characters are delivered for
8781 display in strictly increasing order of their
8782 buffer positions. */
8783 || BIDI_AT_BASE_LEVEL (it->bidi_it))
8784 && IT_CHARPOS (*it) > to_charpos)
8785 || (it->bidi_p
8786 && (prev_method == GET_FROM_IMAGE
8787 || prev_method == GET_FROM_STRETCH
8788 || prev_method == GET_FROM_STRING)
8789 /* Passed TO_CHARPOS from left to right. */
8790 && ((prev_pos < to_charpos
8791 && IT_CHARPOS (*it) > to_charpos)
8792 /* Passed TO_CHARPOS from right to left. */
8793 || (prev_pos > to_charpos
8794 && IT_CHARPOS (*it) < to_charpos)))))
8796 if (it->line_wrap != WORD_WRAP || wrap_it.sp < 0)
8798 result = MOVE_POS_MATCH_OR_ZV;
8799 break;
8801 else if (it->line_wrap == WORD_WRAP && atpos_it.sp < 0)
8802 /* If wrap_it is valid, the current position might be in a
8803 word that is wrapped. So, save the iterator in
8804 atpos_it and continue to see if wrapping happens. */
8805 SAVE_IT (atpos_it, *it, atpos_data);
8808 /* Stop when ZV reached.
8809 We used to stop here when TO_CHARPOS reached as well, but that is
8810 too soon if this glyph does not fit on this line. So we handle it
8811 explicitly below. */
8812 if (!get_next_display_element (it))
8814 result = MOVE_POS_MATCH_OR_ZV;
8815 break;
8818 if (it->line_wrap == TRUNCATE)
8820 /* If it->pixel_width is zero, the last PRODUCE_GLYPHS call
8821 produced something that doesn't consume any screen estate
8822 in the text area, so we don't want to exit the loop at
8823 TO_CHARPOS, before we produce the glyph for that buffer
8824 position. This happens, e.g., when there's an overlay at
8825 TO_CHARPOS that draws a fringe bitmap. */
8826 if (BUFFER_POS_REACHED_P ()
8827 && (it->pixel_width > 0
8828 || IT_CHARPOS (*it) > to_charpos
8829 || it->area != TEXT_AREA))
8831 result = MOVE_POS_MATCH_OR_ZV;
8832 break;
8835 else
8837 if (it->line_wrap == WORD_WRAP && it->area == TEXT_AREA)
8839 if (IT_DISPLAYING_WHITESPACE (it))
8840 may_wrap = true;
8841 else if (may_wrap)
8843 /* We have reached a glyph that follows one or more
8844 whitespace characters. If the position is
8845 already found, we are done. */
8846 if (atpos_it.sp >= 0)
8848 RESTORE_IT (it, &atpos_it, atpos_data);
8849 result = MOVE_POS_MATCH_OR_ZV;
8850 goto done;
8852 if (atx_it.sp >= 0)
8854 RESTORE_IT (it, &atx_it, atx_data);
8855 result = MOVE_X_REACHED;
8856 goto done;
8858 /* Otherwise, we can wrap here. */
8859 SAVE_IT (wrap_it, *it, wrap_data);
8860 may_wrap = false;
8865 /* Remember the line height for the current line, in case
8866 the next element doesn't fit on the line. */
8867 ascent = it->max_ascent;
8868 descent = it->max_descent;
8870 /* The call to produce_glyphs will get the metrics of the
8871 display element IT is loaded with. Record the x-position
8872 before this display element, in case it doesn't fit on the
8873 line. */
8874 x = it->current_x;
8876 PRODUCE_GLYPHS (it);
8878 if (it->area != TEXT_AREA)
8880 prev_method = it->method;
8881 if (it->method == GET_FROM_BUFFER)
8882 prev_pos = IT_CHARPOS (*it);
8883 set_iterator_to_next (it, true);
8884 if (IT_CHARPOS (*it) < CHARPOS (this_line_min_pos))
8885 SET_TEXT_POS (this_line_min_pos,
8886 IT_CHARPOS (*it), IT_BYTEPOS (*it));
8887 if (it->bidi_p
8888 && (op & MOVE_TO_POS)
8889 && IT_CHARPOS (*it) > to_charpos
8890 && IT_CHARPOS (*it) < closest_pos)
8891 closest_pos = IT_CHARPOS (*it);
8892 continue;
8895 /* The number of glyphs we get back in IT->nglyphs will normally
8896 be 1 except when IT->c is (i) a TAB, or (ii) a multi-glyph
8897 character on a terminal frame, or (iii) a line end. For the
8898 second case, IT->nglyphs - 1 padding glyphs will be present.
8899 (On X frames, there is only one glyph produced for a
8900 composite character.)
8902 The behavior implemented below means, for continuation lines,
8903 that as many spaces of a TAB as fit on the current line are
8904 displayed there. For terminal frames, as many glyphs of a
8905 multi-glyph character are displayed in the current line, too.
8906 This is what the old redisplay code did, and we keep it that
8907 way. Under X, the whole shape of a complex character must
8908 fit on the line or it will be completely displayed in the
8909 next line.
8911 Note that both for tabs and padding glyphs, all glyphs have
8912 the same width. */
8913 if (it->nglyphs)
8915 /* More than one glyph or glyph doesn't fit on line. All
8916 glyphs have the same width. */
8917 int single_glyph_width = it->pixel_width / it->nglyphs;
8918 int new_x;
8919 int x_before_this_char = x;
8920 int hpos_before_this_char = it->hpos;
8922 for (i = 0; i < it->nglyphs; ++i, x = new_x)
8924 new_x = x + single_glyph_width;
8926 /* We want to leave anything reaching TO_X to the caller. */
8927 if ((op & MOVE_TO_X) && new_x > to_x)
8929 if (BUFFER_POS_REACHED_P ())
8931 if (it->line_wrap != WORD_WRAP || wrap_it.sp < 0)
8932 goto buffer_pos_reached;
8933 if (atpos_it.sp < 0)
8935 SAVE_IT (atpos_it, *it, atpos_data);
8936 IT_RESET_X_ASCENT_DESCENT (&atpos_it);
8939 else
8941 if (it->line_wrap != WORD_WRAP || wrap_it.sp < 0)
8943 it->current_x = x;
8944 result = MOVE_X_REACHED;
8945 break;
8947 if (atx_it.sp < 0)
8949 SAVE_IT (atx_it, *it, atx_data);
8950 IT_RESET_X_ASCENT_DESCENT (&atx_it);
8955 if (/* Lines are continued. */
8956 it->line_wrap != TRUNCATE
8957 && (/* And glyph doesn't fit on the line. */
8958 new_x > it->last_visible_x
8959 /* Or it fits exactly and we're on a window
8960 system frame. */
8961 || (new_x == it->last_visible_x
8962 && FRAME_WINDOW_P (it->f)
8963 && ((it->bidi_p && it->bidi_it.paragraph_dir == R2L)
8964 ? WINDOW_LEFT_FRINGE_WIDTH (it->w)
8965 : WINDOW_RIGHT_FRINGE_WIDTH (it->w)))))
8967 bool moved_forward = false;
8969 if (/* IT->hpos == 0 means the very first glyph
8970 doesn't fit on the line, e.g. a wide image. */
8971 it->hpos == 0
8972 || (new_x == it->last_visible_x
8973 && FRAME_WINDOW_P (it->f)))
8975 ++it->hpos;
8976 it->current_x = new_x;
8978 /* The character's last glyph just barely fits
8979 in this row. */
8980 if (i == it->nglyphs - 1)
8982 /* If this is the destination position,
8983 return a position *before* it in this row,
8984 now that we know it fits in this row. */
8985 if (BUFFER_POS_REACHED_P ())
8987 bool can_wrap = true;
8989 /* If we are at a whitespace character
8990 that barely fits on this screen line,
8991 but the next character is also
8992 whitespace, we cannot wrap here. */
8993 if (it->line_wrap == WORD_WRAP
8994 && wrap_it.sp >= 0
8995 && may_wrap
8996 && IT_OVERFLOW_NEWLINE_INTO_FRINGE (it))
8998 struct it tem_it;
8999 void *tem_data = NULL;
9001 SAVE_IT (tem_it, *it, tem_data);
9002 set_iterator_to_next (it, true);
9003 if (get_next_display_element (it)
9004 && IT_DISPLAYING_WHITESPACE (it))
9005 can_wrap = false;
9006 RESTORE_IT (it, &tem_it, tem_data);
9008 if (it->line_wrap != WORD_WRAP
9009 || wrap_it.sp < 0
9010 /* If we've just found whitespace
9011 where we can wrap, effectively
9012 ignore the previous wrap point --
9013 it is no longer relevant, but we
9014 won't have an opportunity to
9015 update it, since we've reached
9016 the edge of this screen line. */
9017 || (may_wrap && can_wrap
9018 && IT_OVERFLOW_NEWLINE_INTO_FRINGE (it)))
9020 it->hpos = hpos_before_this_char;
9021 it->current_x = x_before_this_char;
9022 result = MOVE_POS_MATCH_OR_ZV;
9023 break;
9025 if (it->line_wrap == WORD_WRAP
9026 && atpos_it.sp < 0)
9028 SAVE_IT (atpos_it, *it, atpos_data);
9029 atpos_it.current_x = x_before_this_char;
9030 atpos_it.hpos = hpos_before_this_char;
9034 prev_method = it->method;
9035 if (it->method == GET_FROM_BUFFER)
9036 prev_pos = IT_CHARPOS (*it);
9037 set_iterator_to_next (it, true);
9038 if (IT_CHARPOS (*it) < CHARPOS (this_line_min_pos))
9039 SET_TEXT_POS (this_line_min_pos,
9040 IT_CHARPOS (*it), IT_BYTEPOS (*it));
9041 /* On graphical terminals, newlines may
9042 "overflow" into the fringe if
9043 overflow-newline-into-fringe is non-nil.
9044 On text terminals, and on graphical
9045 terminals with no right margin, newlines
9046 may overflow into the last glyph on the
9047 display line.*/
9048 if (!FRAME_WINDOW_P (it->f)
9049 || ((it->bidi_p
9050 && it->bidi_it.paragraph_dir == R2L)
9051 ? WINDOW_LEFT_FRINGE_WIDTH (it->w)
9052 : WINDOW_RIGHT_FRINGE_WIDTH (it->w)) == 0
9053 || IT_OVERFLOW_NEWLINE_INTO_FRINGE (it))
9055 if (!get_next_display_element (it))
9057 result = MOVE_POS_MATCH_OR_ZV;
9058 break;
9060 moved_forward = true;
9061 if (BUFFER_POS_REACHED_P ())
9063 if (ITERATOR_AT_END_OF_LINE_P (it))
9064 result = MOVE_POS_MATCH_OR_ZV;
9065 else
9066 result = MOVE_LINE_CONTINUED;
9067 break;
9069 if (ITERATOR_AT_END_OF_LINE_P (it)
9070 && (it->line_wrap != WORD_WRAP
9071 || wrap_it.sp < 0
9072 || IT_OVERFLOW_NEWLINE_INTO_FRINGE (it)))
9074 result = MOVE_NEWLINE_OR_CR;
9075 break;
9080 else
9081 IT_RESET_X_ASCENT_DESCENT (it);
9083 /* If the screen line ends with whitespace, and we
9084 are under word-wrap, don't use wrap_it: it is no
9085 longer relevant, but we won't have an opportunity
9086 to update it, since we are done with this screen
9087 line. */
9088 if (may_wrap && IT_OVERFLOW_NEWLINE_INTO_FRINGE (it)
9089 /* If the character after the one which set the
9090 may_wrap flag is also whitespace, we can't
9091 wrap here, since the screen line cannot be
9092 wrapped in the middle of whitespace.
9093 Therefore, wrap_it _is_ relevant in that
9094 case. */
9095 && !(moved_forward && IT_DISPLAYING_WHITESPACE (it)))
9097 /* If we've found TO_X, go back there, as we now
9098 know the last word fits on this screen line. */
9099 if ((op & MOVE_TO_X) && new_x == it->last_visible_x
9100 && atx_it.sp >= 0)
9102 RESTORE_IT (it, &atx_it, atx_data);
9103 atpos_it.sp = -1;
9104 atx_it.sp = -1;
9105 result = MOVE_X_REACHED;
9106 break;
9109 else if (wrap_it.sp >= 0)
9111 RESTORE_IT (it, &wrap_it, wrap_data);
9112 atpos_it.sp = -1;
9113 atx_it.sp = -1;
9116 TRACE_MOVE ((stderr, "move_it_in: continued at %d\n",
9117 IT_CHARPOS (*it)));
9118 result = MOVE_LINE_CONTINUED;
9119 break;
9122 if (BUFFER_POS_REACHED_P ())
9124 if (it->line_wrap != WORD_WRAP || wrap_it.sp < 0)
9125 goto buffer_pos_reached;
9126 if (it->line_wrap == WORD_WRAP && atpos_it.sp < 0)
9128 SAVE_IT (atpos_it, *it, atpos_data);
9129 IT_RESET_X_ASCENT_DESCENT (&atpos_it);
9133 if (new_x > it->first_visible_x)
9135 /* If we have reached the visible portion of the
9136 screen line, produce the line number if needed. */
9137 if (line_number_pending)
9139 line_number_pending = false;
9140 it->current_x = it->first_visible_x;
9141 maybe_produce_line_number (it);
9142 it->current_x += new_x - it->first_visible_x;
9144 /* Glyph is visible. Increment number of glyphs that
9145 would be displayed. */
9146 ++it->hpos;
9150 if (result != MOVE_UNDEFINED)
9151 break;
9153 else if (BUFFER_POS_REACHED_P ())
9155 buffer_pos_reached:
9156 IT_RESET_X_ASCENT_DESCENT (it);
9157 result = MOVE_POS_MATCH_OR_ZV;
9158 break;
9160 else if ((op & MOVE_TO_X) && it->current_x >= to_x)
9162 /* Stop when TO_X specified and reached. This check is
9163 necessary here because of lines consisting of a line end,
9164 only. The line end will not produce any glyphs and we
9165 would never get MOVE_X_REACHED. */
9166 eassert (it->nglyphs == 0);
9167 result = MOVE_X_REACHED;
9168 break;
9171 /* Is this a line end? If yes, we're done. */
9172 if (ITERATOR_AT_END_OF_LINE_P (it))
9174 /* If we are past TO_CHARPOS, but never saw any character
9175 positions smaller than TO_CHARPOS, return
9176 MOVE_POS_MATCH_OR_ZV, like the unidirectional display
9177 did. */
9178 if (it->bidi_p && (op & MOVE_TO_POS) != 0)
9180 if (!saw_smaller_pos && IT_CHARPOS (*it) > to_charpos)
9182 if (closest_pos < ZV)
9184 RESTORE_IT (it, &ppos_it, ppos_data);
9185 /* Don't recurse if closest_pos is equal to
9186 to_charpos, since we have just tried that. */
9187 if (closest_pos != to_charpos)
9188 move_it_in_display_line_to (it, closest_pos, -1,
9189 MOVE_TO_POS);
9190 result = MOVE_POS_MATCH_OR_ZV;
9192 else
9193 goto buffer_pos_reached;
9195 else if (it->line_wrap == WORD_WRAP && atpos_it.sp >= 0
9196 && IT_CHARPOS (*it) > to_charpos)
9197 goto buffer_pos_reached;
9198 else
9199 result = MOVE_NEWLINE_OR_CR;
9201 else
9202 result = MOVE_NEWLINE_OR_CR;
9203 /* If we've processed the newline, make sure this flag is
9204 reset, as it must only be set when the newline itself is
9205 processed. */
9206 if (result == MOVE_NEWLINE_OR_CR)
9207 it->constrain_row_ascent_descent_p = false;
9208 break;
9211 prev_method = it->method;
9212 if (it->method == GET_FROM_BUFFER)
9213 prev_pos = IT_CHARPOS (*it);
9215 /* Detect overly-wide wrap-prefixes made of (space ...) display
9216 properties. When such a wrap prefix reaches past the right
9217 margin of the window, we need to avoid the call to
9218 set_iterator_to_next below, so that it->line_wrap is left at
9219 its TRUNCATE value wisely set by handle_line_prefix.
9220 Otherwise, set_iterator_to_next will pop the iterator stack,
9221 restore it->line_wrap, and we might miss the opportunity to
9222 exit the loop and return. */
9223 bool overwide_wrap_prefix =
9224 CONSP (it->object) && EQ (XCAR (it->object), Qspace)
9225 && it->sp > 0 && it->method == GET_FROM_STRETCH
9226 && it->current_x >= it->last_visible_x
9227 && it->continuation_lines_width > 0
9228 && it->line_wrap == TRUNCATE && it->stack[0].line_wrap != TRUNCATE;
9229 /* The current display element has been consumed. Advance
9230 to the next. */
9231 if (!overwide_wrap_prefix)
9232 set_iterator_to_next (it, true);
9233 if (IT_CHARPOS (*it) < CHARPOS (this_line_min_pos))
9234 SET_TEXT_POS (this_line_min_pos, IT_CHARPOS (*it), IT_BYTEPOS (*it));
9235 if (IT_CHARPOS (*it) < to_charpos)
9236 saw_smaller_pos = true;
9237 if (it->bidi_p
9238 && (op & MOVE_TO_POS)
9239 && IT_CHARPOS (*it) >= to_charpos
9240 && IT_CHARPOS (*it) < closest_pos)
9241 closest_pos = IT_CHARPOS (*it);
9243 /* Stop if lines are truncated and IT's current x-position is
9244 past the right edge of the window now. */
9245 if (it->line_wrap == TRUNCATE
9246 && it->current_x >= it->last_visible_x)
9248 if (!FRAME_WINDOW_P (it->f)
9249 || ((it->bidi_p && it->bidi_it.paragraph_dir == R2L)
9250 ? WINDOW_LEFT_FRINGE_WIDTH (it->w)
9251 : WINDOW_RIGHT_FRINGE_WIDTH (it->w)) == 0
9252 || IT_OVERFLOW_NEWLINE_INTO_FRINGE (it))
9254 bool at_eob_p = false;
9256 if ((at_eob_p = !get_next_display_element (it))
9257 || BUFFER_POS_REACHED_P ()
9258 /* If we are past TO_CHARPOS, but never saw any
9259 character positions smaller than TO_CHARPOS,
9260 return MOVE_POS_MATCH_OR_ZV, like the
9261 unidirectional display did. */
9262 || (it->bidi_p && (op & MOVE_TO_POS) != 0
9263 && !saw_smaller_pos
9264 && IT_CHARPOS (*it) > to_charpos))
9266 if (it->bidi_p
9267 && !BUFFER_POS_REACHED_P ()
9268 && !at_eob_p && closest_pos < ZV)
9270 RESTORE_IT (it, &ppos_it, ppos_data);
9271 if (closest_pos != to_charpos)
9272 move_it_in_display_line_to (it, closest_pos, -1,
9273 MOVE_TO_POS);
9275 result = MOVE_POS_MATCH_OR_ZV;
9276 break;
9278 if (ITERATOR_AT_END_OF_LINE_P (it))
9280 result = MOVE_NEWLINE_OR_CR;
9281 break;
9284 else if (it->bidi_p && (op & MOVE_TO_POS) != 0
9285 && !saw_smaller_pos
9286 && IT_CHARPOS (*it) > to_charpos)
9288 if (closest_pos < ZV)
9290 RESTORE_IT (it, &ppos_it, ppos_data);
9291 if (closest_pos != to_charpos)
9292 move_it_in_display_line_to (it, closest_pos, -1,
9293 MOVE_TO_POS);
9295 result = MOVE_POS_MATCH_OR_ZV;
9296 break;
9298 result = MOVE_LINE_TRUNCATED;
9299 break;
9301 #undef IT_RESET_X_ASCENT_DESCENT
9304 #undef BUFFER_POS_REACHED_P
9306 /* If we scanned beyond TO_POS, restore the saved iterator either to
9307 the wrap point (if found), or to atpos/atx location. We decide which
9308 data to use to restore the saved iterator state by their X coordinates,
9309 since buffer positions might increase non-monotonically with screen
9310 coordinates due to bidi reordering. */
9311 if (result == MOVE_LINE_CONTINUED
9312 && it->line_wrap == WORD_WRAP
9313 && wrap_it.sp >= 0
9314 && ((atpos_it.sp >= 0 && wrap_it.current_x < atpos_it.current_x)
9315 || (atx_it.sp >= 0 && wrap_it.current_x < atx_it.current_x)))
9316 RESTORE_IT (it, &wrap_it, wrap_data);
9317 else if (atpos_it.sp >= 0)
9318 RESTORE_IT (it, &atpos_it, atpos_data);
9319 else if (atx_it.sp >= 0)
9320 RESTORE_IT (it, &atx_it, atx_data);
9322 done:
9324 if (atpos_data)
9325 bidi_unshelve_cache (atpos_data, true);
9326 if (atx_data)
9327 bidi_unshelve_cache (atx_data, true);
9328 if (wrap_data)
9329 bidi_unshelve_cache (wrap_data, true);
9330 if (ppos_data)
9331 bidi_unshelve_cache (ppos_data, true);
9333 /* Restore the iterator settings altered at the beginning of this
9334 function. */
9335 it->glyph_row = saved_glyph_row;
9336 return result;
9339 /* For external use. */
9340 void
9341 move_it_in_display_line (struct it *it,
9342 ptrdiff_t to_charpos, int to_x,
9343 enum move_operation_enum op)
9345 if (it->line_wrap == WORD_WRAP
9346 && (op & MOVE_TO_X))
9348 struct it save_it;
9349 void *save_data = NULL;
9350 int skip;
9352 SAVE_IT (save_it, *it, save_data);
9353 skip = move_it_in_display_line_to (it, to_charpos, to_x, op);
9354 /* When word-wrap is on, TO_X may lie past the end
9355 of a wrapped line. Then it->current is the
9356 character on the next line, so backtrack to the
9357 space before the wrap point. */
9358 if (skip == MOVE_LINE_CONTINUED)
9360 int prev_x = max (it->current_x - 1, 0);
9361 RESTORE_IT (it, &save_it, save_data);
9362 move_it_in_display_line_to
9363 (it, -1, prev_x, MOVE_TO_X);
9365 else
9366 bidi_unshelve_cache (save_data, true);
9368 else
9369 move_it_in_display_line_to (it, to_charpos, to_x, op);
9373 /* Move IT forward until it satisfies one or more of the criteria in
9374 TO_CHARPOS, TO_X, TO_Y, and TO_VPOS.
9376 OP is a bit-mask that specifies where to stop, and in particular,
9377 which of those four position arguments makes a difference. See the
9378 description of enum move_operation_enum.
9380 If TO_CHARPOS is in invisible text, e.g. a truncated part of a
9381 screen line, this function will set IT to the next position that is
9382 displayed to the right of TO_CHARPOS on the screen.
9384 Return the maximum pixel length of any line scanned but never more
9385 than it.last_visible_x. */
9388 move_it_to (struct it *it, ptrdiff_t to_charpos, int to_x, int to_y, int to_vpos, int op)
9390 enum move_it_result skip, skip2 = MOVE_X_REACHED;
9391 int line_height, line_start_x = 0, reached = 0;
9392 int max_current_x = 0;
9393 void *backup_data = NULL;
9395 for (;;)
9397 if (op & MOVE_TO_VPOS)
9399 /* If no TO_CHARPOS and no TO_X specified, stop at the
9400 start of the line TO_VPOS. */
9401 if ((op & (MOVE_TO_X | MOVE_TO_POS)) == 0)
9403 if (it->vpos == to_vpos)
9405 reached = 1;
9406 break;
9408 else
9409 skip = move_it_in_display_line_to (it, -1, -1, 0);
9411 else
9413 /* TO_VPOS >= 0 means stop at TO_X in the line at
9414 TO_VPOS, or at TO_POS, whichever comes first. */
9415 if (it->vpos == to_vpos)
9417 reached = 2;
9418 break;
9421 skip = move_it_in_display_line_to (it, to_charpos, to_x, op);
9423 if (skip == MOVE_POS_MATCH_OR_ZV || it->vpos == to_vpos)
9425 reached = 3;
9426 break;
9428 else if (skip == MOVE_X_REACHED && it->vpos != to_vpos)
9430 /* We have reached TO_X but not in the line we want. */
9431 skip = move_it_in_display_line_to (it, to_charpos,
9432 -1, MOVE_TO_POS);
9433 if (skip == MOVE_POS_MATCH_OR_ZV)
9435 reached = 4;
9436 break;
9441 else if (op & MOVE_TO_Y)
9443 struct it it_backup;
9445 if (it->line_wrap == WORD_WRAP)
9446 SAVE_IT (it_backup, *it, backup_data);
9448 /* TO_Y specified means stop at TO_X in the line containing
9449 TO_Y---or at TO_CHARPOS if this is reached first. The
9450 problem is that we can't really tell whether the line
9451 contains TO_Y before we have completely scanned it, and
9452 this may skip past TO_X. What we do is to first scan to
9453 TO_X.
9455 If TO_X is not specified, use a TO_X of zero. The reason
9456 is to make the outcome of this function more predictable.
9457 If we didn't use TO_X == 0, we would stop at the end of
9458 the line which is probably not what a caller would expect
9459 to happen. */
9460 skip = move_it_in_display_line_to
9461 (it, to_charpos, ((op & MOVE_TO_X) ? to_x : 0),
9462 (MOVE_TO_X | (op & MOVE_TO_POS)));
9464 /* If TO_CHARPOS is reached or ZV, we don't have to do more. */
9465 if (skip == MOVE_POS_MATCH_OR_ZV)
9466 reached = 5;
9467 else if (skip == MOVE_X_REACHED)
9469 /* If TO_X was reached, we want to know whether TO_Y is
9470 in the line. We know this is the case if the already
9471 scanned glyphs make the line tall enough. Otherwise,
9472 we must check by scanning the rest of the line. */
9473 line_height = it->max_ascent + it->max_descent;
9474 if (to_y >= it->current_y
9475 && to_y < it->current_y + line_height)
9477 reached = 6;
9478 break;
9480 SAVE_IT (it_backup, *it, backup_data);
9481 TRACE_MOVE ((stderr, "move_it: from %d\n", IT_CHARPOS (*it)));
9482 skip2 = move_it_in_display_line_to (it, to_charpos, -1,
9483 op & MOVE_TO_POS);
9484 TRACE_MOVE ((stderr, "move_it: to %d\n", IT_CHARPOS (*it)));
9485 line_height = it->max_ascent + it->max_descent;
9486 TRACE_MOVE ((stderr, "move_it: line_height = %d\n", line_height));
9488 if (to_y >= it->current_y
9489 && to_y < it->current_y + line_height)
9491 /* If TO_Y is in this line and TO_X was reached
9492 above, we scanned too far. We have to restore
9493 IT's settings to the ones before skipping. But
9494 keep the more accurate values of max_ascent and
9495 max_descent we've found while skipping the rest
9496 of the line, for the sake of callers, such as
9497 pos_visible_p, that need to know the line
9498 height. */
9499 int max_ascent = it->max_ascent;
9500 int max_descent = it->max_descent;
9502 RESTORE_IT (it, &it_backup, backup_data);
9503 it->max_ascent = max_ascent;
9504 it->max_descent = max_descent;
9505 reached = 6;
9507 else
9509 skip = skip2;
9510 if (skip == MOVE_POS_MATCH_OR_ZV)
9511 reached = 7;
9514 else
9516 /* Check whether TO_Y is in this line. */
9517 line_height = it->max_ascent + it->max_descent;
9518 TRACE_MOVE ((stderr, "move_it: line_height = %d\n", line_height));
9520 if (to_y >= it->current_y
9521 && to_y < it->current_y + line_height)
9523 if (to_y > it->current_y)
9524 max_current_x = max (it->current_x, max_current_x);
9526 /* When word-wrap is on, TO_X may lie past the end
9527 of a wrapped line. Then it->current is the
9528 character on the next line, so backtrack to the
9529 space before the wrap point. */
9530 if (skip == MOVE_LINE_CONTINUED
9531 && it->line_wrap == WORD_WRAP)
9533 int prev_x = max (it->current_x - 1, 0);
9534 RESTORE_IT (it, &it_backup, backup_data);
9535 skip = move_it_in_display_line_to
9536 (it, -1, prev_x, MOVE_TO_X);
9539 reached = 6;
9543 if (reached)
9545 max_current_x = max (it->current_x, max_current_x);
9546 break;
9549 else if (BUFFERP (it->object)
9550 && (it->method == GET_FROM_BUFFER
9551 || it->method == GET_FROM_STRETCH)
9552 && IT_CHARPOS (*it) >= to_charpos
9553 /* Under bidi iteration, a call to set_iterator_to_next
9554 can scan far beyond to_charpos if the initial
9555 portion of the next line needs to be reordered. In
9556 that case, give move_it_in_display_line_to another
9557 chance below. */
9558 && !(it->bidi_p
9559 && it->bidi_it.scan_dir == -1))
9560 skip = MOVE_POS_MATCH_OR_ZV;
9561 else
9562 skip = move_it_in_display_line_to (it, to_charpos, -1, MOVE_TO_POS);
9564 switch (skip)
9566 case MOVE_POS_MATCH_OR_ZV:
9567 max_current_x = max (it->current_x, max_current_x);
9568 reached = 8;
9569 goto out;
9571 case MOVE_NEWLINE_OR_CR:
9572 max_current_x = max (it->current_x, max_current_x);
9573 set_iterator_to_next (it, true);
9574 it->continuation_lines_width = 0;
9575 break;
9577 case MOVE_LINE_TRUNCATED:
9578 max_current_x = it->last_visible_x;
9579 it->continuation_lines_width = 0;
9580 reseat_at_next_visible_line_start (it, false);
9581 if ((op & MOVE_TO_POS) != 0
9582 && IT_CHARPOS (*it) > to_charpos)
9584 reached = 9;
9585 goto out;
9587 break;
9589 case MOVE_LINE_CONTINUED:
9590 max_current_x = it->last_visible_x;
9591 /* For continued lines ending in a tab, some of the glyphs
9592 associated with the tab are displayed on the current
9593 line. Since it->current_x does not include these glyphs,
9594 we use it->last_visible_x instead. */
9595 if (it->c == '\t')
9597 it->continuation_lines_width += it->last_visible_x;
9598 /* When moving by vpos, ensure that the iterator really
9599 advances to the next line (bug#847, bug#969). Fixme:
9600 do we need to do this in other circumstances? */
9601 if (it->current_x != it->last_visible_x
9602 && (op & MOVE_TO_VPOS)
9603 && !(op & (MOVE_TO_X | MOVE_TO_POS)))
9605 line_start_x = it->current_x + it->pixel_width
9606 - it->last_visible_x;
9607 if (FRAME_WINDOW_P (it->f))
9609 struct face *face = FACE_FROM_ID (it->f, it->face_id);
9610 struct font *face_font = face->font;
9612 /* When display_line produces a continued line
9613 that ends in a TAB, it skips a tab stop that
9614 is closer than the font's space character
9615 width (see x_produce_glyphs where it produces
9616 the stretch glyph which represents a TAB).
9617 We need to reproduce the same logic here. */
9618 eassert (face_font);
9619 if (face_font)
9621 if (line_start_x < face_font->space_width)
9622 line_start_x
9623 += it->tab_width * face_font->space_width;
9626 set_iterator_to_next (it, false);
9629 else
9630 it->continuation_lines_width += it->current_x;
9631 break;
9633 default:
9634 emacs_abort ();
9637 /* Reset/increment for the next run. */
9638 recenter_overlay_lists (current_buffer, IT_CHARPOS (*it));
9639 it->current_x = line_start_x;
9640 line_start_x = 0;
9641 it->hpos = 0;
9642 it->line_number_produced_p = false;
9643 it->current_y += it->max_ascent + it->max_descent;
9644 ++it->vpos;
9645 last_height = it->max_ascent + it->max_descent;
9646 it->max_ascent = it->max_descent = 0;
9649 out:
9651 /* On text terminals, we may stop at the end of a line in the middle
9652 of a multi-character glyph. If the glyph itself is continued,
9653 i.e. it is actually displayed on the next line, don't treat this
9654 stopping point as valid; move to the next line instead (unless
9655 that brings us offscreen). */
9656 if (!FRAME_WINDOW_P (it->f)
9657 && op & MOVE_TO_POS
9658 && IT_CHARPOS (*it) == to_charpos
9659 && it->what == IT_CHARACTER
9660 && it->nglyphs > 1
9661 && it->line_wrap == WINDOW_WRAP
9662 && it->current_x == it->last_visible_x - 1
9663 && it->c != '\n'
9664 && it->c != '\t'
9665 && it->w->window_end_valid
9666 && it->vpos < it->w->window_end_vpos)
9668 it->continuation_lines_width += it->current_x;
9669 it->current_x = it->hpos = it->max_ascent = it->max_descent = 0;
9670 it->current_y += it->max_ascent + it->max_descent;
9671 ++it->vpos;
9672 last_height = it->max_ascent + it->max_descent;
9675 if (backup_data)
9676 bidi_unshelve_cache (backup_data, true);
9678 TRACE_MOVE ((stderr, "move_it_to: reached %d\n", reached));
9680 return max_current_x;
9684 /* Move iterator IT backward by a specified y-distance DY, DY >= 0.
9686 If DY > 0, move IT backward at least that many pixels. DY = 0
9687 means move IT backward to the preceding line start or BEGV. This
9688 function may move over more than DY pixels if IT->current_y - DY
9689 ends up in the middle of a line; in this case IT->current_y will be
9690 set to the top of the line moved to. */
9692 void
9693 move_it_vertically_backward (struct it *it, int dy)
9695 int nlines, h;
9696 struct it it2, it3;
9697 void *it2data = NULL, *it3data = NULL;
9698 ptrdiff_t start_pos;
9699 int nchars_per_row
9700 = (it->last_visible_x - it->first_visible_x) / FRAME_COLUMN_WIDTH (it->f);
9701 ptrdiff_t pos_limit;
9703 move_further_back:
9704 eassert (dy >= 0);
9706 start_pos = IT_CHARPOS (*it);
9708 /* Estimate how many newlines we must move back. */
9709 nlines = max (1, dy / default_line_pixel_height (it->w));
9710 if (it->line_wrap == TRUNCATE || nchars_per_row == 0)
9711 pos_limit = BEGV;
9712 else
9713 pos_limit = max (start_pos - nlines * nchars_per_row, BEGV);
9715 /* Set the iterator's position that many lines back. But don't go
9716 back more than NLINES full screen lines -- this wins a day with
9717 buffers which have very long lines. */
9718 while (nlines-- && IT_CHARPOS (*it) > pos_limit)
9719 back_to_previous_visible_line_start (it);
9721 /* Reseat the iterator here. When moving backward, we don't want
9722 reseat to skip forward over invisible text, set up the iterator
9723 to deliver from overlay strings at the new position etc. So,
9724 use reseat_1 here. */
9725 reseat_1 (it, it->current.pos, true);
9727 /* We are now surely at a line start. */
9728 it->current_x = it->hpos = 0; /* FIXME: this is incorrect when bidi
9729 reordering is in effect. */
9730 it->continuation_lines_width = 0;
9732 /* Move forward and see what y-distance we moved. First move to the
9733 start of the next line so that we get its height. We need this
9734 height to be able to tell whether we reached the specified
9735 y-distance. */
9736 SAVE_IT (it2, *it, it2data);
9737 it2.max_ascent = it2.max_descent = 0;
9740 move_it_to (&it2, start_pos, -1, -1, it2.vpos + 1,
9741 MOVE_TO_POS | MOVE_TO_VPOS);
9743 while (!(IT_POS_VALID_AFTER_MOVE_P (&it2)
9744 /* If we are in a display string which starts at START_POS,
9745 and that display string includes a newline, and we are
9746 right after that newline (i.e. at the beginning of a
9747 display line), exit the loop, because otherwise we will
9748 infloop, since move_it_to will see that it is already at
9749 START_POS and will not move. */
9750 || (it2.method == GET_FROM_STRING
9751 && IT_CHARPOS (it2) == start_pos
9752 && SREF (it2.string, IT_STRING_BYTEPOS (it2) - 1) == '\n')));
9753 eassert (IT_CHARPOS (*it) >= BEGV);
9754 SAVE_IT (it3, it2, it3data);
9756 move_it_to (&it2, start_pos, -1, -1, -1, MOVE_TO_POS);
9757 eassert (IT_CHARPOS (*it) >= BEGV);
9758 /* H is the actual vertical distance from the position in *IT
9759 and the starting position. */
9760 h = it2.current_y - it->current_y;
9761 /* NLINES is the distance in number of lines. */
9762 nlines = it2.vpos - it->vpos;
9764 /* Correct IT's y and vpos position
9765 so that they are relative to the starting point. */
9766 it->vpos -= nlines;
9767 it->current_y -= h;
9769 if (dy == 0)
9771 /* DY == 0 means move to the start of the screen line. The
9772 value of nlines is > 0 if continuation lines were involved,
9773 or if the original IT position was at start of a line. */
9774 RESTORE_IT (it, it, it2data);
9775 if (nlines > 0)
9776 move_it_by_lines (it, nlines);
9777 /* The above code moves us to some position NLINES down,
9778 usually to its first glyph (leftmost in an L2R line), but
9779 that's not necessarily the start of the line, under bidi
9780 reordering. We want to get to the character position
9781 that is immediately after the newline of the previous
9782 line. */
9783 if (it->bidi_p
9784 && !it->continuation_lines_width
9785 && !STRINGP (it->string)
9786 && IT_CHARPOS (*it) > BEGV
9787 && FETCH_BYTE (IT_BYTEPOS (*it) - 1) != '\n')
9789 ptrdiff_t cp = IT_CHARPOS (*it), bp = IT_BYTEPOS (*it);
9791 DEC_BOTH (cp, bp);
9792 cp = find_newline_no_quit (cp, bp, -1, NULL);
9793 move_it_to (it, cp, -1, -1, -1, MOVE_TO_POS);
9795 bidi_unshelve_cache (it3data, true);
9797 else
9799 /* The y-position we try to reach, relative to *IT.
9800 Note that H has been subtracted in front of the if-statement. */
9801 int target_y = it->current_y + h - dy;
9802 int y0 = it3.current_y;
9803 int y1;
9804 int line_height;
9806 RESTORE_IT (&it3, &it3, it3data);
9807 y1 = line_bottom_y (&it3);
9808 line_height = y1 - y0;
9809 RESTORE_IT (it, it, it2data);
9810 /* If we did not reach target_y, try to move further backward if
9811 we can. If we moved too far backward, try to move forward. */
9812 if (target_y < it->current_y
9813 /* This is heuristic. In a window that's 3 lines high, with
9814 a line height of 13 pixels each, recentering with point
9815 on the bottom line will try to move -39/2 = 19 pixels
9816 backward. Try to avoid moving into the first line. */
9817 && (it->current_y - target_y
9818 > min (window_box_height (it->w), line_height * 2 / 3))
9819 && IT_CHARPOS (*it) > BEGV)
9821 TRACE_MOVE ((stderr, " not far enough -> move_vert %d\n",
9822 target_y - it->current_y));
9823 dy = it->current_y - target_y;
9824 goto move_further_back;
9826 else if (target_y >= it->current_y + line_height
9827 && IT_CHARPOS (*it) < ZV)
9829 /* Should move forward by at least one line, maybe more.
9831 Note: Calling move_it_by_lines can be expensive on
9832 terminal frames, where compute_motion is used (via
9833 vmotion) to do the job, when there are very long lines
9834 and truncate-lines is nil. That's the reason for
9835 treating terminal frames specially here. */
9837 if (!FRAME_WINDOW_P (it->f))
9838 move_it_vertically (it, target_y - it->current_y);
9839 else
9843 move_it_by_lines (it, 1);
9845 while (target_y >= line_bottom_y (it) && IT_CHARPOS (*it) < ZV);
9852 /* Move IT by a specified amount of pixel lines DY. DY negative means
9853 move backwards. DY = 0 means move to start of screen line. At the
9854 end, IT will be on the start of a screen line. */
9856 void
9857 move_it_vertically (struct it *it, int dy)
9859 if (dy <= 0)
9860 move_it_vertically_backward (it, -dy);
9861 else
9863 TRACE_MOVE ((stderr, "move_it_v: from %d, %d\n", IT_CHARPOS (*it), dy));
9864 move_it_to (it, ZV, -1, it->current_y + dy, -1,
9865 MOVE_TO_POS | MOVE_TO_Y);
9866 TRACE_MOVE ((stderr, "move_it_v: to %d\n", IT_CHARPOS (*it)));
9868 /* If buffer ends in ZV without a newline, move to the start of
9869 the line to satisfy the post-condition. */
9870 if (IT_CHARPOS (*it) == ZV
9871 && ZV > BEGV
9872 && FETCH_BYTE (IT_BYTEPOS (*it) - 1) != '\n')
9873 move_it_by_lines (it, 0);
9878 /* Move iterator IT past the end of the text line it is in. */
9880 void
9881 move_it_past_eol (struct it *it)
9883 enum move_it_result rc;
9885 rc = move_it_in_display_line_to (it, Z, 0, MOVE_TO_POS);
9886 if (rc == MOVE_NEWLINE_OR_CR)
9887 set_iterator_to_next (it, false);
9891 /* Move IT by a specified number DVPOS of screen lines down. DVPOS
9892 negative means move up. DVPOS == 0 means move to the start of the
9893 screen line.
9895 Optimization idea: If we would know that IT->f doesn't use
9896 a face with proportional font, we could be faster for
9897 truncate-lines nil. */
9899 void
9900 move_it_by_lines (struct it *it, ptrdiff_t dvpos)
9903 /* The commented-out optimization uses vmotion on terminals. This
9904 gives bad results, because elements like it->what, on which
9905 callers such as pos_visible_p rely, aren't updated. */
9906 /* struct position pos;
9907 if (!FRAME_WINDOW_P (it->f))
9909 struct text_pos textpos;
9911 pos = *vmotion (IT_CHARPOS (*it), dvpos, it->w);
9912 SET_TEXT_POS (textpos, pos.bufpos, pos.bytepos);
9913 reseat (it, textpos, true);
9914 it->vpos += pos.vpos;
9915 it->current_y += pos.vpos;
9917 else */
9919 if (dvpos == 0)
9921 /* DVPOS == 0 means move to the start of the screen line. */
9922 move_it_vertically_backward (it, 0);
9923 /* Let next call to line_bottom_y calculate real line height. */
9924 last_height = 0;
9926 else if (dvpos > 0)
9928 move_it_to (it, -1, -1, -1, it->vpos + dvpos, MOVE_TO_VPOS);
9929 if (!IT_POS_VALID_AFTER_MOVE_P (it))
9931 /* Only move to the next buffer position if we ended up in a
9932 string from display property, not in an overlay string
9933 (before-string or after-string). That is because the
9934 latter don't conceal the underlying buffer position, so
9935 we can ask to move the iterator to the exact position we
9936 are interested in. Note that, even if we are already at
9937 IT_CHARPOS (*it), the call below is not a no-op, as it
9938 will detect that we are at the end of the string, pop the
9939 iterator, and compute it->current_x and it->hpos
9940 correctly. */
9941 move_it_to (it, IT_CHARPOS (*it) + it->string_from_display_prop_p,
9942 -1, -1, -1, MOVE_TO_POS);
9945 else
9947 struct it it2;
9948 void *it2data = NULL;
9949 ptrdiff_t start_charpos, i;
9950 int nchars_per_row
9951 = (it->last_visible_x - it->first_visible_x) / FRAME_COLUMN_WIDTH (it->f);
9952 bool hit_pos_limit = false;
9953 ptrdiff_t pos_limit;
9955 /* Start at the beginning of the screen line containing IT's
9956 position. This may actually move vertically backwards,
9957 in case of overlays, so adjust dvpos accordingly. */
9958 dvpos += it->vpos;
9959 move_it_vertically_backward (it, 0);
9960 dvpos -= it->vpos;
9962 /* Go back -DVPOS buffer lines, but no farther than -DVPOS full
9963 screen lines, and reseat the iterator there. */
9964 start_charpos = IT_CHARPOS (*it);
9965 if (it->line_wrap == TRUNCATE || nchars_per_row == 0)
9966 pos_limit = BEGV;
9967 else
9968 pos_limit = max (start_charpos + dvpos * nchars_per_row, BEGV);
9970 for (i = -dvpos; i > 0 && IT_CHARPOS (*it) > pos_limit; --i)
9971 back_to_previous_visible_line_start (it);
9972 if (i > 0 && IT_CHARPOS (*it) <= pos_limit)
9973 hit_pos_limit = true;
9974 reseat (it, it->current.pos, true);
9976 /* Move further back if we end up in a string or an image. */
9977 while (!IT_POS_VALID_AFTER_MOVE_P (it))
9979 /* First try to move to start of display line. */
9980 dvpos += it->vpos;
9981 move_it_vertically_backward (it, 0);
9982 dvpos -= it->vpos;
9983 if (IT_POS_VALID_AFTER_MOVE_P (it))
9984 break;
9985 /* If start of line is still in string or image,
9986 move further back. */
9987 back_to_previous_visible_line_start (it);
9988 reseat (it, it->current.pos, true);
9989 dvpos--;
9992 it->current_x = it->hpos = 0;
9994 /* Above call may have moved too far if continuation lines
9995 are involved. Scan forward and see if it did. */
9996 SAVE_IT (it2, *it, it2data);
9997 it2.vpos = it2.current_y = 0;
9998 move_it_to (&it2, start_charpos, -1, -1, -1, MOVE_TO_POS);
9999 it->vpos -= it2.vpos;
10000 it->current_y -= it2.current_y;
10001 it->current_x = it->hpos = 0;
10003 /* If we moved too far back, move IT some lines forward. */
10004 if (it2.vpos > -dvpos)
10006 int delta = it2.vpos + dvpos;
10008 RESTORE_IT (&it2, &it2, it2data);
10009 SAVE_IT (it2, *it, it2data);
10010 move_it_to (it, -1, -1, -1, it->vpos + delta, MOVE_TO_VPOS);
10011 /* Move back again if we got too far ahead. */
10012 if (IT_CHARPOS (*it) >= start_charpos)
10013 RESTORE_IT (it, &it2, it2data);
10014 else
10015 bidi_unshelve_cache (it2data, true);
10017 else if (hit_pos_limit && pos_limit > BEGV
10018 && dvpos < 0 && it2.vpos < -dvpos)
10020 /* If we hit the limit, but still didn't make it far enough
10021 back, that means there's a display string with a newline
10022 covering a large chunk of text, and that caused
10023 back_to_previous_visible_line_start try to go too far.
10024 Punish those who commit such atrocities by going back
10025 until we've reached DVPOS, after lifting the limit, which
10026 could make it slow for very long lines. "If it hurts,
10027 don't do that!" */
10028 dvpos += it2.vpos;
10029 RESTORE_IT (it, it, it2data);
10030 for (i = -dvpos; i > 0; --i)
10032 back_to_previous_visible_line_start (it);
10033 it->vpos--;
10035 reseat_1 (it, it->current.pos, true);
10037 else
10038 RESTORE_IT (it, it, it2data);
10043 partial_line_height (struct it *it_origin)
10045 int partial_height;
10046 void *it_data = NULL;
10047 struct it it;
10048 SAVE_IT (it, *it_origin, it_data);
10049 move_it_to (&it, ZV, -1, it.last_visible_y, -1,
10050 MOVE_TO_POS | MOVE_TO_Y);
10051 if (it.what == IT_EOB)
10053 int vis_height = it.last_visible_y - it.current_y;
10054 int height = it.ascent + it.descent;
10055 partial_height = (vis_height < height) ? vis_height : 0;
10057 else
10059 int last_line_y = it.current_y;
10060 move_it_by_lines (&it, 1);
10061 partial_height = (it.current_y > it.last_visible_y)
10062 ? it.last_visible_y - last_line_y : 0;
10064 RESTORE_IT (&it, &it, it_data);
10065 return partial_height;
10068 /* Return true if IT points into the middle of a display vector. */
10070 bool
10071 in_display_vector_p (struct it *it)
10073 return (it->method == GET_FROM_DISPLAY_VECTOR
10074 && it->current.dpvec_index > 0
10075 && it->dpvec + it->current.dpvec_index != it->dpend);
10078 DEFUN ("window-text-pixel-size", Fwindow_text_pixel_size, Swindow_text_pixel_size, 0, 6, 0,
10079 doc: /* Return the size of the text of WINDOW's buffer in pixels.
10080 WINDOW must be a live window and defaults to the selected one. The
10081 return value is a cons of the maximum pixel-width of any text line and
10082 the maximum pixel-height of all text lines.
10084 The optional argument FROM, if non-nil, specifies the first text
10085 position and defaults to the minimum accessible position of the buffer.
10086 If FROM is t, use the minimum accessible position that starts a
10087 non-empty line. TO, if non-nil, specifies the last text position and
10088 defaults to the maximum accessible position of the buffer. If TO is t,
10089 use the maximum accessible position that ends a non-empty line.
10091 The optional argument X-LIMIT, if non-nil, specifies the maximum text
10092 width that can be returned. X-LIMIT nil or omitted, means to use the
10093 pixel-width of WINDOW's body; use this if you want to know how high
10094 WINDOW should be become in order to fit all of its buffer's text with
10095 the width of WINDOW unaltered. Use the maximum width WINDOW may assume
10096 if you intend to change WINDOW's width. In any case, text whose
10097 x-coordinate is beyond X-LIMIT is ignored. Since calculating the width
10098 of long lines can take some time, it's always a good idea to make this
10099 argument as small as possible; in particular, if the buffer contains
10100 long lines that shall be truncated anyway.
10102 The optional argument Y-LIMIT, if non-nil, specifies the maximum text
10103 height (excluding the height of the mode- or header-line, if any) that
10104 can be returned. Text lines whose y-coordinate is beyond Y-LIMIT are
10105 ignored. Since calculating the text height of a large buffer can take
10106 some time, it makes sense to specify this argument if the size of the
10107 buffer is large or unknown.
10109 Optional argument MODE-AND-HEADER-LINE nil or omitted means do not
10110 include the height of the mode- or header-line of WINDOW in the return
10111 value. If it is either the symbol `mode-line' or `header-line', include
10112 only the height of that line, if present, in the return value. If t,
10113 include the height of both, if present, in the return value. */)
10114 (Lisp_Object window, Lisp_Object from, Lisp_Object to, Lisp_Object x_limit,
10115 Lisp_Object y_limit, Lisp_Object mode_and_header_line)
10117 struct window *w = decode_live_window (window);
10118 Lisp_Object buffer = w->contents;
10119 struct buffer *b;
10120 struct it it;
10121 struct buffer *old_b = NULL;
10122 ptrdiff_t start, end, pos;
10123 struct text_pos startp;
10124 void *itdata = NULL;
10125 int c, max_x = 0, max_y = 0, x = 0, y = 0;
10127 CHECK_BUFFER (buffer);
10128 b = XBUFFER (buffer);
10130 if (b != current_buffer)
10132 old_b = current_buffer;
10133 set_buffer_internal (b);
10136 if (NILP (from))
10137 start = BEGV;
10138 else if (EQ (from, Qt))
10140 start = pos = BEGV;
10141 while ((pos++ < ZV) && (c = FETCH_CHAR (pos))
10142 && (c == ' ' || c == '\t' || c == '\n' || c == '\r'))
10143 start = pos;
10144 while ((pos-- > BEGV) && (c = FETCH_CHAR (pos)) && (c == ' ' || c == '\t'))
10145 start = pos;
10147 else
10149 CHECK_NUMBER_COERCE_MARKER (from);
10150 start = min (max (XINT (from), BEGV), ZV);
10153 if (NILP (to))
10154 end = ZV;
10155 else if (EQ (to, Qt))
10157 end = pos = ZV;
10158 while ((pos-- > BEGV) && (c = FETCH_CHAR (pos))
10159 && (c == ' ' || c == '\t' || c == '\n' || c == '\r'))
10160 end = pos;
10161 while ((pos++ < ZV) && (c = FETCH_CHAR (pos)) && (c == ' ' || c == '\t'))
10162 end = pos;
10164 else
10166 CHECK_NUMBER_COERCE_MARKER (to);
10167 end = max (start, min (XINT (to), ZV));
10170 if (!NILP (x_limit) && RANGED_INTEGERP (0, x_limit, INT_MAX))
10171 max_x = XINT (x_limit);
10173 if (NILP (y_limit))
10174 max_y = INT_MAX;
10175 else if (RANGED_INTEGERP (0, y_limit, INT_MAX))
10176 max_y = XINT (y_limit);
10178 itdata = bidi_shelve_cache ();
10179 SET_TEXT_POS (startp, start, CHAR_TO_BYTE (start));
10180 start_display (&it, w, startp);
10181 /* It makes no sense to measure dimensions of region of text that
10182 crosses the point where bidi reordering changes scan direction.
10183 By using unidirectional movement here we at least support the use
10184 case of measuring regions of text that have a uniformly R2L
10185 directionality, and regions that begin and end in text of the
10186 same directionality. */
10187 it.bidi_p = false;
10189 int move_op = MOVE_TO_POS | MOVE_TO_Y;
10190 int to_x = -1;
10191 if (!NILP (x_limit))
10193 it.last_visible_x = max_x;
10194 /* Actually, we never want move_it_to stop at to_x. But to make
10195 sure that move_it_in_display_line_to always moves far enough,
10196 we set to_x to INT_MAX and specify MOVE_TO_X. */
10197 move_op |= MOVE_TO_X;
10198 to_x = INT_MAX;
10201 void *it2data = NULL;
10202 struct it it2;
10203 SAVE_IT (it2, it, it2data);
10205 x = move_it_to (&it, end, to_x, max_y, -1, move_op);
10207 /* We could have a display property at END, in which case asking
10208 move_it_to to stop at END will overshoot and stop at position
10209 after END. So we try again, stopping before END, and account for
10210 the width of the last buffer position manually. */
10211 if (IT_CHARPOS (it) > end)
10213 end--;
10214 RESTORE_IT (&it, &it2, it2data);
10215 x = move_it_to (&it, end, to_x, max_y, -1, move_op);
10216 /* Add the width of the thing at TO, but only if we didn't
10217 overshoot it; if we did, it is already accounted for. Also,
10218 account for the height of the thing at TO. */
10219 if (IT_CHARPOS (it) == end)
10221 x += it.pixel_width;
10222 it.max_ascent = max (it.max_ascent, it.ascent);
10223 it.max_descent = max (it.max_descent, it.descent);
10226 if (!NILP (x_limit))
10228 /* Don't return more than X-LIMIT. */
10229 if (x > max_x)
10230 x = max_x;
10233 /* Subtract height of header-line which was counted automatically by
10234 start_display. */
10235 y = it.current_y + it.max_ascent + it.max_descent
10236 - WINDOW_HEADER_LINE_HEIGHT (w);
10237 /* Don't return more than Y-LIMIT. */
10238 if (y > max_y)
10239 y = max_y;
10241 if (EQ (mode_and_header_line, Qheader_line)
10242 || EQ (mode_and_header_line, Qt))
10243 /* Re-add height of header-line as requested. */
10244 y = y + WINDOW_HEADER_LINE_HEIGHT (w);
10246 if (EQ (mode_and_header_line, Qmode_line)
10247 || EQ (mode_and_header_line, Qt))
10248 /* Add height of mode-line as requested. */
10249 y = y + WINDOW_MODE_LINE_HEIGHT (w);
10251 bidi_unshelve_cache (itdata, false);
10253 if (old_b)
10254 set_buffer_internal (old_b);
10256 return Fcons (make_number (x), make_number (y));
10259 /***********************************************************************
10260 Messages
10261 ***********************************************************************/
10263 /* Return the number of arguments the format string FORMAT needs. */
10265 static ptrdiff_t
10266 format_nargs (char const *format)
10268 ptrdiff_t nargs = 0;
10269 for (char const *p = format; (p = strchr (p, '%')); p++)
10270 if (p[1] == '%')
10271 p++;
10272 else
10273 nargs++;
10274 return nargs;
10277 /* Add a message with format string FORMAT and formatted arguments
10278 to *Messages*. */
10280 void
10281 add_to_log (const char *format, ...)
10283 va_list ap;
10284 va_start (ap, format);
10285 vadd_to_log (format, ap);
10286 va_end (ap);
10289 void
10290 vadd_to_log (char const *format, va_list ap)
10292 ptrdiff_t form_nargs = format_nargs (format);
10293 ptrdiff_t nargs = 1 + form_nargs;
10294 Lisp_Object args[10];
10295 eassert (nargs <= ARRAYELTS (args));
10296 AUTO_STRING (args0, format);
10297 args[0] = args0;
10298 for (ptrdiff_t i = 1; i <= nargs; i++)
10299 args[i] = va_arg (ap, Lisp_Object);
10300 Lisp_Object msg = Qnil;
10301 msg = Fformat_message (nargs, args);
10303 ptrdiff_t len = SBYTES (msg) + 1;
10304 USE_SAFE_ALLOCA;
10305 char *buffer = SAFE_ALLOCA (len);
10306 memcpy (buffer, SDATA (msg), len);
10308 message_dolog (buffer, len - 1, true, STRING_MULTIBYTE (msg));
10309 SAFE_FREE ();
10313 /* Output a newline in the *Messages* buffer if "needs" one. */
10315 void
10316 message_log_maybe_newline (void)
10318 if (message_log_need_newline)
10319 message_dolog ("", 0, true, false);
10323 /* Add a string M of length NBYTES to the message log, optionally
10324 terminated with a newline when NLFLAG is true. MULTIBYTE, if
10325 true, means interpret the contents of M as multibyte. This
10326 function calls low-level routines in order to bypass text property
10327 hooks, etc. which might not be safe to run.
10329 This may GC (insert may run before/after change hooks),
10330 so the buffer M must NOT point to a Lisp string. */
10332 void
10333 message_dolog (const char *m, ptrdiff_t nbytes, bool nlflag, bool multibyte)
10335 const unsigned char *msg = (const unsigned char *) m;
10337 if (!NILP (Vmemory_full))
10338 return;
10340 if (!NILP (Vmessage_log_max))
10342 struct buffer *oldbuf;
10343 Lisp_Object oldpoint, oldbegv, oldzv;
10344 int old_windows_or_buffers_changed = windows_or_buffers_changed;
10345 ptrdiff_t point_at_end = 0;
10346 ptrdiff_t zv_at_end = 0;
10347 Lisp_Object old_deactivate_mark;
10349 old_deactivate_mark = Vdeactivate_mark;
10350 oldbuf = current_buffer;
10352 /* Ensure the Messages buffer exists, and switch to it.
10353 If we created it, set the major-mode. */
10354 bool newbuffer = NILP (Fget_buffer (Vmessages_buffer_name));
10355 Fset_buffer (Fget_buffer_create (Vmessages_buffer_name));
10356 if (newbuffer
10357 && !NILP (Ffboundp (intern ("messages-buffer-mode"))))
10358 call0 (intern ("messages-buffer-mode"));
10360 bset_undo_list (current_buffer, Qt);
10361 bset_cache_long_scans (current_buffer, Qnil);
10363 oldpoint = message_dolog_marker1;
10364 set_marker_restricted_both (oldpoint, Qnil, PT, PT_BYTE);
10365 oldbegv = message_dolog_marker2;
10366 set_marker_restricted_both (oldbegv, Qnil, BEGV, BEGV_BYTE);
10367 oldzv = message_dolog_marker3;
10368 set_marker_restricted_both (oldzv, Qnil, ZV, ZV_BYTE);
10370 if (PT == Z)
10371 point_at_end = 1;
10372 if (ZV == Z)
10373 zv_at_end = 1;
10375 BEGV = BEG;
10376 BEGV_BYTE = BEG_BYTE;
10377 ZV = Z;
10378 ZV_BYTE = Z_BYTE;
10379 TEMP_SET_PT_BOTH (Z, Z_BYTE);
10381 /* Insert the string--maybe converting multibyte to single byte
10382 or vice versa, so that all the text fits the buffer. */
10383 if (multibyte
10384 && NILP (BVAR (current_buffer, enable_multibyte_characters)))
10386 ptrdiff_t i;
10387 int c, char_bytes;
10388 char work[1];
10390 /* Convert a multibyte string to single-byte
10391 for the *Message* buffer. */
10392 for (i = 0; i < nbytes; i += char_bytes)
10394 c = string_char_and_length (msg + i, &char_bytes);
10395 work[0] = CHAR_TO_BYTE8 (c);
10396 insert_1_both (work, 1, 1, true, false, false);
10399 else if (! multibyte
10400 && ! NILP (BVAR (current_buffer, enable_multibyte_characters)))
10402 ptrdiff_t i;
10403 int c, char_bytes;
10404 unsigned char str[MAX_MULTIBYTE_LENGTH];
10405 /* Convert a single-byte string to multibyte
10406 for the *Message* buffer. */
10407 for (i = 0; i < nbytes; i++)
10409 c = msg[i];
10410 MAKE_CHAR_MULTIBYTE (c);
10411 char_bytes = CHAR_STRING (c, str);
10412 insert_1_both ((char *) str, 1, char_bytes, true, false, false);
10415 else if (nbytes)
10416 insert_1_both (m, chars_in_text (msg, nbytes), nbytes,
10417 true, false, false);
10419 if (nlflag)
10421 ptrdiff_t this_bol, this_bol_byte, prev_bol, prev_bol_byte;
10422 printmax_t dups;
10424 insert_1_both ("\n", 1, 1, true, false, false);
10426 scan_newline (Z, Z_BYTE, BEG, BEG_BYTE, -2, false);
10427 this_bol = PT;
10428 this_bol_byte = PT_BYTE;
10430 /* See if this line duplicates the previous one.
10431 If so, combine duplicates. */
10432 if (this_bol > BEG)
10434 scan_newline (PT, PT_BYTE, BEG, BEG_BYTE, -2, false);
10435 prev_bol = PT;
10436 prev_bol_byte = PT_BYTE;
10438 dups = message_log_check_duplicate (prev_bol_byte,
10439 this_bol_byte);
10440 if (dups)
10442 del_range_both (prev_bol, prev_bol_byte,
10443 this_bol, this_bol_byte, false);
10444 if (dups > 1)
10446 char dupstr[sizeof " [ times]"
10447 + INT_STRLEN_BOUND (printmax_t)];
10449 /* If you change this format, don't forget to also
10450 change message_log_check_duplicate. */
10451 int duplen = sprintf (dupstr, " [%"pMd" times]", dups);
10452 TEMP_SET_PT_BOTH (Z - 1, Z_BYTE - 1);
10453 insert_1_both (dupstr, duplen, duplen,
10454 true, false, true);
10459 /* If we have more than the desired maximum number of lines
10460 in the *Messages* buffer now, delete the oldest ones.
10461 This is safe because we don't have undo in this buffer. */
10463 if (NATNUMP (Vmessage_log_max))
10465 scan_newline (Z, Z_BYTE, BEG, BEG_BYTE,
10466 -XFASTINT (Vmessage_log_max) - 1, false);
10467 del_range_both (BEG, BEG_BYTE, PT, PT_BYTE, false);
10470 BEGV = marker_position (oldbegv);
10471 BEGV_BYTE = marker_byte_position (oldbegv);
10473 if (zv_at_end)
10475 ZV = Z;
10476 ZV_BYTE = Z_BYTE;
10478 else
10480 ZV = marker_position (oldzv);
10481 ZV_BYTE = marker_byte_position (oldzv);
10484 if (point_at_end)
10485 TEMP_SET_PT_BOTH (Z, Z_BYTE);
10486 else
10487 /* We can't do Fgoto_char (oldpoint) because it will run some
10488 Lisp code. */
10489 TEMP_SET_PT_BOTH (marker_position (oldpoint),
10490 marker_byte_position (oldpoint));
10492 unchain_marker (XMARKER (oldpoint));
10493 unchain_marker (XMARKER (oldbegv));
10494 unchain_marker (XMARKER (oldzv));
10496 /* We called insert_1_both above with its 5th argument (PREPARE)
10497 false, which prevents insert_1_both from calling
10498 prepare_to_modify_buffer, which in turns prevents us from
10499 incrementing windows_or_buffers_changed even if *Messages* is
10500 shown in some window. So we must manually set
10501 windows_or_buffers_changed here to make up for that. */
10502 windows_or_buffers_changed = old_windows_or_buffers_changed;
10503 bset_redisplay (current_buffer);
10505 set_buffer_internal (oldbuf);
10507 message_log_need_newline = !nlflag;
10508 Vdeactivate_mark = old_deactivate_mark;
10513 /* We are at the end of the buffer after just having inserted a newline.
10514 (Note: We depend on the fact we won't be crossing the gap.)
10515 Check to see if the most recent message looks a lot like the previous one.
10516 Return 0 if different, 1 if the new one should just replace it, or a
10517 value N > 1 if we should also append " [N times]". */
10519 static intmax_t
10520 message_log_check_duplicate (ptrdiff_t prev_bol_byte, ptrdiff_t this_bol_byte)
10522 ptrdiff_t i;
10523 ptrdiff_t len = Z_BYTE - 1 - this_bol_byte;
10524 bool seen_dots = false;
10525 unsigned char *p1 = BUF_BYTE_ADDRESS (current_buffer, prev_bol_byte);
10526 unsigned char *p2 = BUF_BYTE_ADDRESS (current_buffer, this_bol_byte);
10528 for (i = 0; i < len; i++)
10530 if (i >= 3 && p1[i - 3] == '.' && p1[i - 2] == '.' && p1[i - 1] == '.')
10531 seen_dots = true;
10532 if (p1[i] != p2[i])
10533 return seen_dots;
10535 p1 += len;
10536 if (*p1 == '\n')
10537 return 2;
10538 if (*p1++ == ' ' && *p1++ == '[')
10540 char *pend;
10541 intmax_t n = strtoimax ((char *) p1, &pend, 10);
10542 if (0 < n && n < INTMAX_MAX && strncmp (pend, " times]\n", 8) == 0)
10543 return n + 1;
10545 return 0;
10549 /* Display an echo area message M with a specified length of NBYTES
10550 bytes. The string may include null characters. If M is not a
10551 string, clear out any existing message, and let the mini-buffer
10552 text show through.
10554 This function cancels echoing. */
10556 void
10557 message3 (Lisp_Object m)
10559 clear_message (true, true);
10560 cancel_echoing ();
10562 /* First flush out any partial line written with print. */
10563 message_log_maybe_newline ();
10564 if (STRINGP (m))
10566 ptrdiff_t nbytes = SBYTES (m);
10567 bool multibyte = STRING_MULTIBYTE (m);
10568 char *buffer;
10569 USE_SAFE_ALLOCA;
10570 SAFE_ALLOCA_STRING (buffer, m);
10571 message_dolog (buffer, nbytes, true, multibyte);
10572 SAFE_FREE ();
10574 if (! inhibit_message)
10575 message3_nolog (m);
10578 /* Log the message M to stderr. Log an empty line if M is not a string. */
10580 static void
10581 message_to_stderr (Lisp_Object m)
10583 if (noninteractive_need_newline)
10585 noninteractive_need_newline = false;
10586 fputc ('\n', stderr);
10588 if (STRINGP (m))
10590 Lisp_Object coding_system = Vlocale_coding_system;
10591 Lisp_Object s;
10593 if (!NILP (Vcoding_system_for_write))
10594 coding_system = Vcoding_system_for_write;
10595 if (!NILP (coding_system))
10596 s = code_convert_string_norecord (m, coding_system, true);
10597 else
10598 s = m;
10600 fwrite (SDATA (s), SBYTES (s), 1, stderr);
10602 if (!cursor_in_echo_area)
10603 fputc ('\n', stderr);
10604 fflush (stderr);
10607 /* The non-logging version of message3.
10608 This does not cancel echoing, because it is used for echoing.
10609 Perhaps we need to make a separate function for echoing
10610 and make this cancel echoing. */
10612 void
10613 message3_nolog (Lisp_Object m)
10615 struct frame *sf = SELECTED_FRAME ();
10617 if (FRAME_INITIAL_P (sf))
10618 message_to_stderr (m);
10619 /* Error messages get reported properly by cmd_error, so this must be just an
10620 informative message; if the frame hasn't really been initialized yet, just
10621 toss it. */
10622 else if (INTERACTIVE && sf->glyphs_initialized_p)
10624 /* Get the frame containing the mini-buffer
10625 that the selected frame is using. */
10626 Lisp_Object mini_window = FRAME_MINIBUF_WINDOW (sf);
10627 Lisp_Object frame = XWINDOW (mini_window)->frame;
10628 struct frame *f = XFRAME (frame);
10630 if (FRAME_VISIBLE_P (sf) && !FRAME_VISIBLE_P (f))
10631 Fmake_frame_visible (frame);
10633 if (STRINGP (m) && SCHARS (m) > 0)
10635 set_message (m);
10636 if (minibuffer_auto_raise)
10637 Fraise_frame (frame);
10638 /* Assume we are not echoing.
10639 (If we are, echo_now will override this.) */
10640 echo_message_buffer = Qnil;
10642 else
10643 clear_message (true, true);
10645 do_pending_window_change (false);
10646 echo_area_display (true);
10647 do_pending_window_change (false);
10648 if (FRAME_TERMINAL (f)->frame_up_to_date_hook)
10649 (*FRAME_TERMINAL (f)->frame_up_to_date_hook) (f);
10654 /* Display a null-terminated echo area message M. If M is 0, clear
10655 out any existing message, and let the mini-buffer text show through.
10657 The buffer M must continue to exist until after the echo area gets
10658 cleared or some other message gets displayed there. Do not pass
10659 text that is stored in a Lisp string. Do not pass text in a buffer
10660 that was alloca'd. */
10662 void
10663 message1 (const char *m)
10665 message3 (m ? build_unibyte_string (m) : Qnil);
10669 /* The non-logging counterpart of message1. */
10671 void
10672 message1_nolog (const char *m)
10674 message3_nolog (m ? build_unibyte_string (m) : Qnil);
10677 /* Display a message M which contains a single %s
10678 which gets replaced with STRING. */
10680 void
10681 message_with_string (const char *m, Lisp_Object string, bool log)
10683 CHECK_STRING (string);
10685 bool need_message;
10686 if (noninteractive)
10687 need_message = !!m;
10688 else if (!INTERACTIVE)
10689 need_message = false;
10690 else
10692 /* The frame whose minibuffer we're going to display the message on.
10693 It may be larger than the selected frame, so we need
10694 to use its buffer, not the selected frame's buffer. */
10695 Lisp_Object mini_window;
10696 struct frame *f, *sf = SELECTED_FRAME ();
10698 /* Get the frame containing the minibuffer
10699 that the selected frame is using. */
10700 mini_window = FRAME_MINIBUF_WINDOW (sf);
10701 f = XFRAME (WINDOW_FRAME (XWINDOW (mini_window)));
10703 /* Error messages get reported properly by cmd_error, so this must be
10704 just an informative message; if the frame hasn't really been
10705 initialized yet, just toss it. */
10706 need_message = f->glyphs_initialized_p;
10709 if (need_message)
10711 AUTO_STRING (fmt, m);
10712 Lisp_Object msg = CALLN (Fformat_message, fmt, string);
10714 if (noninteractive)
10715 message_to_stderr (msg);
10716 else
10718 if (log)
10719 message3 (msg);
10720 else
10721 message3_nolog (msg);
10723 /* Print should start at the beginning of the message
10724 buffer next time. */
10725 message_buf_print = false;
10731 /* Dump an informative message to the minibuf. If M is 0, clear out
10732 any existing message, and let the mini-buffer text show through.
10734 The message must be safe ASCII (because when Emacs is
10735 non-interactive the message is sent straight to stderr without
10736 encoding first) and the format must not contain ` or ' (because
10737 this function does not account for `text-quoting-style'). If your
10738 message and format do not fit into this category, convert your
10739 arguments to Lisp objects and use Fmessage instead. */
10741 static void ATTRIBUTE_FORMAT_PRINTF (1, 0)
10742 vmessage (const char *m, va_list ap)
10744 if (noninteractive)
10746 if (m)
10748 if (noninteractive_need_newline)
10749 putc ('\n', stderr);
10750 noninteractive_need_newline = false;
10751 vfprintf (stderr, m, ap);
10752 if (!cursor_in_echo_area)
10753 fprintf (stderr, "\n");
10754 fflush (stderr);
10757 else if (INTERACTIVE)
10759 /* The frame whose mini-buffer we're going to display the message
10760 on. It may be larger than the selected frame, so we need to
10761 use its buffer, not the selected frame's buffer. */
10762 Lisp_Object mini_window;
10763 struct frame *f, *sf = SELECTED_FRAME ();
10765 /* Get the frame containing the mini-buffer
10766 that the selected frame is using. */
10767 mini_window = FRAME_MINIBUF_WINDOW (sf);
10768 f = XFRAME (WINDOW_FRAME (XWINDOW (mini_window)));
10770 /* Error messages get reported properly by cmd_error, so this must be
10771 just an informative message; if the frame hasn't really been
10772 initialized yet, just toss it. */
10773 if (f->glyphs_initialized_p)
10775 if (m)
10777 ptrdiff_t len;
10778 ptrdiff_t maxsize = FRAME_MESSAGE_BUF_SIZE (f);
10779 USE_SAFE_ALLOCA;
10780 char *message_buf = SAFE_ALLOCA (maxsize + 1);
10782 len = doprnt (message_buf, maxsize, m, 0, ap);
10784 message3 (make_string (message_buf, len));
10785 SAFE_FREE ();
10787 else
10788 message1 (0);
10790 /* Print should start at the beginning of the message
10791 buffer next time. */
10792 message_buf_print = false;
10797 /* See vmessage for restrictions on the text of the message. */
10798 void
10799 message (const char *m, ...)
10801 va_list ap;
10802 va_start (ap, m);
10803 vmessage (m, ap);
10804 va_end (ap);
10808 /* Display the current message in the current mini-buffer. This is
10809 only called from error handlers in process.c, and is not time
10810 critical. */
10812 void
10813 update_echo_area (void)
10815 if (!NILP (echo_area_buffer[0]))
10817 Lisp_Object string;
10818 string = Fcurrent_message ();
10819 message3 (string);
10824 /* Make sure echo area buffers in `echo_buffers' are live.
10825 If they aren't, make new ones. */
10827 static void
10828 ensure_echo_area_buffers (void)
10830 for (int i = 0; i < 2; i++)
10831 if (!BUFFERP (echo_buffer[i])
10832 || !BUFFER_LIVE_P (XBUFFER (echo_buffer[i])))
10834 Lisp_Object old_buffer = echo_buffer[i];
10835 static char const name_fmt[] = " *Echo Area %d*";
10836 char name[sizeof name_fmt + INT_STRLEN_BOUND (int)];
10837 AUTO_STRING_WITH_LEN (lname, name, sprintf (name, name_fmt, i));
10838 echo_buffer[i] = Fget_buffer_create (lname);
10839 bset_truncate_lines (XBUFFER (echo_buffer[i]), Qnil);
10840 /* to force word wrap in echo area -
10841 it was decided to postpone this*/
10842 /* XBUFFER (echo_buffer[i])->word_wrap = Qt; */
10844 for (int j = 0; j < 2; j++)
10845 if (EQ (old_buffer, echo_area_buffer[j]))
10846 echo_area_buffer[j] = echo_buffer[i];
10851 /* Call FN with args A1..A2 with either the current or last displayed
10852 echo_area_buffer as current buffer.
10854 WHICH zero means use the current message buffer
10855 echo_area_buffer[0]. If that is nil, choose a suitable buffer
10856 from echo_buffer[] and clear it.
10858 WHICH > 0 means use echo_area_buffer[1]. If that is nil, choose a
10859 suitable buffer from echo_buffer[] and clear it.
10861 If WHICH < 0, set echo_area_buffer[1] to echo_area_buffer[0], so
10862 that the current message becomes the last displayed one, choose a
10863 suitable buffer for echo_area_buffer[0], and clear it.
10865 Value is what FN returns. */
10867 static bool
10868 with_echo_area_buffer (struct window *w, int which,
10869 bool (*fn) (ptrdiff_t, Lisp_Object),
10870 ptrdiff_t a1, Lisp_Object a2)
10872 Lisp_Object buffer;
10873 bool this_one, the_other, clear_buffer_p, rc;
10874 ptrdiff_t count = SPECPDL_INDEX ();
10876 /* If buffers aren't live, make new ones. */
10877 ensure_echo_area_buffers ();
10879 clear_buffer_p = false;
10881 if (which == 0)
10882 this_one = false, the_other = true;
10883 else if (which > 0)
10884 this_one = true, the_other = false;
10885 else
10887 this_one = false, the_other = true;
10888 clear_buffer_p = true;
10890 /* We need a fresh one in case the current echo buffer equals
10891 the one containing the last displayed echo area message. */
10892 if (!NILP (echo_area_buffer[this_one])
10893 && EQ (echo_area_buffer[this_one], echo_area_buffer[the_other]))
10894 echo_area_buffer[this_one] = Qnil;
10897 /* Choose a suitable buffer from echo_buffer[] if we don't
10898 have one. */
10899 if (NILP (echo_area_buffer[this_one]))
10901 echo_area_buffer[this_one]
10902 = (EQ (echo_area_buffer[the_other], echo_buffer[this_one])
10903 ? echo_buffer[the_other]
10904 : echo_buffer[this_one]);
10905 clear_buffer_p = true;
10908 buffer = echo_area_buffer[this_one];
10910 /* Don't get confused by reusing the buffer used for echoing
10911 for a different purpose. */
10912 if (echo_kboard == NULL && EQ (buffer, echo_message_buffer))
10913 cancel_echoing ();
10915 record_unwind_protect (unwind_with_echo_area_buffer,
10916 with_echo_area_buffer_unwind_data (w));
10918 /* Make the echo area buffer current. Note that for display
10919 purposes, it is not necessary that the displayed window's buffer
10920 == current_buffer, except for text property lookup. So, let's
10921 only set that buffer temporarily here without doing a full
10922 Fset_window_buffer. We must also change w->pointm, though,
10923 because otherwise an assertions in unshow_buffer fails, and Emacs
10924 aborts. */
10925 set_buffer_internal_1 (XBUFFER (buffer));
10926 if (w)
10928 wset_buffer (w, buffer);
10929 set_marker_both (w->pointm, buffer, BEG, BEG_BYTE);
10930 set_marker_both (w->old_pointm, buffer, BEG, BEG_BYTE);
10933 bset_undo_list (current_buffer, Qt);
10934 bset_read_only (current_buffer, Qnil);
10935 specbind (Qinhibit_read_only, Qt);
10936 specbind (Qinhibit_modification_hooks, Qt);
10938 if (clear_buffer_p && Z > BEG)
10939 del_range (BEG, Z);
10941 eassert (BEGV >= BEG);
10942 eassert (ZV <= Z && ZV >= BEGV);
10944 rc = fn (a1, a2);
10946 eassert (BEGV >= BEG);
10947 eassert (ZV <= Z && ZV >= BEGV);
10949 unbind_to (count, Qnil);
10950 return rc;
10954 /* Save state that should be preserved around the call to the function
10955 FN called in with_echo_area_buffer. */
10957 static Lisp_Object
10958 with_echo_area_buffer_unwind_data (struct window *w)
10960 int i = 0;
10961 Lisp_Object vector, tmp;
10963 /* Reduce consing by keeping one vector in
10964 Vwith_echo_area_save_vector. */
10965 vector = Vwith_echo_area_save_vector;
10966 Vwith_echo_area_save_vector = Qnil;
10968 if (NILP (vector))
10969 vector = Fmake_vector (make_number (11), Qnil);
10971 XSETBUFFER (tmp, current_buffer); ASET (vector, i, tmp); ++i;
10972 ASET (vector, i, Vdeactivate_mark); ++i;
10973 ASET (vector, i, make_number (windows_or_buffers_changed)); ++i;
10975 if (w)
10977 XSETWINDOW (tmp, w); ASET (vector, i, tmp); ++i;
10978 ASET (vector, i, w->contents); ++i;
10979 ASET (vector, i, make_number (marker_position (w->pointm))); ++i;
10980 ASET (vector, i, make_number (marker_byte_position (w->pointm))); ++i;
10981 ASET (vector, i, make_number (marker_position (w->old_pointm))); ++i;
10982 ASET (vector, i, make_number (marker_byte_position (w->old_pointm))); ++i;
10983 ASET (vector, i, make_number (marker_position (w->start))); ++i;
10984 ASET (vector, i, make_number (marker_byte_position (w->start))); ++i;
10986 else
10988 int end = i + 8;
10989 for (; i < end; ++i)
10990 ASET (vector, i, Qnil);
10993 eassert (i == ASIZE (vector));
10994 return vector;
10998 /* Restore global state from VECTOR which was created by
10999 with_echo_area_buffer_unwind_data. */
11001 static void
11002 unwind_with_echo_area_buffer (Lisp_Object vector)
11004 set_buffer_internal_1 (XBUFFER (AREF (vector, 0)));
11005 Vdeactivate_mark = AREF (vector, 1);
11006 windows_or_buffers_changed = XFASTINT (AREF (vector, 2));
11008 if (WINDOWP (AREF (vector, 3)))
11010 struct window *w;
11011 Lisp_Object buffer;
11013 w = XWINDOW (AREF (vector, 3));
11014 buffer = AREF (vector, 4);
11016 wset_buffer (w, buffer);
11017 set_marker_both (w->pointm, buffer,
11018 XFASTINT (AREF (vector, 5)),
11019 XFASTINT (AREF (vector, 6)));
11020 set_marker_both (w->old_pointm, buffer,
11021 XFASTINT (AREF (vector, 7)),
11022 XFASTINT (AREF (vector, 8)));
11023 set_marker_both (w->start, buffer,
11024 XFASTINT (AREF (vector, 9)),
11025 XFASTINT (AREF (vector, 10)));
11028 Vwith_echo_area_save_vector = vector;
11032 /* Set up the echo area for use by print functions. MULTIBYTE_P
11033 means we will print multibyte. */
11035 void
11036 setup_echo_area_for_printing (bool multibyte_p)
11038 /* If we can't find an echo area any more, exit. */
11039 if (! FRAME_LIVE_P (XFRAME (selected_frame)))
11040 Fkill_emacs (Qnil);
11042 ensure_echo_area_buffers ();
11044 if (!message_buf_print)
11046 /* A message has been output since the last time we printed.
11047 Choose a fresh echo area buffer. */
11048 if (EQ (echo_area_buffer[1], echo_buffer[0]))
11049 echo_area_buffer[0] = echo_buffer[1];
11050 else
11051 echo_area_buffer[0] = echo_buffer[0];
11053 /* Switch to that buffer and clear it. */
11054 set_buffer_internal (XBUFFER (echo_area_buffer[0]));
11055 bset_truncate_lines (current_buffer, Qnil);
11057 if (Z > BEG)
11059 ptrdiff_t count = SPECPDL_INDEX ();
11060 specbind (Qinhibit_read_only, Qt);
11061 /* Note that undo recording is always disabled. */
11062 del_range (BEG, Z);
11063 unbind_to (count, Qnil);
11065 TEMP_SET_PT_BOTH (BEG, BEG_BYTE);
11067 /* Set up the buffer for the multibyteness we need. */
11068 if (multibyte_p
11069 != !NILP (BVAR (current_buffer, enable_multibyte_characters)))
11070 Fset_buffer_multibyte (multibyte_p ? Qt : Qnil);
11072 /* Raise the frame containing the echo area. */
11073 if (minibuffer_auto_raise)
11075 struct frame *sf = SELECTED_FRAME ();
11076 Lisp_Object mini_window;
11077 mini_window = FRAME_MINIBUF_WINDOW (sf);
11078 Fraise_frame (WINDOW_FRAME (XWINDOW (mini_window)));
11081 message_log_maybe_newline ();
11082 message_buf_print = true;
11084 else
11086 if (NILP (echo_area_buffer[0]))
11088 if (EQ (echo_area_buffer[1], echo_buffer[0]))
11089 echo_area_buffer[0] = echo_buffer[1];
11090 else
11091 echo_area_buffer[0] = echo_buffer[0];
11094 if (current_buffer != XBUFFER (echo_area_buffer[0]))
11096 /* Someone switched buffers between print requests. */
11097 set_buffer_internal (XBUFFER (echo_area_buffer[0]));
11098 bset_truncate_lines (current_buffer, Qnil);
11104 /* Display an echo area message in window W. Value is true if W's
11105 height is changed. If display_last_displayed_message_p,
11106 display the message that was last displayed, otherwise
11107 display the current message. */
11109 static bool
11110 display_echo_area (struct window *w)
11112 bool no_message_p, window_height_changed_p;
11114 /* Temporarily disable garbage collections while displaying the echo
11115 area. This is done because a GC can print a message itself.
11116 That message would modify the echo area buffer's contents while a
11117 redisplay of the buffer is going on, and seriously confuse
11118 redisplay. */
11119 ptrdiff_t count = inhibit_garbage_collection ();
11121 /* If there is no message, we must call display_echo_area_1
11122 nevertheless because it resizes the window. But we will have to
11123 reset the echo_area_buffer in question to nil at the end because
11124 with_echo_area_buffer will sets it to an empty buffer. */
11125 bool i = display_last_displayed_message_p;
11126 /* According to the C99, C11 and C++11 standards, the integral value
11127 of a "bool" is always 0 or 1, so this array access is safe here,
11128 if oddly typed. */
11129 no_message_p = NILP (echo_area_buffer[i]);
11131 window_height_changed_p
11132 = with_echo_area_buffer (w, display_last_displayed_message_p,
11133 display_echo_area_1,
11134 (intptr_t) w, Qnil);
11136 if (no_message_p)
11137 echo_area_buffer[i] = Qnil;
11139 unbind_to (count, Qnil);
11140 return window_height_changed_p;
11144 /* Helper for display_echo_area. Display the current buffer which
11145 contains the current echo area message in window W, a mini-window,
11146 a pointer to which is passed in A1. A2..A4 are currently not used.
11147 Change the height of W so that all of the message is displayed.
11148 Value is true if height of W was changed. */
11150 static bool
11151 display_echo_area_1 (ptrdiff_t a1, Lisp_Object a2)
11153 intptr_t i1 = a1;
11154 struct window *w = (struct window *) i1;
11155 Lisp_Object window;
11156 struct text_pos start;
11158 /* We are about to enter redisplay without going through
11159 redisplay_internal, so we need to forget these faces by hand
11160 here. */
11161 forget_escape_and_glyphless_faces ();
11163 /* Do this before displaying, so that we have a large enough glyph
11164 matrix for the display. If we can't get enough space for the
11165 whole text, display the last N lines. That works by setting w->start. */
11166 bool window_height_changed_p = resize_mini_window (w, false);
11168 /* Use the starting position chosen by resize_mini_window. */
11169 SET_TEXT_POS_FROM_MARKER (start, w->start);
11171 /* Display. */
11172 clear_glyph_matrix (w->desired_matrix);
11173 XSETWINDOW (window, w);
11174 try_window (window, start, 0);
11176 return window_height_changed_p;
11180 /* Resize the echo area window to exactly the size needed for the
11181 currently displayed message, if there is one. If a mini-buffer
11182 is active, don't shrink it. */
11184 void
11185 resize_echo_area_exactly (void)
11187 if (BUFFERP (echo_area_buffer[0])
11188 && WINDOWP (echo_area_window))
11190 struct window *w = XWINDOW (echo_area_window);
11191 Lisp_Object resize_exactly = (minibuf_level == 0 ? Qt : Qnil);
11192 bool resized_p = with_echo_area_buffer (w, 0, resize_mini_window_1,
11193 (intptr_t) w, resize_exactly);
11194 if (resized_p)
11196 windows_or_buffers_changed = 42;
11197 update_mode_lines = 30;
11198 redisplay_internal ();
11204 /* Callback function for with_echo_area_buffer, when used from
11205 resize_echo_area_exactly. A1 contains a pointer to the window to
11206 resize, EXACTLY non-nil means resize the mini-window exactly to the
11207 size of the text displayed. A3 and A4 are not used. Value is what
11208 resize_mini_window returns. */
11210 static bool
11211 resize_mini_window_1 (ptrdiff_t a1, Lisp_Object exactly)
11213 intptr_t i1 = a1;
11214 return resize_mini_window ((struct window *) i1, !NILP (exactly));
11218 /* Resize mini-window W to fit the size of its contents. EXACT_P
11219 means size the window exactly to the size needed. Otherwise, it's
11220 only enlarged until W's buffer is empty.
11222 Set W->start to the right place to begin display. If the whole
11223 contents fit, start at the beginning. Otherwise, start so as
11224 to make the end of the contents appear. This is particularly
11225 important for y-or-n-p, but seems desirable generally.
11227 Value is true if the window height has been changed. */
11229 bool
11230 resize_mini_window (struct window *w, bool exact_p)
11232 struct frame *f = XFRAME (w->frame);
11233 bool window_height_changed_p = false;
11235 eassert (MINI_WINDOW_P (w));
11237 /* By default, start display at the beginning. */
11238 set_marker_both (w->start, w->contents,
11239 BUF_BEGV (XBUFFER (w->contents)),
11240 BUF_BEGV_BYTE (XBUFFER (w->contents)));
11242 /* Don't resize windows while redisplaying a window; it would
11243 confuse redisplay functions when the size of the window they are
11244 displaying changes from under them. Such a resizing can happen,
11245 for instance, when which-func prints a long message while
11246 we are running fontification-functions. We're running these
11247 functions with safe_call which binds inhibit-redisplay to t. */
11248 if (!NILP (Vinhibit_redisplay))
11249 return false;
11251 /* Nil means don't try to resize. */
11252 if (NILP (Vresize_mini_windows)
11253 || (FRAME_X_P (f) && FRAME_X_OUTPUT (f) == NULL))
11254 return false;
11256 if (!FRAME_MINIBUF_ONLY_P (f))
11258 struct it it;
11259 int total_height = (WINDOW_PIXEL_HEIGHT (XWINDOW (FRAME_ROOT_WINDOW (f)))
11260 + WINDOW_PIXEL_HEIGHT (w));
11261 int unit = FRAME_LINE_HEIGHT (f);
11262 int height, max_height;
11263 struct text_pos start;
11264 struct buffer *old_current_buffer = NULL;
11266 if (current_buffer != XBUFFER (w->contents))
11268 old_current_buffer = current_buffer;
11269 set_buffer_internal (XBUFFER (w->contents));
11272 init_iterator (&it, w, BEGV, BEGV_BYTE, NULL, DEFAULT_FACE_ID);
11274 /* Compute the max. number of lines specified by the user. */
11275 if (FLOATP (Vmax_mini_window_height))
11276 max_height = XFLOAT_DATA (Vmax_mini_window_height) * total_height;
11277 else if (INTEGERP (Vmax_mini_window_height))
11278 max_height = XINT (Vmax_mini_window_height) * unit;
11279 else
11280 max_height = total_height / 4;
11282 /* Correct that max. height if it's bogus. */
11283 max_height = clip_to_bounds (unit, max_height, total_height);
11285 /* Find out the height of the text in the window. */
11286 if (it.line_wrap == TRUNCATE)
11287 height = unit;
11288 else
11290 last_height = 0;
11291 move_it_to (&it, ZV, -1, -1, -1, MOVE_TO_POS);
11292 if (it.max_ascent == 0 && it.max_descent == 0)
11293 height = it.current_y + last_height;
11294 else
11295 height = it.current_y + it.max_ascent + it.max_descent;
11296 height -= min (it.extra_line_spacing, it.max_extra_line_spacing);
11299 /* Compute a suitable window start. */
11300 if (height > max_height)
11302 height = (max_height / unit) * unit;
11303 init_iterator (&it, w, ZV, ZV_BYTE, NULL, DEFAULT_FACE_ID);
11304 move_it_vertically_backward (&it, height - unit);
11305 start = it.current.pos;
11307 else
11308 SET_TEXT_POS (start, BEGV, BEGV_BYTE);
11309 SET_MARKER_FROM_TEXT_POS (w->start, start);
11311 if (EQ (Vresize_mini_windows, Qgrow_only))
11313 /* Let it grow only, until we display an empty message, in which
11314 case the window shrinks again. */
11315 if (height > WINDOW_PIXEL_HEIGHT (w))
11317 int old_height = WINDOW_PIXEL_HEIGHT (w);
11319 FRAME_WINDOWS_FROZEN (f) = true;
11320 grow_mini_window (w, height - WINDOW_PIXEL_HEIGHT (w), true);
11321 window_height_changed_p = WINDOW_PIXEL_HEIGHT (w) != old_height;
11323 else if (height < WINDOW_PIXEL_HEIGHT (w)
11324 && (exact_p || BEGV == ZV))
11326 int old_height = WINDOW_PIXEL_HEIGHT (w);
11328 FRAME_WINDOWS_FROZEN (f) = false;
11329 shrink_mini_window (w, true);
11330 window_height_changed_p = WINDOW_PIXEL_HEIGHT (w) != old_height;
11333 else
11335 /* Always resize to exact size needed. */
11336 if (height > WINDOW_PIXEL_HEIGHT (w))
11338 int old_height = WINDOW_PIXEL_HEIGHT (w);
11340 FRAME_WINDOWS_FROZEN (f) = true;
11341 grow_mini_window (w, height - WINDOW_PIXEL_HEIGHT (w), true);
11342 window_height_changed_p = WINDOW_PIXEL_HEIGHT (w) != old_height;
11344 else if (height < WINDOW_PIXEL_HEIGHT (w))
11346 int old_height = WINDOW_PIXEL_HEIGHT (w);
11348 FRAME_WINDOWS_FROZEN (f) = false;
11349 shrink_mini_window (w, true);
11351 if (height)
11353 FRAME_WINDOWS_FROZEN (f) = true;
11354 grow_mini_window (w, height - WINDOW_PIXEL_HEIGHT (w), true);
11357 window_height_changed_p = WINDOW_PIXEL_HEIGHT (w) != old_height;
11361 if (old_current_buffer)
11362 set_buffer_internal (old_current_buffer);
11365 return window_height_changed_p;
11369 /* Value is the current message, a string, or nil if there is no
11370 current message. */
11372 Lisp_Object
11373 current_message (void)
11375 Lisp_Object msg;
11377 if (!BUFFERP (echo_area_buffer[0]))
11378 msg = Qnil;
11379 else
11381 with_echo_area_buffer (0, 0, current_message_1,
11382 (intptr_t) &msg, Qnil);
11383 if (NILP (msg))
11384 echo_area_buffer[0] = Qnil;
11387 return msg;
11391 static bool
11392 current_message_1 (ptrdiff_t a1, Lisp_Object a2)
11394 intptr_t i1 = a1;
11395 Lisp_Object *msg = (Lisp_Object *) i1;
11397 if (Z > BEG)
11398 *msg = make_buffer_string (BEG, Z, true);
11399 else
11400 *msg = Qnil;
11401 return false;
11405 /* Push the current message on Vmessage_stack for later restoration
11406 by restore_message. Value is true if the current message isn't
11407 empty. This is a relatively infrequent operation, so it's not
11408 worth optimizing. */
11410 bool
11411 push_message (void)
11413 Lisp_Object msg = current_message ();
11414 Vmessage_stack = Fcons (msg, Vmessage_stack);
11415 return STRINGP (msg);
11419 /* Restore message display from the top of Vmessage_stack. */
11421 void
11422 restore_message (void)
11424 eassert (CONSP (Vmessage_stack));
11425 message3_nolog (XCAR (Vmessage_stack));
11429 /* Handler for unwind-protect calling pop_message. */
11431 void
11432 pop_message_unwind (void)
11434 /* Pop the top-most entry off Vmessage_stack. */
11435 eassert (CONSP (Vmessage_stack));
11436 Vmessage_stack = XCDR (Vmessage_stack);
11440 /* Check that Vmessage_stack is nil. Called from emacs.c when Emacs
11441 exits. If the stack is not empty, we have a missing pop_message
11442 somewhere. */
11444 void
11445 check_message_stack (void)
11447 if (!NILP (Vmessage_stack))
11448 emacs_abort ();
11452 /* Truncate to NCHARS what will be displayed in the echo area the next
11453 time we display it---but don't redisplay it now. */
11455 void
11456 truncate_echo_area (ptrdiff_t nchars)
11458 if (nchars == 0)
11459 echo_area_buffer[0] = Qnil;
11460 else if (!noninteractive
11461 && INTERACTIVE
11462 && !NILP (echo_area_buffer[0]))
11464 struct frame *sf = SELECTED_FRAME ();
11465 /* Error messages get reported properly by cmd_error, so this must be
11466 just an informative message; if the frame hasn't really been
11467 initialized yet, just toss it. */
11468 if (sf->glyphs_initialized_p)
11469 with_echo_area_buffer (0, 0, truncate_message_1, nchars, Qnil);
11474 /* Helper function for truncate_echo_area. Truncate the current
11475 message to at most NCHARS characters. */
11477 static bool
11478 truncate_message_1 (ptrdiff_t nchars, Lisp_Object a2)
11480 if (BEG + nchars < Z)
11481 del_range (BEG + nchars, Z);
11482 if (Z == BEG)
11483 echo_area_buffer[0] = Qnil;
11484 return false;
11487 /* Set the current message to STRING. */
11489 static void
11490 set_message (Lisp_Object string)
11492 eassert (STRINGP (string));
11494 message_enable_multibyte = STRING_MULTIBYTE (string);
11496 with_echo_area_buffer (0, -1, set_message_1, 0, string);
11497 message_buf_print = false;
11498 help_echo_showing_p = false;
11500 if (STRINGP (Vdebug_on_message)
11501 && STRINGP (string)
11502 && fast_string_match (Vdebug_on_message, string) >= 0)
11503 call_debugger (list2 (Qerror, string));
11507 /* Helper function for set_message. First argument is ignored and second
11508 argument has the same meaning as for set_message.
11509 This function is called with the echo area buffer being current. */
11511 static bool
11512 set_message_1 (ptrdiff_t a1, Lisp_Object string)
11514 eassert (STRINGP (string));
11516 /* Change multibyteness of the echo buffer appropriately. */
11517 if (message_enable_multibyte
11518 != !NILP (BVAR (current_buffer, enable_multibyte_characters)))
11519 Fset_buffer_multibyte (message_enable_multibyte ? Qt : Qnil);
11521 bset_truncate_lines (current_buffer, message_truncate_lines ? Qt : Qnil);
11522 if (!NILP (BVAR (current_buffer, bidi_display_reordering)))
11523 bset_bidi_paragraph_direction (current_buffer, Qleft_to_right);
11525 /* Insert new message at BEG. */
11526 TEMP_SET_PT_BOTH (BEG, BEG_BYTE);
11528 /* This function takes care of single/multibyte conversion.
11529 We just have to ensure that the echo area buffer has the right
11530 setting of enable_multibyte_characters. */
11531 insert_from_string (string, 0, 0, SCHARS (string), SBYTES (string), true);
11533 return false;
11537 /* Clear messages. CURRENT_P means clear the current message.
11538 LAST_DISPLAYED_P means clear the message last displayed. */
11540 void
11541 clear_message (bool current_p, bool last_displayed_p)
11543 if (current_p)
11545 echo_area_buffer[0] = Qnil;
11546 message_cleared_p = true;
11549 if (last_displayed_p)
11550 echo_area_buffer[1] = Qnil;
11552 message_buf_print = false;
11555 /* Clear garbaged frames.
11557 This function is used where the old redisplay called
11558 redraw_garbaged_frames which in turn called redraw_frame which in
11559 turn called clear_frame. The call to clear_frame was a source of
11560 flickering. I believe a clear_frame is not necessary. It should
11561 suffice in the new redisplay to invalidate all current matrices,
11562 and ensure a complete redisplay of all windows. */
11564 static void
11565 clear_garbaged_frames (void)
11567 if (frame_garbaged)
11569 Lisp_Object tail, frame;
11570 struct frame *sf = SELECTED_FRAME ();
11572 FOR_EACH_FRAME (tail, frame)
11574 struct frame *f = XFRAME (frame);
11576 if (FRAME_VISIBLE_P (f) && FRAME_GARBAGED_P (f))
11578 if (f->resized_p
11579 /* It makes no sense to redraw a non-selected TTY
11580 frame, since that will actually clear the
11581 selected frame, and might leave the selected
11582 frame with corrupted display, if it happens not
11583 to be marked garbaged. */
11584 && !(f != sf && (FRAME_TERMCAP_P (f) || FRAME_MSDOS_P (f))))
11585 redraw_frame (f);
11586 else
11587 clear_current_matrices (f);
11589 #if defined (HAVE_WINDOW_SYSTEM) && !defined (HAVE_NS)
11590 x_clear_under_internal_border (f);
11591 #endif /* HAVE_WINDOW_SYSTEM && !HAVE_NS */
11593 fset_redisplay (f);
11594 f->garbaged = false;
11595 f->resized_p = false;
11599 frame_garbaged = false;
11604 /* Redisplay the echo area of the selected frame. If UPDATE_FRAME_P, update
11605 selected_frame. */
11607 static void
11608 echo_area_display (bool update_frame_p)
11610 Lisp_Object mini_window;
11611 struct window *w;
11612 struct frame *f;
11613 bool window_height_changed_p = false;
11614 struct frame *sf = SELECTED_FRAME ();
11616 mini_window = FRAME_MINIBUF_WINDOW (sf);
11617 if (NILP (mini_window))
11618 return;
11620 w = XWINDOW (mini_window);
11621 f = XFRAME (WINDOW_FRAME (w));
11623 /* Don't display if frame is invisible or not yet initialized. */
11624 if (!FRAME_VISIBLE_P (f) || !f->glyphs_initialized_p)
11625 return;
11627 #ifdef HAVE_WINDOW_SYSTEM
11628 /* When Emacs starts, selected_frame may be the initial terminal
11629 frame. If we let this through, a message would be displayed on
11630 the terminal. */
11631 if (FRAME_INITIAL_P (XFRAME (selected_frame)))
11632 return;
11633 #endif /* HAVE_WINDOW_SYSTEM */
11635 /* Redraw garbaged frames. */
11636 clear_garbaged_frames ();
11638 if (!NILP (echo_area_buffer[0]) || minibuf_level == 0)
11640 echo_area_window = mini_window;
11641 window_height_changed_p = display_echo_area (w);
11642 w->must_be_updated_p = true;
11644 /* Update the display, unless called from redisplay_internal.
11645 Also don't update the screen during redisplay itself. The
11646 update will happen at the end of redisplay, and an update
11647 here could cause confusion. */
11648 if (update_frame_p && !redisplaying_p)
11650 int n = 0;
11652 /* If the display update has been interrupted by pending
11653 input, update mode lines in the frame. Due to the
11654 pending input, it might have been that redisplay hasn't
11655 been called, so that mode lines above the echo area are
11656 garbaged. This looks odd, so we prevent it here. */
11657 if (!display_completed)
11659 n = redisplay_mode_lines (FRAME_ROOT_WINDOW (f), false);
11661 #if defined (HAVE_WINDOW_SYSTEM) && !defined (HAVE_NS)
11662 x_clear_under_internal_border (f);
11663 #endif /* HAVE_WINDOW_SYSTEM && !HAVE_NS */
11667 if (window_height_changed_p
11668 /* Don't do this if Emacs is shutting down. Redisplay
11669 needs to run hooks. */
11670 && !NILP (Vrun_hooks))
11672 /* Must update other windows. Likewise as in other
11673 cases, don't let this update be interrupted by
11674 pending input. */
11675 ptrdiff_t count = SPECPDL_INDEX ();
11676 specbind (Qredisplay_dont_pause, Qt);
11677 fset_redisplay (f);
11678 redisplay_internal ();
11679 unbind_to (count, Qnil);
11681 else if (FRAME_WINDOW_P (f) && n == 0)
11683 /* Window configuration is the same as before.
11684 Can do with a display update of the echo area,
11685 unless we displayed some mode lines. */
11686 update_single_window (w);
11687 flush_frame (f);
11689 else
11690 update_frame (f, true, true);
11692 /* If cursor is in the echo area, make sure that the next
11693 redisplay displays the minibuffer, so that the cursor will
11694 be replaced with what the minibuffer wants. */
11695 if (cursor_in_echo_area)
11696 wset_redisplay (XWINDOW (mini_window));
11699 else if (!EQ (mini_window, selected_window))
11700 wset_redisplay (XWINDOW (mini_window));
11702 /* Last displayed message is now the current message. */
11703 echo_area_buffer[1] = echo_area_buffer[0];
11704 /* Inform read_char that we're not echoing. */
11705 echo_message_buffer = Qnil;
11707 /* Prevent redisplay optimization in redisplay_internal by resetting
11708 this_line_start_pos. This is done because the mini-buffer now
11709 displays the message instead of its buffer text. */
11710 if (EQ (mini_window, selected_window))
11711 CHARPOS (this_line_start_pos) = 0;
11713 if (window_height_changed_p)
11715 fset_redisplay (f);
11717 /* If window configuration was changed, frames may have been
11718 marked garbaged. Clear them or we will experience
11719 surprises wrt scrolling.
11720 FIXME: How/why/when? */
11721 clear_garbaged_frames ();
11725 /* True if W's buffer was changed but not saved. */
11727 static bool
11728 window_buffer_changed (struct window *w)
11730 struct buffer *b = XBUFFER (w->contents);
11732 eassert (BUFFER_LIVE_P (b));
11734 return (BUF_SAVE_MODIFF (b) < BUF_MODIFF (b)) != w->last_had_star;
11737 /* True if W has %c or %C in its mode line and mode line should be updated. */
11739 static bool
11740 mode_line_update_needed (struct window *w)
11742 return (w->column_number_displayed != -1
11743 && !(PT == w->last_point && !window_outdated (w))
11744 && (w->column_number_displayed != current_column ()));
11747 /* True if window start of W is frozen and may not be changed during
11748 redisplay. */
11750 static bool
11751 window_frozen_p (struct window *w)
11753 if (FRAME_WINDOWS_FROZEN (XFRAME (WINDOW_FRAME (w))))
11755 Lisp_Object window;
11757 XSETWINDOW (window, w);
11758 if (MINI_WINDOW_P (w))
11759 return false;
11760 else if (EQ (window, selected_window))
11761 return false;
11762 else if (MINI_WINDOW_P (XWINDOW (selected_window))
11763 && EQ (window, Vminibuf_scroll_window))
11764 /* This special window can't be frozen too. */
11765 return false;
11766 else
11767 return true;
11769 return false;
11772 /***********************************************************************
11773 Mode Lines and Frame Titles
11774 ***********************************************************************/
11776 /* A buffer for constructing non-propertized mode-line strings and
11777 frame titles in it; allocated from the heap in init_xdisp and
11778 resized as needed in store_mode_line_noprop_char. */
11780 static char *mode_line_noprop_buf;
11782 /* The buffer's end, and a current output position in it. */
11784 static char *mode_line_noprop_buf_end;
11785 static char *mode_line_noprop_ptr;
11787 #define MODE_LINE_NOPROP_LEN(start) \
11788 ((mode_line_noprop_ptr - mode_line_noprop_buf) - start)
11790 static enum {
11791 MODE_LINE_DISPLAY = 0,
11792 MODE_LINE_TITLE,
11793 MODE_LINE_NOPROP,
11794 MODE_LINE_STRING
11795 } mode_line_target;
11797 /* Alist that caches the results of :propertize.
11798 Each element is (PROPERTIZED-STRING . PROPERTY-LIST). */
11799 static Lisp_Object mode_line_proptrans_alist;
11801 /* List of strings making up the mode-line. */
11802 static Lisp_Object mode_line_string_list;
11804 /* Base face property when building propertized mode line string. */
11805 static Lisp_Object mode_line_string_face;
11806 static Lisp_Object mode_line_string_face_prop;
11809 /* Unwind data for mode line strings */
11811 static Lisp_Object Vmode_line_unwind_vector;
11813 static Lisp_Object
11814 format_mode_line_unwind_data (struct frame *target_frame,
11815 struct buffer *obuf,
11816 Lisp_Object owin,
11817 bool save_proptrans)
11819 Lisp_Object vector, tmp;
11821 /* Reduce consing by keeping one vector in
11822 Vwith_echo_area_save_vector. */
11823 vector = Vmode_line_unwind_vector;
11824 Vmode_line_unwind_vector = Qnil;
11826 if (NILP (vector))
11827 vector = Fmake_vector (make_number (10), Qnil);
11829 ASET (vector, 0, make_number (mode_line_target));
11830 ASET (vector, 1, make_number (MODE_LINE_NOPROP_LEN (0)));
11831 ASET (vector, 2, mode_line_string_list);
11832 ASET (vector, 3, save_proptrans ? mode_line_proptrans_alist : Qt);
11833 ASET (vector, 4, mode_line_string_face);
11834 ASET (vector, 5, mode_line_string_face_prop);
11836 if (obuf)
11837 XSETBUFFER (tmp, obuf);
11838 else
11839 tmp = Qnil;
11840 ASET (vector, 6, tmp);
11841 ASET (vector, 7, owin);
11842 if (target_frame)
11844 /* Similarly to `with-selected-window', if the operation selects
11845 a window on another frame, we must restore that frame's
11846 selected window, and (for a tty) the top-frame. */
11847 ASET (vector, 8, target_frame->selected_window);
11848 if (FRAME_TERMCAP_P (target_frame))
11849 ASET (vector, 9, FRAME_TTY (target_frame)->top_frame);
11852 return vector;
11855 static void
11856 unwind_format_mode_line (Lisp_Object vector)
11858 Lisp_Object old_window = AREF (vector, 7);
11859 Lisp_Object target_frame_window = AREF (vector, 8);
11860 Lisp_Object old_top_frame = AREF (vector, 9);
11862 mode_line_target = XINT (AREF (vector, 0));
11863 mode_line_noprop_ptr = mode_line_noprop_buf + XINT (AREF (vector, 1));
11864 mode_line_string_list = AREF (vector, 2);
11865 if (! EQ (AREF (vector, 3), Qt))
11866 mode_line_proptrans_alist = AREF (vector, 3);
11867 mode_line_string_face = AREF (vector, 4);
11868 mode_line_string_face_prop = AREF (vector, 5);
11870 /* Select window before buffer, since it may change the buffer. */
11871 if (!NILP (old_window))
11873 /* If the operation that we are unwinding had selected a window
11874 on a different frame, reset its frame-selected-window. For a
11875 text terminal, reset its top-frame if necessary. */
11876 if (!NILP (target_frame_window))
11878 Lisp_Object frame
11879 = WINDOW_FRAME (XWINDOW (target_frame_window));
11881 if (!EQ (frame, WINDOW_FRAME (XWINDOW (old_window))))
11882 Fselect_window (target_frame_window, Qt);
11884 if (!NILP (old_top_frame) && !EQ (old_top_frame, frame))
11885 Fselect_frame (old_top_frame, Qt);
11888 Fselect_window (old_window, Qt);
11891 if (!NILP (AREF (vector, 6)))
11893 set_buffer_internal_1 (XBUFFER (AREF (vector, 6)));
11894 ASET (vector, 6, Qnil);
11897 Vmode_line_unwind_vector = vector;
11901 /* Store a single character C for the frame title in mode_line_noprop_buf.
11902 Re-allocate mode_line_noprop_buf if necessary. */
11904 static void
11905 store_mode_line_noprop_char (char c)
11907 /* If output position has reached the end of the allocated buffer,
11908 increase the buffer's size. */
11909 if (mode_line_noprop_ptr == mode_line_noprop_buf_end)
11911 ptrdiff_t len = MODE_LINE_NOPROP_LEN (0);
11912 ptrdiff_t size = len;
11913 mode_line_noprop_buf =
11914 xpalloc (mode_line_noprop_buf, &size, 1, STRING_BYTES_BOUND, 1);
11915 mode_line_noprop_buf_end = mode_line_noprop_buf + size;
11916 mode_line_noprop_ptr = mode_line_noprop_buf + len;
11919 *mode_line_noprop_ptr++ = c;
11923 /* Store part of a frame title in mode_line_noprop_buf, beginning at
11924 mode_line_noprop_ptr. STRING is the string to store. Do not copy
11925 characters that yield more columns than PRECISION; PRECISION <= 0
11926 means copy the whole string. Pad with spaces until FIELD_WIDTH
11927 number of characters have been copied; FIELD_WIDTH <= 0 means don't
11928 pad. Called from display_mode_element when it is used to build a
11929 frame title. */
11931 static int
11932 store_mode_line_noprop (const char *string, int field_width, int precision)
11934 const unsigned char *str = (const unsigned char *) string;
11935 int n = 0;
11936 ptrdiff_t dummy, nbytes;
11938 /* Copy at most PRECISION chars from STR. */
11939 nbytes = strlen (string);
11940 n += c_string_width (str, nbytes, precision, &dummy, &nbytes);
11941 while (nbytes--)
11942 store_mode_line_noprop_char (*str++);
11944 /* Fill up with spaces until FIELD_WIDTH reached. */
11945 while (field_width > 0
11946 && n < field_width)
11948 store_mode_line_noprop_char (' ');
11949 ++n;
11952 return n;
11955 /***********************************************************************
11956 Frame Titles
11957 ***********************************************************************/
11959 #ifdef HAVE_WINDOW_SYSTEM
11961 /* Set the title of FRAME, if it has changed. The title format is
11962 Vicon_title_format if FRAME is iconified, otherwise it is
11963 frame_title_format. */
11965 static void
11966 x_consider_frame_title (Lisp_Object frame)
11968 struct frame *f = XFRAME (frame);
11970 if ((FRAME_WINDOW_P (f)
11971 || FRAME_MINIBUF_ONLY_P (f)
11972 || f->explicit_name)
11973 && NILP (Fframe_parameter (frame, Qtooltip)))
11975 /* Do we have more than one visible frame on this X display? */
11976 Lisp_Object tail, other_frame, fmt;
11977 ptrdiff_t title_start;
11978 char *title;
11979 ptrdiff_t len;
11980 struct it it;
11981 ptrdiff_t count = SPECPDL_INDEX ();
11983 FOR_EACH_FRAME (tail, other_frame)
11985 struct frame *tf = XFRAME (other_frame);
11987 if (tf != f
11988 && FRAME_KBOARD (tf) == FRAME_KBOARD (f)
11989 && !FRAME_MINIBUF_ONLY_P (tf)
11990 && !EQ (other_frame, tip_frame)
11991 && !FRAME_PARENT_FRAME (tf)
11992 && (FRAME_VISIBLE_P (tf) || FRAME_ICONIFIED_P (tf)))
11993 break;
11996 /* Set global variable indicating that multiple frames exist. */
11997 multiple_frames = CONSP (tail);
11999 /* Switch to the buffer of selected window of the frame. Set up
12000 mode_line_target so that display_mode_element will output into
12001 mode_line_noprop_buf; then display the title. */
12002 record_unwind_protect (unwind_format_mode_line,
12003 format_mode_line_unwind_data
12004 (f, current_buffer, selected_window, false));
12005 /* select-frame calls resize_mini_window, which could resize the
12006 mini-window and by that undo the effect of this redisplay
12007 cycle wrt minibuffer and echo-area display. Binding
12008 inhibit-redisplay to t makes the call to resize_mini_window a
12009 no-op, thus avoiding the adverse side effects. */
12010 specbind (Qinhibit_redisplay, Qt);
12012 Fselect_window (f->selected_window, Qt);
12013 set_buffer_internal_1
12014 (XBUFFER (XWINDOW (f->selected_window)->contents));
12015 fmt = FRAME_ICONIFIED_P (f) ? Vicon_title_format : Vframe_title_format;
12017 mode_line_target = MODE_LINE_TITLE;
12018 title_start = MODE_LINE_NOPROP_LEN (0);
12019 init_iterator (&it, XWINDOW (f->selected_window), -1, -1,
12020 NULL, DEFAULT_FACE_ID);
12021 display_mode_element (&it, 0, -1, -1, fmt, Qnil, false);
12022 len = MODE_LINE_NOPROP_LEN (title_start);
12023 title = mode_line_noprop_buf + title_start;
12024 unbind_to (count, Qnil);
12026 /* Set the title only if it's changed. This avoids consing in
12027 the common case where it hasn't. (If it turns out that we've
12028 already wasted too much time by walking through the list with
12029 display_mode_element, then we might need to optimize at a
12030 higher level than this.) */
12031 if (! STRINGP (f->name)
12032 || SBYTES (f->name) != len
12033 || memcmp (title, SDATA (f->name), len) != 0)
12034 x_implicitly_set_name (f, make_string (title, len), Qnil);
12038 #endif /* not HAVE_WINDOW_SYSTEM */
12041 /***********************************************************************
12042 Menu Bars
12043 ***********************************************************************/
12045 /* True if we will not redisplay all visible windows. */
12046 #define REDISPLAY_SOME_P() \
12047 ((windows_or_buffers_changed == 0 \
12048 || windows_or_buffers_changed == REDISPLAY_SOME) \
12049 && (update_mode_lines == 0 \
12050 || update_mode_lines == REDISPLAY_SOME))
12052 /* Prepare for redisplay by updating menu-bar item lists when
12053 appropriate. This can call eval. */
12055 static void
12056 prepare_menu_bars (void)
12058 bool all_windows = windows_or_buffers_changed || update_mode_lines;
12059 bool some_windows = REDISPLAY_SOME_P ();
12060 Lisp_Object tooltip_frame;
12062 #ifdef HAVE_WINDOW_SYSTEM
12063 tooltip_frame = tip_frame;
12064 #else
12065 tooltip_frame = Qnil;
12066 #endif
12068 if (FUNCTIONP (Vpre_redisplay_function))
12070 Lisp_Object windows = all_windows ? Qt : Qnil;
12071 if (all_windows && some_windows)
12073 Lisp_Object ws = window_list ();
12074 for (windows = Qnil; CONSP (ws); ws = XCDR (ws))
12076 Lisp_Object this = XCAR (ws);
12077 struct window *w = XWINDOW (this);
12078 if (w->redisplay
12079 || XFRAME (w->frame)->redisplay
12080 || XBUFFER (w->contents)->text->redisplay)
12082 windows = Fcons (this, windows);
12086 safe__call1 (true, Vpre_redisplay_function, windows);
12089 /* Update all frame titles based on their buffer names, etc. We do
12090 this before the menu bars so that the buffer-menu will show the
12091 up-to-date frame titles. */
12092 #ifdef HAVE_WINDOW_SYSTEM
12093 if (all_windows)
12095 Lisp_Object tail, frame;
12097 FOR_EACH_FRAME (tail, frame)
12099 struct frame *f = XFRAME (frame);
12100 struct window *w = XWINDOW (FRAME_SELECTED_WINDOW (f));
12101 if (some_windows
12102 && !f->redisplay
12103 && !w->redisplay
12104 && !XBUFFER (w->contents)->text->redisplay)
12105 continue;
12107 if (!EQ (frame, tooltip_frame)
12108 && !FRAME_PARENT_FRAME (f)
12109 && (FRAME_ICONIFIED_P (f)
12110 || FRAME_VISIBLE_P (f) == 1
12111 /* Exclude TTY frames that are obscured because they
12112 are not the top frame on their console. This is
12113 because x_consider_frame_title actually switches
12114 to the frame, which for TTY frames means it is
12115 marked as garbaged, and will be completely
12116 redrawn on the next redisplay cycle. This causes
12117 TTY frames to be completely redrawn, when there
12118 are more than one of them, even though nothing
12119 should be changed on display. */
12120 || (FRAME_VISIBLE_P (f) == 2 && FRAME_WINDOW_P (f))))
12121 x_consider_frame_title (frame);
12124 #endif /* HAVE_WINDOW_SYSTEM */
12126 /* Update the menu bar item lists, if appropriate. This has to be
12127 done before any actual redisplay or generation of display lines. */
12129 if (all_windows)
12131 Lisp_Object tail, frame;
12132 ptrdiff_t count = SPECPDL_INDEX ();
12133 /* True means that update_menu_bar has run its hooks
12134 so any further calls to update_menu_bar shouldn't do so again. */
12135 bool menu_bar_hooks_run = false;
12137 record_unwind_save_match_data ();
12139 FOR_EACH_FRAME (tail, frame)
12141 struct frame *f = XFRAME (frame);
12142 struct window *w = XWINDOW (FRAME_SELECTED_WINDOW (f));
12144 /* Ignore tooltip frame. */
12145 if (EQ (frame, tooltip_frame))
12146 continue;
12148 if (some_windows
12149 && !f->redisplay
12150 && !w->redisplay
12151 && !XBUFFER (w->contents)->text->redisplay)
12152 continue;
12154 run_window_size_change_functions (frame);
12156 if (FRAME_PARENT_FRAME (f))
12157 continue;
12159 menu_bar_hooks_run = update_menu_bar (f, false, menu_bar_hooks_run);
12160 #ifdef HAVE_WINDOW_SYSTEM
12161 update_tool_bar (f, false);
12162 #endif
12165 unbind_to (count, Qnil);
12167 else
12169 struct frame *sf = SELECTED_FRAME ();
12170 update_menu_bar (sf, true, false);
12171 #ifdef HAVE_WINDOW_SYSTEM
12172 update_tool_bar (sf, true);
12173 #endif
12178 /* Update the menu bar item list for frame F. This has to be done
12179 before we start to fill in any display lines, because it can call
12180 eval.
12182 If SAVE_MATCH_DATA, we must save and restore it here.
12184 If HOOKS_RUN, a previous call to update_menu_bar
12185 already ran the menu bar hooks for this redisplay, so there
12186 is no need to run them again. The return value is the
12187 updated value of this flag, to pass to the next call. */
12189 static bool
12190 update_menu_bar (struct frame *f, bool save_match_data, bool hooks_run)
12192 Lisp_Object window;
12193 struct window *w;
12195 /* If called recursively during a menu update, do nothing. This can
12196 happen when, for instance, an activate-menubar-hook causes a
12197 redisplay. */
12198 if (inhibit_menubar_update)
12199 return hooks_run;
12201 window = FRAME_SELECTED_WINDOW (f);
12202 w = XWINDOW (window);
12204 if (FRAME_WINDOW_P (f)
12206 #if defined (USE_X_TOOLKIT) || defined (HAVE_NTGUI) \
12207 || defined (HAVE_NS) || defined (USE_GTK)
12208 FRAME_EXTERNAL_MENU_BAR (f)
12209 #else
12210 FRAME_MENU_BAR_LINES (f) > 0
12211 #endif
12212 : FRAME_MENU_BAR_LINES (f) > 0)
12214 /* If the user has switched buffers or windows, we need to
12215 recompute to reflect the new bindings. But we'll
12216 recompute when update_mode_lines is set too; that means
12217 that people can use force-mode-line-update to request
12218 that the menu bar be recomputed. The adverse effect on
12219 the rest of the redisplay algorithm is about the same as
12220 windows_or_buffers_changed anyway. */
12221 if (windows_or_buffers_changed
12222 /* This used to test w->update_mode_line, but we believe
12223 there is no need to recompute the menu in that case. */
12224 || update_mode_lines
12225 || window_buffer_changed (w))
12227 struct buffer *prev = current_buffer;
12228 ptrdiff_t count = SPECPDL_INDEX ();
12230 specbind (Qinhibit_menubar_update, Qt);
12232 set_buffer_internal_1 (XBUFFER (w->contents));
12233 if (save_match_data)
12234 record_unwind_save_match_data ();
12235 if (NILP (Voverriding_local_map_menu_flag))
12237 specbind (Qoverriding_terminal_local_map, Qnil);
12238 specbind (Qoverriding_local_map, Qnil);
12241 if (!hooks_run)
12243 /* Run the Lucid hook. */
12244 safe_run_hooks (Qactivate_menubar_hook);
12246 /* If it has changed current-menubar from previous value,
12247 really recompute the menu-bar from the value. */
12248 if (! NILP (Vlucid_menu_bar_dirty_flag))
12249 call0 (Qrecompute_lucid_menubar);
12251 safe_run_hooks (Qmenu_bar_update_hook);
12253 hooks_run = true;
12256 XSETFRAME (Vmenu_updating_frame, f);
12257 fset_menu_bar_items (f, menu_bar_items (FRAME_MENU_BAR_ITEMS (f)));
12259 /* Redisplay the menu bar in case we changed it. */
12260 #if defined (USE_X_TOOLKIT) || defined (HAVE_NTGUI) \
12261 || defined (HAVE_NS) || defined (USE_GTK)
12262 if (FRAME_WINDOW_P (f))
12264 #if defined (HAVE_NS)
12265 /* All frames on Mac OS share the same menubar. So only
12266 the selected frame should be allowed to set it. */
12267 if (f == SELECTED_FRAME ())
12268 #endif
12269 set_frame_menubar (f, false, false);
12271 else
12272 /* On a terminal screen, the menu bar is an ordinary screen
12273 line, and this makes it get updated. */
12274 w->update_mode_line = true;
12275 #else /* ! (USE_X_TOOLKIT || HAVE_NTGUI || HAVE_NS || USE_GTK) */
12276 /* In the non-toolkit version, the menu bar is an ordinary screen
12277 line, and this makes it get updated. */
12278 w->update_mode_line = true;
12279 #endif /* ! (USE_X_TOOLKIT || HAVE_NTGUI || HAVE_NS || USE_GTK) */
12281 unbind_to (count, Qnil);
12282 set_buffer_internal_1 (prev);
12286 return hooks_run;
12289 /***********************************************************************
12290 Tool-bars
12291 ***********************************************************************/
12293 #ifdef HAVE_WINDOW_SYSTEM
12295 /* Select `frame' temporarily without running all the code in
12296 do_switch_frame.
12297 FIXME: Maybe do_switch_frame should be trimmed down similarly
12298 when `norecord' is set. */
12299 static void
12300 fast_set_selected_frame (Lisp_Object frame)
12302 if (!EQ (selected_frame, frame))
12304 selected_frame = frame;
12305 selected_window = XFRAME (frame)->selected_window;
12309 /* Update the tool-bar item list for frame F. This has to be done
12310 before we start to fill in any display lines. Called from
12311 prepare_menu_bars. If SAVE_MATCH_DATA, we must save
12312 and restore it here. */
12314 static void
12315 update_tool_bar (struct frame *f, bool save_match_data)
12317 #if defined (USE_GTK) || defined (HAVE_NS)
12318 bool do_update = FRAME_EXTERNAL_TOOL_BAR (f);
12319 #else
12320 bool do_update = (WINDOWP (f->tool_bar_window)
12321 && WINDOW_TOTAL_LINES (XWINDOW (f->tool_bar_window)) > 0);
12322 #endif
12324 if (do_update)
12326 Lisp_Object window;
12327 struct window *w;
12329 window = FRAME_SELECTED_WINDOW (f);
12330 w = XWINDOW (window);
12332 /* If the user has switched buffers or windows, we need to
12333 recompute to reflect the new bindings. But we'll
12334 recompute when update_mode_lines is set too; that means
12335 that people can use force-mode-line-update to request
12336 that the menu bar be recomputed. The adverse effect on
12337 the rest of the redisplay algorithm is about the same as
12338 windows_or_buffers_changed anyway. */
12339 if (windows_or_buffers_changed
12340 || w->update_mode_line
12341 || update_mode_lines
12342 || window_buffer_changed (w))
12344 struct buffer *prev = current_buffer;
12345 ptrdiff_t count = SPECPDL_INDEX ();
12346 Lisp_Object frame, new_tool_bar;
12347 int new_n_tool_bar;
12349 /* Set current_buffer to the buffer of the selected
12350 window of the frame, so that we get the right local
12351 keymaps. */
12352 set_buffer_internal_1 (XBUFFER (w->contents));
12354 /* Save match data, if we must. */
12355 if (save_match_data)
12356 record_unwind_save_match_data ();
12358 /* Make sure that we don't accidentally use bogus keymaps. */
12359 if (NILP (Voverriding_local_map_menu_flag))
12361 specbind (Qoverriding_terminal_local_map, Qnil);
12362 specbind (Qoverriding_local_map, Qnil);
12365 /* We must temporarily set the selected frame to this frame
12366 before calling tool_bar_items, because the calculation of
12367 the tool-bar keymap uses the selected frame (see
12368 `tool-bar-make-keymap' in tool-bar.el). */
12369 eassert (EQ (selected_window,
12370 /* Since we only explicitly preserve selected_frame,
12371 check that selected_window would be redundant. */
12372 XFRAME (selected_frame)->selected_window));
12373 record_unwind_protect (fast_set_selected_frame, selected_frame);
12374 XSETFRAME (frame, f);
12375 fast_set_selected_frame (frame);
12377 /* Build desired tool-bar items from keymaps. */
12378 new_tool_bar
12379 = tool_bar_items (Fcopy_sequence (f->tool_bar_items),
12380 &new_n_tool_bar);
12382 /* Redisplay the tool-bar if we changed it. */
12383 if (new_n_tool_bar != f->n_tool_bar_items
12384 || NILP (Fequal (new_tool_bar, f->tool_bar_items)))
12386 /* Redisplay that happens asynchronously due to an expose event
12387 may access f->tool_bar_items. Make sure we update both
12388 variables within BLOCK_INPUT so no such event interrupts. */
12389 block_input ();
12390 fset_tool_bar_items (f, new_tool_bar);
12391 f->n_tool_bar_items = new_n_tool_bar;
12392 w->update_mode_line = true;
12393 unblock_input ();
12396 unbind_to (count, Qnil);
12397 set_buffer_internal_1 (prev);
12402 #if ! defined (USE_GTK) && ! defined (HAVE_NS)
12404 /* Set F->desired_tool_bar_string to a Lisp string representing frame
12405 F's desired tool-bar contents. F->tool_bar_items must have
12406 been set up previously by calling prepare_menu_bars. */
12408 static void
12409 build_desired_tool_bar_string (struct frame *f)
12411 int i, size, size_needed;
12412 Lisp_Object image, plist;
12414 image = plist = Qnil;
12416 /* Prepare F->desired_tool_bar_string. If we can reuse it, do so.
12417 Otherwise, make a new string. */
12419 /* The size of the string we might be able to reuse. */
12420 size = (STRINGP (f->desired_tool_bar_string)
12421 ? SCHARS (f->desired_tool_bar_string)
12422 : 0);
12424 /* We need one space in the string for each image. */
12425 size_needed = f->n_tool_bar_items;
12427 /* Reuse f->desired_tool_bar_string, if possible. */
12428 if (size < size_needed || NILP (f->desired_tool_bar_string))
12429 fset_desired_tool_bar_string
12430 (f, Fmake_string (make_number (size_needed), make_number (' ')));
12431 else
12433 AUTO_LIST4 (props, Qdisplay, Qnil, Qmenu_item, Qnil);
12434 Fremove_text_properties (make_number (0), make_number (size),
12435 props, f->desired_tool_bar_string);
12438 /* Put a `display' property on the string for the images to display,
12439 put a `menu_item' property on tool-bar items with a value that
12440 is the index of the item in F's tool-bar item vector. */
12441 for (i = 0; i < f->n_tool_bar_items; ++i)
12443 #define PROP(IDX) \
12444 AREF (f->tool_bar_items, i * TOOL_BAR_ITEM_NSLOTS + (IDX))
12446 bool enabled_p = !NILP (PROP (TOOL_BAR_ITEM_ENABLED_P));
12447 bool selected_p = !NILP (PROP (TOOL_BAR_ITEM_SELECTED_P));
12448 int hmargin, vmargin, relief, idx, end;
12450 /* If image is a vector, choose the image according to the
12451 button state. */
12452 image = PROP (TOOL_BAR_ITEM_IMAGES);
12453 if (VECTORP (image))
12455 if (enabled_p)
12456 idx = (selected_p
12457 ? TOOL_BAR_IMAGE_ENABLED_SELECTED
12458 : TOOL_BAR_IMAGE_ENABLED_DESELECTED);
12459 else
12460 idx = (selected_p
12461 ? TOOL_BAR_IMAGE_DISABLED_SELECTED
12462 : TOOL_BAR_IMAGE_DISABLED_DESELECTED);
12464 eassert (ASIZE (image) >= idx);
12465 image = AREF (image, idx);
12467 else
12468 idx = -1;
12470 /* Ignore invalid image specifications. */
12471 if (!valid_image_p (image))
12472 continue;
12474 /* Display the tool-bar button pressed, or depressed. */
12475 plist = Fcopy_sequence (XCDR (image));
12477 /* Compute margin and relief to draw. */
12478 relief = (tool_bar_button_relief >= 0
12479 ? tool_bar_button_relief
12480 : DEFAULT_TOOL_BAR_BUTTON_RELIEF);
12481 hmargin = vmargin = relief;
12483 if (RANGED_INTEGERP (1, Vtool_bar_button_margin,
12484 INT_MAX - max (hmargin, vmargin)))
12486 hmargin += XFASTINT (Vtool_bar_button_margin);
12487 vmargin += XFASTINT (Vtool_bar_button_margin);
12489 else if (CONSP (Vtool_bar_button_margin))
12491 if (RANGED_INTEGERP (1, XCAR (Vtool_bar_button_margin),
12492 INT_MAX - hmargin))
12493 hmargin += XFASTINT (XCAR (Vtool_bar_button_margin));
12495 if (RANGED_INTEGERP (1, XCDR (Vtool_bar_button_margin),
12496 INT_MAX - vmargin))
12497 vmargin += XFASTINT (XCDR (Vtool_bar_button_margin));
12500 if (auto_raise_tool_bar_buttons_p)
12502 /* Add a `:relief' property to the image spec if the item is
12503 selected. */
12504 if (selected_p)
12506 plist = Fplist_put (plist, QCrelief, make_number (-relief));
12507 hmargin -= relief;
12508 vmargin -= relief;
12511 else
12513 /* If image is selected, display it pressed, i.e. with a
12514 negative relief. If it's not selected, display it with a
12515 raised relief. */
12516 plist = Fplist_put (plist, QCrelief,
12517 (selected_p
12518 ? make_number (-relief)
12519 : make_number (relief)));
12520 hmargin -= relief;
12521 vmargin -= relief;
12524 /* Put a margin around the image. */
12525 if (hmargin || vmargin)
12527 if (hmargin == vmargin)
12528 plist = Fplist_put (plist, QCmargin, make_number (hmargin));
12529 else
12530 plist = Fplist_put (plist, QCmargin,
12531 Fcons (make_number (hmargin),
12532 make_number (vmargin)));
12535 /* If button is not enabled, and we don't have special images
12536 for the disabled state, make the image appear disabled by
12537 applying an appropriate algorithm to it. */
12538 if (!enabled_p && idx < 0)
12539 plist = Fplist_put (plist, QCconversion, Qdisabled);
12541 /* Put a `display' text property on the string for the image to
12542 display. Put a `menu-item' property on the string that gives
12543 the start of this item's properties in the tool-bar items
12544 vector. */
12545 image = Fcons (Qimage, plist);
12546 AUTO_LIST4 (props, Qdisplay, image, Qmenu_item,
12547 make_number (i * TOOL_BAR_ITEM_NSLOTS));
12549 /* Let the last image hide all remaining spaces in the tool bar
12550 string. The string can be longer than needed when we reuse a
12551 previous string. */
12552 if (i + 1 == f->n_tool_bar_items)
12553 end = SCHARS (f->desired_tool_bar_string);
12554 else
12555 end = i + 1;
12556 Fadd_text_properties (make_number (i), make_number (end),
12557 props, f->desired_tool_bar_string);
12558 #undef PROP
12563 /* Display one line of the tool-bar of frame IT->f.
12565 HEIGHT specifies the desired height of the tool-bar line.
12566 If the actual height of the glyph row is less than HEIGHT, the
12567 row's height is increased to HEIGHT, and the icons are centered
12568 vertically in the new height.
12570 If HEIGHT is -1, we are counting needed tool-bar lines, so don't
12571 count a final empty row in case the tool-bar width exactly matches
12572 the window width.
12575 static void
12576 display_tool_bar_line (struct it *it, int height)
12578 struct glyph_row *row = it->glyph_row;
12579 int max_x = it->last_visible_x;
12580 struct glyph *last;
12582 /* Don't extend on a previously drawn tool bar items (Bug#16058). */
12583 clear_glyph_row (row);
12584 row->enabled_p = true;
12585 row->y = it->current_y;
12587 /* Note that this isn't made use of if the face hasn't a box,
12588 so there's no need to check the face here. */
12589 it->start_of_box_run_p = true;
12591 while (it->current_x < max_x)
12593 int x, n_glyphs_before, i, nglyphs;
12594 struct it it_before;
12596 /* Get the next display element. */
12597 if (!get_next_display_element (it))
12599 /* Don't count empty row if we are counting needed tool-bar lines. */
12600 if (height < 0 && !it->hpos)
12601 return;
12602 break;
12605 /* Produce glyphs. */
12606 n_glyphs_before = row->used[TEXT_AREA];
12607 it_before = *it;
12609 PRODUCE_GLYPHS (it);
12611 nglyphs = row->used[TEXT_AREA] - n_glyphs_before;
12612 i = 0;
12613 x = it_before.current_x;
12614 while (i < nglyphs)
12616 struct glyph *glyph = row->glyphs[TEXT_AREA] + n_glyphs_before + i;
12618 if (x + glyph->pixel_width > max_x)
12620 /* Glyph doesn't fit on line. Backtrack. */
12621 row->used[TEXT_AREA] = n_glyphs_before;
12622 *it = it_before;
12623 /* If this is the only glyph on this line, it will never fit on the
12624 tool-bar, so skip it. But ensure there is at least one glyph,
12625 so we don't accidentally disable the tool-bar. */
12626 if (n_glyphs_before == 0
12627 && (it->vpos > 0 || IT_STRING_CHARPOS (*it) < it->end_charpos-1))
12628 break;
12629 goto out;
12632 ++it->hpos;
12633 x += glyph->pixel_width;
12634 ++i;
12637 /* Stop at line end. */
12638 if (ITERATOR_AT_END_OF_LINE_P (it))
12639 break;
12641 set_iterator_to_next (it, true);
12644 out:;
12646 row->displays_text_p = row->used[TEXT_AREA] != 0;
12648 /* Use default face for the border below the tool bar.
12650 FIXME: When auto-resize-tool-bars is grow-only, there is
12651 no additional border below the possibly empty tool-bar lines.
12652 So to make the extra empty lines look "normal", we have to
12653 use the tool-bar face for the border too. */
12654 if (!MATRIX_ROW_DISPLAYS_TEXT_P (row)
12655 && !EQ (Vauto_resize_tool_bars, Qgrow_only))
12656 it->face_id = DEFAULT_FACE_ID;
12658 extend_face_to_end_of_line (it);
12659 last = row->glyphs[TEXT_AREA] + row->used[TEXT_AREA] - 1;
12660 last->right_box_line_p = true;
12661 if (last == row->glyphs[TEXT_AREA])
12662 last->left_box_line_p = true;
12664 /* Make line the desired height and center it vertically. */
12665 if ((height -= it->max_ascent + it->max_descent) > 0)
12667 /* Don't add more than one line height. */
12668 height %= FRAME_LINE_HEIGHT (it->f);
12669 it->max_ascent += height / 2;
12670 it->max_descent += (height + 1) / 2;
12673 compute_line_metrics (it);
12675 /* If line is empty, make it occupy the rest of the tool-bar. */
12676 if (!MATRIX_ROW_DISPLAYS_TEXT_P (row))
12678 row->height = row->phys_height = it->last_visible_y - row->y;
12679 row->visible_height = row->height;
12680 row->ascent = row->phys_ascent = 0;
12681 row->extra_line_spacing = 0;
12684 row->full_width_p = true;
12685 row->continued_p = false;
12686 row->truncated_on_left_p = false;
12687 row->truncated_on_right_p = false;
12689 it->current_x = it->hpos = 0;
12690 it->current_y += row->height;
12691 ++it->vpos;
12692 ++it->glyph_row;
12696 /* Value is the number of pixels needed to make all tool-bar items of
12697 frame F visible. The actual number of glyph rows needed is
12698 returned in *N_ROWS if non-NULL. */
12699 static int
12700 tool_bar_height (struct frame *f, int *n_rows, bool pixelwise)
12702 struct window *w = XWINDOW (f->tool_bar_window);
12703 struct it it;
12704 /* tool_bar_height is called from redisplay_tool_bar after building
12705 the desired matrix, so use (unused) mode-line row as temporary row to
12706 avoid destroying the first tool-bar row. */
12707 struct glyph_row *temp_row = MATRIX_MODE_LINE_ROW (w->desired_matrix);
12709 /* Initialize an iterator for iteration over
12710 F->desired_tool_bar_string in the tool-bar window of frame F. */
12711 init_iterator (&it, w, -1, -1, temp_row, TOOL_BAR_FACE_ID);
12712 temp_row->reversed_p = false;
12713 it.first_visible_x = 0;
12714 it.last_visible_x = WINDOW_PIXEL_WIDTH (w);
12715 reseat_to_string (&it, NULL, f->desired_tool_bar_string, 0, 0, 0, -1);
12716 it.paragraph_embedding = L2R;
12718 while (!ITERATOR_AT_END_P (&it))
12720 clear_glyph_row (temp_row);
12721 it.glyph_row = temp_row;
12722 display_tool_bar_line (&it, -1);
12724 clear_glyph_row (temp_row);
12726 /* f->n_tool_bar_rows == 0 means "unknown"; -1 means no tool-bar. */
12727 if (n_rows)
12728 *n_rows = it.vpos > 0 ? it.vpos : -1;
12730 if (pixelwise)
12731 return it.current_y;
12732 else
12733 return (it.current_y + FRAME_LINE_HEIGHT (f) - 1) / FRAME_LINE_HEIGHT (f);
12736 #endif /* !USE_GTK && !HAVE_NS */
12738 DEFUN ("tool-bar-height", Ftool_bar_height, Stool_bar_height,
12739 0, 2, 0,
12740 doc: /* Return the number of lines occupied by the tool bar of FRAME.
12741 If FRAME is nil or omitted, use the selected frame. Optional argument
12742 PIXELWISE non-nil means return the height of the tool bar in pixels. */)
12743 (Lisp_Object frame, Lisp_Object pixelwise)
12745 int height = 0;
12747 #if ! defined (USE_GTK) && ! defined (HAVE_NS)
12748 struct frame *f = decode_any_frame (frame);
12750 if (WINDOWP (f->tool_bar_window)
12751 && WINDOW_PIXEL_HEIGHT (XWINDOW (f->tool_bar_window)) > 0)
12753 update_tool_bar (f, true);
12754 if (f->n_tool_bar_items)
12756 build_desired_tool_bar_string (f);
12757 height = tool_bar_height (f, NULL, !NILP (pixelwise));
12760 #endif
12762 return make_number (height);
12766 /* Display the tool-bar of frame F. Value is true if tool-bar's
12767 height should be changed. */
12768 static bool
12769 redisplay_tool_bar (struct frame *f)
12771 f->tool_bar_redisplayed = true;
12772 #if defined (USE_GTK) || defined (HAVE_NS)
12774 if (FRAME_EXTERNAL_TOOL_BAR (f))
12775 update_frame_tool_bar (f);
12776 return false;
12778 #else /* !USE_GTK && !HAVE_NS */
12780 struct window *w;
12781 struct it it;
12782 struct glyph_row *row;
12784 /* If frame hasn't a tool-bar window or if it is zero-height, don't
12785 do anything. This means you must start with tool-bar-lines
12786 non-zero to get the auto-sizing effect. Or in other words, you
12787 can turn off tool-bars by specifying tool-bar-lines zero. */
12788 if (!WINDOWP (f->tool_bar_window)
12789 || (w = XWINDOW (f->tool_bar_window),
12790 WINDOW_TOTAL_LINES (w) == 0))
12791 return false;
12793 /* Set up an iterator for the tool-bar window. */
12794 init_iterator (&it, w, -1, -1, w->desired_matrix->rows, TOOL_BAR_FACE_ID);
12795 it.first_visible_x = 0;
12796 it.last_visible_x = WINDOW_PIXEL_WIDTH (w);
12797 row = it.glyph_row;
12798 row->reversed_p = false;
12800 /* Build a string that represents the contents of the tool-bar. */
12801 build_desired_tool_bar_string (f);
12802 reseat_to_string (&it, NULL, f->desired_tool_bar_string, 0, 0, 0, -1);
12803 /* FIXME: This should be controlled by a user option. But it
12804 doesn't make sense to have an R2L tool bar if the menu bar cannot
12805 be drawn also R2L, and making the menu bar R2L is tricky due
12806 toolkit-specific code that implements it. If an R2L tool bar is
12807 ever supported, display_tool_bar_line should also be augmented to
12808 call unproduce_glyphs like display_line and display_string
12809 do. */
12810 it.paragraph_embedding = L2R;
12812 if (f->n_tool_bar_rows == 0)
12814 int new_height = tool_bar_height (f, &f->n_tool_bar_rows, true);
12816 if (new_height != WINDOW_PIXEL_HEIGHT (w))
12818 x_change_tool_bar_height (f, new_height);
12819 frame_default_tool_bar_height = new_height;
12820 /* Always do that now. */
12821 clear_glyph_matrix (w->desired_matrix);
12822 f->fonts_changed = true;
12823 return true;
12827 /* Display as many lines as needed to display all tool-bar items. */
12829 if (f->n_tool_bar_rows > 0)
12831 int border, rows, height, extra;
12833 if (TYPE_RANGED_INTEGERP (int, Vtool_bar_border))
12834 border = XINT (Vtool_bar_border);
12835 else if (EQ (Vtool_bar_border, Qinternal_border_width))
12836 border = FRAME_INTERNAL_BORDER_WIDTH (f);
12837 else if (EQ (Vtool_bar_border, Qborder_width))
12838 border = f->border_width;
12839 else
12840 border = 0;
12841 if (border < 0)
12842 border = 0;
12844 rows = f->n_tool_bar_rows;
12845 height = max (1, (it.last_visible_y - border) / rows);
12846 extra = it.last_visible_y - border - height * rows;
12848 while (it.current_y < it.last_visible_y)
12850 int h = 0;
12851 if (extra > 0 && rows-- > 0)
12853 h = (extra + rows - 1) / rows;
12854 extra -= h;
12856 display_tool_bar_line (&it, height + h);
12859 else
12861 while (it.current_y < it.last_visible_y)
12862 display_tool_bar_line (&it, 0);
12865 /* It doesn't make much sense to try scrolling in the tool-bar
12866 window, so don't do it. */
12867 w->desired_matrix->no_scrolling_p = true;
12868 w->must_be_updated_p = true;
12870 if (!NILP (Vauto_resize_tool_bars))
12872 bool change_height_p = true;
12874 /* If we couldn't display everything, change the tool-bar's
12875 height if there is room for more. */
12876 if (IT_STRING_CHARPOS (it) < it.end_charpos)
12877 change_height_p = true;
12879 /* We subtract 1 because display_tool_bar_line advances the
12880 glyph_row pointer before returning to its caller. We want to
12881 examine the last glyph row produced by
12882 display_tool_bar_line. */
12883 row = it.glyph_row - 1;
12885 /* If there are blank lines at the end, except for a partially
12886 visible blank line at the end that is smaller than
12887 FRAME_LINE_HEIGHT, change the tool-bar's height. */
12888 if (!MATRIX_ROW_DISPLAYS_TEXT_P (row)
12889 && row->height >= FRAME_LINE_HEIGHT (f))
12890 change_height_p = true;
12892 /* If row displays tool-bar items, but is partially visible,
12893 change the tool-bar's height. */
12894 if (MATRIX_ROW_DISPLAYS_TEXT_P (row)
12895 && MATRIX_ROW_BOTTOM_Y (row) > it.last_visible_y)
12896 change_height_p = true;
12898 /* Resize windows as needed by changing the `tool-bar-lines'
12899 frame parameter. */
12900 if (change_height_p)
12902 int nrows;
12903 int new_height = tool_bar_height (f, &nrows, true);
12905 change_height_p = ((EQ (Vauto_resize_tool_bars, Qgrow_only)
12906 && !f->minimize_tool_bar_window_p)
12907 ? (new_height > WINDOW_PIXEL_HEIGHT (w))
12908 : (new_height != WINDOW_PIXEL_HEIGHT (w)));
12909 f->minimize_tool_bar_window_p = false;
12911 if (change_height_p)
12913 x_change_tool_bar_height (f, new_height);
12914 frame_default_tool_bar_height = new_height;
12915 clear_glyph_matrix (w->desired_matrix);
12916 f->n_tool_bar_rows = nrows;
12917 f->fonts_changed = true;
12919 return true;
12924 f->minimize_tool_bar_window_p = false;
12925 return false;
12927 #endif /* USE_GTK || HAVE_NS */
12930 #if ! defined (USE_GTK) && ! defined (HAVE_NS)
12932 /* Get information about the tool-bar item which is displayed in GLYPH
12933 on frame F. Return in *PROP_IDX the index where tool-bar item
12934 properties start in F->tool_bar_items. Value is false if
12935 GLYPH doesn't display a tool-bar item. */
12937 static bool
12938 tool_bar_item_info (struct frame *f, struct glyph *glyph, int *prop_idx)
12940 Lisp_Object prop;
12941 int charpos;
12943 /* This function can be called asynchronously, which means we must
12944 exclude any possibility that Fget_text_property signals an
12945 error. */
12946 charpos = min (SCHARS (f->current_tool_bar_string), glyph->charpos);
12947 charpos = max (0, charpos);
12949 /* Get the text property `menu-item' at pos. The value of that
12950 property is the start index of this item's properties in
12951 F->tool_bar_items. */
12952 prop = Fget_text_property (make_number (charpos),
12953 Qmenu_item, f->current_tool_bar_string);
12954 if (! INTEGERP (prop))
12955 return false;
12956 *prop_idx = XINT (prop);
12957 return true;
12961 /* Get information about the tool-bar item at position X/Y on frame F.
12962 Return in *GLYPH a pointer to the glyph of the tool-bar item in
12963 the current matrix of the tool-bar window of F, or NULL if not
12964 on a tool-bar item. Return in *PROP_IDX the index of the tool-bar
12965 item in F->tool_bar_items. Value is
12967 -1 if X/Y is not on a tool-bar item
12968 0 if X/Y is on the same item that was highlighted before.
12969 1 otherwise. */
12971 static int
12972 get_tool_bar_item (struct frame *f, int x, int y, struct glyph **glyph,
12973 int *hpos, int *vpos, int *prop_idx)
12975 Mouse_HLInfo *hlinfo = MOUSE_HL_INFO (f);
12976 struct window *w = XWINDOW (f->tool_bar_window);
12977 int area;
12979 /* Find the glyph under X/Y. */
12980 *glyph = x_y_to_hpos_vpos (w, x, y, hpos, vpos, 0, 0, &area);
12981 if (*glyph == NULL)
12982 return -1;
12984 /* Get the start of this tool-bar item's properties in
12985 f->tool_bar_items. */
12986 if (!tool_bar_item_info (f, *glyph, prop_idx))
12987 return -1;
12989 /* Is mouse on the highlighted item? */
12990 if (EQ (f->tool_bar_window, hlinfo->mouse_face_window)
12991 && *vpos >= hlinfo->mouse_face_beg_row
12992 && *vpos <= hlinfo->mouse_face_end_row
12993 && (*vpos > hlinfo->mouse_face_beg_row
12994 || *hpos >= hlinfo->mouse_face_beg_col)
12995 && (*vpos < hlinfo->mouse_face_end_row
12996 || *hpos < hlinfo->mouse_face_end_col
12997 || hlinfo->mouse_face_past_end))
12998 return 0;
13000 return 1;
13004 /* EXPORT:
13005 Handle mouse button event on the tool-bar of frame F, at
13006 frame-relative coordinates X/Y. DOWN_P is true for a button press,
13007 false for button release. MODIFIERS is event modifiers for button
13008 release. */
13010 void
13011 handle_tool_bar_click (struct frame *f, int x, int y, bool down_p,
13012 int modifiers)
13014 Mouse_HLInfo *hlinfo = MOUSE_HL_INFO (f);
13015 struct window *w = XWINDOW (f->tool_bar_window);
13016 int hpos, vpos, prop_idx;
13017 struct glyph *glyph;
13018 Lisp_Object enabled_p;
13019 int ts;
13021 /* If not on the highlighted tool-bar item, and mouse-highlight is
13022 non-nil, return. This is so we generate the tool-bar button
13023 click only when the mouse button is released on the same item as
13024 where it was pressed. However, when mouse-highlight is disabled,
13025 generate the click when the button is released regardless of the
13026 highlight, since tool-bar items are not highlighted in that
13027 case. */
13028 frame_to_window_pixel_xy (w, &x, &y);
13029 ts = get_tool_bar_item (f, x, y, &glyph, &hpos, &vpos, &prop_idx);
13030 if (ts == -1
13031 || (ts != 0 && !NILP (Vmouse_highlight)))
13032 return;
13034 /* When mouse-highlight is off, generate the click for the item
13035 where the button was pressed, disregarding where it was
13036 released. */
13037 if (NILP (Vmouse_highlight) && !down_p)
13038 prop_idx = f->last_tool_bar_item;
13040 /* If item is disabled, do nothing. */
13041 enabled_p = AREF (f->tool_bar_items, prop_idx + TOOL_BAR_ITEM_ENABLED_P);
13042 if (NILP (enabled_p))
13043 return;
13045 if (down_p)
13047 /* Show item in pressed state. */
13048 if (!NILP (Vmouse_highlight))
13049 show_mouse_face (hlinfo, DRAW_IMAGE_SUNKEN);
13050 f->last_tool_bar_item = prop_idx;
13052 else
13054 Lisp_Object key, frame;
13055 struct input_event event;
13056 EVENT_INIT (event);
13058 /* Show item in released state. */
13059 if (!NILP (Vmouse_highlight))
13060 show_mouse_face (hlinfo, DRAW_IMAGE_RAISED);
13062 key = AREF (f->tool_bar_items, prop_idx + TOOL_BAR_ITEM_KEY);
13064 XSETFRAME (frame, f);
13065 event.kind = TOOL_BAR_EVENT;
13066 event.frame_or_window = frame;
13067 event.arg = frame;
13068 kbd_buffer_store_event (&event);
13070 event.kind = TOOL_BAR_EVENT;
13071 event.frame_or_window = frame;
13072 event.arg = key;
13073 event.modifiers = modifiers;
13074 kbd_buffer_store_event (&event);
13075 f->last_tool_bar_item = -1;
13080 /* Possibly highlight a tool-bar item on frame F when mouse moves to
13081 tool-bar window-relative coordinates X/Y. Called from
13082 note_mouse_highlight. */
13084 static void
13085 note_tool_bar_highlight (struct frame *f, int x, int y)
13087 Lisp_Object window = f->tool_bar_window;
13088 struct window *w = XWINDOW (window);
13089 Display_Info *dpyinfo = FRAME_DISPLAY_INFO (f);
13090 Mouse_HLInfo *hlinfo = MOUSE_HL_INFO (f);
13091 int hpos, vpos;
13092 struct glyph *glyph;
13093 struct glyph_row *row;
13094 int i;
13095 Lisp_Object enabled_p;
13096 int prop_idx;
13097 enum draw_glyphs_face draw = DRAW_IMAGE_RAISED;
13098 bool mouse_down_p;
13099 int rc;
13101 /* Function note_mouse_highlight is called with negative X/Y
13102 values when mouse moves outside of the frame. */
13103 if (x <= 0 || y <= 0)
13105 clear_mouse_face (hlinfo);
13106 return;
13109 rc = get_tool_bar_item (f, x, y, &glyph, &hpos, &vpos, &prop_idx);
13110 if (rc < 0)
13112 /* Not on tool-bar item. */
13113 clear_mouse_face (hlinfo);
13114 return;
13116 else if (rc == 0)
13117 /* On same tool-bar item as before. */
13118 goto set_help_echo;
13120 clear_mouse_face (hlinfo);
13122 /* Mouse is down, but on different tool-bar item? */
13123 mouse_down_p = (x_mouse_grabbed (dpyinfo)
13124 && f == dpyinfo->last_mouse_frame);
13126 if (mouse_down_p && f->last_tool_bar_item != prop_idx)
13127 return;
13129 draw = mouse_down_p ? DRAW_IMAGE_SUNKEN : DRAW_IMAGE_RAISED;
13131 /* If tool-bar item is not enabled, don't highlight it. */
13132 enabled_p = AREF (f->tool_bar_items, prop_idx + TOOL_BAR_ITEM_ENABLED_P);
13133 if (!NILP (enabled_p) && !NILP (Vmouse_highlight))
13135 /* Compute the x-position of the glyph. In front and past the
13136 image is a space. We include this in the highlighted area. */
13137 row = MATRIX_ROW (w->current_matrix, vpos);
13138 for (i = x = 0; i < hpos; ++i)
13139 x += row->glyphs[TEXT_AREA][i].pixel_width;
13141 /* Record this as the current active region. */
13142 hlinfo->mouse_face_beg_col = hpos;
13143 hlinfo->mouse_face_beg_row = vpos;
13144 hlinfo->mouse_face_beg_x = x;
13145 hlinfo->mouse_face_past_end = false;
13147 hlinfo->mouse_face_end_col = hpos + 1;
13148 hlinfo->mouse_face_end_row = vpos;
13149 hlinfo->mouse_face_end_x = x + glyph->pixel_width;
13150 hlinfo->mouse_face_window = window;
13151 hlinfo->mouse_face_face_id = TOOL_BAR_FACE_ID;
13153 /* Display it as active. */
13154 show_mouse_face (hlinfo, draw);
13157 set_help_echo:
13159 /* Set help_echo_string to a help string to display for this tool-bar item.
13160 XTread_socket does the rest. */
13161 help_echo_object = help_echo_window = Qnil;
13162 help_echo_pos = -1;
13163 help_echo_string = AREF (f->tool_bar_items, prop_idx + TOOL_BAR_ITEM_HELP);
13164 if (NILP (help_echo_string))
13165 help_echo_string = AREF (f->tool_bar_items, prop_idx + TOOL_BAR_ITEM_CAPTION);
13168 #endif /* !USE_GTK && !HAVE_NS */
13170 #endif /* HAVE_WINDOW_SYSTEM */
13174 /************************************************************************
13175 Horizontal scrolling
13176 ************************************************************************/
13178 /* For all leaf windows in the window tree rooted at WINDOW, set their
13179 hscroll value so that PT is (i) visible in the window, and (ii) so
13180 that it is not within a certain margin at the window's left and
13181 right border. Value is true if any window's hscroll has been
13182 changed. */
13184 static bool
13185 hscroll_window_tree (Lisp_Object window)
13187 bool hscrolled_p = false;
13188 bool hscroll_relative_p = FLOATP (Vhscroll_step);
13189 int hscroll_step_abs = 0;
13190 double hscroll_step_rel = 0;
13192 if (hscroll_relative_p)
13194 hscroll_step_rel = XFLOAT_DATA (Vhscroll_step);
13195 if (hscroll_step_rel < 0)
13197 hscroll_relative_p = false;
13198 hscroll_step_abs = 0;
13201 else if (TYPE_RANGED_INTEGERP (int, Vhscroll_step))
13203 hscroll_step_abs = XINT (Vhscroll_step);
13204 if (hscroll_step_abs < 0)
13205 hscroll_step_abs = 0;
13207 else
13208 hscroll_step_abs = 0;
13210 while (WINDOWP (window))
13212 struct window *w = XWINDOW (window);
13214 if (WINDOWP (w->contents))
13215 hscrolled_p |= hscroll_window_tree (w->contents);
13216 else if (w->cursor.vpos >= 0)
13218 int h_margin;
13219 int text_area_width;
13220 struct glyph_row *cursor_row;
13221 struct glyph_row *bottom_row;
13223 bottom_row = MATRIX_BOTTOM_TEXT_ROW (w->desired_matrix, w);
13224 if (w->cursor.vpos < bottom_row - w->desired_matrix->rows)
13225 cursor_row = MATRIX_ROW (w->desired_matrix, w->cursor.vpos);
13226 else
13227 cursor_row = bottom_row - 1;
13229 if (!cursor_row->enabled_p)
13231 bottom_row = MATRIX_BOTTOM_TEXT_ROW (w->current_matrix, w);
13232 if (w->cursor.vpos < bottom_row - w->current_matrix->rows)
13233 cursor_row = MATRIX_ROW (w->current_matrix, w->cursor.vpos);
13234 else
13235 cursor_row = bottom_row - 1;
13237 bool row_r2l_p = cursor_row->reversed_p;
13238 bool hscl = hscrolling_current_line_p (w);
13239 int x_offset = 0;
13240 /* When line numbers are displayed, we need to account for
13241 the horizontal space they consume. */
13242 if (!NILP (Vdisplay_line_numbers))
13244 struct glyph *g;
13245 if (!row_r2l_p)
13247 for (g = cursor_row->glyphs[TEXT_AREA];
13248 g < cursor_row->glyphs[TEXT_AREA]
13249 + cursor_row->used[TEXT_AREA];
13250 g++)
13252 if (!(NILP (g->object) && g->charpos < 0))
13253 break;
13254 x_offset += g->pixel_width;
13257 else
13259 for (g = cursor_row->glyphs[TEXT_AREA]
13260 + cursor_row->used[TEXT_AREA];
13261 g > cursor_row->glyphs[TEXT_AREA];
13262 g--)
13264 if (!(NILP ((g - 1)->object) && (g - 1)->charpos < 0))
13265 break;
13266 x_offset += (g - 1)->pixel_width;
13270 if (cursor_row->truncated_on_left_p)
13272 /* On TTY frames, don't count the left truncation glyph. */
13273 struct frame *f = XFRAME (WINDOW_FRAME (w));
13274 x_offset -= (FRAME_TERMCAP_P (f) || FRAME_MSDOS_P (f));
13277 text_area_width = window_box_width (w, TEXT_AREA);
13279 /* Scroll when cursor is inside this scroll margin. */
13280 h_margin = hscroll_margin * WINDOW_FRAME_COLUMN_WIDTH (w);
13282 /* If the position of this window's point has explicitly
13283 changed, no more suspend auto hscrolling. */
13284 if (w->suspend_auto_hscroll
13285 && NILP (Fequal (Fwindow_point (window),
13286 Fwindow_old_point (window))))
13288 w->suspend_auto_hscroll = false;
13289 /* When hscrolling just the current line, and the rest
13290 of lines were temporarily hscrolled, but no longer
13291 are, force thorough redisplay of this window, to show
13292 the effect of disabling hscroll suspension immediately. */
13293 if (w->min_hscroll == 0 && w->hscroll > 0
13294 && EQ (Fbuffer_local_value (Qauto_hscroll_mode, w->contents),
13295 Qcurrent_line))
13296 SET_FRAME_GARBAGED (XFRAME (w->frame));
13299 /* Remember window point. */
13300 Fset_marker (w->old_pointm,
13301 ((w == XWINDOW (selected_window))
13302 ? make_number (BUF_PT (XBUFFER (w->contents)))
13303 : Fmarker_position (w->pointm)),
13304 w->contents);
13306 if (!NILP (Fbuffer_local_value (Qauto_hscroll_mode, w->contents))
13307 && !w->suspend_auto_hscroll
13308 /* In some pathological cases, like restoring a window
13309 configuration into a frame that is much smaller than
13310 the one from which the configuration was saved, we
13311 get glyph rows whose start and end have zero buffer
13312 positions, which we cannot handle below. Just skip
13313 such windows. */
13314 && CHARPOS (cursor_row->start.pos) >= BUF_BEG (w->contents)
13315 /* For left-to-right rows, hscroll when cursor is either
13316 (i) inside the right hscroll margin, or (ii) if it is
13317 inside the left margin and the window is already
13318 hscrolled. */
13319 && ((!row_r2l_p
13320 && ((w->hscroll && w->cursor.x <= h_margin + x_offset)
13321 || (cursor_row->enabled_p
13322 && cursor_row->truncated_on_right_p
13323 && (w->cursor.x >= text_area_width - h_margin))))
13324 /* For right-to-left rows, the logic is similar,
13325 except that rules for scrolling to left and right
13326 are reversed. E.g., if cursor.x <= h_margin, we
13327 need to hscroll "to the right" unconditionally,
13328 and that will scroll the screen to the left so as
13329 to reveal the next portion of the row. */
13330 || (row_r2l_p
13331 && ((cursor_row->enabled_p
13332 /* FIXME: It is confusing to set the
13333 truncated_on_right_p flag when R2L rows
13334 are actually truncated on the left. */
13335 && cursor_row->truncated_on_right_p
13336 && w->cursor.x <= h_margin)
13337 || (w->hscroll
13338 && (w->cursor.x >= (text_area_width - h_margin
13339 - x_offset)))))
13340 /* This last condition is needed when moving
13341 vertically from an hscrolled line to a short line
13342 that doesn't need to be hscrolled. If we omit
13343 this condition, the line from which we move will
13344 remain hscrolled. */
13345 || (hscl
13346 && w->hscroll != w->min_hscroll
13347 && !cursor_row->truncated_on_left_p)))
13349 struct it it;
13350 ptrdiff_t hscroll;
13351 struct buffer *saved_current_buffer;
13352 ptrdiff_t pt;
13353 int wanted_x;
13355 /* Find point in a display of infinite width. */
13356 saved_current_buffer = current_buffer;
13357 current_buffer = XBUFFER (w->contents);
13359 if (w == XWINDOW (selected_window))
13360 pt = PT;
13361 else
13362 pt = clip_to_bounds (BEGV, marker_position (w->pointm), ZV);
13364 /* Move iterator to pt starting at cursor_row->start in
13365 a line with infinite width. */
13366 init_to_row_start (&it, w, cursor_row);
13367 if (hscl)
13368 it.first_visible_x = window_hscroll_limited (w, it.f)
13369 * FRAME_COLUMN_WIDTH (it.f);
13370 it.last_visible_x = DISP_INFINITY;
13371 move_it_in_display_line_to (&it, pt, -1, MOVE_TO_POS);
13372 /* If the line ends in an overlay string with a newline,
13373 we might infloop, because displaying the window will
13374 want to put the cursor after the overlay, i.e. at X
13375 coordinate of zero on the next screen line. So we
13376 use the buffer position prior to the overlay string
13377 instead. */
13378 if (it.method == GET_FROM_STRING && pt > 1)
13380 init_to_row_start (&it, w, cursor_row);
13381 if (hscl)
13382 it.first_visible_x = (window_hscroll_limited (w, it.f)
13383 * FRAME_COLUMN_WIDTH (it.f));
13384 move_it_in_display_line_to (&it, pt - 1, -1, MOVE_TO_POS);
13386 current_buffer = saved_current_buffer;
13388 /* Position cursor in window. */
13389 if (!hscroll_relative_p && hscroll_step_abs == 0)
13390 hscroll = max (0, (it.current_x
13391 - (ITERATOR_AT_END_OF_LINE_P (&it)
13392 ? (text_area_width - 4 * FRAME_COLUMN_WIDTH (it.f))
13393 : (text_area_width / 2))))
13394 / FRAME_COLUMN_WIDTH (it.f);
13395 else if ((!row_r2l_p
13396 && w->cursor.x >= text_area_width - h_margin)
13397 || (row_r2l_p && w->cursor.x <= h_margin))
13399 if (hscroll_relative_p)
13400 wanted_x = text_area_width * (1 - hscroll_step_rel)
13401 - h_margin;
13402 else
13403 wanted_x = text_area_width
13404 - hscroll_step_abs * FRAME_COLUMN_WIDTH (it.f)
13405 - h_margin;
13406 hscroll
13407 = max (0, it.current_x - wanted_x) / FRAME_COLUMN_WIDTH (it.f);
13409 else
13411 if (hscroll_relative_p)
13412 wanted_x = text_area_width * hscroll_step_rel
13413 + h_margin;
13414 else
13415 wanted_x = hscroll_step_abs * FRAME_COLUMN_WIDTH (it.f)
13416 + h_margin;
13417 hscroll
13418 = max (0, it.current_x - wanted_x) / FRAME_COLUMN_WIDTH (it.f);
13420 hscroll = max (hscroll, w->min_hscroll);
13422 /* Don't prevent redisplay optimizations if hscroll
13423 hasn't changed, as it will unnecessarily slow down
13424 redisplay. */
13425 if (w->hscroll != hscroll
13426 /* When hscrolling only the current line, we need to
13427 report hscroll even if its value is equal to the
13428 previous one, because the new line might need a
13429 different value. */
13430 || (hscl && w->last_cursor_vpos != w->cursor.vpos))
13432 struct buffer *b = XBUFFER (w->contents);
13433 b->prevent_redisplay_optimizations_p = true;
13434 w->hscroll = hscroll;
13435 hscrolled_p = true;
13440 window = w->next;
13443 /* Value is true if hscroll of any leaf window has been changed. */
13444 return hscrolled_p;
13448 /* Set hscroll so that cursor is visible and not inside horizontal
13449 scroll margins for all windows in the tree rooted at WINDOW. See
13450 also hscroll_window_tree above. Value is true if any window's
13451 hscroll has been changed. If it has, desired matrices on the frame
13452 of WINDOW are cleared. */
13454 static bool
13455 hscroll_windows (Lisp_Object window)
13457 bool hscrolled_p = hscroll_window_tree (window);
13458 if (hscrolled_p)
13459 clear_desired_matrices (XFRAME (WINDOW_FRAME (XWINDOW (window))));
13460 return hscrolled_p;
13465 /************************************************************************
13466 Redisplay
13467 ************************************************************************/
13469 /* Variables holding some state of redisplay if GLYPH_DEBUG is defined.
13470 This is sometimes handy to have in a debugger session. */
13472 #ifdef GLYPH_DEBUG
13474 /* First and last unchanged row for try_window_id. */
13476 static int debug_first_unchanged_at_end_vpos;
13477 static int debug_last_unchanged_at_beg_vpos;
13479 /* Delta vpos and y. */
13481 static int debug_dvpos, debug_dy;
13483 /* Delta in characters and bytes for try_window_id. */
13485 static ptrdiff_t debug_delta, debug_delta_bytes;
13487 /* Values of window_end_pos and window_end_vpos at the end of
13488 try_window_id. */
13490 static ptrdiff_t debug_end_vpos;
13492 /* Append a string to W->desired_matrix->method. FMT is a printf
13493 format string. If trace_redisplay_p is true also printf the
13494 resulting string to stderr. */
13496 static void debug_method_add (struct window *, char const *, ...)
13497 ATTRIBUTE_FORMAT_PRINTF (2, 3);
13499 static void
13500 debug_method_add (struct window *w, char const *fmt, ...)
13502 void *ptr = w;
13503 char *method = w->desired_matrix->method;
13504 int len = strlen (method);
13505 int size = sizeof w->desired_matrix->method;
13506 int remaining = size - len - 1;
13507 va_list ap;
13509 if (len && remaining)
13511 method[len] = '|';
13512 --remaining, ++len;
13515 va_start (ap, fmt);
13516 vsnprintf (method + len, remaining + 1, fmt, ap);
13517 va_end (ap);
13519 if (trace_redisplay_p)
13520 fprintf (stderr, "%p (%s): %s\n",
13521 ptr,
13522 ((BUFFERP (w->contents)
13523 && STRINGP (BVAR (XBUFFER (w->contents), name)))
13524 ? SSDATA (BVAR (XBUFFER (w->contents), name))
13525 : "no buffer"),
13526 method + len);
13529 #endif /* GLYPH_DEBUG */
13532 /* Value is true if all changes in window W, which displays
13533 current_buffer, are in the text between START and END. START is a
13534 buffer position, END is given as a distance from Z. Used in
13535 redisplay_internal for display optimization. */
13537 static bool
13538 text_outside_line_unchanged_p (struct window *w,
13539 ptrdiff_t start, ptrdiff_t end)
13541 bool unchanged_p = true;
13543 /* If text or overlays have changed, see where. */
13544 if (window_outdated (w))
13546 /* Gap in the line? */
13547 if (GPT < start || Z - GPT < end)
13548 unchanged_p = false;
13550 /* Changes start in front of the line, or end after it? */
13551 if (unchanged_p
13552 && (BEG_UNCHANGED < start - 1
13553 || END_UNCHANGED < end))
13554 unchanged_p = false;
13556 /* If selective display, can't optimize if changes start at the
13557 beginning of the line. */
13558 if (unchanged_p
13559 && INTEGERP (BVAR (current_buffer, selective_display))
13560 && XINT (BVAR (current_buffer, selective_display)) > 0
13561 && (BEG_UNCHANGED < start || GPT <= start))
13562 unchanged_p = false;
13564 /* If there are overlays at the start or end of the line, these
13565 may have overlay strings with newlines in them. A change at
13566 START, for instance, may actually concern the display of such
13567 overlay strings as well, and they are displayed on different
13568 lines. So, quickly rule out this case. (For the future, it
13569 might be desirable to implement something more telling than
13570 just BEG/END_UNCHANGED.) */
13571 if (unchanged_p)
13573 if (BEG + BEG_UNCHANGED == start
13574 && overlay_touches_p (start))
13575 unchanged_p = false;
13576 if (END_UNCHANGED == end
13577 && overlay_touches_p (Z - end))
13578 unchanged_p = false;
13581 /* Under bidi reordering, adding or deleting a character in the
13582 beginning of a paragraph, before the first strong directional
13583 character, can change the base direction of the paragraph (unless
13584 the buffer specifies a fixed paragraph direction), which will
13585 require redisplaying the whole paragraph. It might be worthwhile
13586 to find the paragraph limits and widen the range of redisplayed
13587 lines to that, but for now just give up this optimization. */
13588 if (!NILP (BVAR (XBUFFER (w->contents), bidi_display_reordering))
13589 && NILP (BVAR (XBUFFER (w->contents), bidi_paragraph_direction)))
13590 unchanged_p = false;
13593 return unchanged_p;
13597 /* Do a frame update, taking possible shortcuts into account. This is
13598 the main external entry point for redisplay.
13600 If the last redisplay displayed an echo area message and that message
13601 is no longer requested, we clear the echo area or bring back the
13602 mini-buffer if that is in use. */
13604 void
13605 redisplay (void)
13607 redisplay_internal ();
13611 static Lisp_Object
13612 overlay_arrow_string_or_property (Lisp_Object var)
13614 Lisp_Object val;
13616 if (val = Fget (var, Qoverlay_arrow_string), STRINGP (val))
13617 return val;
13619 return Voverlay_arrow_string;
13622 /* Return true if there are any overlay-arrows in current_buffer. */
13623 static bool
13624 overlay_arrow_in_current_buffer_p (void)
13626 Lisp_Object vlist;
13628 for (vlist = Voverlay_arrow_variable_list;
13629 CONSP (vlist);
13630 vlist = XCDR (vlist))
13632 Lisp_Object var = XCAR (vlist);
13633 Lisp_Object val;
13635 if (!SYMBOLP (var))
13636 continue;
13637 val = find_symbol_value (var);
13638 if (MARKERP (val)
13639 && current_buffer == XMARKER (val)->buffer)
13640 return true;
13642 return false;
13646 /* Return true if any overlay_arrows have moved or overlay-arrow-string
13647 has changed.
13648 If SET_REDISPLAY is true, additionally, set the `redisplay' bit in those
13649 buffers that are affected. */
13651 static bool
13652 overlay_arrows_changed_p (bool set_redisplay)
13654 Lisp_Object vlist;
13655 bool changed = false;
13657 for (vlist = Voverlay_arrow_variable_list;
13658 CONSP (vlist);
13659 vlist = XCDR (vlist))
13661 Lisp_Object var = XCAR (vlist);
13662 Lisp_Object val, pstr;
13664 if (!SYMBOLP (var))
13665 continue;
13666 val = find_symbol_value (var);
13667 if (!MARKERP (val))
13668 continue;
13669 if (! EQ (COERCE_MARKER (val),
13670 /* FIXME: Don't we have a problem, using such a global
13671 * "last-position" if the variable is buffer-local? */
13672 Fget (var, Qlast_arrow_position))
13673 || ! (pstr = overlay_arrow_string_or_property (var),
13674 EQ (pstr, Fget (var, Qlast_arrow_string))))
13676 struct buffer *buf = XMARKER (val)->buffer;
13678 if (set_redisplay)
13680 if (buf)
13681 bset_redisplay (buf);
13682 changed = true;
13684 else
13685 return true;
13688 return changed;
13691 /* Mark overlay arrows to be updated on next redisplay. */
13693 static void
13694 update_overlay_arrows (int up_to_date)
13696 Lisp_Object vlist;
13698 for (vlist = Voverlay_arrow_variable_list;
13699 CONSP (vlist);
13700 vlist = XCDR (vlist))
13702 Lisp_Object var = XCAR (vlist);
13704 if (!SYMBOLP (var))
13705 continue;
13707 if (up_to_date > 0)
13709 Lisp_Object val = find_symbol_value (var);
13710 if (!MARKERP (val))
13711 continue;
13712 Fput (var, Qlast_arrow_position,
13713 COERCE_MARKER (val));
13714 Fput (var, Qlast_arrow_string,
13715 overlay_arrow_string_or_property (var));
13717 else if (up_to_date < 0
13718 || !NILP (Fget (var, Qlast_arrow_position)))
13720 Fput (var, Qlast_arrow_position, Qt);
13721 Fput (var, Qlast_arrow_string, Qt);
13727 /* Return overlay arrow string to display at row.
13728 Return integer (bitmap number) for arrow bitmap in left fringe.
13729 Return nil if no overlay arrow. */
13731 static Lisp_Object
13732 overlay_arrow_at_row (struct it *it, struct glyph_row *row)
13734 Lisp_Object vlist;
13736 for (vlist = Voverlay_arrow_variable_list;
13737 CONSP (vlist);
13738 vlist = XCDR (vlist))
13740 Lisp_Object var = XCAR (vlist);
13741 Lisp_Object val;
13743 if (!SYMBOLP (var))
13744 continue;
13746 val = find_symbol_value (var);
13748 if (MARKERP (val)
13749 && current_buffer == XMARKER (val)->buffer
13750 && (MATRIX_ROW_START_CHARPOS (row) == marker_position (val)))
13752 if (FRAME_WINDOW_P (it->f)
13753 /* FIXME: if ROW->reversed_p is set, this should test
13754 the right fringe, not the left one. */
13755 && WINDOW_LEFT_FRINGE_WIDTH (it->w) > 0)
13757 #ifdef HAVE_WINDOW_SYSTEM
13758 if (val = Fget (var, Qoverlay_arrow_bitmap), SYMBOLP (val))
13760 int fringe_bitmap = lookup_fringe_bitmap (val);
13761 if (fringe_bitmap != 0)
13762 return make_number (fringe_bitmap);
13764 #endif
13765 return make_number (-1); /* Use default arrow bitmap. */
13767 return overlay_arrow_string_or_property (var);
13771 return Qnil;
13774 /* Return true if point moved out of or into a composition. Otherwise
13775 return false. PREV_BUF and PREV_PT are the last point buffer and
13776 position. BUF and PT are the current point buffer and position. */
13778 static bool
13779 check_point_in_composition (struct buffer *prev_buf, ptrdiff_t prev_pt,
13780 struct buffer *buf, ptrdiff_t pt)
13782 ptrdiff_t start, end;
13783 Lisp_Object prop;
13784 Lisp_Object buffer;
13786 XSETBUFFER (buffer, buf);
13787 /* Check a composition at the last point if point moved within the
13788 same buffer. */
13789 if (prev_buf == buf)
13791 if (prev_pt == pt)
13792 /* Point didn't move. */
13793 return false;
13795 if (prev_pt > BUF_BEGV (buf) && prev_pt < BUF_ZV (buf)
13796 && find_composition (prev_pt, -1, &start, &end, &prop, buffer)
13797 && composition_valid_p (start, end, prop)
13798 && start < prev_pt && end > prev_pt)
13799 /* The last point was within the composition. Return true iff
13800 point moved out of the composition. */
13801 return (pt <= start || pt >= end);
13804 /* Check a composition at the current point. */
13805 return (pt > BUF_BEGV (buf) && pt < BUF_ZV (buf)
13806 && find_composition (pt, -1, &start, &end, &prop, buffer)
13807 && composition_valid_p (start, end, prop)
13808 && start < pt && end > pt);
13811 /* Reconsider the clip changes of buffer which is displayed in W. */
13813 static void
13814 reconsider_clip_changes (struct window *w)
13816 struct buffer *b = XBUFFER (w->contents);
13818 if (b->clip_changed
13819 && w->window_end_valid
13820 && w->current_matrix->buffer == b
13821 && w->current_matrix->zv == BUF_ZV (b)
13822 && w->current_matrix->begv == BUF_BEGV (b))
13823 b->clip_changed = false;
13825 /* If display wasn't paused, and W is not a tool bar window, see if
13826 point has been moved into or out of a composition. In that case,
13827 set b->clip_changed to force updating the screen. If
13828 b->clip_changed has already been set, skip this check. */
13829 if (!b->clip_changed && w->window_end_valid)
13831 ptrdiff_t pt = (w == XWINDOW (selected_window)
13832 ? PT : marker_position (w->pointm));
13834 if ((w->current_matrix->buffer != b || pt != w->last_point)
13835 && check_point_in_composition (w->current_matrix->buffer,
13836 w->last_point, b, pt))
13837 b->clip_changed = true;
13841 static void
13842 propagate_buffer_redisplay (void)
13843 { /* Resetting b->text->redisplay is problematic!
13844 We can't just reset it in the case that some window that displays
13845 it has not been redisplayed; and such a window can stay
13846 unredisplayed for a long time if it's currently invisible.
13847 But we do want to reset it at the end of redisplay otherwise
13848 its displayed windows will keep being redisplayed over and over
13849 again.
13850 So we copy all b->text->redisplay flags up to their windows here,
13851 such that mark_window_display_accurate can safely reset
13852 b->text->redisplay. */
13853 Lisp_Object ws = window_list ();
13854 for (; CONSP (ws); ws = XCDR (ws))
13856 struct window *thisw = XWINDOW (XCAR (ws));
13857 struct buffer *thisb = XBUFFER (thisw->contents);
13858 if (thisb->text->redisplay)
13859 thisw->redisplay = true;
13863 #define STOP_POLLING \
13864 do { if (! polling_stopped_here) stop_polling (); \
13865 polling_stopped_here = true; } while (false)
13867 #define RESUME_POLLING \
13868 do { if (polling_stopped_here) start_polling (); \
13869 polling_stopped_here = false; } while (false)
13872 /* Perhaps in the future avoid recentering windows if it
13873 is not necessary; currently that causes some problems. */
13875 static void
13876 redisplay_internal (void)
13878 struct window *w = XWINDOW (selected_window);
13879 struct window *sw;
13880 struct frame *fr;
13881 bool pending;
13882 bool must_finish = false, match_p;
13883 struct text_pos tlbufpos, tlendpos;
13884 int number_of_visible_frames;
13885 ptrdiff_t count;
13886 struct frame *sf;
13887 bool polling_stopped_here = false;
13888 Lisp_Object tail, frame;
13890 /* Set a limit to the number of retries we perform due to horizontal
13891 scrolling, this avoids getting stuck in an uninterruptible
13892 infinite loop (Bug #24633). */
13893 enum { MAX_HSCROLL_RETRIES = 16 };
13894 int hscroll_retries = 0;
13896 /* Limit the number of retries for when frame(s) become garbaged as
13897 result of redisplaying them. Some packages set various redisplay
13898 hooks, such as window-scroll-functions, to run Lisp that always
13899 calls APIs which cause the frame's garbaged flag to become set,
13900 so we loop indefinitely. */
13901 enum {MAX_GARBAGED_FRAME_RETRIES = 2 };
13902 int garbaged_frame_retries = 0;
13904 /* True means redisplay has to consider all windows on all
13905 frames. False, only selected_window is considered. */
13906 bool consider_all_windows_p;
13908 /* True means redisplay has to redisplay the miniwindow. */
13909 bool update_miniwindow_p = false;
13911 TRACE ((stderr, "redisplay_internal %d\n", redisplaying_p));
13913 /* No redisplay if running in batch mode or frame is not yet fully
13914 initialized, or redisplay is explicitly turned off by setting
13915 Vinhibit_redisplay. */
13916 if (FRAME_INITIAL_P (SELECTED_FRAME ())
13917 || !NILP (Vinhibit_redisplay))
13918 return;
13920 /* Don't examine these until after testing Vinhibit_redisplay.
13921 When Emacs is shutting down, perhaps because its connection to
13922 X has dropped, we should not look at them at all. */
13923 fr = XFRAME (w->frame);
13924 sf = SELECTED_FRAME ();
13926 if (!fr->glyphs_initialized_p)
13927 return;
13929 #if defined (USE_X_TOOLKIT) || defined (USE_GTK) || defined (HAVE_NS)
13930 if (popup_activated ())
13931 return;
13932 #endif
13934 /* I don't think this happens but let's be paranoid. */
13935 if (redisplaying_p)
13936 return;
13938 /* Record a function that clears redisplaying_p
13939 when we leave this function. */
13940 count = SPECPDL_INDEX ();
13941 record_unwind_protect_void (unwind_redisplay);
13942 redisplaying_p = true;
13943 block_buffer_flips ();
13944 specbind (Qinhibit_free_realized_faces, Qnil);
13946 /* Record this function, so it appears on the profiler's backtraces. */
13947 record_in_backtrace (Qredisplay_internal_xC_functionx, 0, 0);
13949 FOR_EACH_FRAME (tail, frame)
13950 XFRAME (frame)->already_hscrolled_p = false;
13952 retry:
13953 /* Remember the currently selected window. */
13954 sw = w;
13956 pending = false;
13957 forget_escape_and_glyphless_faces ();
13959 inhibit_free_realized_faces = false;
13961 /* If face_change, init_iterator will free all realized faces, which
13962 includes the faces referenced from current matrices. So, we
13963 can't reuse current matrices in this case. */
13964 if (face_change)
13965 windows_or_buffers_changed = 47;
13967 if ((FRAME_TERMCAP_P (sf) || FRAME_MSDOS_P (sf))
13968 && FRAME_TTY (sf)->previous_frame != sf)
13970 /* Since frames on a single ASCII terminal share the same
13971 display area, displaying a different frame means redisplay
13972 the whole thing. */
13973 SET_FRAME_GARBAGED (sf);
13974 #ifndef DOS_NT
13975 set_tty_color_mode (FRAME_TTY (sf), sf);
13976 #endif
13977 FRAME_TTY (sf)->previous_frame = sf;
13980 /* Set the visible flags for all frames. Do this before checking for
13981 resized or garbaged frames; they want to know if their frames are
13982 visible. See the comment in frame.h for FRAME_SAMPLE_VISIBILITY. */
13983 number_of_visible_frames = 0;
13985 FOR_EACH_FRAME (tail, frame)
13987 struct frame *f = XFRAME (frame);
13989 if (FRAME_VISIBLE_P (f))
13991 ++number_of_visible_frames;
13992 /* Adjust matrices for visible frames only. */
13993 if (f->fonts_changed)
13995 adjust_frame_glyphs (f);
13996 /* Disable all redisplay optimizations for this frame.
13997 This is because adjust_frame_glyphs resets the
13998 enabled_p flag for all glyph rows of all windows, so
13999 many optimizations will fail anyway, and some might
14000 fail to test that flag and do bogus things as
14001 result. */
14002 SET_FRAME_GARBAGED (f);
14003 f->fonts_changed = false;
14005 /* If cursor type has been changed on the frame
14006 other than selected, consider all frames. */
14007 if (f != sf && f->cursor_type_changed)
14008 fset_redisplay (f);
14010 clear_desired_matrices (f);
14013 /* Notice any pending interrupt request to change frame size. */
14014 do_pending_window_change (true);
14016 /* Clear frames marked as garbaged. */
14017 clear_garbaged_frames ();
14019 /* Build menubar and tool-bar items. */
14020 if (NILP (Vmemory_full))
14021 prepare_menu_bars ();
14023 /* do_pending_window_change could change the selected_window due to
14024 frame resizing which makes the selected window too small.
14025 prepare_menu_bars may call lisp hooks and hence also change the
14026 selected_window. */
14027 if (WINDOWP (selected_window) && (w = XWINDOW (selected_window)) != sw)
14028 sw = w;
14030 reconsider_clip_changes (w);
14032 /* In most cases selected window displays current buffer. */
14033 match_p = XBUFFER (w->contents) == current_buffer;
14034 if (match_p)
14036 /* Detect case that we need to write or remove a star in the mode line. */
14037 if ((SAVE_MODIFF < MODIFF) != w->last_had_star)
14038 w->update_mode_line = true;
14040 if (mode_line_update_needed (w))
14041 w->update_mode_line = true;
14043 /* If reconsider_clip_changes above decided that the narrowing
14044 in the current buffer changed, make sure all other windows
14045 showing that buffer will be redisplayed. */
14046 if (current_buffer->clip_changed)
14047 bset_update_mode_line (current_buffer);
14050 /* Normally the message* functions will have already displayed and
14051 updated the echo area, but the frame may have been trashed, or
14052 the update may have been preempted, so display the echo area
14053 again here. Checking message_cleared_p captures the case that
14054 the echo area should be cleared. */
14055 if ((!NILP (echo_area_buffer[0]) && !display_last_displayed_message_p)
14056 || (!NILP (echo_area_buffer[1]) && display_last_displayed_message_p)
14057 || (message_cleared_p
14058 && minibuf_level == 0
14059 /* If the mini-window is currently selected, this means the
14060 echo-area doesn't show through. */
14061 && !MINI_WINDOW_P (XWINDOW (selected_window))))
14063 echo_area_display (false);
14065 /* If echo_area_display resizes the mini-window, the redisplay and
14066 window_sizes_changed flags of the selected frame are set, but
14067 it's too late for the hooks in window-size-change-functions,
14068 which have been examined already in prepare_menu_bars. So in
14069 that case we call the hooks here only for the selected frame. */
14070 if (sf->redisplay)
14072 ptrdiff_t count1 = SPECPDL_INDEX ();
14074 record_unwind_save_match_data ();
14075 run_window_size_change_functions (selected_frame);
14076 unbind_to (count1, Qnil);
14079 if (message_cleared_p)
14080 update_miniwindow_p = true;
14082 must_finish = true;
14084 /* If we don't display the current message, don't clear the
14085 message_cleared_p flag, because, if we did, we wouldn't clear
14086 the echo area in the next redisplay which doesn't preserve
14087 the echo area. */
14088 if (!display_last_displayed_message_p)
14089 message_cleared_p = false;
14091 else if (EQ (selected_window, minibuf_window)
14092 && (current_buffer->clip_changed || window_outdated (w))
14093 && resize_mini_window (w, false))
14095 if (sf->redisplay)
14097 ptrdiff_t count1 = SPECPDL_INDEX ();
14099 record_unwind_save_match_data ();
14100 run_window_size_change_functions (selected_frame);
14101 unbind_to (count1, Qnil);
14104 /* Resized active mini-window to fit the size of what it is
14105 showing if its contents might have changed. */
14106 must_finish = true;
14108 /* If window configuration was changed, frames may have been
14109 marked garbaged. Clear them or we will experience
14110 surprises wrt scrolling. */
14111 clear_garbaged_frames ();
14114 if (windows_or_buffers_changed && !update_mode_lines)
14115 /* Code that sets windows_or_buffers_changed doesn't distinguish whether
14116 only the windows's contents needs to be refreshed, or whether the
14117 mode-lines also need a refresh. */
14118 update_mode_lines = (windows_or_buffers_changed == REDISPLAY_SOME
14119 ? REDISPLAY_SOME : 32);
14121 /* If specs for an arrow have changed, do thorough redisplay
14122 to ensure we remove any arrow that should no longer exist. */
14123 /* Apparently, this is the only case where we update other windows,
14124 without updating other mode-lines. */
14125 overlay_arrows_changed_p (true);
14127 consider_all_windows_p = (update_mode_lines
14128 || windows_or_buffers_changed);
14130 #define AINC(a,i) \
14132 Lisp_Object entry = Fgethash (make_number (i), a, make_number (0)); \
14133 if (INTEGERP (entry)) \
14134 Fputhash (make_number (i), make_number (1 + XINT (entry)), a); \
14137 AINC (Vredisplay__all_windows_cause, windows_or_buffers_changed);
14138 AINC (Vredisplay__mode_lines_cause, update_mode_lines);
14140 /* Optimize the case that only the line containing the cursor in the
14141 selected window has changed. Variables starting with this_ are
14142 set in display_line and record information about the line
14143 containing the cursor. */
14144 tlbufpos = this_line_start_pos;
14145 tlendpos = this_line_end_pos;
14146 if (!consider_all_windows_p
14147 && CHARPOS (tlbufpos) > 0
14148 && !w->update_mode_line
14149 && !current_buffer->clip_changed
14150 && !current_buffer->prevent_redisplay_optimizations_p
14151 && FRAME_VISIBLE_P (XFRAME (w->frame))
14152 && !FRAME_OBSCURED_P (XFRAME (w->frame))
14153 && !XFRAME (w->frame)->cursor_type_changed
14154 && !XFRAME (w->frame)->face_change
14155 /* Make sure recorded data applies to current buffer, etc. */
14156 && this_line_buffer == current_buffer
14157 && match_p
14158 && !w->force_start
14159 && !w->optional_new_start
14160 /* Point must be on the line that we have info recorded about. */
14161 && PT >= CHARPOS (tlbufpos)
14162 && PT <= Z - CHARPOS (tlendpos)
14163 /* All text outside that line, including its final newline,
14164 must be unchanged. */
14165 && text_outside_line_unchanged_p (w, CHARPOS (tlbufpos),
14166 CHARPOS (tlendpos)))
14168 if (CHARPOS (tlbufpos) > BEGV
14169 && FETCH_BYTE (BYTEPOS (tlbufpos) - 1) != '\n'
14170 && (CHARPOS (tlbufpos) == ZV
14171 || FETCH_BYTE (BYTEPOS (tlbufpos)) == '\n'))
14172 /* Former continuation line has disappeared by becoming empty. */
14173 goto cancel;
14174 else if (window_outdated (w) || MINI_WINDOW_P (w))
14176 /* We have to handle the case of continuation around a
14177 wide-column character (see the comment in indent.c around
14178 line 1340).
14180 For instance, in the following case:
14182 -------- Insert --------
14183 K_A_N_\\ `a' K_A_N_a\ `X_' are wide-column chars.
14184 J_I_ ==> J_I_ `^^' are cursors.
14185 ^^ ^^
14186 -------- --------
14188 As we have to redraw the line above, we cannot use this
14189 optimization. */
14191 struct it it;
14192 int line_height_before = this_line_pixel_height;
14194 /* Note that start_display will handle the case that the
14195 line starting at tlbufpos is a continuation line. */
14196 start_display (&it, w, tlbufpos);
14198 /* Implementation note: It this still necessary? */
14199 if (it.current_x != this_line_start_x)
14200 goto cancel;
14202 TRACE ((stderr, "trying display optimization 1\n"));
14203 w->cursor.vpos = -1;
14204 overlay_arrow_seen = false;
14205 it.vpos = this_line_vpos;
14206 it.current_y = this_line_y;
14207 it.glyph_row = MATRIX_ROW (w->desired_matrix, this_line_vpos);
14208 display_line (&it, -1);
14210 /* If line contains point, is not continued,
14211 and ends at same distance from eob as before, we win. */
14212 if (w->cursor.vpos >= 0
14213 /* Line is not continued, otherwise this_line_start_pos
14214 would have been set to 0 in display_line. */
14215 && CHARPOS (this_line_start_pos)
14216 /* Line ends as before. */
14217 && CHARPOS (this_line_end_pos) == CHARPOS (tlendpos)
14218 /* Line has same height as before. Otherwise other lines
14219 would have to be shifted up or down. */
14220 && this_line_pixel_height == line_height_before)
14222 /* If this is not the window's last line, we must adjust
14223 the charstarts of the lines below. */
14224 if (it.current_y < it.last_visible_y)
14226 struct glyph_row *row
14227 = MATRIX_ROW (w->current_matrix, this_line_vpos + 1);
14228 ptrdiff_t delta, delta_bytes;
14230 /* We used to distinguish between two cases here,
14231 conditioned by Z - CHARPOS (tlendpos) == ZV, for
14232 when the line ends in a newline or the end of the
14233 buffer's accessible portion. But both cases did
14234 the same, so they were collapsed. */
14235 delta = (Z
14236 - CHARPOS (tlendpos)
14237 - MATRIX_ROW_START_CHARPOS (row));
14238 delta_bytes = (Z_BYTE
14239 - BYTEPOS (tlendpos)
14240 - MATRIX_ROW_START_BYTEPOS (row));
14242 increment_matrix_positions (w->current_matrix,
14243 this_line_vpos + 1,
14244 w->current_matrix->nrows,
14245 delta, delta_bytes);
14248 /* If this row displays text now but previously didn't,
14249 or vice versa, w->window_end_vpos may have to be
14250 adjusted. */
14251 if (MATRIX_ROW_DISPLAYS_TEXT_P (it.glyph_row - 1))
14253 if (w->window_end_vpos < this_line_vpos)
14254 w->window_end_vpos = this_line_vpos;
14256 else if (w->window_end_vpos == this_line_vpos
14257 && this_line_vpos > 0)
14258 w->window_end_vpos = this_line_vpos - 1;
14259 w->window_end_valid = false;
14261 /* Update hint: No need to try to scroll in update_window. */
14262 w->desired_matrix->no_scrolling_p = true;
14264 #ifdef GLYPH_DEBUG
14265 *w->desired_matrix->method = 0;
14266 debug_method_add (w, "optimization 1");
14267 #endif
14268 #ifdef HAVE_WINDOW_SYSTEM
14269 update_window_fringes (w, false);
14270 #endif
14271 goto update;
14273 else
14274 goto cancel;
14276 else if (/* Cursor position hasn't changed. */
14277 PT == w->last_point
14278 /* Make sure the cursor was last displayed
14279 in this window. Otherwise we have to reposition it. */
14281 /* PXW: Must be converted to pixels, probably. */
14282 && 0 <= w->cursor.vpos
14283 && w->cursor.vpos < WINDOW_TOTAL_LINES (w))
14285 if (!must_finish)
14287 do_pending_window_change (true);
14288 /* If selected_window changed, redisplay again. */
14289 if (WINDOWP (selected_window)
14290 && (w = XWINDOW (selected_window)) != sw)
14291 goto retry;
14293 /* We used to always goto end_of_redisplay here, but this
14294 isn't enough if we have a blinking cursor. */
14295 if (w->cursor_off_p == w->last_cursor_off_p)
14296 goto end_of_redisplay;
14298 goto update;
14300 /* If highlighting the region, or if the cursor is in the echo area,
14301 then we can't just move the cursor. */
14302 else if (NILP (Vshow_trailing_whitespace)
14303 && !cursor_in_echo_area)
14305 struct it it;
14306 struct glyph_row *row;
14308 /* Skip from tlbufpos to PT and see where it is. Note that
14309 PT may be in invisible text. If so, we will end at the
14310 next visible position. */
14311 init_iterator (&it, w, CHARPOS (tlbufpos), BYTEPOS (tlbufpos),
14312 NULL, DEFAULT_FACE_ID);
14313 it.current_x = this_line_start_x;
14314 it.current_y = this_line_y;
14315 it.vpos = this_line_vpos;
14317 /* The call to move_it_to stops in front of PT, but
14318 moves over before-strings. */
14319 move_it_to (&it, PT, -1, -1, -1, MOVE_TO_POS);
14321 if (it.vpos == this_line_vpos
14322 && (row = MATRIX_ROW (w->current_matrix, this_line_vpos),
14323 row->enabled_p))
14325 eassert (this_line_vpos == it.vpos);
14326 eassert (this_line_y == it.current_y);
14327 set_cursor_from_row (w, row, w->current_matrix, 0, 0, 0, 0);
14328 if (cursor_row_fully_visible_p (w, false, true))
14330 #ifdef GLYPH_DEBUG
14331 *w->desired_matrix->method = 0;
14332 debug_method_add (w, "optimization 3");
14333 #endif
14334 goto update;
14336 else
14337 goto cancel;
14339 else
14340 goto cancel;
14343 cancel:
14344 /* Text changed drastically or point moved off of line. */
14345 SET_MATRIX_ROW_ENABLED_P (w->desired_matrix, this_line_vpos, false);
14348 CHARPOS (this_line_start_pos) = 0;
14349 ++clear_face_cache_count;
14350 #ifdef HAVE_WINDOW_SYSTEM
14351 ++clear_image_cache_count;
14352 #endif
14354 /* Build desired matrices, and update the display. If
14355 consider_all_windows_p, do it for all windows on all frames that
14356 require redisplay, as specified by their 'redisplay' flag.
14357 Otherwise do it for selected_window, only. */
14359 if (consider_all_windows_p)
14361 FOR_EACH_FRAME (tail, frame)
14362 XFRAME (frame)->updated_p = false;
14364 propagate_buffer_redisplay ();
14366 FOR_EACH_FRAME (tail, frame)
14368 struct frame *f = XFRAME (frame);
14370 /* We don't have to do anything for unselected terminal
14371 frames. */
14372 if ((FRAME_TERMCAP_P (f) || FRAME_MSDOS_P (f))
14373 && !EQ (FRAME_TTY (f)->top_frame, frame))
14374 continue;
14376 retry_frame:
14377 if (FRAME_WINDOW_P (f) || FRAME_TERMCAP_P (f) || f == sf)
14379 bool gcscrollbars
14380 /* Only GC scrollbars when we redisplay the whole frame. */
14381 = f->redisplay || !REDISPLAY_SOME_P ();
14382 bool f_redisplay_flag = f->redisplay;
14383 /* Mark all the scroll bars to be removed; we'll redeem
14384 the ones we want when we redisplay their windows. */
14385 if (gcscrollbars && FRAME_TERMINAL (f)->condemn_scroll_bars_hook)
14386 FRAME_TERMINAL (f)->condemn_scroll_bars_hook (f);
14388 if (FRAME_VISIBLE_P (f) && !FRAME_OBSCURED_P (f))
14389 redisplay_windows (FRAME_ROOT_WINDOW (f));
14390 /* Remember that the invisible frames need to be redisplayed next
14391 time they're visible. */
14392 else if (!REDISPLAY_SOME_P ())
14393 f->redisplay = true;
14395 /* The X error handler may have deleted that frame. */
14396 if (!FRAME_LIVE_P (f))
14397 continue;
14399 /* Any scroll bars which redisplay_windows should have
14400 nuked should now go away. */
14401 if (gcscrollbars && FRAME_TERMINAL (f)->judge_scroll_bars_hook)
14402 FRAME_TERMINAL (f)->judge_scroll_bars_hook (f);
14404 if (FRAME_VISIBLE_P (f) && !FRAME_OBSCURED_P (f))
14406 /* If fonts changed on visible frame, display again. */
14407 if (f->fonts_changed)
14409 adjust_frame_glyphs (f);
14410 /* Disable all redisplay optimizations for this
14411 frame. For the reasons, see the comment near
14412 the previous call to adjust_frame_glyphs above. */
14413 SET_FRAME_GARBAGED (f);
14414 f->fonts_changed = false;
14415 goto retry_frame;
14418 /* See if we have to hscroll. */
14419 if (!f->already_hscrolled_p)
14421 f->already_hscrolled_p = true;
14422 if (hscroll_retries <= MAX_HSCROLL_RETRIES
14423 && hscroll_windows (f->root_window))
14425 hscroll_retries++;
14426 goto retry_frame;
14430 /* If the frame's redisplay flag was not set before
14431 we went about redisplaying its windows, but it is
14432 set now, that means we employed some redisplay
14433 optimizations inside redisplay_windows, and
14434 bypassed producing some screen lines. But if
14435 f->redisplay is now set, it might mean the old
14436 faces are no longer valid (e.g., if redisplaying
14437 some window called some Lisp which defined a new
14438 face or redefined an existing face), so trying to
14439 use them in update_frame will segfault.
14440 Therefore, we must redisplay this frame. */
14441 if (!f_redisplay_flag && f->redisplay)
14442 goto retry_frame;
14443 /* In some case (e.g., window resize), we notice
14444 only during window updating that the window
14445 content changed unpredictably (e.g., a GTK
14446 scrollbar moved, or some Lisp hook that winds up
14447 calling adjust_frame_glyphs) and that our
14448 previous estimation of the frame content was
14449 garbage. We have to start over. These cases
14450 should be rare, so going all the way back to the
14451 top of redisplay should be good enough. */
14452 if (FRAME_GARBAGED_P (f)
14453 && garbaged_frame_retries++ < MAX_GARBAGED_FRAME_RETRIES)
14454 goto retry;
14456 #if defined (HAVE_WINDOW_SYSTEM) && !defined (HAVE_NS)
14457 x_clear_under_internal_border (f);
14458 #endif /* HAVE_WINDOW_SYSTEM && !HAVE_NS */
14460 /* Prevent various kinds of signals during display
14461 update. stdio is not robust about handling
14462 signals, which can cause an apparent I/O error. */
14463 if (interrupt_input)
14464 unrequest_sigio ();
14465 STOP_POLLING;
14467 pending |= update_frame (f, false, false);
14468 f->cursor_type_changed = false;
14469 f->updated_p = true;
14474 eassert (EQ (XFRAME (selected_frame)->selected_window, selected_window));
14476 if (!pending)
14478 /* Do the mark_window_display_accurate after all windows have
14479 been redisplayed because this call resets flags in buffers
14480 which are needed for proper redisplay. */
14481 FOR_EACH_FRAME (tail, frame)
14483 struct frame *f = XFRAME (frame);
14484 if (f->updated_p)
14486 f->redisplay = false;
14487 f->garbaged = false;
14488 mark_window_display_accurate (f->root_window, true);
14489 if (FRAME_TERMINAL (f)->frame_up_to_date_hook)
14490 FRAME_TERMINAL (f)->frame_up_to_date_hook (f);
14495 else if (FRAME_VISIBLE_P (sf) && !FRAME_OBSCURED_P (sf))
14497 displayed_buffer = XBUFFER (XWINDOW (selected_window)->contents);
14498 /* Use list_of_error, not Qerror, so that
14499 we catch only errors and don't run the debugger. */
14500 internal_condition_case_1 (redisplay_window_1, selected_window,
14501 list_of_error,
14502 redisplay_window_error);
14503 if (update_miniwindow_p)
14504 internal_condition_case_1 (redisplay_window_1,
14505 FRAME_MINIBUF_WINDOW (sf), list_of_error,
14506 redisplay_window_error);
14508 /* Compare desired and current matrices, perform output. */
14510 update:
14511 /* If fonts changed, display again. Likewise if redisplay_window_1
14512 above caused some change (e.g., a change in faces) that requires
14513 considering the entire frame again. */
14514 if (sf->fonts_changed || sf->redisplay)
14516 if (sf->redisplay)
14518 /* Set this to force a more thorough redisplay.
14519 Otherwise, we might immediately loop back to the
14520 above "else-if" clause (since all the conditions that
14521 led here might still be true), and we will then
14522 infloop, because the selected-frame's redisplay flag
14523 is not (and cannot be) reset. */
14524 windows_or_buffers_changed = 50;
14526 goto retry;
14529 /* Prevent freeing of realized faces, since desired matrices are
14530 pending that reference the faces we computed and cached. */
14531 inhibit_free_realized_faces = true;
14533 /* Prevent various kinds of signals during display update.
14534 stdio is not robust about handling signals,
14535 which can cause an apparent I/O error. */
14536 if (interrupt_input)
14537 unrequest_sigio ();
14538 STOP_POLLING;
14540 if (FRAME_VISIBLE_P (sf) && !FRAME_OBSCURED_P (sf))
14542 if (hscroll_retries <= MAX_HSCROLL_RETRIES
14543 && hscroll_windows (selected_window))
14545 hscroll_retries++;
14546 goto retry;
14549 XWINDOW (selected_window)->must_be_updated_p = true;
14550 pending = update_frame (sf, false, false);
14551 sf->cursor_type_changed = false;
14554 /* We may have called echo_area_display at the top of this
14555 function. If the echo area is on another frame, that may
14556 have put text on a frame other than the selected one, so the
14557 above call to update_frame would not have caught it. Catch
14558 it here. */
14559 Lisp_Object mini_window = FRAME_MINIBUF_WINDOW (sf);
14560 struct frame *mini_frame = XFRAME (WINDOW_FRAME (XWINDOW (mini_window)));
14562 if (mini_frame != sf && FRAME_WINDOW_P (mini_frame))
14564 XWINDOW (mini_window)->must_be_updated_p = true;
14565 pending |= update_frame (mini_frame, false, false);
14566 mini_frame->cursor_type_changed = false;
14567 if (!pending && hscroll_retries <= MAX_HSCROLL_RETRIES
14568 && hscroll_windows (mini_window))
14570 hscroll_retries++;
14571 goto retry;
14576 /* If display was paused because of pending input, make sure we do a
14577 thorough update the next time. */
14578 if (pending)
14580 /* Prevent the optimization at the beginning of
14581 redisplay_internal that tries a single-line update of the
14582 line containing the cursor in the selected window. */
14583 CHARPOS (this_line_start_pos) = 0;
14585 /* Let the overlay arrow be updated the next time. */
14586 update_overlay_arrows (0);
14588 /* If we pause after scrolling, some rows in the current
14589 matrices of some windows are not valid. */
14590 if (!WINDOW_FULL_WIDTH_P (w)
14591 && !FRAME_WINDOW_P (XFRAME (w->frame)))
14592 update_mode_lines = 36;
14594 else
14596 if (!consider_all_windows_p)
14598 /* This has already been done above if
14599 consider_all_windows_p is set. */
14600 if (XBUFFER (w->contents)->text->redisplay
14601 && buffer_window_count (XBUFFER (w->contents)) > 1)
14602 /* This can happen if b->text->redisplay was set during
14603 jit-lock. */
14604 propagate_buffer_redisplay ();
14605 mark_window_display_accurate_1 (w, true);
14607 /* Say overlay arrows are up to date. */
14608 update_overlay_arrows (1);
14610 if (FRAME_TERMINAL (sf)->frame_up_to_date_hook != 0)
14611 FRAME_TERMINAL (sf)->frame_up_to_date_hook (sf);
14614 update_mode_lines = 0;
14615 windows_or_buffers_changed = 0;
14618 /* Start SIGIO interrupts coming again. Having them off during the
14619 code above makes it less likely one will discard output, but not
14620 impossible, since there might be stuff in the system buffer here.
14621 But it is much hairier to try to do anything about that. */
14622 if (interrupt_input)
14623 request_sigio ();
14624 RESUME_POLLING;
14626 /* If a frame has become visible which was not before, redisplay
14627 again, so that we display it. Expose events for such a frame
14628 (which it gets when becoming visible) don't call the parts of
14629 redisplay constructing glyphs, so simply exposing a frame won't
14630 display anything in this case. So, we have to display these
14631 frames here explicitly. */
14632 if (!pending)
14634 int new_count = 0;
14636 FOR_EACH_FRAME (tail, frame)
14638 if (XFRAME (frame)->visible)
14639 new_count++;
14642 if (new_count != number_of_visible_frames)
14643 windows_or_buffers_changed = 52;
14646 /* Change frame size now if a change is pending. */
14647 do_pending_window_change (true);
14649 /* If we just did a pending size change, or have additional
14650 visible frames, or selected_window changed, redisplay again. */
14651 if ((windows_or_buffers_changed && !pending)
14652 || (WINDOWP (selected_window) && (w = XWINDOW (selected_window)) != sw))
14653 goto retry;
14655 /* Clear the face and image caches.
14657 We used to do this only if consider_all_windows_p. But the cache
14658 needs to be cleared if a timer creates images in the current
14659 buffer (e.g. the test case in Bug#6230). */
14661 if (clear_face_cache_count > CLEAR_FACE_CACHE_COUNT)
14663 clear_face_cache (false);
14664 clear_face_cache_count = 0;
14667 #ifdef HAVE_WINDOW_SYSTEM
14668 if (clear_image_cache_count > CLEAR_IMAGE_CACHE_COUNT)
14670 clear_image_caches (Qnil);
14671 clear_image_cache_count = 0;
14673 #endif /* HAVE_WINDOW_SYSTEM */
14675 end_of_redisplay:
14676 #ifdef HAVE_NS
14677 ns_set_doc_edited ();
14678 #endif
14679 if (interrupt_input && interrupts_deferred)
14680 request_sigio ();
14682 unbind_to (count, Qnil);
14683 RESUME_POLLING;
14686 static void
14687 unwind_redisplay_preserve_echo_area (void)
14689 unblock_buffer_flips ();
14692 /* Redisplay, but leave alone any recent echo area message unless
14693 another message has been requested in its place.
14695 This is useful in situations where you need to redisplay but no
14696 user action has occurred, making it inappropriate for the message
14697 area to be cleared. See tracking_off and
14698 wait_reading_process_output for examples of these situations.
14700 FROM_WHERE is an integer saying from where this function was
14701 called. This is useful for debugging. */
14703 void
14704 redisplay_preserve_echo_area (int from_where)
14706 TRACE ((stderr, "redisplay_preserve_echo_area (%d)\n", from_where));
14708 block_input ();
14709 ptrdiff_t count = SPECPDL_INDEX ();
14710 record_unwind_protect_void (unwind_redisplay_preserve_echo_area);
14711 block_buffer_flips ();
14712 unblock_input ();
14714 if (!NILP (echo_area_buffer[1]))
14716 /* We have a previously displayed message, but no current
14717 message. Redisplay the previous message. */
14718 display_last_displayed_message_p = true;
14719 redisplay_internal ();
14720 display_last_displayed_message_p = false;
14722 else
14723 redisplay_internal ();
14725 flush_frame (SELECTED_FRAME ());
14726 unbind_to (count, Qnil);
14730 /* Function registered with record_unwind_protect in redisplay_internal. */
14732 static void
14733 unwind_redisplay (void)
14735 redisplaying_p = false;
14736 unblock_buffer_flips ();
14740 /* Mark the display of leaf window W as accurate or inaccurate.
14741 If ACCURATE_P, mark display of W as accurate.
14742 If !ACCURATE_P, arrange for W to be redisplayed the next
14743 time redisplay_internal is called. */
14745 static void
14746 mark_window_display_accurate_1 (struct window *w, bool accurate_p)
14748 struct buffer *b = XBUFFER (w->contents);
14750 w->last_modified = accurate_p ? BUF_MODIFF (b) : 0;
14751 w->last_overlay_modified = accurate_p ? BUF_OVERLAY_MODIFF (b) : 0;
14752 w->last_had_star = BUF_MODIFF (b) > BUF_SAVE_MODIFF (b);
14754 if (accurate_p)
14756 b->clip_changed = false;
14757 b->prevent_redisplay_optimizations_p = false;
14758 eassert (buffer_window_count (b) > 0);
14759 /* Resetting b->text->redisplay is problematic!
14760 In order to make it safer to do it here, redisplay_internal must
14761 have copied all b->text->redisplay to their respective windows. */
14762 b->text->redisplay = false;
14764 BUF_UNCHANGED_MODIFIED (b) = BUF_MODIFF (b);
14765 BUF_OVERLAY_UNCHANGED_MODIFIED (b) = BUF_OVERLAY_MODIFF (b);
14766 BUF_BEG_UNCHANGED (b) = BUF_GPT (b) - BUF_BEG (b);
14767 BUF_END_UNCHANGED (b) = BUF_Z (b) - BUF_GPT (b);
14769 w->current_matrix->buffer = b;
14770 w->current_matrix->begv = BUF_BEGV (b);
14771 w->current_matrix->zv = BUF_ZV (b);
14773 w->last_cursor_vpos = w->cursor.vpos;
14774 w->last_cursor_off_p = w->cursor_off_p;
14776 if (w == XWINDOW (selected_window))
14777 w->last_point = BUF_PT (b);
14778 else
14779 w->last_point = marker_position (w->pointm);
14781 w->window_end_valid = true;
14782 w->update_mode_line = false;
14785 w->redisplay = !accurate_p;
14789 /* Mark the display of windows in the window tree rooted at WINDOW as
14790 accurate or inaccurate. If ACCURATE_P, mark display of
14791 windows as accurate. If !ACCURATE_P, arrange for windows to
14792 be redisplayed the next time redisplay_internal is called. */
14794 void
14795 mark_window_display_accurate (Lisp_Object window, bool accurate_p)
14797 struct window *w;
14799 for (; !NILP (window); window = w->next)
14801 w = XWINDOW (window);
14802 if (WINDOWP (w->contents))
14803 mark_window_display_accurate (w->contents, accurate_p);
14804 else
14805 mark_window_display_accurate_1 (w, accurate_p);
14808 if (accurate_p)
14809 update_overlay_arrows (1);
14810 else
14811 /* Force a thorough redisplay the next time by setting
14812 last_arrow_position and last_arrow_string to t, which is
14813 unequal to any useful value of Voverlay_arrow_... */
14814 update_overlay_arrows (-1);
14818 /* Return value in display table DP (Lisp_Char_Table *) for character
14819 C. Since a display table doesn't have any parent, we don't have to
14820 follow parent. Do not call this function directly but use the
14821 macro DISP_CHAR_VECTOR. */
14823 Lisp_Object
14824 disp_char_vector (struct Lisp_Char_Table *dp, int c)
14826 Lisp_Object val;
14828 if (ASCII_CHAR_P (c))
14830 val = dp->ascii;
14831 if (SUB_CHAR_TABLE_P (val))
14832 val = XSUB_CHAR_TABLE (val)->contents[c];
14834 else
14836 Lisp_Object table;
14838 XSETCHAR_TABLE (table, dp);
14839 val = char_table_ref (table, c);
14841 if (NILP (val))
14842 val = dp->defalt;
14843 return val;
14846 static int buffer_flip_blocked_depth;
14848 static void
14849 block_buffer_flips (void)
14851 eassert (buffer_flip_blocked_depth >= 0);
14852 buffer_flip_blocked_depth++;
14855 static void
14856 unblock_buffer_flips (void)
14858 eassert (buffer_flip_blocked_depth > 0);
14859 if (--buffer_flip_blocked_depth == 0)
14861 Lisp_Object tail, frame;
14862 block_input ();
14863 FOR_EACH_FRAME (tail, frame)
14865 struct frame *f = XFRAME (frame);
14866 if (FRAME_TERMINAL (f)->buffer_flipping_unblocked_hook)
14867 (*FRAME_TERMINAL (f)->buffer_flipping_unblocked_hook) (f);
14869 unblock_input ();
14873 bool
14874 buffer_flipping_blocked_p (void)
14876 return buffer_flip_blocked_depth > 0;
14880 /***********************************************************************
14881 Window Redisplay
14882 ***********************************************************************/
14884 /* Redisplay all leaf windows in the window tree rooted at WINDOW. */
14886 static void
14887 redisplay_windows (Lisp_Object window)
14889 while (!NILP (window))
14891 struct window *w = XWINDOW (window);
14893 if (WINDOWP (w->contents))
14894 redisplay_windows (w->contents);
14895 else if (BUFFERP (w->contents))
14897 displayed_buffer = XBUFFER (w->contents);
14898 /* Use list_of_error, not Qerror, so that
14899 we catch only errors and don't run the debugger. */
14900 internal_condition_case_1 (redisplay_window_0, window,
14901 list_of_error,
14902 redisplay_window_error);
14905 window = w->next;
14909 static Lisp_Object
14910 redisplay_window_error (Lisp_Object ignore)
14912 displayed_buffer->display_error_modiff = BUF_MODIFF (displayed_buffer);
14913 return Qnil;
14916 static Lisp_Object
14917 redisplay_window_0 (Lisp_Object window)
14919 if (displayed_buffer->display_error_modiff < BUF_MODIFF (displayed_buffer))
14920 redisplay_window (window, false);
14921 return Qnil;
14924 static Lisp_Object
14925 redisplay_window_1 (Lisp_Object window)
14927 if (displayed_buffer->display_error_modiff < BUF_MODIFF (displayed_buffer))
14928 redisplay_window (window, true);
14929 return Qnil;
14933 /* Set cursor position of W. PT is assumed to be displayed in ROW.
14934 DELTA and DELTA_BYTES are the numbers of characters and bytes by
14935 which positions recorded in ROW differ from current buffer
14936 positions.
14938 Return true iff cursor is on this row. */
14940 static bool
14941 set_cursor_from_row (struct window *w, struct glyph_row *row,
14942 struct glyph_matrix *matrix,
14943 ptrdiff_t delta, ptrdiff_t delta_bytes,
14944 int dy, int dvpos)
14946 struct glyph *glyph = row->glyphs[TEXT_AREA];
14947 struct glyph *end = glyph + row->used[TEXT_AREA];
14948 struct glyph *cursor = NULL;
14949 /* The last known character position in row. */
14950 ptrdiff_t last_pos = MATRIX_ROW_START_CHARPOS (row) + delta;
14951 int x = row->x;
14952 ptrdiff_t pt_old = PT - delta;
14953 ptrdiff_t pos_before = MATRIX_ROW_START_CHARPOS (row) + delta;
14954 ptrdiff_t pos_after = MATRIX_ROW_END_CHARPOS (row) + delta;
14955 struct glyph *glyph_before = glyph - 1, *glyph_after = end;
14956 /* A glyph beyond the edge of TEXT_AREA which we should never
14957 touch. */
14958 struct glyph *glyphs_end = end;
14959 /* True means we've found a match for cursor position, but that
14960 glyph has the avoid_cursor_p flag set. */
14961 bool match_with_avoid_cursor = false;
14962 /* True means we've seen at least one glyph that came from a
14963 display string. */
14964 bool string_seen = false;
14965 /* Largest and smallest buffer positions seen so far during scan of
14966 glyph row. */
14967 ptrdiff_t bpos_max = pos_before;
14968 ptrdiff_t bpos_min = pos_after;
14969 /* Last buffer position covered by an overlay string with an integer
14970 `cursor' property. */
14971 ptrdiff_t bpos_covered = 0;
14972 /* True means the display string on which to display the cursor
14973 comes from a text property, not from an overlay. */
14974 bool string_from_text_prop = false;
14976 /* Don't even try doing anything if called for a mode-line or
14977 header-line row, since the rest of the code isn't prepared to
14978 deal with such calamities. */
14979 eassert (!row->mode_line_p);
14980 if (row->mode_line_p)
14981 return false;
14983 /* Skip over glyphs not having an object at the start and the end of
14984 the row. These are special glyphs like truncation marks on
14985 terminal frames. */
14986 if (MATRIX_ROW_DISPLAYS_TEXT_P (row))
14988 if (!row->reversed_p)
14990 while (glyph < end
14991 && NILP (glyph->object)
14992 && glyph->charpos < 0)
14994 x += glyph->pixel_width;
14995 ++glyph;
14997 while (end > glyph
14998 && NILP ((end - 1)->object)
14999 /* CHARPOS is zero for blanks and stretch glyphs
15000 inserted by extend_face_to_end_of_line. */
15001 && (end - 1)->charpos <= 0)
15002 --end;
15003 glyph_before = glyph - 1;
15004 glyph_after = end;
15006 else
15008 struct glyph *g;
15010 /* If the glyph row is reversed, we need to process it from back
15011 to front, so swap the edge pointers. */
15012 glyphs_end = end = glyph - 1;
15013 glyph += row->used[TEXT_AREA] - 1;
15015 while (glyph > end + 1
15016 && NILP (glyph->object)
15017 && glyph->charpos < 0)
15018 --glyph;
15019 if (NILP (glyph->object) && glyph->charpos < 0)
15020 --glyph;
15021 /* By default, in reversed rows we put the cursor on the
15022 rightmost (first in the reading order) glyph. */
15023 for (x = 0, g = end + 1; g < glyph; g++)
15024 x += g->pixel_width;
15025 while (end < glyph
15026 && NILP ((end + 1)->object)
15027 && (end + 1)->charpos <= 0)
15028 ++end;
15029 glyph_before = glyph + 1;
15030 glyph_after = end;
15033 else if (row->reversed_p)
15035 /* In R2L rows that don't display text, put the cursor on the
15036 rightmost glyph. Case in point: an empty last line that is
15037 part of an R2L paragraph. */
15038 cursor = end - 1;
15039 /* Avoid placing the cursor on the last glyph of the row, where
15040 on terminal frames we hold the vertical border between
15041 adjacent windows. */
15042 if (!FRAME_WINDOW_P (WINDOW_XFRAME (w))
15043 && !WINDOW_RIGHTMOST_P (w)
15044 && cursor == row->glyphs[LAST_AREA] - 1)
15045 cursor--;
15046 x = -1; /* will be computed below, at label compute_x */
15049 /* Step 1: Try to find the glyph whose character position
15050 corresponds to point. If that's not possible, find 2 glyphs
15051 whose character positions are the closest to point, one before
15052 point, the other after it. */
15053 if (!row->reversed_p)
15054 while (/* not marched to end of glyph row */
15055 glyph < end
15056 /* glyph was not inserted by redisplay for internal purposes */
15057 && !NILP (glyph->object))
15059 if (BUFFERP (glyph->object))
15061 ptrdiff_t dpos = glyph->charpos - pt_old;
15063 if (glyph->charpos > bpos_max)
15064 bpos_max = glyph->charpos;
15065 if (glyph->charpos < bpos_min)
15066 bpos_min = glyph->charpos;
15067 if (!glyph->avoid_cursor_p)
15069 /* If we hit point, we've found the glyph on which to
15070 display the cursor. */
15071 if (dpos == 0)
15073 match_with_avoid_cursor = false;
15074 break;
15076 /* See if we've found a better approximation to
15077 POS_BEFORE or to POS_AFTER. */
15078 if (0 > dpos && dpos > pos_before - pt_old)
15080 pos_before = glyph->charpos;
15081 glyph_before = glyph;
15083 else if (0 < dpos && dpos < pos_after - pt_old)
15085 pos_after = glyph->charpos;
15086 glyph_after = glyph;
15089 else if (dpos == 0)
15090 match_with_avoid_cursor = true;
15092 else if (STRINGP (glyph->object))
15094 Lisp_Object chprop;
15095 ptrdiff_t glyph_pos = glyph->charpos;
15097 chprop = Fget_char_property (make_number (glyph_pos), Qcursor,
15098 glyph->object);
15099 if (!NILP (chprop))
15101 /* If the string came from a `display' text property,
15102 look up the buffer position of that property and
15103 use that position to update bpos_max, as if we
15104 actually saw such a position in one of the row's
15105 glyphs. This helps with supporting integer values
15106 of `cursor' property on the display string in
15107 situations where most or all of the row's buffer
15108 text is completely covered by display properties,
15109 so that no glyph with valid buffer positions is
15110 ever seen in the row. */
15111 ptrdiff_t prop_pos =
15112 string_buffer_position_lim (glyph->object, pos_before,
15113 pos_after, false);
15115 if (prop_pos >= pos_before)
15116 bpos_max = prop_pos;
15118 if (INTEGERP (chprop))
15120 bpos_covered = bpos_max + XINT (chprop);
15121 /* If the `cursor' property covers buffer positions up
15122 to and including point, we should display cursor on
15123 this glyph. Note that, if a `cursor' property on one
15124 of the string's characters has an integer value, we
15125 will break out of the loop below _before_ we get to
15126 the position match above. IOW, integer values of
15127 the `cursor' property override the "exact match for
15128 point" strategy of positioning the cursor. */
15129 /* Implementation note: bpos_max == pt_old when, e.g.,
15130 we are in an empty line, where bpos_max is set to
15131 MATRIX_ROW_START_CHARPOS, see above. */
15132 if (bpos_max <= pt_old && bpos_covered >= pt_old)
15134 cursor = glyph;
15135 break;
15139 string_seen = true;
15141 x += glyph->pixel_width;
15142 ++glyph;
15144 else if (glyph > end) /* row is reversed */
15145 while (!NILP (glyph->object))
15147 if (BUFFERP (glyph->object))
15149 ptrdiff_t dpos = glyph->charpos - pt_old;
15151 if (glyph->charpos > bpos_max)
15152 bpos_max = glyph->charpos;
15153 if (glyph->charpos < bpos_min)
15154 bpos_min = glyph->charpos;
15155 if (!glyph->avoid_cursor_p)
15157 if (dpos == 0)
15159 match_with_avoid_cursor = false;
15160 break;
15162 if (0 > dpos && dpos > pos_before - pt_old)
15164 pos_before = glyph->charpos;
15165 glyph_before = glyph;
15167 else if (0 < dpos && dpos < pos_after - pt_old)
15169 pos_after = glyph->charpos;
15170 glyph_after = glyph;
15173 else if (dpos == 0)
15174 match_with_avoid_cursor = true;
15176 else if (STRINGP (glyph->object))
15178 Lisp_Object chprop;
15179 ptrdiff_t glyph_pos = glyph->charpos;
15181 chprop = Fget_char_property (make_number (glyph_pos), Qcursor,
15182 glyph->object);
15183 if (!NILP (chprop))
15185 ptrdiff_t prop_pos =
15186 string_buffer_position_lim (glyph->object, pos_before,
15187 pos_after, false);
15189 if (prop_pos >= pos_before)
15190 bpos_max = prop_pos;
15192 if (INTEGERP (chprop))
15194 bpos_covered = bpos_max + XINT (chprop);
15195 /* If the `cursor' property covers buffer positions up
15196 to and including point, we should display cursor on
15197 this glyph. */
15198 if (bpos_max <= pt_old && bpos_covered >= pt_old)
15200 cursor = glyph;
15201 break;
15204 string_seen = true;
15206 --glyph;
15207 if (glyph == glyphs_end) /* don't dereference outside TEXT_AREA */
15209 x--; /* can't use any pixel_width */
15210 break;
15212 x -= glyph->pixel_width;
15215 /* Step 2: If we didn't find an exact match for point, we need to
15216 look for a proper place to put the cursor among glyphs between
15217 GLYPH_BEFORE and GLYPH_AFTER. */
15218 if (!((row->reversed_p ? glyph > glyphs_end : glyph < glyphs_end)
15219 && BUFFERP (glyph->object) && glyph->charpos == pt_old)
15220 && !(bpos_max <= pt_old && pt_old <= bpos_covered))
15222 /* An empty line has a single glyph whose OBJECT is nil and
15223 whose CHARPOS is the position of a newline on that line.
15224 Note that on a TTY, there are more glyphs after that, which
15225 were produced by extend_face_to_end_of_line, but their
15226 CHARPOS is zero or negative. */
15227 bool empty_line_p =
15228 ((row->reversed_p ? glyph > glyphs_end : glyph < glyphs_end)
15229 && NILP (glyph->object) && glyph->charpos > 0
15230 /* On a TTY, continued and truncated rows also have a glyph at
15231 their end whose OBJECT is nil and whose CHARPOS is
15232 positive (the continuation and truncation glyphs), but such
15233 rows are obviously not "empty". */
15234 && !(row->continued_p || row->truncated_on_right_p));
15236 if (row->ends_in_ellipsis_p && pos_after == last_pos)
15238 ptrdiff_t ellipsis_pos;
15240 /* Scan back over the ellipsis glyphs. */
15241 if (!row->reversed_p)
15243 ellipsis_pos = (glyph - 1)->charpos;
15244 while (glyph > row->glyphs[TEXT_AREA]
15245 && (glyph - 1)->charpos == ellipsis_pos)
15246 glyph--, x -= glyph->pixel_width;
15247 /* That loop always goes one position too far, including
15248 the glyph before the ellipsis. So scan forward over
15249 that one. */
15250 x += glyph->pixel_width;
15251 glyph++;
15253 else /* row is reversed */
15255 ellipsis_pos = (glyph + 1)->charpos;
15256 while (glyph < row->glyphs[TEXT_AREA] + row->used[TEXT_AREA] - 1
15257 && (glyph + 1)->charpos == ellipsis_pos)
15258 glyph++, x += glyph->pixel_width;
15259 x -= glyph->pixel_width;
15260 glyph--;
15263 else if (match_with_avoid_cursor)
15265 cursor = glyph_after;
15266 x = -1;
15268 else if (string_seen)
15270 int incr = row->reversed_p ? -1 : +1;
15272 /* Need to find the glyph that came out of a string which is
15273 present at point. That glyph is somewhere between
15274 GLYPH_BEFORE and GLYPH_AFTER, and it came from a string
15275 positioned between POS_BEFORE and POS_AFTER in the
15276 buffer. */
15277 struct glyph *start, *stop;
15278 ptrdiff_t pos = pos_before;
15280 x = -1;
15282 /* If the row ends in a newline from a display string,
15283 reordering could have moved the glyphs belonging to the
15284 string out of the [GLYPH_BEFORE..GLYPH_AFTER] range. So
15285 in this case we extend the search to the last glyph in
15286 the row that was not inserted by redisplay. */
15287 if (row->ends_in_newline_from_string_p)
15289 glyph_after = end;
15290 pos_after = MATRIX_ROW_END_CHARPOS (row) + delta;
15293 /* GLYPH_BEFORE and GLYPH_AFTER are the glyphs that
15294 correspond to POS_BEFORE and POS_AFTER, respectively. We
15295 need START and STOP in the order that corresponds to the
15296 row's direction as given by its reversed_p flag. If the
15297 directionality of characters between POS_BEFORE and
15298 POS_AFTER is the opposite of the row's base direction,
15299 these characters will have been reordered for display,
15300 and we need to reverse START and STOP. */
15301 if (!row->reversed_p)
15303 start = min (glyph_before, glyph_after);
15304 stop = max (glyph_before, glyph_after);
15306 else
15308 start = max (glyph_before, glyph_after);
15309 stop = min (glyph_before, glyph_after);
15311 for (glyph = start + incr;
15312 row->reversed_p ? glyph > stop : glyph < stop; )
15315 /* Any glyphs that come from the buffer are here because
15316 of bidi reordering. Skip them, and only pay
15317 attention to glyphs that came from some string. */
15318 if (STRINGP (glyph->object))
15320 Lisp_Object str;
15321 ptrdiff_t tem;
15322 /* If the display property covers the newline, we
15323 need to search for it one position farther. */
15324 ptrdiff_t lim = pos_after
15325 + (pos_after == MATRIX_ROW_END_CHARPOS (row) + delta);
15327 string_from_text_prop = false;
15328 str = glyph->object;
15329 tem = string_buffer_position_lim (str, pos, lim, false);
15330 if (tem == 0 /* from overlay */
15331 || pos <= tem)
15333 /* If the string from which this glyph came is
15334 found in the buffer at point, or at position
15335 that is closer to point than pos_after, then
15336 we've found the glyph we've been looking for.
15337 If it comes from an overlay (tem == 0), and
15338 it has the `cursor' property on one of its
15339 glyphs, record that glyph as a candidate for
15340 displaying the cursor. (As in the
15341 unidirectional version, we will display the
15342 cursor on the last candidate we find.) */
15343 if (tem == 0
15344 || tem == pt_old
15345 || (tem - pt_old > 0 && tem < pos_after))
15347 /* The glyphs from this string could have
15348 been reordered. Find the one with the
15349 smallest string position. Or there could
15350 be a character in the string with the
15351 `cursor' property, which means display
15352 cursor on that character's glyph. */
15353 ptrdiff_t strpos = glyph->charpos;
15355 if (tem)
15357 cursor = glyph;
15358 string_from_text_prop = true;
15360 for ( ;
15361 (row->reversed_p ? glyph > stop : glyph < stop)
15362 && EQ (glyph->object, str);
15363 glyph += incr)
15365 Lisp_Object cprop;
15366 ptrdiff_t gpos = glyph->charpos;
15368 cprop = Fget_char_property (make_number (gpos),
15369 Qcursor,
15370 glyph->object);
15371 if (!NILP (cprop))
15373 cursor = glyph;
15374 break;
15376 if (tem && glyph->charpos < strpos)
15378 strpos = glyph->charpos;
15379 cursor = glyph;
15383 if (tem == pt_old
15384 || (tem - pt_old > 0 && tem < pos_after))
15385 goto compute_x;
15387 if (tem)
15388 pos = tem + 1; /* don't find previous instances */
15390 /* This string is not what we want; skip all of the
15391 glyphs that came from it. */
15392 while ((row->reversed_p ? glyph > stop : glyph < stop)
15393 && EQ (glyph->object, str))
15394 glyph += incr;
15396 else
15397 glyph += incr;
15400 /* If we reached the end of the line, and END was from a string,
15401 the cursor is not on this line. */
15402 if (cursor == NULL
15403 && (row->reversed_p ? glyph <= end : glyph >= end)
15404 && (row->reversed_p ? end > glyphs_end : end < glyphs_end)
15405 && STRINGP (end->object)
15406 && row->continued_p)
15407 return false;
15409 /* A truncated row may not include PT among its character positions.
15410 Setting the cursor inside the scroll margin will trigger
15411 recalculation of hscroll in hscroll_window_tree. But if a
15412 display string covers point, defer to the string-handling
15413 code below to figure this out. */
15414 else if (row->truncated_on_left_p && pt_old < bpos_min)
15416 cursor = glyph_before;
15417 x = -1;
15419 else if ((row->truncated_on_right_p && pt_old > bpos_max)
15420 /* Zero-width characters produce no glyphs. */
15421 || (!empty_line_p
15422 && (row->reversed_p
15423 ? glyph_after > glyphs_end
15424 : glyph_after < glyphs_end)))
15426 cursor = glyph_after;
15427 x = -1;
15431 compute_x:
15432 if (cursor != NULL)
15433 glyph = cursor;
15434 else if (glyph == glyphs_end
15435 && pos_before == pos_after
15436 && STRINGP ((row->reversed_p
15437 ? row->glyphs[TEXT_AREA] + row->used[TEXT_AREA] - 1
15438 : row->glyphs[TEXT_AREA])->object))
15440 /* If all the glyphs of this row came from strings, put the
15441 cursor on the first glyph of the row. This avoids having the
15442 cursor outside of the text area in this very rare and hard
15443 use case. */
15444 glyph =
15445 row->reversed_p
15446 ? row->glyphs[TEXT_AREA] + row->used[TEXT_AREA] - 1
15447 : row->glyphs[TEXT_AREA];
15449 if (x < 0)
15451 struct glyph *g;
15453 /* Need to compute x that corresponds to GLYPH. */
15454 for (g = row->glyphs[TEXT_AREA], x = row->x; g < glyph; g++)
15456 if (g >= row->glyphs[TEXT_AREA] + row->used[TEXT_AREA])
15457 emacs_abort ();
15458 x += g->pixel_width;
15462 /* ROW could be part of a continued line, which, under bidi
15463 reordering, might have other rows whose start and end charpos
15464 occlude point. Only set w->cursor if we found a better
15465 approximation to the cursor position than we have from previously
15466 examined candidate rows belonging to the same continued line. */
15467 if (/* We already have a candidate row. */
15468 w->cursor.vpos >= 0
15469 /* That candidate is not the row we are processing. */
15470 && MATRIX_ROW (matrix, w->cursor.vpos) != row
15471 /* Make sure cursor.vpos specifies a row whose start and end
15472 charpos occlude point, and it is valid candidate for being a
15473 cursor-row. This is because some callers of this function
15474 leave cursor.vpos at the row where the cursor was displayed
15475 during the last redisplay cycle. */
15476 && MATRIX_ROW_START_CHARPOS (MATRIX_ROW (matrix, w->cursor.vpos)) <= pt_old
15477 && pt_old <= MATRIX_ROW_END_CHARPOS (MATRIX_ROW (matrix, w->cursor.vpos))
15478 && cursor_row_p (MATRIX_ROW (matrix, w->cursor.vpos)))
15480 struct glyph *g1
15481 = MATRIX_ROW_GLYPH_START (matrix, w->cursor.vpos) + w->cursor.hpos;
15483 /* Don't consider glyphs that are outside TEXT_AREA. */
15484 if (!(row->reversed_p ? glyph > glyphs_end : glyph < glyphs_end))
15485 return false;
15486 /* Keep the candidate whose buffer position is the closest to
15487 point or has the `cursor' property. */
15488 if (/* Previous candidate is a glyph in TEXT_AREA of that row. */
15489 w->cursor.hpos >= 0
15490 && w->cursor.hpos < MATRIX_ROW_USED (matrix, w->cursor.vpos)
15491 && ((BUFFERP (g1->object)
15492 && (g1->charpos == pt_old /* An exact match always wins. */
15493 || (BUFFERP (glyph->object)
15494 && eabs (g1->charpos - pt_old)
15495 < eabs (glyph->charpos - pt_old))))
15496 /* Previous candidate is a glyph from a string that has
15497 a non-nil `cursor' property. */
15498 || (STRINGP (g1->object)
15499 && (!NILP (Fget_char_property (make_number (g1->charpos),
15500 Qcursor, g1->object))
15501 /* Previous candidate is from the same display
15502 string as this one, and the display string
15503 came from a text property. */
15504 || (EQ (g1->object, glyph->object)
15505 && string_from_text_prop)
15506 /* this candidate is from newline and its
15507 position is not an exact match */
15508 || (NILP (glyph->object)
15509 && glyph->charpos != pt_old)))))
15510 return false;
15511 /* If this candidate gives an exact match, use that. */
15512 if (!((BUFFERP (glyph->object) && glyph->charpos == pt_old)
15513 /* If this candidate is a glyph created for the
15514 terminating newline of a line, and point is on that
15515 newline, it wins because it's an exact match. */
15516 || (!row->continued_p
15517 && NILP (glyph->object)
15518 && glyph->charpos == 0
15519 && pt_old == MATRIX_ROW_END_CHARPOS (row) - 1))
15520 /* Otherwise, keep the candidate that comes from a row
15521 spanning less buffer positions. This may win when one or
15522 both candidate positions are on glyphs that came from
15523 display strings, for which we cannot compare buffer
15524 positions. */
15525 && MATRIX_ROW_END_CHARPOS (MATRIX_ROW (matrix, w->cursor.vpos))
15526 - MATRIX_ROW_START_CHARPOS (MATRIX_ROW (matrix, w->cursor.vpos))
15527 < MATRIX_ROW_END_CHARPOS (row) - MATRIX_ROW_START_CHARPOS (row))
15528 return false;
15530 w->cursor.hpos = glyph - row->glyphs[TEXT_AREA];
15531 w->cursor.x = x;
15532 w->cursor.vpos = MATRIX_ROW_VPOS (row, matrix) + dvpos;
15533 w->cursor.y = row->y + dy;
15535 if (w == XWINDOW (selected_window))
15537 if (!row->continued_p
15538 && !MATRIX_ROW_CONTINUATION_LINE_P (row)
15539 && row->x == 0)
15541 this_line_buffer = XBUFFER (w->contents);
15543 CHARPOS (this_line_start_pos)
15544 = MATRIX_ROW_START_CHARPOS (row) + delta;
15545 BYTEPOS (this_line_start_pos)
15546 = MATRIX_ROW_START_BYTEPOS (row) + delta_bytes;
15548 CHARPOS (this_line_end_pos)
15549 = Z - (MATRIX_ROW_END_CHARPOS (row) + delta);
15550 BYTEPOS (this_line_end_pos)
15551 = Z_BYTE - (MATRIX_ROW_END_BYTEPOS (row) + delta_bytes);
15553 this_line_y = w->cursor.y;
15554 this_line_pixel_height = row->height;
15555 this_line_vpos = w->cursor.vpos;
15556 this_line_start_x = row->x;
15558 else
15559 CHARPOS (this_line_start_pos) = 0;
15562 return true;
15566 /* Run window scroll functions, if any, for WINDOW with new window
15567 start STARTP. Sets the window start of WINDOW to that position.
15569 We assume that the window's buffer is really current. */
15571 static struct text_pos
15572 run_window_scroll_functions (Lisp_Object window, struct text_pos startp)
15574 struct window *w = XWINDOW (window);
15575 SET_MARKER_FROM_TEXT_POS (w->start, startp);
15577 eassert (current_buffer == XBUFFER (w->contents));
15579 if (!NILP (Vwindow_scroll_functions))
15581 run_hook_with_args_2 (Qwindow_scroll_functions, window,
15582 make_number (CHARPOS (startp)));
15583 SET_TEXT_POS_FROM_MARKER (startp, w->start);
15584 /* In case the hook functions switch buffers. */
15585 set_buffer_internal (XBUFFER (w->contents));
15588 return startp;
15592 /* Make sure the line containing the cursor is fully visible.
15593 A value of true means there is nothing to be done.
15594 (Either the line is fully visible, or it cannot be made so,
15595 or we cannot tell.)
15597 If FORCE_P, return false even if partial visible cursor row
15598 is higher than window.
15600 If CURRENT_MATRIX_P, use the information from the
15601 window's current glyph matrix; otherwise use the desired glyph
15602 matrix.
15604 A value of false means the caller should do scrolling
15605 as if point had gone off the screen. */
15607 static bool
15608 cursor_row_fully_visible_p (struct window *w, bool force_p,
15609 bool current_matrix_p)
15611 struct glyph_matrix *matrix;
15612 struct glyph_row *row;
15613 int window_height;
15615 if (!make_cursor_line_fully_visible_p)
15616 return true;
15618 /* It's not always possible to find the cursor, e.g, when a window
15619 is full of overlay strings. Don't do anything in that case. */
15620 if (w->cursor.vpos < 0)
15621 return true;
15623 matrix = current_matrix_p ? w->current_matrix : w->desired_matrix;
15624 row = MATRIX_ROW (matrix, w->cursor.vpos);
15626 /* If the cursor row is not partially visible, there's nothing to do. */
15627 if (!MATRIX_ROW_PARTIALLY_VISIBLE_P (w, row))
15628 return true;
15630 /* If the row the cursor is in is taller than the window's height,
15631 it's not clear what to do, so do nothing. */
15632 window_height = window_box_height (w);
15633 if (row->height >= window_height)
15635 if (!force_p || MINI_WINDOW_P (w)
15636 || w->vscroll || w->cursor.vpos == 0)
15637 return true;
15639 return false;
15643 /* Try scrolling PT into view in window WINDOW. JUST_THIS_ONE_P
15644 means only WINDOW is redisplayed in redisplay_internal.
15645 TEMP_SCROLL_STEP has the same meaning as emacs_scroll_step, and is used
15646 in redisplay_window to bring a partially visible line into view in
15647 the case that only the cursor has moved.
15649 LAST_LINE_MISFIT should be true if we're scrolling because the
15650 last screen line's vertical height extends past the end of the screen.
15652 Value is
15654 1 if scrolling succeeded
15656 0 if scrolling didn't find point.
15658 -1 if new fonts have been loaded so that we must interrupt
15659 redisplay, adjust glyph matrices, and try again. */
15661 enum
15663 SCROLLING_SUCCESS,
15664 SCROLLING_FAILED,
15665 SCROLLING_NEED_LARGER_MATRICES
15668 /* If scroll-conservatively is more than this, never recenter.
15670 If you change this, don't forget to update the doc string of
15671 `scroll-conservatively' and the Emacs manual. */
15672 #define SCROLL_LIMIT 100
15674 static int
15675 try_scrolling (Lisp_Object window, bool just_this_one_p,
15676 ptrdiff_t arg_scroll_conservatively, ptrdiff_t scroll_step,
15677 bool temp_scroll_step, bool last_line_misfit)
15679 struct window *w = XWINDOW (window);
15680 struct text_pos pos, startp;
15681 struct it it;
15682 int this_scroll_margin, scroll_max, rc, height;
15683 int dy = 0, amount_to_scroll = 0;
15684 bool scroll_down_p = false;
15685 int extra_scroll_margin_lines = last_line_misfit;
15686 Lisp_Object aggressive;
15687 /* We will never try scrolling more than this number of lines. */
15688 int scroll_limit = SCROLL_LIMIT;
15689 int frame_line_height = default_line_pixel_height (w);
15691 #ifdef GLYPH_DEBUG
15692 debug_method_add (w, "try_scrolling");
15693 #endif
15695 SET_TEXT_POS_FROM_MARKER (startp, w->start);
15697 this_scroll_margin = window_scroll_margin (w, MARGIN_IN_PIXELS);
15699 /* Force arg_scroll_conservatively to have a reasonable value, to
15700 avoid scrolling too far away with slow move_it_* functions. Note
15701 that the user can supply scroll-conservatively equal to
15702 `most-positive-fixnum', which can be larger than INT_MAX. */
15703 if (arg_scroll_conservatively > scroll_limit)
15705 arg_scroll_conservatively = scroll_limit + 1;
15706 scroll_max = scroll_limit * frame_line_height;
15708 else if (scroll_step || arg_scroll_conservatively || temp_scroll_step)
15709 /* Compute how much we should try to scroll maximally to bring
15710 point into view. */
15711 scroll_max = (max (scroll_step,
15712 max (arg_scroll_conservatively, temp_scroll_step))
15713 * frame_line_height);
15714 else if (NUMBERP (BVAR (current_buffer, scroll_down_aggressively))
15715 || NUMBERP (BVAR (current_buffer, scroll_up_aggressively)))
15716 /* We're trying to scroll because of aggressive scrolling but no
15717 scroll_step is set. Choose an arbitrary one. */
15718 scroll_max = 10 * frame_line_height;
15719 else
15720 scroll_max = 0;
15722 too_near_end:
15724 /* Decide whether to scroll down. */
15725 if (PT > CHARPOS (startp))
15727 int scroll_margin_y;
15729 /* Compute the pixel ypos of the scroll margin, then move IT to
15730 either that ypos or PT, whichever comes first. */
15731 start_display (&it, w, startp);
15732 scroll_margin_y = it.last_visible_y - partial_line_height (&it)
15733 - this_scroll_margin
15734 - frame_line_height * extra_scroll_margin_lines;
15735 move_it_to (&it, PT, -1, scroll_margin_y - 1, -1,
15736 (MOVE_TO_POS | MOVE_TO_Y));
15738 if (PT > CHARPOS (it.current.pos))
15740 int y0 = line_bottom_y (&it);
15741 /* Compute how many pixels below window bottom to stop searching
15742 for PT. This avoids costly search for PT that is far away if
15743 the user limited scrolling by a small number of lines, but
15744 always finds PT if scroll_conservatively is set to a large
15745 number, such as most-positive-fixnum. */
15746 int slack = max (scroll_max, 10 * frame_line_height);
15747 int y_to_move = it.last_visible_y + slack;
15749 /* Compute the distance from the scroll margin to PT or to
15750 the scroll limit, whichever comes first. This should
15751 include the height of the cursor line, to make that line
15752 fully visible. */
15753 move_it_to (&it, PT, -1, y_to_move,
15754 -1, MOVE_TO_POS | MOVE_TO_Y);
15755 dy = line_bottom_y (&it) - y0;
15757 if (dy > scroll_max)
15758 return SCROLLING_FAILED;
15760 if (dy > 0)
15761 scroll_down_p = true;
15763 else if (PT == IT_CHARPOS (it)
15764 && IT_CHARPOS (it) < ZV
15765 && it.method == GET_FROM_STRING
15766 && arg_scroll_conservatively > scroll_limit
15767 && it.current_x == 0)
15769 enum move_it_result skip;
15770 int y1 = it.current_y;
15771 int vpos;
15773 /* A before-string that includes newlines and is displayed
15774 on the last visible screen line could fail us under
15775 scroll-conservatively > 100, because we will be unable to
15776 position the cursor on that last visible line. Try to
15777 recover by finding the first screen line that has some
15778 glyphs coming from the buffer text. */
15779 do {
15780 skip = move_it_in_display_line_to (&it, ZV, -1, MOVE_TO_POS);
15781 if (skip != MOVE_NEWLINE_OR_CR
15782 || IT_CHARPOS (it) != PT
15783 || it.method == GET_FROM_BUFFER)
15784 break;
15785 vpos = it.vpos;
15786 move_it_to (&it, -1, -1, -1, vpos + 1, MOVE_TO_VPOS);
15787 } while (it.vpos > vpos);
15789 dy = it.current_y - y1;
15791 if (dy > scroll_max)
15792 return SCROLLING_FAILED;
15794 if (dy > 0)
15795 scroll_down_p = true;
15799 if (scroll_down_p)
15801 /* Point is in or below the bottom scroll margin, so move the
15802 window start down. If scrolling conservatively, move it just
15803 enough down to make point visible. If scroll_step is set,
15804 move it down by scroll_step. */
15805 if (arg_scroll_conservatively)
15806 amount_to_scroll
15807 = min (max (dy, frame_line_height),
15808 frame_line_height * arg_scroll_conservatively);
15809 else if (scroll_step || temp_scroll_step)
15810 amount_to_scroll = scroll_max;
15811 else
15813 aggressive = BVAR (current_buffer, scroll_up_aggressively);
15814 height = WINDOW_BOX_TEXT_HEIGHT (w);
15815 if (NUMBERP (aggressive))
15817 double float_amount = XFLOATINT (aggressive) * height;
15818 int aggressive_scroll = float_amount;
15819 if (aggressive_scroll == 0 && float_amount > 0)
15820 aggressive_scroll = 1;
15821 /* Don't let point enter the scroll margin near top of
15822 the window. This could happen if the value of
15823 scroll_up_aggressively is too large and there are
15824 non-zero margins, because scroll_up_aggressively
15825 means put point that fraction of window height
15826 _from_the_bottom_margin_. */
15827 if (aggressive_scroll + 2 * this_scroll_margin > height)
15828 aggressive_scroll = height - 2 * this_scroll_margin;
15829 amount_to_scroll = dy + aggressive_scroll;
15833 if (amount_to_scroll <= 0)
15834 return SCROLLING_FAILED;
15836 start_display (&it, w, startp);
15837 if (arg_scroll_conservatively <= scroll_limit)
15838 move_it_vertically (&it, amount_to_scroll);
15839 else
15841 /* Extra precision for users who set scroll-conservatively
15842 to a large number: make sure the amount we scroll
15843 the window start is never less than amount_to_scroll,
15844 which was computed as distance from window bottom to
15845 point. This matters when lines at window top and lines
15846 below window bottom have different height. */
15847 struct it it1;
15848 void *it1data = NULL;
15849 /* We use a temporary it1 because line_bottom_y can modify
15850 its argument, if it moves one line down; see there. */
15851 int start_y;
15853 SAVE_IT (it1, it, it1data);
15854 start_y = line_bottom_y (&it1);
15855 do {
15856 RESTORE_IT (&it, &it, it1data);
15857 move_it_by_lines (&it, 1);
15858 SAVE_IT (it1, it, it1data);
15859 } while (IT_CHARPOS (it) < ZV
15860 && line_bottom_y (&it1) - start_y < amount_to_scroll);
15861 bidi_unshelve_cache (it1data, true);
15864 /* If STARTP is unchanged, move it down another screen line. */
15865 if (IT_CHARPOS (it) == CHARPOS (startp))
15866 move_it_by_lines (&it, 1);
15867 startp = it.current.pos;
15869 else
15871 struct text_pos scroll_margin_pos = startp;
15872 int y_offset = 0;
15874 /* See if point is inside the scroll margin at the top of the
15875 window. */
15876 if (this_scroll_margin)
15878 int y_start;
15880 start_display (&it, w, startp);
15881 y_start = it.current_y;
15882 move_it_vertically (&it, this_scroll_margin);
15883 scroll_margin_pos = it.current.pos;
15884 /* If we didn't move enough before hitting ZV, request
15885 additional amount of scroll, to move point out of the
15886 scroll margin. */
15887 if (IT_CHARPOS (it) == ZV
15888 && it.current_y - y_start < this_scroll_margin)
15889 y_offset = this_scroll_margin - (it.current_y - y_start);
15892 if (PT < CHARPOS (scroll_margin_pos))
15894 /* Point is in the scroll margin at the top of the window or
15895 above what is displayed in the window. */
15896 int y0, y_to_move;
15898 /* Compute the vertical distance from PT to the scroll
15899 margin position. Move as far as scroll_max allows, or
15900 one screenful, or 10 screen lines, whichever is largest.
15901 Give up if distance is greater than scroll_max or if we
15902 didn't reach the scroll margin position. */
15903 SET_TEXT_POS (pos, PT, PT_BYTE);
15904 start_display (&it, w, pos);
15905 y0 = it.current_y;
15906 y_to_move = max (it.last_visible_y,
15907 max (scroll_max, 10 * frame_line_height));
15908 move_it_to (&it, CHARPOS (scroll_margin_pos), 0,
15909 y_to_move, -1,
15910 MOVE_TO_POS | MOVE_TO_X | MOVE_TO_Y);
15911 dy = it.current_y - y0;
15912 if (dy > scroll_max
15913 || IT_CHARPOS (it) < CHARPOS (scroll_margin_pos))
15914 return SCROLLING_FAILED;
15916 /* Additional scroll for when ZV was too close to point. */
15917 dy += y_offset;
15919 /* Compute new window start. */
15920 start_display (&it, w, startp);
15922 if (arg_scroll_conservatively)
15923 amount_to_scroll = max (dy, frame_line_height
15924 * max (scroll_step, temp_scroll_step));
15925 else if (scroll_step || temp_scroll_step)
15926 amount_to_scroll = scroll_max;
15927 else
15929 aggressive = BVAR (current_buffer, scroll_down_aggressively);
15930 height = WINDOW_BOX_TEXT_HEIGHT (w);
15931 if (NUMBERP (aggressive))
15933 double float_amount = XFLOATINT (aggressive) * height;
15934 int aggressive_scroll = float_amount;
15935 if (aggressive_scroll == 0 && float_amount > 0)
15936 aggressive_scroll = 1;
15937 /* Don't let point enter the scroll margin near
15938 bottom of the window, if the value of
15939 scroll_down_aggressively happens to be too
15940 large. */
15941 if (aggressive_scroll + 2 * this_scroll_margin > height)
15942 aggressive_scroll = height - 2 * this_scroll_margin;
15943 amount_to_scroll = dy + aggressive_scroll;
15947 if (amount_to_scroll <= 0)
15948 return SCROLLING_FAILED;
15950 move_it_vertically_backward (&it, amount_to_scroll);
15951 startp = it.current.pos;
15955 /* Run window scroll functions. */
15956 startp = run_window_scroll_functions (window, startp);
15958 /* Display the window. Give up if new fonts are loaded, or if point
15959 doesn't appear. */
15960 if (!try_window (window, startp, 0))
15961 rc = SCROLLING_NEED_LARGER_MATRICES;
15962 else if (w->cursor.vpos < 0)
15964 clear_glyph_matrix (w->desired_matrix);
15965 rc = SCROLLING_FAILED;
15967 else
15969 /* Maybe forget recorded base line for line number display. */
15970 if (!just_this_one_p
15971 || current_buffer->clip_changed
15972 || BEG_UNCHANGED < CHARPOS (startp))
15973 w->base_line_number = 0;
15975 /* If cursor ends up on a partially visible line,
15976 treat that as being off the bottom of the screen. */
15977 if (! cursor_row_fully_visible_p (w, extra_scroll_margin_lines <= 1,
15978 false)
15979 /* It's possible that the cursor is on the first line of the
15980 buffer, which is partially obscured due to a vscroll
15981 (Bug#7537). In that case, avoid looping forever. */
15982 && extra_scroll_margin_lines < w->desired_matrix->nrows - 1)
15984 clear_glyph_matrix (w->desired_matrix);
15985 ++extra_scroll_margin_lines;
15986 goto too_near_end;
15988 rc = SCROLLING_SUCCESS;
15991 return rc;
15995 /* Compute a suitable window start for window W if display of W starts
15996 on a continuation line. Value is true if a new window start
15997 was computed.
15999 The new window start will be computed, based on W's width, starting
16000 from the start of the continued line. It is the start of the
16001 screen line with the minimum distance from the old start W->start,
16002 which is still before point (otherwise point will definitely not
16003 be visible in the window). */
16005 static bool
16006 compute_window_start_on_continuation_line (struct window *w)
16008 struct text_pos pos, start_pos, pos_before_pt;
16009 bool window_start_changed_p = false;
16011 SET_TEXT_POS_FROM_MARKER (start_pos, w->start);
16013 /* If window start is on a continuation line... Window start may be
16014 < BEGV in case there's invisible text at the start of the
16015 buffer (M-x rmail, for example). */
16016 if (CHARPOS (start_pos) > BEGV
16017 && FETCH_BYTE (BYTEPOS (start_pos) - 1) != '\n')
16019 struct it it;
16020 struct glyph_row *row;
16022 /* Handle the case that the window start is out of range. */
16023 if (CHARPOS (start_pos) < BEGV)
16024 SET_TEXT_POS (start_pos, BEGV, BEGV_BYTE);
16025 else if (CHARPOS (start_pos) > ZV)
16026 SET_TEXT_POS (start_pos, ZV, ZV_BYTE);
16028 /* Find the start of the continued line. This should be fast
16029 because find_newline is fast (newline cache). */
16030 row = w->desired_matrix->rows + window_wants_header_line (w);
16031 init_iterator (&it, w, CHARPOS (start_pos), BYTEPOS (start_pos),
16032 row, DEFAULT_FACE_ID);
16033 reseat_at_previous_visible_line_start (&it);
16035 /* If the line start is "too far" away from the window start,
16036 say it takes too much time to compute a new window start.
16037 Also, give up if the line start is after point, as in that
16038 case point will not be visible with any window start we
16039 compute. */
16040 if (IT_CHARPOS (it) <= PT
16041 || (CHARPOS (start_pos) - IT_CHARPOS (it)
16042 /* PXW: Do we need upper bounds here? */
16043 < WINDOW_TOTAL_LINES (w) * WINDOW_TOTAL_COLS (w)))
16045 int min_distance, distance;
16047 /* Move forward by display lines to find the new window
16048 start. If window width was enlarged, the new start can
16049 be expected to be > the old start. If window width was
16050 decreased, the new window start will be < the old start.
16051 So, we're looking for the display line start with the
16052 minimum distance from the old window start. */
16053 pos_before_pt = pos = it.current.pos;
16054 min_distance = DISP_INFINITY;
16055 while ((distance = eabs (CHARPOS (start_pos) - IT_CHARPOS (it))),
16056 distance < min_distance)
16058 min_distance = distance;
16059 if (CHARPOS (pos) <= PT)
16060 pos_before_pt = pos;
16061 pos = it.current.pos;
16062 if (it.line_wrap == WORD_WRAP)
16064 /* Under WORD_WRAP, move_it_by_lines is likely to
16065 overshoot and stop not at the first, but the
16066 second character from the left margin. So in
16067 that case, we need a more tight control on the X
16068 coordinate of the iterator than move_it_by_lines
16069 promises in its contract. The method is to first
16070 go to the last (rightmost) visible character of a
16071 line, then move to the leftmost character on the
16072 next line in a separate call. */
16073 move_it_to (&it, ZV, it.last_visible_x, it.current_y, -1,
16074 MOVE_TO_POS | MOVE_TO_X | MOVE_TO_Y);
16075 move_it_to (&it, ZV, 0,
16076 it.current_y + it.max_ascent + it.max_descent, -1,
16077 MOVE_TO_POS | MOVE_TO_X | MOVE_TO_Y);
16079 else
16080 move_it_by_lines (&it, 1);
16083 /* It makes very little sense to make the new window start
16084 after point, as point won't be visible. If that's what
16085 the loop above finds, fall back on the candidate before
16086 or at point that is closest to the old window start. */
16087 if (CHARPOS (pos) > PT)
16088 pos = pos_before_pt;
16090 /* Set the window start there. */
16091 SET_MARKER_FROM_TEXT_POS (w->start, pos);
16092 window_start_changed_p = true;
16096 return window_start_changed_p;
16100 /* Try cursor movement in case text has not changed in window WINDOW,
16101 with window start STARTP. Value is
16103 CURSOR_MOVEMENT_SUCCESS if successful
16105 CURSOR_MOVEMENT_CANNOT_BE_USED if this method cannot be used
16107 CURSOR_MOVEMENT_MUST_SCROLL if we know we have to scroll the
16108 display. *SCROLL_STEP is set to true, under certain circumstances, if
16109 we want to scroll as if scroll-step were set to 1. See the code.
16111 CURSOR_MOVEMENT_NEED_LARGER_MATRICES if we need larger matrices, in
16112 which case we have to abort this redisplay, and adjust matrices
16113 first. */
16115 enum
16117 CURSOR_MOVEMENT_SUCCESS,
16118 CURSOR_MOVEMENT_CANNOT_BE_USED,
16119 CURSOR_MOVEMENT_MUST_SCROLL,
16120 CURSOR_MOVEMENT_NEED_LARGER_MATRICES
16123 static int
16124 try_cursor_movement (Lisp_Object window, struct text_pos startp,
16125 bool *scroll_step)
16127 struct window *w = XWINDOW (window);
16128 struct frame *f = XFRAME (w->frame);
16129 int rc = CURSOR_MOVEMENT_CANNOT_BE_USED;
16131 #ifdef GLYPH_DEBUG
16132 if (inhibit_try_cursor_movement)
16133 return rc;
16134 #endif
16136 /* Previously, there was a check for Lisp integer in the
16137 if-statement below. Now, this field is converted to
16138 ptrdiff_t, thus zero means invalid position in a buffer. */
16139 eassert (w->last_point > 0);
16140 /* Likewise there was a check whether window_end_vpos is nil or larger
16141 than the window. Now window_end_vpos is int and so never nil, but
16142 let's leave eassert to check whether it fits in the window. */
16143 eassert (!w->window_end_valid
16144 || w->window_end_vpos < w->current_matrix->nrows);
16146 /* Handle case where text has not changed, only point, and it has
16147 not moved off the frame. */
16148 if (/* Point may be in this window. */
16149 PT >= CHARPOS (startp)
16150 /* Selective display hasn't changed. */
16151 && !current_buffer->clip_changed
16152 /* Function force-mode-line-update is used to force a thorough
16153 redisplay. It sets either windows_or_buffers_changed or
16154 update_mode_lines. So don't take a shortcut here for these
16155 cases. */
16156 && !update_mode_lines
16157 && !windows_or_buffers_changed
16158 && !f->cursor_type_changed
16159 && NILP (Vshow_trailing_whitespace)
16160 /* When display-line-numbers is in relative mode, moving point
16161 requires to redraw the entire window. */
16162 && !EQ (Vdisplay_line_numbers, Qrelative)
16163 && !EQ (Vdisplay_line_numbers, Qvisual)
16164 /* When the current line number should be displayed in a
16165 distinct face, moving point cannot be handled in optimized
16166 way as below. */
16167 && !(!NILP (Vdisplay_line_numbers)
16168 && NILP (Finternal_lisp_face_equal_p (Qline_number,
16169 Qline_number_current_line,
16170 w->frame)))
16171 /* This code is not used for mini-buffer for the sake of the case
16172 of redisplaying to replace an echo area message; since in
16173 that case the mini-buffer contents per se are usually
16174 unchanged. This code is of no real use in the mini-buffer
16175 since the handling of this_line_start_pos, etc., in redisplay
16176 handles the same cases. */
16177 && !EQ (window, minibuf_window)
16178 /* When overlay arrow is shown in current buffer, point movement
16179 is no longer "simple", as it typically causes the overlay
16180 arrow to move as well. */
16181 && !overlay_arrow_in_current_buffer_p ())
16183 int this_scroll_margin, top_scroll_margin;
16184 struct glyph_row *row = NULL;
16186 #ifdef GLYPH_DEBUG
16187 debug_method_add (w, "cursor movement");
16188 #endif
16190 this_scroll_margin = window_scroll_margin (w, MARGIN_IN_PIXELS);
16192 top_scroll_margin = this_scroll_margin;
16193 if (window_wants_header_line (w))
16194 top_scroll_margin += CURRENT_HEADER_LINE_HEIGHT (w);
16196 /* Start with the row the cursor was displayed during the last
16197 not paused redisplay. Give up if that row is not valid. */
16198 if (w->last_cursor_vpos < 0
16199 || w->last_cursor_vpos >= w->current_matrix->nrows)
16200 rc = CURSOR_MOVEMENT_MUST_SCROLL;
16201 else
16203 row = MATRIX_ROW (w->current_matrix, w->last_cursor_vpos);
16204 if (row->mode_line_p)
16205 ++row;
16206 if (!row->enabled_p)
16207 rc = CURSOR_MOVEMENT_MUST_SCROLL;
16210 if (rc == CURSOR_MOVEMENT_CANNOT_BE_USED)
16212 bool scroll_p = false, must_scroll = false;
16213 int last_y = window_text_bottom_y (w) - this_scroll_margin;
16215 if (PT > w->last_point)
16217 /* Point has moved forward. */
16218 while (MATRIX_ROW_END_CHARPOS (row) < PT
16219 && MATRIX_ROW_BOTTOM_Y (row) < last_y)
16221 eassert (row->enabled_p);
16222 ++row;
16225 /* If the end position of a row equals the start
16226 position of the next row, and PT is at that position,
16227 we would rather display cursor in the next line. */
16228 while (MATRIX_ROW_BOTTOM_Y (row) < last_y
16229 && MATRIX_ROW_END_CHARPOS (row) == PT
16230 && row < MATRIX_MODE_LINE_ROW (w->current_matrix)
16231 && MATRIX_ROW_START_CHARPOS (row+1) == PT
16232 && !cursor_row_p (row))
16233 ++row;
16235 /* If within the scroll margin, scroll. Note that
16236 MATRIX_ROW_BOTTOM_Y gives the pixel position at which
16237 the next line would be drawn, and that
16238 this_scroll_margin can be zero. */
16239 if (MATRIX_ROW_BOTTOM_Y (row) > last_y
16240 || PT > MATRIX_ROW_END_CHARPOS (row)
16241 /* Line is completely visible last line in window
16242 and PT is to be set in the next line. */
16243 || (MATRIX_ROW_BOTTOM_Y (row) == last_y
16244 && PT == MATRIX_ROW_END_CHARPOS (row)
16245 && !row->ends_at_zv_p
16246 && !MATRIX_ROW_ENDS_IN_MIDDLE_OF_CHAR_P (row)))
16247 scroll_p = true;
16249 else if (PT < w->last_point)
16251 /* Cursor has to be moved backward. Note that PT >=
16252 CHARPOS (startp) because of the outer if-statement. */
16253 while (!row->mode_line_p
16254 && (MATRIX_ROW_START_CHARPOS (row) > PT
16255 || (MATRIX_ROW_START_CHARPOS (row) == PT
16256 && (MATRIX_ROW_STARTS_IN_MIDDLE_OF_CHAR_P (row)
16257 || (/* STARTS_IN_MIDDLE_OF_STRING_P (row) */
16258 row > w->current_matrix->rows
16259 && (row-1)->ends_in_newline_from_string_p))))
16260 && (row->y > top_scroll_margin
16261 || CHARPOS (startp) == BEGV))
16263 eassert (row->enabled_p);
16264 --row;
16267 /* Consider the following case: Window starts at BEGV,
16268 there is invisible, intangible text at BEGV, so that
16269 display starts at some point START > BEGV. It can
16270 happen that we are called with PT somewhere between
16271 BEGV and START. Try to handle that case. */
16272 if (row < w->current_matrix->rows
16273 || row->mode_line_p)
16275 row = w->current_matrix->rows;
16276 if (row->mode_line_p)
16277 ++row;
16280 /* Due to newlines in overlay strings, we may have to
16281 skip forward over overlay strings. */
16282 while (MATRIX_ROW_BOTTOM_Y (row) < last_y
16283 && MATRIX_ROW_END_CHARPOS (row) == PT
16284 && !cursor_row_p (row))
16285 ++row;
16287 /* If within the scroll margin, scroll. */
16288 if (row->y < top_scroll_margin
16289 && CHARPOS (startp) != BEGV)
16290 scroll_p = true;
16292 else
16294 /* Cursor did not move. So don't scroll even if cursor line
16295 is partially visible, as it was so before. */
16296 rc = CURSOR_MOVEMENT_SUCCESS;
16299 if (PT < MATRIX_ROW_START_CHARPOS (row)
16300 || PT > MATRIX_ROW_END_CHARPOS (row))
16302 /* if PT is not in the glyph row, give up. */
16303 rc = CURSOR_MOVEMENT_MUST_SCROLL;
16304 must_scroll = true;
16306 else if (rc != CURSOR_MOVEMENT_SUCCESS
16307 && !NILP (BVAR (XBUFFER (w->contents), bidi_display_reordering)))
16309 struct glyph_row *row1;
16311 /* If rows are bidi-reordered and point moved, back up
16312 until we find a row that does not belong to a
16313 continuation line. This is because we must consider
16314 all rows of a continued line as candidates for the
16315 new cursor positioning, since row start and end
16316 positions change non-linearly with vertical position
16317 in such rows. */
16318 /* FIXME: Revisit this when glyph ``spilling'' in
16319 continuation lines' rows is implemented for
16320 bidi-reordered rows. */
16321 for (row1 = MATRIX_FIRST_TEXT_ROW (w->current_matrix);
16322 MATRIX_ROW_CONTINUATION_LINE_P (row);
16323 --row)
16325 /* If we hit the beginning of the displayed portion
16326 without finding the first row of a continued
16327 line, give up. */
16328 if (row <= row1)
16330 rc = CURSOR_MOVEMENT_MUST_SCROLL;
16331 break;
16333 eassert (row->enabled_p);
16336 if (must_scroll)
16338 else if (rc != CURSOR_MOVEMENT_SUCCESS
16339 && MATRIX_ROW_PARTIALLY_VISIBLE_P (w, row)
16340 /* Make sure this isn't a header line by any chance, since
16341 then MATRIX_ROW_PARTIALLY_VISIBLE_P might yield true. */
16342 && !row->mode_line_p
16343 && make_cursor_line_fully_visible_p)
16345 if (PT == MATRIX_ROW_END_CHARPOS (row)
16346 && !row->ends_at_zv_p
16347 && !MATRIX_ROW_ENDS_IN_MIDDLE_OF_CHAR_P (row))
16348 rc = CURSOR_MOVEMENT_MUST_SCROLL;
16349 else if (row->height > window_box_height (w))
16351 /* If we end up in a partially visible line, let's
16352 make it fully visible, except when it's taller
16353 than the window, in which case we can't do much
16354 about it. */
16355 *scroll_step = true;
16356 rc = CURSOR_MOVEMENT_MUST_SCROLL;
16358 else
16360 set_cursor_from_row (w, row, w->current_matrix, 0, 0, 0, 0);
16361 if (!cursor_row_fully_visible_p (w, false, true))
16362 rc = CURSOR_MOVEMENT_MUST_SCROLL;
16363 else
16364 rc = CURSOR_MOVEMENT_SUCCESS;
16367 else if (scroll_p)
16368 rc = CURSOR_MOVEMENT_MUST_SCROLL;
16369 else if (rc != CURSOR_MOVEMENT_SUCCESS
16370 && !NILP (BVAR (XBUFFER (w->contents), bidi_display_reordering)))
16372 /* With bidi-reordered rows, there could be more than
16373 one candidate row whose start and end positions
16374 occlude point. We need to let set_cursor_from_row
16375 find the best candidate. */
16376 /* FIXME: Revisit this when glyph ``spilling'' in
16377 continuation lines' rows is implemented for
16378 bidi-reordered rows. */
16379 bool rv = false;
16383 bool at_zv_p = false, exact_match_p = false;
16385 if (MATRIX_ROW_START_CHARPOS (row) <= PT
16386 && PT <= MATRIX_ROW_END_CHARPOS (row)
16387 && cursor_row_p (row))
16388 rv |= set_cursor_from_row (w, row, w->current_matrix,
16389 0, 0, 0, 0);
16390 /* As soon as we've found the exact match for point,
16391 or the first suitable row whose ends_at_zv_p flag
16392 is set, we are done. */
16393 if (rv)
16395 at_zv_p = MATRIX_ROW (w->current_matrix,
16396 w->cursor.vpos)->ends_at_zv_p;
16397 if (!at_zv_p
16398 && w->cursor.hpos >= 0
16399 && w->cursor.hpos < MATRIX_ROW_USED (w->current_matrix,
16400 w->cursor.vpos))
16402 struct glyph_row *candidate =
16403 MATRIX_ROW (w->current_matrix, w->cursor.vpos);
16404 struct glyph *g =
16405 candidate->glyphs[TEXT_AREA] + w->cursor.hpos;
16406 ptrdiff_t endpos = MATRIX_ROW_END_CHARPOS (candidate);
16408 exact_match_p =
16409 (BUFFERP (g->object) && g->charpos == PT)
16410 || (NILP (g->object)
16411 && (g->charpos == PT
16412 || (g->charpos == 0 && endpos - 1 == PT)));
16414 if (at_zv_p || exact_match_p)
16416 rc = CURSOR_MOVEMENT_SUCCESS;
16417 break;
16420 if (MATRIX_ROW_BOTTOM_Y (row) == last_y)
16421 break;
16422 ++row;
16424 while (((MATRIX_ROW_CONTINUATION_LINE_P (row)
16425 || row->continued_p)
16426 && MATRIX_ROW_BOTTOM_Y (row) <= last_y)
16427 || (MATRIX_ROW_START_CHARPOS (row) == PT
16428 && MATRIX_ROW_BOTTOM_Y (row) < last_y));
16429 /* If we didn't find any candidate rows, or exited the
16430 loop before all the candidates were examined, signal
16431 to the caller that this method failed. */
16432 if (rc != CURSOR_MOVEMENT_SUCCESS
16433 && !(rv
16434 && !MATRIX_ROW_CONTINUATION_LINE_P (row)
16435 && !row->continued_p))
16436 rc = CURSOR_MOVEMENT_MUST_SCROLL;
16437 else if (rv)
16438 rc = CURSOR_MOVEMENT_SUCCESS;
16440 else
16444 if (set_cursor_from_row (w, row, w->current_matrix, 0, 0, 0, 0))
16446 rc = CURSOR_MOVEMENT_SUCCESS;
16447 break;
16449 ++row;
16451 while (MATRIX_ROW_BOTTOM_Y (row) < last_y
16452 && MATRIX_ROW_START_CHARPOS (row) == PT
16453 && cursor_row_p (row));
16458 return rc;
16462 void
16463 set_vertical_scroll_bar (struct window *w)
16465 ptrdiff_t start, end, whole;
16467 /* Calculate the start and end positions for the current window.
16468 At some point, it would be nice to choose between scrollbars
16469 which reflect the whole buffer size, with special markers
16470 indicating narrowing, and scrollbars which reflect only the
16471 visible region.
16473 Note that mini-buffers sometimes aren't displaying any text. */
16474 if (!MINI_WINDOW_P (w)
16475 || (w == XWINDOW (minibuf_window)
16476 && NILP (echo_area_buffer[0])))
16478 struct buffer *buf = XBUFFER (w->contents);
16479 whole = BUF_ZV (buf) - BUF_BEGV (buf);
16480 start = marker_position (w->start) - BUF_BEGV (buf);
16481 /* I don't think this is guaranteed to be right. For the
16482 moment, we'll pretend it is. */
16483 end = BUF_Z (buf) - w->window_end_pos - BUF_BEGV (buf);
16485 if (end < start)
16486 end = start;
16487 if (whole < (end - start))
16488 whole = end - start;
16490 else
16491 start = end = whole = 0;
16493 /* Indicate what this scroll bar ought to be displaying now. */
16494 if (FRAME_TERMINAL (XFRAME (w->frame))->set_vertical_scroll_bar_hook)
16495 (*FRAME_TERMINAL (XFRAME (w->frame))->set_vertical_scroll_bar_hook)
16496 (w, end - start, whole, start);
16500 void
16501 set_horizontal_scroll_bar (struct window *w)
16503 int start, end, whole, portion;
16505 if (!MINI_WINDOW_P (w)
16506 || (w == XWINDOW (minibuf_window)
16507 && NILP (echo_area_buffer[0])))
16509 struct buffer *b = XBUFFER (w->contents);
16510 struct buffer *old_buffer = NULL;
16511 struct it it;
16512 struct text_pos startp;
16514 if (b != current_buffer)
16516 old_buffer = current_buffer;
16517 set_buffer_internal (b);
16520 SET_TEXT_POS_FROM_MARKER (startp, w->start);
16521 start_display (&it, w, startp);
16522 it.last_visible_x = INT_MAX;
16523 whole = move_it_to (&it, -1, INT_MAX, window_box_height (w), -1,
16524 MOVE_TO_X | MOVE_TO_Y);
16525 /* whole = move_it_to (&it, w->window_end_pos, INT_MAX,
16526 window_box_height (w), -1,
16527 MOVE_TO_POS | MOVE_TO_X | MOVE_TO_Y); */
16529 start = w->hscroll * FRAME_COLUMN_WIDTH (WINDOW_XFRAME (w));
16530 end = start + window_box_width (w, TEXT_AREA);
16531 portion = end - start;
16532 /* After enlarging a horizontally scrolled window such that it
16533 gets at least as wide as the text it contains, make sure that
16534 the thumb doesn't fill the entire scroll bar so we can still
16535 drag it back to see the entire text. */
16536 whole = max (whole, end);
16538 if (it.bidi_p)
16540 Lisp_Object pdir;
16542 pdir = Fcurrent_bidi_paragraph_direction (Qnil);
16543 if (EQ (pdir, Qright_to_left))
16545 start = whole - end;
16546 end = start + portion;
16550 if (old_buffer)
16551 set_buffer_internal (old_buffer);
16553 else
16554 start = end = whole = portion = 0;
16556 w->hscroll_whole = whole;
16558 /* Indicate what this scroll bar ought to be displaying now. */
16559 if (FRAME_TERMINAL (XFRAME (w->frame))->set_horizontal_scroll_bar_hook)
16560 (*FRAME_TERMINAL (XFRAME (w->frame))->set_horizontal_scroll_bar_hook)
16561 (w, portion, whole, start);
16565 /* Redisplay leaf window WINDOW. JUST_THIS_ONE_P means only
16566 selected_window is redisplayed.
16568 We can return without actually redisplaying the window if fonts has been
16569 changed on window's frame. In that case, redisplay_internal will retry.
16571 As one of the important parts of redisplaying a window, we need to
16572 decide whether the previous window-start position (stored in the
16573 window's w->start marker position) is still valid, and if it isn't,
16574 recompute it. Some details about that:
16576 . The previous window-start could be in a continuation line, in
16577 which case we need to recompute it when the window width
16578 changes. See compute_window_start_on_continuation_line and its
16579 call below.
16581 . The text that changed since last redisplay could include the
16582 previous window-start position. In that case, we try to salvage
16583 what we can from the current glyph matrix by calling
16584 try_scrolling, which see.
16586 . Some Emacs command could force us to use a specific window-start
16587 position by setting the window's force_start flag, or gently
16588 propose doing that by setting the window's optional_new_start
16589 flag. In these cases, we try using the specified start point if
16590 that succeeds (i.e. the window desired matrix is successfully
16591 recomputed, and point location is within the window). In case
16592 of optional_new_start, we first check if the specified start
16593 position is feasible, i.e. if it will allow point to be
16594 displayed in the window. If using the specified start point
16595 fails, e.g., if new fonts are needed to be loaded, we abort the
16596 redisplay cycle and leave it up to the next cycle to figure out
16597 things.
16599 . Note that the window's force_start flag is sometimes set by
16600 redisplay itself, when it decides that the previous window start
16601 point is fine and should be kept. Search for "goto force_start"
16602 below to see the details. Like the values of window-start
16603 specified outside of redisplay, these internally-deduced values
16604 are tested for feasibility, and ignored if found to be
16605 unfeasible.
16607 . Note that the function try_window, used to completely redisplay
16608 a window, accepts the window's start point as its argument.
16609 This is used several times in the redisplay code to control
16610 where the window start will be, according to user options such
16611 as scroll-conservatively, and also to ensure the screen line
16612 showing point will be fully (as opposed to partially) visible on
16613 display. */
16615 static void
16616 redisplay_window (Lisp_Object window, bool just_this_one_p)
16618 struct window *w = XWINDOW (window);
16619 struct frame *f = XFRAME (w->frame);
16620 struct buffer *buffer = XBUFFER (w->contents);
16621 struct buffer *old = current_buffer;
16622 struct text_pos lpoint, opoint, startp;
16623 bool update_mode_line;
16624 int tem;
16625 struct it it;
16626 /* Record it now because it's overwritten. */
16627 bool current_matrix_up_to_date_p = false;
16628 bool used_current_matrix_p = false;
16629 /* This is less strict than current_matrix_up_to_date_p.
16630 It indicates that the buffer contents and narrowing are unchanged. */
16631 bool buffer_unchanged_p = false;
16632 bool temp_scroll_step = false;
16633 ptrdiff_t count = SPECPDL_INDEX ();
16634 int rc;
16635 int centering_position = -1;
16636 bool last_line_misfit = false;
16637 ptrdiff_t beg_unchanged, end_unchanged;
16638 int frame_line_height, margin;
16639 bool use_desired_matrix;
16640 void *itdata = NULL;
16642 SET_TEXT_POS (lpoint, PT, PT_BYTE);
16643 opoint = lpoint;
16645 #ifdef GLYPH_DEBUG
16646 *w->desired_matrix->method = 0;
16647 #endif
16649 if (!just_this_one_p
16650 && REDISPLAY_SOME_P ()
16651 && !w->redisplay
16652 && !w->update_mode_line
16653 && !f->face_change
16654 && !f->redisplay
16655 && !buffer->text->redisplay
16656 && BUF_PT (buffer) == w->last_point)
16657 return;
16659 /* Make sure that both W's markers are valid. */
16660 eassert (XMARKER (w->start)->buffer == buffer);
16661 eassert (XMARKER (w->pointm)->buffer == buffer);
16663 reconsider_clip_changes (w);
16664 frame_line_height = default_line_pixel_height (w);
16665 margin = window_scroll_margin (w, MARGIN_IN_LINES);
16668 /* Has the mode line to be updated? */
16669 update_mode_line = (w->update_mode_line
16670 || update_mode_lines
16671 || buffer->clip_changed
16672 || buffer->prevent_redisplay_optimizations_p);
16674 if (!just_this_one_p)
16675 /* If `just_this_one_p' is set, we apparently set must_be_updated_p more
16676 cleverly elsewhere. */
16677 w->must_be_updated_p = true;
16679 if (MINI_WINDOW_P (w))
16681 if (w == XWINDOW (echo_area_window)
16682 && !NILP (echo_area_buffer[0]))
16684 if (update_mode_line)
16685 /* We may have to update a tty frame's menu bar or a
16686 tool-bar. Example `M-x C-h C-h C-g'. */
16687 goto finish_menu_bars;
16688 else
16689 /* We've already displayed the echo area glyphs in this window. */
16690 goto finish_scroll_bars;
16692 else if ((w != XWINDOW (minibuf_window)
16693 || minibuf_level == 0)
16694 /* When buffer is nonempty, redisplay window normally. */
16695 && BUF_Z (XBUFFER (w->contents)) == BUF_BEG (XBUFFER (w->contents))
16696 /* Quail displays non-mini buffers in minibuffer window.
16697 In that case, redisplay the window normally. */
16698 && !NILP (Fmemq (w->contents, Vminibuffer_list)))
16700 /* W is a mini-buffer window, but it's not active, so clear
16701 it. */
16702 int yb = window_text_bottom_y (w);
16703 struct glyph_row *row;
16704 int y;
16706 for (y = 0, row = w->desired_matrix->rows;
16707 y < yb;
16708 y += row->height, ++row)
16709 blank_row (w, row, y);
16710 goto finish_scroll_bars;
16713 clear_glyph_matrix (w->desired_matrix);
16716 /* Otherwise set up data on this window; select its buffer and point
16717 value. */
16718 /* Really select the buffer, for the sake of buffer-local
16719 variables. */
16720 set_buffer_internal_1 (XBUFFER (w->contents));
16722 current_matrix_up_to_date_p
16723 = (w->window_end_valid
16724 && !current_buffer->clip_changed
16725 && !current_buffer->prevent_redisplay_optimizations_p
16726 && !window_outdated (w)
16727 && !hscrolling_current_line_p (w));
16729 beg_unchanged = BEG_UNCHANGED;
16730 end_unchanged = END_UNCHANGED;
16732 SET_TEXT_POS (opoint, PT, PT_BYTE);
16734 specbind (Qinhibit_point_motion_hooks, Qt);
16736 buffer_unchanged_p
16737 = (w->window_end_valid
16738 && !current_buffer->clip_changed
16739 && !window_outdated (w));
16741 /* When windows_or_buffers_changed is non-zero, we can't rely
16742 on the window end being valid, so set it to zero there. */
16743 if (windows_or_buffers_changed)
16745 /* If window starts on a continuation line, maybe adjust the
16746 window start in case the window's width changed. */
16747 if (XMARKER (w->start)->buffer == current_buffer)
16748 compute_window_start_on_continuation_line (w);
16750 w->window_end_valid = false;
16751 /* If so, we also can't rely on current matrix
16752 and should not fool try_cursor_movement below. */
16753 current_matrix_up_to_date_p = false;
16756 /* Some sanity checks. */
16757 CHECK_WINDOW_END (w);
16758 if (Z == Z_BYTE && CHARPOS (opoint) != BYTEPOS (opoint))
16759 emacs_abort ();
16760 if (BYTEPOS (opoint) < CHARPOS (opoint))
16761 emacs_abort ();
16763 if (mode_line_update_needed (w))
16764 update_mode_line = true;
16766 /* Point refers normally to the selected window. For any other
16767 window, set up appropriate value. */
16768 if (!EQ (window, selected_window))
16770 ptrdiff_t new_pt = marker_position (w->pointm);
16771 ptrdiff_t new_pt_byte = marker_byte_position (w->pointm);
16773 if (new_pt < BEGV)
16775 new_pt = BEGV;
16776 new_pt_byte = BEGV_BYTE;
16777 set_marker_both (w->pointm, Qnil, BEGV, BEGV_BYTE);
16779 else if (new_pt > (ZV - 1))
16781 new_pt = ZV;
16782 new_pt_byte = ZV_BYTE;
16783 set_marker_both (w->pointm, Qnil, ZV, ZV_BYTE);
16786 /* We don't use SET_PT so that the point-motion hooks don't run. */
16787 TEMP_SET_PT_BOTH (new_pt, new_pt_byte);
16790 /* If any of the character widths specified in the display table
16791 have changed, invalidate the width run cache. It's true that
16792 this may be a bit late to catch such changes, but the rest of
16793 redisplay goes (non-fatally) haywire when the display table is
16794 changed, so why should we worry about doing any better? */
16795 if (current_buffer->width_run_cache
16796 || (current_buffer->base_buffer
16797 && current_buffer->base_buffer->width_run_cache))
16799 struct Lisp_Char_Table *disptab = buffer_display_table ();
16801 if (! disptab_matches_widthtab
16802 (disptab, XVECTOR (BVAR (current_buffer, width_table))))
16804 struct buffer *buf = current_buffer;
16806 if (buf->base_buffer)
16807 buf = buf->base_buffer;
16808 invalidate_region_cache (buf, buf->width_run_cache, BEG, Z);
16809 recompute_width_table (current_buffer, disptab);
16813 /* If window-start is screwed up, choose a new one. */
16814 if (XMARKER (w->start)->buffer != current_buffer)
16815 goto recenter;
16817 SET_TEXT_POS_FROM_MARKER (startp, w->start);
16819 /* If someone specified a new starting point but did not insist,
16820 check whether it can be used. */
16821 if ((w->optional_new_start || window_frozen_p (w))
16822 && CHARPOS (startp) >= BEGV
16823 && CHARPOS (startp) <= ZV)
16825 ptrdiff_t it_charpos;
16827 w->optional_new_start = false;
16828 start_display (&it, w, startp);
16829 move_it_to (&it, PT, 0, it.last_visible_y, -1,
16830 MOVE_TO_POS | MOVE_TO_X | MOVE_TO_Y);
16831 /* Record IT's position now, since line_bottom_y might change
16832 that. */
16833 it_charpos = IT_CHARPOS (it);
16834 /* Make sure we set the force_start flag only if the cursor row
16835 will be fully visible. Otherwise, the code under force_start
16836 label below will try to move point back into view, which is
16837 not what the code which sets optional_new_start wants. */
16838 if ((it.current_y == 0 || line_bottom_y (&it) < it.last_visible_y)
16839 && !w->force_start)
16841 if (it_charpos == PT)
16842 w->force_start = true;
16843 /* IT may overshoot PT if text at PT is invisible. */
16844 else if (it_charpos > PT && CHARPOS (startp) <= PT)
16845 w->force_start = true;
16846 #ifdef GLYPH_DEBUG
16847 if (w->force_start)
16849 if (window_frozen_p (w))
16850 debug_method_add (w, "set force_start from frozen window start");
16851 else
16852 debug_method_add (w, "set force_start from optional_new_start");
16854 #endif
16858 force_start:
16860 /* Handle case where place to start displaying has been specified,
16861 unless the specified location is outside the accessible range. */
16862 if (w->force_start)
16864 /* We set this later on if we have to adjust point. */
16865 int new_vpos = -1;
16867 w->force_start = false;
16868 w->vscroll = 0;
16869 w->window_end_valid = false;
16871 /* Forget any recorded base line for line number display. */
16872 if (!buffer_unchanged_p)
16873 w->base_line_number = 0;
16875 /* Redisplay the mode line. Select the buffer properly for that.
16876 Also, run the hook window-scroll-functions
16877 because we have scrolled. */
16878 /* Note, we do this after clearing force_start because
16879 if there's an error, it is better to forget about force_start
16880 than to get into an infinite loop calling the hook functions
16881 and having them get more errors. */
16882 if (!update_mode_line
16883 || ! NILP (Vwindow_scroll_functions))
16885 update_mode_line = true;
16886 w->update_mode_line = true;
16887 startp = run_window_scroll_functions (window, startp);
16890 if (CHARPOS (startp) < BEGV)
16891 SET_TEXT_POS (startp, BEGV, BEGV_BYTE);
16892 else if (CHARPOS (startp) > ZV)
16893 SET_TEXT_POS (startp, ZV, ZV_BYTE);
16895 /* Redisplay, then check if cursor has been set during the
16896 redisplay. Give up if new fonts were loaded. */
16897 /* We used to issue a CHECK_MARGINS argument to try_window here,
16898 but this causes scrolling to fail when point begins inside
16899 the scroll margin (bug#148) -- cyd */
16900 if (!try_window (window, startp, 0))
16902 w->force_start = true;
16903 clear_glyph_matrix (w->desired_matrix);
16904 goto need_larger_matrices;
16907 if (w->cursor.vpos < 0)
16909 /* If point does not appear, try to move point so it does
16910 appear. The desired matrix has been built above, so we
16911 can use it here. First see if point is in invisible
16912 text, and if so, move it to the first visible buffer
16913 position past that. */
16914 struct glyph_row *r = NULL;
16915 Lisp_Object invprop =
16916 get_char_property_and_overlay (make_number (PT), Qinvisible,
16917 Qnil, NULL);
16919 if (TEXT_PROP_MEANS_INVISIBLE (invprop) != 0)
16921 ptrdiff_t alt_pt;
16922 Lisp_Object invprop_end =
16923 Fnext_single_char_property_change (make_number (PT), Qinvisible,
16924 Qnil, Qnil);
16926 if (NATNUMP (invprop_end))
16927 alt_pt = XFASTINT (invprop_end);
16928 else
16929 alt_pt = ZV;
16930 r = row_containing_pos (w, alt_pt, w->desired_matrix->rows,
16931 NULL, 0);
16933 if (r)
16934 new_vpos = MATRIX_ROW_BOTTOM_Y (r);
16935 else /* Give up and just move to the middle of the window. */
16936 new_vpos = window_box_height (w) / 2;
16939 if (!cursor_row_fully_visible_p (w, false, false))
16941 /* Point does appear, but on a line partly visible at end of window.
16942 Move it back to a fully-visible line. */
16943 new_vpos = window_box_height (w);
16944 /* But if window_box_height suggests a Y coordinate that is
16945 not less than we already have, that line will clearly not
16946 be fully visible, so give up and scroll the display.
16947 This can happen when the default face uses a font whose
16948 dimensions are different from the frame's default
16949 font. */
16950 if (new_vpos >= w->cursor.y)
16952 w->cursor.vpos = -1;
16953 clear_glyph_matrix (w->desired_matrix);
16954 goto try_to_scroll;
16957 else if (w->cursor.vpos >= 0)
16959 /* Some people insist on not letting point enter the scroll
16960 margin, even though this part handles windows that didn't
16961 scroll at all. */
16962 int pixel_margin = margin * frame_line_height;
16963 bool header_line = window_wants_header_line (w);
16965 /* Note: We add an extra FRAME_LINE_HEIGHT, because the loop
16966 below, which finds the row to move point to, advances by
16967 the Y coordinate of the _next_ row, see the definition of
16968 MATRIX_ROW_BOTTOM_Y. */
16969 if (w->cursor.vpos < margin + header_line)
16971 w->cursor.vpos = -1;
16972 clear_glyph_matrix (w->desired_matrix);
16973 goto try_to_scroll;
16975 else
16977 int window_height = window_box_height (w);
16979 if (header_line)
16980 window_height += CURRENT_HEADER_LINE_HEIGHT (w);
16981 if (w->cursor.y >= window_height - pixel_margin)
16983 w->cursor.vpos = -1;
16984 clear_glyph_matrix (w->desired_matrix);
16985 goto try_to_scroll;
16990 /* If we need to move point for either of the above reasons,
16991 now actually do it. */
16992 if (new_vpos >= 0)
16994 struct glyph_row *row;
16996 row = MATRIX_FIRST_TEXT_ROW (w->desired_matrix);
16997 while (MATRIX_ROW_BOTTOM_Y (row) < new_vpos)
16998 ++row;
17000 TEMP_SET_PT_BOTH (MATRIX_ROW_START_CHARPOS (row),
17001 MATRIX_ROW_START_BYTEPOS (row));
17003 if (w != XWINDOW (selected_window))
17004 set_marker_both (w->pointm, Qnil, PT, PT_BYTE);
17005 else if (current_buffer == old)
17006 SET_TEXT_POS (lpoint, PT, PT_BYTE);
17008 set_cursor_from_row (w, row, w->desired_matrix, 0, 0, 0, 0);
17010 /* Re-run pre-redisplay-function so it can update the region
17011 according to the new position of point. */
17012 /* Other than the cursor, w's redisplay is done so we can set its
17013 redisplay to false. Also the buffer's redisplay can be set to
17014 false, since propagate_buffer_redisplay should have already
17015 propagated its info to `w' anyway. */
17016 w->redisplay = false;
17017 XBUFFER (w->contents)->text->redisplay = false;
17018 safe__call1 (true, Vpre_redisplay_function, Fcons (window, Qnil));
17020 if (w->redisplay || XBUFFER (w->contents)->text->redisplay
17021 || ((EQ (Vdisplay_line_numbers, Qrelative)
17022 || EQ (Vdisplay_line_numbers, Qvisual))
17023 && row != MATRIX_FIRST_TEXT_ROW (w->desired_matrix)))
17025 /* Either pre-redisplay-function made changes (e.g. move
17026 the region), or we moved point in a window that is
17027 under display-line-numbers = relative mode. We need
17028 another round of redisplay. */
17029 clear_glyph_matrix (w->desired_matrix);
17030 if (!try_window (window, startp, 0))
17031 goto need_larger_matrices;
17034 if (w->cursor.vpos < 0 || !cursor_row_fully_visible_p (w, false, false))
17036 clear_glyph_matrix (w->desired_matrix);
17037 goto try_to_scroll;
17040 #ifdef GLYPH_DEBUG
17041 debug_method_add (w, "forced window start");
17042 #endif
17043 goto done;
17046 /* Handle case where text has not changed, only point, and it has
17047 not moved off the frame, and we are not retrying after hscroll.
17048 (current_matrix_up_to_date_p is true when retrying.) */
17049 if (current_matrix_up_to_date_p
17050 && (rc = try_cursor_movement (window, startp, &temp_scroll_step),
17051 rc != CURSOR_MOVEMENT_CANNOT_BE_USED))
17053 switch (rc)
17055 case CURSOR_MOVEMENT_SUCCESS:
17056 used_current_matrix_p = true;
17057 goto done;
17059 case CURSOR_MOVEMENT_MUST_SCROLL:
17060 goto try_to_scroll;
17062 default:
17063 emacs_abort ();
17066 /* If current starting point was originally the beginning of a line
17067 but no longer is, find a new starting point. */
17068 else if (w->start_at_line_beg
17069 && !(CHARPOS (startp) <= BEGV
17070 || FETCH_BYTE (BYTEPOS (startp) - 1) == '\n'))
17072 #ifdef GLYPH_DEBUG
17073 debug_method_add (w, "recenter 1");
17074 #endif
17075 goto recenter;
17078 /* Try scrolling with try_window_id. Value is > 0 if update has
17079 been done, it is -1 if we know that the same window start will
17080 not work. It is 0 if unsuccessful for some other reason. */
17081 else if ((tem = try_window_id (w)) != 0)
17083 #ifdef GLYPH_DEBUG
17084 debug_method_add (w, "try_window_id %d", tem);
17085 #endif
17087 if (f->fonts_changed)
17088 goto need_larger_matrices;
17089 if (tem > 0)
17090 goto done;
17092 /* Otherwise try_window_id has returned -1 which means that we
17093 don't want the alternative below this comment to execute. */
17095 else if (CHARPOS (startp) >= BEGV
17096 && CHARPOS (startp) <= ZV
17097 && PT >= CHARPOS (startp)
17098 && (CHARPOS (startp) < ZV
17099 /* Avoid starting at end of buffer. */
17100 || CHARPOS (startp) == BEGV
17101 || !window_outdated (w)))
17103 int d1, d2, d5, d6;
17104 int rtop, rbot;
17106 /* If first window line is a continuation line, and window start
17107 is inside the modified region, but the first change is before
17108 current window start, we must select a new window start.
17110 However, if this is the result of a down-mouse event (e.g. by
17111 extending the mouse-drag-overlay), we don't want to select a
17112 new window start, since that would change the position under
17113 the mouse, resulting in an unwanted mouse-movement rather
17114 than a simple mouse-click. */
17115 if (!w->start_at_line_beg
17116 && NILP (do_mouse_tracking)
17117 && CHARPOS (startp) > BEGV
17118 && CHARPOS (startp) > BEG + beg_unchanged
17119 && CHARPOS (startp) <= Z - end_unchanged
17120 /* Even if w->start_at_line_beg is nil, a new window may
17121 start at a line_beg, since that's how set_buffer_window
17122 sets it. So, we need to check the return value of
17123 compute_window_start_on_continuation_line. (See also
17124 bug#197). */
17125 && XMARKER (w->start)->buffer == current_buffer
17126 && compute_window_start_on_continuation_line (w)
17127 /* It doesn't make sense to force the window start like we
17128 do at label force_start if it is already known that point
17129 will not be fully visible in the resulting window, because
17130 doing so will move point from its correct position
17131 instead of scrolling the window to bring point into view.
17132 See bug#9324. */
17133 && pos_visible_p (w, PT, &d1, &d2, &rtop, &rbot, &d5, &d6)
17134 /* A very tall row could need more than the window height,
17135 in which case we accept that it is partially visible. */
17136 && (rtop != 0) == (rbot != 0))
17138 w->force_start = true;
17139 SET_TEXT_POS_FROM_MARKER (startp, w->start);
17140 #ifdef GLYPH_DEBUG
17141 debug_method_add (w, "recomputed window start in continuation line");
17142 #endif
17143 goto force_start;
17146 #ifdef GLYPH_DEBUG
17147 debug_method_add (w, "same window start");
17148 #endif
17150 /* Try to redisplay starting at same place as before.
17151 If point has not moved off frame, accept the results. */
17152 if (!current_matrix_up_to_date_p
17153 /* Don't use try_window_reusing_current_matrix in this case
17154 because a window scroll function can have changed the
17155 buffer. */
17156 || !NILP (Vwindow_scroll_functions)
17157 || MINI_WINDOW_P (w)
17158 || !(used_current_matrix_p
17159 = try_window_reusing_current_matrix (w)))
17161 IF_DEBUG (debug_method_add (w, "1"));
17162 clear_glyph_matrix (w->desired_matrix);
17163 if (try_window (window, startp, TRY_WINDOW_CHECK_MARGINS) < 0)
17164 /* -1 means we need to scroll.
17165 0 means we need new matrices, but fonts_changed
17166 is set in that case, so we will detect it below. */
17167 goto try_to_scroll;
17170 if (f->fonts_changed)
17171 goto need_larger_matrices;
17173 if (w->cursor.vpos >= 0)
17175 if (!just_this_one_p
17176 || current_buffer->clip_changed
17177 || BEG_UNCHANGED < CHARPOS (startp))
17178 /* Forget any recorded base line for line number display. */
17179 w->base_line_number = 0;
17181 if (!cursor_row_fully_visible_p (w, true, false))
17183 clear_glyph_matrix (w->desired_matrix);
17184 last_line_misfit = true;
17186 /* Drop through and scroll. */
17187 else
17188 goto done;
17190 else
17191 clear_glyph_matrix (w->desired_matrix);
17194 try_to_scroll:
17196 /* Redisplay the mode line. Select the buffer properly for that. */
17197 if (!update_mode_line)
17199 update_mode_line = true;
17200 w->update_mode_line = true;
17203 /* Try to scroll by specified few lines. */
17204 if ((scroll_conservatively
17205 || emacs_scroll_step
17206 || temp_scroll_step
17207 || NUMBERP (BVAR (current_buffer, scroll_up_aggressively))
17208 || NUMBERP (BVAR (current_buffer, scroll_down_aggressively)))
17209 && CHARPOS (startp) >= BEGV
17210 && CHARPOS (startp) <= ZV)
17212 /* The function returns -1 if new fonts were loaded, 1 if
17213 successful, 0 if not successful. */
17214 int ss = try_scrolling (window, just_this_one_p,
17215 scroll_conservatively,
17216 emacs_scroll_step,
17217 temp_scroll_step, last_line_misfit);
17218 switch (ss)
17220 case SCROLLING_SUCCESS:
17221 goto done;
17223 case SCROLLING_NEED_LARGER_MATRICES:
17224 goto need_larger_matrices;
17226 case SCROLLING_FAILED:
17227 break;
17229 default:
17230 emacs_abort ();
17234 /* Finally, just choose a place to start which positions point
17235 according to user preferences. */
17237 recenter:
17239 #ifdef GLYPH_DEBUG
17240 debug_method_add (w, "recenter");
17241 #endif
17243 /* Forget any previously recorded base line for line number display. */
17244 if (!buffer_unchanged_p)
17245 w->base_line_number = 0;
17247 /* Determine the window start relative to point. */
17248 init_iterator (&it, w, PT, PT_BYTE, NULL, DEFAULT_FACE_ID);
17249 it.current_y = it.last_visible_y;
17250 if (centering_position < 0)
17252 ptrdiff_t margin_pos = CHARPOS (startp);
17253 Lisp_Object aggressive;
17254 bool scrolling_up;
17256 /* If there is a scroll margin at the top of the window, find
17257 its character position. */
17258 if (margin
17259 /* Cannot call start_display if startp is not in the
17260 accessible region of the buffer. This can happen when we
17261 have just switched to a different buffer and/or changed
17262 its restriction. In that case, startp is initialized to
17263 the character position 1 (BEGV) because we did not yet
17264 have chance to display the buffer even once. */
17265 && BEGV <= CHARPOS (startp) && CHARPOS (startp) <= ZV)
17267 struct it it1;
17268 void *it1data = NULL;
17270 SAVE_IT (it1, it, it1data);
17271 start_display (&it1, w, startp);
17272 move_it_vertically (&it1, margin * frame_line_height);
17273 margin_pos = IT_CHARPOS (it1);
17274 RESTORE_IT (&it, &it, it1data);
17276 scrolling_up = PT > margin_pos;
17277 aggressive =
17278 scrolling_up
17279 ? BVAR (current_buffer, scroll_up_aggressively)
17280 : BVAR (current_buffer, scroll_down_aggressively);
17282 if (!MINI_WINDOW_P (w)
17283 && (scroll_conservatively > SCROLL_LIMIT || NUMBERP (aggressive)))
17285 int pt_offset = 0;
17287 /* Setting scroll-conservatively overrides
17288 scroll-*-aggressively. */
17289 if (!scroll_conservatively && NUMBERP (aggressive))
17291 double float_amount = XFLOATINT (aggressive);
17293 pt_offset = float_amount * WINDOW_BOX_TEXT_HEIGHT (w);
17294 if (pt_offset == 0 && float_amount > 0)
17295 pt_offset = 1;
17296 if (pt_offset && margin > 0)
17297 margin -= 1;
17299 /* Compute how much to move the window start backward from
17300 point so that point will be displayed where the user
17301 wants it. */
17302 if (scrolling_up)
17304 centering_position = it.last_visible_y;
17305 if (pt_offset)
17306 centering_position -= pt_offset;
17307 centering_position -=
17308 (frame_line_height * (1 + margin + last_line_misfit)
17309 + WINDOW_HEADER_LINE_HEIGHT (w));
17310 /* Don't let point enter the scroll margin near top of
17311 the window. */
17312 if (centering_position < margin * frame_line_height)
17313 centering_position = margin * frame_line_height;
17315 else
17316 centering_position = margin * frame_line_height + pt_offset;
17318 else
17319 /* Set the window start half the height of the window backward
17320 from point. */
17321 centering_position = window_box_height (w) / 2;
17323 move_it_vertically_backward (&it, centering_position);
17325 eassert (IT_CHARPOS (it) >= BEGV);
17327 /* The function move_it_vertically_backward may move over more
17328 than the specified y-distance. If it->w is small, e.g. a
17329 mini-buffer window, we may end up in front of the window's
17330 display area. Start displaying at the start of the line
17331 containing PT in this case. */
17332 if (it.current_y <= 0)
17334 init_iterator (&it, w, PT, PT_BYTE, NULL, DEFAULT_FACE_ID);
17335 move_it_vertically_backward (&it, 0);
17336 it.current_y = 0;
17339 it.current_x = it.hpos = 0;
17341 /* Set the window start position here explicitly, to avoid an
17342 infinite loop in case the functions in window-scroll-functions
17343 get errors. */
17344 set_marker_both (w->start, Qnil, IT_CHARPOS (it), IT_BYTEPOS (it));
17346 /* Run scroll hooks. */
17347 startp = run_window_scroll_functions (window, it.current.pos);
17349 /* We invoke try_window and try_window_reusing_current_matrix below,
17350 and they manipulate the bidi cache. Save and restore the cache
17351 state of our iterator, so we could continue using it after that. */
17352 itdata = bidi_shelve_cache ();
17354 /* Redisplay the window. */
17355 use_desired_matrix = false;
17356 if (!current_matrix_up_to_date_p
17357 || windows_or_buffers_changed
17358 || f->cursor_type_changed
17359 /* Don't use try_window_reusing_current_matrix in this case
17360 because it can have changed the buffer. */
17361 || !NILP (Vwindow_scroll_functions)
17362 || !just_this_one_p
17363 || MINI_WINDOW_P (w)
17364 || !(used_current_matrix_p
17365 = try_window_reusing_current_matrix (w)))
17366 use_desired_matrix = (try_window (window, startp, 0) == 1);
17368 bidi_unshelve_cache (itdata, false);
17370 /* If new fonts have been loaded (due to fontsets), give up. We
17371 have to start a new redisplay since we need to re-adjust glyph
17372 matrices. */
17373 if (f->fonts_changed)
17374 goto need_larger_matrices;
17376 /* If cursor did not appear assume that the middle of the window is
17377 in the first line of the window. Do it again with the next line.
17378 (Imagine a window of height 100, displaying two lines of height
17379 60. Moving back 50 from it->last_visible_y will end in the first
17380 line.) */
17381 if (w->cursor.vpos < 0)
17383 if (w->window_end_valid && PT >= Z - w->window_end_pos)
17385 clear_glyph_matrix (w->desired_matrix);
17386 move_it_by_lines (&it, 1);
17387 try_window (window, it.current.pos, 0);
17389 else if (PT < IT_CHARPOS (it))
17391 clear_glyph_matrix (w->desired_matrix);
17392 move_it_by_lines (&it, -1);
17393 try_window (window, it.current.pos, 0);
17395 else if (scroll_conservatively > SCROLL_LIMIT
17396 && (it.method == GET_FROM_STRING
17397 || overlay_touches_p (IT_CHARPOS (it)))
17398 && IT_CHARPOS (it) < ZV)
17400 /* If the window starts with a before-string that spans more
17401 than one screen line, using that position to display the
17402 window might fail to bring point into the view, because
17403 start_display will always start by displaying the string,
17404 whereas the code above determines where to set w->start
17405 by the buffer position of the place where it takes screen
17406 coordinates. Try to recover by finding the next screen
17407 line that displays buffer text. */
17408 ptrdiff_t pos0 = IT_CHARPOS (it);
17410 clear_glyph_matrix (w->desired_matrix);
17411 do {
17412 move_it_by_lines (&it, 1);
17413 } while (IT_CHARPOS (it) == pos0);
17414 try_window (window, it.current.pos, 0);
17416 else
17418 /* Not much we can do about it. */
17422 /* Consider the following case: Window starts at BEGV, there is
17423 invisible, intangible text at BEGV, so that display starts at
17424 some point START > BEGV. It can happen that we are called with
17425 PT somewhere between BEGV and START. Try to handle that case,
17426 and similar ones. */
17427 if (w->cursor.vpos < 0)
17429 /* Prefer the desired matrix to the current matrix, if possible,
17430 in the fallback calculations below. This is because using
17431 the current matrix might completely goof, e.g. if its first
17432 row is after point. */
17433 struct glyph_matrix *matrix =
17434 use_desired_matrix ? w->desired_matrix : w->current_matrix;
17435 /* First, try locating the proper glyph row for PT. */
17436 struct glyph_row *row =
17437 row_containing_pos (w, PT, matrix->rows, NULL, 0);
17439 /* Sometimes point is at the beginning of invisible text that is
17440 before the 1st character displayed in the row. In that case,
17441 row_containing_pos fails to find the row, because no glyphs
17442 with appropriate buffer positions are present in the row.
17443 Therefore, we next try to find the row which shows the 1st
17444 position after the invisible text. */
17445 if (!row)
17447 Lisp_Object val =
17448 get_char_property_and_overlay (make_number (PT), Qinvisible,
17449 Qnil, NULL);
17451 if (TEXT_PROP_MEANS_INVISIBLE (val) != 0)
17453 ptrdiff_t alt_pos;
17454 Lisp_Object invis_end =
17455 Fnext_single_char_property_change (make_number (PT), Qinvisible,
17456 Qnil, Qnil);
17458 if (NATNUMP (invis_end))
17459 alt_pos = XFASTINT (invis_end);
17460 else
17461 alt_pos = ZV;
17462 row = row_containing_pos (w, alt_pos, matrix->rows, NULL, 0);
17465 /* Finally, fall back on the first row of the window after the
17466 header line (if any). This is slightly better than not
17467 displaying the cursor at all. */
17468 if (!row)
17470 row = matrix->rows;
17471 if (row->mode_line_p)
17472 ++row;
17474 set_cursor_from_row (w, row, matrix, 0, 0, 0, 0);
17477 if (!cursor_row_fully_visible_p (w, false, false))
17479 /* If vscroll is enabled, disable it and try again. */
17480 if (w->vscroll)
17482 w->vscroll = 0;
17483 clear_glyph_matrix (w->desired_matrix);
17484 goto recenter;
17487 /* Users who set scroll-conservatively to a large number want
17488 point just above/below the scroll margin. If we ended up
17489 with point's row partially visible, move the window start to
17490 make that row fully visible and out of the margin. */
17491 if (scroll_conservatively > SCROLL_LIMIT)
17493 int window_total_lines
17494 = WINDOW_TOTAL_LINES (w) * FRAME_LINE_HEIGHT (f) / frame_line_height;
17495 bool move_down = w->cursor.vpos >= window_total_lines / 2;
17497 move_it_by_lines (&it, move_down ? margin + 1 : -(margin + 1));
17498 clear_glyph_matrix (w->desired_matrix);
17499 if (1 == try_window (window, it.current.pos,
17500 TRY_WINDOW_CHECK_MARGINS))
17501 goto done;
17504 /* If centering point failed to make the whole line visible,
17505 put point at the top instead. That has to make the whole line
17506 visible, if it can be done. */
17507 if (centering_position == 0)
17508 goto done;
17510 clear_glyph_matrix (w->desired_matrix);
17511 centering_position = 0;
17512 goto recenter;
17515 done:
17517 SET_TEXT_POS_FROM_MARKER (startp, w->start);
17518 w->start_at_line_beg = (CHARPOS (startp) == BEGV
17519 || FETCH_BYTE (BYTEPOS (startp) - 1) == '\n');
17521 /* Display the mode line, if we must. */
17522 if ((update_mode_line
17523 /* If window not full width, must redo its mode line
17524 if (a) the window to its side is being redone and
17525 (b) we do a frame-based redisplay. This is a consequence
17526 of how inverted lines are drawn in frame-based redisplay. */
17527 || (!just_this_one_p
17528 && !FRAME_WINDOW_P (f)
17529 && !WINDOW_FULL_WIDTH_P (w))
17530 /* Line number to display. */
17531 || w->base_line_pos > 0
17532 /* Column number is displayed and different from the one displayed. */
17533 || (w->column_number_displayed != -1
17534 && (w->column_number_displayed != current_column ())))
17535 /* This means that the window has a mode line. */
17536 && (window_wants_mode_line (w)
17537 || window_wants_header_line (w)))
17540 display_mode_lines (w);
17542 /* If mode line height has changed, arrange for a thorough
17543 immediate redisplay using the correct mode line height. */
17544 if (window_wants_mode_line (w)
17545 && CURRENT_MODE_LINE_HEIGHT (w) != DESIRED_MODE_LINE_HEIGHT (w))
17547 f->fonts_changed = true;
17548 w->mode_line_height = -1;
17549 MATRIX_MODE_LINE_ROW (w->current_matrix)->height
17550 = DESIRED_MODE_LINE_HEIGHT (w);
17553 /* If header line height has changed, arrange for a thorough
17554 immediate redisplay using the correct header line height. */
17555 if (window_wants_header_line (w)
17556 && CURRENT_HEADER_LINE_HEIGHT (w) != DESIRED_HEADER_LINE_HEIGHT (w))
17558 f->fonts_changed = true;
17559 w->header_line_height = -1;
17560 MATRIX_HEADER_LINE_ROW (w->current_matrix)->height
17561 = DESIRED_HEADER_LINE_HEIGHT (w);
17564 if (f->fonts_changed)
17565 goto need_larger_matrices;
17568 if (!line_number_displayed && w->base_line_pos != -1)
17570 w->base_line_pos = 0;
17571 w->base_line_number = 0;
17574 finish_menu_bars:
17576 /* When we reach a frame's selected window, redo the frame's menu
17577 bar and the frame's title. */
17578 if (update_mode_line
17579 && EQ (FRAME_SELECTED_WINDOW (f), window))
17581 bool redisplay_menu_p;
17583 if (FRAME_WINDOW_P (f))
17585 #if defined (USE_X_TOOLKIT) || defined (HAVE_NTGUI) \
17586 || defined (HAVE_NS) || defined (USE_GTK)
17587 redisplay_menu_p = FRAME_EXTERNAL_MENU_BAR (f);
17588 #else
17589 redisplay_menu_p = FRAME_MENU_BAR_LINES (f) > 0;
17590 #endif
17592 else
17593 redisplay_menu_p = FRAME_MENU_BAR_LINES (f) > 0;
17595 if (redisplay_menu_p)
17596 display_menu_bar (w);
17598 #ifdef HAVE_WINDOW_SYSTEM
17599 if (FRAME_WINDOW_P (f))
17601 #if defined (USE_GTK) || defined (HAVE_NS)
17602 if (FRAME_EXTERNAL_TOOL_BAR (f))
17603 redisplay_tool_bar (f);
17604 #else
17605 if (WINDOWP (f->tool_bar_window)
17606 && (FRAME_TOOL_BAR_LINES (f) > 0
17607 || !NILP (Vauto_resize_tool_bars))
17608 && redisplay_tool_bar (f))
17609 ignore_mouse_drag_p = true;
17610 #endif
17612 x_consider_frame_title (w->frame);
17613 #endif
17616 #ifdef HAVE_WINDOW_SYSTEM
17617 if (FRAME_WINDOW_P (f)
17618 && update_window_fringes (w, (just_this_one_p
17619 || (!used_current_matrix_p && !overlay_arrow_seen)
17620 || w->pseudo_window_p)))
17622 update_begin (f);
17623 block_input ();
17624 if (draw_window_fringes (w, true))
17626 if (WINDOW_RIGHT_DIVIDER_WIDTH (w))
17627 x_draw_right_divider (w);
17628 else
17629 x_draw_vertical_border (w);
17631 unblock_input ();
17632 update_end (f);
17635 if (WINDOW_BOTTOM_DIVIDER_WIDTH (w))
17636 x_draw_bottom_divider (w);
17637 #endif /* HAVE_WINDOW_SYSTEM */
17639 /* We go to this label, with fonts_changed set, if it is
17640 necessary to try again using larger glyph matrices.
17641 We have to redeem the scroll bar even in this case,
17642 because the loop in redisplay_internal expects that. */
17643 need_larger_matrices:
17645 finish_scroll_bars:
17647 if (WINDOW_HAS_VERTICAL_SCROLL_BAR (w) || WINDOW_HAS_HORIZONTAL_SCROLL_BAR (w))
17649 if (WINDOW_HAS_VERTICAL_SCROLL_BAR (w))
17650 /* Set the thumb's position and size. */
17651 set_vertical_scroll_bar (w);
17653 if (WINDOW_HAS_HORIZONTAL_SCROLL_BAR (w))
17654 /* Set the thumb's position and size. */
17655 set_horizontal_scroll_bar (w);
17657 /* Note that we actually used the scroll bar attached to this
17658 window, so it shouldn't be deleted at the end of redisplay. */
17659 if (FRAME_TERMINAL (f)->redeem_scroll_bar_hook)
17660 (*FRAME_TERMINAL (f)->redeem_scroll_bar_hook) (w);
17663 /* Restore current_buffer and value of point in it. The window
17664 update may have changed the buffer, so first make sure `opoint'
17665 is still valid (Bug#6177). */
17666 if (CHARPOS (opoint) < BEGV)
17667 TEMP_SET_PT_BOTH (BEGV, BEGV_BYTE);
17668 else if (CHARPOS (opoint) > ZV)
17669 TEMP_SET_PT_BOTH (Z, Z_BYTE);
17670 else
17671 TEMP_SET_PT_BOTH (CHARPOS (opoint), BYTEPOS (opoint));
17673 set_buffer_internal_1 (old);
17674 /* Avoid an abort in TEMP_SET_PT_BOTH if the buffer has become
17675 shorter. This can be caused by log truncation in *Messages*. */
17676 if (CHARPOS (lpoint) <= ZV)
17677 TEMP_SET_PT_BOTH (CHARPOS (lpoint), BYTEPOS (lpoint));
17679 unbind_to (count, Qnil);
17683 /* Build the complete desired matrix of WINDOW with a window start
17684 buffer position POS.
17686 Value is 1 if successful. It is zero if fonts were loaded during
17687 redisplay which makes re-adjusting glyph matrices necessary, and -1
17688 if point would appear in the scroll margins.
17689 (We check the former only if TRY_WINDOW_IGNORE_FONTS_CHANGE is
17690 unset in FLAGS, and the latter only if TRY_WINDOW_CHECK_MARGINS is
17691 set in FLAGS.) */
17694 try_window (Lisp_Object window, struct text_pos pos, int flags)
17696 struct window *w = XWINDOW (window);
17697 struct it it;
17698 struct glyph_row *last_text_row = NULL;
17699 struct frame *f = XFRAME (w->frame);
17700 int cursor_vpos = w->cursor.vpos;
17702 /* Make POS the new window start. */
17703 set_marker_both (w->start, Qnil, CHARPOS (pos), BYTEPOS (pos));
17705 /* Mark cursor position as unknown. No overlay arrow seen. */
17706 w->cursor.vpos = -1;
17707 overlay_arrow_seen = false;
17709 /* Initialize iterator and info to start at POS. */
17710 start_display (&it, w, pos);
17711 it.glyph_row->reversed_p = false;
17713 /* Display all lines of W. */
17714 while (it.current_y < it.last_visible_y)
17716 if (display_line (&it, cursor_vpos))
17717 last_text_row = it.glyph_row - 1;
17718 if (f->fonts_changed && !(flags & TRY_WINDOW_IGNORE_FONTS_CHANGE))
17719 return 0;
17722 /* Save the character position of 'it' before we call
17723 'start_display' again. */
17724 ptrdiff_t it_charpos = IT_CHARPOS (it);
17726 /* Don't let the cursor end in the scroll margins. */
17727 if ((flags & TRY_WINDOW_CHECK_MARGINS)
17728 && !MINI_WINDOW_P (w))
17730 int this_scroll_margin = window_scroll_margin (w, MARGIN_IN_PIXELS);
17731 start_display (&it, w, pos);
17733 if ((w->cursor.y >= 0 /* not vscrolled */
17734 && w->cursor.y < this_scroll_margin
17735 && CHARPOS (pos) > BEGV
17736 && it_charpos < ZV)
17737 /* rms: considering make_cursor_line_fully_visible_p here
17738 seems to give wrong results. We don't want to recenter
17739 when the last line is partly visible, we want to allow
17740 that case to be handled in the usual way. */
17741 || w->cursor.y > (it.last_visible_y - partial_line_height (&it)
17742 - this_scroll_margin - 1))
17744 w->cursor.vpos = -1;
17745 clear_glyph_matrix (w->desired_matrix);
17746 return -1;
17750 /* If bottom moved off end of frame, change mode line percentage. */
17751 if (w->window_end_pos <= 0 && Z != it_charpos)
17752 w->update_mode_line = true;
17754 /* Set window_end_pos to the offset of the last character displayed
17755 on the window from the end of current_buffer. Set
17756 window_end_vpos to its row number. */
17757 if (last_text_row)
17759 eassert (MATRIX_ROW_DISPLAYS_TEXT_P (last_text_row));
17760 adjust_window_ends (w, last_text_row, false);
17761 eassert
17762 (MATRIX_ROW_DISPLAYS_TEXT_P (MATRIX_ROW (w->desired_matrix,
17763 w->window_end_vpos)));
17765 else
17767 w->window_end_bytepos = Z_BYTE - ZV_BYTE;
17768 w->window_end_pos = Z - ZV;
17769 w->window_end_vpos = 0;
17772 /* But that is not valid info until redisplay finishes. */
17773 w->window_end_valid = false;
17774 return 1;
17779 /************************************************************************
17780 Window redisplay reusing current matrix when buffer has not changed
17781 ************************************************************************/
17783 /* Try redisplay of window W showing an unchanged buffer with a
17784 different window start than the last time it was displayed by
17785 reusing its current matrix. Value is true if successful.
17786 W->start is the new window start. */
17788 static bool
17789 try_window_reusing_current_matrix (struct window *w)
17791 struct frame *f = XFRAME (w->frame);
17792 struct glyph_row *bottom_row;
17793 struct it it;
17794 struct run run;
17795 struct text_pos start, new_start;
17796 int nrows_scrolled, i;
17797 struct glyph_row *last_text_row;
17798 struct glyph_row *last_reused_text_row;
17799 struct glyph_row *start_row;
17800 int start_vpos, min_y, max_y;
17802 #ifdef GLYPH_DEBUG
17803 if (inhibit_try_window_reusing)
17804 return false;
17805 #endif
17807 if (/* This function doesn't handle terminal frames. */
17808 !FRAME_WINDOW_P (f)
17809 /* Don't try to reuse the display if windows have been split
17810 or such. */
17811 || windows_or_buffers_changed
17812 || f->cursor_type_changed
17813 /* This function cannot handle buffers where the overlay arrow
17814 is shown on the fringes, because if the arrow position
17815 changes, we cannot just reuse the current matrix. */
17816 || overlay_arrow_in_current_buffer_p ())
17817 return false;
17819 /* Can't do this if showing trailing whitespace. */
17820 if (!NILP (Vshow_trailing_whitespace))
17821 return false;
17823 /* If top-line visibility has changed, give up. */
17824 if (window_wants_header_line (w)
17825 != MATRIX_HEADER_LINE_ROW (w->current_matrix)->mode_line_p)
17826 return false;
17828 /* Give up if old or new display is scrolled vertically. We could
17829 make this function handle this, but right now it doesn't. */
17830 start_row = MATRIX_FIRST_TEXT_ROW (w->current_matrix);
17831 if (w->vscroll || MATRIX_ROW_PARTIALLY_VISIBLE_P (w, start_row))
17832 return false;
17834 /* Clear the desired matrix for the display below. */
17835 clear_glyph_matrix (w->desired_matrix);
17837 /* Give up if line numbers are being displayed, because reusing the
17838 current matrix might use the wrong width for line-number
17839 display. */
17840 if (!NILP (Vdisplay_line_numbers))
17841 return false;
17843 /* The variable new_start now holds the new window start. The old
17844 start `start' can be determined from the current matrix. */
17845 SET_TEXT_POS_FROM_MARKER (new_start, w->start);
17846 start = start_row->minpos;
17847 start_vpos = MATRIX_ROW_VPOS (start_row, w->current_matrix);
17849 if (CHARPOS (new_start) <= CHARPOS (start))
17851 /* Don't use this method if the display starts with an ellipsis
17852 displayed for invisible text. It's not easy to handle that case
17853 below, and it's certainly not worth the effort since this is
17854 not a frequent case. */
17855 if (in_ellipses_for_invisible_text_p (&start_row->start, w))
17856 return false;
17858 IF_DEBUG (debug_method_add (w, "twu1"));
17860 /* Display up to a row that can be reused. The variable
17861 last_text_row is set to the last row displayed that displays
17862 text. Note that it.vpos == 0 if or if not there is a
17863 header-line; it's not the same as the MATRIX_ROW_VPOS! */
17864 start_display (&it, w, new_start);
17865 w->cursor.vpos = -1;
17866 last_text_row = last_reused_text_row = NULL;
17868 while (it.current_y < it.last_visible_y && !f->fonts_changed)
17870 /* If we have reached into the characters in the START row,
17871 that means the line boundaries have changed. So we
17872 can't start copying with the row START. Maybe it will
17873 work to start copying with the following row. */
17874 while (IT_CHARPOS (it) > CHARPOS (start))
17876 /* Advance to the next row as the "start". */
17877 start_row++;
17878 start = start_row->minpos;
17879 /* If there are no more rows to try, or just one, give up. */
17880 if (start_row == MATRIX_MODE_LINE_ROW (w->current_matrix) - 1
17881 || w->vscroll || MATRIX_ROW_PARTIALLY_VISIBLE_P (w, start_row)
17882 || CHARPOS (start) == ZV)
17884 clear_glyph_matrix (w->desired_matrix);
17885 return false;
17888 start_vpos = MATRIX_ROW_VPOS (start_row, w->current_matrix);
17890 /* If we have reached alignment, we can copy the rest of the
17891 rows. */
17892 if (IT_CHARPOS (it) == CHARPOS (start)
17893 /* Don't accept "alignment" inside a display vector,
17894 since start_row could have started in the middle of
17895 that same display vector (thus their character
17896 positions match), and we have no way of telling if
17897 that is the case. */
17898 && it.current.dpvec_index < 0)
17899 break;
17901 it.glyph_row->reversed_p = false;
17902 if (display_line (&it, -1))
17903 last_text_row = it.glyph_row - 1;
17907 /* A value of current_y < last_visible_y means that we stopped
17908 at the previous window start, which in turn means that we
17909 have at least one reusable row. */
17910 if (it.current_y < it.last_visible_y)
17912 struct glyph_row *row;
17914 /* IT.vpos always starts from 0; it counts text lines. */
17915 nrows_scrolled = it.vpos - (start_row - MATRIX_FIRST_TEXT_ROW (w->current_matrix));
17917 /* Find PT if not already found in the lines displayed. */
17918 if (w->cursor.vpos < 0)
17920 int dy = it.current_y - start_row->y;
17922 row = MATRIX_FIRST_TEXT_ROW (w->current_matrix);
17923 row = row_containing_pos (w, PT, row, NULL, dy);
17924 if (row)
17925 set_cursor_from_row (w, row, w->current_matrix, 0, 0,
17926 dy, nrows_scrolled);
17927 else
17929 clear_glyph_matrix (w->desired_matrix);
17930 return false;
17934 /* Scroll the display. Do it before the current matrix is
17935 changed. The problem here is that update has not yet
17936 run, i.e. part of the current matrix is not up to date.
17937 scroll_run_hook will clear the cursor, and use the
17938 current matrix to get the height of the row the cursor is
17939 in. */
17940 run.current_y = start_row->y;
17941 run.desired_y = it.current_y;
17942 run.height = it.last_visible_y - it.current_y;
17944 if (run.height > 0 && run.current_y != run.desired_y)
17946 update_begin (f);
17947 FRAME_RIF (f)->update_window_begin_hook (w);
17948 FRAME_RIF (f)->clear_window_mouse_face (w);
17949 FRAME_RIF (f)->scroll_run_hook (w, &run);
17950 FRAME_RIF (f)->update_window_end_hook (w, false, false);
17951 update_end (f);
17954 /* Shift current matrix down by nrows_scrolled lines. */
17955 bottom_row = MATRIX_BOTTOM_TEXT_ROW (w->current_matrix, w);
17956 rotate_matrix (w->current_matrix,
17957 start_vpos,
17958 MATRIX_ROW_VPOS (bottom_row, w->current_matrix),
17959 nrows_scrolled);
17961 /* Disable lines that must be updated. */
17962 for (i = 0; i < nrows_scrolled; ++i)
17963 (start_row + i)->enabled_p = false;
17965 /* Re-compute Y positions. */
17966 min_y = WINDOW_HEADER_LINE_HEIGHT (w);
17967 max_y = it.last_visible_y;
17968 for (row = start_row + nrows_scrolled;
17969 row < bottom_row;
17970 ++row)
17972 row->y = it.current_y;
17973 row->visible_height = row->height;
17975 if (row->y < min_y)
17976 row->visible_height -= min_y - row->y;
17977 if (row->y + row->height > max_y)
17978 row->visible_height -= row->y + row->height - max_y;
17979 if (row->fringe_bitmap_periodic_p)
17980 row->redraw_fringe_bitmaps_p = true;
17982 it.current_y += row->height;
17984 if (MATRIX_ROW_DISPLAYS_TEXT_P (row))
17985 last_reused_text_row = row;
17986 if (MATRIX_ROW_BOTTOM_Y (row) >= it.last_visible_y)
17987 break;
17990 /* Disable lines in the current matrix which are now
17991 below the window. */
17992 for (++row; row < bottom_row; ++row)
17993 row->enabled_p = row->mode_line_p = false;
17996 /* Update window_end_pos etc.; last_reused_text_row is the last
17997 reused row from the current matrix containing text, if any.
17998 The value of last_text_row is the last displayed line
17999 containing text. */
18000 if (last_reused_text_row)
18001 adjust_window_ends (w, last_reused_text_row, true);
18002 else if (last_text_row)
18003 adjust_window_ends (w, last_text_row, false);
18004 else
18006 /* This window must be completely empty. */
18007 w->window_end_bytepos = Z_BYTE - ZV_BYTE;
18008 w->window_end_pos = Z - ZV;
18009 w->window_end_vpos = 0;
18011 w->window_end_valid = false;
18013 /* Update hint: don't try scrolling again in update_window. */
18014 w->desired_matrix->no_scrolling_p = true;
18016 #ifdef GLYPH_DEBUG
18017 debug_method_add (w, "try_window_reusing_current_matrix 1");
18018 #endif
18019 return true;
18021 else if (CHARPOS (new_start) > CHARPOS (start))
18023 struct glyph_row *pt_row, *row;
18024 struct glyph_row *first_reusable_row;
18025 struct glyph_row *first_row_to_display;
18026 int dy;
18027 int yb = window_text_bottom_y (w);
18029 /* Find the row starting at new_start, if there is one. Don't
18030 reuse a partially visible line at the end. */
18031 first_reusable_row = start_row;
18032 while (first_reusable_row->enabled_p
18033 && MATRIX_ROW_BOTTOM_Y (first_reusable_row) < yb
18034 && (MATRIX_ROW_START_CHARPOS (first_reusable_row)
18035 < CHARPOS (new_start)))
18036 ++first_reusable_row;
18038 /* Give up if there is no row to reuse. */
18039 if (MATRIX_ROW_BOTTOM_Y (first_reusable_row) >= yb
18040 || !first_reusable_row->enabled_p
18041 || (MATRIX_ROW_START_CHARPOS (first_reusable_row)
18042 != CHARPOS (new_start)))
18043 return false;
18045 /* We can reuse fully visible rows beginning with
18046 first_reusable_row to the end of the window. Set
18047 first_row_to_display to the first row that cannot be reused.
18048 Set pt_row to the row containing point, if there is any. */
18049 pt_row = NULL;
18050 for (first_row_to_display = first_reusable_row;
18051 MATRIX_ROW_BOTTOM_Y (first_row_to_display) < yb;
18052 ++first_row_to_display)
18054 if (PT >= MATRIX_ROW_START_CHARPOS (first_row_to_display)
18055 && (PT < MATRIX_ROW_END_CHARPOS (first_row_to_display)
18056 || (PT == MATRIX_ROW_END_CHARPOS (first_row_to_display)
18057 && first_row_to_display->ends_at_zv_p
18058 && pt_row == NULL)))
18059 pt_row = first_row_to_display;
18062 /* Start displaying at the start of first_row_to_display. */
18063 eassert (first_row_to_display->y < yb);
18064 init_to_row_start (&it, w, first_row_to_display);
18066 nrows_scrolled = (MATRIX_ROW_VPOS (first_reusable_row, w->current_matrix)
18067 - start_vpos);
18068 it.vpos = (MATRIX_ROW_VPOS (first_row_to_display, w->current_matrix)
18069 - nrows_scrolled);
18070 it.current_y = (first_row_to_display->y - first_reusable_row->y
18071 + WINDOW_HEADER_LINE_HEIGHT (w));
18073 /* Display lines beginning with first_row_to_display in the
18074 desired matrix. Set last_text_row to the last row displayed
18075 that displays text. */
18076 it.glyph_row = MATRIX_ROW (w->desired_matrix, it.vpos);
18077 if (pt_row == NULL)
18078 w->cursor.vpos = -1;
18079 last_text_row = NULL;
18080 while (it.current_y < it.last_visible_y && !f->fonts_changed)
18081 if (display_line (&it, w->cursor.vpos))
18082 last_text_row = it.glyph_row - 1;
18084 /* If point is in a reused row, adjust y and vpos of the cursor
18085 position. */
18086 if (pt_row)
18088 w->cursor.vpos -= nrows_scrolled;
18089 w->cursor.y -= first_reusable_row->y - start_row->y;
18092 /* Give up if point isn't in a row displayed or reused. (This
18093 also handles the case where w->cursor.vpos < nrows_scrolled
18094 after the calls to display_line, which can happen with scroll
18095 margins. See bug#1295.) */
18096 if (w->cursor.vpos < 0)
18098 clear_glyph_matrix (w->desired_matrix);
18099 return false;
18102 /* Scroll the display. */
18103 run.current_y = first_reusable_row->y;
18104 run.desired_y = WINDOW_HEADER_LINE_HEIGHT (w);
18105 run.height = it.last_visible_y - run.current_y;
18106 dy = run.current_y - run.desired_y;
18108 if (run.height)
18110 update_begin (f);
18111 FRAME_RIF (f)->update_window_begin_hook (w);
18112 FRAME_RIF (f)->clear_window_mouse_face (w);
18113 FRAME_RIF (f)->scroll_run_hook (w, &run);
18114 FRAME_RIF (f)->update_window_end_hook (w, false, false);
18115 update_end (f);
18118 /* Adjust Y positions of reused rows. */
18119 bottom_row = MATRIX_BOTTOM_TEXT_ROW (w->current_matrix, w);
18120 min_y = WINDOW_HEADER_LINE_HEIGHT (w);
18121 max_y = it.last_visible_y;
18122 for (row = first_reusable_row; row < first_row_to_display; ++row)
18124 row->y -= dy;
18125 row->visible_height = row->height;
18126 if (row->y < min_y)
18127 row->visible_height -= min_y - row->y;
18128 if (row->y + row->height > max_y)
18129 row->visible_height -= row->y + row->height - max_y;
18130 if (row->fringe_bitmap_periodic_p)
18131 row->redraw_fringe_bitmaps_p = true;
18134 /* Scroll the current matrix. */
18135 eassert (nrows_scrolled > 0);
18136 rotate_matrix (w->current_matrix,
18137 start_vpos,
18138 MATRIX_ROW_VPOS (bottom_row, w->current_matrix),
18139 -nrows_scrolled);
18141 /* Disable rows not reused. */
18142 for (row -= nrows_scrolled; row < bottom_row; ++row)
18143 row->enabled_p = false;
18145 /* Point may have moved to a different line, so we cannot assume that
18146 the previous cursor position is valid; locate the correct row. */
18147 if (pt_row)
18149 for (row = MATRIX_ROW (w->current_matrix, w->cursor.vpos);
18150 row < bottom_row
18151 && PT >= MATRIX_ROW_END_CHARPOS (row)
18152 && !row->ends_at_zv_p;
18153 row++)
18155 w->cursor.vpos++;
18156 w->cursor.y = row->y;
18158 if (row < bottom_row)
18160 /* Can't simply scan the row for point with
18161 bidi-reordered glyph rows. Let set_cursor_from_row
18162 figure out where to put the cursor, and if it fails,
18163 give up. */
18164 if (!NILP (BVAR (XBUFFER (w->contents), bidi_display_reordering)))
18166 if (!set_cursor_from_row (w, row, w->current_matrix,
18167 0, 0, 0, 0))
18169 clear_glyph_matrix (w->desired_matrix);
18170 return false;
18173 else
18175 struct glyph *glyph = row->glyphs[TEXT_AREA] + w->cursor.hpos;
18176 struct glyph *end = row->glyphs[TEXT_AREA] + row->used[TEXT_AREA];
18178 for (; glyph < end
18179 && (!BUFFERP (glyph->object)
18180 || glyph->charpos < PT);
18181 glyph++)
18183 w->cursor.hpos++;
18184 w->cursor.x += glyph->pixel_width;
18190 /* Adjust window end. A null value of last_text_row means that
18191 the window end is in reused rows which in turn means that
18192 only its vpos can have changed. */
18193 if (last_text_row)
18194 adjust_window_ends (w, last_text_row, false);
18195 else
18196 w->window_end_vpos -= nrows_scrolled;
18198 w->window_end_valid = false;
18199 w->desired_matrix->no_scrolling_p = true;
18201 #ifdef GLYPH_DEBUG
18202 debug_method_add (w, "try_window_reusing_current_matrix 2");
18203 #endif
18204 return true;
18207 return false;
18212 /************************************************************************
18213 Window redisplay reusing current matrix when buffer has changed
18214 ************************************************************************/
18216 static struct glyph_row *find_last_unchanged_at_beg_row (struct window *);
18217 static struct glyph_row *find_first_unchanged_at_end_row (struct window *,
18218 ptrdiff_t *, ptrdiff_t *);
18219 static struct glyph_row *
18220 find_last_row_displaying_text (struct glyph_matrix *, struct it *,
18221 struct glyph_row *);
18224 /* Return the last row in MATRIX displaying text. If row START is
18225 non-null, start searching with that row. IT gives the dimensions
18226 of the display. Value is null if matrix is empty; otherwise it is
18227 a pointer to the row found. */
18229 static struct glyph_row *
18230 find_last_row_displaying_text (struct glyph_matrix *matrix, struct it *it,
18231 struct glyph_row *start)
18233 struct glyph_row *row, *row_found;
18235 /* Set row_found to the last row in IT->w's current matrix
18236 displaying text. The loop looks funny but think of partially
18237 visible lines. */
18238 row_found = NULL;
18239 row = start ? start : MATRIX_FIRST_TEXT_ROW (matrix);
18240 while (MATRIX_ROW_DISPLAYS_TEXT_P (row))
18242 eassert (row->enabled_p);
18243 row_found = row;
18244 if (MATRIX_ROW_BOTTOM_Y (row) >= it->last_visible_y)
18245 break;
18246 ++row;
18249 return row_found;
18253 /* Return the last row in the current matrix of W that is not affected
18254 by changes at the start of current_buffer that occurred since W's
18255 current matrix was built. Value is null if no such row exists.
18257 BEG_UNCHANGED us the number of characters unchanged at the start of
18258 current_buffer. BEG + BEG_UNCHANGED is the buffer position of the
18259 first changed character in current_buffer. Characters at positions <
18260 BEG + BEG_UNCHANGED are at the same buffer positions as they were
18261 when the current matrix was built. */
18263 static struct glyph_row *
18264 find_last_unchanged_at_beg_row (struct window *w)
18266 ptrdiff_t first_changed_pos = BEG + BEG_UNCHANGED;
18267 struct glyph_row *row;
18268 struct glyph_row *row_found = NULL;
18269 int yb = window_text_bottom_y (w);
18271 /* Find the last row displaying unchanged text. */
18272 for (row = MATRIX_FIRST_TEXT_ROW (w->current_matrix);
18273 MATRIX_ROW_DISPLAYS_TEXT_P (row)
18274 && MATRIX_ROW_START_CHARPOS (row) < first_changed_pos;
18275 ++row)
18277 if (/* If row ends before first_changed_pos, it is unchanged,
18278 except in some case. */
18279 MATRIX_ROW_END_CHARPOS (row) <= first_changed_pos
18280 /* When row ends in ZV and we write at ZV it is not
18281 unchanged. */
18282 && !row->ends_at_zv_p
18283 /* When first_changed_pos is the end of a continued line,
18284 row is not unchanged because it may be no longer
18285 continued. */
18286 && !(MATRIX_ROW_END_CHARPOS (row) == first_changed_pos
18287 && (row->continued_p
18288 || row->exact_window_width_line_p))
18289 /* If ROW->end is beyond ZV, then ROW->end is outdated and
18290 needs to be recomputed, so don't consider this row as
18291 unchanged. This happens when the last line was
18292 bidi-reordered and was killed immediately before this
18293 redisplay cycle. In that case, ROW->end stores the
18294 buffer position of the first visual-order character of
18295 the killed text, which is now beyond ZV. */
18296 && CHARPOS (row->end.pos) <= ZV)
18297 row_found = row;
18299 /* Stop if last visible row. */
18300 if (MATRIX_ROW_BOTTOM_Y (row) >= yb)
18301 break;
18304 return row_found;
18308 /* Find the first glyph row in the current matrix of W that is not
18309 affected by changes at the end of current_buffer since the
18310 time W's current matrix was built.
18312 Return in *DELTA the number of chars by which buffer positions in
18313 unchanged text at the end of current_buffer must be adjusted.
18315 Return in *DELTA_BYTES the corresponding number of bytes.
18317 Value is null if no such row exists, i.e. all rows are affected by
18318 changes. */
18320 static struct glyph_row *
18321 find_first_unchanged_at_end_row (struct window *w,
18322 ptrdiff_t *delta, ptrdiff_t *delta_bytes)
18324 struct glyph_row *row;
18325 struct glyph_row *row_found = NULL;
18327 *delta = *delta_bytes = 0;
18329 /* Display must not have been paused, otherwise the current matrix
18330 is not up to date. */
18331 eassert (w->window_end_valid);
18333 /* A value of window_end_pos >= END_UNCHANGED means that the window
18334 end is in the range of changed text. If so, there is no
18335 unchanged row at the end of W's current matrix. */
18336 if (w->window_end_pos >= END_UNCHANGED)
18337 return NULL;
18339 /* Set row to the last row in W's current matrix displaying text. */
18340 row = MATRIX_ROW (w->current_matrix, w->window_end_vpos);
18342 /* If matrix is entirely empty, no unchanged row exists. */
18343 if (MATRIX_ROW_DISPLAYS_TEXT_P (row))
18345 /* The value of row is the last glyph row in the matrix having a
18346 meaningful buffer position in it. The end position of row
18347 corresponds to window_end_pos. This allows us to translate
18348 buffer positions in the current matrix to current buffer
18349 positions for characters not in changed text. */
18350 ptrdiff_t Z_old =
18351 MATRIX_ROW_END_CHARPOS (row) + w->window_end_pos;
18352 ptrdiff_t Z_BYTE_old =
18353 MATRIX_ROW_END_BYTEPOS (row) + w->window_end_bytepos;
18354 ptrdiff_t last_unchanged_pos, last_unchanged_pos_old;
18355 struct glyph_row *first_text_row
18356 = MATRIX_FIRST_TEXT_ROW (w->current_matrix);
18358 *delta = Z - Z_old;
18359 *delta_bytes = Z_BYTE - Z_BYTE_old;
18361 /* Set last_unchanged_pos to the buffer position of the last
18362 character in the buffer that has not been changed. Z is the
18363 index + 1 of the last character in current_buffer, i.e. by
18364 subtracting END_UNCHANGED we get the index of the last
18365 unchanged character, and we have to add BEG to get its buffer
18366 position. */
18367 last_unchanged_pos = Z - END_UNCHANGED + BEG;
18368 last_unchanged_pos_old = last_unchanged_pos - *delta;
18370 /* Search backward from ROW for a row displaying a line that
18371 starts at a minimum position >= last_unchanged_pos_old. */
18372 for (; row > first_text_row; --row)
18374 /* This used to abort, but it can happen.
18375 It is ok to just stop the search instead here. KFS. */
18376 if (!row->enabled_p || !MATRIX_ROW_DISPLAYS_TEXT_P (row))
18377 break;
18379 if (MATRIX_ROW_START_CHARPOS (row) >= last_unchanged_pos_old)
18380 row_found = row;
18384 eassert (!row_found || MATRIX_ROW_DISPLAYS_TEXT_P (row_found));
18386 return row_found;
18390 /* Make sure that glyph rows in the current matrix of window W
18391 reference the same glyph memory as corresponding rows in the
18392 frame's frame matrix. This function is called after scrolling W's
18393 current matrix on a terminal frame in try_window_id and
18394 try_window_reusing_current_matrix. */
18396 static void
18397 sync_frame_with_window_matrix_rows (struct window *w)
18399 struct frame *f = XFRAME (w->frame);
18400 struct glyph_row *window_row, *window_row_end, *frame_row;
18402 /* Preconditions: W must be a leaf window and full-width. Its frame
18403 must have a frame matrix. */
18404 eassert (BUFFERP (w->contents));
18405 eassert (WINDOW_FULL_WIDTH_P (w));
18406 eassert (!FRAME_WINDOW_P (f));
18408 /* If W is a full-width window, glyph pointers in W's current matrix
18409 have, by definition, to be the same as glyph pointers in the
18410 corresponding frame matrix. Note that frame matrices have no
18411 marginal areas (see build_frame_matrix). */
18412 window_row = w->current_matrix->rows;
18413 window_row_end = window_row + w->current_matrix->nrows;
18414 frame_row = f->current_matrix->rows + WINDOW_TOP_EDGE_LINE (w);
18415 while (window_row < window_row_end)
18417 struct glyph *start = window_row->glyphs[LEFT_MARGIN_AREA];
18418 struct glyph *end = window_row->glyphs[LAST_AREA];
18420 frame_row->glyphs[LEFT_MARGIN_AREA] = start;
18421 frame_row->glyphs[TEXT_AREA] = start;
18422 frame_row->glyphs[RIGHT_MARGIN_AREA] = end;
18423 frame_row->glyphs[LAST_AREA] = end;
18425 /* Disable frame rows whose corresponding window rows have
18426 been disabled in try_window_id. */
18427 if (!window_row->enabled_p)
18428 frame_row->enabled_p = false;
18430 ++window_row, ++frame_row;
18435 /* Find the glyph row in window W containing CHARPOS. Consider all
18436 rows between START and END (not inclusive). END null means search
18437 all rows to the end of the display area of W. Value is the row
18438 containing CHARPOS or null. */
18440 struct glyph_row *
18441 row_containing_pos (struct window *w, ptrdiff_t charpos,
18442 struct glyph_row *start, struct glyph_row *end, int dy)
18444 struct glyph_row *row = start;
18445 struct glyph_row *best_row = NULL;
18446 ptrdiff_t mindif = BUF_ZV (XBUFFER (w->contents)) + 1;
18447 int last_y;
18449 /* If we happen to start on a header-line, skip that. */
18450 if (row->mode_line_p)
18451 ++row;
18453 if ((end && row >= end) || !row->enabled_p)
18454 return NULL;
18456 last_y = window_text_bottom_y (w) - dy;
18458 while (true)
18460 /* Give up if we have gone too far. */
18461 if ((end && row >= end) || !row->enabled_p)
18462 return NULL;
18463 /* This formerly returned if they were equal.
18464 I think that both quantities are of a "last plus one" type;
18465 if so, when they are equal, the row is within the screen. -- rms. */
18466 if (MATRIX_ROW_BOTTOM_Y (row) > last_y)
18467 return NULL;
18469 /* If it is in this row, return this row. */
18470 if (! (MATRIX_ROW_END_CHARPOS (row) < charpos
18471 || (MATRIX_ROW_END_CHARPOS (row) == charpos
18472 /* The end position of a row equals the start
18473 position of the next row. If CHARPOS is there, we
18474 would rather consider it displayed in the next
18475 line, except when this line ends in ZV. */
18476 && !row_for_charpos_p (row, charpos)))
18477 && charpos >= MATRIX_ROW_START_CHARPOS (row))
18479 struct glyph *g;
18481 if (NILP (BVAR (XBUFFER (w->contents), bidi_display_reordering))
18482 || (!best_row && !row->continued_p))
18483 return row;
18484 /* In bidi-reordered rows, there could be several rows whose
18485 edges surround CHARPOS, all of these rows belonging to
18486 the same continued line. We need to find the row which
18487 fits CHARPOS the best. */
18488 for (g = row->glyphs[TEXT_AREA];
18489 g < row->glyphs[TEXT_AREA] + row->used[TEXT_AREA];
18490 g++)
18492 if (!STRINGP (g->object))
18494 if (g->charpos > 0 && eabs (g->charpos - charpos) < mindif)
18496 mindif = eabs (g->charpos - charpos);
18497 best_row = row;
18498 /* Exact match always wins. */
18499 if (mindif == 0)
18500 return best_row;
18505 else if (best_row && !row->continued_p)
18506 return best_row;
18507 ++row;
18512 /* Try to redisplay window W by reusing its existing display. W's
18513 current matrix must be up to date when this function is called,
18514 i.e., window_end_valid must be true.
18516 Value is
18518 >= 1 if successful, i.e. display has been updated
18519 specifically:
18520 1 means the changes were in front of a newline that precedes
18521 the window start, and the whole current matrix was reused
18522 2 means the changes were after the last position displayed
18523 in the window, and the whole current matrix was reused
18524 3 means portions of the current matrix were reused, while
18525 some of the screen lines were redrawn
18526 -1 if redisplay with same window start is known not to succeed
18527 0 if otherwise unsuccessful
18529 The following steps are performed:
18531 1. Find the last row in the current matrix of W that is not
18532 affected by changes at the start of current_buffer. If no such row
18533 is found, give up.
18535 2. Find the first row in W's current matrix that is not affected by
18536 changes at the end of current_buffer. Maybe there is no such row.
18538 3. Display lines beginning with the row + 1 found in step 1 to the
18539 row found in step 2 or, if step 2 didn't find a row, to the end of
18540 the window.
18542 4. If cursor is not known to appear on the window, give up.
18544 5. If display stopped at the row found in step 2, scroll the
18545 display and current matrix as needed.
18547 6. Maybe display some lines at the end of W, if we must. This can
18548 happen under various circumstances, like a partially visible line
18549 becoming fully visible, or because newly displayed lines are displayed
18550 in smaller font sizes.
18552 7. Update W's window end information. */
18554 static int
18555 try_window_id (struct window *w)
18557 struct frame *f = XFRAME (w->frame);
18558 struct glyph_matrix *current_matrix = w->current_matrix;
18559 struct glyph_matrix *desired_matrix = w->desired_matrix;
18560 struct glyph_row *last_unchanged_at_beg_row;
18561 struct glyph_row *first_unchanged_at_end_row;
18562 struct glyph_row *row;
18563 struct glyph_row *bottom_row;
18564 int bottom_vpos;
18565 struct it it;
18566 ptrdiff_t delta = 0, delta_bytes = 0, stop_pos;
18567 int dvpos, dy;
18568 struct text_pos start_pos;
18569 struct run run;
18570 int first_unchanged_at_end_vpos = 0;
18571 struct glyph_row *last_text_row, *last_text_row_at_end;
18572 struct text_pos start;
18573 ptrdiff_t first_changed_charpos, last_changed_charpos;
18575 #ifdef GLYPH_DEBUG
18576 if (inhibit_try_window_id)
18577 return 0;
18578 #endif
18580 /* This is handy for debugging. */
18581 #if false
18582 #define GIVE_UP(X) \
18583 do { \
18584 TRACE ((stderr, "try_window_id give up %d\n", (X))); \
18585 return 0; \
18586 } while (false)
18587 #else
18588 #define GIVE_UP(X) return 0
18589 #endif
18591 SET_TEXT_POS_FROM_MARKER (start, w->start);
18593 /* Don't use this for mini-windows because these can show
18594 messages and mini-buffers, and we don't handle that here. */
18595 if (MINI_WINDOW_P (w))
18596 GIVE_UP (1);
18598 /* This flag is used to prevent redisplay optimizations. */
18599 if (windows_or_buffers_changed || f->cursor_type_changed)
18600 GIVE_UP (2);
18602 /* This function's optimizations cannot be used if overlays have
18603 changed in the buffer displayed by the window, so give up if they
18604 have. */
18605 if (w->last_overlay_modified != OVERLAY_MODIFF)
18606 GIVE_UP (200);
18608 /* Verify that narrowing has not changed.
18609 Also verify that we were not told to prevent redisplay optimizations.
18610 It would be nice to further
18611 reduce the number of cases where this prevents try_window_id. */
18612 if (current_buffer->clip_changed
18613 || current_buffer->prevent_redisplay_optimizations_p)
18614 GIVE_UP (3);
18616 /* Window must either use window-based redisplay or be full width. */
18617 if (!FRAME_WINDOW_P (f)
18618 && (!FRAME_LINE_INS_DEL_OK (f)
18619 || !WINDOW_FULL_WIDTH_P (w)))
18620 GIVE_UP (4);
18622 /* Give up if point is known NOT to appear in W. */
18623 if (PT < CHARPOS (start))
18624 GIVE_UP (5);
18626 /* Another way to prevent redisplay optimizations. */
18627 if (w->last_modified == 0)
18628 GIVE_UP (6);
18630 /* Verify that window is not hscrolled. */
18631 if (w->hscroll != 0)
18632 GIVE_UP (7);
18634 /* Verify that display wasn't paused. */
18635 if (!w->window_end_valid)
18636 GIVE_UP (8);
18638 /* Likewise if highlighting trailing whitespace. */
18639 if (!NILP (Vshow_trailing_whitespace))
18640 GIVE_UP (11);
18642 /* Can't use this if overlay arrow position and/or string have
18643 changed. */
18644 if (overlay_arrows_changed_p (false))
18645 GIVE_UP (12);
18647 /* When word-wrap is on, adding a space to the first word of a
18648 wrapped line can change the wrap position, altering the line
18649 above it. It might be worthwhile to handle this more
18650 intelligently, but for now just redisplay from scratch. */
18651 if (!NILP (BVAR (XBUFFER (w->contents), word_wrap)))
18652 GIVE_UP (21);
18654 /* Under bidi reordering, adding or deleting a character in the
18655 beginning of a paragraph, before the first strong directional
18656 character, can change the base direction of the paragraph (unless
18657 the buffer specifies a fixed paragraph direction), which will
18658 require redisplaying the whole paragraph. It might be worthwhile
18659 to find the paragraph limits and widen the range of redisplayed
18660 lines to that, but for now just give up this optimization and
18661 redisplay from scratch. */
18662 if (!NILP (BVAR (XBUFFER (w->contents), bidi_display_reordering))
18663 && NILP (BVAR (XBUFFER (w->contents), bidi_paragraph_direction)))
18664 GIVE_UP (22);
18666 /* Give up if the buffer has line-spacing set, as Lisp-level changes
18667 to that variable require thorough redisplay. */
18668 if (!NILP (BVAR (XBUFFER (w->contents), extra_line_spacing)))
18669 GIVE_UP (23);
18671 /* Give up if display-line-numbers is in relative mode, or when the
18672 current line's number needs to be displayed in a distinct face. */
18673 if (EQ (Vdisplay_line_numbers, Qrelative)
18674 || EQ (Vdisplay_line_numbers, Qvisual)
18675 || (!NILP (Vdisplay_line_numbers)
18676 && NILP (Finternal_lisp_face_equal_p (Qline_number,
18677 Qline_number_current_line,
18678 w->frame))))
18679 GIVE_UP (24);
18681 /* Make sure beg_unchanged and end_unchanged are up to date. Do it
18682 only if buffer has really changed. The reason is that the gap is
18683 initially at Z for freshly visited files. The code below would
18684 set end_unchanged to 0 in that case. */
18685 if (MODIFF > SAVE_MODIFF
18686 /* This seems to happen sometimes after saving a buffer. */
18687 || BEG_UNCHANGED + END_UNCHANGED > Z_BYTE)
18689 if (GPT - BEG < BEG_UNCHANGED)
18690 BEG_UNCHANGED = GPT - BEG;
18691 if (Z - GPT < END_UNCHANGED)
18692 END_UNCHANGED = Z - GPT;
18695 /* The position of the first and last character that has been changed. */
18696 first_changed_charpos = BEG + BEG_UNCHANGED;
18697 last_changed_charpos = Z - END_UNCHANGED;
18699 /* If window starts after a line end, and the last change is in
18700 front of that newline, then changes don't affect the display.
18701 This case happens with stealth-fontification. Note that although
18702 the display is unchanged, glyph positions in the matrix have to
18703 be adjusted, of course. */
18704 row = MATRIX_ROW (w->current_matrix, w->window_end_vpos);
18705 if (MATRIX_ROW_DISPLAYS_TEXT_P (row)
18706 && ((last_changed_charpos < CHARPOS (start)
18707 && CHARPOS (start) == BEGV)
18708 || (last_changed_charpos < CHARPOS (start) - 1
18709 && FETCH_BYTE (BYTEPOS (start) - 1) == '\n')))
18711 ptrdiff_t Z_old, Z_delta, Z_BYTE_old, Z_delta_bytes;
18712 struct glyph_row *r0;
18714 /* Compute how many chars/bytes have been added to or removed
18715 from the buffer. */
18716 Z_old = MATRIX_ROW_END_CHARPOS (row) + w->window_end_pos;
18717 Z_BYTE_old = MATRIX_ROW_END_BYTEPOS (row) + w->window_end_bytepos;
18718 Z_delta = Z - Z_old;
18719 Z_delta_bytes = Z_BYTE - Z_BYTE_old;
18721 /* Give up if PT is not in the window. Note that it already has
18722 been checked at the start of try_window_id that PT is not in
18723 front of the window start. */
18724 if (PT >= MATRIX_ROW_END_CHARPOS (row) + Z_delta)
18725 GIVE_UP (13);
18727 /* If window start is unchanged, we can reuse the whole matrix
18728 as is, after adjusting glyph positions. No need to compute
18729 the window end again, since its offset from Z hasn't changed. */
18730 r0 = MATRIX_FIRST_TEXT_ROW (current_matrix);
18731 if (CHARPOS (start) == MATRIX_ROW_START_CHARPOS (r0) + Z_delta
18732 && BYTEPOS (start) == MATRIX_ROW_START_BYTEPOS (r0) + Z_delta_bytes
18733 /* PT must not be in a partially visible line. */
18734 && !(PT >= MATRIX_ROW_START_CHARPOS (row) + Z_delta
18735 && MATRIX_ROW_BOTTOM_Y (row) > window_text_bottom_y (w)))
18737 /* Adjust positions in the glyph matrix. */
18738 if (Z_delta || Z_delta_bytes)
18740 struct glyph_row *r1
18741 = MATRIX_BOTTOM_TEXT_ROW (current_matrix, w);
18742 increment_matrix_positions (w->current_matrix,
18743 MATRIX_ROW_VPOS (r0, current_matrix),
18744 MATRIX_ROW_VPOS (r1, current_matrix),
18745 Z_delta, Z_delta_bytes);
18748 /* Set the cursor. */
18749 row = row_containing_pos (w, PT, r0, NULL, 0);
18750 if (row)
18751 set_cursor_from_row (w, row, current_matrix, 0, 0, 0, 0);
18752 return 1;
18756 /* Handle the case that changes are all below what is displayed in
18757 the window, and that PT is in the window. This shortcut cannot
18758 be taken if ZV is visible in the window, and text has been added
18759 there that is visible in the window. */
18760 if (first_changed_charpos >= MATRIX_ROW_END_CHARPOS (row)
18761 /* ZV is not visible in the window, or there are no
18762 changes at ZV, actually. */
18763 && (current_matrix->zv > MATRIX_ROW_END_CHARPOS (row)
18764 || first_changed_charpos == last_changed_charpos))
18766 struct glyph_row *r0;
18768 /* Give up if PT is not in the window. Note that it already has
18769 been checked at the start of try_window_id that PT is not in
18770 front of the window start. */
18771 if (PT >= MATRIX_ROW_END_CHARPOS (row))
18772 GIVE_UP (14);
18774 /* If window start is unchanged, we can reuse the whole matrix
18775 as is, without changing glyph positions since no text has
18776 been added/removed in front of the window end. */
18777 r0 = MATRIX_FIRST_TEXT_ROW (current_matrix);
18778 if (TEXT_POS_EQUAL_P (start, r0->minpos)
18779 /* PT must not be in a partially visible line. */
18780 && !(PT >= MATRIX_ROW_START_CHARPOS (row)
18781 && MATRIX_ROW_BOTTOM_Y (row) > window_text_bottom_y (w)))
18783 /* We have to compute the window end anew since text
18784 could have been added/removed after it. */
18785 w->window_end_pos = Z - MATRIX_ROW_END_CHARPOS (row);
18786 w->window_end_bytepos = Z_BYTE - MATRIX_ROW_END_BYTEPOS (row);
18788 /* Set the cursor. */
18789 row = row_containing_pos (w, PT, r0, NULL, 0);
18790 if (row)
18791 set_cursor_from_row (w, row, current_matrix, 0, 0, 0, 0);
18792 return 2;
18796 /* Give up if window start is in the changed area.
18798 The condition used to read
18800 (BEG_UNCHANGED + END_UNCHANGED != Z - BEG && ...)
18802 but why that was tested escapes me at the moment. */
18803 if (CHARPOS (start) >= first_changed_charpos
18804 && CHARPOS (start) <= last_changed_charpos)
18805 GIVE_UP (15);
18807 /* Check that window start agrees with the start of the first glyph
18808 row in its current matrix. Check this after we know the window
18809 start is not in changed text, otherwise positions would not be
18810 comparable. */
18811 row = MATRIX_FIRST_TEXT_ROW (current_matrix);
18812 if (!TEXT_POS_EQUAL_P (start, row->minpos))
18813 GIVE_UP (16);
18815 /* Give up if the window ends in strings. Overlay strings
18816 at the end are difficult to handle, so don't try. */
18817 row = MATRIX_ROW (current_matrix, w->window_end_vpos);
18818 if (MATRIX_ROW_START_CHARPOS (row) == MATRIX_ROW_END_CHARPOS (row))
18819 GIVE_UP (20);
18821 /* Compute the position at which we have to start displaying new
18822 lines. Some of the lines at the top of the window might be
18823 reusable because they are not displaying changed text. Find the
18824 last row in W's current matrix not affected by changes at the
18825 start of current_buffer. Value is null if changes start in the
18826 first line of window. */
18827 last_unchanged_at_beg_row = find_last_unchanged_at_beg_row (w);
18828 if (last_unchanged_at_beg_row)
18830 /* Avoid starting to display in the middle of a character, a TAB
18831 for instance. This is easier than to set up the iterator
18832 exactly, and it's not a frequent case, so the additional
18833 effort wouldn't really pay off. */
18834 while ((MATRIX_ROW_ENDS_IN_MIDDLE_OF_CHAR_P (last_unchanged_at_beg_row)
18835 || last_unchanged_at_beg_row->ends_in_newline_from_string_p)
18836 && last_unchanged_at_beg_row > w->current_matrix->rows)
18837 --last_unchanged_at_beg_row;
18839 if (MATRIX_ROW_ENDS_IN_MIDDLE_OF_CHAR_P (last_unchanged_at_beg_row))
18840 GIVE_UP (17);
18842 if (! init_to_row_end (&it, w, last_unchanged_at_beg_row))
18843 GIVE_UP (18);
18844 start_pos = it.current.pos;
18846 /* Start displaying new lines in the desired matrix at the same
18847 vpos we would use in the current matrix, i.e. below
18848 last_unchanged_at_beg_row. */
18849 it.vpos = 1 + MATRIX_ROW_VPOS (last_unchanged_at_beg_row,
18850 current_matrix);
18851 it.glyph_row = MATRIX_ROW (desired_matrix, it.vpos);
18852 it.current_y = MATRIX_ROW_BOTTOM_Y (last_unchanged_at_beg_row);
18854 eassert (it.hpos == 0 && it.current_x == 0);
18856 else
18858 /* There are no reusable lines at the start of the window.
18859 Start displaying in the first text line. */
18860 start_display (&it, w, start);
18861 it.vpos = it.first_vpos;
18862 start_pos = it.current.pos;
18865 /* Find the first row that is not affected by changes at the end of
18866 the buffer. Value will be null if there is no unchanged row, in
18867 which case we must redisplay to the end of the window. delta
18868 will be set to the value by which buffer positions beginning with
18869 first_unchanged_at_end_row have to be adjusted due to text
18870 changes. */
18871 first_unchanged_at_end_row
18872 = find_first_unchanged_at_end_row (w, &delta, &delta_bytes);
18873 IF_DEBUG (debug_delta = delta);
18874 IF_DEBUG (debug_delta_bytes = delta_bytes);
18876 /* Set stop_pos to the buffer position up to which we will have to
18877 display new lines. If first_unchanged_at_end_row != NULL, this
18878 is the buffer position of the start of the line displayed in that
18879 row. For first_unchanged_at_end_row == NULL, use 0 to indicate
18880 that we don't stop at a buffer position. */
18881 stop_pos = 0;
18882 if (first_unchanged_at_end_row)
18884 eassert (last_unchanged_at_beg_row == NULL
18885 || first_unchanged_at_end_row >= last_unchanged_at_beg_row);
18887 /* If this is a continuation line, move forward to the next one
18888 that isn't. Changes in lines above affect this line.
18889 Caution: this may move first_unchanged_at_end_row to a row
18890 not displaying text. */
18891 while (MATRIX_ROW_CONTINUATION_LINE_P (first_unchanged_at_end_row)
18892 && MATRIX_ROW_DISPLAYS_TEXT_P (first_unchanged_at_end_row)
18893 && (MATRIX_ROW_BOTTOM_Y (first_unchanged_at_end_row)
18894 < it.last_visible_y))
18895 ++first_unchanged_at_end_row;
18897 if (!MATRIX_ROW_DISPLAYS_TEXT_P (first_unchanged_at_end_row)
18898 || (MATRIX_ROW_BOTTOM_Y (first_unchanged_at_end_row)
18899 >= it.last_visible_y))
18900 first_unchanged_at_end_row = NULL;
18901 else
18903 stop_pos = (MATRIX_ROW_START_CHARPOS (first_unchanged_at_end_row)
18904 + delta);
18905 first_unchanged_at_end_vpos
18906 = MATRIX_ROW_VPOS (first_unchanged_at_end_row, current_matrix);
18907 eassert (stop_pos >= Z - END_UNCHANGED);
18910 else if (last_unchanged_at_beg_row == NULL)
18911 GIVE_UP (19);
18914 #ifdef GLYPH_DEBUG
18916 /* Either there is no unchanged row at the end, or the one we have
18917 now displays text. This is a necessary condition for the window
18918 end pos calculation at the end of this function. */
18919 eassert (first_unchanged_at_end_row == NULL
18920 || MATRIX_ROW_DISPLAYS_TEXT_P (first_unchanged_at_end_row));
18922 debug_last_unchanged_at_beg_vpos
18923 = (last_unchanged_at_beg_row
18924 ? MATRIX_ROW_VPOS (last_unchanged_at_beg_row, current_matrix)
18925 : -1);
18926 debug_first_unchanged_at_end_vpos = first_unchanged_at_end_vpos;
18928 #endif /* GLYPH_DEBUG */
18931 /* Display new lines. Set last_text_row to the last new line
18932 displayed which has text on it, i.e. might end up as being the
18933 line where the window_end_vpos is. */
18934 w->cursor.vpos = -1;
18935 last_text_row = NULL;
18936 overlay_arrow_seen = false;
18937 if (it.current_y < it.last_visible_y
18938 && !f->fonts_changed
18939 && (first_unchanged_at_end_row == NULL
18940 || IT_CHARPOS (it) < stop_pos))
18941 it.glyph_row->reversed_p = false;
18942 while (it.current_y < it.last_visible_y
18943 && !f->fonts_changed
18944 && (first_unchanged_at_end_row == NULL
18945 || IT_CHARPOS (it) < stop_pos))
18947 if (display_line (&it, -1))
18948 last_text_row = it.glyph_row - 1;
18951 if (f->fonts_changed)
18952 return -1;
18954 /* The redisplay iterations in display_line above could have
18955 triggered font-lock, which could have done something that
18956 invalidates IT->w window's end-point information, on which we
18957 rely below. E.g., one package, which will remain unnamed, used
18958 to install a font-lock-fontify-region-function that called
18959 bury-buffer, whose side effect is to switch the buffer displayed
18960 by IT->w, and that predictably resets IT->w's window_end_valid
18961 flag, which we already tested at the entry to this function.
18962 Amply punish such packages/modes by giving up on this
18963 optimization in those cases. */
18964 if (!w->window_end_valid)
18966 clear_glyph_matrix (w->desired_matrix);
18967 return -1;
18970 /* Compute differences in buffer positions, y-positions etc. for
18971 lines reused at the bottom of the window. Compute what we can
18972 scroll. */
18973 if (first_unchanged_at_end_row
18974 /* No lines reused because we displayed everything up to the
18975 bottom of the window. */
18976 && it.current_y < it.last_visible_y)
18978 dvpos = (it.vpos
18979 - MATRIX_ROW_VPOS (first_unchanged_at_end_row,
18980 current_matrix));
18981 dy = it.current_y - first_unchanged_at_end_row->y;
18982 run.current_y = first_unchanged_at_end_row->y;
18983 run.desired_y = run.current_y + dy;
18984 run.height = it.last_visible_y - max (run.current_y, run.desired_y);
18986 else
18988 delta = delta_bytes = dvpos = dy
18989 = run.current_y = run.desired_y = run.height = 0;
18990 first_unchanged_at_end_row = NULL;
18992 IF_DEBUG ((debug_dvpos = dvpos, debug_dy = dy));
18995 /* Find the cursor if not already found. We have to decide whether
18996 PT will appear on this window (it sometimes doesn't, but this is
18997 not a very frequent case.) This decision has to be made before
18998 the current matrix is altered. A value of cursor.vpos < 0 means
18999 that PT is either in one of the lines beginning at
19000 first_unchanged_at_end_row or below the window. Don't care for
19001 lines that might be displayed later at the window end; as
19002 mentioned, this is not a frequent case. */
19003 if (w->cursor.vpos < 0)
19005 /* Cursor in unchanged rows at the top? */
19006 if (PT < CHARPOS (start_pos)
19007 && last_unchanged_at_beg_row)
19009 row = row_containing_pos (w, PT,
19010 MATRIX_FIRST_TEXT_ROW (w->current_matrix),
19011 last_unchanged_at_beg_row + 1, 0);
19012 if (row)
19013 set_cursor_from_row (w, row, w->current_matrix, 0, 0, 0, 0);
19016 /* Start from first_unchanged_at_end_row looking for PT. */
19017 else if (first_unchanged_at_end_row)
19019 row = row_containing_pos (w, PT - delta,
19020 first_unchanged_at_end_row, NULL, 0);
19021 if (row)
19022 set_cursor_from_row (w, row, w->current_matrix, delta,
19023 delta_bytes, dy, dvpos);
19026 /* Give up if cursor was not found. */
19027 if (w->cursor.vpos < 0)
19029 clear_glyph_matrix (w->desired_matrix);
19030 return -1;
19034 /* Don't let the cursor end in the scroll margins. */
19036 int this_scroll_margin = window_scroll_margin (w, MARGIN_IN_PIXELS);
19037 int cursor_height = MATRIX_ROW (w->desired_matrix, w->cursor.vpos)->height;
19039 if ((w->cursor.y < this_scroll_margin
19040 && CHARPOS (start) > BEGV)
19041 /* Old redisplay didn't take scroll margin into account at the bottom,
19042 but then global-hl-line-mode doesn't scroll. KFS 2004-06-14 */
19043 || (w->cursor.y + (make_cursor_line_fully_visible_p
19044 ? cursor_height + this_scroll_margin
19045 : 1)) > it.last_visible_y)
19047 w->cursor.vpos = -1;
19048 clear_glyph_matrix (w->desired_matrix);
19049 return -1;
19053 /* Scroll the display. Do it before changing the current matrix so
19054 that xterm.c doesn't get confused about where the cursor glyph is
19055 found. */
19056 if (dy && run.height)
19058 update_begin (f);
19060 if (FRAME_WINDOW_P (f))
19062 FRAME_RIF (f)->update_window_begin_hook (w);
19063 FRAME_RIF (f)->clear_window_mouse_face (w);
19064 FRAME_RIF (f)->scroll_run_hook (w, &run);
19065 FRAME_RIF (f)->update_window_end_hook (w, false, false);
19067 else
19069 /* Terminal frame. In this case, dvpos gives the number of
19070 lines to scroll by; dvpos < 0 means scroll up. */
19071 int from_vpos
19072 = MATRIX_ROW_VPOS (first_unchanged_at_end_row, w->current_matrix);
19073 int from = WINDOW_TOP_EDGE_LINE (w) + from_vpos;
19074 int end = (WINDOW_TOP_EDGE_LINE (w)
19075 + window_wants_header_line (w)
19076 + window_internal_height (w));
19078 #if defined (HAVE_GPM) || defined (MSDOS)
19079 x_clear_window_mouse_face (w);
19080 #endif
19081 /* Perform the operation on the screen. */
19082 if (dvpos > 0)
19084 /* Scroll last_unchanged_at_beg_row to the end of the
19085 window down dvpos lines. */
19086 set_terminal_window (f, end);
19088 /* On dumb terminals delete dvpos lines at the end
19089 before inserting dvpos empty lines. */
19090 if (!FRAME_SCROLL_REGION_OK (f))
19091 ins_del_lines (f, end - dvpos, -dvpos);
19093 /* Insert dvpos empty lines in front of
19094 last_unchanged_at_beg_row. */
19095 ins_del_lines (f, from, dvpos);
19097 else if (dvpos < 0)
19099 /* Scroll up last_unchanged_at_beg_vpos to the end of
19100 the window to last_unchanged_at_beg_vpos - |dvpos|. */
19101 set_terminal_window (f, end);
19103 /* Delete dvpos lines in front of
19104 last_unchanged_at_beg_vpos. ins_del_lines will set
19105 the cursor to the given vpos and emit |dvpos| delete
19106 line sequences. */
19107 ins_del_lines (f, from + dvpos, dvpos);
19109 /* On a dumb terminal insert dvpos empty lines at the
19110 end. */
19111 if (!FRAME_SCROLL_REGION_OK (f))
19112 ins_del_lines (f, end + dvpos, -dvpos);
19115 set_terminal_window (f, 0);
19118 update_end (f);
19121 /* Shift reused rows of the current matrix to the right position.
19122 BOTTOM_ROW is the last + 1 row in the current matrix reserved for
19123 text. */
19124 bottom_row = MATRIX_BOTTOM_TEXT_ROW (current_matrix, w);
19125 bottom_vpos = MATRIX_ROW_VPOS (bottom_row, current_matrix);
19126 if (dvpos < 0)
19128 rotate_matrix (current_matrix, first_unchanged_at_end_vpos + dvpos,
19129 bottom_vpos, dvpos);
19130 clear_glyph_matrix_rows (current_matrix, bottom_vpos + dvpos,
19131 bottom_vpos);
19133 else if (dvpos > 0)
19135 rotate_matrix (current_matrix, first_unchanged_at_end_vpos,
19136 bottom_vpos, dvpos);
19137 clear_glyph_matrix_rows (current_matrix, first_unchanged_at_end_vpos,
19138 first_unchanged_at_end_vpos + dvpos);
19141 /* For frame-based redisplay, make sure that current frame and window
19142 matrix are in sync with respect to glyph memory. */
19143 if (!FRAME_WINDOW_P (f))
19144 sync_frame_with_window_matrix_rows (w);
19146 /* Adjust buffer positions in reused rows. */
19147 if (delta || delta_bytes)
19148 increment_matrix_positions (current_matrix,
19149 first_unchanged_at_end_vpos + dvpos,
19150 bottom_vpos, delta, delta_bytes);
19152 /* Adjust Y positions. */
19153 if (dy)
19154 shift_glyph_matrix (w, current_matrix,
19155 first_unchanged_at_end_vpos + dvpos,
19156 bottom_vpos, dy);
19158 if (first_unchanged_at_end_row)
19160 first_unchanged_at_end_row += dvpos;
19161 if (first_unchanged_at_end_row->y >= it.last_visible_y
19162 || !MATRIX_ROW_DISPLAYS_TEXT_P (first_unchanged_at_end_row))
19163 first_unchanged_at_end_row = NULL;
19166 /* If scrolling up, there may be some lines to display at the end of
19167 the window. */
19168 last_text_row_at_end = NULL;
19169 if (dy < 0)
19171 /* Scrolling up can leave for example a partially visible line
19172 at the end of the window to be redisplayed. */
19173 /* Set last_row to the glyph row in the current matrix where the
19174 window end line is found. It has been moved up or down in
19175 the matrix by dvpos. */
19176 int last_vpos = w->window_end_vpos + dvpos;
19177 struct glyph_row *last_row = MATRIX_ROW (current_matrix, last_vpos);
19179 /* If last_row is the window end line, it should display text. */
19180 eassert (MATRIX_ROW_DISPLAYS_TEXT_P (last_row));
19182 /* If window end line was partially visible before, begin
19183 displaying at that line. Otherwise begin displaying with the
19184 line following it. */
19185 if (MATRIX_ROW_BOTTOM_Y (last_row) - dy >= it.last_visible_y)
19187 init_to_row_start (&it, w, last_row);
19188 it.vpos = last_vpos;
19189 it.current_y = last_row->y;
19191 else
19193 init_to_row_end (&it, w, last_row);
19194 it.vpos = 1 + last_vpos;
19195 it.current_y = MATRIX_ROW_BOTTOM_Y (last_row);
19196 ++last_row;
19199 /* We may start in a continuation line. If so, we have to
19200 get the right continuation_lines_width and current_x. */
19201 it.continuation_lines_width = last_row->continuation_lines_width;
19202 it.hpos = it.current_x = 0;
19204 /* Display the rest of the lines at the window end. */
19205 it.glyph_row = MATRIX_ROW (desired_matrix, it.vpos);
19206 while (it.current_y < it.last_visible_y && !f->fonts_changed)
19208 /* Is it always sure that the display agrees with lines in
19209 the current matrix? I don't think so, so we mark rows
19210 displayed invalid in the current matrix by setting their
19211 enabled_p flag to false. */
19212 SET_MATRIX_ROW_ENABLED_P (w->current_matrix, it.vpos, false);
19213 if (display_line (&it, w->cursor.vpos))
19214 last_text_row_at_end = it.glyph_row - 1;
19218 /* Update window_end_pos and window_end_vpos. */
19219 if (first_unchanged_at_end_row && !last_text_row_at_end)
19221 /* Window end line if one of the preserved rows from the current
19222 matrix. Set row to the last row displaying text in current
19223 matrix starting at first_unchanged_at_end_row, after
19224 scrolling. */
19225 eassert (MATRIX_ROW_DISPLAYS_TEXT_P (first_unchanged_at_end_row));
19226 row = find_last_row_displaying_text (w->current_matrix, &it,
19227 first_unchanged_at_end_row);
19228 eassume (row && MATRIX_ROW_DISPLAYS_TEXT_P (row));
19229 adjust_window_ends (w, row, true);
19230 eassert (w->window_end_bytepos >= 0);
19231 IF_DEBUG (debug_method_add (w, "A"));
19233 else if (last_text_row_at_end)
19235 adjust_window_ends (w, last_text_row_at_end, false);
19236 eassert (w->window_end_bytepos >= 0);
19237 IF_DEBUG (debug_method_add (w, "B"));
19239 else if (last_text_row)
19241 /* We have displayed either to the end of the window or at the
19242 end of the window, i.e. the last row with text is to be found
19243 in the desired matrix. */
19244 adjust_window_ends (w, last_text_row, false);
19245 eassert (w->window_end_bytepos >= 0);
19247 else if (first_unchanged_at_end_row == NULL
19248 && last_text_row == NULL
19249 && last_text_row_at_end == NULL)
19251 /* Displayed to end of window, but no line containing text was
19252 displayed. Lines were deleted at the end of the window. */
19253 bool first_vpos = window_wants_header_line (w);
19254 int vpos = w->window_end_vpos;
19255 struct glyph_row *current_row = current_matrix->rows + vpos;
19256 struct glyph_row *desired_row = desired_matrix->rows + vpos;
19258 for (row = NULL; !row; --vpos, --current_row, --desired_row)
19260 eassert (first_vpos <= vpos);
19261 if (desired_row->enabled_p)
19263 if (MATRIX_ROW_DISPLAYS_TEXT_P (desired_row))
19264 row = desired_row;
19266 else if (MATRIX_ROW_DISPLAYS_TEXT_P (current_row))
19267 row = current_row;
19270 w->window_end_vpos = vpos + 1;
19271 w->window_end_pos = Z - MATRIX_ROW_END_CHARPOS (row);
19272 w->window_end_bytepos = Z_BYTE - MATRIX_ROW_END_BYTEPOS (row);
19273 eassert (w->window_end_bytepos >= 0);
19274 IF_DEBUG (debug_method_add (w, "C"));
19276 else
19277 emacs_abort ();
19279 IF_DEBUG ((debug_end_pos = w->window_end_pos,
19280 debug_end_vpos = w->window_end_vpos));
19282 /* Record that display has not been completed. */
19283 w->window_end_valid = false;
19284 w->desired_matrix->no_scrolling_p = true;
19285 return 3;
19287 #undef GIVE_UP
19292 /***********************************************************************
19293 More debugging support
19294 ***********************************************************************/
19296 #ifdef GLYPH_DEBUG
19298 void dump_glyph_row (struct glyph_row *, int, int) EXTERNALLY_VISIBLE;
19299 void dump_glyph_matrix (struct glyph_matrix *, int) EXTERNALLY_VISIBLE;
19300 void dump_glyph (struct glyph_row *, struct glyph *, int) EXTERNALLY_VISIBLE;
19303 /* Dump the contents of glyph matrix MATRIX on stderr.
19305 GLYPHS 0 means don't show glyph contents.
19306 GLYPHS 1 means show glyphs in short form
19307 GLYPHS > 1 means show glyphs in long form. */
19309 void
19310 dump_glyph_matrix (struct glyph_matrix *matrix, int glyphs)
19312 int i;
19313 for (i = 0; i < matrix->nrows; ++i)
19314 dump_glyph_row (MATRIX_ROW (matrix, i), i, glyphs);
19318 /* Dump contents of glyph GLYPH to stderr. ROW and AREA are
19319 the glyph row and area where the glyph comes from. */
19321 void
19322 dump_glyph (struct glyph_row *row, struct glyph *glyph, int area)
19324 if (glyph->type == CHAR_GLYPH
19325 || glyph->type == GLYPHLESS_GLYPH)
19327 fprintf (stderr,
19328 " %5"pD"d %c %9"pD"d %c %3d 0x%06x %c %4d %1.1d%1.1d\n",
19329 glyph - row->glyphs[TEXT_AREA],
19330 (glyph->type == CHAR_GLYPH
19331 ? 'C'
19332 : 'G'),
19333 glyph->charpos,
19334 (BUFFERP (glyph->object)
19335 ? 'B'
19336 : (STRINGP (glyph->object)
19337 ? 'S'
19338 : (NILP (glyph->object)
19339 ? '0'
19340 : '-'))),
19341 glyph->pixel_width,
19342 glyph->u.ch,
19343 (glyph->u.ch < 0x80 && glyph->u.ch >= ' '
19344 ? (int) glyph->u.ch
19345 : '.'),
19346 glyph->face_id,
19347 glyph->left_box_line_p,
19348 glyph->right_box_line_p);
19350 else if (glyph->type == STRETCH_GLYPH)
19352 fprintf (stderr,
19353 " %5"pD"d %c %9"pD"d %c %3d 0x%06x %c %4d %1.1d%1.1d\n",
19354 glyph - row->glyphs[TEXT_AREA],
19355 'S',
19356 glyph->charpos,
19357 (BUFFERP (glyph->object)
19358 ? 'B'
19359 : (STRINGP (glyph->object)
19360 ? 'S'
19361 : (NILP (glyph->object)
19362 ? '0'
19363 : '-'))),
19364 glyph->pixel_width,
19366 ' ',
19367 glyph->face_id,
19368 glyph->left_box_line_p,
19369 glyph->right_box_line_p);
19371 else if (glyph->type == IMAGE_GLYPH)
19373 fprintf (stderr,
19374 " %5"pD"d %c %9"pD"d %c %3d 0x%06x %c %4d %1.1d%1.1d\n",
19375 glyph - row->glyphs[TEXT_AREA],
19376 'I',
19377 glyph->charpos,
19378 (BUFFERP (glyph->object)
19379 ? 'B'
19380 : (STRINGP (glyph->object)
19381 ? 'S'
19382 : (NILP (glyph->object)
19383 ? '0'
19384 : '-'))),
19385 glyph->pixel_width,
19386 (unsigned int) glyph->u.img_id,
19387 '.',
19388 glyph->face_id,
19389 glyph->left_box_line_p,
19390 glyph->right_box_line_p);
19392 else if (glyph->type == COMPOSITE_GLYPH)
19394 fprintf (stderr,
19395 " %5"pD"d %c %9"pD"d %c %3d 0x%06x",
19396 glyph - row->glyphs[TEXT_AREA],
19397 '+',
19398 glyph->charpos,
19399 (BUFFERP (glyph->object)
19400 ? 'B'
19401 : (STRINGP (glyph->object)
19402 ? 'S'
19403 : (NILP (glyph->object)
19404 ? '0'
19405 : '-'))),
19406 glyph->pixel_width,
19407 (unsigned int) glyph->u.cmp.id);
19408 if (glyph->u.cmp.automatic)
19409 fprintf (stderr,
19410 "[%d-%d]",
19411 glyph->slice.cmp.from, glyph->slice.cmp.to);
19412 fprintf (stderr, " . %4d %1.1d%1.1d\n",
19413 glyph->face_id,
19414 glyph->left_box_line_p,
19415 glyph->right_box_line_p);
19417 else if (glyph->type == XWIDGET_GLYPH)
19419 #ifndef HAVE_XWIDGETS
19420 eassume (false);
19421 #else
19422 fprintf (stderr,
19423 " %5d %4c %6d %c %3d 0x%05x %c %4d %1.1d%1.1d\n",
19424 glyph - row->glyphs[TEXT_AREA],
19425 'X',
19426 glyph->charpos,
19427 (BUFFERP (glyph->object)
19428 ? 'B'
19429 : (STRINGP (glyph->object)
19430 ? 'S'
19431 : '-')),
19432 glyph->pixel_width,
19433 glyph->u.xwidget,
19434 '.',
19435 glyph->face_id,
19436 glyph->left_box_line_p,
19437 glyph->right_box_line_p);
19438 #endif
19443 /* Dump the contents of glyph row at VPOS in MATRIX to stderr.
19444 GLYPHS 0 means don't show glyph contents.
19445 GLYPHS 1 means show glyphs in short form
19446 GLYPHS > 1 means show glyphs in long form. */
19448 void
19449 dump_glyph_row (struct glyph_row *row, int vpos, int glyphs)
19451 if (glyphs != 1)
19453 fprintf (stderr, "Row Start End Used oE><\\CTZFesm X Y W H V A P\n");
19454 fprintf (stderr, "==============================================================================\n");
19456 fprintf (stderr, "%3d %9"pD"d %9"pD"d %4d %1.1d%1.1d%1.1d%1.1d\
19457 %1.1d%1.1d%1.1d%1.1d%1.1d%1.1d%1.1d%1.1d %4d %4d %4d %4d %4d %4d %4d\n",
19458 vpos,
19459 MATRIX_ROW_START_CHARPOS (row),
19460 MATRIX_ROW_END_CHARPOS (row),
19461 row->used[TEXT_AREA],
19462 row->contains_overlapping_glyphs_p,
19463 row->enabled_p,
19464 row->truncated_on_left_p,
19465 row->truncated_on_right_p,
19466 row->continued_p,
19467 MATRIX_ROW_CONTINUATION_LINE_P (row),
19468 MATRIX_ROW_DISPLAYS_TEXT_P (row),
19469 row->ends_at_zv_p,
19470 row->fill_line_p,
19471 row->ends_in_middle_of_char_p,
19472 row->starts_in_middle_of_char_p,
19473 row->mouse_face_p,
19474 row->x,
19475 row->y,
19476 row->pixel_width,
19477 row->height,
19478 row->visible_height,
19479 row->ascent,
19480 row->phys_ascent);
19481 /* The next 3 lines should align to "Start" in the header. */
19482 fprintf (stderr, " %9"pD"d %9"pD"d\t%5d\n", row->start.overlay_string_index,
19483 row->end.overlay_string_index,
19484 row->continuation_lines_width);
19485 fprintf (stderr, " %9"pD"d %9"pD"d\n",
19486 CHARPOS (row->start.string_pos),
19487 CHARPOS (row->end.string_pos));
19488 fprintf (stderr, " %9d %9d\n", row->start.dpvec_index,
19489 row->end.dpvec_index);
19492 if (glyphs > 1)
19494 int area;
19496 for (area = LEFT_MARGIN_AREA; area < LAST_AREA; ++area)
19498 struct glyph *glyph = row->glyphs[area];
19499 struct glyph *glyph_end = glyph + row->used[area];
19501 /* Glyph for a line end in text. */
19502 if (area == TEXT_AREA && glyph == glyph_end && glyph->charpos > 0)
19503 ++glyph_end;
19505 if (glyph < glyph_end)
19506 fprintf (stderr, " Glyph# Type Pos O W Code C Face LR\n");
19508 for (; glyph < glyph_end; ++glyph)
19509 dump_glyph (row, glyph, area);
19512 else if (glyphs == 1)
19514 int area;
19515 char s[SHRT_MAX + 4];
19517 for (area = LEFT_MARGIN_AREA; area < LAST_AREA; ++area)
19519 int i;
19521 for (i = 0; i < row->used[area]; ++i)
19523 struct glyph *glyph = row->glyphs[area] + i;
19524 if (i == row->used[area] - 1
19525 && area == TEXT_AREA
19526 && NILP (glyph->object)
19527 && glyph->type == CHAR_GLYPH
19528 && glyph->u.ch == ' ')
19530 strcpy (&s[i], "[\\n]");
19531 i += 4;
19533 else if (glyph->type == CHAR_GLYPH
19534 && glyph->u.ch < 0x80
19535 && glyph->u.ch >= ' ')
19536 s[i] = glyph->u.ch;
19537 else
19538 s[i] = '.';
19541 s[i] = '\0';
19542 fprintf (stderr, "%3d: (%d) '%s'\n", vpos, row->enabled_p, s);
19548 DEFUN ("dump-glyph-matrix", Fdump_glyph_matrix,
19549 Sdump_glyph_matrix, 0, 1, "p",
19550 doc: /* Dump the current matrix of the selected window to stderr.
19551 Shows contents of glyph row structures. With non-nil
19552 parameter GLYPHS, dump glyphs as well. If GLYPHS is 1 show
19553 glyphs in short form, otherwise show glyphs in long form.
19555 Interactively, no argument means show glyphs in short form;
19556 with numeric argument, its value is passed as the GLYPHS flag. */)
19557 (Lisp_Object glyphs)
19559 struct window *w = XWINDOW (selected_window);
19560 struct buffer *buffer = XBUFFER (w->contents);
19562 fprintf (stderr, "PT = %"pD"d, BEGV = %"pD"d. ZV = %"pD"d\n",
19563 BUF_PT (buffer), BUF_BEGV (buffer), BUF_ZV (buffer));
19564 fprintf (stderr, "Cursor x = %d, y = %d, hpos = %d, vpos = %d\n",
19565 w->cursor.x, w->cursor.y, w->cursor.hpos, w->cursor.vpos);
19566 fprintf (stderr, "=============================================\n");
19567 dump_glyph_matrix (w->current_matrix,
19568 TYPE_RANGED_INTEGERP (int, glyphs) ? XINT (glyphs) : 0);
19569 return Qnil;
19573 DEFUN ("dump-frame-glyph-matrix", Fdump_frame_glyph_matrix,
19574 Sdump_frame_glyph_matrix, 0, 0, "", doc: /* Dump the current glyph matrix of the selected frame to stderr.
19575 Only text-mode frames have frame glyph matrices. */)
19576 (void)
19578 struct frame *f = XFRAME (selected_frame);
19580 if (f->current_matrix)
19581 dump_glyph_matrix (f->current_matrix, 1);
19582 else
19583 fprintf (stderr, "*** This frame doesn't have a frame glyph matrix ***\n");
19584 return Qnil;
19588 DEFUN ("dump-glyph-row", Fdump_glyph_row, Sdump_glyph_row, 1, 2, "P",
19589 doc: /* Dump glyph row ROW to stderr.
19590 Interactively, ROW is the prefix numeric argument and defaults to
19591 the row which displays point.
19592 Optional argument GLYPHS 0 means don't dump glyphs.
19593 GLYPHS 1 means dump glyphs in short form.
19594 GLYPHS > 1 or omitted means dump glyphs in long form. */)
19595 (Lisp_Object row, Lisp_Object glyphs)
19597 struct glyph_matrix *matrix;
19598 EMACS_INT vpos;
19600 if (NILP (row))
19602 int d1, d2, d3, d4, d5, ypos;
19603 bool visible_p = pos_visible_p (XWINDOW (selected_window), PT,
19604 &d1, &d2, &d3, &d4, &d5, &ypos);
19605 if (visible_p)
19606 vpos = ypos;
19607 else
19608 vpos = 0;
19610 else
19612 CHECK_NUMBER (row);
19613 vpos = XINT (row);
19615 matrix = XWINDOW (selected_window)->current_matrix;
19616 if (vpos >= 0 && vpos < matrix->nrows)
19617 dump_glyph_row (MATRIX_ROW (matrix, vpos),
19618 vpos,
19619 TYPE_RANGED_INTEGERP (int, glyphs) ? XINT (glyphs) : 2);
19620 return Qnil;
19624 DEFUN ("dump-tool-bar-row", Fdump_tool_bar_row, Sdump_tool_bar_row, 1, 2, "P",
19625 doc: /* Dump glyph row ROW of the tool-bar of the current frame to stderr.
19626 Interactively, ROW is the prefix numeric argument and defaults to zero.
19627 GLYPHS 0 means don't dump glyphs.
19628 GLYPHS 1 means dump glyphs in short form.
19629 GLYPHS > 1 or omitted means dump glyphs in long form.
19631 If there's no tool-bar, or if the tool-bar is not drawn by Emacs,
19632 do nothing. */)
19633 (Lisp_Object row, Lisp_Object glyphs)
19635 #if defined (HAVE_WINDOW_SYSTEM) && ! defined (USE_GTK) && ! defined (HAVE_NS)
19636 struct frame *sf = SELECTED_FRAME ();
19637 struct glyph_matrix *m = XWINDOW (sf->tool_bar_window)->current_matrix;
19638 EMACS_INT vpos;
19640 if (NILP (row))
19641 vpos = 0;
19642 else
19644 CHECK_NUMBER (row);
19645 vpos = XINT (row);
19647 if (vpos >= 0 && vpos < m->nrows)
19648 dump_glyph_row (MATRIX_ROW (m, vpos), vpos,
19649 TYPE_RANGED_INTEGERP (int, glyphs) ? XINT (glyphs) : 2);
19650 #endif
19651 return Qnil;
19655 DEFUN ("trace-redisplay", Ftrace_redisplay, Strace_redisplay, 0, 1, "P",
19656 doc: /* Toggle tracing of redisplay.
19657 With ARG, turn tracing on if and only if ARG is positive. */)
19658 (Lisp_Object arg)
19660 if (NILP (arg))
19661 trace_redisplay_p = !trace_redisplay_p;
19662 else
19664 arg = Fprefix_numeric_value (arg);
19665 trace_redisplay_p = XINT (arg) > 0;
19668 return Qnil;
19672 DEFUN ("trace-to-stderr", Ftrace_to_stderr, Strace_to_stderr, 1, MANY, "",
19673 doc: /* Like `format', but print result to stderr.
19674 usage: (trace-to-stderr STRING &rest OBJECTS) */)
19675 (ptrdiff_t nargs, Lisp_Object *args)
19677 Lisp_Object s = Fformat (nargs, args);
19678 fwrite (SDATA (s), 1, SBYTES (s), stderr);
19679 return Qnil;
19682 #endif /* GLYPH_DEBUG */
19686 /***********************************************************************
19687 Building Desired Matrix Rows
19688 ***********************************************************************/
19690 /* Return a temporary glyph row holding the glyphs of an overlay arrow.
19691 Used for non-window-redisplay windows, and for windows w/o left fringe. */
19693 static struct glyph_row *
19694 get_overlay_arrow_glyph_row (struct window *w, Lisp_Object overlay_arrow_string)
19696 struct frame *f = XFRAME (WINDOW_FRAME (w));
19697 struct buffer *buffer = XBUFFER (w->contents);
19698 struct buffer *old = current_buffer;
19699 const unsigned char *arrow_string = SDATA (overlay_arrow_string);
19700 ptrdiff_t arrow_len = SCHARS (overlay_arrow_string);
19701 const unsigned char *arrow_end = arrow_string + arrow_len;
19702 const unsigned char *p;
19703 struct it it;
19704 bool multibyte_p;
19705 int n_glyphs_before;
19707 set_buffer_temp (buffer);
19708 init_iterator (&it, w, -1, -1, &scratch_glyph_row, DEFAULT_FACE_ID);
19709 scratch_glyph_row.reversed_p = false;
19710 it.glyph_row->used[TEXT_AREA] = 0;
19711 SET_TEXT_POS (it.position, 0, 0);
19713 multibyte_p = !NILP (BVAR (buffer, enable_multibyte_characters));
19714 p = arrow_string;
19715 while (p < arrow_end)
19717 Lisp_Object face, ilisp;
19719 /* Get the next character. */
19720 if (multibyte_p)
19721 it.c = it.char_to_display = string_char_and_length (p, &it.len);
19722 else
19724 it.c = it.char_to_display = *p, it.len = 1;
19725 if (! ASCII_CHAR_P (it.c))
19726 it.char_to_display = BYTE8_TO_CHAR (it.c);
19728 p += it.len;
19730 /* Get its face. */
19731 ilisp = make_number (p - arrow_string);
19732 face = Fget_text_property (ilisp, Qface, overlay_arrow_string);
19733 it.face_id = compute_char_face (f, it.char_to_display, face);
19735 /* Compute its width, get its glyphs. */
19736 n_glyphs_before = it.glyph_row->used[TEXT_AREA];
19737 SET_TEXT_POS (it.position, -1, -1);
19738 PRODUCE_GLYPHS (&it);
19740 /* If this character doesn't fit any more in the line, we have
19741 to remove some glyphs. */
19742 if (it.current_x > it.last_visible_x)
19744 it.glyph_row->used[TEXT_AREA] = n_glyphs_before;
19745 break;
19749 set_buffer_temp (old);
19750 return it.glyph_row;
19754 /* Insert truncation glyphs at the start of IT->glyph_row. Which
19755 glyphs to insert is determined by produce_special_glyphs. */
19757 static void
19758 insert_left_trunc_glyphs (struct it *it)
19760 struct it truncate_it;
19761 struct glyph *from, *end, *to, *toend;
19763 eassert (!FRAME_WINDOW_P (it->f)
19764 || (!it->glyph_row->reversed_p
19765 && WINDOW_LEFT_FRINGE_WIDTH (it->w) == 0)
19766 || (it->glyph_row->reversed_p
19767 && WINDOW_RIGHT_FRINGE_WIDTH (it->w) == 0));
19769 /* Get the truncation glyphs. */
19770 truncate_it = *it;
19771 truncate_it.current_x = 0;
19772 truncate_it.face_id = DEFAULT_FACE_ID;
19773 truncate_it.glyph_row = &scratch_glyph_row;
19774 truncate_it.area = TEXT_AREA;
19775 truncate_it.glyph_row->used[TEXT_AREA] = 0;
19776 CHARPOS (truncate_it.position) = BYTEPOS (truncate_it.position) = -1;
19777 truncate_it.object = Qnil;
19778 produce_special_glyphs (&truncate_it, IT_TRUNCATION);
19780 /* Overwrite glyphs from IT with truncation glyphs. */
19781 if (!it->glyph_row->reversed_p)
19783 short tused = truncate_it.glyph_row->used[TEXT_AREA];
19785 from = truncate_it.glyph_row->glyphs[TEXT_AREA];
19786 end = from + tused;
19787 to = it->glyph_row->glyphs[TEXT_AREA];
19788 toend = to + it->glyph_row->used[TEXT_AREA];
19789 if (FRAME_WINDOW_P (it->f))
19791 /* On GUI frames, when variable-size fonts are displayed,
19792 the truncation glyphs may need more pixels than the row's
19793 glyphs they overwrite. We overwrite more glyphs to free
19794 enough screen real estate, and enlarge the stretch glyph
19795 on the right (see display_line), if there is one, to
19796 preserve the screen position of the truncation glyphs on
19797 the right. */
19798 int w = 0;
19799 struct glyph *g = to;
19800 short used;
19802 /* The first glyph could be partially visible, in which case
19803 it->glyph_row->x will be negative. But we want the left
19804 truncation glyphs to be aligned at the left margin of the
19805 window, so we override the x coordinate at which the row
19806 will begin. */
19807 it->glyph_row->x = 0;
19808 while (g < toend && w < it->truncation_pixel_width)
19810 w += g->pixel_width;
19811 ++g;
19813 if (g - to - tused > 0)
19815 memmove (to + tused, g, (toend - g) * sizeof(*g));
19816 it->glyph_row->used[TEXT_AREA] -= g - to - tused;
19818 used = it->glyph_row->used[TEXT_AREA];
19819 if (it->glyph_row->truncated_on_right_p
19820 && WINDOW_RIGHT_FRINGE_WIDTH (it->w) == 0
19821 && it->glyph_row->glyphs[TEXT_AREA][used - 2].type
19822 == STRETCH_GLYPH)
19824 int extra = w - it->truncation_pixel_width;
19826 it->glyph_row->glyphs[TEXT_AREA][used - 2].pixel_width += extra;
19830 while (from < end)
19831 *to++ = *from++;
19833 /* There may be padding glyphs left over. Overwrite them too. */
19834 if (!FRAME_WINDOW_P (it->f))
19836 while (to < toend && CHAR_GLYPH_PADDING_P (*to))
19838 from = truncate_it.glyph_row->glyphs[TEXT_AREA];
19839 while (from < end)
19840 *to++ = *from++;
19844 if (to > toend)
19845 it->glyph_row->used[TEXT_AREA] = to - it->glyph_row->glyphs[TEXT_AREA];
19847 else
19849 short tused = truncate_it.glyph_row->used[TEXT_AREA];
19851 /* In R2L rows, overwrite the last (rightmost) glyphs, and do
19852 that back to front. */
19853 end = truncate_it.glyph_row->glyphs[TEXT_AREA];
19854 from = end + truncate_it.glyph_row->used[TEXT_AREA] - 1;
19855 toend = it->glyph_row->glyphs[TEXT_AREA];
19856 to = toend + it->glyph_row->used[TEXT_AREA] - 1;
19857 if (FRAME_WINDOW_P (it->f))
19859 int w = 0;
19860 struct glyph *g = to;
19862 while (g >= toend && w < it->truncation_pixel_width)
19864 w += g->pixel_width;
19865 --g;
19867 if (to - g - tused > 0)
19868 to = g + tused;
19869 if (it->glyph_row->truncated_on_right_p
19870 && WINDOW_LEFT_FRINGE_WIDTH (it->w) == 0
19871 && it->glyph_row->glyphs[TEXT_AREA][1].type == STRETCH_GLYPH)
19873 int extra = w - it->truncation_pixel_width;
19875 it->glyph_row->glyphs[TEXT_AREA][1].pixel_width += extra;
19879 while (from >= end && to >= toend)
19880 *to-- = *from--;
19881 if (!FRAME_WINDOW_P (it->f))
19883 while (to >= toend && CHAR_GLYPH_PADDING_P (*to))
19885 from =
19886 truncate_it.glyph_row->glyphs[TEXT_AREA]
19887 + truncate_it.glyph_row->used[TEXT_AREA] - 1;
19888 while (from >= end && to >= toend)
19889 *to-- = *from--;
19892 if (from >= end)
19894 /* Need to free some room before prepending additional
19895 glyphs. */
19896 int move_by = from - end + 1;
19897 struct glyph *g0 = it->glyph_row->glyphs[TEXT_AREA];
19898 struct glyph *g = g0 + it->glyph_row->used[TEXT_AREA] - 1;
19900 for ( ; g >= g0; g--)
19901 g[move_by] = *g;
19902 while (from >= end)
19903 *to-- = *from--;
19904 it->glyph_row->used[TEXT_AREA] += move_by;
19909 /* Compute the hash code for ROW. */
19910 unsigned
19911 row_hash (struct glyph_row *row)
19913 int area, k;
19914 unsigned hashval = 0;
19916 for (area = LEFT_MARGIN_AREA; area < LAST_AREA; ++area)
19917 for (k = 0; k < row->used[area]; ++k)
19918 hashval = ((((hashval << 4) + (hashval >> 24)) & 0x0fffffff)
19919 + row->glyphs[area][k].u.val
19920 + row->glyphs[area][k].face_id
19921 + row->glyphs[area][k].padding_p
19922 + (row->glyphs[area][k].type << 2));
19924 return hashval;
19927 /* Compute the pixel height and width of IT->glyph_row.
19929 Most of the time, ascent and height of a display line will be equal
19930 to the max_ascent and max_height values of the display iterator
19931 structure. This is not the case if
19933 1. We hit ZV without displaying anything. In this case, max_ascent
19934 and max_height will be zero.
19936 2. We have some glyphs that don't contribute to the line height.
19937 (The glyph row flag contributes_to_line_height_p is for future
19938 pixmap extensions).
19940 The first case is easily covered by using default values because in
19941 these cases, the line height does not really matter, except that it
19942 must not be zero. */
19944 static void
19945 compute_line_metrics (struct it *it)
19947 struct glyph_row *row = it->glyph_row;
19949 if (FRAME_WINDOW_P (it->f))
19951 int i, min_y, max_y;
19953 /* The line may consist of one space only, that was added to
19954 place the cursor on it. If so, the row's height hasn't been
19955 computed yet. */
19956 if (row->height == 0)
19958 if (it->max_ascent + it->max_descent == 0)
19959 it->max_descent = it->max_phys_descent = FRAME_LINE_HEIGHT (it->f);
19960 row->ascent = it->max_ascent;
19961 row->height = it->max_ascent + it->max_descent;
19962 row->phys_ascent = it->max_phys_ascent;
19963 row->phys_height = it->max_phys_ascent + it->max_phys_descent;
19964 row->extra_line_spacing = it->max_extra_line_spacing;
19967 /* Compute the width of this line. */
19968 row->pixel_width = row->x;
19969 for (i = 0; i < row->used[TEXT_AREA]; ++i)
19970 row->pixel_width += row->glyphs[TEXT_AREA][i].pixel_width;
19972 eassert (row->pixel_width >= 0);
19973 eassert (row->ascent >= 0 && row->height > 0);
19975 row->overlapping_p = (MATRIX_ROW_OVERLAPS_SUCC_P (row)
19976 || MATRIX_ROW_OVERLAPS_PRED_P (row));
19978 /* If first line's physical ascent is larger than its logical
19979 ascent, use the physical ascent, and make the row taller.
19980 This makes accented characters fully visible. */
19981 if (row == MATRIX_FIRST_TEXT_ROW (it->w->desired_matrix)
19982 && row->phys_ascent > row->ascent)
19984 row->height += row->phys_ascent - row->ascent;
19985 row->ascent = row->phys_ascent;
19988 /* Compute how much of the line is visible. */
19989 row->visible_height = row->height;
19991 min_y = WINDOW_HEADER_LINE_HEIGHT (it->w);
19992 max_y = WINDOW_BOX_HEIGHT_NO_MODE_LINE (it->w);
19994 if (row->y < min_y)
19995 row->visible_height -= min_y - row->y;
19996 if (row->y + row->height > max_y)
19997 row->visible_height -= row->y + row->height - max_y;
19999 else
20001 row->pixel_width = row->used[TEXT_AREA];
20002 if (row->continued_p)
20003 row->pixel_width -= it->continuation_pixel_width;
20004 else if (row->truncated_on_right_p)
20005 row->pixel_width -= it->truncation_pixel_width;
20006 row->ascent = row->phys_ascent = 0;
20007 row->height = row->phys_height = row->visible_height = 1;
20008 row->extra_line_spacing = 0;
20011 /* Compute a hash code for this row. */
20012 row->hash = row_hash (row);
20014 it->max_ascent = it->max_descent = 0;
20015 it->max_phys_ascent = it->max_phys_descent = 0;
20019 /* Append one space to the glyph row of iterator IT if doing a
20020 window-based redisplay. The space has the same face as
20021 IT->face_id. Value is true if a space was added.
20023 This function is called to make sure that there is always one glyph
20024 at the end of a glyph row that the cursor can be set on under
20025 window-systems. (If there weren't such a glyph we would not know
20026 how wide and tall a box cursor should be displayed).
20028 At the same time this space let's a nicely handle clearing to the
20029 end of the line if the row ends in italic text. */
20031 static bool
20032 append_space_for_newline (struct it *it, bool default_face_p)
20034 if (FRAME_WINDOW_P (it->f))
20036 int n = it->glyph_row->used[TEXT_AREA];
20038 if (it->glyph_row->glyphs[TEXT_AREA] + n
20039 < it->glyph_row->glyphs[1 + TEXT_AREA])
20041 /* Save some values that must not be changed.
20042 Must save IT->c and IT->len because otherwise
20043 ITERATOR_AT_END_P wouldn't work anymore after
20044 append_space_for_newline has been called. */
20045 enum display_element_type saved_what = it->what;
20046 int saved_c = it->c, saved_len = it->len;
20047 int saved_char_to_display = it->char_to_display;
20048 int saved_x = it->current_x;
20049 int saved_face_id = it->face_id;
20050 bool saved_box_end = it->end_of_box_run_p;
20051 struct text_pos saved_pos;
20052 Lisp_Object saved_object;
20053 struct face *face;
20055 saved_object = it->object;
20056 saved_pos = it->position;
20058 it->what = IT_CHARACTER;
20059 memset (&it->position, 0, sizeof it->position);
20060 it->object = Qnil;
20061 it->c = it->char_to_display = ' ';
20062 it->len = 1;
20064 /* If the default face was remapped, be sure to use the
20065 remapped face for the appended newline. */
20066 if (default_face_p)
20067 it->face_id = lookup_basic_face (it->f, DEFAULT_FACE_ID);
20068 else if (it->face_before_selective_p)
20069 it->face_id = it->saved_face_id;
20070 face = FACE_FROM_ID (it->f, it->face_id);
20071 it->face_id = FACE_FOR_CHAR (it->f, face, 0, -1, Qnil);
20072 /* In R2L rows, we will prepend a stretch glyph that will
20073 have the end_of_box_run_p flag set for it, so there's no
20074 need for the appended newline glyph to have that flag
20075 set. */
20076 if (it->glyph_row->reversed_p
20077 /* But if the appended newline glyph goes all the way to
20078 the end of the row, there will be no stretch glyph,
20079 so leave the box flag set. */
20080 && saved_x + FRAME_COLUMN_WIDTH (it->f) < it->last_visible_x)
20081 it->end_of_box_run_p = false;
20083 PRODUCE_GLYPHS (it);
20085 #ifdef HAVE_WINDOW_SYSTEM
20086 /* Make sure this space glyph has the right ascent and
20087 descent values, or else cursor at end of line will look
20088 funny, and height of empty lines will be incorrect. */
20089 struct glyph *g = it->glyph_row->glyphs[TEXT_AREA] + n;
20090 struct font *font = face->font ? face->font : FRAME_FONT (it->f);
20091 if (n == 0)
20093 Lisp_Object height, total_height;
20094 int extra_line_spacing = it->extra_line_spacing;
20095 int boff = font->baseline_offset;
20097 if (font->vertical_centering)
20098 boff = VCENTER_BASELINE_OFFSET (font, it->f) - boff;
20100 it->object = saved_object; /* get_it_property needs this */
20101 normal_char_ascent_descent (font, -1, &it->ascent, &it->descent);
20102 /* Must do a subset of line height processing from
20103 x_produce_glyph for newline characters. */
20104 height = get_it_property (it, Qline_height);
20105 if (CONSP (height)
20106 && CONSP (XCDR (height))
20107 && NILP (XCDR (XCDR (height))))
20109 total_height = XCAR (XCDR (height));
20110 height = XCAR (height);
20112 else
20113 total_height = Qnil;
20114 height = calc_line_height_property (it, height, font, boff, true);
20116 if (it->override_ascent >= 0)
20118 it->ascent = it->override_ascent;
20119 it->descent = it->override_descent;
20120 boff = it->override_boff;
20122 if (EQ (height, Qt))
20123 extra_line_spacing = 0;
20124 else
20126 Lisp_Object spacing;
20128 it->phys_ascent = it->ascent;
20129 it->phys_descent = it->descent;
20130 if (!NILP (height)
20131 && XINT (height) > it->ascent + it->descent)
20132 it->ascent = XINT (height) - it->descent;
20134 if (!NILP (total_height))
20135 spacing = calc_line_height_property (it, total_height, font,
20136 boff, false);
20137 else
20139 spacing = get_it_property (it, Qline_spacing);
20140 spacing = calc_line_height_property (it, spacing, font,
20141 boff, false);
20143 if (INTEGERP (spacing))
20145 extra_line_spacing = XINT (spacing);
20146 if (!NILP (total_height))
20147 extra_line_spacing -= (it->phys_ascent + it->phys_descent);
20150 if (extra_line_spacing > 0)
20152 it->descent += extra_line_spacing;
20153 if (extra_line_spacing > it->max_extra_line_spacing)
20154 it->max_extra_line_spacing = extra_line_spacing;
20156 it->max_ascent = it->ascent;
20157 it->max_descent = it->descent;
20158 /* Make sure compute_line_metrics recomputes the row height. */
20159 it->glyph_row->height = 0;
20162 g->ascent = it->max_ascent;
20163 g->descent = it->max_descent;
20164 #endif
20166 it->override_ascent = -1;
20167 it->constrain_row_ascent_descent_p = false;
20168 it->current_x = saved_x;
20169 it->object = saved_object;
20170 it->position = saved_pos;
20171 it->what = saved_what;
20172 it->face_id = saved_face_id;
20173 it->len = saved_len;
20174 it->c = saved_c;
20175 it->char_to_display = saved_char_to_display;
20176 it->end_of_box_run_p = saved_box_end;
20177 return true;
20181 return false;
20185 /* Extend the face of the last glyph in the text area of IT->glyph_row
20186 to the end of the display line. Called from display_line. If the
20187 glyph row is empty, add a space glyph to it so that we know the
20188 face to draw. Set the glyph row flag fill_line_p. If the glyph
20189 row is R2L, prepend a stretch glyph to cover the empty space to the
20190 left of the leftmost glyph. */
20192 static void
20193 extend_face_to_end_of_line (struct it *it)
20195 struct face *face, *default_face;
20196 struct frame *f = it->f;
20198 /* If line is already filled, do nothing. Non window-system frames
20199 get a grace of one more ``pixel'' because their characters are
20200 1-``pixel'' wide, so they hit the equality too early. This grace
20201 is needed only for R2L rows that are not continued, to produce
20202 one extra blank where we could display the cursor. */
20203 if ((it->current_x >= it->last_visible_x
20204 + (!FRAME_WINDOW_P (f)
20205 && it->glyph_row->reversed_p
20206 && !it->glyph_row->continued_p))
20207 /* If the window has display margins, we will need to extend
20208 their face even if the text area is filled. */
20209 && !(WINDOW_LEFT_MARGIN_WIDTH (it->w) > 0
20210 || WINDOW_RIGHT_MARGIN_WIDTH (it->w) > 0))
20211 return;
20213 /* The default face, possibly remapped. */
20214 default_face = FACE_FROM_ID_OR_NULL (f,
20215 lookup_basic_face (f, DEFAULT_FACE_ID));
20217 /* Face extension extends the background and box of IT->face_id
20218 to the end of the line. If the background equals the background
20219 of the frame, we don't have to do anything. */
20220 face = FACE_FROM_ID (f, (it->face_before_selective_p
20221 ? it->saved_face_id
20222 : it->face_id));
20224 if (FRAME_WINDOW_P (f)
20225 && MATRIX_ROW_DISPLAYS_TEXT_P (it->glyph_row)
20226 && face->box == FACE_NO_BOX
20227 && face->background == FRAME_BACKGROUND_PIXEL (f)
20228 #ifdef HAVE_WINDOW_SYSTEM
20229 && !face->stipple
20230 #endif
20231 && !it->glyph_row->reversed_p)
20232 return;
20234 /* Set the glyph row flag indicating that the face of the last glyph
20235 in the text area has to be drawn to the end of the text area. */
20236 it->glyph_row->fill_line_p = true;
20238 /* If current character of IT is not ASCII, make sure we have the
20239 ASCII face. This will be automatically undone the next time
20240 get_next_display_element returns a multibyte character. Note
20241 that the character will always be single byte in unibyte
20242 text. */
20243 if (!ASCII_CHAR_P (it->c))
20245 it->face_id = FACE_FOR_CHAR (f, face, 0, -1, Qnil);
20248 if (FRAME_WINDOW_P (f))
20250 /* If the row is empty, add a space with the current face of IT,
20251 so that we know which face to draw. */
20252 if (it->glyph_row->used[TEXT_AREA] == 0)
20254 it->glyph_row->glyphs[TEXT_AREA][0] = space_glyph;
20255 it->glyph_row->glyphs[TEXT_AREA][0].face_id = face->id;
20256 it->glyph_row->used[TEXT_AREA] = 1;
20258 /* Mode line and the header line don't have margins, and
20259 likewise the frame's tool-bar window, if there is any. */
20260 if (!(it->glyph_row->mode_line_p
20261 #if defined (HAVE_WINDOW_SYSTEM) && ! defined (USE_GTK) && ! defined (HAVE_NS)
20262 || (WINDOWP (f->tool_bar_window)
20263 && it->w == XWINDOW (f->tool_bar_window))
20264 #endif
20267 if (WINDOW_LEFT_MARGIN_WIDTH (it->w) > 0
20268 && it->glyph_row->used[LEFT_MARGIN_AREA] == 0)
20270 it->glyph_row->glyphs[LEFT_MARGIN_AREA][0] = space_glyph;
20271 it->glyph_row->glyphs[LEFT_MARGIN_AREA][0].face_id =
20272 default_face->id;
20273 it->glyph_row->used[LEFT_MARGIN_AREA] = 1;
20275 if (WINDOW_RIGHT_MARGIN_WIDTH (it->w) > 0
20276 && it->glyph_row->used[RIGHT_MARGIN_AREA] == 0)
20278 it->glyph_row->glyphs[RIGHT_MARGIN_AREA][0] = space_glyph;
20279 it->glyph_row->glyphs[RIGHT_MARGIN_AREA][0].face_id =
20280 default_face->id;
20281 it->glyph_row->used[RIGHT_MARGIN_AREA] = 1;
20284 #ifdef HAVE_WINDOW_SYSTEM
20285 if (it->glyph_row->reversed_p)
20287 /* Prepend a stretch glyph to the row, such that the
20288 rightmost glyph will be drawn flushed all the way to the
20289 right margin of the window. The stretch glyph that will
20290 occupy the empty space, if any, to the left of the
20291 glyphs. */
20292 struct font *font = face->font ? face->font : FRAME_FONT (f);
20293 struct glyph *row_start = it->glyph_row->glyphs[TEXT_AREA];
20294 struct glyph *row_end = row_start + it->glyph_row->used[TEXT_AREA];
20295 struct glyph *g;
20296 int row_width, stretch_ascent, stretch_width;
20297 struct text_pos saved_pos;
20298 int saved_face_id;
20299 bool saved_avoid_cursor, saved_box_start;
20301 for (row_width = 0, g = row_start; g < row_end; g++)
20302 row_width += g->pixel_width;
20304 /* FIXME: There are various minor display glitches in R2L
20305 rows when only one of the fringes is missing. The
20306 strange condition below produces the least bad effect. */
20307 if ((WINDOW_LEFT_FRINGE_WIDTH (it->w) == 0)
20308 == (WINDOW_RIGHT_FRINGE_WIDTH (it->w) == 0)
20309 || WINDOW_RIGHT_FRINGE_WIDTH (it->w) != 0)
20310 stretch_width = window_box_width (it->w, TEXT_AREA);
20311 else
20312 stretch_width = it->last_visible_x - it->first_visible_x;
20313 stretch_width -= row_width;
20315 if (stretch_width > 0)
20317 stretch_ascent =
20318 (((it->ascent + it->descent)
20319 * FONT_BASE (font)) / FONT_HEIGHT (font));
20320 saved_pos = it->position;
20321 memset (&it->position, 0, sizeof it->position);
20322 saved_avoid_cursor = it->avoid_cursor_p;
20323 it->avoid_cursor_p = true;
20324 saved_face_id = it->face_id;
20325 saved_box_start = it->start_of_box_run_p;
20326 /* The last row's stretch glyph should get the default
20327 face, to avoid painting the rest of the window with
20328 the region face, if the region ends at ZV. */
20329 if (it->glyph_row->ends_at_zv_p)
20330 it->face_id = default_face->id;
20331 else
20332 it->face_id = face->id;
20333 it->start_of_box_run_p = false;
20334 append_stretch_glyph (it, Qnil, stretch_width,
20335 it->ascent + it->descent, stretch_ascent);
20336 it->position = saved_pos;
20337 it->avoid_cursor_p = saved_avoid_cursor;
20338 it->face_id = saved_face_id;
20339 it->start_of_box_run_p = saved_box_start;
20341 /* If stretch_width comes out negative, it means that the
20342 last glyph is only partially visible. In R2L rows, we
20343 want the leftmost glyph to be partially visible, so we
20344 need to give the row the corresponding left offset. */
20345 if (stretch_width < 0)
20346 it->glyph_row->x = stretch_width;
20348 #endif /* HAVE_WINDOW_SYSTEM */
20350 else
20352 /* Save some values that must not be changed. */
20353 int saved_x = it->current_x;
20354 struct text_pos saved_pos;
20355 Lisp_Object saved_object;
20356 enum display_element_type saved_what = it->what;
20357 int saved_face_id = it->face_id;
20359 saved_object = it->object;
20360 saved_pos = it->position;
20362 it->what = IT_CHARACTER;
20363 memset (&it->position, 0, sizeof it->position);
20364 it->object = Qnil;
20365 it->c = it->char_to_display = ' ';
20366 it->len = 1;
20368 if (WINDOW_LEFT_MARGIN_WIDTH (it->w) > 0
20369 && (it->glyph_row->used[LEFT_MARGIN_AREA]
20370 < WINDOW_LEFT_MARGIN_WIDTH (it->w))
20371 && !it->glyph_row->mode_line_p
20372 && default_face->background != FRAME_BACKGROUND_PIXEL (f))
20374 struct glyph *g = it->glyph_row->glyphs[LEFT_MARGIN_AREA];
20375 struct glyph *e = g + it->glyph_row->used[LEFT_MARGIN_AREA];
20377 for (it->current_x = 0; g < e; g++)
20378 it->current_x += g->pixel_width;
20380 it->area = LEFT_MARGIN_AREA;
20381 it->face_id = default_face->id;
20382 while (it->glyph_row->used[LEFT_MARGIN_AREA]
20383 < WINDOW_LEFT_MARGIN_WIDTH (it->w)
20384 && g < it->glyph_row->glyphs[TEXT_AREA])
20386 PRODUCE_GLYPHS (it);
20387 /* term.c:produce_glyphs advances it->current_x only for
20388 TEXT_AREA. */
20389 it->current_x += it->pixel_width;
20390 g++;
20393 it->current_x = saved_x;
20394 it->area = TEXT_AREA;
20397 /* The last row's blank glyphs should get the default face, to
20398 avoid painting the rest of the window with the region face,
20399 if the region ends at ZV. */
20400 if (it->glyph_row->ends_at_zv_p)
20401 it->face_id = default_face->id;
20402 else
20403 it->face_id = face->id;
20404 PRODUCE_GLYPHS (it);
20406 while (it->current_x <= it->last_visible_x)
20407 PRODUCE_GLYPHS (it);
20409 if (WINDOW_RIGHT_MARGIN_WIDTH (it->w) > 0
20410 && (it->glyph_row->used[RIGHT_MARGIN_AREA]
20411 < WINDOW_RIGHT_MARGIN_WIDTH (it->w))
20412 && !it->glyph_row->mode_line_p
20413 && default_face->background != FRAME_BACKGROUND_PIXEL (f))
20415 struct glyph *g = it->glyph_row->glyphs[RIGHT_MARGIN_AREA];
20416 struct glyph *e = g + it->glyph_row->used[RIGHT_MARGIN_AREA];
20418 for ( ; g < e; g++)
20419 it->current_x += g->pixel_width;
20421 it->area = RIGHT_MARGIN_AREA;
20422 it->face_id = default_face->id;
20423 while (it->glyph_row->used[RIGHT_MARGIN_AREA]
20424 < WINDOW_RIGHT_MARGIN_WIDTH (it->w)
20425 && g < it->glyph_row->glyphs[LAST_AREA])
20427 PRODUCE_GLYPHS (it);
20428 it->current_x += it->pixel_width;
20429 g++;
20432 it->area = TEXT_AREA;
20435 /* Don't count these blanks really. It would let us insert a left
20436 truncation glyph below and make us set the cursor on them, maybe. */
20437 it->current_x = saved_x;
20438 it->object = saved_object;
20439 it->position = saved_pos;
20440 it->what = saved_what;
20441 it->face_id = saved_face_id;
20446 /* Value is true if text starting at CHARPOS in current_buffer is
20447 trailing whitespace. */
20449 static bool
20450 trailing_whitespace_p (ptrdiff_t charpos)
20452 ptrdiff_t bytepos = CHAR_TO_BYTE (charpos);
20453 int c = 0;
20455 while (bytepos < ZV_BYTE
20456 && (c = FETCH_CHAR (bytepos),
20457 c == ' ' || c == '\t'))
20458 ++bytepos;
20460 if (bytepos >= ZV_BYTE || c == '\n' || c == '\r')
20462 if (bytepos != PT_BYTE)
20463 return true;
20465 return false;
20469 /* Highlight trailing whitespace, if any, in ROW. */
20471 static void
20472 highlight_trailing_whitespace (struct frame *f, struct glyph_row *row)
20474 int used = row->used[TEXT_AREA];
20476 if (used)
20478 struct glyph *start = row->glyphs[TEXT_AREA];
20479 struct glyph *glyph = start + used - 1;
20481 if (row->reversed_p)
20483 /* Right-to-left rows need to be processed in the opposite
20484 direction, so swap the edge pointers. */
20485 glyph = start;
20486 start = row->glyphs[TEXT_AREA] + used - 1;
20489 /* Skip over glyphs inserted to display the cursor at the
20490 end of a line, for extending the face of the last glyph
20491 to the end of the line on terminals, and for truncation
20492 and continuation glyphs. */
20493 if (!row->reversed_p)
20495 while (glyph >= start
20496 && glyph->type == CHAR_GLYPH
20497 && NILP (glyph->object))
20498 --glyph;
20500 else
20502 while (glyph <= start
20503 && glyph->type == CHAR_GLYPH
20504 && NILP (glyph->object))
20505 ++glyph;
20508 /* If last glyph is a space or stretch, and it's trailing
20509 whitespace, set the face of all trailing whitespace glyphs in
20510 IT->glyph_row to `trailing-whitespace'. */
20511 if ((row->reversed_p ? glyph <= start : glyph >= start)
20512 && BUFFERP (glyph->object)
20513 && (glyph->type == STRETCH_GLYPH
20514 || (glyph->type == CHAR_GLYPH
20515 && glyph->u.ch == ' '))
20516 && trailing_whitespace_p (glyph->charpos))
20518 int face_id = lookup_named_face (f, Qtrailing_whitespace, false);
20519 if (face_id < 0)
20520 return;
20522 if (!row->reversed_p)
20524 while (glyph >= start
20525 && BUFFERP (glyph->object)
20526 && (glyph->type == STRETCH_GLYPH
20527 || (glyph->type == CHAR_GLYPH
20528 && glyph->u.ch == ' ')))
20529 (glyph--)->face_id = face_id;
20531 else
20533 while (glyph <= start
20534 && BUFFERP (glyph->object)
20535 && (glyph->type == STRETCH_GLYPH
20536 || (glyph->type == CHAR_GLYPH
20537 && glyph->u.ch == ' ')))
20538 (glyph++)->face_id = face_id;
20545 /* Value is true if glyph row ROW should be
20546 considered to hold the buffer position CHARPOS. */
20548 static bool
20549 row_for_charpos_p (struct glyph_row *row, ptrdiff_t charpos)
20551 bool result = true;
20553 if (charpos == CHARPOS (row->end.pos)
20554 || charpos == MATRIX_ROW_END_CHARPOS (row))
20556 /* Suppose the row ends on a string.
20557 Unless the row is continued, that means it ends on a newline
20558 in the string. If it's anything other than a display string
20559 (e.g., a before-string from an overlay), we don't want the
20560 cursor there. (This heuristic seems to give the optimal
20561 behavior for the various types of multi-line strings.)
20562 One exception: if the string has `cursor' property on one of
20563 its characters, we _do_ want the cursor there. */
20564 if (CHARPOS (row->end.string_pos) >= 0)
20566 if (row->continued_p)
20567 result = true;
20568 else
20570 /* Check for `display' property. */
20571 struct glyph *beg = row->glyphs[TEXT_AREA];
20572 struct glyph *end = beg + row->used[TEXT_AREA] - 1;
20573 struct glyph *glyph;
20575 result = false;
20576 for (glyph = end; glyph >= beg; --glyph)
20577 if (STRINGP (glyph->object))
20579 Lisp_Object prop
20580 = Fget_char_property (make_number (charpos),
20581 Qdisplay, Qnil);
20582 result =
20583 (!NILP (prop)
20584 && display_prop_string_p (prop, glyph->object));
20585 /* If there's a `cursor' property on one of the
20586 string's characters, this row is a cursor row,
20587 even though this is not a display string. */
20588 if (!result)
20590 Lisp_Object s = glyph->object;
20592 for ( ; glyph >= beg && EQ (glyph->object, s); --glyph)
20594 ptrdiff_t gpos = glyph->charpos;
20596 if (!NILP (Fget_char_property (make_number (gpos),
20597 Qcursor, s)))
20599 result = true;
20600 break;
20604 break;
20608 else if (MATRIX_ROW_ENDS_IN_MIDDLE_OF_CHAR_P (row))
20610 /* If the row ends in middle of a real character,
20611 and the line is continued, we want the cursor here.
20612 That's because CHARPOS (ROW->end.pos) would equal
20613 PT if PT is before the character. */
20614 if (!row->ends_in_ellipsis_p)
20615 result = row->continued_p;
20616 else
20617 /* If the row ends in an ellipsis, then
20618 CHARPOS (ROW->end.pos) will equal point after the
20619 invisible text. We want that position to be displayed
20620 after the ellipsis. */
20621 result = false;
20623 /* If the row ends at ZV, display the cursor at the end of that
20624 row instead of at the start of the row below. */
20625 else
20626 result = row->ends_at_zv_p;
20629 return result;
20632 /* Value is true if glyph row ROW should be
20633 used to hold the cursor. */
20635 static bool
20636 cursor_row_p (struct glyph_row *row)
20638 return row_for_charpos_p (row, PT);
20643 /* Push the property PROP so that it will be rendered at the current
20644 position in IT. Return true if PROP was successfully pushed, false
20645 otherwise. Called from handle_line_prefix to handle the
20646 `line-prefix' and `wrap-prefix' properties. */
20648 static bool
20649 push_prefix_prop (struct it *it, Lisp_Object prop)
20651 struct text_pos pos =
20652 STRINGP (it->string) ? it->current.string_pos : it->current.pos;
20654 eassert (it->method == GET_FROM_BUFFER
20655 || it->method == GET_FROM_DISPLAY_VECTOR
20656 || it->method == GET_FROM_STRING
20657 || it->method == GET_FROM_IMAGE);
20659 /* We need to save the current buffer/string position, so it will be
20660 restored by pop_it, because iterate_out_of_display_property
20661 depends on that being set correctly, but some situations leave
20662 it->position not yet set when this function is called. */
20663 push_it (it, &pos);
20665 if (STRINGP (prop))
20667 if (SCHARS (prop) == 0)
20669 pop_it (it);
20670 return false;
20673 it->string = prop;
20674 it->string_from_prefix_prop_p = true;
20675 it->multibyte_p = STRING_MULTIBYTE (it->string);
20676 it->current.overlay_string_index = -1;
20677 IT_STRING_CHARPOS (*it) = IT_STRING_BYTEPOS (*it) = 0;
20678 it->end_charpos = it->string_nchars = SCHARS (it->string);
20679 it->method = GET_FROM_STRING;
20680 it->stop_charpos = 0;
20681 it->prev_stop = 0;
20682 it->base_level_stop = 0;
20683 it->cmp_it.id = -1;
20685 /* Force paragraph direction to be that of the parent
20686 buffer/string. */
20687 if (it->bidi_p && it->bidi_it.paragraph_dir == R2L)
20688 it->paragraph_embedding = it->bidi_it.paragraph_dir;
20689 else
20690 it->paragraph_embedding = L2R;
20692 /* Set up the bidi iterator for this display string. */
20693 if (it->bidi_p)
20695 it->bidi_it.string.lstring = it->string;
20696 it->bidi_it.string.s = NULL;
20697 it->bidi_it.string.schars = it->end_charpos;
20698 it->bidi_it.string.bufpos = IT_CHARPOS (*it);
20699 it->bidi_it.string.from_disp_str = it->string_from_display_prop_p;
20700 it->bidi_it.string.unibyte = !it->multibyte_p;
20701 it->bidi_it.w = it->w;
20702 bidi_init_it (0, 0, FRAME_WINDOW_P (it->f), &it->bidi_it);
20705 else if (CONSP (prop) && EQ (XCAR (prop), Qspace))
20707 it->method = GET_FROM_STRETCH;
20708 it->object = prop;
20710 #ifdef HAVE_WINDOW_SYSTEM
20711 else if (IMAGEP (prop))
20713 it->what = IT_IMAGE;
20714 it->image_id = lookup_image (it->f, prop);
20715 it->method = GET_FROM_IMAGE;
20717 #endif /* HAVE_WINDOW_SYSTEM */
20718 else
20720 pop_it (it); /* bogus display property, give up */
20721 return false;
20724 return true;
20727 /* Return the character-property PROP at the current position in IT. */
20729 static Lisp_Object
20730 get_it_property (struct it *it, Lisp_Object prop)
20732 Lisp_Object position, object = it->object;
20734 if (STRINGP (object))
20735 position = make_number (IT_STRING_CHARPOS (*it));
20736 else if (BUFFERP (object))
20738 position = make_number (IT_CHARPOS (*it));
20739 object = it->window;
20741 else
20742 return Qnil;
20744 return Fget_char_property (position, prop, object);
20747 /* See if there's a line- or wrap-prefix, and if so, push it on IT. */
20749 static void
20750 handle_line_prefix (struct it *it)
20752 Lisp_Object prefix;
20754 if (it->continuation_lines_width > 0)
20756 prefix = get_it_property (it, Qwrap_prefix);
20757 if (NILP (prefix))
20758 prefix = Vwrap_prefix;
20760 else
20762 prefix = get_it_property (it, Qline_prefix);
20763 if (NILP (prefix))
20764 prefix = Vline_prefix;
20766 if (! NILP (prefix) && push_prefix_prop (it, prefix))
20768 /* If the prefix is wider than the window, and we try to wrap
20769 it, it would acquire its own wrap prefix, and so on till the
20770 iterator stack overflows. So, don't wrap the prefix. */
20771 it->line_wrap = TRUNCATE;
20772 it->avoid_cursor_p = true;
20778 /* Remove N glyphs at the start of a reversed IT->glyph_row. Called
20779 only for R2L lines from display_line and display_string, when they
20780 decide that too many glyphs were produced by PRODUCE_GLYPHS, and
20781 the line/string needs to be continued on the next glyph row. */
20782 static void
20783 unproduce_glyphs (struct it *it, int n)
20785 struct glyph *glyph, *end;
20787 eassert (it->glyph_row);
20788 eassert (it->glyph_row->reversed_p);
20789 eassert (it->area == TEXT_AREA);
20790 eassert (n <= it->glyph_row->used[TEXT_AREA]);
20792 if (n > it->glyph_row->used[TEXT_AREA])
20793 n = it->glyph_row->used[TEXT_AREA];
20794 glyph = it->glyph_row->glyphs[TEXT_AREA] + n;
20795 end = it->glyph_row->glyphs[TEXT_AREA] + it->glyph_row->used[TEXT_AREA];
20796 for ( ; glyph < end; glyph++)
20797 glyph[-n] = *glyph;
20800 /* Find the positions in a bidi-reordered ROW to serve as ROW->minpos
20801 and ROW->maxpos. */
20802 static void
20803 find_row_edges (struct it *it, struct glyph_row *row,
20804 ptrdiff_t min_pos, ptrdiff_t min_bpos,
20805 ptrdiff_t max_pos, ptrdiff_t max_bpos)
20807 /* FIXME: Revisit this when glyph ``spilling'' in continuation
20808 lines' rows is implemented for bidi-reordered rows. */
20810 /* ROW->minpos is the value of min_pos, the minimal buffer position
20811 we have in ROW, or ROW->start.pos if that is smaller. */
20812 if (min_pos <= ZV && min_pos < row->start.pos.charpos)
20813 SET_TEXT_POS (row->minpos, min_pos, min_bpos);
20814 else
20815 /* We didn't find buffer positions smaller than ROW->start, or
20816 didn't find _any_ valid buffer positions in any of the glyphs,
20817 so we must trust the iterator's computed positions. */
20818 row->minpos = row->start.pos;
20819 if (max_pos <= 0)
20821 max_pos = CHARPOS (it->current.pos);
20822 max_bpos = BYTEPOS (it->current.pos);
20825 /* Here are the various use-cases for ending the row, and the
20826 corresponding values for ROW->maxpos:
20828 Line ends in a newline from buffer eol_pos + 1
20829 Line is continued from buffer max_pos + 1
20830 Line is truncated on right it->current.pos
20831 Line ends in a newline from string max_pos + 1(*)
20832 (*) + 1 only when line ends in a forward scan
20833 Line is continued from string max_pos
20834 Line is continued from display vector max_pos
20835 Line is entirely from a string min_pos == max_pos
20836 Line is entirely from a display vector min_pos == max_pos
20837 Line that ends at ZV ZV
20839 If you discover other use-cases, please add them here as
20840 appropriate. */
20841 if (row->ends_at_zv_p)
20842 row->maxpos = it->current.pos;
20843 else if (row->used[TEXT_AREA])
20845 bool seen_this_string = false;
20846 struct glyph_row *r1 = row - 1;
20848 /* Did we see the same display string on the previous row? */
20849 if (STRINGP (it->object)
20850 /* this is not the first row */
20851 && row > it->w->desired_matrix->rows
20852 /* previous row is not the header line */
20853 && !r1->mode_line_p
20854 /* previous row also ends in a newline from a string */
20855 && r1->ends_in_newline_from_string_p)
20857 struct glyph *start, *end;
20859 /* Search for the last glyph of the previous row that came
20860 from buffer or string. Depending on whether the row is
20861 L2R or R2L, we need to process it front to back or the
20862 other way round. */
20863 if (!r1->reversed_p)
20865 start = r1->glyphs[TEXT_AREA];
20866 end = start + r1->used[TEXT_AREA];
20867 /* Glyphs inserted by redisplay have nil as their object. */
20868 while (end > start
20869 && NILP ((end - 1)->object)
20870 && (end - 1)->charpos <= 0)
20871 --end;
20872 if (end > start)
20874 if (EQ ((end - 1)->object, it->object))
20875 seen_this_string = true;
20877 else
20878 /* If all the glyphs of the previous row were inserted
20879 by redisplay, it means the previous row was
20880 produced from a single newline, which is only
20881 possible if that newline came from the same string
20882 as the one which produced this ROW. */
20883 seen_this_string = true;
20885 else
20887 end = r1->glyphs[TEXT_AREA] - 1;
20888 start = end + r1->used[TEXT_AREA];
20889 while (end < start
20890 && NILP ((end + 1)->object)
20891 && (end + 1)->charpos <= 0)
20892 ++end;
20893 if (end < start)
20895 if (EQ ((end + 1)->object, it->object))
20896 seen_this_string = true;
20898 else
20899 seen_this_string = true;
20902 /* Take note of each display string that covers a newline only
20903 once, the first time we see it. This is for when a display
20904 string includes more than one newline in it. */
20905 if (row->ends_in_newline_from_string_p && !seen_this_string)
20907 /* If we were scanning the buffer forward when we displayed
20908 the string, we want to account for at least one buffer
20909 position that belongs to this row (position covered by
20910 the display string), so that cursor positioning will
20911 consider this row as a candidate when point is at the end
20912 of the visual line represented by this row. This is not
20913 required when scanning back, because max_pos will already
20914 have a much larger value. */
20915 if (CHARPOS (row->end.pos) > max_pos)
20916 INC_BOTH (max_pos, max_bpos);
20917 SET_TEXT_POS (row->maxpos, max_pos, max_bpos);
20919 else if (CHARPOS (it->eol_pos) > 0)
20920 SET_TEXT_POS (row->maxpos,
20921 CHARPOS (it->eol_pos) + 1, BYTEPOS (it->eol_pos) + 1);
20922 else if (row->continued_p)
20924 /* If max_pos is different from IT's current position, it
20925 means IT->method does not belong to the display element
20926 at max_pos. However, it also means that the display
20927 element at max_pos was displayed in its entirety on this
20928 line, which is equivalent to saying that the next line
20929 starts at the next buffer position. */
20930 if (IT_CHARPOS (*it) == max_pos && it->method != GET_FROM_BUFFER)
20931 SET_TEXT_POS (row->maxpos, max_pos, max_bpos);
20932 else
20934 INC_BOTH (max_pos, max_bpos);
20935 SET_TEXT_POS (row->maxpos, max_pos, max_bpos);
20938 else if (row->truncated_on_right_p)
20939 /* display_line already called reseat_at_next_visible_line_start,
20940 which puts the iterator at the beginning of the next line, in
20941 the logical order. */
20942 row->maxpos = it->current.pos;
20943 else if (max_pos == min_pos && it->method != GET_FROM_BUFFER)
20944 /* A line that is entirely from a string/image/stretch... */
20945 row->maxpos = row->minpos;
20946 else
20947 emacs_abort ();
20949 else
20950 row->maxpos = it->current.pos;
20953 /* Like display_count_lines, but capable of counting outside of the
20954 current narrowed region. */
20955 static ptrdiff_t
20956 display_count_lines_logically (ptrdiff_t start_byte, ptrdiff_t limit_byte,
20957 ptrdiff_t count, ptrdiff_t *byte_pos_ptr)
20959 if (!display_line_numbers_widen || (BEGV == BEG && ZV == Z))
20960 return display_count_lines (start_byte, limit_byte, count, byte_pos_ptr);
20962 ptrdiff_t val;
20963 ptrdiff_t pdl_count = SPECPDL_INDEX ();
20964 record_unwind_protect (save_restriction_restore, save_restriction_save ());
20965 Fwiden ();
20966 val = display_count_lines (start_byte, limit_byte, count, byte_pos_ptr);
20967 unbind_to (pdl_count, Qnil);
20968 return val;
20971 /* Count the number of screen lines in window IT->w between character
20972 position IT_CHARPOS(*IT) and the line showing that window's point. */
20973 static ptrdiff_t
20974 display_count_lines_visually (struct it *it)
20976 struct it tem_it;
20977 ptrdiff_t to;
20978 struct text_pos from;
20980 /* If we already calculated a relative line number, use that. This
20981 trick relies on the fact that visual lines (a.k.a. "glyph rows")
20982 are laid out sequentially, one by one, for each sequence of calls
20983 to display_line or other similar function that follows a call to
20984 init_iterator. */
20985 if (it->lnum_bytepos > 0)
20986 return it->lnum + 1;
20987 else
20989 ptrdiff_t count = SPECPDL_INDEX ();
20991 if (IT_CHARPOS (*it) <= PT)
20993 from = it->current.pos;
20994 to = PT;
20996 else
20998 SET_TEXT_POS (from, PT, PT_BYTE);
20999 to = IT_CHARPOS (*it);
21001 start_display (&tem_it, it->w, from);
21002 /* Need to disable visual mode temporarily, since otherwise the
21003 call to move_it_to will cause infinite recursion. */
21004 specbind (Qdisplay_line_numbers, Qrelative);
21005 /* Some redisplay optimizations could invoke us very far from
21006 PT, which will make the caller painfully slow. There should
21007 be no need to go too far beyond the window's bottom, as any
21008 such optimization will fail to show point anyway. */
21009 move_it_to (&tem_it, to, -1,
21010 tem_it.last_visible_y
21011 + (SCROLL_LIMIT + 10) * FRAME_LINE_HEIGHT (tem_it.f),
21012 -1, MOVE_TO_POS | MOVE_TO_Y);
21013 unbind_to (count, Qnil);
21014 return IT_CHARPOS (*it) <= PT ? -tem_it.vpos : tem_it.vpos;
21018 /* Produce the line-number glyphs for the current glyph_row. If
21019 IT->glyph_row is non-NULL, populate the row with the produced
21020 glyphs. */
21021 static void
21022 maybe_produce_line_number (struct it *it)
21024 ptrdiff_t last_line = it->lnum;
21025 ptrdiff_t start_from, bytepos;
21026 ptrdiff_t this_line;
21027 bool first_time = false;
21028 ptrdiff_t beg_byte = display_line_numbers_widen ? BEG_BYTE : BEGV_BYTE;
21029 ptrdiff_t z_byte = display_line_numbers_widen ? Z_BYTE : ZV_BYTE;
21030 void *itdata = bidi_shelve_cache ();
21032 if (EQ (Vdisplay_line_numbers, Qvisual))
21033 this_line = display_count_lines_visually (it);
21034 else
21036 if (!last_line)
21038 /* If possible, reuse data cached by line-number-mode. */
21039 if (it->w->base_line_number > 0
21040 && it->w->base_line_pos > 0
21041 && it->w->base_line_pos <= IT_CHARPOS (*it)
21042 /* line-number-mode always displays narrowed line
21043 numbers, so we cannot use its data if the user wants
21044 line numbers that disregard narrowing, or if the
21045 buffer's narrowing has just changed. */
21046 && !(display_line_numbers_widen
21047 && (BEG_BYTE != BEGV_BYTE || Z_BYTE != ZV_BYTE))
21048 && !current_buffer->clip_changed)
21050 start_from = CHAR_TO_BYTE (it->w->base_line_pos);
21051 last_line = it->w->base_line_number - 1;
21053 else
21054 start_from = beg_byte;
21055 if (!it->lnum_bytepos)
21056 first_time = true;
21058 else
21059 start_from = it->lnum_bytepos;
21061 /* Paranoia: what if someone changes the narrowing since the
21062 last time display_line was called? Shouldn't really happen,
21063 but who knows what some crazy Lisp invoked by :eval could do? */
21064 if (!(beg_byte <= start_from && start_from <= z_byte))
21066 last_line = 0;
21067 start_from = beg_byte;
21070 this_line =
21071 last_line + display_count_lines_logically (start_from,
21072 IT_BYTEPOS (*it),
21073 IT_CHARPOS (*it), &bytepos);
21074 eassert (this_line > 0 || (this_line == 0 && start_from == beg_byte));
21075 eassert (bytepos == IT_BYTEPOS (*it));
21078 /* Record the line number information. */
21079 if (this_line != last_line || !it->lnum_bytepos)
21081 it->lnum = this_line;
21082 it->lnum_bytepos = IT_BYTEPOS (*it);
21085 /* Produce the glyphs for the line number. */
21086 struct it tem_it;
21087 char lnum_buf[INT_STRLEN_BOUND (ptrdiff_t) + 1];
21088 bool beyond_zv = IT_BYTEPOS (*it) >= ZV_BYTE ? true : false;
21089 ptrdiff_t lnum_offset = -1; /* to produce 1-based line numbers */
21090 int lnum_face_id = merge_faces (it->f, Qline_number, 0, DEFAULT_FACE_ID);
21091 int current_lnum_face_id
21092 = merge_faces (it->f, Qline_number_current_line, 0, DEFAULT_FACE_ID);
21093 /* Compute point's line number if needed. */
21094 if ((EQ (Vdisplay_line_numbers, Qrelative)
21095 || EQ (Vdisplay_line_numbers, Qvisual)
21096 || lnum_face_id != current_lnum_face_id)
21097 && !it->pt_lnum)
21099 ptrdiff_t ignored;
21100 if (PT_BYTE > it->lnum_bytepos && !EQ (Vdisplay_line_numbers, Qvisual))
21101 it->pt_lnum =
21102 this_line + display_count_lines_logically (it->lnum_bytepos, PT_BYTE,
21103 PT, &ignored);
21104 else
21105 it->pt_lnum = display_count_lines_logically (beg_byte, PT_BYTE, PT,
21106 &ignored);
21108 /* Compute the required width if needed. */
21109 if (!it->lnum_width)
21111 if (NATNUMP (Vdisplay_line_numbers_width))
21112 it->lnum_width = XFASTINT (Vdisplay_line_numbers_width);
21114 /* Max line number to be displayed cannot be more than the one
21115 corresponding to the last row of the desired matrix. */
21116 ptrdiff_t max_lnum;
21118 if (NILP (Vdisplay_line_numbers_current_absolute)
21119 && (EQ (Vdisplay_line_numbers, Qrelative)
21120 || EQ (Vdisplay_line_numbers, Qvisual)))
21121 /* We subtract one more because the current line is always
21122 zero in this mode. */
21123 max_lnum = it->w->desired_matrix->nrows - 2;
21124 else if (EQ (Vdisplay_line_numbers, Qvisual))
21125 max_lnum = it->pt_lnum + it->w->desired_matrix->nrows - 1;
21126 else
21127 max_lnum = this_line + it->w->desired_matrix->nrows - 1 - it->vpos;
21128 max_lnum = max (1, max_lnum);
21129 it->lnum_width = max (it->lnum_width, log10 (max_lnum) + 1);
21130 eassert (it->lnum_width > 0);
21132 if (EQ (Vdisplay_line_numbers, Qrelative))
21133 lnum_offset = it->pt_lnum;
21134 else if (EQ (Vdisplay_line_numbers, Qvisual))
21135 lnum_offset = 0;
21137 /* Under 'relative', display the absolute line number for the
21138 current line, unless the user requests otherwise. */
21139 ptrdiff_t lnum_to_display = eabs (this_line - lnum_offset);
21140 if ((EQ (Vdisplay_line_numbers, Qrelative)
21141 || EQ (Vdisplay_line_numbers, Qvisual))
21142 && lnum_to_display == 0
21143 && !NILP (Vdisplay_line_numbers_current_absolute))
21144 lnum_to_display = it->pt_lnum + 1;
21145 /* In L2R rows we need to append the blank separator, in R2L
21146 rows we need to prepend it. But this function is usually
21147 called when no display elements were produced from the
21148 following line, so the paragraph direction might be unknown.
21149 Therefore we cheat and add 2 blanks, one on either side. */
21150 pint2str (lnum_buf, it->lnum_width + 1, lnum_to_display);
21151 strcat (lnum_buf, " ");
21153 /* Setup for producing the glyphs. */
21154 init_iterator (&tem_it, it->w, -1, -1, &scratch_glyph_row,
21155 /* FIXME: Use specialized face. */
21156 DEFAULT_FACE_ID);
21157 scratch_glyph_row.reversed_p = false;
21158 scratch_glyph_row.used[TEXT_AREA] = 0;
21159 SET_TEXT_POS (tem_it.position, 0, 0);
21160 tem_it.avoid_cursor_p = true;
21161 tem_it.bidi_p = true;
21162 tem_it.bidi_it.type = WEAK_EN;
21163 /* According to UAX#9, EN goes up 2 levels in L2R paragraph and
21164 1 level in R2L paragraphs. Emulate that, assuming we are in
21165 an L2R paragraph. */
21166 tem_it.bidi_it.resolved_level = 2;
21168 /* Produce glyphs for the line number in a scratch glyph_row. */
21169 int n_glyphs_before;
21170 for (const char *p = lnum_buf; *p; p++)
21172 /* For continuation lines and lines after ZV, instead of a line
21173 number, produce a blank prefix of the same width. Use the
21174 default face for the blank field beyond ZV. */
21175 if (beyond_zv)
21176 tem_it.face_id = it->base_face_id;
21177 else if (lnum_face_id != current_lnum_face_id
21178 && (EQ (Vdisplay_line_numbers, Qvisual)
21179 ? this_line == 0
21180 : this_line == it->pt_lnum))
21181 tem_it.face_id = current_lnum_face_id;
21182 else
21183 tem_it.face_id = lnum_face_id;
21184 if (beyond_zv
21185 /* Don't display the same line number more than once. */
21186 || (!EQ (Vdisplay_line_numbers, Qvisual)
21187 && (it->continuation_lines_width > 0
21188 || (this_line == last_line && !first_time))))
21189 tem_it.c = tem_it.char_to_display = ' ';
21190 else
21191 tem_it.c = tem_it.char_to_display = *p;
21192 tem_it.len = 1;
21193 n_glyphs_before = scratch_glyph_row.used[TEXT_AREA];
21194 /* Make sure these glyphs will have a "position" of -1. */
21195 SET_TEXT_POS (tem_it.position, -1, -1);
21196 PRODUCE_GLYPHS (&tem_it);
21198 /* Stop producing glyphs if we don't have enough space on
21199 this line. FIXME: should we refrain from producing the
21200 line number at all in that case? */
21201 if (tem_it.current_x > tem_it.last_visible_x)
21203 scratch_glyph_row.used[TEXT_AREA] = n_glyphs_before;
21204 break;
21208 /* Record the width in pixels we need for the line number display. */
21209 it->lnum_pixel_width = tem_it.current_x;
21210 /* Copy the produced glyphs into IT's glyph_row. */
21211 struct glyph *g = scratch_glyph_row.glyphs[TEXT_AREA];
21212 struct glyph *e = g + scratch_glyph_row.used[TEXT_AREA];
21213 struct glyph *p = it->glyph_row ? it->glyph_row->glyphs[TEXT_AREA] : NULL;
21214 short *u = it->glyph_row ? &it->glyph_row->used[TEXT_AREA] : NULL;
21216 eassert (it->glyph_row == NULL || it->glyph_row->used[TEXT_AREA] == 0);
21218 for ( ; g < e; g++)
21220 it->current_x += g->pixel_width;
21221 /* The following is important when this function is called
21222 from move_it_in_display_line_to: HPOS is incremented only
21223 when we are in the visible portion of the glyph row. */
21224 if (it->current_x > it->first_visible_x)
21225 it->hpos++;
21226 if (p)
21228 *p++ = *g;
21229 (*u)++;
21233 /* Update IT's metrics due to glyphs produced for line numbers. */
21234 if (it->glyph_row)
21236 struct glyph_row *row = it->glyph_row;
21238 it->max_ascent = max (row->ascent, tem_it.max_ascent);
21239 it->max_descent = max (row->height - row->ascent, tem_it.max_descent);
21240 it->max_phys_ascent = max (row->phys_ascent, tem_it.max_phys_ascent);
21241 it->max_phys_descent = max (row->phys_height - row->phys_ascent,
21242 tem_it.max_phys_descent);
21244 else
21246 it->max_ascent = max (it->max_ascent, tem_it.max_ascent);
21247 it->max_descent = max (it->max_descent, tem_it.max_descent);
21248 it->max_phys_ascent = max (it->max_phys_ascent, tem_it.max_phys_ascent);
21249 it->max_phys_descent = max (it->max_phys_descent, tem_it.max_phys_descent);
21252 it->line_number_produced_p = true;
21254 bidi_unshelve_cache (itdata, false);
21257 /* Return true if this glyph row needs a line number to be produced
21258 for it. */
21259 static bool
21260 should_produce_line_number (struct it *it)
21262 if (NILP (Vdisplay_line_numbers))
21263 return false;
21265 /* Don't display line numbers in minibuffer windows. */
21266 if (MINI_WINDOW_P (it->w))
21267 return false;
21269 #ifdef HAVE_WINDOW_SYSTEM
21270 /* Don't display line number in tooltip frames. */
21271 if (FRAMEP (tip_frame) && EQ (WINDOW_FRAME (it->w), tip_frame)
21272 #ifdef USE_GTK
21273 /* GTK builds store in tip_frame the frame that shows the tip,
21274 so we need an additional test. */
21275 && !NILP (Fframe_parameter (tip_frame, Qtooltip))
21276 #endif
21278 return false;
21279 #endif
21281 /* If the character at current position has a non-nil special
21282 property, disable line numbers for this row. This is for
21283 packages such as company-mode, which need this for their tricky
21284 layout, where line numbers get in the way. */
21285 Lisp_Object val = Fget_char_property (make_number (IT_CHARPOS (*it)),
21286 Qdisplay_line_numbers_disable,
21287 it->window);
21288 /* For ZV, we need to also look in empty overlays at that point,
21289 because get-char-property always returns nil for ZV, except if
21290 the property is in 'default-text-properties'. */
21291 if (NILP (val) && IT_CHARPOS (*it) >= ZV)
21292 val = disable_line_numbers_overlay_at_eob ();
21293 return NILP (val) ? true : false;
21296 /* Return true if ROW has no glyphs except those inserted by the
21297 display engine. This is needed for indicate-empty-lines and
21298 similar features when the glyph row starts with glyphs which didn't
21299 come from buffer or string. */
21300 static bool
21301 row_text_area_empty (struct glyph_row *row)
21303 if (!row->reversed_p)
21305 for (struct glyph *g = row->glyphs[TEXT_AREA];
21306 g < row->glyphs[TEXT_AREA] + row->used[TEXT_AREA];
21307 g++)
21308 if (!NILP (g->object) || g->charpos > 0)
21309 return false;
21311 else
21313 for (struct glyph *g = row->glyphs[TEXT_AREA] + row->used[TEXT_AREA] - 1;
21314 g > row->glyphs[TEXT_AREA];
21315 g--)
21316 if (!NILP ((g - 1)->object) || (g - 1)->charpos > 0)
21317 return false;
21320 return true;
21323 /* Construct the glyph row IT->glyph_row in the desired matrix of
21324 IT->w from text at the current position of IT. See dispextern.h
21325 for an overview of struct it. Value is true if
21326 IT->glyph_row displays text, as opposed to a line displaying ZV
21327 only. CURSOR_VPOS is the window-relative vertical position of
21328 the glyph row displaying the cursor, or -1 if unknown. */
21330 static bool
21331 display_line (struct it *it, int cursor_vpos)
21333 struct glyph_row *row = it->glyph_row;
21334 Lisp_Object overlay_arrow_string;
21335 struct it wrap_it;
21336 void *wrap_data = NULL;
21337 bool may_wrap = false;
21338 int wrap_x UNINIT;
21339 int wrap_row_used = -1;
21340 int wrap_row_ascent UNINIT, wrap_row_height UNINIT;
21341 int wrap_row_phys_ascent UNINIT, wrap_row_phys_height UNINIT;
21342 int wrap_row_extra_line_spacing UNINIT;
21343 ptrdiff_t wrap_row_min_pos UNINIT, wrap_row_min_bpos UNINIT;
21344 ptrdiff_t wrap_row_max_pos UNINIT, wrap_row_max_bpos UNINIT;
21345 int cvpos;
21346 ptrdiff_t min_pos = ZV + 1, max_pos = 0;
21347 ptrdiff_t min_bpos UNINIT, max_bpos UNINIT;
21348 bool pending_handle_line_prefix = false;
21349 int header_line = window_wants_header_line (it->w);
21350 bool hscroll_this_line = (cursor_vpos >= 0
21351 && it->vpos == cursor_vpos - header_line
21352 && hscrolling_current_line_p (it->w));
21353 int first_visible_x = it->first_visible_x;
21354 int last_visible_x = it->last_visible_x;
21355 int x_incr = 0;
21357 /* We always start displaying at hpos zero even if hscrolled. */
21358 eassert (it->hpos == 0 && it->current_x == 0);
21360 if (MATRIX_ROW_VPOS (row, it->w->desired_matrix)
21361 >= it->w->desired_matrix->nrows)
21363 it->w->nrows_scale_factor++;
21364 it->f->fonts_changed = true;
21365 return false;
21368 /* Clear the result glyph row and enable it. */
21369 prepare_desired_row (it->w, row, false);
21371 row->y = it->current_y;
21372 row->start = it->start;
21373 row->continuation_lines_width = it->continuation_lines_width;
21374 row->displays_text_p = true;
21375 row->starts_in_middle_of_char_p = it->starts_in_middle_of_char_p;
21376 it->starts_in_middle_of_char_p = false;
21377 it->tab_offset = 0;
21378 it->line_number_produced_p = false;
21380 /* Arrange the overlays nicely for our purposes. Usually, we call
21381 display_line on only one line at a time, in which case this
21382 can't really hurt too much, or we call it on lines which appear
21383 one after another in the buffer, in which case all calls to
21384 recenter_overlay_lists but the first will be pretty cheap. */
21385 recenter_overlay_lists (current_buffer, IT_CHARPOS (*it));
21387 /* If we are going to display the cursor's line, account for the
21388 hscroll of that line. We subtract the window's min_hscroll,
21389 because that was already accounted for in init_iterator. */
21390 if (hscroll_this_line)
21391 x_incr =
21392 (window_hscroll_limited (it->w, it->f) - it->w->min_hscroll)
21393 * FRAME_COLUMN_WIDTH (it->f);
21395 bool line_number_needed = should_produce_line_number (it);
21397 /* Move over display elements that are not visible because we are
21398 hscrolled. This may stop at an x-position < first_visible_x
21399 if the first glyph is partially visible or if we hit a line end. */
21400 if (it->current_x < it->first_visible_x + x_incr)
21402 enum move_it_result move_result;
21404 this_line_min_pos = row->start.pos;
21405 if (hscroll_this_line)
21407 it->first_visible_x += x_incr;
21408 it->last_visible_x += x_incr;
21410 move_result = move_it_in_display_line_to (it, ZV, it->first_visible_x,
21411 MOVE_TO_POS | MOVE_TO_X);
21412 /* If we are under a large hscroll, move_it_in_display_line_to
21413 could hit the end of the line without reaching
21414 first_visible_x. Pretend that we did reach it. This is
21415 especially important on a TTY, where we will call
21416 extend_face_to_end_of_line, which needs to know how many
21417 blank glyphs to produce. */
21418 if (it->current_x < it->first_visible_x
21419 && (move_result == MOVE_NEWLINE_OR_CR
21420 || move_result == MOVE_POS_MATCH_OR_ZV))
21421 it->current_x = it->first_visible_x;
21423 /* In case move_it_in_display_line_to above "produced" the line
21424 number. */
21425 it->line_number_produced_p = false;
21427 /* Record the smallest positions seen while we moved over
21428 display elements that are not visible. This is needed by
21429 redisplay_internal for optimizing the case where the cursor
21430 stays inside the same line. The rest of this function only
21431 considers positions that are actually displayed, so
21432 RECORD_MAX_MIN_POS will not otherwise record positions that
21433 are hscrolled to the left of the left edge of the window. */
21434 min_pos = CHARPOS (this_line_min_pos);
21435 min_bpos = BYTEPOS (this_line_min_pos);
21437 /* Produce line number, if needed. */
21438 if (line_number_needed)
21439 maybe_produce_line_number (it);
21441 else if (it->area == TEXT_AREA)
21443 /* Line numbers should precede the line-prefix or wrap-prefix. */
21444 if (line_number_needed)
21445 maybe_produce_line_number (it);
21447 /* We only do this when not calling move_it_in_display_line_to
21448 above, because that function calls itself handle_line_prefix. */
21449 handle_line_prefix (it);
21451 else
21453 /* Line-prefix and wrap-prefix are always displayed in the text
21454 area. But if this is the first call to display_line after
21455 init_iterator, the iterator might have been set up to write
21456 into a marginal area, e.g. if the line begins with some
21457 display property that writes to the margins. So we need to
21458 wait with the call to handle_line_prefix until whatever
21459 writes to the margin has done its job. */
21460 pending_handle_line_prefix = true;
21463 /* Get the initial row height. This is either the height of the
21464 text hscrolled, if there is any, or zero. */
21465 row->ascent = it->max_ascent;
21466 row->height = it->max_ascent + it->max_descent;
21467 row->phys_ascent = it->max_phys_ascent;
21468 row->phys_height = it->max_phys_ascent + it->max_phys_descent;
21469 row->extra_line_spacing = it->max_extra_line_spacing;
21471 /* Utility macro to record max and min buffer positions seen until now. */
21472 #define RECORD_MAX_MIN_POS(IT) \
21473 do \
21475 bool composition_p \
21476 = !STRINGP ((IT)->string) && ((IT)->what == IT_COMPOSITION); \
21477 ptrdiff_t current_pos = \
21478 composition_p ? (IT)->cmp_it.charpos \
21479 : IT_CHARPOS (*(IT)); \
21480 ptrdiff_t current_bpos = \
21481 composition_p ? CHAR_TO_BYTE (current_pos) \
21482 : IT_BYTEPOS (*(IT)); \
21483 if (current_pos < min_pos) \
21485 min_pos = current_pos; \
21486 min_bpos = current_bpos; \
21488 if (IT_CHARPOS (*it) > max_pos) \
21490 max_pos = IT_CHARPOS (*it); \
21491 max_bpos = IT_BYTEPOS (*it); \
21494 while (false)
21496 /* Loop generating characters. The loop is left with IT on the next
21497 character to display. */
21498 while (true)
21500 int n_glyphs_before, hpos_before, x_before;
21501 int x, nglyphs;
21502 int ascent = 0, descent = 0, phys_ascent = 0, phys_descent = 0;
21504 /* Retrieve the next thing to display. Value is false if end of
21505 buffer reached. */
21506 if (!get_next_display_element (it))
21508 bool row_has_glyphs = false;
21509 /* Maybe add a space at the end of this line that is used to
21510 display the cursor there under X. Set the charpos of the
21511 first glyph of blank lines not corresponding to any text
21512 to -1. */
21513 if (IT_OVERFLOW_NEWLINE_INTO_FRINGE (it))
21514 row->exact_window_width_line_p = true;
21515 else if ((append_space_for_newline (it, true)
21516 && row->used[TEXT_AREA] == 1)
21517 || row->used[TEXT_AREA] == 0
21518 || (row_has_glyphs = row_text_area_empty (row)))
21520 row->glyphs[TEXT_AREA]->charpos = -1;
21521 /* Don't reset the displays_text_p flag if we are
21522 displaying line numbers or line-prefix. */
21523 if (!row_has_glyphs)
21524 row->displays_text_p = false;
21526 if (!NILP (BVAR (XBUFFER (it->w->contents), indicate_empty_lines))
21527 && (!MINI_WINDOW_P (it->w)))
21528 row->indicate_empty_line_p = true;
21531 it->continuation_lines_width = 0;
21532 /* Reset those iterator values set from display property
21533 values. This is for the case when the display property
21534 ends at ZV, and is not a replacing property, so pop_it is
21535 not called. */
21536 it->font_height = Qnil;
21537 it->voffset = 0;
21538 row->ends_at_zv_p = true;
21539 /* A row that displays right-to-left text must always have
21540 its last face extended all the way to the end of line,
21541 even if this row ends in ZV, because we still write to
21542 the screen left to right. We also need to extend the
21543 last face if the default face is remapped to some
21544 different face, otherwise the functions that clear
21545 portions of the screen will clear with the default face's
21546 background color. */
21547 if (row->reversed_p
21548 || lookup_basic_face (it->f, DEFAULT_FACE_ID) != DEFAULT_FACE_ID)
21549 extend_face_to_end_of_line (it);
21550 break;
21553 /* Now, get the metrics of what we want to display. This also
21554 generates glyphs in `row' (which is IT->glyph_row). */
21555 n_glyphs_before = row->used[TEXT_AREA];
21556 x = it->current_x;
21558 /* Remember the line height so far in case the next element doesn't
21559 fit on the line. */
21560 if (it->line_wrap != TRUNCATE)
21562 ascent = it->max_ascent;
21563 descent = it->max_descent;
21564 phys_ascent = it->max_phys_ascent;
21565 phys_descent = it->max_phys_descent;
21567 if (it->line_wrap == WORD_WRAP && it->area == TEXT_AREA)
21569 if (IT_DISPLAYING_WHITESPACE (it))
21570 may_wrap = true;
21571 else if (may_wrap)
21573 SAVE_IT (wrap_it, *it, wrap_data);
21574 wrap_x = x;
21575 wrap_row_used = row->used[TEXT_AREA];
21576 wrap_row_ascent = row->ascent;
21577 wrap_row_height = row->height;
21578 wrap_row_phys_ascent = row->phys_ascent;
21579 wrap_row_phys_height = row->phys_height;
21580 wrap_row_extra_line_spacing = row->extra_line_spacing;
21581 wrap_row_min_pos = min_pos;
21582 wrap_row_min_bpos = min_bpos;
21583 wrap_row_max_pos = max_pos;
21584 wrap_row_max_bpos = max_bpos;
21585 may_wrap = false;
21590 PRODUCE_GLYPHS (it);
21592 /* If this display element was in marginal areas, continue with
21593 the next one. */
21594 if (it->area != TEXT_AREA)
21596 row->ascent = max (row->ascent, it->max_ascent);
21597 row->height = max (row->height, it->max_ascent + it->max_descent);
21598 row->phys_ascent = max (row->phys_ascent, it->max_phys_ascent);
21599 row->phys_height = max (row->phys_height,
21600 it->max_phys_ascent + it->max_phys_descent);
21601 row->extra_line_spacing = max (row->extra_line_spacing,
21602 it->max_extra_line_spacing);
21603 set_iterator_to_next (it, true);
21604 /* If we didn't handle the line/wrap prefix above, and the
21605 call to set_iterator_to_next just switched to TEXT_AREA,
21606 process the prefix now. */
21607 if (it->area == TEXT_AREA && pending_handle_line_prefix)
21609 /* Line numbers should precede the line-prefix or wrap-prefix. */
21610 if (line_number_needed)
21611 maybe_produce_line_number (it);
21613 pending_handle_line_prefix = false;
21614 handle_line_prefix (it);
21616 continue;
21619 /* Does the display element fit on the line? If we truncate
21620 lines, we should draw past the right edge of the window. If
21621 we don't truncate, we want to stop so that we can display the
21622 continuation glyph before the right margin. If lines are
21623 continued, there are two possible strategies for characters
21624 resulting in more than 1 glyph (e.g. tabs): Display as many
21625 glyphs as possible in this line and leave the rest for the
21626 continuation line, or display the whole element in the next
21627 line. Original redisplay did the former, so we do it also. */
21628 nglyphs = row->used[TEXT_AREA] - n_glyphs_before;
21629 hpos_before = it->hpos;
21630 x_before = x;
21632 if (/* Not a newline. */
21633 nglyphs > 0
21634 /* Glyphs produced fit entirely in the line. */
21635 && it->current_x < it->last_visible_x)
21637 it->hpos += nglyphs;
21638 row->ascent = max (row->ascent, it->max_ascent);
21639 row->height = max (row->height, it->max_ascent + it->max_descent);
21640 row->phys_ascent = max (row->phys_ascent, it->max_phys_ascent);
21641 row->phys_height = max (row->phys_height,
21642 it->max_phys_ascent + it->max_phys_descent);
21643 row->extra_line_spacing = max (row->extra_line_spacing,
21644 it->max_extra_line_spacing);
21645 if (it->current_x - it->pixel_width < it->first_visible_x
21646 /* When line numbers are displayed, row->x should not be
21647 offset, as the first glyph after the line number can
21648 never be partially visible. */
21649 && !line_number_needed
21650 /* In R2L rows, we arrange in extend_face_to_end_of_line
21651 to add a right offset to the line, by a suitable
21652 change to the stretch glyph that is the leftmost
21653 glyph of the line. */
21654 && !row->reversed_p)
21655 row->x = x - it->first_visible_x;
21656 /* Record the maximum and minimum buffer positions seen so
21657 far in glyphs that will be displayed by this row. */
21658 if (it->bidi_p)
21659 RECORD_MAX_MIN_POS (it);
21661 else
21663 int i, new_x;
21664 struct glyph *glyph;
21666 for (i = 0; i < nglyphs; ++i, x = new_x)
21668 /* Identify the glyphs added by the last call to
21669 PRODUCE_GLYPHS. In R2L rows, they are prepended to
21670 the previous glyphs. */
21671 if (!row->reversed_p)
21672 glyph = row->glyphs[TEXT_AREA] + n_glyphs_before + i;
21673 else
21674 glyph = row->glyphs[TEXT_AREA] + nglyphs - 1 - i;
21675 new_x = x + glyph->pixel_width;
21677 if (/* Lines are continued. */
21678 it->line_wrap != TRUNCATE
21679 && (/* Glyph doesn't fit on the line. */
21680 new_x > it->last_visible_x
21681 /* Or it fits exactly on a window system frame. */
21682 || (new_x == it->last_visible_x
21683 && FRAME_WINDOW_P (it->f)
21684 && (row->reversed_p
21685 ? WINDOW_LEFT_FRINGE_WIDTH (it->w)
21686 : WINDOW_RIGHT_FRINGE_WIDTH (it->w)))))
21688 /* End of a continued line. */
21690 if (it->hpos == 0
21691 || (new_x == it->last_visible_x
21692 && FRAME_WINDOW_P (it->f)
21693 && (row->reversed_p
21694 ? WINDOW_LEFT_FRINGE_WIDTH (it->w)
21695 : WINDOW_RIGHT_FRINGE_WIDTH (it->w))))
21697 /* Current glyph is the only one on the line or
21698 fits exactly on the line. We must continue
21699 the line because we can't draw the cursor
21700 after the glyph. */
21701 row->continued_p = true;
21702 it->current_x = new_x;
21703 it->continuation_lines_width += new_x;
21704 ++it->hpos;
21705 if (i == nglyphs - 1)
21707 /* If line-wrap is on, check if a previous
21708 wrap point was found. */
21709 if (!IT_OVERFLOW_NEWLINE_INTO_FRINGE (it)
21710 && wrap_row_used > 0
21711 /* Even if there is a previous wrap
21712 point, continue the line here as
21713 usual, if (i) the previous character
21714 was a space or tab AND (ii) the
21715 current character is not. */
21716 && (!may_wrap
21717 || IT_DISPLAYING_WHITESPACE (it)))
21718 goto back_to_wrap;
21720 /* Record the maximum and minimum buffer
21721 positions seen so far in glyphs that will be
21722 displayed by this row. */
21723 if (it->bidi_p)
21724 RECORD_MAX_MIN_POS (it);
21725 set_iterator_to_next (it, true);
21726 if (IT_OVERFLOW_NEWLINE_INTO_FRINGE (it))
21728 if (!get_next_display_element (it))
21730 row->exact_window_width_line_p = true;
21731 it->continuation_lines_width = 0;
21732 it->font_height = Qnil;
21733 it->voffset = 0;
21734 row->continued_p = false;
21735 row->ends_at_zv_p = true;
21737 else if (ITERATOR_AT_END_OF_LINE_P (it))
21739 row->continued_p = false;
21740 row->exact_window_width_line_p = true;
21742 /* If line-wrap is on, check if a
21743 previous wrap point was found. */
21744 else if (wrap_row_used > 0
21745 /* Even if there is a previous wrap
21746 point, continue the line here as
21747 usual, if (i) the previous character
21748 was a space or tab AND (ii) the
21749 current character is not. */
21750 && (!may_wrap
21751 || IT_DISPLAYING_WHITESPACE (it)))
21752 goto back_to_wrap;
21756 else if (it->bidi_p)
21757 RECORD_MAX_MIN_POS (it);
21758 if (WINDOW_LEFT_MARGIN_WIDTH (it->w) > 0
21759 || WINDOW_RIGHT_MARGIN_WIDTH (it->w) > 0)
21760 extend_face_to_end_of_line (it);
21762 else if (CHAR_GLYPH_PADDING_P (*glyph)
21763 && !FRAME_WINDOW_P (it->f))
21765 /* A padding glyph that doesn't fit on this line.
21766 This means the whole character doesn't fit
21767 on the line. */
21768 if (row->reversed_p)
21769 unproduce_glyphs (it, row->used[TEXT_AREA]
21770 - n_glyphs_before);
21771 row->used[TEXT_AREA] = n_glyphs_before;
21773 /* Fill the rest of the row with continuation
21774 glyphs like in 20.x. */
21775 while (row->glyphs[TEXT_AREA] + row->used[TEXT_AREA]
21776 < row->glyphs[1 + TEXT_AREA])
21777 produce_special_glyphs (it, IT_CONTINUATION);
21779 row->continued_p = true;
21780 it->current_x = x_before;
21781 it->continuation_lines_width += x_before;
21783 /* Restore the height to what it was before the
21784 element not fitting on the line. */
21785 it->max_ascent = ascent;
21786 it->max_descent = descent;
21787 it->max_phys_ascent = phys_ascent;
21788 it->max_phys_descent = phys_descent;
21789 if (WINDOW_LEFT_MARGIN_WIDTH (it->w) > 0
21790 || WINDOW_RIGHT_MARGIN_WIDTH (it->w) > 0)
21791 extend_face_to_end_of_line (it);
21793 else if (wrap_row_used > 0)
21795 back_to_wrap:
21796 if (row->reversed_p)
21797 unproduce_glyphs (it,
21798 row->used[TEXT_AREA] - wrap_row_used);
21799 RESTORE_IT (it, &wrap_it, wrap_data);
21800 it->continuation_lines_width += wrap_x;
21801 row->used[TEXT_AREA] = wrap_row_used;
21802 row->ascent = wrap_row_ascent;
21803 row->height = wrap_row_height;
21804 row->phys_ascent = wrap_row_phys_ascent;
21805 row->phys_height = wrap_row_phys_height;
21806 row->extra_line_spacing = wrap_row_extra_line_spacing;
21807 min_pos = wrap_row_min_pos;
21808 min_bpos = wrap_row_min_bpos;
21809 max_pos = wrap_row_max_pos;
21810 max_bpos = wrap_row_max_bpos;
21811 row->continued_p = true;
21812 row->ends_at_zv_p = false;
21813 row->exact_window_width_line_p = false;
21815 /* Make sure that a non-default face is extended
21816 up to the right margin of the window. */
21817 extend_face_to_end_of_line (it);
21819 else if ((it->what == IT_CHARACTER
21820 || it->what == IT_STRETCH
21821 || it->what == IT_COMPOSITION)
21822 && it->c == '\t' && FRAME_WINDOW_P (it->f))
21824 /* A TAB that extends past the right edge of the
21825 window. This produces a single glyph on
21826 window system frames. We leave the glyph in
21827 this row and let it fill the row, but don't
21828 consume the TAB. */
21829 if ((row->reversed_p
21830 ? WINDOW_LEFT_FRINGE_WIDTH (it->w)
21831 : WINDOW_RIGHT_FRINGE_WIDTH (it->w)) == 0)
21832 produce_special_glyphs (it, IT_CONTINUATION);
21833 it->continuation_lines_width += it->last_visible_x;
21834 row->ends_in_middle_of_char_p = true;
21835 row->continued_p = true;
21836 glyph->pixel_width = it->last_visible_x - x;
21837 it->starts_in_middle_of_char_p = true;
21838 if (WINDOW_LEFT_MARGIN_WIDTH (it->w) > 0
21839 || WINDOW_RIGHT_MARGIN_WIDTH (it->w) > 0)
21840 extend_face_to_end_of_line (it);
21842 else
21844 /* Something other than a TAB that draws past
21845 the right edge of the window. Restore
21846 positions to values before the element. */
21847 if (row->reversed_p)
21848 unproduce_glyphs (it, row->used[TEXT_AREA]
21849 - (n_glyphs_before + i));
21850 row->used[TEXT_AREA] = n_glyphs_before + i;
21852 /* Display continuation glyphs. */
21853 it->current_x = x_before;
21854 it->continuation_lines_width += x;
21855 if (!FRAME_WINDOW_P (it->f)
21856 || (row->reversed_p
21857 ? WINDOW_LEFT_FRINGE_WIDTH (it->w)
21858 : WINDOW_RIGHT_FRINGE_WIDTH (it->w)) == 0)
21859 produce_special_glyphs (it, IT_CONTINUATION);
21860 row->continued_p = true;
21862 extend_face_to_end_of_line (it);
21864 if (nglyphs > 1 && i > 0)
21866 row->ends_in_middle_of_char_p = true;
21867 it->starts_in_middle_of_char_p = true;
21870 /* Restore the height to what it was before the
21871 element not fitting on the line. */
21872 it->max_ascent = ascent;
21873 it->max_descent = descent;
21874 it->max_phys_ascent = phys_ascent;
21875 it->max_phys_descent = phys_descent;
21878 break;
21880 else if (new_x > it->first_visible_x)
21882 /* Increment number of glyphs actually displayed. */
21883 ++it->hpos;
21885 /* Record the maximum and minimum buffer positions
21886 seen so far in glyphs that will be displayed by
21887 this row. */
21888 if (it->bidi_p)
21889 RECORD_MAX_MIN_POS (it);
21891 if (x < it->first_visible_x && !row->reversed_p
21892 && !line_number_needed)
21893 /* Glyph is partially visible, i.e. row starts at
21894 negative X position. Don't do that in R2L
21895 rows, where we arrange to add a right offset to
21896 the line in extend_face_to_end_of_line, by a
21897 suitable change to the stretch glyph that is
21898 the leftmost glyph of the line. */
21899 row->x = x - it->first_visible_x;
21900 /* When the last glyph of an R2L row only fits
21901 partially on the line, we need to set row->x to a
21902 negative offset, so that the leftmost glyph is
21903 the one that is partially visible. But if we are
21904 going to produce the truncation glyph, this will
21905 be taken care of in produce_special_glyphs. */
21906 if (row->reversed_p
21907 && new_x > it->last_visible_x
21908 && !line_number_needed
21909 && !(it->line_wrap == TRUNCATE
21910 && WINDOW_LEFT_FRINGE_WIDTH (it->w) == 0))
21912 eassert (FRAME_WINDOW_P (it->f));
21913 row->x = it->last_visible_x - new_x;
21916 else
21918 /* Glyph is completely off the left margin of the
21919 window. This should not happen because of the
21920 move_it_in_display_line at the start of this
21921 function, unless the text display area of the
21922 window is empty. */
21923 eassert (it->first_visible_x <= it->last_visible_x);
21926 /* Even if this display element produced no glyphs at all,
21927 we want to record its position. */
21928 if (it->bidi_p && nglyphs == 0)
21929 RECORD_MAX_MIN_POS (it);
21931 row->ascent = max (row->ascent, it->max_ascent);
21932 row->height = max (row->height, it->max_ascent + it->max_descent);
21933 row->phys_ascent = max (row->phys_ascent, it->max_phys_ascent);
21934 row->phys_height = max (row->phys_height,
21935 it->max_phys_ascent + it->max_phys_descent);
21936 row->extra_line_spacing = max (row->extra_line_spacing,
21937 it->max_extra_line_spacing);
21939 /* End of this display line if row is continued. */
21940 if (row->continued_p || row->ends_at_zv_p)
21941 break;
21944 at_end_of_line:
21945 /* Is this a line end? If yes, we're also done, after making
21946 sure that a non-default face is extended up to the right
21947 margin of the window. */
21948 if (ITERATOR_AT_END_OF_LINE_P (it))
21950 int used_before = row->used[TEXT_AREA];
21952 row->ends_in_newline_from_string_p = STRINGP (it->object);
21954 /* Add a space at the end of the line that is used to
21955 display the cursor there. */
21956 if (!IT_OVERFLOW_NEWLINE_INTO_FRINGE (it))
21957 append_space_for_newline (it, false);
21959 /* Extend the face to the end of the line. */
21960 extend_face_to_end_of_line (it);
21962 /* Make sure we have the position. */
21963 if (used_before == 0)
21964 row->glyphs[TEXT_AREA]->charpos = CHARPOS (it->position);
21966 /* Record the position of the newline, for use in
21967 find_row_edges. */
21968 it->eol_pos = it->current.pos;
21970 /* Consume the line end. This skips over invisible lines. */
21971 set_iterator_to_next (it, true);
21972 it->continuation_lines_width = 0;
21973 break;
21976 /* Detect overly-wide wrap-prefixes made of (space ...) display
21977 properties. When such a wrap prefix reaches past the right
21978 margin of the window, we need to avoid the call to
21979 set_iterator_to_next below, so that it->line_wrap is left at
21980 its TRUNCATE value wisely set by handle_line_prefix.
21981 Otherwise, set_iterator_to_next will pop the iterator stack,
21982 restore it->line_wrap, and redisplay might infloop. */
21983 bool overwide_wrap_prefix =
21984 CONSP (it->object) && EQ (XCAR (it->object), Qspace)
21985 && it->sp > 0 && it->method == GET_FROM_STRETCH
21986 && it->current_x >= it->last_visible_x
21987 && it->continuation_lines_width > 0
21988 && it->line_wrap == TRUNCATE && it->stack[0].line_wrap != TRUNCATE;
21990 /* Proceed with next display element. Note that this skips
21991 over lines invisible because of selective display. */
21992 if (!overwide_wrap_prefix)
21993 set_iterator_to_next (it, true);
21995 /* If we truncate lines, we are done when the last displayed
21996 glyphs reach past the right margin of the window. */
21997 if (it->line_wrap == TRUNCATE
21998 && ((FRAME_WINDOW_P (it->f)
21999 /* Images are preprocessed in produce_image_glyph such
22000 that they are cropped at the right edge of the
22001 window, so an image glyph will always end exactly at
22002 last_visible_x, even if there's no right fringe. */
22003 && ((row->reversed_p
22004 ? WINDOW_LEFT_FRINGE_WIDTH (it->w)
22005 : WINDOW_RIGHT_FRINGE_WIDTH (it->w))
22006 || it->what == IT_IMAGE))
22007 ? (it->current_x >= it->last_visible_x)
22008 : (it->current_x > it->last_visible_x)))
22010 /* Maybe add truncation glyphs. */
22011 if (!FRAME_WINDOW_P (it->f)
22012 || (row->reversed_p
22013 ? WINDOW_LEFT_FRINGE_WIDTH (it->w)
22014 : WINDOW_RIGHT_FRINGE_WIDTH (it->w)) == 0)
22016 int i, n;
22018 if (!row->reversed_p)
22020 for (i = row->used[TEXT_AREA] - 1; i > 0; --i)
22021 if (!CHAR_GLYPH_PADDING_P (row->glyphs[TEXT_AREA][i]))
22022 break;
22024 else
22026 for (i = 0; i < row->used[TEXT_AREA]; i++)
22027 if (!CHAR_GLYPH_PADDING_P (row->glyphs[TEXT_AREA][i]))
22028 break;
22029 /* Remove any padding glyphs at the front of ROW, to
22030 make room for the truncation glyphs we will be
22031 adding below. The loop below always inserts at
22032 least one truncation glyph, so also remove the
22033 last glyph added to ROW. */
22034 unproduce_glyphs (it, i + 1);
22035 /* Adjust i for the loop below. */
22036 i = row->used[TEXT_AREA] - (i + 1);
22039 /* produce_special_glyphs overwrites the last glyph, so
22040 we don't want that if we want to keep that last
22041 glyph, which means it's an image. */
22042 if (it->current_x > it->last_visible_x)
22044 it->current_x = x_before;
22045 if (!FRAME_WINDOW_P (it->f))
22047 for (n = row->used[TEXT_AREA]; i < n; ++i)
22049 row->used[TEXT_AREA] = i;
22050 produce_special_glyphs (it, IT_TRUNCATION);
22053 else
22055 row->used[TEXT_AREA] = i;
22056 produce_special_glyphs (it, IT_TRUNCATION);
22058 it->hpos = hpos_before;
22061 else if (IT_OVERFLOW_NEWLINE_INTO_FRINGE (it))
22063 /* Don't truncate if we can overflow newline into fringe. */
22064 if (!get_next_display_element (it))
22066 it->continuation_lines_width = 0;
22067 it->font_height = Qnil;
22068 it->voffset = 0;
22069 row->ends_at_zv_p = true;
22070 row->exact_window_width_line_p = true;
22071 break;
22073 if (ITERATOR_AT_END_OF_LINE_P (it))
22075 row->exact_window_width_line_p = true;
22076 goto at_end_of_line;
22078 it->current_x = x_before;
22079 it->hpos = hpos_before;
22082 row->truncated_on_right_p = true;
22083 it->continuation_lines_width = 0;
22084 reseat_at_next_visible_line_start (it, false);
22085 /* We insist below that IT's position be at ZV because in
22086 bidi-reordered lines the character at visible line start
22087 might not be the character that follows the newline in
22088 the logical order. */
22089 if (IT_BYTEPOS (*it) > BEG_BYTE)
22090 row->ends_at_zv_p =
22091 IT_BYTEPOS (*it) >= ZV_BYTE && FETCH_BYTE (ZV_BYTE - 1) != '\n';
22092 else
22093 row->ends_at_zv_p = false;
22094 break;
22098 if (wrap_data)
22099 bidi_unshelve_cache (wrap_data, true);
22101 /* If line is not empty and hscrolled, maybe insert truncation glyphs
22102 at the left window margin. */
22103 if (it->first_visible_x
22104 && IT_CHARPOS (*it) != CHARPOS (row->start.pos))
22106 if (!FRAME_WINDOW_P (it->f)
22107 || (((row->reversed_p
22108 ? WINDOW_RIGHT_FRINGE_WIDTH (it->w)
22109 : WINDOW_LEFT_FRINGE_WIDTH (it->w)) == 0)
22110 /* Don't let insert_left_trunc_glyphs overwrite the
22111 first glyph of the row if it is an image. */
22112 && row->glyphs[TEXT_AREA]->type != IMAGE_GLYPH))
22113 insert_left_trunc_glyphs (it);
22114 row->truncated_on_left_p = true;
22117 /* Remember the position at which this line ends.
22119 BIDI Note: any code that needs MATRIX_ROW_START/END_CHARPOS
22120 cannot be before the call to find_row_edges below, since that is
22121 where these positions are determined. */
22122 row->end = it->current;
22123 if (!it->bidi_p)
22125 row->minpos = row->start.pos;
22126 row->maxpos = row->end.pos;
22128 else
22130 /* ROW->minpos and ROW->maxpos must be the smallest and
22131 `1 + the largest' buffer positions in ROW. But if ROW was
22132 bidi-reordered, these two positions can be anywhere in the
22133 row, so we must determine them now. */
22134 find_row_edges (it, row, min_pos, min_bpos, max_pos, max_bpos);
22137 /* If the start of this line is the overlay arrow-position, then
22138 mark this glyph row as the one containing the overlay arrow.
22139 This is clearly a mess with variable size fonts. It would be
22140 better to let it be displayed like cursors under X. */
22141 if ((MATRIX_ROW_DISPLAYS_TEXT_P (row) || !overlay_arrow_seen)
22142 && (overlay_arrow_string = overlay_arrow_at_row (it, row),
22143 !NILP (overlay_arrow_string)))
22145 /* Overlay arrow in window redisplay is a fringe bitmap. */
22146 if (STRINGP (overlay_arrow_string))
22148 struct glyph_row *arrow_row
22149 = get_overlay_arrow_glyph_row (it->w, overlay_arrow_string);
22150 struct glyph *glyph = arrow_row->glyphs[TEXT_AREA];
22151 struct glyph *arrow_end = glyph + arrow_row->used[TEXT_AREA];
22152 struct glyph *p = row->glyphs[TEXT_AREA];
22153 struct glyph *p2, *end;
22155 /* Copy the arrow glyphs. */
22156 while (glyph < arrow_end)
22157 *p++ = *glyph++;
22159 /* Throw away padding glyphs. */
22160 p2 = p;
22161 end = row->glyphs[TEXT_AREA] + row->used[TEXT_AREA];
22162 while (p2 < end && CHAR_GLYPH_PADDING_P (*p2))
22163 ++p2;
22164 if (p2 > p)
22166 while (p2 < end)
22167 *p++ = *p2++;
22168 row->used[TEXT_AREA] = p2 - row->glyphs[TEXT_AREA];
22171 else
22173 eassert (INTEGERP (overlay_arrow_string));
22174 row->overlay_arrow_bitmap = XINT (overlay_arrow_string);
22176 overlay_arrow_seen = true;
22179 /* Highlight trailing whitespace. */
22180 if (!NILP (Vshow_trailing_whitespace))
22181 highlight_trailing_whitespace (it->f, it->glyph_row);
22183 /* Compute pixel dimensions of this line. */
22184 compute_line_metrics (it);
22186 /* Implementation note: No changes in the glyphs of ROW or in their
22187 faces can be done past this point, because compute_line_metrics
22188 computes ROW's hash value and stores it within the glyph_row
22189 structure. */
22191 /* Record whether this row ends inside an ellipsis. */
22192 row->ends_in_ellipsis_p
22193 = (it->method == GET_FROM_DISPLAY_VECTOR
22194 && it->ellipsis_p);
22196 /* Save fringe bitmaps in this row. */
22197 row->left_user_fringe_bitmap = it->left_user_fringe_bitmap;
22198 row->left_user_fringe_face_id = it->left_user_fringe_face_id;
22199 row->right_user_fringe_bitmap = it->right_user_fringe_bitmap;
22200 row->right_user_fringe_face_id = it->right_user_fringe_face_id;
22202 it->left_user_fringe_bitmap = 0;
22203 it->left_user_fringe_face_id = 0;
22204 it->right_user_fringe_bitmap = 0;
22205 it->right_user_fringe_face_id = 0;
22207 /* Maybe set the cursor. */
22208 cvpos = it->w->cursor.vpos;
22209 if ((cvpos < 0
22210 /* In bidi-reordered rows, keep checking for proper cursor
22211 position even if one has been found already, because buffer
22212 positions in such rows change non-linearly with ROW->VPOS,
22213 when a line is continued. One exception: when we are at ZV,
22214 display cursor on the first suitable glyph row, since all
22215 the empty rows after that also have their position set to ZV. */
22216 /* FIXME: Revisit this when glyph ``spilling'' in continuation
22217 lines' rows is implemented for bidi-reordered rows. */
22218 || (it->bidi_p
22219 && !MATRIX_ROW (it->w->desired_matrix, cvpos)->ends_at_zv_p))
22220 && PT >= MATRIX_ROW_START_CHARPOS (row)
22221 && PT <= MATRIX_ROW_END_CHARPOS (row)
22222 && cursor_row_p (row))
22223 set_cursor_from_row (it->w, row, it->w->desired_matrix, 0, 0, 0, 0);
22225 /* Prepare for the next line. This line starts horizontally at (X
22226 HPOS) = (0 0). Vertical positions are incremented. As a
22227 convenience for the caller, IT->glyph_row is set to the next
22228 row to be used. */
22229 it->current_x = it->hpos = 0;
22230 it->current_y += row->height;
22231 /* Restore the first and last visible X if we adjusted them for
22232 current-line hscrolling. */
22233 if (hscroll_this_line)
22235 it->first_visible_x = first_visible_x;
22236 it->last_visible_x = last_visible_x;
22238 SET_TEXT_POS (it->eol_pos, 0, 0);
22239 ++it->vpos;
22240 ++it->glyph_row;
22241 /* The next row should by default use the same value of the
22242 reversed_p flag as this one. set_iterator_to_next decides when
22243 it's a new paragraph, and PRODUCE_GLYPHS recomputes the value of
22244 the flag accordingly. */
22245 if (it->glyph_row < MATRIX_BOTTOM_TEXT_ROW (it->w->desired_matrix, it->w))
22246 it->glyph_row->reversed_p = row->reversed_p;
22247 it->start = row->end;
22248 return MATRIX_ROW_DISPLAYS_TEXT_P (row);
22250 #undef RECORD_MAX_MIN_POS
22253 DEFUN ("current-bidi-paragraph-direction", Fcurrent_bidi_paragraph_direction,
22254 Scurrent_bidi_paragraph_direction, 0, 1, 0,
22255 doc: /* Return paragraph direction at point in BUFFER.
22256 Value is either `left-to-right' or `right-to-left'.
22257 If BUFFER is omitted or nil, it defaults to the current buffer.
22259 Paragraph direction determines how the text in the paragraph is displayed.
22260 In left-to-right paragraphs, text begins at the left margin of the window
22261 and the reading direction is generally left to right. In right-to-left
22262 paragraphs, text begins at the right margin and is read from right to left.
22264 See also `bidi-paragraph-direction'. */)
22265 (Lisp_Object buffer)
22267 struct buffer *buf = current_buffer;
22268 struct buffer *old = buf;
22270 if (! NILP (buffer))
22272 CHECK_BUFFER (buffer);
22273 buf = XBUFFER (buffer);
22276 if (NILP (BVAR (buf, bidi_display_reordering))
22277 || NILP (BVAR (buf, enable_multibyte_characters))
22278 /* When we are loading loadup.el, the character property tables
22279 needed for bidi iteration are not yet available. */
22280 || redisplay__inhibit_bidi)
22281 return Qleft_to_right;
22282 else if (!NILP (BVAR (buf, bidi_paragraph_direction)))
22283 return BVAR (buf, bidi_paragraph_direction);
22284 else
22286 /* Determine the direction from buffer text. We could try to
22287 use current_matrix if it is up to date, but this seems fast
22288 enough as it is. */
22289 struct bidi_it itb;
22290 ptrdiff_t pos = BUF_PT (buf);
22291 ptrdiff_t bytepos = BUF_PT_BYTE (buf);
22292 int c;
22293 void *itb_data = bidi_shelve_cache ();
22295 set_buffer_temp (buf);
22296 /* bidi_paragraph_init finds the base direction of the paragraph
22297 by searching forward from paragraph start. We need the base
22298 direction of the current or _previous_ paragraph, so we need
22299 to make sure we are within that paragraph. To that end, find
22300 the previous non-empty line. */
22301 if (pos >= ZV && pos > BEGV)
22302 DEC_BOTH (pos, bytepos);
22303 AUTO_STRING (trailing_white_space, "[\f\t ]*\n");
22304 if (fast_looking_at (trailing_white_space,
22305 pos, bytepos, ZV, ZV_BYTE, Qnil) > 0)
22307 while ((c = FETCH_BYTE (bytepos)) == '\n'
22308 || c == ' ' || c == '\t' || c == '\f')
22310 if (bytepos <= BEGV_BYTE)
22311 break;
22312 bytepos--;
22313 pos--;
22315 while (!CHAR_HEAD_P (FETCH_BYTE (bytepos)))
22316 bytepos--;
22318 bidi_init_it (pos, bytepos, FRAME_WINDOW_P (SELECTED_FRAME ()), &itb);
22319 itb.paragraph_dir = NEUTRAL_DIR;
22320 itb.string.s = NULL;
22321 itb.string.lstring = Qnil;
22322 itb.string.bufpos = 0;
22323 itb.string.from_disp_str = false;
22324 itb.string.unibyte = false;
22325 /* We have no window to use here for ignoring window-specific
22326 overlays. Using NULL for window pointer will cause
22327 compute_display_string_pos to use the current buffer. */
22328 itb.w = NULL;
22329 bidi_paragraph_init (NEUTRAL_DIR, &itb, true);
22330 bidi_unshelve_cache (itb_data, false);
22331 set_buffer_temp (old);
22332 switch (itb.paragraph_dir)
22334 case L2R:
22335 return Qleft_to_right;
22336 break;
22337 case R2L:
22338 return Qright_to_left;
22339 break;
22340 default:
22341 emacs_abort ();
22346 DEFUN ("bidi-find-overridden-directionality",
22347 Fbidi_find_overridden_directionality,
22348 Sbidi_find_overridden_directionality, 2, 3, 0,
22349 doc: /* Return position between FROM and TO where directionality was overridden.
22351 This function returns the first character position in the specified
22352 region of OBJECT where there is a character whose `bidi-class' property
22353 is `L', but which was forced to display as `R' by a directional
22354 override, and likewise with characters whose `bidi-class' is `R'
22355 or `AL' that were forced to display as `L'.
22357 If no such character is found, the function returns nil.
22359 OBJECT is a Lisp string or buffer to search for overridden
22360 directionality, and defaults to the current buffer if nil or omitted.
22361 OBJECT can also be a window, in which case the function will search
22362 the buffer displayed in that window. Passing the window instead of
22363 a buffer is preferable when the buffer is displayed in some window,
22364 because this function will then be able to correctly account for
22365 window-specific overlays, which can affect the results.
22367 Strong directional characters `L', `R', and `AL' can have their
22368 intrinsic directionality overridden by directional override
22369 control characters RLO (u+202e) and LRO (u+202d). See the
22370 function `get-char-code-property' for a way to inquire about
22371 the `bidi-class' property of a character. */)
22372 (Lisp_Object from, Lisp_Object to, Lisp_Object object)
22374 struct buffer *buf = current_buffer;
22375 struct buffer *old = buf;
22376 struct window *w = NULL;
22377 bool frame_window_p = FRAME_WINDOW_P (SELECTED_FRAME ());
22378 struct bidi_it itb;
22379 ptrdiff_t from_pos, to_pos, from_bpos;
22380 void *itb_data;
22382 if (!NILP (object))
22384 if (BUFFERP (object))
22385 buf = XBUFFER (object);
22386 else if (WINDOWP (object))
22388 w = decode_live_window (object);
22389 buf = XBUFFER (w->contents);
22390 frame_window_p = FRAME_WINDOW_P (XFRAME (w->frame));
22392 else
22393 CHECK_STRING (object);
22396 if (STRINGP (object))
22398 /* Characters in unibyte strings are always treated by bidi.c as
22399 strong LTR. */
22400 if (!STRING_MULTIBYTE (object)
22401 /* When we are loading loadup.el, the character property
22402 tables needed for bidi iteration are not yet
22403 available. */
22404 || redisplay__inhibit_bidi)
22405 return Qnil;
22407 validate_subarray (object, from, to, SCHARS (object), &from_pos, &to_pos);
22408 if (from_pos >= SCHARS (object))
22409 return Qnil;
22411 /* Set up the bidi iterator. */
22412 itb_data = bidi_shelve_cache ();
22413 itb.paragraph_dir = NEUTRAL_DIR;
22414 itb.string.lstring = object;
22415 itb.string.s = NULL;
22416 itb.string.schars = SCHARS (object);
22417 itb.string.bufpos = 0;
22418 itb.string.from_disp_str = false;
22419 itb.string.unibyte = false;
22420 itb.w = w;
22421 bidi_init_it (0, 0, frame_window_p, &itb);
22423 else
22425 /* Nothing this fancy can happen in unibyte buffers, or in a
22426 buffer that disabled reordering, or if FROM is at EOB. */
22427 if (NILP (BVAR (buf, bidi_display_reordering))
22428 || NILP (BVAR (buf, enable_multibyte_characters))
22429 /* When we are loading loadup.el, the character property
22430 tables needed for bidi iteration are not yet
22431 available. */
22432 || redisplay__inhibit_bidi)
22433 return Qnil;
22435 set_buffer_temp (buf);
22436 validate_region (&from, &to);
22437 from_pos = XINT (from);
22438 to_pos = XINT (to);
22439 if (from_pos >= ZV)
22440 return Qnil;
22442 /* Set up the bidi iterator. */
22443 itb_data = bidi_shelve_cache ();
22444 from_bpos = CHAR_TO_BYTE (from_pos);
22445 if (from_pos == BEGV)
22447 itb.charpos = BEGV;
22448 itb.bytepos = BEGV_BYTE;
22450 else if (FETCH_CHAR (from_bpos - 1) == '\n')
22452 itb.charpos = from_pos;
22453 itb.bytepos = from_bpos;
22455 else
22456 itb.charpos = find_newline_no_quit (from_pos, CHAR_TO_BYTE (from_pos),
22457 -1, &itb.bytepos);
22458 itb.paragraph_dir = NEUTRAL_DIR;
22459 itb.string.s = NULL;
22460 itb.string.lstring = Qnil;
22461 itb.string.bufpos = 0;
22462 itb.string.from_disp_str = false;
22463 itb.string.unibyte = false;
22464 itb.w = w;
22465 bidi_init_it (itb.charpos, itb.bytepos, frame_window_p, &itb);
22468 ptrdiff_t found;
22469 do {
22470 /* For the purposes of this function, the actual base direction of
22471 the paragraph doesn't matter, so just set it to L2R. */
22472 bidi_paragraph_init (L2R, &itb, false);
22473 while ((found = bidi_find_first_overridden (&itb)) < from_pos)
22475 } while (found == ZV && itb.ch == '\n' && itb.charpos < to_pos);
22477 bidi_unshelve_cache (itb_data, false);
22478 set_buffer_temp (old);
22480 return (from_pos <= found && found < to_pos) ? make_number (found) : Qnil;
22483 DEFUN ("move-point-visually", Fmove_point_visually,
22484 Smove_point_visually, 1, 1, 0,
22485 doc: /* Move point in the visual order in the specified DIRECTION.
22486 DIRECTION can be 1, meaning move to the right, or -1, which moves to the
22487 left.
22489 Value is the new character position of point. */)
22490 (Lisp_Object direction)
22492 struct window *w = XWINDOW (selected_window);
22493 struct buffer *b = XBUFFER (w->contents);
22494 struct glyph_row *row;
22495 int dir;
22496 Lisp_Object paragraph_dir;
22498 #define ROW_GLYPH_NEWLINE_P(ROW,GLYPH) \
22499 (!(ROW)->continued_p \
22500 && NILP ((GLYPH)->object) \
22501 && (GLYPH)->type == CHAR_GLYPH \
22502 && (GLYPH)->u.ch == ' ' \
22503 && (GLYPH)->charpos >= 0 \
22504 && !(GLYPH)->avoid_cursor_p)
22506 CHECK_NUMBER (direction);
22507 dir = XINT (direction);
22508 if (dir > 0)
22509 dir = 1;
22510 else
22511 dir = -1;
22513 /* If current matrix is up-to-date, we can use the information
22514 recorded in the glyphs, at least as long as the goal is on the
22515 screen. */
22516 if (w->window_end_valid
22517 && !windows_or_buffers_changed
22518 && b
22519 && !b->clip_changed
22520 && !b->prevent_redisplay_optimizations_p
22521 && !window_outdated (w)
22522 /* We rely below on the cursor coordinates to be up to date, but
22523 we cannot trust them if some command moved point since the
22524 last complete redisplay. */
22525 && w->last_point == BUF_PT (b)
22526 && w->cursor.vpos >= 0
22527 && w->cursor.vpos < w->current_matrix->nrows
22528 && (row = MATRIX_ROW (w->current_matrix, w->cursor.vpos))->enabled_p)
22530 struct glyph *g = row->glyphs[TEXT_AREA];
22531 struct glyph *e = dir > 0 ? g + row->used[TEXT_AREA] : g - 1;
22532 struct glyph *gpt = g + w->cursor.hpos;
22534 for (g = gpt + dir; (dir > 0 ? g < e : g > e); g += dir)
22536 if (BUFFERP (g->object) && g->charpos != PT)
22538 SET_PT (g->charpos);
22539 w->cursor.vpos = -1;
22540 return make_number (PT);
22542 else if (!NILP (g->object) && !EQ (g->object, gpt->object))
22544 ptrdiff_t new_pos;
22546 if (BUFFERP (gpt->object))
22548 new_pos = PT;
22549 if ((gpt->resolved_level - row->reversed_p) % 2 == 0)
22550 new_pos += (row->reversed_p ? -dir : dir);
22551 else
22552 new_pos -= (row->reversed_p ? -dir : dir);
22553 new_pos = clip_to_bounds (BEGV, new_pos, ZV);
22554 /* If we didn't move, we've hit BEGV or ZV, so we
22555 need to signal a suitable error. */
22556 if (new_pos == PT)
22557 break;
22559 else if (BUFFERP (g->object))
22560 new_pos = g->charpos;
22561 else
22562 break;
22563 SET_PT (new_pos);
22564 w->cursor.vpos = -1;
22565 return make_number (PT);
22567 else if (ROW_GLYPH_NEWLINE_P (row, g))
22569 /* Glyphs inserted at the end of a non-empty line for
22570 positioning the cursor have zero charpos, so we must
22571 deduce the value of point by other means. */
22572 if (g->charpos > 0)
22573 SET_PT (g->charpos);
22574 else if (row->ends_at_zv_p && PT != ZV)
22575 SET_PT (ZV);
22576 else if (PT != MATRIX_ROW_END_CHARPOS (row) - 1)
22577 SET_PT (MATRIX_ROW_END_CHARPOS (row) - 1);
22578 else
22579 break;
22580 w->cursor.vpos = -1;
22581 return make_number (PT);
22584 if (g == e || NILP (g->object))
22586 if (row->truncated_on_left_p || row->truncated_on_right_p)
22587 goto simulate_display;
22588 if (!row->reversed_p)
22589 row += dir;
22590 else
22591 row -= dir;
22592 if (!(MATRIX_FIRST_TEXT_ROW (w->current_matrix) <= row
22593 && row < MATRIX_BOTTOM_TEXT_ROW (w->current_matrix, w)))
22594 goto simulate_display;
22596 if (dir > 0)
22598 if (row->reversed_p && !row->continued_p)
22600 SET_PT (MATRIX_ROW_END_CHARPOS (row) - 1);
22601 w->cursor.vpos = -1;
22602 return make_number (PT);
22604 g = row->glyphs[TEXT_AREA];
22605 e = g + row->used[TEXT_AREA];
22606 for ( ; g < e; g++)
22608 if (BUFFERP (g->object)
22609 /* Empty lines have only one glyph, which stands
22610 for the newline, and whose charpos is the
22611 buffer position of the newline. */
22612 || ROW_GLYPH_NEWLINE_P (row, g)
22613 /* When the buffer ends in a newline, the line at
22614 EOB also has one glyph, but its charpos is -1. */
22615 || (row->ends_at_zv_p
22616 && !row->reversed_p
22617 && NILP (g->object)
22618 && g->type == CHAR_GLYPH
22619 && g->u.ch == ' '))
22621 if (g->charpos > 0)
22622 SET_PT (g->charpos);
22623 else if (!row->reversed_p
22624 && row->ends_at_zv_p
22625 && PT != ZV)
22626 SET_PT (ZV);
22627 else
22628 continue;
22629 w->cursor.vpos = -1;
22630 return make_number (PT);
22634 else
22636 if (!row->reversed_p && !row->continued_p)
22638 SET_PT (MATRIX_ROW_END_CHARPOS (row) - 1);
22639 w->cursor.vpos = -1;
22640 return make_number (PT);
22642 e = row->glyphs[TEXT_AREA];
22643 g = e + row->used[TEXT_AREA] - 1;
22644 for ( ; g >= e; g--)
22646 if (BUFFERP (g->object)
22647 || (ROW_GLYPH_NEWLINE_P (row, g)
22648 && g->charpos > 0)
22649 /* Empty R2L lines on GUI frames have the buffer
22650 position of the newline stored in the stretch
22651 glyph. */
22652 || g->type == STRETCH_GLYPH
22653 || (row->ends_at_zv_p
22654 && row->reversed_p
22655 && NILP (g->object)
22656 && g->type == CHAR_GLYPH
22657 && g->u.ch == ' '))
22659 if (g->charpos > 0)
22660 SET_PT (g->charpos);
22661 else if (row->reversed_p
22662 && row->ends_at_zv_p
22663 && PT != ZV)
22664 SET_PT (ZV);
22665 else
22666 continue;
22667 w->cursor.vpos = -1;
22668 return make_number (PT);
22675 simulate_display:
22677 /* If we wind up here, we failed to move by using the glyphs, so we
22678 need to simulate display instead. */
22680 if (b)
22681 paragraph_dir = Fcurrent_bidi_paragraph_direction (w->contents);
22682 else
22683 paragraph_dir = Qleft_to_right;
22684 if (EQ (paragraph_dir, Qright_to_left))
22685 dir = -dir;
22686 if (PT <= BEGV && dir < 0)
22687 xsignal0 (Qbeginning_of_buffer);
22688 else if (PT >= ZV && dir > 0)
22689 xsignal0 (Qend_of_buffer);
22690 else
22692 struct text_pos pt;
22693 struct it it;
22694 int pt_x, target_x, pixel_width, pt_vpos;
22695 bool at_eol_p;
22696 bool overshoot_expected = false;
22697 bool target_is_eol_p = false;
22699 /* Setup the arena. */
22700 SET_TEXT_POS (pt, PT, PT_BYTE);
22701 start_display (&it, w, pt);
22702 /* When lines are truncated, we could be called with point
22703 outside of the windows edges, in which case move_it_*
22704 functions either prematurely stop at window's edge or jump to
22705 the next screen line, whereas we rely below on our ability to
22706 reach point, in order to start from its X coordinate. So we
22707 need to disregard the window's horizontal extent in that case. */
22708 if (it.line_wrap == TRUNCATE)
22709 it.last_visible_x = DISP_INFINITY;
22711 if (it.cmp_it.id < 0
22712 && it.method == GET_FROM_STRING
22713 && it.area == TEXT_AREA
22714 && it.string_from_display_prop_p
22715 && (it.sp > 0 && it.stack[it.sp - 1].method == GET_FROM_BUFFER))
22716 overshoot_expected = true;
22718 /* Find the X coordinate of point. We start from the beginning
22719 of this or previous line to make sure we are before point in
22720 the logical order (since the move_it_* functions can only
22721 move forward). */
22722 reseat:
22723 reseat_at_previous_visible_line_start (&it);
22724 it.current_x = it.hpos = it.current_y = it.vpos = 0;
22725 if (IT_CHARPOS (it) != PT)
22727 move_it_to (&it, overshoot_expected ? PT - 1 : PT,
22728 -1, -1, -1, MOVE_TO_POS);
22729 /* If we missed point because the character there is
22730 displayed out of a display vector that has more than one
22731 glyph, retry expecting overshoot. */
22732 if (it.method == GET_FROM_DISPLAY_VECTOR
22733 && it.current.dpvec_index > 0
22734 && !overshoot_expected)
22736 overshoot_expected = true;
22737 goto reseat;
22739 else if (IT_CHARPOS (it) != PT && !overshoot_expected)
22740 move_it_in_display_line (&it, PT, -1, MOVE_TO_POS);
22742 pt_x = it.current_x;
22743 pt_vpos = it.vpos;
22744 if (dir > 0 || overshoot_expected)
22746 struct glyph_row *row = it.glyph_row;
22748 /* When point is at beginning of line, we don't have
22749 information about the glyph there loaded into struct
22750 it. Calling get_next_display_element fixes that. */
22751 if (pt_x == 0)
22752 get_next_display_element (&it);
22753 at_eol_p = ITERATOR_AT_END_OF_LINE_P (&it);
22754 it.glyph_row = NULL;
22755 PRODUCE_GLYPHS (&it); /* compute it.pixel_width */
22756 it.glyph_row = row;
22757 /* PRODUCE_GLYPHS advances it.current_x, so we must restore
22758 it, lest it will become out of sync with it's buffer
22759 position. */
22760 it.current_x = pt_x;
22762 else
22763 at_eol_p = ITERATOR_AT_END_OF_LINE_P (&it);
22764 pixel_width = it.pixel_width;
22765 if (overshoot_expected && at_eol_p)
22766 pixel_width = 0;
22767 else if (pixel_width <= 0)
22768 pixel_width = 1;
22770 /* If there's a display string (or something similar) at point,
22771 we are actually at the glyph to the left of point, so we need
22772 to correct the X coordinate. */
22773 if (overshoot_expected)
22775 if (it.bidi_p)
22776 pt_x += pixel_width * it.bidi_it.scan_dir;
22777 else
22778 pt_x += pixel_width;
22781 /* Compute target X coordinate, either to the left or to the
22782 right of point. On TTY frames, all characters have the same
22783 pixel width of 1, so we can use that. On GUI frames we don't
22784 have an easy way of getting at the pixel width of the
22785 character to the left of point, so we use a different method
22786 of getting to that place. */
22787 if (dir > 0)
22788 target_x = pt_x + pixel_width;
22789 else
22790 target_x = pt_x - (!FRAME_WINDOW_P (it.f)) * pixel_width;
22792 /* Target X coordinate could be one line above or below the line
22793 of point, in which case we need to adjust the target X
22794 coordinate. Also, if moving to the left, we need to begin at
22795 the left edge of the point's screen line. */
22796 if (dir < 0)
22798 if (pt_x > 0)
22800 start_display (&it, w, pt);
22801 if (it.line_wrap == TRUNCATE)
22802 it.last_visible_x = DISP_INFINITY;
22803 reseat_at_previous_visible_line_start (&it);
22804 it.current_x = it.current_y = it.hpos = 0;
22805 if (pt_vpos != 0)
22806 move_it_by_lines (&it, pt_vpos);
22808 else
22810 move_it_by_lines (&it, -1);
22811 target_x = it.last_visible_x - !FRAME_WINDOW_P (it.f);
22812 target_is_eol_p = true;
22813 /* Under word-wrap, we don't know the x coordinate of
22814 the last character displayed on the previous line,
22815 which immediately precedes the wrap point. To find
22816 out its x coordinate, we try moving to the right
22817 margin of the window, which will stop at the wrap
22818 point, and then reset target_x to point at the
22819 character that precedes the wrap point. This is not
22820 needed on GUI frames, because (see below) there we
22821 move from the left margin one grapheme cluster at a
22822 time, and stop when we hit the wrap point. */
22823 if (!FRAME_WINDOW_P (it.f) && it.line_wrap == WORD_WRAP)
22825 void *it_data = NULL;
22826 struct it it2;
22828 SAVE_IT (it2, it, it_data);
22829 move_it_in_display_line_to (&it, ZV, target_x,
22830 MOVE_TO_POS | MOVE_TO_X);
22831 /* If we arrived at target_x, that _is_ the last
22832 character on the previous line. */
22833 if (it.current_x != target_x)
22834 target_x = it.current_x - 1;
22835 RESTORE_IT (&it, &it2, it_data);
22839 else
22841 if (at_eol_p
22842 || (target_x >= it.last_visible_x
22843 && it.line_wrap != TRUNCATE))
22845 if (pt_x > 0)
22846 move_it_by_lines (&it, 0);
22847 move_it_by_lines (&it, 1);
22848 target_x = 0;
22852 /* Move to the target X coordinate. */
22853 /* On GUI frames, as we don't know the X coordinate of the
22854 character to the left of point, moving point to the left
22855 requires walking, one grapheme cluster at a time, until we
22856 find ourself at a place immediately to the left of the
22857 character at point. */
22858 if (FRAME_WINDOW_P (it.f) && dir < 0)
22860 struct text_pos new_pos;
22861 enum move_it_result rc = MOVE_X_REACHED;
22863 if (it.current_x == 0)
22864 get_next_display_element (&it);
22865 if (it.what == IT_COMPOSITION)
22867 new_pos.charpos = it.cmp_it.charpos;
22868 new_pos.bytepos = -1;
22870 else
22871 new_pos = it.current.pos;
22873 while (it.current_x + it.pixel_width <= target_x
22874 && (rc == MOVE_X_REACHED
22875 /* Under word-wrap, move_it_in_display_line_to
22876 stops at correct coordinates, but sometimes
22877 returns MOVE_POS_MATCH_OR_ZV. */
22878 || (it.line_wrap == WORD_WRAP
22879 && rc == MOVE_POS_MATCH_OR_ZV)))
22881 int new_x = it.current_x + it.pixel_width;
22883 /* For composed characters, we want the position of the
22884 first character in the grapheme cluster (usually, the
22885 composition's base character), whereas it.current
22886 might give us the position of the _last_ one, e.g. if
22887 the composition is rendered in reverse due to bidi
22888 reordering. */
22889 if (it.what == IT_COMPOSITION)
22891 new_pos.charpos = it.cmp_it.charpos;
22892 new_pos.bytepos = -1;
22894 else
22895 new_pos = it.current.pos;
22896 if (new_x == it.current_x)
22897 new_x++;
22898 rc = move_it_in_display_line_to (&it, ZV, new_x,
22899 MOVE_TO_POS | MOVE_TO_X);
22900 if (ITERATOR_AT_END_OF_LINE_P (&it) && !target_is_eol_p)
22901 break;
22903 /* The previous position we saw in the loop is the one we
22904 want. */
22905 if (new_pos.bytepos == -1)
22906 new_pos.bytepos = CHAR_TO_BYTE (new_pos.charpos);
22907 it.current.pos = new_pos;
22909 else if (it.current_x != target_x)
22910 move_it_in_display_line_to (&it, ZV, target_x, MOVE_TO_POS | MOVE_TO_X);
22912 /* If we ended up in a display string that covers point, move to
22913 buffer position to the right in the visual order. */
22914 if (dir > 0)
22916 while (IT_CHARPOS (it) == PT)
22918 set_iterator_to_next (&it, false);
22919 if (!get_next_display_element (&it))
22920 break;
22924 /* Move point to that position. */
22925 SET_PT_BOTH (IT_CHARPOS (it), IT_BYTEPOS (it));
22928 return make_number (PT);
22930 #undef ROW_GLYPH_NEWLINE_P
22933 DEFUN ("bidi-resolved-levels", Fbidi_resolved_levels,
22934 Sbidi_resolved_levels, 0, 1, 0,
22935 doc: /* Return the resolved bidirectional levels of characters at VPOS.
22937 The resolved levels are produced by the Emacs bidi reordering engine
22938 that implements the UBA, the Unicode Bidirectional Algorithm. Please
22939 read the Unicode Standard Annex 9 (UAX#9) for background information
22940 about these levels.
22942 VPOS is the zero-based number of the current window's screen line
22943 for which to produce the resolved levels. If VPOS is nil or omitted,
22944 it defaults to the screen line of point. If the window displays a
22945 header line, VPOS of zero will report on the header line, and first
22946 line of text in the window will have VPOS of 1.
22948 Value is an array of resolved levels, indexed by glyph number.
22949 Glyphs are numbered from zero starting from the beginning of the
22950 screen line, i.e. the left edge of the window for left-to-right lines
22951 and from the right edge for right-to-left lines. The resolved levels
22952 are produced only for the window's text area; text in display margins
22953 is not included.
22955 If the selected window's display is not up-to-date, or if the specified
22956 screen line does not display text, this function returns nil. It is
22957 highly recommended to bind this function to some simple key, like F8,
22958 in order to avoid these problems.
22960 This function exists mainly for testing the correctness of the
22961 Emacs UBA implementation, in particular with the test suite. */)
22962 (Lisp_Object vpos)
22964 struct window *w = XWINDOW (selected_window);
22965 struct buffer *b = XBUFFER (w->contents);
22966 int nrow;
22967 struct glyph_row *row;
22969 if (NILP (vpos))
22971 int d1, d2, d3, d4, d5;
22973 pos_visible_p (w, PT, &d1, &d2, &d3, &d4, &d5, &nrow);
22975 else
22977 CHECK_NUMBER_COERCE_MARKER (vpos);
22978 nrow = XINT (vpos);
22981 /* We require up-to-date glyph matrix for this window. */
22982 if (w->window_end_valid
22983 && !windows_or_buffers_changed
22984 && b
22985 && !b->clip_changed
22986 && !b->prevent_redisplay_optimizations_p
22987 && !window_outdated (w)
22988 && nrow >= 0
22989 && nrow < w->current_matrix->nrows
22990 && (row = MATRIX_ROW (w->current_matrix, nrow))->enabled_p
22991 && MATRIX_ROW_DISPLAYS_TEXT_P (row))
22993 struct glyph *g, *e, *g1;
22994 int nglyphs, i;
22995 Lisp_Object levels;
22997 if (!row->reversed_p) /* Left-to-right glyph row. */
22999 g = g1 = row->glyphs[TEXT_AREA];
23000 e = g + row->used[TEXT_AREA];
23002 /* Skip over glyphs at the start of the row that was
23003 generated by redisplay for its own needs. */
23004 while (g < e
23005 && NILP (g->object)
23006 && g->charpos < 0)
23007 g++;
23008 g1 = g;
23010 /* Count the "interesting" glyphs in this row. */
23011 for (nglyphs = 0; g < e && !NILP (g->object); g++)
23012 nglyphs++;
23014 /* Create and fill the array. */
23015 levels = make_uninit_vector (nglyphs);
23016 for (i = 0; g1 < g; i++, g1++)
23017 ASET (levels, i, make_number (g1->resolved_level));
23019 else /* Right-to-left glyph row. */
23021 g = row->glyphs[TEXT_AREA] + row->used[TEXT_AREA] - 1;
23022 e = row->glyphs[TEXT_AREA] - 1;
23023 while (g > e
23024 && NILP (g->object)
23025 && g->charpos < 0)
23026 g--;
23027 g1 = g;
23028 for (nglyphs = 0; g > e && !NILP (g->object); g--)
23029 nglyphs++;
23030 levels = make_uninit_vector (nglyphs);
23031 for (i = 0; g1 > g; i++, g1--)
23032 ASET (levels, i, make_number (g1->resolved_level));
23034 return levels;
23036 else
23037 return Qnil;
23042 /***********************************************************************
23043 Menu Bar
23044 ***********************************************************************/
23046 /* Redisplay the menu bar in the frame for window W.
23048 The menu bar of X frames that don't have X toolkit support is
23049 displayed in a special window W->frame->menu_bar_window.
23051 The menu bar of terminal frames is treated specially as far as
23052 glyph matrices are concerned. Menu bar lines are not part of
23053 windows, so the update is done directly on the frame matrix rows
23054 for the menu bar. */
23056 static void
23057 display_menu_bar (struct window *w)
23059 struct frame *f = XFRAME (WINDOW_FRAME (w));
23060 struct it it;
23061 Lisp_Object items;
23062 int i;
23064 /* Don't do all this for graphical frames. */
23065 #ifdef HAVE_NTGUI
23066 if (FRAME_W32_P (f))
23067 return;
23068 #endif
23069 #if defined (USE_X_TOOLKIT) || defined (USE_GTK)
23070 if (FRAME_X_P (f))
23071 return;
23072 #endif
23074 #ifdef HAVE_NS
23075 if (FRAME_NS_P (f))
23076 return;
23077 #endif /* HAVE_NS */
23079 #if defined (USE_X_TOOLKIT) || defined (USE_GTK)
23080 eassert (!FRAME_WINDOW_P (f));
23081 init_iterator (&it, w, -1, -1, f->desired_matrix->rows, MENU_FACE_ID);
23082 it.first_visible_x = 0;
23083 it.last_visible_x = FRAME_PIXEL_WIDTH (f);
23084 #elif defined (HAVE_X_WINDOWS) /* X without toolkit. */
23085 if (FRAME_WINDOW_P (f))
23087 /* Menu bar lines are displayed in the desired matrix of the
23088 dummy window menu_bar_window. */
23089 struct window *menu_w;
23090 menu_w = XWINDOW (f->menu_bar_window);
23091 init_iterator (&it, menu_w, -1, -1, menu_w->desired_matrix->rows,
23092 MENU_FACE_ID);
23093 it.first_visible_x = 0;
23094 it.last_visible_x = FRAME_PIXEL_WIDTH (f);
23096 else
23097 #endif /* not USE_X_TOOLKIT and not USE_GTK */
23099 /* This is a TTY frame, i.e. character hpos/vpos are used as
23100 pixel x/y. */
23101 init_iterator (&it, w, -1, -1, f->desired_matrix->rows,
23102 MENU_FACE_ID);
23103 it.first_visible_x = 0;
23104 it.last_visible_x = FRAME_COLS (f);
23107 /* FIXME: This should be controlled by a user option. See the
23108 comments in redisplay_tool_bar and display_mode_line about
23109 this. */
23110 it.paragraph_embedding = L2R;
23112 /* Clear all rows of the menu bar. */
23113 for (i = 0; i < FRAME_MENU_BAR_LINES (f); ++i)
23115 struct glyph_row *row = it.glyph_row + i;
23116 clear_glyph_row (row);
23117 row->enabled_p = true;
23118 row->full_width_p = true;
23119 row->reversed_p = false;
23122 /* Display all items of the menu bar. */
23123 items = FRAME_MENU_BAR_ITEMS (it.f);
23124 for (i = 0; i < ASIZE (items); i += 4)
23126 Lisp_Object string;
23128 /* Stop at nil string. */
23129 string = AREF (items, i + 1);
23130 if (NILP (string))
23131 break;
23133 /* Remember where item was displayed. */
23134 ASET (items, i + 3, make_number (it.hpos));
23136 /* Display the item, pad with one space. */
23137 if (it.current_x < it.last_visible_x)
23138 display_string (NULL, string, Qnil, 0, 0, &it,
23139 SCHARS (string) + 1, 0, 0, -1);
23142 /* Fill out the line with spaces. */
23143 if (it.current_x < it.last_visible_x)
23144 display_string ("", Qnil, Qnil, 0, 0, &it, -1, 0, 0, -1);
23146 /* Compute the total height of the lines. */
23147 compute_line_metrics (&it);
23150 /* Deep copy of a glyph row, including the glyphs. */
23151 static void
23152 deep_copy_glyph_row (struct glyph_row *to, struct glyph_row *from)
23154 struct glyph *pointers[1 + LAST_AREA];
23155 int to_used = to->used[TEXT_AREA];
23157 /* Save glyph pointers of TO. */
23158 memcpy (pointers, to->glyphs, sizeof to->glyphs);
23160 /* Do a structure assignment. */
23161 *to = *from;
23163 /* Restore original glyph pointers of TO. */
23164 memcpy (to->glyphs, pointers, sizeof to->glyphs);
23166 /* Copy the glyphs. */
23167 memcpy (to->glyphs[TEXT_AREA], from->glyphs[TEXT_AREA],
23168 min (from->used[TEXT_AREA], to_used) * sizeof (struct glyph));
23170 /* If we filled only part of the TO row, fill the rest with
23171 space_glyph (which will display as empty space). */
23172 if (to_used > from->used[TEXT_AREA])
23173 fill_up_frame_row_with_spaces (to, to_used);
23176 /* Display one menu item on a TTY, by overwriting the glyphs in the
23177 frame F's desired glyph matrix with glyphs produced from the menu
23178 item text. Called from term.c to display TTY drop-down menus one
23179 item at a time.
23181 ITEM_TEXT is the menu item text as a C string.
23183 FACE_ID is the face ID to be used for this menu item. FACE_ID
23184 could specify one of 3 faces: a face for an enabled item, a face
23185 for a disabled item, or a face for a selected item.
23187 X and Y are coordinates of the first glyph in the frame's desired
23188 matrix to be overwritten by the menu item. Since this is a TTY, Y
23189 is the zero-based number of the glyph row and X is the zero-based
23190 glyph number in the row, starting from left, where to start
23191 displaying the item.
23193 SUBMENU means this menu item drops down a submenu, which
23194 should be indicated by displaying a proper visual cue after the
23195 item text. */
23197 void
23198 display_tty_menu_item (const char *item_text, int width, int face_id,
23199 int x, int y, bool submenu)
23201 struct it it;
23202 struct frame *f = SELECTED_FRAME ();
23203 struct window *w = XWINDOW (f->selected_window);
23204 struct glyph_row *row;
23205 size_t item_len = strlen (item_text);
23207 eassert (FRAME_TERMCAP_P (f));
23209 /* Don't write beyond the matrix's last row. This can happen for
23210 TTY screens that are not high enough to show the entire menu.
23211 (This is actually a bit of defensive programming, as
23212 tty_menu_display already limits the number of menu items to one
23213 less than the number of screen lines.) */
23214 if (y >= f->desired_matrix->nrows)
23215 return;
23217 init_iterator (&it, w, -1, -1, f->desired_matrix->rows + y, MENU_FACE_ID);
23218 it.first_visible_x = 0;
23219 it.last_visible_x = FRAME_COLS (f) - 1;
23220 row = it.glyph_row;
23221 /* Start with the row contents from the current matrix. */
23222 deep_copy_glyph_row (row, f->current_matrix->rows + y);
23223 bool saved_width = row->full_width_p;
23224 row->full_width_p = true;
23225 bool saved_reversed = row->reversed_p;
23226 row->reversed_p = false;
23227 row->enabled_p = true;
23229 /* Arrange for the menu item glyphs to start at (X,Y) and have the
23230 desired face. */
23231 eassert (x < f->desired_matrix->matrix_w);
23232 it.current_x = it.hpos = x;
23233 it.current_y = it.vpos = y;
23234 int saved_used = row->used[TEXT_AREA];
23235 bool saved_truncated = row->truncated_on_right_p;
23236 row->used[TEXT_AREA] = x;
23237 it.face_id = face_id;
23238 it.line_wrap = TRUNCATE;
23240 /* FIXME: This should be controlled by a user option. See the
23241 comments in redisplay_tool_bar and display_mode_line about this.
23242 Also, if paragraph_embedding could ever be R2L, changes will be
23243 needed to avoid shifting to the right the row characters in
23244 term.c:append_glyph. */
23245 it.paragraph_embedding = L2R;
23247 /* Pad with a space on the left. */
23248 display_string (" ", Qnil, Qnil, 0, 0, &it, 1, 0, FRAME_COLS (f) - 1, -1);
23249 width--;
23250 /* Display the menu item, pad with spaces to WIDTH. */
23251 if (submenu)
23253 display_string (item_text, Qnil, Qnil, 0, 0, &it,
23254 item_len, 0, FRAME_COLS (f) - 1, -1);
23255 width -= item_len;
23256 /* Indicate with " >" that there's a submenu. */
23257 display_string (" >", Qnil, Qnil, 0, 0, &it, width, 0,
23258 FRAME_COLS (f) - 1, -1);
23260 else
23261 display_string (item_text, Qnil, Qnil, 0, 0, &it,
23262 width, 0, FRAME_COLS (f) - 1, -1);
23264 row->used[TEXT_AREA] = max (saved_used, row->used[TEXT_AREA]);
23265 row->truncated_on_right_p = saved_truncated;
23266 row->hash = row_hash (row);
23267 row->full_width_p = saved_width;
23268 row->reversed_p = saved_reversed;
23271 /***********************************************************************
23272 Mode Line
23273 ***********************************************************************/
23275 /* Redisplay mode lines in the window tree whose root is WINDOW.
23276 If FORCE, redisplay mode lines unconditionally.
23277 Otherwise, redisplay only mode lines that are garbaged. Value is
23278 the number of windows whose mode lines were redisplayed. */
23280 static int
23281 redisplay_mode_lines (Lisp_Object window, bool force)
23283 int nwindows = 0;
23285 while (!NILP (window))
23287 struct window *w = XWINDOW (window);
23289 if (WINDOWP (w->contents))
23290 nwindows += redisplay_mode_lines (w->contents, force);
23291 else if (force
23292 || FRAME_GARBAGED_P (XFRAME (w->frame))
23293 || !MATRIX_MODE_LINE_ROW (w->current_matrix)->enabled_p)
23295 struct text_pos lpoint;
23296 struct buffer *old = current_buffer;
23298 /* Set the window's buffer for the mode line display. */
23299 SET_TEXT_POS (lpoint, PT, PT_BYTE);
23300 set_buffer_internal_1 (XBUFFER (w->contents));
23302 /* Point refers normally to the selected window. For any
23303 other window, set up appropriate value. */
23304 if (!EQ (window, selected_window))
23306 struct text_pos pt;
23308 CLIP_TEXT_POS_FROM_MARKER (pt, w->pointm);
23309 TEMP_SET_PT_BOTH (CHARPOS (pt), BYTEPOS (pt));
23312 /* Display mode lines. */
23313 clear_glyph_matrix (w->desired_matrix);
23314 if (display_mode_lines (w))
23315 ++nwindows;
23317 /* Restore old settings. */
23318 set_buffer_internal_1 (old);
23319 TEMP_SET_PT_BOTH (CHARPOS (lpoint), BYTEPOS (lpoint));
23322 window = w->next;
23325 return nwindows;
23329 /* Display the mode and/or header line of window W. Value is the
23330 sum number of mode lines and header lines displayed. */
23332 static int
23333 display_mode_lines (struct window *w)
23335 Lisp_Object old_selected_window = selected_window;
23336 Lisp_Object old_selected_frame = selected_frame;
23337 Lisp_Object new_frame = w->frame;
23338 Lisp_Object old_frame_selected_window = XFRAME (new_frame)->selected_window;
23339 int n = 0;
23341 selected_frame = new_frame;
23342 /* FIXME: If we were to allow the mode-line's computation changing the buffer
23343 or window's point, then we'd need select_window_1 here as well. */
23344 XSETWINDOW (selected_window, w);
23345 XFRAME (new_frame)->selected_window = selected_window;
23347 /* These will be set while the mode line specs are processed. */
23348 line_number_displayed = false;
23349 w->column_number_displayed = -1;
23351 if (window_wants_mode_line (w))
23353 Lisp_Object window_mode_line_format
23354 = window_parameter (w, Qmode_line_format);
23356 struct window *sel_w = XWINDOW (old_selected_window);
23358 /* Select mode line face based on the real selected window. */
23359 display_mode_line (w, CURRENT_MODE_LINE_FACE_ID_3 (sel_w, sel_w, w),
23360 NILP (window_mode_line_format)
23361 ? BVAR (current_buffer, mode_line_format)
23362 : window_mode_line_format);
23363 ++n;
23366 if (window_wants_header_line (w))
23368 Lisp_Object window_header_line_format
23369 = window_parameter (w, Qheader_line_format);
23371 display_mode_line (w, HEADER_LINE_FACE_ID,
23372 NILP (window_header_line_format)
23373 ? BVAR (current_buffer, header_line_format)
23374 : window_header_line_format);
23375 ++n;
23378 XFRAME (new_frame)->selected_window = old_frame_selected_window;
23379 selected_frame = old_selected_frame;
23380 selected_window = old_selected_window;
23381 if (n > 0)
23382 w->must_be_updated_p = true;
23383 return n;
23387 /* Display mode or header line of window W. FACE_ID specifies which
23388 line to display; it is either MODE_LINE_FACE_ID or
23389 HEADER_LINE_FACE_ID. FORMAT is the mode/header line format to
23390 display. Value is the pixel height of the mode/header line
23391 displayed. */
23393 static int
23394 display_mode_line (struct window *w, enum face_id face_id, Lisp_Object format)
23396 struct it it;
23397 struct face *face;
23398 ptrdiff_t count = SPECPDL_INDEX ();
23400 init_iterator (&it, w, -1, -1, NULL, face_id);
23401 /* Don't extend on a previously drawn mode-line.
23402 This may happen if called from pos_visible_p. */
23403 it.glyph_row->enabled_p = false;
23404 prepare_desired_row (w, it.glyph_row, true);
23406 it.glyph_row->mode_line_p = true;
23408 /* FIXME: This should be controlled by a user option. But
23409 supporting such an option is not trivial, since the mode line is
23410 made up of many separate strings. */
23411 it.paragraph_embedding = L2R;
23413 record_unwind_protect (unwind_format_mode_line,
23414 format_mode_line_unwind_data (NULL, NULL,
23415 Qnil, false));
23417 mode_line_target = MODE_LINE_DISPLAY;
23419 /* Temporarily make frame's keyboard the current kboard so that
23420 kboard-local variables in the mode_line_format will get the right
23421 values. */
23422 push_kboard (FRAME_KBOARD (it.f));
23423 record_unwind_save_match_data ();
23424 display_mode_element (&it, 0, 0, 0, format, Qnil, false);
23425 pop_kboard ();
23427 unbind_to (count, Qnil);
23429 /* Fill up with spaces. */
23430 display_string (" ", Qnil, Qnil, 0, 0, &it, 10000, -1, -1, 0);
23432 compute_line_metrics (&it);
23433 it.glyph_row->full_width_p = true;
23434 it.glyph_row->continued_p = false;
23435 it.glyph_row->truncated_on_left_p = false;
23436 it.glyph_row->truncated_on_right_p = false;
23438 /* Make a 3D mode-line have a shadow at its right end. */
23439 face = FACE_FROM_ID (it.f, face_id);
23440 extend_face_to_end_of_line (&it);
23441 if (face->box != FACE_NO_BOX)
23443 struct glyph *last = (it.glyph_row->glyphs[TEXT_AREA]
23444 + it.glyph_row->used[TEXT_AREA] - 1);
23445 last->right_box_line_p = true;
23448 return it.glyph_row->height;
23451 /* Move element ELT in LIST to the front of LIST.
23452 Return the updated list. */
23454 static Lisp_Object
23455 move_elt_to_front (Lisp_Object elt, Lisp_Object list)
23457 register Lisp_Object tail, prev;
23458 register Lisp_Object tem;
23460 tail = list;
23461 prev = Qnil;
23462 while (CONSP (tail))
23464 tem = XCAR (tail);
23466 if (EQ (elt, tem))
23468 /* Splice out the link TAIL. */
23469 if (NILP (prev))
23470 list = XCDR (tail);
23471 else
23472 Fsetcdr (prev, XCDR (tail));
23474 /* Now make it the first. */
23475 Fsetcdr (tail, list);
23476 return tail;
23478 else
23479 prev = tail;
23480 tail = XCDR (tail);
23481 maybe_quit ();
23484 /* Not found--return unchanged LIST. */
23485 return list;
23488 /* Contribute ELT to the mode line for window IT->w. How it
23489 translates into text depends on its data type.
23491 IT describes the display environment in which we display, as usual.
23493 DEPTH is the depth in recursion. It is used to prevent
23494 infinite recursion here.
23496 FIELD_WIDTH is the number of characters the display of ELT should
23497 occupy in the mode line, and PRECISION is the maximum number of
23498 characters to display from ELT's representation. See
23499 display_string for details.
23501 Returns the hpos of the end of the text generated by ELT.
23503 PROPS is a property list to add to any string we encounter.
23505 If RISKY, remove (disregard) any properties in any string
23506 we encounter, and ignore :eval and :propertize.
23508 The global variable `mode_line_target' determines whether the
23509 output is passed to `store_mode_line_noprop',
23510 `store_mode_line_string', or `display_string'. */
23512 static int
23513 display_mode_element (struct it *it, int depth, int field_width, int precision,
23514 Lisp_Object elt, Lisp_Object props, bool risky)
23516 int n = 0, field, prec;
23517 bool literal = false;
23519 tail_recurse:
23520 if (depth > 100)
23521 elt = build_string ("*too-deep*");
23523 depth++;
23525 switch (XTYPE (elt))
23527 case Lisp_String:
23529 /* A string: output it and check for %-constructs within it. */
23530 unsigned char c;
23531 ptrdiff_t offset = 0;
23533 if (SCHARS (elt) > 0
23534 && (!NILP (props) || risky))
23536 Lisp_Object oprops, aelt;
23537 oprops = Ftext_properties_at (make_number (0), elt);
23539 /* If the starting string's properties are not what
23540 we want, translate the string. Also, if the string
23541 is risky, do that anyway. */
23543 if (NILP (Fequal (props, oprops)) || risky)
23545 /* If the starting string has properties,
23546 merge the specified ones onto the existing ones. */
23547 if (! NILP (oprops) && !risky)
23549 Lisp_Object tem;
23551 oprops = Fcopy_sequence (oprops);
23552 tem = props;
23553 while (CONSP (tem))
23555 oprops = Fplist_put (oprops, XCAR (tem),
23556 XCAR (XCDR (tem)));
23557 tem = XCDR (XCDR (tem));
23559 props = oprops;
23562 aelt = Fassoc (elt, mode_line_proptrans_alist, Qnil);
23563 if (! NILP (aelt) && !NILP (Fequal (props, XCDR (aelt))))
23565 /* AELT is what we want. Move it to the front
23566 without consing. */
23567 elt = XCAR (aelt);
23568 mode_line_proptrans_alist
23569 = move_elt_to_front (aelt, mode_line_proptrans_alist);
23571 else
23573 Lisp_Object tem;
23575 /* If AELT has the wrong props, it is useless.
23576 so get rid of it. */
23577 if (! NILP (aelt))
23578 mode_line_proptrans_alist
23579 = Fdelq (aelt, mode_line_proptrans_alist);
23581 elt = Fcopy_sequence (elt);
23582 Fset_text_properties (make_number (0), Flength (elt),
23583 props, elt);
23584 /* Add this item to mode_line_proptrans_alist. */
23585 mode_line_proptrans_alist
23586 = Fcons (Fcons (elt, props),
23587 mode_line_proptrans_alist);
23588 /* Truncate mode_line_proptrans_alist
23589 to at most 50 elements. */
23590 tem = Fnthcdr (make_number (50),
23591 mode_line_proptrans_alist);
23592 if (! NILP (tem))
23593 XSETCDR (tem, Qnil);
23598 offset = 0;
23600 if (literal)
23602 prec = precision - n;
23603 switch (mode_line_target)
23605 case MODE_LINE_NOPROP:
23606 case MODE_LINE_TITLE:
23607 n += store_mode_line_noprop (SSDATA (elt), -1, prec);
23608 break;
23609 case MODE_LINE_STRING:
23610 n += store_mode_line_string (NULL, elt, true, 0, prec, Qnil);
23611 break;
23612 case MODE_LINE_DISPLAY:
23613 n += display_string (NULL, elt, Qnil, 0, 0, it,
23614 0, prec, 0, STRING_MULTIBYTE (elt));
23615 break;
23618 break;
23621 /* Handle the non-literal case. */
23623 while ((precision <= 0 || n < precision)
23624 && SREF (elt, offset) != 0
23625 && (mode_line_target != MODE_LINE_DISPLAY
23626 || it->current_x < it->last_visible_x))
23628 ptrdiff_t last_offset = offset;
23630 /* Advance to end of string or next format specifier. */
23631 while ((c = SREF (elt, offset++)) != '\0' && c != '%')
23634 if (offset - 1 != last_offset)
23636 ptrdiff_t nchars, nbytes;
23638 /* Output to end of string or up to '%'. Field width
23639 is length of string. Don't output more than
23640 PRECISION allows us. */
23641 offset--;
23643 prec = c_string_width (SDATA (elt) + last_offset,
23644 offset - last_offset, precision - n,
23645 &nchars, &nbytes);
23647 switch (mode_line_target)
23649 case MODE_LINE_NOPROP:
23650 case MODE_LINE_TITLE:
23651 n += store_mode_line_noprop (SSDATA (elt) + last_offset, 0, prec);
23652 break;
23653 case MODE_LINE_STRING:
23655 ptrdiff_t bytepos = last_offset;
23656 ptrdiff_t charpos = string_byte_to_char (elt, bytepos);
23657 ptrdiff_t endpos = (precision <= 0
23658 ? string_byte_to_char (elt, offset)
23659 : charpos + nchars);
23660 Lisp_Object mode_string
23661 = Fsubstring (elt, make_number (charpos),
23662 make_number (endpos));
23663 n += store_mode_line_string (NULL, mode_string, false,
23664 0, 0, Qnil);
23666 break;
23667 case MODE_LINE_DISPLAY:
23669 ptrdiff_t bytepos = last_offset;
23670 ptrdiff_t charpos = string_byte_to_char (elt, bytepos);
23672 if (precision <= 0)
23673 nchars = string_byte_to_char (elt, offset) - charpos;
23674 n += display_string (NULL, elt, Qnil, 0, charpos,
23675 it, 0, nchars, 0,
23676 STRING_MULTIBYTE (elt));
23678 break;
23681 else /* c == '%' */
23683 ptrdiff_t percent_position = offset;
23685 /* Get the specified minimum width. Zero means
23686 don't pad. */
23687 field = 0;
23688 while ((c = SREF (elt, offset++)) >= '0' && c <= '9')
23689 field = field * 10 + c - '0';
23691 /* Don't pad beyond the total padding allowed. */
23692 if (field_width - n > 0 && field > field_width - n)
23693 field = field_width - n;
23695 /* Note that either PRECISION <= 0 or N < PRECISION. */
23696 prec = precision - n;
23698 if (c == 'M')
23699 n += display_mode_element (it, depth, field, prec,
23700 Vglobal_mode_string, props,
23701 risky);
23702 else if (c != 0)
23704 bool multibyte;
23705 ptrdiff_t bytepos, charpos;
23706 const char *spec;
23707 Lisp_Object string;
23709 bytepos = percent_position;
23710 charpos = (STRING_MULTIBYTE (elt)
23711 ? string_byte_to_char (elt, bytepos)
23712 : bytepos);
23713 spec = decode_mode_spec (it->w, c, field, &string);
23714 multibyte = STRINGP (string) && STRING_MULTIBYTE (string);
23716 switch (mode_line_target)
23718 case MODE_LINE_NOPROP:
23719 case MODE_LINE_TITLE:
23720 n += store_mode_line_noprop (spec, field, prec);
23721 break;
23722 case MODE_LINE_STRING:
23724 Lisp_Object tem = build_string (spec);
23725 props = Ftext_properties_at (make_number (charpos), elt);
23726 /* Should only keep face property in props */
23727 n += store_mode_line_string (NULL, tem, false,
23728 field, prec, props);
23730 break;
23731 case MODE_LINE_DISPLAY:
23733 int nglyphs_before, nwritten;
23735 nglyphs_before = it->glyph_row->used[TEXT_AREA];
23736 nwritten = display_string (spec, string, elt,
23737 charpos, 0, it,
23738 field, prec, 0,
23739 multibyte);
23741 /* Assign to the glyphs written above the
23742 string where the `%x' came from, position
23743 of the `%'. */
23744 if (nwritten > 0)
23746 struct glyph *glyph
23747 = (it->glyph_row->glyphs[TEXT_AREA]
23748 + nglyphs_before);
23749 int i;
23751 for (i = 0; i < nwritten; ++i)
23753 glyph[i].object = elt;
23754 glyph[i].charpos = charpos;
23757 n += nwritten;
23760 break;
23763 else /* c == 0 */
23764 break;
23768 break;
23770 case Lisp_Symbol:
23771 /* A symbol: process the value of the symbol recursively
23772 as if it appeared here directly. Avoid error if symbol void.
23773 Special case: if value of symbol is a string, output the string
23774 literally. */
23776 register Lisp_Object tem;
23778 /* If the variable is not marked as risky to set
23779 then its contents are risky to use. */
23780 if (NILP (Fget (elt, Qrisky_local_variable)))
23781 risky = true;
23783 tem = Fboundp (elt);
23784 if (!NILP (tem))
23786 tem = Fsymbol_value (elt);
23787 /* If value is a string, output that string literally:
23788 don't check for % within it. */
23789 if (STRINGP (tem))
23790 literal = true;
23792 if (!EQ (tem, elt))
23794 /* Give up right away for nil or t. */
23795 elt = tem;
23796 goto tail_recurse;
23800 break;
23802 case Lisp_Cons:
23804 register Lisp_Object car, tem;
23806 /* A cons cell: five distinct cases.
23807 If first element is :eval or :propertize, do something special.
23808 If first element is a string or a cons, process all the elements
23809 and effectively concatenate them.
23810 If first element is a negative number, truncate displaying cdr to
23811 at most that many characters. If positive, pad (with spaces)
23812 to at least that many characters.
23813 If first element is a symbol, process the cadr or caddr recursively
23814 according to whether the symbol's value is non-nil or nil. */
23815 car = XCAR (elt);
23816 if (EQ (car, QCeval))
23818 /* An element of the form (:eval FORM) means evaluate FORM
23819 and use the result as mode line elements. */
23821 if (risky)
23822 break;
23824 if (CONSP (XCDR (elt)))
23826 Lisp_Object spec;
23827 spec = safe__eval (true, XCAR (XCDR (elt)));
23828 /* The :eval form could delete the frame stored in the
23829 iterator, which will cause a crash if we try to
23830 access faces and other fields (e.g., FRAME_KBOARD)
23831 on that frame. This is a nonsensical thing to do,
23832 and signaling an error from redisplay might be
23833 dangerous, but we cannot continue with an invalid frame. */
23834 if (!FRAME_LIVE_P (it->f))
23835 signal_error (":eval deleted the frame being displayed", elt);
23836 n += display_mode_element (it, depth, field_width - n,
23837 precision - n, spec, props,
23838 risky);
23841 else if (EQ (car, QCpropertize))
23843 /* An element of the form (:propertize ELT PROPS...)
23844 means display ELT but applying properties PROPS. */
23846 if (risky)
23847 break;
23849 if (CONSP (XCDR (elt)))
23850 n += display_mode_element (it, depth, field_width - n,
23851 precision - n, XCAR (XCDR (elt)),
23852 XCDR (XCDR (elt)), risky);
23854 else if (SYMBOLP (car))
23856 tem = Fboundp (car);
23857 elt = XCDR (elt);
23858 if (!CONSP (elt))
23859 goto invalid;
23860 /* elt is now the cdr, and we know it is a cons cell.
23861 Use its car if CAR has a non-nil value. */
23862 if (!NILP (tem))
23864 tem = Fsymbol_value (car);
23865 if (!NILP (tem))
23867 elt = XCAR (elt);
23868 goto tail_recurse;
23871 /* Symbol's value is nil (or symbol is unbound)
23872 Get the cddr of the original list
23873 and if possible find the caddr and use that. */
23874 elt = XCDR (elt);
23875 if (NILP (elt))
23876 break;
23877 else if (!CONSP (elt))
23878 goto invalid;
23879 elt = XCAR (elt);
23880 goto tail_recurse;
23882 else if (INTEGERP (car))
23884 register int lim = XINT (car);
23885 elt = XCDR (elt);
23886 if (lim < 0)
23888 /* Negative int means reduce maximum width. */
23889 if (precision <= 0)
23890 precision = -lim;
23891 else
23892 precision = min (precision, -lim);
23894 else if (lim > 0)
23896 /* Padding specified. Don't let it be more than
23897 current maximum. */
23898 if (precision > 0)
23899 lim = min (precision, lim);
23901 /* If that's more padding than already wanted, queue it.
23902 But don't reduce padding already specified even if
23903 that is beyond the current truncation point. */
23904 field_width = max (lim, field_width);
23906 goto tail_recurse;
23908 else if (STRINGP (car) || CONSP (car))
23909 FOR_EACH_TAIL_SAFE (elt)
23911 if (0 < precision && precision <= n)
23912 break;
23913 n += display_mode_element (it, depth,
23914 /* Pad after only the last
23915 list element. */
23916 (! CONSP (XCDR (elt))
23917 ? field_width - n
23918 : 0),
23919 precision - n, XCAR (elt),
23920 props, risky);
23923 break;
23925 default:
23926 invalid:
23927 elt = build_string ("*invalid*");
23928 goto tail_recurse;
23931 /* Pad to FIELD_WIDTH. */
23932 if (field_width > 0 && n < field_width)
23934 switch (mode_line_target)
23936 case MODE_LINE_NOPROP:
23937 case MODE_LINE_TITLE:
23938 n += store_mode_line_noprop ("", field_width - n, 0);
23939 break;
23940 case MODE_LINE_STRING:
23941 n += store_mode_line_string ("", Qnil, false, field_width - n, 0,
23942 Qnil);
23943 break;
23944 case MODE_LINE_DISPLAY:
23945 n += display_string ("", Qnil, Qnil, 0, 0, it, field_width - n,
23946 0, 0, 0);
23947 break;
23951 return n;
23954 /* Store a mode-line string element in mode_line_string_list.
23956 If STRING is non-null, display that C string. Otherwise, the Lisp
23957 string LISP_STRING is displayed.
23959 FIELD_WIDTH is the minimum number of output glyphs to produce.
23960 If STRING has fewer characters than FIELD_WIDTH, pad to the right
23961 with spaces. FIELD_WIDTH <= 0 means don't pad.
23963 PRECISION is the maximum number of characters to output from
23964 STRING. PRECISION <= 0 means don't truncate the string.
23966 If COPY_STRING, make a copy of LISP_STRING before adding
23967 properties to the string.
23969 PROPS are the properties to add to the string.
23970 The mode_line_string_face face property is always added to the string.
23973 static int
23974 store_mode_line_string (const char *string, Lisp_Object lisp_string,
23975 bool copy_string,
23976 int field_width, int precision, Lisp_Object props)
23978 ptrdiff_t len;
23979 int n = 0;
23981 if (string != NULL)
23983 len = strlen (string);
23984 if (precision > 0 && len > precision)
23985 len = precision;
23986 lisp_string = make_string (string, len);
23987 if (NILP (props))
23988 props = mode_line_string_face_prop;
23989 else if (!NILP (mode_line_string_face))
23991 Lisp_Object face = Fplist_get (props, Qface);
23992 props = Fcopy_sequence (props);
23993 if (NILP (face))
23994 face = mode_line_string_face;
23995 else
23996 face = list2 (face, mode_line_string_face);
23997 props = Fplist_put (props, Qface, face);
23999 Fadd_text_properties (make_number (0), make_number (len),
24000 props, lisp_string);
24002 else
24004 len = XFASTINT (Flength (lisp_string));
24005 if (precision > 0 && len > precision)
24007 len = precision;
24008 lisp_string = Fsubstring (lisp_string, make_number (0), make_number (len));
24009 precision = -1;
24011 if (!NILP (mode_line_string_face))
24013 Lisp_Object face;
24014 if (NILP (props))
24015 props = Ftext_properties_at (make_number (0), lisp_string);
24016 face = Fplist_get (props, Qface);
24017 if (NILP (face))
24018 face = mode_line_string_face;
24019 else
24020 face = list2 (face, mode_line_string_face);
24021 props = list2 (Qface, face);
24022 if (copy_string)
24023 lisp_string = Fcopy_sequence (lisp_string);
24025 if (!NILP (props))
24026 Fadd_text_properties (make_number (0), make_number (len),
24027 props, lisp_string);
24030 if (len > 0)
24032 mode_line_string_list = Fcons (lisp_string, mode_line_string_list);
24033 n += len;
24036 if (field_width > len)
24038 field_width -= len;
24039 lisp_string = Fmake_string (make_number (field_width), make_number (' '));
24040 if (!NILP (props))
24041 Fadd_text_properties (make_number (0), make_number (field_width),
24042 props, lisp_string);
24043 mode_line_string_list = Fcons (lisp_string, mode_line_string_list);
24044 n += field_width;
24047 return n;
24051 DEFUN ("format-mode-line", Fformat_mode_line, Sformat_mode_line,
24052 1, 4, 0,
24053 doc: /* Format a string out of a mode line format specification.
24054 First arg FORMAT specifies the mode line format (see `mode-line-format'
24055 for details) to use.
24057 By default, the format is evaluated for the currently selected window.
24059 Optional second arg FACE specifies the face property to put on all
24060 characters for which no face is specified. The value nil means the
24061 default face. The value t means whatever face the window's mode line
24062 currently uses (either `mode-line' or `mode-line-inactive',
24063 depending on whether the window is the selected window or not).
24064 An integer value means the value string has no text
24065 properties.
24067 Optional third and fourth args WINDOW and BUFFER specify the window
24068 and buffer to use as the context for the formatting (defaults
24069 are the selected window and the WINDOW's buffer). */)
24070 (Lisp_Object format, Lisp_Object face,
24071 Lisp_Object window, Lisp_Object buffer)
24073 struct it it;
24074 int len;
24075 struct window *w;
24076 struct buffer *old_buffer = NULL;
24077 int face_id;
24078 bool no_props = INTEGERP (face);
24079 ptrdiff_t count = SPECPDL_INDEX ();
24080 Lisp_Object str;
24081 int string_start = 0;
24083 w = decode_any_window (window);
24084 XSETWINDOW (window, w);
24086 if (NILP (buffer))
24087 buffer = w->contents;
24088 CHECK_BUFFER (buffer);
24090 /* Make formatting the modeline a non-op when noninteractive, otherwise
24091 there will be problems later caused by a partially initialized frame. */
24092 if (NILP (format) || noninteractive)
24093 return empty_unibyte_string;
24095 if (no_props)
24096 face = Qnil;
24098 face_id = (NILP (face) || EQ (face, Qdefault)) ? DEFAULT_FACE_ID
24099 : EQ (face, Qt) ? (EQ (window, selected_window)
24100 ? MODE_LINE_FACE_ID : MODE_LINE_INACTIVE_FACE_ID)
24101 : EQ (face, Qmode_line) ? MODE_LINE_FACE_ID
24102 : EQ (face, Qmode_line_inactive) ? MODE_LINE_INACTIVE_FACE_ID
24103 : EQ (face, Qheader_line) ? HEADER_LINE_FACE_ID
24104 : EQ (face, Qtool_bar) ? TOOL_BAR_FACE_ID
24105 : DEFAULT_FACE_ID;
24107 old_buffer = current_buffer;
24109 /* Save things including mode_line_proptrans_alist,
24110 and set that to nil so that we don't alter the outer value. */
24111 record_unwind_protect (unwind_format_mode_line,
24112 format_mode_line_unwind_data
24113 (XFRAME (WINDOW_FRAME (w)),
24114 old_buffer, selected_window, true));
24115 mode_line_proptrans_alist = Qnil;
24117 Fselect_window (window, Qt);
24118 set_buffer_internal_1 (XBUFFER (buffer));
24120 init_iterator (&it, w, -1, -1, NULL, face_id);
24122 if (no_props)
24124 mode_line_target = MODE_LINE_NOPROP;
24125 mode_line_string_face_prop = Qnil;
24126 mode_line_string_list = Qnil;
24127 string_start = MODE_LINE_NOPROP_LEN (0);
24129 else
24131 mode_line_target = MODE_LINE_STRING;
24132 mode_line_string_list = Qnil;
24133 mode_line_string_face = face;
24134 mode_line_string_face_prop
24135 = NILP (face) ? Qnil : list2 (Qface, face);
24138 push_kboard (FRAME_KBOARD (it.f));
24139 display_mode_element (&it, 0, 0, 0, format, Qnil, false);
24140 pop_kboard ();
24142 if (no_props)
24144 len = MODE_LINE_NOPROP_LEN (string_start);
24145 str = make_string (mode_line_noprop_buf + string_start, len);
24147 else
24149 mode_line_string_list = Fnreverse (mode_line_string_list);
24150 str = Fmapconcat (Qidentity, mode_line_string_list,
24151 empty_unibyte_string);
24154 unbind_to (count, Qnil);
24155 return str;
24158 /* Write a null-terminated, right justified decimal representation of
24159 the positive integer D to BUF using a minimal field width WIDTH. */
24161 static void
24162 pint2str (register char *buf, register int width, register ptrdiff_t d)
24164 register char *p = buf;
24166 if (d <= 0)
24167 *p++ = '0';
24168 else
24170 while (d > 0)
24172 *p++ = d % 10 + '0';
24173 d /= 10;
24177 for (width -= (int) (p - buf); width > 0; --width)
24178 *p++ = ' ';
24179 *p-- = '\0';
24180 while (p > buf)
24182 d = *buf;
24183 *buf++ = *p;
24184 *p-- = d;
24188 /* Write a null-terminated, right justified decimal and "human
24189 readable" representation of the nonnegative integer D to BUF using
24190 a minimal field width WIDTH. D should be smaller than 999.5e24. */
24192 static const char power_letter[] =
24194 0, /* no letter */
24195 'k', /* kilo */
24196 'M', /* mega */
24197 'G', /* giga */
24198 'T', /* tera */
24199 'P', /* peta */
24200 'E', /* exa */
24201 'Z', /* zetta */
24202 'Y' /* yotta */
24205 static void
24206 pint2hrstr (char *buf, int width, ptrdiff_t d)
24208 /* We aim to represent the nonnegative integer D as
24209 QUOTIENT.TENTHS * 10 ^ (3 * EXPONENT). */
24210 ptrdiff_t quotient = d;
24211 int remainder = 0;
24212 /* -1 means: do not use TENTHS. */
24213 int tenths = -1;
24214 int exponent = 0;
24216 /* Length of QUOTIENT.TENTHS as a string. */
24217 int length;
24219 char * psuffix;
24220 char * p;
24222 if (quotient >= 1000)
24224 /* Scale to the appropriate EXPONENT. */
24227 remainder = quotient % 1000;
24228 quotient /= 1000;
24229 exponent++;
24231 while (quotient >= 1000);
24233 /* Round to nearest and decide whether to use TENTHS or not. */
24234 if (quotient <= 9)
24236 tenths = remainder / 100;
24237 if (remainder % 100 >= 50)
24239 if (tenths < 9)
24240 tenths++;
24241 else
24243 quotient++;
24244 if (quotient == 10)
24245 tenths = -1;
24246 else
24247 tenths = 0;
24251 else
24252 if (remainder >= 500)
24254 if (quotient < 999)
24255 quotient++;
24256 else
24258 quotient = 1;
24259 exponent++;
24260 tenths = 0;
24265 /* Calculate the LENGTH of QUOTIENT.TENTHS as a string. */
24266 if (tenths == -1 && quotient <= 99)
24267 if (quotient <= 9)
24268 length = 1;
24269 else
24270 length = 2;
24271 else
24272 length = 3;
24273 p = psuffix = buf + max (width, length);
24275 /* Print EXPONENT. */
24276 *psuffix++ = power_letter[exponent];
24277 *psuffix = '\0';
24279 /* Print TENTHS. */
24280 if (tenths >= 0)
24282 *--p = '0' + tenths;
24283 *--p = '.';
24286 /* Print QUOTIENT. */
24289 int digit = quotient % 10;
24290 *--p = '0' + digit;
24292 while ((quotient /= 10) != 0);
24294 /* Print leading spaces. */
24295 while (buf < p)
24296 *--p = ' ';
24299 /* Set a mnemonic character for coding_system (Lisp symbol) in BUF.
24300 If EOL_FLAG, set also a mnemonic character for end-of-line
24301 type of CODING_SYSTEM. Return updated pointer into BUF. */
24303 static unsigned char invalid_eol_type[] = "(*invalid*)";
24305 static char *
24306 decode_mode_spec_coding (Lisp_Object coding_system, char *buf, bool eol_flag)
24308 Lisp_Object val;
24309 bool multibyte = !NILP (BVAR (current_buffer, enable_multibyte_characters));
24310 const unsigned char *eol_str;
24311 int eol_str_len;
24312 /* The EOL conversion we are using. */
24313 Lisp_Object eoltype;
24315 val = CODING_SYSTEM_SPEC (coding_system);
24316 eoltype = Qnil;
24318 if (!VECTORP (val)) /* Not yet decided. */
24320 *buf++ = multibyte ? '-' : ' ';
24321 if (eol_flag)
24322 eoltype = eol_mnemonic_undecided;
24323 /* Don't mention EOL conversion if it isn't decided. */
24325 else
24327 Lisp_Object attrs;
24328 Lisp_Object eolvalue;
24330 attrs = AREF (val, 0);
24331 eolvalue = AREF (val, 2);
24333 *buf++ = multibyte
24334 ? XFASTINT (CODING_ATTR_MNEMONIC (attrs))
24335 : ' ';
24337 if (eol_flag)
24339 /* The EOL conversion that is normal on this system. */
24341 if (NILP (eolvalue)) /* Not yet decided. */
24342 eoltype = eol_mnemonic_undecided;
24343 else if (VECTORP (eolvalue)) /* Not yet decided. */
24344 eoltype = eol_mnemonic_undecided;
24345 else /* eolvalue is Qunix, Qdos, or Qmac. */
24346 eoltype = (EQ (eolvalue, Qunix)
24347 ? eol_mnemonic_unix
24348 : EQ (eolvalue, Qdos)
24349 ? eol_mnemonic_dos : eol_mnemonic_mac);
24353 if (eol_flag)
24355 /* Mention the EOL conversion if it is not the usual one. */
24356 if (STRINGP (eoltype))
24358 eol_str = SDATA (eoltype);
24359 eol_str_len = SBYTES (eoltype);
24361 else if (CHARACTERP (eoltype))
24363 int c = XFASTINT (eoltype);
24364 return buf + CHAR_STRING (c, (unsigned char *) buf);
24366 else
24368 eol_str = invalid_eol_type;
24369 eol_str_len = sizeof (invalid_eol_type) - 1;
24371 memcpy (buf, eol_str, eol_str_len);
24372 buf += eol_str_len;
24375 return buf;
24378 /* Return the approximate percentage N is of D (rounding upward), or 99,
24379 whichever is less. Assume 0 < D and 0 <= N <= D * INT_MAX / 100. */
24381 static int
24382 percent99 (ptrdiff_t n, ptrdiff_t d)
24384 int percent = (d - 1 + 100.0 * n) / d;
24385 return min (percent, 99);
24388 /* Return a string for the output of a mode line %-spec for window W,
24389 generated by character C. FIELD_WIDTH > 0 means pad the string
24390 returned with spaces to that value. Return a Lisp string in
24391 *STRING if the resulting string is taken from that Lisp string.
24393 Note we operate on the current buffer for most purposes. */
24395 static char lots_of_dashes[] = "--------------------------------------------------------------------------------------------------------------------------------------------";
24397 static const char *
24398 decode_mode_spec (struct window *w, register int c, int field_width,
24399 Lisp_Object *string)
24401 Lisp_Object obj;
24402 struct frame *f = XFRAME (WINDOW_FRAME (w));
24403 char *decode_mode_spec_buf = f->decode_mode_spec_buffer;
24404 /* We are going to use f->decode_mode_spec_buffer as the buffer to
24405 produce strings from numerical values, so limit preposterously
24406 large values of FIELD_WIDTH to avoid overrunning the buffer's
24407 end. The size of the buffer is enough for FRAME_MESSAGE_BUF_SIZE
24408 bytes plus the terminating null. */
24409 int width = min (field_width, FRAME_MESSAGE_BUF_SIZE (f));
24410 struct buffer *b = current_buffer;
24412 obj = Qnil;
24413 *string = Qnil;
24415 switch (c)
24417 case '*':
24418 if (!NILP (BVAR (b, read_only)))
24419 return "%";
24420 if (BUF_MODIFF (b) > BUF_SAVE_MODIFF (b))
24421 return "*";
24422 return "-";
24424 case '+':
24425 /* This differs from %* only for a modified read-only buffer. */
24426 if (BUF_MODIFF (b) > BUF_SAVE_MODIFF (b))
24427 return "*";
24428 if (!NILP (BVAR (b, read_only)))
24429 return "%";
24430 return "-";
24432 case '&':
24433 /* This differs from %* in ignoring read-only-ness. */
24434 if (BUF_MODIFF (b) > BUF_SAVE_MODIFF (b))
24435 return "*";
24436 return "-";
24438 case '%':
24439 return "%";
24441 case '[':
24443 int i;
24444 char *p;
24446 if (command_loop_level > 5)
24447 return "[[[... ";
24448 p = decode_mode_spec_buf;
24449 for (i = 0; i < command_loop_level; i++)
24450 *p++ = '[';
24451 *p = 0;
24452 return decode_mode_spec_buf;
24455 case ']':
24457 int i;
24458 char *p;
24460 if (command_loop_level > 5)
24461 return " ...]]]";
24462 p = decode_mode_spec_buf;
24463 for (i = 0; i < command_loop_level; i++)
24464 *p++ = ']';
24465 *p = 0;
24466 return decode_mode_spec_buf;
24469 case '-':
24471 register int i;
24473 /* Let lots_of_dashes be a string of infinite length. */
24474 if (mode_line_target == MODE_LINE_NOPROP
24475 || mode_line_target == MODE_LINE_STRING)
24476 return "--";
24477 if (field_width <= 0
24478 || field_width > sizeof (lots_of_dashes))
24480 for (i = 0; i < FRAME_MESSAGE_BUF_SIZE (f) - 1; ++i)
24481 decode_mode_spec_buf[i] = '-';
24482 decode_mode_spec_buf[i] = '\0';
24483 return decode_mode_spec_buf;
24485 else
24486 return lots_of_dashes;
24489 case 'b':
24490 obj = BVAR (b, name);
24491 break;
24493 case 'c':
24494 case 'C':
24495 /* %c, %C, and %l are ignored in `frame-title-format'.
24496 (In redisplay_internal, the frame title is drawn _before_ the
24497 windows are updated, so the stuff which depends on actual
24498 window contents (such as %l) may fail to render properly, or
24499 even crash emacs.) */
24500 if (mode_line_target == MODE_LINE_TITLE)
24501 return "";
24502 else
24504 ptrdiff_t col = current_column ();
24505 int disp_col = (c == 'C') ? col + 1 : col;
24506 w->column_number_displayed = col;
24507 pint2str (decode_mode_spec_buf, width, disp_col);
24508 return decode_mode_spec_buf;
24511 case 'e':
24512 #if !defined SYSTEM_MALLOC && !defined HYBRID_MALLOC
24514 if (NILP (Vmemory_full))
24515 return "";
24516 else
24517 return "!MEM FULL! ";
24519 #else
24520 return "";
24521 #endif
24523 case 'F':
24524 /* %F displays the frame name. */
24525 if (!NILP (f->title))
24526 return SSDATA (f->title);
24527 if (f->explicit_name || ! FRAME_WINDOW_P (f))
24528 return SSDATA (f->name);
24529 return "Emacs";
24531 case 'f':
24532 obj = BVAR (b, filename);
24533 break;
24535 case 'i':
24537 ptrdiff_t size = ZV - BEGV;
24538 pint2str (decode_mode_spec_buf, width, size);
24539 return decode_mode_spec_buf;
24542 case 'I':
24544 ptrdiff_t size = ZV - BEGV;
24545 pint2hrstr (decode_mode_spec_buf, width, size);
24546 return decode_mode_spec_buf;
24549 case 'l':
24551 ptrdiff_t startpos, startpos_byte, line, linepos, linepos_byte;
24552 ptrdiff_t topline, nlines, height;
24553 ptrdiff_t junk;
24555 /* %c, %C, and %l are ignored in `frame-title-format'. */
24556 if (mode_line_target == MODE_LINE_TITLE)
24557 return "";
24559 startpos = marker_position (w->start);
24560 startpos_byte = marker_byte_position (w->start);
24561 height = WINDOW_TOTAL_LINES (w);
24563 /* If we decided that this buffer isn't suitable for line numbers,
24564 don't forget that too fast. */
24565 if (w->base_line_pos == -1)
24566 goto no_value;
24568 /* If the buffer is very big, don't waste time. */
24569 if (INTEGERP (Vline_number_display_limit)
24570 && BUF_ZV (b) - BUF_BEGV (b) > XINT (Vline_number_display_limit))
24572 w->base_line_pos = 0;
24573 w->base_line_number = 0;
24574 goto no_value;
24577 if (w->base_line_number > 0
24578 && w->base_line_pos > 0
24579 && w->base_line_pos <= startpos)
24581 line = w->base_line_number;
24582 linepos = w->base_line_pos;
24583 linepos_byte = buf_charpos_to_bytepos (b, linepos);
24585 else
24587 line = 1;
24588 linepos = BUF_BEGV (b);
24589 linepos_byte = BUF_BEGV_BYTE (b);
24592 /* Count lines from base line to window start position. */
24593 nlines = display_count_lines (linepos_byte,
24594 startpos_byte,
24595 startpos, &junk);
24597 topline = nlines + line;
24599 /* Determine a new base line, if the old one is too close
24600 or too far away, or if we did not have one.
24601 "Too close" means it's plausible a scroll-down would
24602 go back past it. */
24603 if (startpos == BUF_BEGV (b))
24605 w->base_line_number = topline;
24606 w->base_line_pos = BUF_BEGV (b);
24608 else if (nlines < height + 25 || nlines > height * 3 + 50
24609 || linepos == BUF_BEGV (b))
24611 ptrdiff_t limit = BUF_BEGV (b);
24612 ptrdiff_t limit_byte = BUF_BEGV_BYTE (b);
24613 ptrdiff_t position;
24614 ptrdiff_t distance =
24615 (height * 2 + 30) * line_number_display_limit_width;
24617 if (startpos - distance > limit)
24619 limit = startpos - distance;
24620 limit_byte = CHAR_TO_BYTE (limit);
24623 nlines = display_count_lines (startpos_byte,
24624 limit_byte,
24625 - (height * 2 + 30),
24626 &position);
24627 /* If we couldn't find the lines we wanted within
24628 line_number_display_limit_width chars per line,
24629 give up on line numbers for this window. */
24630 if (position == limit_byte && limit == startpos - distance)
24632 w->base_line_pos = -1;
24633 w->base_line_number = 0;
24634 goto no_value;
24637 w->base_line_number = topline - nlines;
24638 w->base_line_pos = BYTE_TO_CHAR (position);
24641 /* Now count lines from the start pos to point. */
24642 nlines = display_count_lines (startpos_byte,
24643 PT_BYTE, PT, &junk);
24645 /* Record that we did display the line number. */
24646 line_number_displayed = true;
24648 /* Make the string to show. */
24649 pint2str (decode_mode_spec_buf, width, topline + nlines);
24650 return decode_mode_spec_buf;
24651 no_value:
24653 char *p = decode_mode_spec_buf;
24654 int pad = width - 2;
24655 while (pad-- > 0)
24656 *p++ = ' ';
24657 *p++ = '?';
24658 *p++ = '?';
24659 *p = '\0';
24660 return decode_mode_spec_buf;
24663 break;
24665 case 'm':
24666 obj = BVAR (b, mode_name);
24667 break;
24669 case 'n':
24670 if (BUF_BEGV (b) > BUF_BEG (b) || BUF_ZV (b) < BUF_Z (b))
24671 return " Narrow";
24672 break;
24674 /* Display the "degree of travel" of the window through the buffer. */
24675 case 'o':
24677 ptrdiff_t toppos = marker_position (w->start);
24678 ptrdiff_t botpos = BUF_Z (b) - w->window_end_pos;
24679 ptrdiff_t begv = BUF_BEGV (b);
24680 ptrdiff_t zv = BUF_ZV (b);
24682 if (zv <= botpos)
24683 return toppos <= begv ? "All" : "Bottom";
24684 else if (toppos <= begv)
24685 return "Top";
24686 else
24688 sprintf (decode_mode_spec_buf, "%2d%%",
24689 percent99 (toppos - begv, (toppos - begv) + (zv - botpos)));
24690 return decode_mode_spec_buf;
24694 /* Display percentage of buffer above the top of the screen. */
24695 case 'p':
24697 ptrdiff_t pos = marker_position (w->start);
24698 ptrdiff_t begv = BUF_BEGV (b);
24699 ptrdiff_t zv = BUF_ZV (b);
24701 if (w->window_end_pos <= BUF_Z (b) - zv)
24702 return pos <= begv ? "All" : "Bottom";
24703 else if (pos <= begv)
24704 return "Top";
24705 else
24707 sprintf (decode_mode_spec_buf, "%2d%%",
24708 percent99 (pos - begv, zv - begv));
24709 return decode_mode_spec_buf;
24713 /* Display percentage of size above the bottom of the screen. */
24714 case 'P':
24716 ptrdiff_t toppos = marker_position (w->start);
24717 ptrdiff_t botpos = BUF_Z (b) - w->window_end_pos;
24718 ptrdiff_t begv = BUF_BEGV (b);
24719 ptrdiff_t zv = BUF_ZV (b);
24721 if (zv <= botpos)
24722 return toppos <= begv ? "All" : "Bottom";
24723 else
24725 sprintf (decode_mode_spec_buf,
24726 &"Top%2d%%"[begv < toppos ? sizeof "Top" - 1 : 0],
24727 percent99 (botpos - begv, zv - begv));
24728 return decode_mode_spec_buf;
24732 /* Display percentage offsets of top and bottom of the window,
24733 using "All" (but not "Top" or "Bottom") where appropriate. */
24734 case 'q':
24736 ptrdiff_t toppos = marker_position (w->start);
24737 ptrdiff_t botpos = BUF_Z (b) - w->window_end_pos;
24738 ptrdiff_t begv = BUF_BEGV (b);
24739 ptrdiff_t zv = BUF_ZV (b);
24740 int top_perc, bot_perc;
24742 if ((toppos <= begv) && (zv <= botpos))
24743 return "All ";
24745 top_perc = toppos <= begv ? 0 : percent99 (toppos - begv, zv - begv);
24746 bot_perc = zv <= botpos ? 100 : percent99 (botpos - begv, zv - begv);
24748 if (top_perc == bot_perc)
24749 sprintf (decode_mode_spec_buf, "%d%%", top_perc);
24750 else
24751 sprintf (decode_mode_spec_buf, "%d-%d%%", top_perc, bot_perc);
24753 return decode_mode_spec_buf;
24756 case 's':
24757 /* status of process */
24758 obj = Fget_buffer_process (Fcurrent_buffer ());
24759 if (NILP (obj))
24760 return "no process";
24761 #ifndef MSDOS
24762 obj = Fsymbol_name (Fprocess_status (obj));
24763 #endif
24764 break;
24766 case '@':
24768 ptrdiff_t count = inhibit_garbage_collection ();
24769 Lisp_Object curdir = BVAR (current_buffer, directory);
24770 Lisp_Object val = Qnil;
24772 if (STRINGP (curdir))
24773 val = call1 (intern ("file-remote-p"), curdir);
24775 unbind_to (count, Qnil);
24777 if (NILP (val))
24778 return "-";
24779 else
24780 return "@";
24783 case 'z':
24784 /* coding-system (not including end-of-line format) */
24785 case 'Z':
24786 /* coding-system (including end-of-line type) */
24788 bool eol_flag = (c == 'Z');
24789 char *p = decode_mode_spec_buf;
24791 if (! FRAME_WINDOW_P (f))
24793 /* No need to mention EOL here--the terminal never needs
24794 to do EOL conversion. */
24795 p = decode_mode_spec_coding (CODING_ID_NAME
24796 (FRAME_KEYBOARD_CODING (f)->id),
24797 p, false);
24798 p = decode_mode_spec_coding (CODING_ID_NAME
24799 (FRAME_TERMINAL_CODING (f)->id),
24800 p, false);
24802 p = decode_mode_spec_coding (BVAR (b, buffer_file_coding_system),
24803 p, eol_flag);
24805 #if false /* This proves to be annoying; I think we can do without. -- rms. */
24806 #ifdef subprocesses
24807 obj = Fget_buffer_process (Fcurrent_buffer ());
24808 if (PROCESSP (obj))
24810 p = decode_mode_spec_coding
24811 (XPROCESS (obj)->decode_coding_system, p, eol_flag);
24812 p = decode_mode_spec_coding
24813 (XPROCESS (obj)->encode_coding_system, p, eol_flag);
24815 #endif /* subprocesses */
24816 #endif /* false */
24817 *p = 0;
24818 return decode_mode_spec_buf;
24822 if (STRINGP (obj))
24824 *string = obj;
24825 return SSDATA (obj);
24827 else
24828 return "";
24832 /* Count up to COUNT lines starting from START_BYTE. COUNT negative
24833 means count lines back from START_BYTE. But don't go beyond
24834 LIMIT_BYTE. Return the number of lines thus found (always
24835 nonnegative).
24837 Set *BYTE_POS_PTR to the byte position where we stopped. This is
24838 either the position COUNT lines after/before START_BYTE, if we
24839 found COUNT lines, or LIMIT_BYTE if we hit the limit before finding
24840 COUNT lines. */
24842 static ptrdiff_t
24843 display_count_lines (ptrdiff_t start_byte,
24844 ptrdiff_t limit_byte, ptrdiff_t count,
24845 ptrdiff_t *byte_pos_ptr)
24847 register unsigned char *cursor;
24848 unsigned char *base;
24850 register ptrdiff_t ceiling;
24851 register unsigned char *ceiling_addr;
24852 ptrdiff_t orig_count = count;
24854 /* If we are not in selective display mode,
24855 check only for newlines. */
24856 bool selective_display
24857 = (!NILP (BVAR (current_buffer, selective_display))
24858 && !INTEGERP (BVAR (current_buffer, selective_display)));
24860 if (count > 0)
24862 while (start_byte < limit_byte)
24864 ceiling = BUFFER_CEILING_OF (start_byte);
24865 ceiling = min (limit_byte - 1, ceiling);
24866 ceiling_addr = BYTE_POS_ADDR (ceiling) + 1;
24867 base = (cursor = BYTE_POS_ADDR (start_byte));
24871 if (selective_display)
24873 while (*cursor != '\n' && *cursor != 015
24874 && ++cursor != ceiling_addr)
24875 continue;
24876 if (cursor == ceiling_addr)
24877 break;
24879 else
24881 cursor = memchr (cursor, '\n', ceiling_addr - cursor);
24882 if (! cursor)
24883 break;
24886 cursor++;
24888 if (--count == 0)
24890 start_byte += cursor - base;
24891 *byte_pos_ptr = start_byte;
24892 return orig_count;
24895 while (cursor < ceiling_addr);
24897 start_byte += ceiling_addr - base;
24900 else
24902 while (start_byte > limit_byte)
24904 ceiling = BUFFER_FLOOR_OF (start_byte - 1);
24905 ceiling = max (limit_byte, ceiling);
24906 ceiling_addr = BYTE_POS_ADDR (ceiling);
24907 base = (cursor = BYTE_POS_ADDR (start_byte - 1) + 1);
24908 while (true)
24910 if (selective_display)
24912 while (--cursor >= ceiling_addr
24913 && *cursor != '\n' && *cursor != 015)
24914 continue;
24915 if (cursor < ceiling_addr)
24916 break;
24918 else
24920 cursor = memrchr (ceiling_addr, '\n', cursor - ceiling_addr);
24921 if (! cursor)
24922 break;
24925 if (++count == 0)
24927 start_byte += cursor - base + 1;
24928 *byte_pos_ptr = start_byte;
24929 /* When scanning backwards, we should
24930 not count the newline posterior to which we stop. */
24931 return - orig_count - 1;
24934 start_byte += ceiling_addr - base;
24938 *byte_pos_ptr = limit_byte;
24940 if (count < 0)
24941 return - orig_count + count;
24942 return orig_count - count;
24948 /***********************************************************************
24949 Displaying strings
24950 ***********************************************************************/
24952 /* Display a NUL-terminated string, starting with index START.
24954 If STRING is non-null, display that C string. Otherwise, the Lisp
24955 string LISP_STRING is displayed. There's a case that STRING is
24956 non-null and LISP_STRING is not nil. It means STRING is a string
24957 data of LISP_STRING. In that case, we display LISP_STRING while
24958 ignoring its text properties.
24960 If FACE_STRING is not nil, FACE_STRING_POS is a position in
24961 FACE_STRING. Display STRING or LISP_STRING with the face at
24962 FACE_STRING_POS in FACE_STRING:
24964 Display the string in the environment given by IT, but use the
24965 standard display table, temporarily.
24967 FIELD_WIDTH is the minimum number of output glyphs to produce.
24968 If STRING has fewer characters than FIELD_WIDTH, pad to the right
24969 with spaces. If STRING has more characters, more than FIELD_WIDTH
24970 glyphs will be produced. FIELD_WIDTH <= 0 means don't pad.
24972 PRECISION is the maximum number of characters to output from
24973 STRING. PRECISION < 0 means don't truncate the string.
24975 This is roughly equivalent to printf format specifiers:
24977 FIELD_WIDTH PRECISION PRINTF
24978 ----------------------------------------
24979 -1 -1 %s
24980 -1 10 %.10s
24981 10 -1 %10s
24982 20 10 %20.10s
24984 MULTIBYTE zero means do not display multibyte chars, > 0 means do
24985 display them, and < 0 means obey the current buffer's value of
24986 enable_multibyte_characters.
24988 Value is the number of columns displayed. */
24990 static int
24991 display_string (const char *string, Lisp_Object lisp_string, Lisp_Object face_string,
24992 ptrdiff_t face_string_pos, ptrdiff_t start, struct it *it,
24993 int field_width, int precision, int max_x, int multibyte)
24995 int hpos_at_start = it->hpos;
24996 int saved_face_id = it->face_id;
24997 struct glyph_row *row = it->glyph_row;
24998 ptrdiff_t it_charpos;
25000 /* Initialize the iterator IT for iteration over STRING beginning
25001 with index START. */
25002 reseat_to_string (it, NILP (lisp_string) ? string : NULL, lisp_string, start,
25003 precision, field_width, multibyte);
25004 if (string && STRINGP (lisp_string))
25005 /* LISP_STRING is the one returned by decode_mode_spec. We should
25006 ignore its text properties. */
25007 it->stop_charpos = it->end_charpos;
25009 /* If displaying STRING, set up the face of the iterator from
25010 FACE_STRING, if that's given. */
25011 if (STRINGP (face_string))
25013 ptrdiff_t endptr;
25014 struct face *face;
25016 it->face_id
25017 = face_at_string_position (it->w, face_string, face_string_pos,
25018 0, &endptr, it->base_face_id, false);
25019 face = FACE_FROM_ID (it->f, it->face_id);
25020 it->face_box_p = face->box != FACE_NO_BOX;
25023 /* Set max_x to the maximum allowed X position. Don't let it go
25024 beyond the right edge of the window. */
25025 if (max_x <= 0)
25026 max_x = it->last_visible_x;
25027 else
25028 max_x = min (max_x, it->last_visible_x);
25030 /* Skip over display elements that are not visible. because IT->w is
25031 hscrolled. */
25032 if (it->current_x < it->first_visible_x)
25033 move_it_in_display_line_to (it, 100000, it->first_visible_x,
25034 MOVE_TO_POS | MOVE_TO_X);
25036 row->ascent = it->max_ascent;
25037 row->height = it->max_ascent + it->max_descent;
25038 row->phys_ascent = it->max_phys_ascent;
25039 row->phys_height = it->max_phys_ascent + it->max_phys_descent;
25040 row->extra_line_spacing = it->max_extra_line_spacing;
25042 if (STRINGP (it->string))
25043 it_charpos = IT_STRING_CHARPOS (*it);
25044 else
25045 it_charpos = IT_CHARPOS (*it);
25047 /* This condition is for the case that we are called with current_x
25048 past last_visible_x. */
25049 while (it->current_x < max_x)
25051 int x_before, x, n_glyphs_before, i, nglyphs;
25053 /* Get the next display element. */
25054 if (!get_next_display_element (it))
25055 break;
25057 /* Produce glyphs. */
25058 x_before = it->current_x;
25059 n_glyphs_before = row->used[TEXT_AREA];
25060 PRODUCE_GLYPHS (it);
25062 nglyphs = row->used[TEXT_AREA] - n_glyphs_before;
25063 i = 0;
25064 x = x_before;
25065 while (i < nglyphs)
25067 struct glyph *glyph = row->glyphs[TEXT_AREA] + n_glyphs_before + i;
25069 if (it->line_wrap != TRUNCATE
25070 && x + glyph->pixel_width > max_x)
25072 /* End of continued line or max_x reached. */
25073 if (CHAR_GLYPH_PADDING_P (*glyph))
25075 /* A wide character is unbreakable. */
25076 if (row->reversed_p)
25077 unproduce_glyphs (it, row->used[TEXT_AREA]
25078 - n_glyphs_before);
25079 row->used[TEXT_AREA] = n_glyphs_before;
25080 it->current_x = x_before;
25082 else
25084 if (row->reversed_p)
25085 unproduce_glyphs (it, row->used[TEXT_AREA]
25086 - (n_glyphs_before + i));
25087 row->used[TEXT_AREA] = n_glyphs_before + i;
25088 it->current_x = x;
25090 break;
25092 else if (x + glyph->pixel_width >= it->first_visible_x)
25094 /* Glyph is at least partially visible. */
25095 ++it->hpos;
25096 if (x < it->first_visible_x)
25097 row->x = x - it->first_visible_x;
25099 else
25101 /* Glyph is off the left margin of the display area.
25102 Should not happen. */
25103 emacs_abort ();
25106 row->ascent = max (row->ascent, it->max_ascent);
25107 row->height = max (row->height, it->max_ascent + it->max_descent);
25108 row->phys_ascent = max (row->phys_ascent, it->max_phys_ascent);
25109 row->phys_height = max (row->phys_height,
25110 it->max_phys_ascent + it->max_phys_descent);
25111 row->extra_line_spacing = max (row->extra_line_spacing,
25112 it->max_extra_line_spacing);
25113 x += glyph->pixel_width;
25114 ++i;
25117 /* Stop if max_x reached. */
25118 if (i < nglyphs)
25119 break;
25121 /* Stop at line ends. */
25122 if (ITERATOR_AT_END_OF_LINE_P (it))
25124 it->continuation_lines_width = 0;
25125 break;
25128 set_iterator_to_next (it, true);
25129 if (STRINGP (it->string))
25130 it_charpos = IT_STRING_CHARPOS (*it);
25131 else
25132 it_charpos = IT_CHARPOS (*it);
25134 /* Stop if truncating at the right edge. */
25135 if (it->line_wrap == TRUNCATE
25136 && it->current_x >= it->last_visible_x)
25138 /* Add truncation mark, but don't do it if the line is
25139 truncated at a padding space. */
25140 if (it_charpos < it->string_nchars)
25142 if (!FRAME_WINDOW_P (it->f))
25144 int ii, n;
25146 if (it->current_x > it->last_visible_x)
25148 if (!row->reversed_p)
25150 for (ii = row->used[TEXT_AREA] - 1; ii > 0; --ii)
25151 if (!CHAR_GLYPH_PADDING_P (row->glyphs[TEXT_AREA][ii]))
25152 break;
25154 else
25156 for (ii = 0; ii < row->used[TEXT_AREA]; ii++)
25157 if (!CHAR_GLYPH_PADDING_P (row->glyphs[TEXT_AREA][ii]))
25158 break;
25159 unproduce_glyphs (it, ii + 1);
25160 ii = row->used[TEXT_AREA] - (ii + 1);
25162 for (n = row->used[TEXT_AREA]; ii < n; ++ii)
25164 row->used[TEXT_AREA] = ii;
25165 produce_special_glyphs (it, IT_TRUNCATION);
25168 produce_special_glyphs (it, IT_TRUNCATION);
25170 row->truncated_on_right_p = true;
25172 break;
25176 /* Maybe insert a truncation at the left. */
25177 if (it->first_visible_x
25178 && it_charpos > 0)
25180 if (!FRAME_WINDOW_P (it->f)
25181 || (row->reversed_p
25182 ? WINDOW_RIGHT_FRINGE_WIDTH (it->w)
25183 : WINDOW_LEFT_FRINGE_WIDTH (it->w)) == 0)
25184 insert_left_trunc_glyphs (it);
25185 row->truncated_on_left_p = true;
25188 it->face_id = saved_face_id;
25190 /* Value is number of columns displayed. */
25191 return it->hpos - hpos_at_start;
25196 /* This is like a combination of memq and assq. Return 1/2 if PROPVAL
25197 appears as an element of LIST or as the car of an element of LIST.
25198 If PROPVAL is a list, compare each element against LIST in that
25199 way, and return 1/2 if any element of PROPVAL is found in LIST.
25200 Otherwise return 0. This function cannot quit.
25201 The return value is 2 if the text is invisible but with an ellipsis
25202 and 1 if it's invisible and without an ellipsis. */
25205 invisible_prop (Lisp_Object propval, Lisp_Object list)
25207 Lisp_Object tail, proptail;
25209 for (tail = list; CONSP (tail); tail = XCDR (tail))
25211 register Lisp_Object tem;
25212 tem = XCAR (tail);
25213 if (EQ (propval, tem))
25214 return 1;
25215 if (CONSP (tem) && EQ (propval, XCAR (tem)))
25216 return NILP (XCDR (tem)) ? 1 : 2;
25219 if (CONSP (propval))
25221 for (proptail = propval; CONSP (proptail); proptail = XCDR (proptail))
25223 Lisp_Object propelt;
25224 propelt = XCAR (proptail);
25225 for (tail = list; CONSP (tail); tail = XCDR (tail))
25227 register Lisp_Object tem;
25228 tem = XCAR (tail);
25229 if (EQ (propelt, tem))
25230 return 1;
25231 if (CONSP (tem) && EQ (propelt, XCAR (tem)))
25232 return NILP (XCDR (tem)) ? 1 : 2;
25237 return 0;
25240 DEFUN ("invisible-p", Finvisible_p, Sinvisible_p, 1, 1, 0,
25241 doc: /* Non-nil if text properties at POS cause text there to be currently invisible.
25242 POS should be a marker or a buffer position; the value of the `invisible'
25243 property at that position in the current buffer is examined.
25244 POS can also be the actual value of the `invisible' text or overlay
25245 property of the text of interest, in which case the value itself is
25246 examined.
25248 The non-nil value returned can be t for currently invisible text that is
25249 entirely hidden on display, or some other non-nil, non-t value if the
25250 text is replaced by an ellipsis.
25252 Note that whether text with `invisible' property is actually hidden on
25253 display may depend on `buffer-invisibility-spec', which see. */)
25254 (Lisp_Object pos)
25256 Lisp_Object prop
25257 = (NATNUMP (pos) || MARKERP (pos)
25258 ? Fget_char_property (pos, Qinvisible, Qnil)
25259 : pos);
25260 int invis = TEXT_PROP_MEANS_INVISIBLE (prop);
25261 return (invis == 0 ? Qnil
25262 : invis == 1 ? Qt
25263 : make_number (invis));
25266 /* Calculate a width or height in pixels from a specification using
25267 the following elements:
25269 SPEC ::=
25270 NUM - a (fractional) multiple of the default font width/height
25271 (NUM) - specifies exactly NUM pixels
25272 UNIT - a fixed number of pixels, see below.
25273 ELEMENT - size of a display element in pixels, see below.
25274 (NUM . SPEC) - equals NUM * SPEC
25275 (+ SPEC SPEC ...) - add pixel values
25276 (- SPEC SPEC ...) - subtract pixel values
25277 (- SPEC) - negate pixel value
25279 NUM ::=
25280 INT or FLOAT - a number constant
25281 SYMBOL - use symbol's (buffer local) variable binding.
25283 UNIT ::=
25284 in - pixels per inch *)
25285 mm - pixels per 1/1000 meter *)
25286 cm - pixels per 1/100 meter *)
25287 width - width of current font in pixels.
25288 height - height of current font in pixels.
25290 *) using the ratio(s) defined in display-pixels-per-inch.
25292 ELEMENT ::=
25294 left-fringe - left fringe width in pixels
25295 right-fringe - right fringe width in pixels
25297 left-margin - left margin width in pixels
25298 right-margin - right margin width in pixels
25300 scroll-bar - scroll-bar area width in pixels
25302 Examples:
25304 Pixels corresponding to 5 inches:
25305 (5 . in)
25307 Total width of non-text areas on left side of window (if scroll-bar is on left):
25308 '(space :width (+ left-fringe left-margin scroll-bar))
25310 Align to first text column (in header line):
25311 '(space :align-to 0)
25313 Align to middle of text area minus half the width of variable `my-image'
25314 containing a loaded image:
25315 '(space :align-to (0.5 . (- text my-image)))
25317 Width of left margin minus width of 1 character in the default font:
25318 '(space :width (- left-margin 1))
25320 Width of left margin minus width of 2 characters in the current font:
25321 '(space :width (- left-margin (2 . width)))
25323 Center 1 character over left-margin (in header line):
25324 '(space :align-to (+ left-margin (0.5 . left-margin) -0.5))
25326 Different ways to express width of left fringe plus left margin minus one pixel:
25327 '(space :width (- (+ left-fringe left-margin) (1)))
25328 '(space :width (+ left-fringe left-margin (- (1))))
25329 '(space :width (+ left-fringe left-margin (-1)))
25331 If ALIGN_TO is NULL, returns the result in *RES. If ALIGN_TO is
25332 non-NULL, the value of *ALIGN_TO is a window-relative pixel
25333 coordinate, and *RES is the additional pixel width from that point
25334 till the end of the stretch glyph.
25336 WIDTH_P non-zero means take the width dimension or X coordinate of
25337 the object specified by PROP, WIDTH_P zero means take the height
25338 dimension or the Y coordinate. (Therefore, if ALIGN_TO is
25339 non-NULL, WIDTH_P should be non-zero.)
25341 FONT is the font of the face of the surrounding text.
25343 The return value is non-zero if width or height were successfully
25344 calculated, i.e. if PROP is a valid spec. */
25346 static bool
25347 calc_pixel_width_or_height (double *res, struct it *it, Lisp_Object prop,
25348 struct font *font, bool width_p, int *align_to)
25350 double pixels;
25352 # define OK_PIXELS(val) (*res = (val), true)
25353 # define OK_ALIGN_TO(val) (*align_to = (val), true)
25355 if (NILP (prop))
25356 return OK_PIXELS (0);
25358 eassert (FRAME_LIVE_P (it->f));
25360 if (SYMBOLP (prop))
25362 if (SCHARS (SYMBOL_NAME (prop)) == 2)
25364 char *unit = SSDATA (SYMBOL_NAME (prop));
25366 /* The UNIT expression, e.g. as part of (NUM . UNIT). */
25367 if (unit[0] == 'i' && unit[1] == 'n')
25368 pixels = 1.0;
25369 else if (unit[0] == 'm' && unit[1] == 'm')
25370 pixels = 25.4;
25371 else if (unit[0] == 'c' && unit[1] == 'm')
25372 pixels = 2.54;
25373 else
25374 pixels = 0;
25375 if (pixels > 0)
25377 double ppi = (width_p ? FRAME_RES_X (it->f)
25378 : FRAME_RES_Y (it->f));
25380 if (ppi > 0)
25381 return OK_PIXELS (ppi / pixels);
25382 return false;
25386 #ifdef HAVE_WINDOW_SYSTEM
25387 /* 'height': the height of FONT. */
25388 if (EQ (prop, Qheight))
25389 return OK_PIXELS (font
25390 ? normal_char_height (font, -1)
25391 : FRAME_LINE_HEIGHT (it->f));
25392 /* 'width': the width of FONT. */
25393 if (EQ (prop, Qwidth))
25394 return OK_PIXELS (font
25395 ? FONT_WIDTH (font)
25396 : FRAME_COLUMN_WIDTH (it->f));
25397 #else
25398 if (EQ (prop, Qheight) || EQ (prop, Qwidth))
25399 return OK_PIXELS (1);
25400 #endif
25402 /* 'text': the width or height of the text area. */
25403 if (EQ (prop, Qtext))
25404 return OK_PIXELS (width_p
25405 ? (window_box_width (it->w, TEXT_AREA)
25406 - it->lnum_pixel_width)
25407 : WINDOW_BOX_HEIGHT_NO_MODE_LINE (it->w));
25409 /* ':align_to'. First time we compute the value, window
25410 elements are interpreted as the position of the element's
25411 left edge. */
25412 if (align_to && *align_to < 0)
25414 *res = 0;
25415 /* 'left': left edge of the text area. */
25416 if (EQ (prop, Qleft))
25417 return OK_ALIGN_TO (window_box_left_offset (it->w, TEXT_AREA)
25418 + it->lnum_pixel_width);
25419 /* 'right': right edge of the text area. */
25420 if (EQ (prop, Qright))
25421 return OK_ALIGN_TO (window_box_right_offset (it->w, TEXT_AREA));
25422 /* 'center': the center of the text area. */
25423 if (EQ (prop, Qcenter))
25424 return OK_ALIGN_TO (window_box_left_offset (it->w, TEXT_AREA)
25425 + it->lnum_pixel_width
25426 + window_box_width (it->w, TEXT_AREA) / 2);
25427 /* 'left-fringe': left edge of the left fringe. */
25428 if (EQ (prop, Qleft_fringe))
25429 return OK_ALIGN_TO (WINDOW_HAS_FRINGES_OUTSIDE_MARGINS (it->w)
25430 ? WINDOW_LEFT_SCROLL_BAR_AREA_WIDTH (it->w)
25431 : window_box_right_offset (it->w, LEFT_MARGIN_AREA));
25432 /* 'right-fringe': left edge of the right fringe. */
25433 if (EQ (prop, Qright_fringe))
25434 return OK_ALIGN_TO (WINDOW_HAS_FRINGES_OUTSIDE_MARGINS (it->w)
25435 ? window_box_right_offset (it->w, RIGHT_MARGIN_AREA)
25436 : window_box_right_offset (it->w, TEXT_AREA));
25437 /* 'left-margin': left edge of the left display margin. */
25438 if (EQ (prop, Qleft_margin))
25439 return OK_ALIGN_TO (window_box_left_offset (it->w, LEFT_MARGIN_AREA));
25440 /* 'right-margin': left edge of the right display margin. */
25441 if (EQ (prop, Qright_margin))
25442 return OK_ALIGN_TO (window_box_left_offset (it->w, RIGHT_MARGIN_AREA));
25443 /* 'scroll-bar': left edge of the vertical scroll bar. */
25444 if (EQ (prop, Qscroll_bar))
25445 return OK_ALIGN_TO (WINDOW_HAS_VERTICAL_SCROLL_BAR_ON_LEFT (it->w)
25447 : (window_box_right_offset (it->w, RIGHT_MARGIN_AREA)
25448 + (WINDOW_HAS_FRINGES_OUTSIDE_MARGINS (it->w)
25449 ? WINDOW_RIGHT_FRINGE_WIDTH (it->w)
25450 : 0)));
25452 else
25454 /* Otherwise, the elements stand for their width. */
25455 if (EQ (prop, Qleft_fringe))
25456 return OK_PIXELS (WINDOW_LEFT_FRINGE_WIDTH (it->w));
25457 if (EQ (prop, Qright_fringe))
25458 return OK_PIXELS (WINDOW_RIGHT_FRINGE_WIDTH (it->w));
25459 if (EQ (prop, Qleft_margin))
25460 return OK_PIXELS (WINDOW_LEFT_MARGIN_WIDTH (it->w));
25461 if (EQ (prop, Qright_margin))
25462 return OK_PIXELS (WINDOW_RIGHT_MARGIN_WIDTH (it->w));
25463 if (EQ (prop, Qscroll_bar))
25464 return OK_PIXELS (WINDOW_SCROLL_BAR_AREA_WIDTH (it->w));
25467 prop = buffer_local_value (prop, it->w->contents);
25468 if (EQ (prop, Qunbound))
25469 prop = Qnil;
25472 if (NUMBERP (prop))
25474 int base_unit = (width_p
25475 ? FRAME_COLUMN_WIDTH (it->f)
25476 : FRAME_LINE_HEIGHT (it->f));
25477 if (width_p && align_to && *align_to < 0)
25478 return OK_PIXELS (XFLOATINT (prop) * base_unit + it->lnum_pixel_width);
25479 return OK_PIXELS (XFLOATINT (prop) * base_unit);
25482 if (CONSP (prop))
25484 Lisp_Object car = XCAR (prop);
25485 Lisp_Object cdr = XCDR (prop);
25487 if (SYMBOLP (car))
25489 #ifdef HAVE_WINDOW_SYSTEM
25490 /* '(image PROPS...)': width or height of the specified image. */
25491 if (FRAME_WINDOW_P (it->f)
25492 && valid_image_p (prop))
25494 ptrdiff_t id = lookup_image (it->f, prop);
25495 struct image *img = IMAGE_FROM_ID (it->f, id);
25497 return OK_PIXELS (width_p ? img->width : img->height);
25499 /* '(xwidget PROPS...)': dimensions of the specified xwidget. */
25500 if (FRAME_WINDOW_P (it->f) && valid_xwidget_spec_p (prop))
25502 /* TODO: Don't return dummy size. */
25503 return OK_PIXELS (100);
25505 #endif
25506 /* '(+ EXPR...)' or '(- EXPR...)' add or subtract
25507 recursively calculated values. */
25508 if (EQ (car, Qplus) || EQ (car, Qminus))
25510 bool first = true;
25511 double px;
25513 pixels = 0;
25514 while (CONSP (cdr))
25516 if (!calc_pixel_width_or_height (&px, it, XCAR (cdr),
25517 font, width_p, align_to))
25518 return false;
25519 if (first)
25520 pixels = (EQ (car, Qplus) ? px : -px), first = false;
25521 else
25522 pixels += px;
25523 cdr = XCDR (cdr);
25525 if (EQ (car, Qminus))
25526 pixels = -pixels;
25527 return OK_PIXELS (pixels);
25530 car = buffer_local_value (car, it->w->contents);
25531 if (EQ (car, Qunbound))
25532 car = Qnil;
25535 /* '(NUM)': absolute number of pixels. */
25536 if (NUMBERP (car))
25538 double fact;
25539 int offset =
25540 width_p && align_to && *align_to < 0 ? it->lnum_pixel_width : 0;
25541 pixels = XFLOATINT (car);
25542 if (NILP (cdr))
25543 return OK_PIXELS (pixels + offset);
25544 if (calc_pixel_width_or_height (&fact, it, cdr,
25545 font, width_p, align_to))
25546 return OK_PIXELS (pixels * fact + offset);
25547 return false;
25550 return false;
25553 return false;
25556 void
25557 get_font_ascent_descent (struct font *font, int *ascent, int *descent)
25559 #ifdef HAVE_WINDOW_SYSTEM
25560 normal_char_ascent_descent (font, -1, ascent, descent);
25561 #else
25562 *ascent = 1;
25563 *descent = 0;
25564 #endif
25568 /***********************************************************************
25569 Glyph Display
25570 ***********************************************************************/
25572 #ifdef HAVE_WINDOW_SYSTEM
25574 #ifdef GLYPH_DEBUG
25576 void
25577 dump_glyph_string (struct glyph_string *s)
25579 fprintf (stderr, "glyph string\n");
25580 fprintf (stderr, " x, y, w, h = %d, %d, %d, %d\n",
25581 s->x, s->y, s->width, s->height);
25582 fprintf (stderr, " ybase = %d\n", s->ybase);
25583 fprintf (stderr, " hl = %u\n", s->hl);
25584 fprintf (stderr, " left overhang = %d, right = %d\n",
25585 s->left_overhang, s->right_overhang);
25586 fprintf (stderr, " nchars = %d\n", s->nchars);
25587 fprintf (stderr, " extends to end of line = %d\n",
25588 s->extends_to_end_of_line_p);
25589 fprintf (stderr, " font height = %d\n", FONT_HEIGHT (s->font));
25590 fprintf (stderr, " bg width = %d\n", s->background_width);
25593 #endif /* GLYPH_DEBUG */
25595 /* Initialize glyph string S. CHAR2B is a suitably allocated vector
25596 of XChar2b structures for S; it can't be allocated in
25597 init_glyph_string because it must be allocated via `alloca'. W
25598 is the window on which S is drawn. ROW and AREA are the glyph row
25599 and area within the row from which S is constructed. START is the
25600 index of the first glyph structure covered by S. HL is a
25601 face-override for drawing S. */
25603 #ifdef HAVE_NTGUI
25604 #define OPTIONAL_HDC(hdc) HDC hdc,
25605 #define DECLARE_HDC(hdc) HDC hdc;
25606 #define ALLOCATE_HDC(hdc, f) hdc = get_frame_dc ((f))
25607 #define RELEASE_HDC(hdc, f) release_frame_dc ((f), (hdc))
25608 #endif
25610 #ifndef OPTIONAL_HDC
25611 #define OPTIONAL_HDC(hdc)
25612 #define DECLARE_HDC(hdc)
25613 #define ALLOCATE_HDC(hdc, f)
25614 #define RELEASE_HDC(hdc, f)
25615 #endif
25617 static void
25618 init_glyph_string (struct glyph_string *s,
25619 OPTIONAL_HDC (hdc)
25620 XChar2b *char2b, struct window *w, struct glyph_row *row,
25621 enum glyph_row_area area, int start, enum draw_glyphs_face hl)
25623 memset (s, 0, sizeof *s);
25624 s->w = w;
25625 s->f = XFRAME (w->frame);
25626 #ifdef HAVE_NTGUI
25627 s->hdc = hdc;
25628 #endif
25629 s->display = FRAME_X_DISPLAY (s->f);
25630 s->char2b = char2b;
25631 s->hl = hl;
25632 s->row = row;
25633 s->area = area;
25634 s->first_glyph = row->glyphs[area] + start;
25635 s->height = row->height;
25636 s->y = WINDOW_TO_FRAME_PIXEL_Y (w, row->y);
25637 s->ybase = s->y + row->ascent;
25641 /* Append the list of glyph strings with head H and tail T to the list
25642 with head *HEAD and tail *TAIL. Set *HEAD and *TAIL to the result. */
25644 static void
25645 append_glyph_string_lists (struct glyph_string **head, struct glyph_string **tail,
25646 struct glyph_string *h, struct glyph_string *t)
25648 if (h)
25650 if (*head)
25651 (*tail)->next = h;
25652 else
25653 *head = h;
25654 h->prev = *tail;
25655 *tail = t;
25660 /* Prepend the list of glyph strings with head H and tail T to the
25661 list with head *HEAD and tail *TAIL. Set *HEAD and *TAIL to the
25662 result. */
25664 static void
25665 prepend_glyph_string_lists (struct glyph_string **head, struct glyph_string **tail,
25666 struct glyph_string *h, struct glyph_string *t)
25668 if (h)
25670 if (*head)
25671 (*head)->prev = t;
25672 else
25673 *tail = t;
25674 t->next = *head;
25675 *head = h;
25680 /* Append glyph string S to the list with head *HEAD and tail *TAIL.
25681 Set *HEAD and *TAIL to the resulting list. */
25683 static void
25684 append_glyph_string (struct glyph_string **head, struct glyph_string **tail,
25685 struct glyph_string *s)
25687 s->next = s->prev = NULL;
25688 append_glyph_string_lists (head, tail, s, s);
25692 /* Get face and two-byte form of character C in face FACE_ID on frame F.
25693 The encoding of C is returned in *CHAR2B. DISPLAY_P means
25694 make sure that X resources for the face returned are allocated.
25695 Value is a pointer to a realized face that is ready for display if
25696 DISPLAY_P. */
25698 static struct face *
25699 get_char_face_and_encoding (struct frame *f, int c, int face_id,
25700 XChar2b *char2b, bool display_p)
25702 struct face *face = FACE_FROM_ID (f, face_id);
25703 unsigned code = 0;
25705 if (face->font)
25707 code = face->font->driver->encode_char (face->font, c);
25709 if (code == FONT_INVALID_CODE)
25710 code = 0;
25712 STORE_XCHAR2B (char2b, (code >> 8), (code & 0xFF));
25714 /* Make sure X resources of the face are allocated. */
25715 #ifdef HAVE_X_WINDOWS
25716 if (display_p)
25717 #endif
25719 eassert (face != NULL);
25720 prepare_face_for_display (f, face);
25723 return face;
25727 /* Get face and two-byte form of character glyph GLYPH on frame F.
25728 The encoding of GLYPH->u.ch is returned in *CHAR2B. Value is
25729 a pointer to a realized face that is ready for display. */
25731 static struct face *
25732 get_glyph_face_and_encoding (struct frame *f, struct glyph *glyph,
25733 XChar2b *char2b)
25735 struct face *face;
25736 unsigned code = 0;
25738 eassert (glyph->type == CHAR_GLYPH);
25739 face = FACE_FROM_ID (f, glyph->face_id);
25741 /* Make sure X resources of the face are allocated. */
25742 prepare_face_for_display (f, face);
25744 if (face->font)
25746 if (CHAR_BYTE8_P (glyph->u.ch))
25747 code = CHAR_TO_BYTE8 (glyph->u.ch);
25748 else
25749 code = face->font->driver->encode_char (face->font, glyph->u.ch);
25751 if (code == FONT_INVALID_CODE)
25752 code = 0;
25755 STORE_XCHAR2B (char2b, (code >> 8), (code & 0xFF));
25756 return face;
25760 /* Get glyph code of character C in FONT in the two-byte form CHAR2B.
25761 Return true iff FONT has a glyph for C. */
25763 static bool
25764 get_char_glyph_code (int c, struct font *font, XChar2b *char2b)
25766 unsigned code;
25768 if (CHAR_BYTE8_P (c))
25769 code = CHAR_TO_BYTE8 (c);
25770 else
25771 code = font->driver->encode_char (font, c);
25773 if (code == FONT_INVALID_CODE)
25774 return false;
25775 STORE_XCHAR2B (char2b, (code >> 8), (code & 0xFF));
25776 return true;
25780 /* Fill glyph string S with composition components specified by S->cmp.
25782 BASE_FACE is the base face of the composition.
25783 S->cmp_from is the index of the first component for S.
25785 OVERLAPS non-zero means S should draw the foreground only, and use
25786 its physical height for clipping. See also draw_glyphs.
25788 Value is the index of a component not in S. */
25790 static int
25791 fill_composite_glyph_string (struct glyph_string *s, struct face *base_face,
25792 int overlaps)
25794 int i;
25795 /* For all glyphs of this composition, starting at the offset
25796 S->cmp_from, until we reach the end of the definition or encounter a
25797 glyph that requires the different face, add it to S. */
25798 struct face *face;
25800 eassert (s);
25802 s->for_overlaps = overlaps;
25803 s->face = NULL;
25804 s->font = NULL;
25805 for (i = s->cmp_from; i < s->cmp->glyph_len; i++)
25807 int c = COMPOSITION_GLYPH (s->cmp, i);
25809 /* TAB in a composition means display glyphs with padding space
25810 on the left or right. */
25811 if (c != '\t')
25813 int face_id = FACE_FOR_CHAR (s->f, base_face->ascii_face, c,
25814 -1, Qnil);
25816 face = get_char_face_and_encoding (s->f, c, face_id,
25817 s->char2b + i, true);
25818 if (face)
25820 if (! s->face)
25822 s->face = face;
25823 s->font = s->face->font;
25825 else if (s->face != face)
25826 break;
25829 ++s->nchars;
25831 s->cmp_to = i;
25833 if (s->face == NULL)
25835 s->face = base_face->ascii_face;
25836 s->font = s->face->font;
25839 /* All glyph strings for the same composition has the same width,
25840 i.e. the width set for the first component of the composition. */
25841 s->width = s->first_glyph->pixel_width;
25843 /* If the specified font could not be loaded, use the frame's
25844 default font, but record the fact that we couldn't load it in
25845 the glyph string so that we can draw rectangles for the
25846 characters of the glyph string. */
25847 if (s->font == NULL)
25849 s->font_not_found_p = true;
25850 s->font = FRAME_FONT (s->f);
25853 /* Adjust base line for subscript/superscript text. */
25854 s->ybase += s->first_glyph->voffset;
25856 return s->cmp_to;
25859 static int
25860 fill_gstring_glyph_string (struct glyph_string *s, int face_id,
25861 int start, int end, int overlaps)
25863 struct glyph *glyph, *last;
25864 Lisp_Object lgstring;
25865 int i;
25867 s->for_overlaps = overlaps;
25868 glyph = s->row->glyphs[s->area] + start;
25869 last = s->row->glyphs[s->area] + end;
25870 s->cmp_id = glyph->u.cmp.id;
25871 s->cmp_from = glyph->slice.cmp.from;
25872 s->cmp_to = glyph->slice.cmp.to + 1;
25873 s->face = FACE_FROM_ID (s->f, face_id);
25874 lgstring = composition_gstring_from_id (s->cmp_id);
25875 s->font = XFONT_OBJECT (LGSTRING_FONT (lgstring));
25876 glyph++;
25877 while (glyph < last
25878 && glyph->u.cmp.automatic
25879 && glyph->u.cmp.id == s->cmp_id
25880 && s->cmp_to == glyph->slice.cmp.from)
25881 s->cmp_to = (glyph++)->slice.cmp.to + 1;
25883 for (i = s->cmp_from; i < s->cmp_to; i++)
25885 Lisp_Object lglyph = LGSTRING_GLYPH (lgstring, i);
25886 unsigned code = LGLYPH_CODE (lglyph);
25888 STORE_XCHAR2B ((s->char2b + i), code >> 8, code & 0xFF);
25890 s->width = composition_gstring_width (lgstring, s->cmp_from, s->cmp_to, NULL);
25891 return glyph - s->row->glyphs[s->area];
25895 /* Fill glyph string S from a sequence glyphs for glyphless characters.
25896 See the comment of fill_glyph_string for arguments.
25897 Value is the index of the first glyph not in S. */
25900 static int
25901 fill_glyphless_glyph_string (struct glyph_string *s, int face_id,
25902 int start, int end, int overlaps)
25904 struct glyph *glyph, *last;
25905 int voffset;
25907 eassert (s->first_glyph->type == GLYPHLESS_GLYPH);
25908 s->for_overlaps = overlaps;
25909 glyph = s->row->glyphs[s->area] + start;
25910 last = s->row->glyphs[s->area] + end;
25911 voffset = glyph->voffset;
25912 s->face = FACE_FROM_ID (s->f, face_id);
25913 s->font = s->face->font ? s->face->font : FRAME_FONT (s->f);
25914 s->nchars = 1;
25915 s->width = glyph->pixel_width;
25916 glyph++;
25917 while (glyph < last
25918 && glyph->type == GLYPHLESS_GLYPH
25919 && glyph->voffset == voffset
25920 && glyph->face_id == face_id)
25922 s->nchars++;
25923 s->width += glyph->pixel_width;
25924 glyph++;
25926 s->ybase += voffset;
25927 return glyph - s->row->glyphs[s->area];
25931 /* Fill glyph string S from a sequence of character glyphs.
25933 FACE_ID is the face id of the string. START is the index of the
25934 first glyph to consider, END is the index of the last + 1.
25935 OVERLAPS non-zero means S should draw the foreground only, and use
25936 its physical height for clipping. See also draw_glyphs.
25938 Value is the index of the first glyph not in S. */
25940 static int
25941 fill_glyph_string (struct glyph_string *s, int face_id,
25942 int start, int end, int overlaps)
25944 struct glyph *glyph, *last;
25945 int voffset;
25946 bool glyph_not_available_p;
25948 eassert (s->f == XFRAME (s->w->frame));
25949 eassert (s->nchars == 0);
25950 eassert (start >= 0 && end > start);
25952 s->for_overlaps = overlaps;
25953 glyph = s->row->glyphs[s->area] + start;
25954 last = s->row->glyphs[s->area] + end;
25955 voffset = glyph->voffset;
25956 s->padding_p = glyph->padding_p;
25957 glyph_not_available_p = glyph->glyph_not_available_p;
25959 while (glyph < last
25960 && glyph->type == CHAR_GLYPH
25961 && glyph->voffset == voffset
25962 /* Same face id implies same font, nowadays. */
25963 && glyph->face_id == face_id
25964 && glyph->glyph_not_available_p == glyph_not_available_p)
25966 s->face = get_glyph_face_and_encoding (s->f, glyph,
25967 s->char2b + s->nchars);
25968 ++s->nchars;
25969 eassert (s->nchars <= end - start);
25970 s->width += glyph->pixel_width;
25971 if (glyph++->padding_p != s->padding_p)
25972 break;
25975 s->font = s->face->font;
25977 /* If the specified font could not be loaded, use the frame's font,
25978 but record the fact that we couldn't load it in
25979 S->font_not_found_p so that we can draw rectangles for the
25980 characters of the glyph string. */
25981 if (s->font == NULL || glyph_not_available_p)
25983 s->font_not_found_p = true;
25984 s->font = FRAME_FONT (s->f);
25987 /* Adjust base line for subscript/superscript text. */
25988 s->ybase += voffset;
25990 eassert (s->face && s->face->gc);
25991 return glyph - s->row->glyphs[s->area];
25995 /* Fill glyph string S from image glyph S->first_glyph. */
25997 static void
25998 fill_image_glyph_string (struct glyph_string *s)
26000 eassert (s->first_glyph->type == IMAGE_GLYPH);
26001 s->img = IMAGE_FROM_ID (s->f, s->first_glyph->u.img_id);
26002 eassert (s->img);
26003 s->slice = s->first_glyph->slice.img;
26004 s->face = FACE_FROM_ID (s->f, s->first_glyph->face_id);
26005 s->font = s->face->font;
26006 s->width = s->first_glyph->pixel_width;
26008 /* Adjust base line for subscript/superscript text. */
26009 s->ybase += s->first_glyph->voffset;
26013 #ifdef HAVE_XWIDGETS
26014 static void
26015 fill_xwidget_glyph_string (struct glyph_string *s)
26017 eassert (s->first_glyph->type == XWIDGET_GLYPH);
26018 s->face = FACE_FROM_ID (s->f, s->first_glyph->face_id);
26019 s->font = s->face->font;
26020 s->width = s->first_glyph->pixel_width;
26021 s->ybase += s->first_glyph->voffset;
26022 s->xwidget = s->first_glyph->u.xwidget;
26024 #endif
26025 /* Fill glyph string S from a sequence of stretch glyphs.
26027 START is the index of the first glyph to consider,
26028 END is the index of the last + 1.
26030 Value is the index of the first glyph not in S. */
26032 static int
26033 fill_stretch_glyph_string (struct glyph_string *s, int start, int end)
26035 struct glyph *glyph, *last;
26036 int voffset, face_id;
26038 eassert (s->first_glyph->type == STRETCH_GLYPH);
26040 glyph = s->row->glyphs[s->area] + start;
26041 last = s->row->glyphs[s->area] + end;
26042 face_id = glyph->face_id;
26043 s->face = FACE_FROM_ID (s->f, face_id);
26044 s->font = s->face->font;
26045 s->width = glyph->pixel_width;
26046 s->nchars = 1;
26047 voffset = glyph->voffset;
26049 for (++glyph;
26050 (glyph < last
26051 && glyph->type == STRETCH_GLYPH
26052 && glyph->voffset == voffset
26053 && glyph->face_id == face_id);
26054 ++glyph)
26055 s->width += glyph->pixel_width;
26057 /* Adjust base line for subscript/superscript text. */
26058 s->ybase += voffset;
26060 /* The case that face->gc == 0 is handled when drawing the glyph
26061 string by calling prepare_face_for_display. */
26062 eassert (s->face);
26063 return glyph - s->row->glyphs[s->area];
26066 static struct font_metrics *
26067 get_per_char_metric (struct font *font, XChar2b *char2b)
26069 static struct font_metrics metrics;
26070 unsigned code;
26072 if (! font)
26073 return NULL;
26074 code = (XCHAR2B_BYTE1 (char2b) << 8) | XCHAR2B_BYTE2 (char2b);
26075 if (code == FONT_INVALID_CODE)
26076 return NULL;
26077 font->driver->text_extents (font, &code, 1, &metrics);
26078 return &metrics;
26081 /* A subroutine that computes "normal" values of ASCENT and DESCENT
26082 for FONT. Values are taken from font-global ones, except for fonts
26083 that claim preposterously large values, but whose glyphs actually
26084 have reasonable dimensions. C is the character to use for metrics
26085 if the font-global values are too large; if C is negative, the
26086 function selects a default character. */
26087 static void
26088 normal_char_ascent_descent (struct font *font, int c, int *ascent, int *descent)
26090 *ascent = FONT_BASE (font);
26091 *descent = FONT_DESCENT (font);
26093 if (FONT_TOO_HIGH (font))
26095 XChar2b char2b;
26097 /* Get metrics of C, defaulting to a reasonably sized ASCII
26098 character. */
26099 if (get_char_glyph_code (c >= 0 ? c : '{', font, &char2b))
26101 struct font_metrics *pcm = get_per_char_metric (font, &char2b);
26103 if (!(pcm->width == 0 && pcm->rbearing == 0 && pcm->lbearing == 0))
26105 /* We add 1 pixel to character dimensions as heuristics
26106 that produces nicer display, e.g. when the face has
26107 the box attribute. */
26108 *ascent = pcm->ascent + 1;
26109 *descent = pcm->descent + 1;
26115 /* A subroutine that computes a reasonable "normal character height"
26116 for fonts that claim preposterously large vertical dimensions, but
26117 whose glyphs are actually reasonably sized. C is the character
26118 whose metrics to use for those fonts, or -1 for default
26119 character. */
26120 static int
26121 normal_char_height (struct font *font, int c)
26123 int ascent, descent;
26125 normal_char_ascent_descent (font, c, &ascent, &descent);
26127 return ascent + descent;
26130 /* EXPORT for RIF:
26131 Set *LEFT and *RIGHT to the left and right overhang of GLYPH on
26132 frame F. Overhangs of glyphs other than type CHAR_GLYPH are
26133 assumed to be zero. */
26135 void
26136 x_get_glyph_overhangs (struct glyph *glyph, struct frame *f, int *left, int *right)
26138 *left = *right = 0;
26140 if (glyph->type == CHAR_GLYPH)
26142 XChar2b char2b;
26143 struct face *face = get_glyph_face_and_encoding (f, glyph, &char2b);
26144 if (face->font)
26146 struct font_metrics *pcm = get_per_char_metric (face->font, &char2b);
26147 if (pcm)
26149 if (pcm->rbearing > pcm->width)
26150 *right = pcm->rbearing - pcm->width;
26151 if (pcm->lbearing < 0)
26152 *left = -pcm->lbearing;
26156 else if (glyph->type == COMPOSITE_GLYPH)
26158 if (! glyph->u.cmp.automatic)
26160 struct composition *cmp = composition_table[glyph->u.cmp.id];
26162 if (cmp->rbearing > cmp->pixel_width)
26163 *right = cmp->rbearing - cmp->pixel_width;
26164 if (cmp->lbearing < 0)
26165 *left = - cmp->lbearing;
26167 else
26169 Lisp_Object gstring = composition_gstring_from_id (glyph->u.cmp.id);
26170 struct font_metrics metrics;
26172 composition_gstring_width (gstring, glyph->slice.cmp.from,
26173 glyph->slice.cmp.to + 1, &metrics);
26174 if (metrics.rbearing > metrics.width)
26175 *right = metrics.rbearing - metrics.width;
26176 if (metrics.lbearing < 0)
26177 *left = - metrics.lbearing;
26183 /* Return the index of the first glyph preceding glyph string S that
26184 is overwritten by S because of S's left overhang. Value is -1
26185 if no glyphs are overwritten. */
26187 static int
26188 left_overwritten (struct glyph_string *s)
26190 int k;
26192 if (s->left_overhang)
26194 int x = 0, i;
26195 struct glyph *glyphs = s->row->glyphs[s->area];
26196 int first = s->first_glyph - glyphs;
26198 for (i = first - 1; i >= 0 && x > -s->left_overhang; --i)
26199 x -= glyphs[i].pixel_width;
26201 k = i + 1;
26203 else
26204 k = -1;
26206 return k;
26210 /* Return the index of the first glyph preceding glyph string S that
26211 is overwriting S because of its right overhang. Value is -1 if no
26212 glyph in front of S overwrites S. */
26214 static int
26215 left_overwriting (struct glyph_string *s)
26217 int i, k, x;
26218 struct glyph *glyphs = s->row->glyphs[s->area];
26219 int first = s->first_glyph - glyphs;
26221 k = -1;
26222 x = 0;
26223 for (i = first - 1; i >= 0; --i)
26225 int left, right;
26226 x_get_glyph_overhangs (glyphs + i, s->f, &left, &right);
26227 if (x + right > 0)
26228 k = i;
26229 x -= glyphs[i].pixel_width;
26232 return k;
26236 /* Return the index of the last glyph following glyph string S that is
26237 overwritten by S because of S's right overhang. Value is -1 if
26238 no such glyph is found. */
26240 static int
26241 right_overwritten (struct glyph_string *s)
26243 int k = -1;
26245 if (s->right_overhang)
26247 int x = 0, i;
26248 struct glyph *glyphs = s->row->glyphs[s->area];
26249 int first = (s->first_glyph - glyphs
26250 + (s->first_glyph->type == COMPOSITE_GLYPH ? 1 : s->nchars));
26251 int end = s->row->used[s->area];
26253 for (i = first; i < end && s->right_overhang > x; ++i)
26254 x += glyphs[i].pixel_width;
26256 k = i;
26259 return k;
26263 /* Return the index of the last glyph following glyph string S that
26264 overwrites S because of its left overhang. Value is negative
26265 if no such glyph is found. */
26267 static int
26268 right_overwriting (struct glyph_string *s)
26270 int i, k, x;
26271 int end = s->row->used[s->area];
26272 struct glyph *glyphs = s->row->glyphs[s->area];
26273 int first = (s->first_glyph - glyphs
26274 + (s->first_glyph->type == COMPOSITE_GLYPH ? 1 : s->nchars));
26276 k = -1;
26277 x = 0;
26278 for (i = first; i < end; ++i)
26280 int left, right;
26281 x_get_glyph_overhangs (glyphs + i, s->f, &left, &right);
26282 if (x - left < 0)
26283 k = i;
26284 x += glyphs[i].pixel_width;
26287 return k;
26291 /* Set background width of glyph string S. START is the index of the
26292 first glyph following S. LAST_X is the right-most x-position + 1
26293 in the drawing area. */
26295 static void
26296 set_glyph_string_background_width (struct glyph_string *s, int start, int last_x)
26298 /* If the face of this glyph string has to be drawn to the end of
26299 the drawing area, set S->extends_to_end_of_line_p. */
26301 if (start == s->row->used[s->area]
26302 && ((s->row->fill_line_p
26303 && (s->hl == DRAW_NORMAL_TEXT
26304 || s->hl == DRAW_IMAGE_RAISED
26305 || s->hl == DRAW_IMAGE_SUNKEN))
26306 || s->hl == DRAW_MOUSE_FACE))
26307 s->extends_to_end_of_line_p = true;
26309 /* If S extends its face to the end of the line, set its
26310 background_width to the distance to the right edge of the drawing
26311 area. */
26312 if (s->extends_to_end_of_line_p)
26313 s->background_width = last_x - s->x + 1;
26314 else
26315 s->background_width = s->width;
26319 /* Return glyph string that shares background with glyph string S and
26320 whose `background_width' member has been set. */
26322 static struct glyph_string *
26323 glyph_string_containing_background_width (struct glyph_string *s)
26325 if (s->cmp)
26326 while (s->cmp_from)
26327 s = s->prev;
26329 return s;
26333 /* Compute overhangs and x-positions for glyph string S and its
26334 predecessors, or successors. X is the starting x-position for S.
26335 BACKWARD_P means process predecessors. */
26337 static void
26338 compute_overhangs_and_x (struct glyph_string *s, int x, bool backward_p)
26340 if (backward_p)
26342 while (s)
26344 if (FRAME_RIF (s->f)->compute_glyph_string_overhangs)
26345 FRAME_RIF (s->f)->compute_glyph_string_overhangs (s);
26346 if (!s->cmp || s->cmp_to == s->cmp->glyph_len)
26347 x -= s->width;
26348 s->x = x;
26349 s = s->prev;
26352 else
26354 while (s)
26356 if (FRAME_RIF (s->f)->compute_glyph_string_overhangs)
26357 FRAME_RIF (s->f)->compute_glyph_string_overhangs (s);
26358 s->x = x;
26359 if (!s->cmp || s->cmp_to == s->cmp->glyph_len)
26360 x += s->width;
26361 s = s->next;
26368 /* The following macros are only called from draw_glyphs below.
26369 They reference the following parameters of that function directly:
26370 `w', `row', `area', and `overlap_p'
26371 as well as the following local variables:
26372 `s', `f', and `hdc' (in W32) */
26374 #ifdef HAVE_NTGUI
26375 /* On W32, silently add local `hdc' variable to argument list of
26376 init_glyph_string. */
26377 #define INIT_GLYPH_STRING(s, char2b, w, row, area, start, hl) \
26378 init_glyph_string (s, hdc, char2b, w, row, area, start, hl)
26379 #else
26380 #define INIT_GLYPH_STRING(s, char2b, w, row, area, start, hl) \
26381 init_glyph_string (s, char2b, w, row, area, start, hl)
26382 #endif
26384 /* Add a glyph string for a stretch glyph to the list of strings
26385 between HEAD and TAIL. START is the index of the stretch glyph in
26386 row area AREA of glyph row ROW. END is the index of the last glyph
26387 in that glyph row area. X is the current output position assigned
26388 to the new glyph string constructed. HL overrides that face of the
26389 glyph; e.g. it is DRAW_CURSOR if a cursor has to be drawn. LAST_X
26390 is the right-most x-position of the drawing area. */
26392 /* SunOS 4 bundled cc, barfed on continuations in the arg lists here
26393 and below -- keep them on one line. */
26394 #define BUILD_STRETCH_GLYPH_STRING(START, END, HEAD, TAIL, HL, X, LAST_X) \
26395 do \
26397 s = alloca (sizeof *s); \
26398 INIT_GLYPH_STRING (s, NULL, w, row, area, START, HL); \
26399 START = fill_stretch_glyph_string (s, START, END); \
26400 append_glyph_string (&HEAD, &TAIL, s); \
26401 s->x = (X); \
26403 while (false)
26406 /* Add a glyph string for an image glyph to the list of strings
26407 between HEAD and TAIL. START is the index of the image glyph in
26408 row area AREA of glyph row ROW. END is the index of the last glyph
26409 in that glyph row area. X is the current output position assigned
26410 to the new glyph string constructed. HL overrides that face of the
26411 glyph; e.g. it is DRAW_CURSOR if a cursor has to be drawn. LAST_X
26412 is the right-most x-position of the drawing area. */
26414 #define BUILD_IMAGE_GLYPH_STRING(START, END, HEAD, TAIL, HL, X, LAST_X) \
26415 do \
26417 s = alloca (sizeof *s); \
26418 INIT_GLYPH_STRING (s, NULL, w, row, area, START, HL); \
26419 fill_image_glyph_string (s); \
26420 append_glyph_string (&HEAD, &TAIL, s); \
26421 ++START; \
26422 s->x = (X); \
26424 while (false)
26426 #ifndef HAVE_XWIDGETS
26427 # define BUILD_XWIDGET_GLYPH_STRING(START, END, HEAD, TAIL, HL, X, LAST_X) \
26428 eassume (false)
26429 #else
26430 # define BUILD_XWIDGET_GLYPH_STRING(START, END, HEAD, TAIL, HL, X, LAST_X) \
26431 do \
26433 s = alloca (sizeof *s); \
26434 INIT_GLYPH_STRING (s, NULL, w, row, area, START, HL); \
26435 fill_xwidget_glyph_string (s); \
26436 append_glyph_string (&(HEAD), &(TAIL), s); \
26437 ++(START); \
26438 s->x = (X); \
26440 while (false)
26441 #endif
26443 /* Add a glyph string for a sequence of character glyphs to the list
26444 of strings between HEAD and TAIL. START is the index of the first
26445 glyph in row area AREA of glyph row ROW that is part of the new
26446 glyph string. END is the index of the last glyph in that glyph row
26447 area. X is the current output position assigned to the new glyph
26448 string constructed. HL overrides that face of the glyph; e.g. it
26449 is DRAW_CURSOR if a cursor has to be drawn. LAST_X is the
26450 right-most x-position of the drawing area. */
26452 #define BUILD_CHAR_GLYPH_STRINGS(START, END, HEAD, TAIL, HL, X, LAST_X) \
26453 do \
26455 int face_id; \
26456 XChar2b *char2b; \
26458 face_id = (row)->glyphs[area][START].face_id; \
26460 s = alloca (sizeof *s); \
26461 SAFE_NALLOCA (char2b, 1, (END) - (START)); \
26462 INIT_GLYPH_STRING (s, char2b, w, row, area, START, HL); \
26463 append_glyph_string (&HEAD, &TAIL, s); \
26464 s->x = (X); \
26465 START = fill_glyph_string (s, face_id, START, END, overlaps); \
26467 while (false)
26470 /* Add a glyph string for a composite sequence to the list of strings
26471 between HEAD and TAIL. START is the index of the first glyph in
26472 row area AREA of glyph row ROW that is part of the new glyph
26473 string. END is the index of the last glyph in that glyph row area.
26474 X is the current output position assigned to the new glyph string
26475 constructed. HL overrides that face of the glyph; e.g. it is
26476 DRAW_CURSOR if a cursor has to be drawn. LAST_X is the right-most
26477 x-position of the drawing area. */
26479 #define BUILD_COMPOSITE_GLYPH_STRING(START, END, HEAD, TAIL, HL, X, LAST_X) \
26480 do { \
26481 int face_id = (row)->glyphs[area][START].face_id; \
26482 struct face *base_face = FACE_FROM_ID (f, face_id); \
26483 ptrdiff_t cmp_id = (row)->glyphs[area][START].u.cmp.id; \
26484 struct composition *cmp = composition_table[cmp_id]; \
26485 XChar2b *char2b; \
26486 struct glyph_string *first_s = NULL; \
26487 int n; \
26489 SAFE_NALLOCA (char2b, 1, cmp->glyph_len); \
26491 /* Make glyph_strings for each glyph sequence that is drawable by \
26492 the same face, and append them to HEAD/TAIL. */ \
26493 for (n = 0; n < cmp->glyph_len;) \
26495 s = alloca (sizeof *s); \
26496 INIT_GLYPH_STRING (s, char2b, w, row, area, START, HL); \
26497 append_glyph_string (&(HEAD), &(TAIL), s); \
26498 s->cmp = cmp; \
26499 s->cmp_from = n; \
26500 s->x = (X); \
26501 if (n == 0) \
26502 first_s = s; \
26503 n = fill_composite_glyph_string (s, base_face, overlaps); \
26506 ++START; \
26507 s = first_s; \
26508 } while (false)
26511 /* Add a glyph string for a glyph-string sequence to the list of strings
26512 between HEAD and TAIL. */
26514 #define BUILD_GSTRING_GLYPH_STRING(START, END, HEAD, TAIL, HL, X, LAST_X) \
26515 do { \
26516 int face_id; \
26517 XChar2b *char2b; \
26518 Lisp_Object gstring; \
26520 face_id = (row)->glyphs[area][START].face_id; \
26521 gstring = (composition_gstring_from_id \
26522 ((row)->glyphs[area][START].u.cmp.id)); \
26523 s = alloca (sizeof *s); \
26524 SAFE_NALLOCA (char2b, 1, LGSTRING_GLYPH_LEN (gstring)); \
26525 INIT_GLYPH_STRING (s, char2b, w, row, area, START, HL); \
26526 append_glyph_string (&(HEAD), &(TAIL), s); \
26527 s->x = (X); \
26528 START = fill_gstring_glyph_string (s, face_id, START, END, overlaps); \
26529 } while (false)
26532 /* Add a glyph string for a sequence of glyphless character's glyphs
26533 to the list of strings between HEAD and TAIL. The meanings of
26534 arguments are the same as those of BUILD_CHAR_GLYPH_STRINGS. */
26536 #define BUILD_GLYPHLESS_GLYPH_STRING(START, END, HEAD, TAIL, HL, X, LAST_X) \
26537 do \
26539 int face_id; \
26541 face_id = (row)->glyphs[area][START].face_id; \
26543 s = alloca (sizeof *s); \
26544 INIT_GLYPH_STRING (s, NULL, w, row, area, START, HL); \
26545 append_glyph_string (&HEAD, &TAIL, s); \
26546 s->x = (X); \
26547 START = fill_glyphless_glyph_string (s, face_id, START, END, \
26548 overlaps); \
26550 while (false)
26553 /* Build a list of glyph strings between HEAD and TAIL for the glyphs
26554 of AREA of glyph row ROW on window W between indices START and END.
26555 HL overrides the face for drawing glyph strings, e.g. it is
26556 DRAW_CURSOR to draw a cursor. X and LAST_X are start and end
26557 x-positions of the drawing area.
26559 This is an ugly monster macro construct because we must use alloca
26560 to allocate glyph strings (because draw_glyphs can be called
26561 asynchronously). */
26563 #define BUILD_GLYPH_STRINGS_1(START, END, HEAD, TAIL, HL, X, LAST_X) \
26564 do \
26566 HEAD = TAIL = NULL; \
26567 while (START < END) \
26569 struct glyph *first_glyph = (row)->glyphs[area] + START; \
26570 switch (first_glyph->type) \
26572 case CHAR_GLYPH: \
26573 BUILD_CHAR_GLYPH_STRINGS (START, END, HEAD, TAIL, \
26574 HL, X, LAST_X); \
26575 break; \
26577 case COMPOSITE_GLYPH: \
26578 if (first_glyph->u.cmp.automatic) \
26579 BUILD_GSTRING_GLYPH_STRING (START, END, HEAD, TAIL, \
26580 HL, X, LAST_X); \
26581 else \
26582 BUILD_COMPOSITE_GLYPH_STRING (START, END, HEAD, TAIL, \
26583 HL, X, LAST_X); \
26584 break; \
26586 case STRETCH_GLYPH: \
26587 BUILD_STRETCH_GLYPH_STRING (START, END, HEAD, TAIL, \
26588 HL, X, LAST_X); \
26589 break; \
26591 case IMAGE_GLYPH: \
26592 BUILD_IMAGE_GLYPH_STRING (START, END, HEAD, TAIL, \
26593 HL, X, LAST_X); \
26594 break;
26596 #define BUILD_GLYPH_STRINGS_XW(START, END, HEAD, TAIL, HL, X, LAST_X) \
26597 case XWIDGET_GLYPH: \
26598 BUILD_XWIDGET_GLYPH_STRING (START, END, HEAD, TAIL, \
26599 HL, X, LAST_X); \
26600 break;
26602 #define BUILD_GLYPH_STRINGS_2(START, END, HEAD, TAIL, HL, X, LAST_X) \
26603 case GLYPHLESS_GLYPH: \
26604 BUILD_GLYPHLESS_GLYPH_STRING (START, END, HEAD, TAIL, \
26605 HL, X, LAST_X); \
26606 break; \
26608 default: \
26609 emacs_abort (); \
26612 if (s) \
26614 set_glyph_string_background_width (s, START, LAST_X); \
26615 (X) += s->width; \
26618 } while (false)
26621 #define BUILD_GLYPH_STRINGS(START, END, HEAD, TAIL, HL, X, LAST_X) \
26622 BUILD_GLYPH_STRINGS_1(START, END, HEAD, TAIL, HL, X, LAST_X) \
26623 BUILD_GLYPH_STRINGS_XW(START, END, HEAD, TAIL, HL, X, LAST_X) \
26624 BUILD_GLYPH_STRINGS_2(START, END, HEAD, TAIL, HL, X, LAST_X)
26627 /* Draw glyphs between START and END in AREA of ROW on window W,
26628 starting at x-position X. X is relative to AREA in W. HL is a
26629 face-override with the following meaning:
26631 DRAW_NORMAL_TEXT draw normally
26632 DRAW_CURSOR draw in cursor face
26633 DRAW_MOUSE_FACE draw in mouse face.
26634 DRAW_INVERSE_VIDEO draw in mode line face
26635 DRAW_IMAGE_SUNKEN draw an image with a sunken relief around it
26636 DRAW_IMAGE_RAISED draw an image with a raised relief around it
26638 If OVERLAPS is non-zero, draw only the foreground of characters and
26639 clip to the physical height of ROW. Non-zero value also defines
26640 the overlapping part to be drawn:
26642 OVERLAPS_PRED overlap with preceding rows
26643 OVERLAPS_SUCC overlap with succeeding rows
26644 OVERLAPS_BOTH overlap with both preceding/succeeding rows
26645 OVERLAPS_ERASED_CURSOR overlap with erased cursor area
26647 Value is the x-position reached, relative to AREA of W. */
26649 static int
26650 draw_glyphs (struct window *w, int x, struct glyph_row *row,
26651 enum glyph_row_area area, ptrdiff_t start, ptrdiff_t end,
26652 enum draw_glyphs_face hl, int overlaps)
26654 struct glyph_string *head, *tail;
26655 struct glyph_string *s;
26656 struct glyph_string *clip_head = NULL, *clip_tail = NULL;
26657 int i, j, x_reached, last_x, area_left = 0;
26658 struct frame *f = XFRAME (WINDOW_FRAME (w));
26659 DECLARE_HDC (hdc);
26661 ALLOCATE_HDC (hdc, f);
26663 /* Let's rather be paranoid than getting a SEGV. */
26664 end = min (end, row->used[area]);
26665 start = clip_to_bounds (0, start, end);
26667 /* Translate X to frame coordinates. Set last_x to the right
26668 end of the drawing area. */
26669 if (row->full_width_p)
26671 /* X is relative to the left edge of W, without scroll bars
26672 or fringes. */
26673 area_left = WINDOW_LEFT_EDGE_X (w);
26674 last_x = (WINDOW_LEFT_EDGE_X (w) + WINDOW_PIXEL_WIDTH (w)
26675 - (row->mode_line_p ? WINDOW_RIGHT_DIVIDER_WIDTH (w) : 0));
26677 else
26679 area_left = window_box_left (w, area);
26680 last_x = area_left + window_box_width (w, area);
26682 x += area_left;
26684 /* Build a doubly-linked list of glyph_string structures between
26685 head and tail from what we have to draw. Note that the macro
26686 BUILD_GLYPH_STRINGS will modify its start parameter. That's
26687 the reason we use a separate variable `i'. */
26688 i = start;
26689 USE_SAFE_ALLOCA;
26690 BUILD_GLYPH_STRINGS (i, end, head, tail, hl, x, last_x);
26691 if (tail)
26693 s = glyph_string_containing_background_width (tail);
26694 x_reached = s->x + s->background_width;
26696 else
26697 x_reached = x;
26699 /* If there are any glyphs with lbearing < 0 or rbearing > width in
26700 the row, redraw some glyphs in front or following the glyph
26701 strings built above. */
26702 if (head && !overlaps && row->contains_overlapping_glyphs_p)
26704 struct glyph_string *h, *t;
26705 Mouse_HLInfo *hlinfo = MOUSE_HL_INFO (f);
26706 int mouse_beg_col UNINIT, mouse_end_col UNINIT;
26707 bool check_mouse_face = false;
26708 int dummy_x = 0;
26710 /* If mouse highlighting is on, we may need to draw adjacent
26711 glyphs using mouse-face highlighting. */
26712 if (area == TEXT_AREA && row->mouse_face_p
26713 && hlinfo->mouse_face_beg_row >= 0
26714 && hlinfo->mouse_face_end_row >= 0)
26716 ptrdiff_t row_vpos = MATRIX_ROW_VPOS (row, w->current_matrix);
26718 if (row_vpos >= hlinfo->mouse_face_beg_row
26719 && row_vpos <= hlinfo->mouse_face_end_row)
26721 check_mouse_face = true;
26722 mouse_beg_col = (row_vpos == hlinfo->mouse_face_beg_row)
26723 ? hlinfo->mouse_face_beg_col : 0;
26724 mouse_end_col = (row_vpos == hlinfo->mouse_face_end_row)
26725 ? hlinfo->mouse_face_end_col
26726 : row->used[TEXT_AREA];
26730 /* Compute overhangs for all glyph strings. */
26731 if (FRAME_RIF (f)->compute_glyph_string_overhangs)
26732 for (s = head; s; s = s->next)
26733 FRAME_RIF (f)->compute_glyph_string_overhangs (s);
26735 /* Prepend glyph strings for glyphs in front of the first glyph
26736 string that are overwritten because of the first glyph
26737 string's left overhang. The background of all strings
26738 prepended must be drawn because the first glyph string
26739 draws over it. */
26740 i = left_overwritten (head);
26741 if (i >= 0)
26743 enum draw_glyphs_face overlap_hl;
26745 /* If this row contains mouse highlighting, attempt to draw
26746 the overlapped glyphs with the correct highlight. This
26747 code fails if the overlap encompasses more than one glyph
26748 and mouse-highlight spans only some of these glyphs.
26749 However, making it work perfectly involves a lot more
26750 code, and I don't know if the pathological case occurs in
26751 practice, so we'll stick to this for now. --- cyd */
26752 if (check_mouse_face
26753 && mouse_beg_col < start && mouse_end_col > i)
26754 overlap_hl = DRAW_MOUSE_FACE;
26755 else
26756 overlap_hl = DRAW_NORMAL_TEXT;
26758 if (hl != overlap_hl)
26759 clip_head = head;
26760 j = i;
26761 BUILD_GLYPH_STRINGS (j, start, h, t,
26762 overlap_hl, dummy_x, last_x);
26763 start = i;
26764 compute_overhangs_and_x (t, head->x, true);
26765 prepend_glyph_string_lists (&head, &tail, h, t);
26766 if (clip_head == NULL)
26767 clip_head = head;
26770 /* Prepend glyph strings for glyphs in front of the first glyph
26771 string that overwrite that glyph string because of their
26772 right overhang. For these strings, only the foreground must
26773 be drawn, because it draws over the glyph string at `head'.
26774 The background must not be drawn because this would overwrite
26775 right overhangs of preceding glyphs for which no glyph
26776 strings exist. */
26777 i = left_overwriting (head);
26778 if (i >= 0)
26780 enum draw_glyphs_face overlap_hl;
26782 if (check_mouse_face
26783 && mouse_beg_col < start && mouse_end_col > i)
26784 overlap_hl = DRAW_MOUSE_FACE;
26785 else
26786 overlap_hl = DRAW_NORMAL_TEXT;
26788 if (hl == overlap_hl || clip_head == NULL)
26789 clip_head = head;
26790 BUILD_GLYPH_STRINGS (i, start, h, t,
26791 overlap_hl, dummy_x, last_x);
26792 for (s = h; s; s = s->next)
26793 s->background_filled_p = true;
26794 compute_overhangs_and_x (t, head->x, true);
26795 prepend_glyph_string_lists (&head, &tail, h, t);
26798 /* Append glyphs strings for glyphs following the last glyph
26799 string tail that are overwritten by tail. The background of
26800 these strings has to be drawn because tail's foreground draws
26801 over it. */
26802 i = right_overwritten (tail);
26803 if (i >= 0)
26805 enum draw_glyphs_face overlap_hl;
26807 if (check_mouse_face
26808 && mouse_beg_col < i && mouse_end_col > end)
26809 overlap_hl = DRAW_MOUSE_FACE;
26810 else
26811 overlap_hl = DRAW_NORMAL_TEXT;
26813 if (hl != overlap_hl)
26814 clip_tail = tail;
26815 BUILD_GLYPH_STRINGS (end, i, h, t,
26816 overlap_hl, x, last_x);
26817 /* Because BUILD_GLYPH_STRINGS updates the first argument,
26818 we don't have `end = i;' here. */
26819 compute_overhangs_and_x (h, tail->x + tail->width, false);
26820 append_glyph_string_lists (&head, &tail, h, t);
26821 if (clip_tail == NULL)
26822 clip_tail = tail;
26825 /* Append glyph strings for glyphs following the last glyph
26826 string tail that overwrite tail. The foreground of such
26827 glyphs has to be drawn because it writes into the background
26828 of tail. The background must not be drawn because it could
26829 paint over the foreground of following glyphs. */
26830 i = right_overwriting (tail);
26831 if (i >= 0)
26833 enum draw_glyphs_face overlap_hl;
26834 if (check_mouse_face
26835 && mouse_beg_col < i && mouse_end_col > end)
26836 overlap_hl = DRAW_MOUSE_FACE;
26837 else
26838 overlap_hl = DRAW_NORMAL_TEXT;
26840 if (hl == overlap_hl || clip_tail == NULL)
26841 clip_tail = tail;
26842 i++; /* We must include the Ith glyph. */
26843 BUILD_GLYPH_STRINGS (end, i, h, t,
26844 overlap_hl, x, last_x);
26845 for (s = h; s; s = s->next)
26846 s->background_filled_p = true;
26847 compute_overhangs_and_x (h, tail->x + tail->width, false);
26848 append_glyph_string_lists (&head, &tail, h, t);
26850 tail = glyph_string_containing_background_width (tail);
26851 if (clip_tail)
26852 clip_tail = glyph_string_containing_background_width (clip_tail);
26853 if (clip_head || clip_tail)
26854 for (s = head; s; s = s->next)
26856 s->clip_head = clip_head;
26857 s->clip_tail = clip_tail;
26861 /* Draw all strings. */
26862 for (s = head; s; s = s->next)
26863 FRAME_RIF (f)->draw_glyph_string (s);
26865 #ifndef HAVE_NS
26866 /* When focus a sole frame and move horizontally, this clears on_p
26867 causing a failure to erase prev cursor position. */
26868 if (area == TEXT_AREA
26869 && !row->full_width_p
26870 /* When drawing overlapping rows, only the glyph strings'
26871 foreground is drawn, which doesn't erase a cursor
26872 completely. */
26873 && !overlaps)
26875 int x0 = clip_head ? clip_head->x : (head ? head->x : x);
26876 int x1 = (clip_tail ? clip_tail->x + clip_tail->background_width
26877 : (tail ? tail->x + tail->background_width : x));
26878 x0 -= area_left;
26879 x1 -= area_left;
26881 notice_overwritten_cursor (w, TEXT_AREA, x0, x1,
26882 row->y, MATRIX_ROW_BOTTOM_Y (row));
26884 #endif
26886 /* Value is the x-position up to which drawn, relative to AREA of W.
26887 This doesn't include parts drawn because of overhangs. */
26888 if (row->full_width_p)
26889 x_reached = FRAME_TO_WINDOW_PIXEL_X (w, x_reached);
26890 else
26891 x_reached -= area_left;
26893 RELEASE_HDC (hdc, f);
26895 SAFE_FREE ();
26896 return x_reached;
26899 /* Find the first glyph in the run of underlined glyphs preceding the
26900 beginning of glyph string S, and return its font (which could be
26901 NULL). This is needed because that font determines the underline
26902 position and thickness for the entire run of the underlined glyphs.
26903 This function is called from the draw_glyph_string method of GUI
26904 frame's redisplay interface (RIF) when it needs to draw in an
26905 underlined face. */
26906 struct font *
26907 font_for_underline_metrics (struct glyph_string *s)
26909 struct glyph *g0 = s->row->glyphs[s->area], *g;
26911 for (g = s->first_glyph - 1; g >= g0; g--)
26913 struct face *prev_face = FACE_FROM_ID (s->f, g->face_id);
26914 if (!(prev_face && prev_face->underline_p))
26915 break;
26918 /* If preceding glyphs are not underlined, use the font of S. */
26919 if (g == s->first_glyph - 1)
26920 return s->font;
26921 else
26923 /* Otherwise use the font of the last glyph we saw in the above
26924 loop whose face had the underline_p flag set. */
26925 return FACE_FROM_ID (s->f, g[1].face_id)->font;
26929 /* Expand row matrix if too narrow. Don't expand if area
26930 is not present. */
26932 #define IT_EXPAND_MATRIX_WIDTH(it, area) \
26934 if (!it->f->fonts_changed \
26935 && (it->glyph_row->glyphs[area] \
26936 < it->glyph_row->glyphs[area + 1])) \
26938 it->w->ncols_scale_factor++; \
26939 it->f->fonts_changed = true; \
26943 /* Store one glyph for IT->char_to_display in IT->glyph_row.
26944 Called from x_produce_glyphs when IT->glyph_row is non-null. */
26946 static void
26947 append_glyph (struct it *it)
26949 struct glyph *glyph;
26950 enum glyph_row_area area = it->area;
26952 eassert (it->glyph_row);
26953 eassert (it->char_to_display != '\n' && it->char_to_display != '\t');
26955 glyph = it->glyph_row->glyphs[area] + it->glyph_row->used[area];
26956 if (glyph < it->glyph_row->glyphs[area + 1])
26958 /* If the glyph row is reversed, we need to prepend the glyph
26959 rather than append it. */
26960 if (it->glyph_row->reversed_p && area == TEXT_AREA)
26962 struct glyph *g;
26964 /* Make room for the additional glyph. */
26965 for (g = glyph - 1; g >= it->glyph_row->glyphs[area]; g--)
26966 g[1] = *g;
26967 glyph = it->glyph_row->glyphs[area];
26969 glyph->charpos = CHARPOS (it->position);
26970 glyph->object = it->object;
26971 if (it->pixel_width > 0)
26973 eassert (it->pixel_width <= SHRT_MAX);
26974 glyph->pixel_width = it->pixel_width;
26975 glyph->padding_p = false;
26977 else
26979 /* Assure at least 1-pixel width. Otherwise, cursor can't
26980 be displayed correctly. */
26981 glyph->pixel_width = 1;
26982 glyph->padding_p = true;
26984 glyph->ascent = it->ascent;
26985 glyph->descent = it->descent;
26986 glyph->voffset = it->voffset;
26987 glyph->type = CHAR_GLYPH;
26988 glyph->avoid_cursor_p = it->avoid_cursor_p;
26989 glyph->multibyte_p = it->multibyte_p;
26990 if (it->glyph_row->reversed_p && area == TEXT_AREA)
26992 /* In R2L rows, the left and the right box edges need to be
26993 drawn in reverse direction. */
26994 glyph->right_box_line_p = it->start_of_box_run_p;
26995 glyph->left_box_line_p = it->end_of_box_run_p;
26997 else
26999 glyph->left_box_line_p = it->start_of_box_run_p;
27000 glyph->right_box_line_p = it->end_of_box_run_p;
27002 glyph->overlaps_vertically_p = (it->phys_ascent > it->ascent
27003 || it->phys_descent > it->descent);
27004 glyph->glyph_not_available_p = it->glyph_not_available_p;
27005 glyph->face_id = it->face_id;
27006 glyph->u.ch = it->char_to_display;
27007 glyph->slice.img = null_glyph_slice;
27008 glyph->font_type = FONT_TYPE_UNKNOWN;
27009 if (it->bidi_p)
27011 glyph->resolved_level = it->bidi_it.resolved_level;
27012 eassert ((it->bidi_it.type & 7) == it->bidi_it.type);
27013 glyph->bidi_type = it->bidi_it.type;
27015 else
27017 glyph->resolved_level = 0;
27018 glyph->bidi_type = UNKNOWN_BT;
27020 ++it->glyph_row->used[area];
27022 else
27023 IT_EXPAND_MATRIX_WIDTH (it, area);
27026 /* Store one glyph for the composition IT->cmp_it.id in
27027 IT->glyph_row. Called from x_produce_glyphs when IT->glyph_row is
27028 non-null. */
27030 static void
27031 append_composite_glyph (struct it *it)
27033 struct glyph *glyph;
27034 enum glyph_row_area area = it->area;
27036 eassert (it->glyph_row);
27038 glyph = it->glyph_row->glyphs[area] + it->glyph_row->used[area];
27039 if (glyph < it->glyph_row->glyphs[area + 1])
27041 /* If the glyph row is reversed, we need to prepend the glyph
27042 rather than append it. */
27043 if (it->glyph_row->reversed_p && it->area == TEXT_AREA)
27045 struct glyph *g;
27047 /* Make room for the new glyph. */
27048 for (g = glyph - 1; g >= it->glyph_row->glyphs[it->area]; g--)
27049 g[1] = *g;
27050 glyph = it->glyph_row->glyphs[it->area];
27052 glyph->charpos = it->cmp_it.charpos;
27053 glyph->object = it->object;
27054 eassert (it->pixel_width <= SHRT_MAX);
27055 glyph->pixel_width = it->pixel_width;
27056 glyph->ascent = it->ascent;
27057 glyph->descent = it->descent;
27058 glyph->voffset = it->voffset;
27059 glyph->type = COMPOSITE_GLYPH;
27060 if (it->cmp_it.ch < 0)
27062 glyph->u.cmp.automatic = false;
27063 glyph->u.cmp.id = it->cmp_it.id;
27064 glyph->slice.cmp.from = glyph->slice.cmp.to = 0;
27066 else
27068 glyph->u.cmp.automatic = true;
27069 glyph->u.cmp.id = it->cmp_it.id;
27070 glyph->slice.cmp.from = it->cmp_it.from;
27071 glyph->slice.cmp.to = it->cmp_it.to - 1;
27073 glyph->avoid_cursor_p = it->avoid_cursor_p;
27074 glyph->multibyte_p = it->multibyte_p;
27075 if (it->glyph_row->reversed_p && area == TEXT_AREA)
27077 /* In R2L rows, the left and the right box edges need to be
27078 drawn in reverse direction. */
27079 glyph->right_box_line_p = it->start_of_box_run_p;
27080 glyph->left_box_line_p = it->end_of_box_run_p;
27082 else
27084 glyph->left_box_line_p = it->start_of_box_run_p;
27085 glyph->right_box_line_p = it->end_of_box_run_p;
27087 glyph->overlaps_vertically_p = (it->phys_ascent > it->ascent
27088 || it->phys_descent > it->descent);
27089 glyph->padding_p = false;
27090 glyph->glyph_not_available_p = false;
27091 glyph->face_id = it->face_id;
27092 glyph->font_type = FONT_TYPE_UNKNOWN;
27093 if (it->bidi_p)
27095 glyph->resolved_level = it->bidi_it.resolved_level;
27096 eassert ((it->bidi_it.type & 7) == it->bidi_it.type);
27097 glyph->bidi_type = it->bidi_it.type;
27099 ++it->glyph_row->used[area];
27101 else
27102 IT_EXPAND_MATRIX_WIDTH (it, area);
27106 /* Change IT->ascent and IT->height according to the setting of
27107 IT->voffset. */
27109 static void
27110 take_vertical_position_into_account (struct it *it)
27112 if (it->voffset)
27114 if (it->voffset < 0)
27115 /* Increase the ascent so that we can display the text higher
27116 in the line. */
27117 it->ascent -= it->voffset;
27118 else
27119 /* Increase the descent so that we can display the text lower
27120 in the line. */
27121 it->descent += it->voffset;
27126 /* Produce glyphs/get display metrics for the image IT is loaded with.
27127 See the description of struct display_iterator in dispextern.h for
27128 an overview of struct display_iterator. */
27130 static void
27131 produce_image_glyph (struct it *it)
27133 struct image *img;
27134 struct face *face;
27135 int glyph_ascent, crop;
27136 struct glyph_slice slice;
27138 eassert (it->what == IT_IMAGE);
27140 face = FACE_FROM_ID (it->f, it->face_id);
27141 /* Make sure X resources of the face is loaded. */
27142 prepare_face_for_display (it->f, face);
27144 if (it->image_id < 0)
27146 /* Fringe bitmap. */
27147 it->ascent = it->phys_ascent = 0;
27148 it->descent = it->phys_descent = 0;
27149 it->pixel_width = 0;
27150 it->nglyphs = 0;
27151 return;
27154 img = IMAGE_FROM_ID (it->f, it->image_id);
27155 /* Make sure X resources of the image is loaded. */
27156 prepare_image_for_display (it->f, img);
27158 slice.x = slice.y = 0;
27159 slice.width = img->width;
27160 slice.height = img->height;
27162 if (INTEGERP (it->slice.x))
27163 slice.x = XINT (it->slice.x);
27164 else if (FLOATP (it->slice.x))
27165 slice.x = XFLOAT_DATA (it->slice.x) * img->width;
27167 if (INTEGERP (it->slice.y))
27168 slice.y = XINT (it->slice.y);
27169 else if (FLOATP (it->slice.y))
27170 slice.y = XFLOAT_DATA (it->slice.y) * img->height;
27172 if (INTEGERP (it->slice.width))
27173 slice.width = XINT (it->slice.width);
27174 else if (FLOATP (it->slice.width))
27175 slice.width = XFLOAT_DATA (it->slice.width) * img->width;
27177 if (INTEGERP (it->slice.height))
27178 slice.height = XINT (it->slice.height);
27179 else if (FLOATP (it->slice.height))
27180 slice.height = XFLOAT_DATA (it->slice.height) * img->height;
27182 if (slice.x >= img->width)
27183 slice.x = img->width;
27184 if (slice.y >= img->height)
27185 slice.y = img->height;
27186 if (slice.x + slice.width >= img->width)
27187 slice.width = img->width - slice.x;
27188 if (slice.y + slice.height > img->height)
27189 slice.height = img->height - slice.y;
27191 if (slice.width == 0 || slice.height == 0)
27192 return;
27194 it->ascent = it->phys_ascent = glyph_ascent = image_ascent (img, face, &slice);
27196 it->descent = slice.height - glyph_ascent;
27197 if (slice.y == 0)
27198 it->descent += img->vmargin;
27199 if (slice.y + slice.height == img->height)
27200 it->descent += img->vmargin;
27201 it->phys_descent = it->descent;
27203 it->pixel_width = slice.width;
27204 if (slice.x == 0)
27205 it->pixel_width += img->hmargin;
27206 if (slice.x + slice.width == img->width)
27207 it->pixel_width += img->hmargin;
27209 /* It's quite possible for images to have an ascent greater than
27210 their height, so don't get confused in that case. */
27211 if (it->descent < 0)
27212 it->descent = 0;
27214 it->nglyphs = 1;
27216 if (face->box != FACE_NO_BOX)
27218 if (face->box_line_width > 0)
27220 if (slice.y == 0)
27221 it->ascent += face->box_line_width;
27222 if (slice.y + slice.height == img->height)
27223 it->descent += face->box_line_width;
27226 if (it->start_of_box_run_p && slice.x == 0)
27227 it->pixel_width += eabs (face->box_line_width);
27228 if (it->end_of_box_run_p && slice.x + slice.width == img->width)
27229 it->pixel_width += eabs (face->box_line_width);
27232 take_vertical_position_into_account (it);
27234 /* Automatically crop wide image glyphs at right edge so we can
27235 draw the cursor on same display row. */
27236 if ((crop = it->pixel_width - (it->last_visible_x - it->current_x), crop > 0)
27237 && (it->hpos == 0 || it->pixel_width > it->last_visible_x / 4))
27239 it->pixel_width -= crop;
27240 slice.width -= crop;
27243 if (it->glyph_row)
27245 struct glyph *glyph;
27246 enum glyph_row_area area = it->area;
27248 glyph = it->glyph_row->glyphs[area] + it->glyph_row->used[area];
27249 if (it->glyph_row->reversed_p)
27251 struct glyph *g;
27253 /* Make room for the new glyph. */
27254 for (g = glyph - 1; g >= it->glyph_row->glyphs[it->area]; g--)
27255 g[1] = *g;
27256 glyph = it->glyph_row->glyphs[it->area];
27258 if (glyph < it->glyph_row->glyphs[area + 1])
27260 glyph->charpos = CHARPOS (it->position);
27261 glyph->object = it->object;
27262 glyph->pixel_width = clip_to_bounds (-1, it->pixel_width, SHRT_MAX);
27263 glyph->ascent = glyph_ascent;
27264 glyph->descent = it->descent;
27265 glyph->voffset = it->voffset;
27266 glyph->type = IMAGE_GLYPH;
27267 glyph->avoid_cursor_p = it->avoid_cursor_p;
27268 glyph->multibyte_p = it->multibyte_p;
27269 if (it->glyph_row->reversed_p && area == TEXT_AREA)
27271 /* In R2L rows, the left and the right box edges need to be
27272 drawn in reverse direction. */
27273 glyph->right_box_line_p = it->start_of_box_run_p;
27274 glyph->left_box_line_p = it->end_of_box_run_p;
27276 else
27278 glyph->left_box_line_p = it->start_of_box_run_p;
27279 glyph->right_box_line_p = it->end_of_box_run_p;
27281 glyph->overlaps_vertically_p = false;
27282 glyph->padding_p = false;
27283 glyph->glyph_not_available_p = false;
27284 glyph->face_id = it->face_id;
27285 glyph->u.img_id = img->id;
27286 glyph->slice.img = slice;
27287 glyph->font_type = FONT_TYPE_UNKNOWN;
27288 if (it->bidi_p)
27290 glyph->resolved_level = it->bidi_it.resolved_level;
27291 eassert ((it->bidi_it.type & 7) == it->bidi_it.type);
27292 glyph->bidi_type = it->bidi_it.type;
27294 ++it->glyph_row->used[area];
27296 else
27297 IT_EXPAND_MATRIX_WIDTH (it, area);
27301 static void
27302 produce_xwidget_glyph (struct it *it)
27304 #ifdef HAVE_XWIDGETS
27305 struct xwidget *xw;
27306 int glyph_ascent, crop;
27307 eassert (it->what == IT_XWIDGET);
27309 struct face *face = FACE_FROM_ID (it->f, it->face_id);
27310 /* Make sure X resources of the face is loaded. */
27311 prepare_face_for_display (it->f, face);
27313 xw = it->xwidget;
27314 it->ascent = it->phys_ascent = glyph_ascent = xw->height/2;
27315 it->descent = xw->height/2;
27316 it->phys_descent = it->descent;
27317 it->pixel_width = xw->width;
27318 /* It's quite possible for images to have an ascent greater than
27319 their height, so don't get confused in that case. */
27320 if (it->descent < 0)
27321 it->descent = 0;
27323 it->nglyphs = 1;
27325 if (face->box != FACE_NO_BOX)
27327 if (face->box_line_width > 0)
27329 it->ascent += face->box_line_width;
27330 it->descent += face->box_line_width;
27333 if (it->start_of_box_run_p)
27334 it->pixel_width += eabs (face->box_line_width);
27335 it->pixel_width += eabs (face->box_line_width);
27338 take_vertical_position_into_account (it);
27340 /* Automatically crop wide image glyphs at right edge so we can
27341 draw the cursor on same display row. */
27342 crop = it->pixel_width - (it->last_visible_x - it->current_x);
27343 if (crop > 0 && (it->hpos == 0 || it->pixel_width > it->last_visible_x / 4))
27344 it->pixel_width -= crop;
27346 if (it->glyph_row)
27348 enum glyph_row_area area = it->area;
27349 struct glyph *glyph
27350 = it->glyph_row->glyphs[area] + it->glyph_row->used[area];
27352 if (it->glyph_row->reversed_p)
27354 struct glyph *g;
27356 /* Make room for the new glyph. */
27357 for (g = glyph - 1; g >= it->glyph_row->glyphs[it->area]; g--)
27358 g[1] = *g;
27359 glyph = it->glyph_row->glyphs[it->area];
27361 if (glyph < it->glyph_row->glyphs[area + 1])
27363 glyph->charpos = CHARPOS (it->position);
27364 glyph->object = it->object;
27365 glyph->pixel_width = clip_to_bounds (-1, it->pixel_width, SHRT_MAX);
27366 glyph->ascent = glyph_ascent;
27367 glyph->descent = it->descent;
27368 glyph->voffset = it->voffset;
27369 glyph->type = XWIDGET_GLYPH;
27370 glyph->avoid_cursor_p = it->avoid_cursor_p;
27371 glyph->multibyte_p = it->multibyte_p;
27372 if (it->glyph_row->reversed_p && area == TEXT_AREA)
27374 /* In R2L rows, the left and the right box edges need to be
27375 drawn in reverse direction. */
27376 glyph->right_box_line_p = it->start_of_box_run_p;
27377 glyph->left_box_line_p = it->end_of_box_run_p;
27379 else
27381 glyph->left_box_line_p = it->start_of_box_run_p;
27382 glyph->right_box_line_p = it->end_of_box_run_p;
27384 glyph->overlaps_vertically_p = 0;
27385 glyph->padding_p = 0;
27386 glyph->glyph_not_available_p = 0;
27387 glyph->face_id = it->face_id;
27388 glyph->u.xwidget = it->xwidget;
27389 glyph->font_type = FONT_TYPE_UNKNOWN;
27390 if (it->bidi_p)
27392 glyph->resolved_level = it->bidi_it.resolved_level;
27393 eassert ((it->bidi_it.type & 7) == it->bidi_it.type);
27394 glyph->bidi_type = it->bidi_it.type;
27396 ++it->glyph_row->used[area];
27398 else
27399 IT_EXPAND_MATRIX_WIDTH (it, area);
27401 #endif
27404 /* Append a stretch glyph to IT->glyph_row. OBJECT is the source
27405 of the glyph, WIDTH and HEIGHT are the width and height of the
27406 stretch. ASCENT is the ascent of the glyph (0 <= ASCENT <= HEIGHT). */
27408 static void
27409 append_stretch_glyph (struct it *it, Lisp_Object object,
27410 int width, int height, int ascent)
27412 struct glyph *glyph;
27413 enum glyph_row_area area = it->area;
27415 eassert (ascent >= 0 && ascent <= height);
27417 glyph = it->glyph_row->glyphs[area] + it->glyph_row->used[area];
27418 if (glyph < it->glyph_row->glyphs[area + 1])
27420 /* If the glyph row is reversed, we need to prepend the glyph
27421 rather than append it. */
27422 if (it->glyph_row->reversed_p && area == TEXT_AREA)
27424 struct glyph *g;
27426 /* Make room for the additional glyph. */
27427 for (g = glyph - 1; g >= it->glyph_row->glyphs[area]; g--)
27428 g[1] = *g;
27429 glyph = it->glyph_row->glyphs[area];
27431 /* Decrease the width of the first glyph of the row that
27432 begins before first_visible_x (e.g., due to hscroll).
27433 This is so the overall width of the row becomes smaller
27434 by the scroll amount, and the stretch glyph appended by
27435 extend_face_to_end_of_line will be wider, to shift the
27436 row glyphs to the right. (In L2R rows, the corresponding
27437 left-shift effect is accomplished by setting row->x to a
27438 negative value, which won't work with R2L rows.)
27440 This must leave us with a positive value of WIDTH, since
27441 otherwise the call to move_it_in_display_line_to at the
27442 beginning of display_line would have got past the entire
27443 first glyph, and then it->current_x would have been
27444 greater or equal to it->first_visible_x. */
27445 if (it->current_x < it->first_visible_x)
27446 width -= it->first_visible_x - it->current_x;
27447 eassert (width > 0);
27449 glyph->charpos = CHARPOS (it->position);
27450 glyph->object = object;
27451 /* FIXME: It would be better to use TYPE_MAX here, but
27452 __typeof__ is not portable enough... */
27453 glyph->pixel_width = clip_to_bounds (-1, width, SHRT_MAX);
27454 glyph->ascent = ascent;
27455 glyph->descent = height - ascent;
27456 glyph->voffset = it->voffset;
27457 glyph->type = STRETCH_GLYPH;
27458 glyph->avoid_cursor_p = it->avoid_cursor_p;
27459 glyph->multibyte_p = it->multibyte_p;
27460 if (it->glyph_row->reversed_p && area == TEXT_AREA)
27462 /* In R2L rows, the left and the right box edges need to be
27463 drawn in reverse direction. */
27464 glyph->right_box_line_p = it->start_of_box_run_p;
27465 glyph->left_box_line_p = it->end_of_box_run_p;
27467 else
27469 glyph->left_box_line_p = it->start_of_box_run_p;
27470 glyph->right_box_line_p = it->end_of_box_run_p;
27472 glyph->overlaps_vertically_p = false;
27473 glyph->padding_p = false;
27474 glyph->glyph_not_available_p = false;
27475 glyph->face_id = it->face_id;
27476 glyph->u.stretch.ascent = ascent;
27477 glyph->u.stretch.height = height;
27478 glyph->slice.img = null_glyph_slice;
27479 glyph->font_type = FONT_TYPE_UNKNOWN;
27480 if (it->bidi_p)
27482 glyph->resolved_level = it->bidi_it.resolved_level;
27483 eassert ((it->bidi_it.type & 7) == it->bidi_it.type);
27484 glyph->bidi_type = it->bidi_it.type;
27486 else
27488 glyph->resolved_level = 0;
27489 glyph->bidi_type = UNKNOWN_BT;
27491 ++it->glyph_row->used[area];
27493 else
27494 IT_EXPAND_MATRIX_WIDTH (it, area);
27497 #endif /* HAVE_WINDOW_SYSTEM */
27499 /* Produce a stretch glyph for iterator IT. IT->object is the value
27500 of the glyph property displayed. The value must be a list
27501 `(space KEYWORD VALUE ...)' with the following KEYWORD/VALUE pairs
27502 being recognized:
27504 1. `:width WIDTH' specifies that the space should be WIDTH *
27505 canonical char width wide. WIDTH may be an integer or floating
27506 point number.
27508 2. `:relative-width FACTOR' specifies that the width of the stretch
27509 should be computed from the width of the first character having the
27510 `glyph' property, and should be FACTOR times that width.
27512 3. `:align-to HPOS' specifies that the space should be wide enough
27513 to reach HPOS, a value in canonical character units.
27515 Exactly one of the above pairs must be present.
27517 4. `:height HEIGHT' specifies that the height of the stretch produced
27518 should be HEIGHT, measured in canonical character units.
27520 5. `:relative-height FACTOR' specifies that the height of the
27521 stretch should be FACTOR times the height of the characters having
27522 the glyph property.
27524 Either none or exactly one of 4 or 5 must be present.
27526 6. `:ascent ASCENT' specifies that ASCENT percent of the height
27527 of the stretch should be used for the ascent of the stretch.
27528 ASCENT must be in the range 0 <= ASCENT <= 100. */
27530 void
27531 produce_stretch_glyph (struct it *it)
27533 /* (space :width WIDTH :height HEIGHT ...) */
27534 Lisp_Object prop, plist;
27535 int width = 0, height = 0, align_to = -1;
27536 bool zero_width_ok_p = false;
27537 double tem;
27538 struct font *font = NULL;
27540 #ifdef HAVE_WINDOW_SYSTEM
27541 int ascent = 0;
27542 bool zero_height_ok_p = false;
27544 if (FRAME_WINDOW_P (it->f))
27546 struct face *face = FACE_FROM_ID (it->f, it->face_id);
27547 font = face->font ? face->font : FRAME_FONT (it->f);
27548 prepare_face_for_display (it->f, face);
27550 #endif
27552 /* List should start with `space'. */
27553 eassert (CONSP (it->object) && EQ (XCAR (it->object), Qspace));
27554 plist = XCDR (it->object);
27556 /* Compute the width of the stretch. */
27557 if ((prop = Fplist_get (plist, QCwidth), !NILP (prop))
27558 && calc_pixel_width_or_height (&tem, it, prop, font, true, 0))
27560 /* Absolute width `:width WIDTH' specified and valid. */
27561 zero_width_ok_p = true;
27562 width = (int)tem;
27564 else if (prop = Fplist_get (plist, QCrelative_width), NUMVAL (prop) > 0)
27566 /* Relative width `:relative-width FACTOR' specified and valid.
27567 Compute the width of the characters having the `glyph'
27568 property. */
27569 struct it it2;
27570 unsigned char *p = BYTE_POS_ADDR (IT_BYTEPOS (*it));
27572 it2 = *it;
27573 if (it->multibyte_p)
27574 it2.c = it2.char_to_display = STRING_CHAR_AND_LENGTH (p, it2.len);
27575 else
27577 it2.c = it2.char_to_display = *p, it2.len = 1;
27578 if (! ASCII_CHAR_P (it2.c))
27579 it2.char_to_display = BYTE8_TO_CHAR (it2.c);
27582 it2.glyph_row = NULL;
27583 it2.what = IT_CHARACTER;
27584 PRODUCE_GLYPHS (&it2);
27585 width = NUMVAL (prop) * it2.pixel_width;
27587 else if ((prop = Fplist_get (plist, QCalign_to), !NILP (prop))
27588 && calc_pixel_width_or_height (&tem, it, prop, font, true,
27589 &align_to))
27591 if (it->glyph_row == NULL || !it->glyph_row->mode_line_p)
27592 align_to = (align_to < 0
27594 : align_to - window_box_left_offset (it->w, TEXT_AREA));
27595 else if (align_to < 0)
27596 align_to = window_box_left_offset (it->w, TEXT_AREA);
27597 width = max (0, (int)tem + align_to - it->current_x);
27598 zero_width_ok_p = true;
27600 else
27601 /* Nothing specified -> width defaults to canonical char width. */
27602 width = FRAME_COLUMN_WIDTH (it->f);
27604 if (width <= 0 && (width < 0 || !zero_width_ok_p))
27605 width = 1;
27607 #ifdef HAVE_WINDOW_SYSTEM
27608 /* Compute height. */
27609 if (FRAME_WINDOW_P (it->f))
27611 int default_height = normal_char_height (font, ' ');
27613 if ((prop = Fplist_get (plist, QCheight), !NILP (prop))
27614 && calc_pixel_width_or_height (&tem, it, prop, font, false, 0))
27616 height = (int)tem;
27617 zero_height_ok_p = true;
27619 else if (prop = Fplist_get (plist, QCrelative_height),
27620 NUMVAL (prop) > 0)
27621 height = default_height * NUMVAL (prop);
27622 else
27623 height = default_height;
27625 if (height <= 0 && (height < 0 || !zero_height_ok_p))
27626 height = 1;
27628 /* Compute percentage of height used for ascent. If
27629 `:ascent ASCENT' is present and valid, use that. Otherwise,
27630 derive the ascent from the font in use. */
27631 if (prop = Fplist_get (plist, QCascent),
27632 NUMVAL (prop) > 0 && NUMVAL (prop) <= 100)
27633 ascent = height * NUMVAL (prop) / 100.0;
27634 else if (!NILP (prop)
27635 && calc_pixel_width_or_height (&tem, it, prop, font, false, 0))
27636 ascent = min (max (0, (int)tem), height);
27637 else
27638 ascent = (height * FONT_BASE (font)) / FONT_HEIGHT (font);
27640 else
27641 #endif /* HAVE_WINDOW_SYSTEM */
27642 height = 1;
27644 if (width > 0 && it->line_wrap != TRUNCATE
27645 && it->current_x + width > it->last_visible_x)
27647 width = it->last_visible_x - it->current_x;
27648 #ifdef HAVE_WINDOW_SYSTEM
27649 /* Subtract one more pixel from the stretch width, but only on
27650 GUI frames, since on a TTY each glyph is one "pixel" wide. */
27651 width -= FRAME_WINDOW_P (it->f);
27652 #endif
27655 if (width > 0 && height > 0 && it->glyph_row)
27657 Lisp_Object o_object = it->object;
27658 Lisp_Object object = it->stack[it->sp - 1].string;
27659 int n = width;
27661 if (!STRINGP (object))
27662 object = it->w->contents;
27663 #ifdef HAVE_WINDOW_SYSTEM
27664 if (FRAME_WINDOW_P (it->f))
27665 append_stretch_glyph (it, object, width, height, ascent);
27666 else
27667 #endif
27669 it->object = object;
27670 it->char_to_display = ' ';
27671 it->pixel_width = it->len = 1;
27672 while (n--)
27673 tty_append_glyph (it);
27674 it->object = o_object;
27678 it->pixel_width = width;
27679 #ifdef HAVE_WINDOW_SYSTEM
27680 if (FRAME_WINDOW_P (it->f))
27682 it->ascent = it->phys_ascent = ascent;
27683 it->descent = it->phys_descent = height - it->ascent;
27684 it->nglyphs = width > 0 && height > 0;
27685 take_vertical_position_into_account (it);
27687 else
27688 #endif
27689 it->nglyphs = width;
27692 /* Get information about special display element WHAT in an
27693 environment described by IT. WHAT is one of IT_TRUNCATION or
27694 IT_CONTINUATION. Maybe produce glyphs for WHAT if IT has a
27695 non-null glyph_row member. This function ensures that fields like
27696 face_id, c, len of IT are left untouched. */
27698 static void
27699 produce_special_glyphs (struct it *it, enum display_element_type what)
27701 struct it temp_it;
27702 Lisp_Object gc;
27703 GLYPH glyph;
27705 temp_it = *it;
27706 temp_it.object = Qnil;
27707 memset (&temp_it.current, 0, sizeof temp_it.current);
27709 if (what == IT_CONTINUATION)
27711 /* Continuation glyph. For R2L lines, we mirror it by hand. */
27712 if (it->bidi_it.paragraph_dir == R2L)
27713 SET_GLYPH_FROM_CHAR (glyph, '/');
27714 else
27715 SET_GLYPH_FROM_CHAR (glyph, '\\');
27716 if (it->dp
27717 && (gc = DISP_CONTINUE_GLYPH (it->dp), GLYPH_CODE_P (gc)))
27719 /* FIXME: Should we mirror GC for R2L lines? */
27720 SET_GLYPH_FROM_GLYPH_CODE (glyph, gc);
27721 spec_glyph_lookup_face (XWINDOW (it->window), &glyph);
27724 else if (what == IT_TRUNCATION)
27726 /* Truncation glyph. */
27727 SET_GLYPH_FROM_CHAR (glyph, '$');
27728 if (it->dp
27729 && (gc = DISP_TRUNC_GLYPH (it->dp), GLYPH_CODE_P (gc)))
27731 /* FIXME: Should we mirror GC for R2L lines? */
27732 SET_GLYPH_FROM_GLYPH_CODE (glyph, gc);
27733 spec_glyph_lookup_face (XWINDOW (it->window), &glyph);
27736 else
27737 emacs_abort ();
27739 #ifdef HAVE_WINDOW_SYSTEM
27740 /* On a GUI frame, when the right fringe (left fringe for R2L rows)
27741 is turned off, we precede the truncation/continuation glyphs by a
27742 stretch glyph whose width is computed such that these special
27743 glyphs are aligned at the window margin, even when very different
27744 fonts are used in different glyph rows. */
27745 if (FRAME_WINDOW_P (temp_it.f)
27746 /* init_iterator calls this with it->glyph_row == NULL, and it
27747 wants only the pixel width of the truncation/continuation
27748 glyphs. */
27749 && temp_it.glyph_row
27750 /* insert_left_trunc_glyphs calls us at the beginning of the
27751 row, and it has its own calculation of the stretch glyph
27752 width. */
27753 && temp_it.glyph_row->used[TEXT_AREA] > 0
27754 && (temp_it.glyph_row->reversed_p
27755 ? WINDOW_LEFT_FRINGE_WIDTH (temp_it.w)
27756 : WINDOW_RIGHT_FRINGE_WIDTH (temp_it.w)) == 0)
27758 int stretch_width = temp_it.last_visible_x - temp_it.current_x;
27760 if (stretch_width > 0)
27762 struct face *face = FACE_FROM_ID (temp_it.f, temp_it.face_id);
27763 struct font *font =
27764 face->font ? face->font : FRAME_FONT (temp_it.f);
27765 int stretch_ascent =
27766 (((temp_it.ascent + temp_it.descent)
27767 * FONT_BASE (font)) / FONT_HEIGHT (font));
27769 append_stretch_glyph (&temp_it, Qnil, stretch_width,
27770 temp_it.ascent + temp_it.descent,
27771 stretch_ascent);
27774 #endif
27776 temp_it.dp = NULL;
27777 temp_it.what = IT_CHARACTER;
27778 temp_it.c = temp_it.char_to_display = GLYPH_CHAR (glyph);
27779 temp_it.face_id = GLYPH_FACE (glyph);
27780 temp_it.len = CHAR_BYTES (temp_it.c);
27782 PRODUCE_GLYPHS (&temp_it);
27783 it->pixel_width = temp_it.pixel_width;
27784 it->nglyphs = temp_it.nglyphs;
27787 #ifdef HAVE_WINDOW_SYSTEM
27789 /* Calculate line-height and line-spacing properties.
27790 An integer value specifies explicit pixel value.
27791 A float value specifies relative value to current face height.
27792 A cons (float . face-name) specifies relative value to
27793 height of specified face font.
27795 Returns height in pixels, or nil. */
27797 static Lisp_Object
27798 calc_line_height_property (struct it *it, Lisp_Object val, struct font *font,
27799 int boff, bool override)
27801 Lisp_Object face_name = Qnil;
27802 int ascent, descent, height;
27804 if (NILP (val) || INTEGERP (val) || (override && EQ (val, Qt)))
27805 return val;
27807 if (CONSP (val))
27809 face_name = XCAR (val);
27810 val = XCDR (val);
27811 if (!NUMBERP (val))
27812 val = make_number (1);
27813 if (NILP (face_name))
27815 height = it->ascent + it->descent;
27816 goto scale;
27820 if (NILP (face_name))
27822 font = FRAME_FONT (it->f);
27823 boff = FRAME_BASELINE_OFFSET (it->f);
27825 else if (EQ (face_name, Qt))
27827 override = false;
27829 else
27831 int face_id;
27832 struct face *face;
27834 face_id = lookup_named_face (it->f, face_name, false);
27835 face = FACE_FROM_ID_OR_NULL (it->f, face_id);
27836 if (face == NULL || ((font = face->font) == NULL))
27837 return make_number (-1);
27838 boff = font->baseline_offset;
27839 if (font->vertical_centering)
27840 boff = VCENTER_BASELINE_OFFSET (font, it->f) - boff;
27843 normal_char_ascent_descent (font, -1, &ascent, &descent);
27845 if (override)
27847 it->override_ascent = ascent;
27848 it->override_descent = descent;
27849 it->override_boff = boff;
27852 height = ascent + descent;
27854 scale:
27855 if (FLOATP (val))
27856 height = (int)(XFLOAT_DATA (val) * height);
27857 else if (INTEGERP (val))
27858 height *= XINT (val);
27860 return make_number (height);
27864 /* Append a glyph for a glyphless character to IT->glyph_row. FACE_ID
27865 is a face ID to be used for the glyph. FOR_NO_FONT is true if
27866 and only if this is for a character for which no font was found.
27868 If the display method (it->glyphless_method) is
27869 GLYPHLESS_DISPLAY_ACRONYM or GLYPHLESS_DISPLAY_HEX_CODE, LEN is a
27870 length of the acronym or the hexadecimal string, UPPER_XOFF and
27871 UPPER_YOFF are pixel offsets for the upper part of the string,
27872 LOWER_XOFF and LOWER_YOFF are for the lower part.
27874 For the other display methods, LEN through LOWER_YOFF are zero. */
27876 static void
27877 append_glyphless_glyph (struct it *it, int face_id, bool for_no_font, int len,
27878 short upper_xoff, short upper_yoff,
27879 short lower_xoff, short lower_yoff)
27881 struct glyph *glyph;
27882 enum glyph_row_area area = it->area;
27884 glyph = it->glyph_row->glyphs[area] + it->glyph_row->used[area];
27885 if (glyph < it->glyph_row->glyphs[area + 1])
27887 /* If the glyph row is reversed, we need to prepend the glyph
27888 rather than append it. */
27889 if (it->glyph_row->reversed_p && area == TEXT_AREA)
27891 struct glyph *g;
27893 /* Make room for the additional glyph. */
27894 for (g = glyph - 1; g >= it->glyph_row->glyphs[area]; g--)
27895 g[1] = *g;
27896 glyph = it->glyph_row->glyphs[area];
27898 glyph->charpos = CHARPOS (it->position);
27899 glyph->object = it->object;
27900 eassert (it->pixel_width <= SHRT_MAX);
27901 glyph->pixel_width = it->pixel_width;
27902 glyph->ascent = it->ascent;
27903 glyph->descent = it->descent;
27904 glyph->voffset = it->voffset;
27905 glyph->type = GLYPHLESS_GLYPH;
27906 glyph->u.glyphless.method = it->glyphless_method;
27907 glyph->u.glyphless.for_no_font = for_no_font;
27908 glyph->u.glyphless.len = len;
27909 glyph->u.glyphless.ch = it->c;
27910 glyph->slice.glyphless.upper_xoff = upper_xoff;
27911 glyph->slice.glyphless.upper_yoff = upper_yoff;
27912 glyph->slice.glyphless.lower_xoff = lower_xoff;
27913 glyph->slice.glyphless.lower_yoff = lower_yoff;
27914 glyph->avoid_cursor_p = it->avoid_cursor_p;
27915 glyph->multibyte_p = it->multibyte_p;
27916 if (it->glyph_row->reversed_p && area == TEXT_AREA)
27918 /* In R2L rows, the left and the right box edges need to be
27919 drawn in reverse direction. */
27920 glyph->right_box_line_p = it->start_of_box_run_p;
27921 glyph->left_box_line_p = it->end_of_box_run_p;
27923 else
27925 glyph->left_box_line_p = it->start_of_box_run_p;
27926 glyph->right_box_line_p = it->end_of_box_run_p;
27928 glyph->overlaps_vertically_p = (it->phys_ascent > it->ascent
27929 || it->phys_descent > it->descent);
27930 glyph->padding_p = false;
27931 glyph->glyph_not_available_p = false;
27932 glyph->face_id = face_id;
27933 glyph->font_type = FONT_TYPE_UNKNOWN;
27934 if (it->bidi_p)
27936 glyph->resolved_level = it->bidi_it.resolved_level;
27937 eassert ((it->bidi_it.type & 7) == it->bidi_it.type);
27938 glyph->bidi_type = it->bidi_it.type;
27940 ++it->glyph_row->used[area];
27942 else
27943 IT_EXPAND_MATRIX_WIDTH (it, area);
27947 /* Produce a glyph for a glyphless character for iterator IT.
27948 IT->glyphless_method specifies which method to use for displaying
27949 the character. See the description of enum
27950 glyphless_display_method in dispextern.h for the detail.
27952 FOR_NO_FONT is true if and only if this is for a character for
27953 which no font was found. ACRONYM, if non-nil, is an acronym string
27954 for the character. */
27956 static void
27957 produce_glyphless_glyph (struct it *it, bool for_no_font, Lisp_Object acronym)
27959 int face_id;
27960 struct face *face;
27961 struct font *font;
27962 int base_width, base_height, width, height;
27963 short upper_xoff, upper_yoff, lower_xoff, lower_yoff;
27964 int len;
27966 /* Get the metrics of the base font. We always refer to the current
27967 ASCII face. */
27968 face = FACE_FROM_ID (it->f, it->face_id)->ascii_face;
27969 font = face->font ? face->font : FRAME_FONT (it->f);
27970 normal_char_ascent_descent (font, -1, &it->ascent, &it->descent);
27971 it->ascent += font->baseline_offset;
27972 it->descent -= font->baseline_offset;
27973 base_height = it->ascent + it->descent;
27974 base_width = font->average_width;
27976 face_id = merge_glyphless_glyph_face (it);
27978 if (it->glyphless_method == GLYPHLESS_DISPLAY_THIN_SPACE)
27980 it->pixel_width = THIN_SPACE_WIDTH;
27981 len = 0;
27982 upper_xoff = upper_yoff = lower_xoff = lower_yoff = 0;
27984 else if (it->glyphless_method == GLYPHLESS_DISPLAY_EMPTY_BOX)
27986 width = CHARACTER_WIDTH (it->c);
27987 if (width == 0)
27988 width = 1;
27989 else if (width > 4)
27990 width = 4;
27991 it->pixel_width = base_width * width;
27992 len = 0;
27993 upper_xoff = upper_yoff = lower_xoff = lower_yoff = 0;
27995 else
27997 char buf[7];
27998 const char *str;
27999 unsigned int code[6];
28000 int upper_len;
28001 int ascent, descent;
28002 struct font_metrics metrics_upper, metrics_lower;
28004 face = FACE_FROM_ID (it->f, face_id);
28005 font = face->font ? face->font : FRAME_FONT (it->f);
28006 prepare_face_for_display (it->f, face);
28008 if (it->glyphless_method == GLYPHLESS_DISPLAY_ACRONYM)
28010 if (! STRINGP (acronym) && CHAR_TABLE_P (Vglyphless_char_display))
28011 acronym = CHAR_TABLE_REF (Vglyphless_char_display, it->c);
28012 if (CONSP (acronym))
28013 acronym = XCAR (acronym);
28014 str = STRINGP (acronym) ? SSDATA (acronym) : "";
28016 else
28018 eassert (it->glyphless_method == GLYPHLESS_DISPLAY_HEX_CODE);
28019 sprintf (buf, "%0*X", it->c < 0x10000 ? 4 : 6, it->c + 0u);
28020 str = buf;
28022 for (len = 0; str[len] && ASCII_CHAR_P (str[len]) && len < 6; len++)
28023 code[len] = font->driver->encode_char (font, str[len]);
28024 upper_len = (len + 1) / 2;
28025 font->driver->text_extents (font, code, upper_len,
28026 &metrics_upper);
28027 font->driver->text_extents (font, code + upper_len, len - upper_len,
28028 &metrics_lower);
28032 /* +4 is for vertical bars of a box plus 1-pixel spaces at both side. */
28033 width = max (metrics_upper.width, metrics_lower.width) + 4;
28034 upper_xoff = upper_yoff = 2; /* the typical case */
28035 if (base_width >= width)
28037 /* Align the upper to the left, the lower to the right. */
28038 it->pixel_width = base_width;
28039 lower_xoff = base_width - 2 - metrics_lower.width;
28041 else
28043 /* Center the shorter one. */
28044 it->pixel_width = width;
28045 if (metrics_upper.width >= metrics_lower.width)
28046 lower_xoff = (width - metrics_lower.width) / 2;
28047 else
28049 /* FIXME: This code doesn't look right. It formerly was
28050 missing the "lower_xoff = 0;", which couldn't have
28051 been right since it left lower_xoff uninitialized. */
28052 lower_xoff = 0;
28053 upper_xoff = (width - metrics_upper.width) / 2;
28057 /* +5 is for horizontal bars of a box plus 1-pixel spaces at
28058 top, bottom, and between upper and lower strings. */
28059 height = (metrics_upper.ascent + metrics_upper.descent
28060 + metrics_lower.ascent + metrics_lower.descent) + 5;
28061 /* Center vertically.
28062 H:base_height, D:base_descent
28063 h:height, ld:lower_descent, la:lower_ascent, ud:upper_descent
28065 ascent = - (D - H/2 - h/2 + 1); "+ 1" for rounding up
28066 descent = D - H/2 + h/2;
28067 lower_yoff = descent - 2 - ld;
28068 upper_yoff = lower_yoff - la - 1 - ud; */
28069 ascent = - (it->descent - (base_height + height + 1) / 2);
28070 descent = it->descent - (base_height - height) / 2;
28071 lower_yoff = descent - 2 - metrics_lower.descent;
28072 upper_yoff = (lower_yoff - metrics_lower.ascent - 1
28073 - metrics_upper.descent);
28074 /* Don't make the height shorter than the base height. */
28075 if (height > base_height)
28077 it->ascent = ascent;
28078 it->descent = descent;
28082 it->phys_ascent = it->ascent;
28083 it->phys_descent = it->descent;
28084 if (it->glyph_row)
28085 append_glyphless_glyph (it, face_id, for_no_font, len,
28086 upper_xoff, upper_yoff,
28087 lower_xoff, lower_yoff);
28088 it->nglyphs = 1;
28089 take_vertical_position_into_account (it);
28093 /* RIF:
28094 Produce glyphs/get display metrics for the display element IT is
28095 loaded with. See the description of struct it in dispextern.h
28096 for an overview of struct it. */
28098 void
28099 x_produce_glyphs (struct it *it)
28101 int extra_line_spacing = it->extra_line_spacing;
28103 it->glyph_not_available_p = false;
28105 if (it->what == IT_CHARACTER)
28107 XChar2b char2b;
28108 struct face *face = FACE_FROM_ID (it->f, it->face_id);
28109 struct font *font = face->font;
28110 struct font_metrics *pcm = NULL;
28111 int boff; /* Baseline offset. */
28113 if (font == NULL)
28115 /* When no suitable font is found, display this character by
28116 the method specified in the first extra slot of
28117 Vglyphless_char_display. */
28118 Lisp_Object acronym = lookup_glyphless_char_display (-1, it);
28120 eassert (it->what == IT_GLYPHLESS);
28121 produce_glyphless_glyph (it, true,
28122 STRINGP (acronym) ? acronym : Qnil);
28123 goto done;
28126 boff = font->baseline_offset;
28127 if (font->vertical_centering)
28128 boff = VCENTER_BASELINE_OFFSET (font, it->f) - boff;
28130 if (it->char_to_display != '\n' && it->char_to_display != '\t')
28132 it->nglyphs = 1;
28134 if (it->override_ascent >= 0)
28136 it->ascent = it->override_ascent;
28137 it->descent = it->override_descent;
28138 boff = it->override_boff;
28140 else
28142 it->ascent = FONT_BASE (font) + boff;
28143 it->descent = FONT_DESCENT (font) - boff;
28146 if (get_char_glyph_code (it->char_to_display, font, &char2b))
28148 pcm = get_per_char_metric (font, &char2b);
28149 if (pcm->width == 0
28150 && pcm->rbearing == 0 && pcm->lbearing == 0)
28151 pcm = NULL;
28154 if (pcm)
28156 it->phys_ascent = pcm->ascent + boff;
28157 it->phys_descent = pcm->descent - boff;
28158 it->pixel_width = pcm->width;
28159 /* Don't use font-global values for ascent and descent
28160 if they result in an exceedingly large line height. */
28161 if (it->override_ascent < 0)
28163 if (FONT_TOO_HIGH (font))
28165 it->ascent = it->phys_ascent;
28166 it->descent = it->phys_descent;
28167 /* These limitations are enforced by an
28168 assertion near the end of this function. */
28169 if (it->ascent < 0)
28170 it->ascent = 0;
28171 if (it->descent < 0)
28172 it->descent = 0;
28176 else
28178 it->glyph_not_available_p = true;
28179 it->phys_ascent = it->ascent;
28180 it->phys_descent = it->descent;
28181 it->pixel_width = font->space_width;
28184 if (it->constrain_row_ascent_descent_p)
28186 if (it->descent > it->max_descent)
28188 it->ascent += it->descent - it->max_descent;
28189 it->descent = it->max_descent;
28191 if (it->ascent > it->max_ascent)
28193 it->descent = min (it->max_descent, it->descent + it->ascent - it->max_ascent);
28194 it->ascent = it->max_ascent;
28196 it->phys_ascent = min (it->phys_ascent, it->ascent);
28197 it->phys_descent = min (it->phys_descent, it->descent);
28198 extra_line_spacing = 0;
28201 /* If this is a space inside a region of text with
28202 `space-width' property, change its width. */
28203 bool stretched_p
28204 = it->char_to_display == ' ' && !NILP (it->space_width);
28205 if (stretched_p)
28206 it->pixel_width *= XFLOATINT (it->space_width);
28208 /* If face has a box, add the box thickness to the character
28209 height. If character has a box line to the left and/or
28210 right, add the box line width to the character's width. */
28211 if (face->box != FACE_NO_BOX)
28213 int thick = face->box_line_width;
28215 if (thick > 0)
28217 it->ascent += thick;
28218 it->descent += thick;
28220 else
28221 thick = -thick;
28223 if (it->start_of_box_run_p)
28224 it->pixel_width += thick;
28225 if (it->end_of_box_run_p)
28226 it->pixel_width += thick;
28229 /* If face has an overline, add the height of the overline
28230 (1 pixel) and a 1 pixel margin to the character height. */
28231 if (face->overline_p)
28232 it->ascent += overline_margin;
28234 if (it->constrain_row_ascent_descent_p)
28236 if (it->ascent > it->max_ascent)
28237 it->ascent = it->max_ascent;
28238 if (it->descent > it->max_descent)
28239 it->descent = it->max_descent;
28242 take_vertical_position_into_account (it);
28244 /* If we have to actually produce glyphs, do it. */
28245 if (it->glyph_row)
28247 if (stretched_p)
28249 /* Translate a space with a `space-width' property
28250 into a stretch glyph. */
28251 int ascent = (((it->ascent + it->descent) * FONT_BASE (font))
28252 / FONT_HEIGHT (font));
28253 append_stretch_glyph (it, it->object, it->pixel_width,
28254 it->ascent + it->descent, ascent);
28256 else
28257 append_glyph (it);
28259 /* If characters with lbearing or rbearing are displayed
28260 in this line, record that fact in a flag of the
28261 glyph row. This is used to optimize X output code. */
28262 if (pcm && (pcm->lbearing < 0 || pcm->rbearing > pcm->width))
28263 it->glyph_row->contains_overlapping_glyphs_p = true;
28265 if (! stretched_p && it->pixel_width == 0)
28266 /* We assure that all visible glyphs have at least 1-pixel
28267 width. */
28268 it->pixel_width = 1;
28270 else if (it->char_to_display == '\n')
28272 /* A newline has no width, but we need the height of the
28273 line. But if previous part of the line sets a height,
28274 don't increase that height. */
28276 Lisp_Object height;
28277 Lisp_Object total_height = Qnil;
28279 it->override_ascent = -1;
28280 it->pixel_width = 0;
28281 it->nglyphs = 0;
28283 height = get_it_property (it, Qline_height);
28284 /* Split (line-height total-height) list. */
28285 if (CONSP (height)
28286 && CONSP (XCDR (height))
28287 && NILP (XCDR (XCDR (height))))
28289 total_height = XCAR (XCDR (height));
28290 height = XCAR (height);
28292 height = calc_line_height_property (it, height, font, boff, true);
28294 if (it->override_ascent >= 0)
28296 it->ascent = it->override_ascent;
28297 it->descent = it->override_descent;
28298 boff = it->override_boff;
28300 else
28302 if (FONT_TOO_HIGH (font))
28304 it->ascent = font->pixel_size + boff - 1;
28305 it->descent = -boff + 1;
28306 if (it->descent < 0)
28307 it->descent = 0;
28309 else
28311 it->ascent = FONT_BASE (font) + boff;
28312 it->descent = FONT_DESCENT (font) - boff;
28316 if (EQ (height, Qt))
28318 if (it->descent > it->max_descent)
28320 it->ascent += it->descent - it->max_descent;
28321 it->descent = it->max_descent;
28323 if (it->ascent > it->max_ascent)
28325 it->descent = min (it->max_descent, it->descent + it->ascent - it->max_ascent);
28326 it->ascent = it->max_ascent;
28328 it->phys_ascent = min (it->phys_ascent, it->ascent);
28329 it->phys_descent = min (it->phys_descent, it->descent);
28330 it->constrain_row_ascent_descent_p = true;
28331 extra_line_spacing = 0;
28333 else
28335 Lisp_Object spacing;
28337 it->phys_ascent = it->ascent;
28338 it->phys_descent = it->descent;
28340 if ((it->max_ascent > 0 || it->max_descent > 0)
28341 && face->box != FACE_NO_BOX
28342 && face->box_line_width > 0)
28344 it->ascent += face->box_line_width;
28345 it->descent += face->box_line_width;
28347 if (!NILP (height)
28348 && XINT (height) > it->ascent + it->descent)
28349 it->ascent = XINT (height) - it->descent;
28351 if (!NILP (total_height))
28352 spacing = calc_line_height_property (it, total_height, font,
28353 boff, false);
28354 else
28356 spacing = get_it_property (it, Qline_spacing);
28357 spacing = calc_line_height_property (it, spacing, font,
28358 boff, false);
28360 if (INTEGERP (spacing))
28362 extra_line_spacing = XINT (spacing);
28363 if (!NILP (total_height))
28364 extra_line_spacing -= (it->phys_ascent + it->phys_descent);
28368 else /* i.e. (it->char_to_display == '\t') */
28370 if (font->space_width > 0)
28372 int tab_width = it->tab_width * font->space_width;
28373 int x = it->current_x + it->continuation_lines_width;
28374 int x0 = x;
28375 /* Adjust for line numbers, if needed. */
28376 if (!NILP (Vdisplay_line_numbers) && it->line_number_produced_p)
28378 x -= it->lnum_pixel_width;
28379 /* Restore the original TAB width, if required. */
28380 if (x + it->tab_offset >= it->first_visible_x)
28381 x += it->tab_offset;
28384 int next_tab_x = ((1 + x + tab_width - 1) / tab_width) * tab_width;
28386 /* If the distance from the current position to the next tab
28387 stop is less than a space character width, use the
28388 tab stop after that. */
28389 if (next_tab_x - x < font->space_width)
28390 next_tab_x += tab_width;
28391 if (!NILP (Vdisplay_line_numbers) && it->line_number_produced_p)
28393 next_tab_x += it->lnum_pixel_width;
28394 /* If the line is hscrolled, and the TAB starts before
28395 the first visible pixel, simulate negative row->x. */
28396 if (x < it->first_visible_x)
28398 next_tab_x -= it->first_visible_x - x;
28399 it->tab_offset = it->first_visible_x - x;
28401 else
28402 next_tab_x -= it->tab_offset;
28405 it->pixel_width = next_tab_x - x0;
28406 it->nglyphs = 1;
28407 if (FONT_TOO_HIGH (font))
28409 if (get_char_glyph_code (' ', font, &char2b))
28411 pcm = get_per_char_metric (font, &char2b);
28412 if (pcm->width == 0
28413 && pcm->rbearing == 0 && pcm->lbearing == 0)
28414 pcm = NULL;
28417 if (pcm)
28419 it->ascent = pcm->ascent + boff;
28420 it->descent = pcm->descent - boff;
28422 else
28424 it->ascent = font->pixel_size + boff - 1;
28425 it->descent = -boff + 1;
28427 if (it->ascent < 0)
28428 it->ascent = 0;
28429 if (it->descent < 0)
28430 it->descent = 0;
28432 else
28434 it->ascent = FONT_BASE (font) + boff;
28435 it->descent = FONT_DESCENT (font) - boff;
28437 it->phys_ascent = it->ascent;
28438 it->phys_descent = it->descent;
28440 if (it->glyph_row)
28442 append_stretch_glyph (it, it->object, it->pixel_width,
28443 it->ascent + it->descent, it->ascent);
28446 else
28448 it->pixel_width = 0;
28449 it->nglyphs = 1;
28453 if (FONT_TOO_HIGH (font))
28455 int font_ascent, font_descent;
28457 /* For very large fonts, where we ignore the declared font
28458 dimensions, and go by per-character metrics instead,
28459 don't let the row ascent and descent values (and the row
28460 height computed from them) be smaller than the "normal"
28461 character metrics. This avoids unpleasant effects
28462 whereby lines on display would change their height
28463 depending on which characters are shown. */
28464 normal_char_ascent_descent (font, -1, &font_ascent, &font_descent);
28465 it->max_ascent = max (it->max_ascent, font_ascent);
28466 it->max_descent = max (it->max_descent, font_descent);
28469 else if (it->what == IT_COMPOSITION && it->cmp_it.ch < 0)
28471 /* A static composition.
28473 Note: A composition is represented as one glyph in the
28474 glyph matrix. There are no padding glyphs.
28476 Important note: pixel_width, ascent, and descent are the
28477 values of what is drawn by draw_glyphs (i.e. the values of
28478 the overall glyphs composed). */
28479 struct face *face = FACE_FROM_ID (it->f, it->face_id);
28480 int boff; /* baseline offset */
28481 struct composition *cmp = composition_table[it->cmp_it.id];
28482 int glyph_len = cmp->glyph_len;
28483 struct font *font = face->font;
28485 it->nglyphs = 1;
28487 /* If we have not yet calculated pixel size data of glyphs of
28488 the composition for the current face font, calculate them
28489 now. Theoretically, we have to check all fonts for the
28490 glyphs, but that requires much time and memory space. So,
28491 here we check only the font of the first glyph. This may
28492 lead to incorrect display, but it's very rare, and C-l
28493 (recenter-top-bottom) can correct the display anyway. */
28494 if (! cmp->font || cmp->font != font)
28496 /* Ascent and descent of the font of the first character
28497 of this composition (adjusted by baseline offset).
28498 Ascent and descent of overall glyphs should not be less
28499 than these, respectively. */
28500 int font_ascent, font_descent, font_height;
28501 /* Bounding box of the overall glyphs. */
28502 int leftmost, rightmost, lowest, highest;
28503 int lbearing, rbearing;
28504 int i, width, ascent, descent;
28505 int c;
28506 XChar2b char2b;
28507 struct font_metrics *pcm;
28508 ptrdiff_t pos;
28510 eassume (0 < glyph_len); /* See Bug#8512. */
28512 c = COMPOSITION_GLYPH (cmp, glyph_len - 1);
28513 while (c == '\t' && 0 < --glyph_len);
28515 bool right_padded = glyph_len < cmp->glyph_len;
28516 for (i = 0; i < glyph_len; i++)
28518 c = COMPOSITION_GLYPH (cmp, i);
28519 if (c != '\t')
28520 break;
28521 cmp->offsets[i * 2] = cmp->offsets[i * 2 + 1] = 0;
28523 bool left_padded = i > 0;
28525 pos = (STRINGP (it->string) ? IT_STRING_CHARPOS (*it)
28526 : IT_CHARPOS (*it));
28527 /* If no suitable font is found, use the default font. */
28528 bool font_not_found_p = font == NULL;
28529 if (font_not_found_p)
28531 face = face->ascii_face;
28532 font = face->font;
28534 boff = font->baseline_offset;
28535 if (font->vertical_centering)
28536 boff = VCENTER_BASELINE_OFFSET (font, it->f) - boff;
28537 normal_char_ascent_descent (font, -1, &font_ascent, &font_descent);
28538 font_ascent += boff;
28539 font_descent -= boff;
28540 font_height = font_ascent + font_descent;
28542 cmp->font = font;
28544 pcm = NULL;
28545 if (! font_not_found_p)
28547 get_char_face_and_encoding (it->f, c, it->face_id,
28548 &char2b, false);
28549 pcm = get_per_char_metric (font, &char2b);
28552 /* Initialize the bounding box. */
28553 if (pcm)
28555 width = cmp->glyph_len > 0 ? pcm->width : 0;
28556 ascent = pcm->ascent;
28557 descent = pcm->descent;
28558 lbearing = pcm->lbearing;
28559 rbearing = pcm->rbearing;
28561 else
28563 width = cmp->glyph_len > 0 ? font->space_width : 0;
28564 ascent = FONT_BASE (font);
28565 descent = FONT_DESCENT (font);
28566 lbearing = 0;
28567 rbearing = width;
28570 rightmost = width;
28571 leftmost = 0;
28572 lowest = - descent + boff;
28573 highest = ascent + boff;
28575 if (! font_not_found_p
28576 && font->default_ascent
28577 && CHAR_TABLE_P (Vuse_default_ascent)
28578 && !NILP (Faref (Vuse_default_ascent,
28579 make_number (it->char_to_display))))
28580 highest = font->default_ascent + boff;
28582 /* Draw the first glyph at the normal position. It may be
28583 shifted to right later if some other glyphs are drawn
28584 at the left. */
28585 cmp->offsets[i * 2] = 0;
28586 cmp->offsets[i * 2 + 1] = boff;
28587 cmp->lbearing = lbearing;
28588 cmp->rbearing = rbearing;
28590 /* Set cmp->offsets for the remaining glyphs. */
28591 for (i++; i < glyph_len; i++)
28593 int left, right, btm, top;
28594 int ch = COMPOSITION_GLYPH (cmp, i);
28595 int face_id;
28596 struct face *this_face;
28598 if (ch == '\t')
28599 ch = ' ';
28600 face_id = FACE_FOR_CHAR (it->f, face, ch, pos, it->string);
28601 this_face = FACE_FROM_ID (it->f, face_id);
28602 font = this_face->font;
28604 if (font == NULL)
28605 pcm = NULL;
28606 else
28608 get_char_face_and_encoding (it->f, ch, face_id,
28609 &char2b, false);
28610 pcm = get_per_char_metric (font, &char2b);
28612 if (! pcm)
28613 cmp->offsets[i * 2] = cmp->offsets[i * 2 + 1] = 0;
28614 else
28616 width = pcm->width;
28617 ascent = pcm->ascent;
28618 descent = pcm->descent;
28619 lbearing = pcm->lbearing;
28620 rbearing = pcm->rbearing;
28621 if (cmp->method != COMPOSITION_WITH_RULE_ALTCHARS)
28623 /* Relative composition with or without
28624 alternate chars. */
28625 left = (leftmost + rightmost - width) / 2;
28626 btm = - descent + boff;
28627 if (font->relative_compose
28628 && (! CHAR_TABLE_P (Vignore_relative_composition)
28629 || NILP (Faref (Vignore_relative_composition,
28630 make_number (ch)))))
28633 if (- descent >= font->relative_compose)
28634 /* One extra pixel between two glyphs. */
28635 btm = highest + 1;
28636 else if (ascent <= 0)
28637 /* One extra pixel between two glyphs. */
28638 btm = lowest - 1 - ascent - descent;
28641 else
28643 /* A composition rule is specified by an integer
28644 value that encodes global and new reference
28645 points (GREF and NREF). GREF and NREF are
28646 specified by numbers as below:
28648 0---1---2 -- ascent
28652 9--10--11 -- center
28654 ---3---4---5--- baseline
28656 6---7---8 -- descent
28658 int rule = COMPOSITION_RULE (cmp, i);
28659 int gref, nref, grefx, grefy, nrefx, nrefy, xoff, yoff;
28661 COMPOSITION_DECODE_RULE (rule, gref, nref, xoff, yoff);
28662 grefx = gref % 3, nrefx = nref % 3;
28663 grefy = gref / 3, nrefy = nref / 3;
28664 if (xoff)
28665 xoff = font_height * (xoff - 128) / 256;
28666 if (yoff)
28667 yoff = font_height * (yoff - 128) / 256;
28669 left = (leftmost
28670 + grefx * (rightmost - leftmost) / 2
28671 - nrefx * width / 2
28672 + xoff);
28674 btm = ((grefy == 0 ? highest
28675 : grefy == 1 ? 0
28676 : grefy == 2 ? lowest
28677 : (highest + lowest) / 2)
28678 - (nrefy == 0 ? ascent + descent
28679 : nrefy == 1 ? descent - boff
28680 : nrefy == 2 ? 0
28681 : (ascent + descent) / 2)
28682 + yoff);
28685 cmp->offsets[i * 2] = left;
28686 cmp->offsets[i * 2 + 1] = btm + descent;
28688 /* Update the bounding box of the overall glyphs. */
28689 if (width > 0)
28691 right = left + width;
28692 if (left < leftmost)
28693 leftmost = left;
28694 if (right > rightmost)
28695 rightmost = right;
28697 top = btm + descent + ascent;
28698 if (top > highest)
28699 highest = top;
28700 if (btm < lowest)
28701 lowest = btm;
28703 if (cmp->lbearing > left + lbearing)
28704 cmp->lbearing = left + lbearing;
28705 if (cmp->rbearing < left + rbearing)
28706 cmp->rbearing = left + rbearing;
28710 /* If there are glyphs whose x-offsets are negative,
28711 shift all glyphs to the right and make all x-offsets
28712 non-negative. */
28713 if (leftmost < 0)
28715 for (i = 0; i < cmp->glyph_len; i++)
28716 cmp->offsets[i * 2] -= leftmost;
28717 rightmost -= leftmost;
28718 cmp->lbearing -= leftmost;
28719 cmp->rbearing -= leftmost;
28722 if (left_padded && cmp->lbearing < 0)
28724 for (i = 0; i < cmp->glyph_len; i++)
28725 cmp->offsets[i * 2] -= cmp->lbearing;
28726 rightmost -= cmp->lbearing;
28727 cmp->rbearing -= cmp->lbearing;
28728 cmp->lbearing = 0;
28730 if (right_padded && rightmost < cmp->rbearing)
28732 rightmost = cmp->rbearing;
28735 cmp->pixel_width = rightmost;
28736 cmp->ascent = highest;
28737 cmp->descent = - lowest;
28738 if (cmp->ascent < font_ascent)
28739 cmp->ascent = font_ascent;
28740 if (cmp->descent < font_descent)
28741 cmp->descent = font_descent;
28744 if (it->glyph_row
28745 && (cmp->lbearing < 0
28746 || cmp->rbearing > cmp->pixel_width))
28747 it->glyph_row->contains_overlapping_glyphs_p = true;
28749 it->pixel_width = cmp->pixel_width;
28750 it->ascent = it->phys_ascent = cmp->ascent;
28751 it->descent = it->phys_descent = cmp->descent;
28752 if (face->box != FACE_NO_BOX)
28754 int thick = face->box_line_width;
28756 if (thick > 0)
28758 it->ascent += thick;
28759 it->descent += thick;
28761 else
28762 thick = - thick;
28764 if (it->start_of_box_run_p)
28765 it->pixel_width += thick;
28766 if (it->end_of_box_run_p)
28767 it->pixel_width += thick;
28770 /* If face has an overline, add the height of the overline
28771 (1 pixel) and a 1 pixel margin to the character height. */
28772 if (face->overline_p)
28773 it->ascent += overline_margin;
28775 take_vertical_position_into_account (it);
28776 if (it->ascent < 0)
28777 it->ascent = 0;
28778 if (it->descent < 0)
28779 it->descent = 0;
28781 if (it->glyph_row && cmp->glyph_len > 0)
28782 append_composite_glyph (it);
28784 else if (it->what == IT_COMPOSITION)
28786 /* A dynamic (automatic) composition. */
28787 struct face *face = FACE_FROM_ID (it->f, it->face_id);
28788 Lisp_Object gstring;
28789 struct font_metrics metrics;
28791 it->nglyphs = 1;
28793 gstring = composition_gstring_from_id (it->cmp_it.id);
28794 it->pixel_width
28795 = composition_gstring_width (gstring, it->cmp_it.from, it->cmp_it.to,
28796 &metrics);
28797 if (it->glyph_row
28798 && (metrics.lbearing < 0 || metrics.rbearing > metrics.width))
28799 it->glyph_row->contains_overlapping_glyphs_p = true;
28800 it->ascent = it->phys_ascent = metrics.ascent;
28801 it->descent = it->phys_descent = metrics.descent;
28802 if (face->box != FACE_NO_BOX)
28804 int thick = face->box_line_width;
28806 if (thick > 0)
28808 it->ascent += thick;
28809 it->descent += thick;
28811 else
28812 thick = - thick;
28814 if (it->start_of_box_run_p)
28815 it->pixel_width += thick;
28816 if (it->end_of_box_run_p)
28817 it->pixel_width += thick;
28819 /* If face has an overline, add the height of the overline
28820 (1 pixel) and a 1 pixel margin to the character height. */
28821 if (face->overline_p)
28822 it->ascent += overline_margin;
28823 take_vertical_position_into_account (it);
28824 if (it->ascent < 0)
28825 it->ascent = 0;
28826 if (it->descent < 0)
28827 it->descent = 0;
28829 if (it->glyph_row)
28830 append_composite_glyph (it);
28832 else if (it->what == IT_GLYPHLESS)
28833 produce_glyphless_glyph (it, false, Qnil);
28834 else if (it->what == IT_IMAGE)
28835 produce_image_glyph (it);
28836 else if (it->what == IT_STRETCH)
28837 produce_stretch_glyph (it);
28838 else if (it->what == IT_XWIDGET)
28839 produce_xwidget_glyph (it);
28841 done:
28842 /* Accumulate dimensions. Note: can't assume that it->descent > 0
28843 because this isn't true for images with `:ascent 100'. */
28844 eassert (it->ascent >= 0 && it->descent >= 0);
28845 if (it->area == TEXT_AREA)
28846 it->current_x += it->pixel_width;
28848 if (extra_line_spacing > 0)
28850 it->descent += extra_line_spacing;
28851 if (extra_line_spacing > it->max_extra_line_spacing)
28852 it->max_extra_line_spacing = extra_line_spacing;
28855 it->max_ascent = max (it->max_ascent, it->ascent);
28856 it->max_descent = max (it->max_descent, it->descent);
28857 it->max_phys_ascent = max (it->max_phys_ascent, it->phys_ascent);
28858 it->max_phys_descent = max (it->max_phys_descent, it->phys_descent);
28861 /* EXPORT for RIF:
28862 Output LEN glyphs starting at START at the nominal cursor position.
28863 Advance the nominal cursor over the text. UPDATED_ROW is the glyph row
28864 being updated, and UPDATED_AREA is the area of that row being updated. */
28866 void
28867 x_write_glyphs (struct window *w, struct glyph_row *updated_row,
28868 struct glyph *start, enum glyph_row_area updated_area, int len)
28870 int x, hpos, chpos = w->phys_cursor.hpos;
28872 eassert (updated_row);
28873 /* When the window is hscrolled, cursor hpos can legitimately be out
28874 of bounds, but we draw the cursor at the corresponding window
28875 margin in that case. */
28876 if (!updated_row->reversed_p && chpos < 0)
28877 chpos = 0;
28878 if (updated_row->reversed_p && chpos >= updated_row->used[TEXT_AREA])
28879 chpos = updated_row->used[TEXT_AREA] - 1;
28881 block_input ();
28883 /* Write glyphs. */
28885 hpos = start - updated_row->glyphs[updated_area];
28886 x = draw_glyphs (w, w->output_cursor.x,
28887 updated_row, updated_area,
28888 hpos, hpos + len,
28889 DRAW_NORMAL_TEXT, 0);
28891 /* Invalidate old phys cursor if the glyph at its hpos is redrawn. */
28892 if (updated_area == TEXT_AREA
28893 && w->phys_cursor_on_p
28894 && w->phys_cursor.vpos == w->output_cursor.vpos
28895 && chpos >= hpos
28896 && chpos < hpos + len)
28897 w->phys_cursor_on_p = false;
28899 unblock_input ();
28901 /* Advance the output cursor. */
28902 w->output_cursor.hpos += len;
28903 w->output_cursor.x = x;
28907 /* EXPORT for RIF:
28908 Insert LEN glyphs from START at the nominal cursor position. */
28910 void
28911 x_insert_glyphs (struct window *w, struct glyph_row *updated_row,
28912 struct glyph *start, enum glyph_row_area updated_area, int len)
28914 struct frame *f;
28915 int line_height, shift_by_width, shifted_region_width;
28916 struct glyph_row *row;
28917 struct glyph *glyph;
28918 int frame_x, frame_y;
28919 ptrdiff_t hpos;
28921 eassert (updated_row);
28922 block_input ();
28923 f = XFRAME (WINDOW_FRAME (w));
28925 /* Get the height of the line we are in. */
28926 row = updated_row;
28927 line_height = row->height;
28929 /* Get the width of the glyphs to insert. */
28930 shift_by_width = 0;
28931 for (glyph = start; glyph < start + len; ++glyph)
28932 shift_by_width += glyph->pixel_width;
28934 /* Get the width of the region to shift right. */
28935 shifted_region_width = (window_box_width (w, updated_area)
28936 - w->output_cursor.x
28937 - shift_by_width);
28939 /* Shift right. */
28940 frame_x = window_box_left (w, updated_area) + w->output_cursor.x;
28941 frame_y = WINDOW_TO_FRAME_PIXEL_Y (w, w->output_cursor.y);
28943 FRAME_RIF (f)->shift_glyphs_for_insert (f, frame_x, frame_y, shifted_region_width,
28944 line_height, shift_by_width);
28946 /* Write the glyphs. */
28947 hpos = start - row->glyphs[updated_area];
28948 draw_glyphs (w, w->output_cursor.x, row, updated_area,
28949 hpos, hpos + len,
28950 DRAW_NORMAL_TEXT, 0);
28952 /* Advance the output cursor. */
28953 w->output_cursor.hpos += len;
28954 w->output_cursor.x += shift_by_width;
28955 unblock_input ();
28959 /* EXPORT for RIF:
28960 Erase the current text line from the nominal cursor position
28961 (inclusive) to pixel column TO_X (exclusive). The idea is that
28962 everything from TO_X onward is already erased.
28964 TO_X is a pixel position relative to UPDATED_AREA of currently
28965 updated window W. TO_X == -1 means clear to the end of this area. */
28967 void
28968 x_clear_end_of_line (struct window *w, struct glyph_row *updated_row,
28969 enum glyph_row_area updated_area, int to_x)
28971 struct frame *f;
28972 int max_x, min_y, max_y;
28973 int from_x, from_y, to_y;
28975 eassert (updated_row);
28976 f = XFRAME (w->frame);
28978 if (updated_row->full_width_p)
28979 max_x = (WINDOW_PIXEL_WIDTH (w)
28980 - (updated_row->mode_line_p ? WINDOW_RIGHT_DIVIDER_WIDTH (w) : 0));
28981 else
28982 max_x = window_box_width (w, updated_area);
28983 max_y = window_text_bottom_y (w);
28985 /* TO_X == 0 means don't do anything. TO_X < 0 means clear to end
28986 of window. For TO_X > 0, truncate to end of drawing area. */
28987 if (to_x == 0)
28988 return;
28989 else if (to_x < 0)
28990 to_x = max_x;
28991 else
28992 to_x = min (to_x, max_x);
28994 to_y = min (max_y, w->output_cursor.y + updated_row->height);
28996 /* Notice if the cursor will be cleared by this operation. */
28997 if (!updated_row->full_width_p)
28998 notice_overwritten_cursor (w, updated_area,
28999 w->output_cursor.x, -1,
29000 updated_row->y,
29001 MATRIX_ROW_BOTTOM_Y (updated_row));
29003 from_x = w->output_cursor.x;
29005 /* Translate to frame coordinates. */
29006 if (updated_row->full_width_p)
29008 from_x = WINDOW_TO_FRAME_PIXEL_X (w, from_x);
29009 to_x = WINDOW_TO_FRAME_PIXEL_X (w, to_x);
29011 else
29013 int area_left = window_box_left (w, updated_area);
29014 from_x += area_left;
29015 to_x += area_left;
29018 min_y = WINDOW_HEADER_LINE_HEIGHT (w);
29019 from_y = WINDOW_TO_FRAME_PIXEL_Y (w, max (min_y, w->output_cursor.y));
29020 to_y = WINDOW_TO_FRAME_PIXEL_Y (w, to_y);
29022 /* Prevent inadvertently clearing to end of the X window. */
29023 if (to_x > from_x && to_y > from_y)
29025 block_input ();
29026 FRAME_RIF (f)->clear_frame_area (f, from_x, from_y,
29027 to_x - from_x, to_y - from_y);
29028 unblock_input ();
29032 #endif /* HAVE_WINDOW_SYSTEM */
29036 /***********************************************************************
29037 Cursor types
29038 ***********************************************************************/
29040 /* Value is the internal representation of the specified cursor type
29041 ARG. If type is BAR_CURSOR, return in *WIDTH the specified width
29042 of the bar cursor. */
29044 static enum text_cursor_kinds
29045 get_specified_cursor_type (Lisp_Object arg, int *width)
29047 enum text_cursor_kinds type;
29049 if (NILP (arg))
29050 return NO_CURSOR;
29052 if (EQ (arg, Qbox))
29053 return FILLED_BOX_CURSOR;
29055 if (EQ (arg, Qhollow))
29056 return HOLLOW_BOX_CURSOR;
29058 if (EQ (arg, Qbar))
29060 *width = 2;
29061 return BAR_CURSOR;
29064 if (CONSP (arg)
29065 && EQ (XCAR (arg), Qbar)
29066 && RANGED_INTEGERP (0, XCDR (arg), INT_MAX))
29068 *width = XINT (XCDR (arg));
29069 return BAR_CURSOR;
29072 if (EQ (arg, Qhbar))
29074 *width = 2;
29075 return HBAR_CURSOR;
29078 if (CONSP (arg)
29079 && EQ (XCAR (arg), Qhbar)
29080 && RANGED_INTEGERP (0, XCDR (arg), INT_MAX))
29082 *width = XINT (XCDR (arg));
29083 return HBAR_CURSOR;
29086 /* Treat anything unknown as "hollow box cursor".
29087 It was bad to signal an error; people have trouble fixing
29088 .Xdefaults with Emacs, when it has something bad in it. */
29089 type = HOLLOW_BOX_CURSOR;
29091 return type;
29094 /* Set the default cursor types for specified frame. */
29095 void
29096 set_frame_cursor_types (struct frame *f, Lisp_Object arg)
29098 int width = 1;
29099 Lisp_Object tem;
29101 FRAME_DESIRED_CURSOR (f) = get_specified_cursor_type (arg, &width);
29102 FRAME_CURSOR_WIDTH (f) = width;
29104 /* By default, set up the blink-off state depending on the on-state. */
29106 tem = Fassoc (arg, Vblink_cursor_alist, Qnil);
29107 if (!NILP (tem))
29109 FRAME_BLINK_OFF_CURSOR (f)
29110 = get_specified_cursor_type (XCDR (tem), &width);
29111 FRAME_BLINK_OFF_CURSOR_WIDTH (f) = width;
29113 else
29114 FRAME_BLINK_OFF_CURSOR (f) = DEFAULT_CURSOR;
29116 /* Make sure the cursor gets redrawn. */
29117 f->cursor_type_changed = true;
29121 #ifdef HAVE_WINDOW_SYSTEM
29123 /* Return the cursor we want to be displayed in window W. Return
29124 width of bar/hbar cursor through WIDTH arg. Return with
29125 ACTIVE_CURSOR arg set to true if cursor in window W is `active'
29126 (i.e. if the `system caret' should track this cursor).
29128 In a mini-buffer window, we want the cursor only to appear if we
29129 are reading input from this window. For the selected window, we
29130 want the cursor type given by the frame parameter or buffer local
29131 setting of cursor-type. If explicitly marked off, draw no cursor.
29132 In all other cases, we want a hollow box cursor. */
29134 static enum text_cursor_kinds
29135 get_window_cursor_type (struct window *w, struct glyph *glyph, int *width,
29136 bool *active_cursor)
29138 struct frame *f = XFRAME (w->frame);
29139 struct buffer *b = XBUFFER (w->contents);
29140 int cursor_type = DEFAULT_CURSOR;
29141 Lisp_Object alt_cursor;
29142 bool non_selected = false;
29144 *active_cursor = true;
29146 /* Echo area */
29147 if (cursor_in_echo_area
29148 && FRAME_HAS_MINIBUF_P (f)
29149 && EQ (FRAME_MINIBUF_WINDOW (f), echo_area_window))
29151 if (w == XWINDOW (echo_area_window))
29153 if (EQ (BVAR (b, cursor_type), Qt) || NILP (BVAR (b, cursor_type)))
29155 *width = FRAME_CURSOR_WIDTH (f);
29156 return FRAME_DESIRED_CURSOR (f);
29158 else
29159 return get_specified_cursor_type (BVAR (b, cursor_type), width);
29162 *active_cursor = false;
29163 non_selected = true;
29166 /* Detect a nonselected window or nonselected frame. */
29167 else if (w != XWINDOW (f->selected_window)
29168 || f != FRAME_DISPLAY_INFO (f)->x_highlight_frame)
29170 *active_cursor = false;
29172 if (MINI_WINDOW_P (w) && minibuf_level == 0)
29173 return NO_CURSOR;
29175 non_selected = true;
29178 /* Never display a cursor in a window in which cursor-type is nil. */
29179 if (NILP (BVAR (b, cursor_type)))
29180 return NO_CURSOR;
29182 /* Get the normal cursor type for this window. */
29183 if (EQ (BVAR (b, cursor_type), Qt))
29185 cursor_type = FRAME_DESIRED_CURSOR (f);
29186 *width = FRAME_CURSOR_WIDTH (f);
29188 else
29189 cursor_type = get_specified_cursor_type (BVAR (b, cursor_type), width);
29191 /* Use cursor-in-non-selected-windows instead
29192 for non-selected window or frame. */
29193 if (non_selected)
29195 alt_cursor = BVAR (b, cursor_in_non_selected_windows);
29196 if (!EQ (Qt, alt_cursor))
29197 return get_specified_cursor_type (alt_cursor, width);
29198 /* t means modify the normal cursor type. */
29199 if (cursor_type == FILLED_BOX_CURSOR)
29200 cursor_type = HOLLOW_BOX_CURSOR;
29201 else if (cursor_type == BAR_CURSOR && *width > 1)
29202 --*width;
29203 return cursor_type;
29206 /* Use normal cursor if not blinked off. */
29207 if (!w->cursor_off_p)
29209 if (glyph != NULL && glyph->type == XWIDGET_GLYPH)
29210 return NO_CURSOR;
29211 if (glyph != NULL && glyph->type == IMAGE_GLYPH)
29213 if (cursor_type == FILLED_BOX_CURSOR)
29215 /* Using a block cursor on large images can be very annoying.
29216 So use a hollow cursor for "large" images.
29217 If image is not transparent (no mask), also use hollow cursor. */
29218 struct image *img = IMAGE_OPT_FROM_ID (f, glyph->u.img_id);
29219 if (img != NULL && IMAGEP (img->spec))
29221 /* Arbitrarily, interpret "Large" as >32x32 and >NxN
29222 where N = size of default frame font size.
29223 This should cover most of the "tiny" icons people may use. */
29224 if (!img->mask
29225 || img->width > max (32, WINDOW_FRAME_COLUMN_WIDTH (w))
29226 || img->height > max (32, WINDOW_FRAME_LINE_HEIGHT (w)))
29227 cursor_type = HOLLOW_BOX_CURSOR;
29230 else if (cursor_type != NO_CURSOR)
29232 /* Display current only supports BOX and HOLLOW cursors for images.
29233 So for now, unconditionally use a HOLLOW cursor when cursor is
29234 not a solid box cursor. */
29235 cursor_type = HOLLOW_BOX_CURSOR;
29238 return cursor_type;
29241 /* Cursor is blinked off, so determine how to "toggle" it. */
29243 /* First look for an entry matching the buffer's cursor-type in blink-cursor-alist. */
29244 if ((alt_cursor = Fassoc (BVAR (b, cursor_type), Vblink_cursor_alist, Qnil), !NILP (alt_cursor)))
29245 return get_specified_cursor_type (XCDR (alt_cursor), width);
29247 /* Then see if frame has specified a specific blink off cursor type. */
29248 if (FRAME_BLINK_OFF_CURSOR (f) != DEFAULT_CURSOR)
29250 *width = FRAME_BLINK_OFF_CURSOR_WIDTH (f);
29251 return FRAME_BLINK_OFF_CURSOR (f);
29254 #if false
29255 /* Some people liked having a permanently visible blinking cursor,
29256 while others had very strong opinions against it. So it was
29257 decided to remove it. KFS 2003-09-03 */
29259 /* Finally perform built-in cursor blinking:
29260 filled box <-> hollow box
29261 wide [h]bar <-> narrow [h]bar
29262 narrow [h]bar <-> no cursor
29263 other type <-> no cursor */
29265 if (cursor_type == FILLED_BOX_CURSOR)
29266 return HOLLOW_BOX_CURSOR;
29268 if ((cursor_type == BAR_CURSOR || cursor_type == HBAR_CURSOR) && *width > 1)
29270 *width = 1;
29271 return cursor_type;
29273 #endif
29275 return NO_CURSOR;
29279 /* Notice when the text cursor of window W has been completely
29280 overwritten by a drawing operation that outputs glyphs in AREA
29281 starting at X0 and ending at X1 in the line starting at Y0 and
29282 ending at Y1. X coordinates are area-relative. X1 < 0 means all
29283 the rest of the line after X0 has been written. Y coordinates
29284 are window-relative. */
29286 static void
29287 notice_overwritten_cursor (struct window *w, enum glyph_row_area area,
29288 int x0, int x1, int y0, int y1)
29290 int cx0, cx1, cy0, cy1;
29291 struct glyph_row *row;
29293 if (!w->phys_cursor_on_p)
29294 return;
29295 if (area != TEXT_AREA)
29296 return;
29298 if (w->phys_cursor.vpos < 0
29299 || w->phys_cursor.vpos >= w->current_matrix->nrows
29300 || (row = w->current_matrix->rows + w->phys_cursor.vpos,
29301 !(row->enabled_p && MATRIX_ROW_DISPLAYS_TEXT_P (row))))
29302 return;
29304 if (row->cursor_in_fringe_p)
29306 row->cursor_in_fringe_p = false;
29307 draw_fringe_bitmap (w, row, row->reversed_p);
29308 w->phys_cursor_on_p = false;
29309 return;
29312 cx0 = w->phys_cursor.x;
29313 cx1 = cx0 + w->phys_cursor_width;
29314 if (x0 > cx0 || (x1 >= 0 && x1 < cx1))
29315 return;
29317 /* The cursor image will be completely removed from the
29318 screen if the output area intersects the cursor area in
29319 y-direction. When we draw in [y0 y1[, and some part of
29320 the cursor is at y < y0, that part must have been drawn
29321 before. When scrolling, the cursor is erased before
29322 actually scrolling, so we don't come here. When not
29323 scrolling, the rows above the old cursor row must have
29324 changed, and in this case these rows must have written
29325 over the cursor image.
29327 Likewise if part of the cursor is below y1, with the
29328 exception of the cursor being in the first blank row at
29329 the buffer and window end because update_text_area
29330 doesn't draw that row. (Except when it does, but
29331 that's handled in update_text_area.) */
29333 cy0 = w->phys_cursor.y;
29334 cy1 = cy0 + w->phys_cursor_height;
29335 if ((y0 < cy0 || y0 >= cy1) && (y1 <= cy0 || y1 >= cy1))
29336 return;
29338 w->phys_cursor_on_p = false;
29341 #endif /* HAVE_WINDOW_SYSTEM */
29344 /************************************************************************
29345 Mouse Face
29346 ************************************************************************/
29348 #ifdef HAVE_WINDOW_SYSTEM
29350 /* EXPORT for RIF:
29351 Fix the display of area AREA of overlapping row ROW in window W
29352 with respect to the overlapping part OVERLAPS. */
29354 void
29355 x_fix_overlapping_area (struct window *w, struct glyph_row *row,
29356 enum glyph_row_area area, int overlaps)
29358 int i, x;
29360 block_input ();
29362 x = 0;
29363 for (i = 0; i < row->used[area];)
29365 if (row->glyphs[area][i].overlaps_vertically_p)
29367 int start = i, start_x = x;
29371 x += row->glyphs[area][i].pixel_width;
29372 ++i;
29374 while (i < row->used[area]
29375 && row->glyphs[area][i].overlaps_vertically_p);
29377 draw_glyphs (w, start_x, row, area,
29378 start, i,
29379 DRAW_NORMAL_TEXT, overlaps);
29381 else
29383 x += row->glyphs[area][i].pixel_width;
29384 ++i;
29388 unblock_input ();
29392 /* EXPORT:
29393 Draw the cursor glyph of window W in glyph row ROW. See the
29394 comment of draw_glyphs for the meaning of HL. */
29396 void
29397 draw_phys_cursor_glyph (struct window *w, struct glyph_row *row,
29398 enum draw_glyphs_face hl)
29400 /* If cursor hpos is out of bounds, don't draw garbage. This can
29401 happen in mini-buffer windows when switching between echo area
29402 glyphs and mini-buffer. */
29403 if ((row->reversed_p
29404 ? (w->phys_cursor.hpos >= 0)
29405 : (w->phys_cursor.hpos < row->used[TEXT_AREA])))
29407 bool on_p = w->phys_cursor_on_p;
29408 int x1;
29409 int hpos = w->phys_cursor.hpos;
29411 /* When the window is hscrolled, cursor hpos can legitimately be
29412 out of bounds, but we draw the cursor at the corresponding
29413 window margin in that case. */
29414 if (!row->reversed_p && hpos < 0)
29415 hpos = 0;
29416 if (row->reversed_p && hpos >= row->used[TEXT_AREA])
29417 hpos = row->used[TEXT_AREA] - 1;
29419 x1 = draw_glyphs (w, w->phys_cursor.x, row, TEXT_AREA, hpos, hpos + 1,
29420 hl, 0);
29421 w->phys_cursor_on_p = on_p;
29423 if (hl == DRAW_CURSOR)
29424 w->phys_cursor_width = x1 - w->phys_cursor.x;
29425 /* When we erase the cursor, and ROW is overlapped by other
29426 rows, make sure that these overlapping parts of other rows
29427 are redrawn. */
29428 else if (hl == DRAW_NORMAL_TEXT && row->overlapped_p)
29430 w->phys_cursor_width = x1 - w->phys_cursor.x;
29432 if (row > w->current_matrix->rows
29433 && MATRIX_ROW_OVERLAPS_SUCC_P (row - 1))
29434 x_fix_overlapping_area (w, row - 1, TEXT_AREA,
29435 OVERLAPS_ERASED_CURSOR);
29437 if (MATRIX_ROW_BOTTOM_Y (row) < window_text_bottom_y (w)
29438 && MATRIX_ROW_OVERLAPS_PRED_P (row + 1))
29439 x_fix_overlapping_area (w, row + 1, TEXT_AREA,
29440 OVERLAPS_ERASED_CURSOR);
29446 /* Erase the image of a cursor of window W from the screen. */
29448 void
29449 erase_phys_cursor (struct window *w)
29451 struct frame *f = XFRAME (w->frame);
29452 Mouse_HLInfo *hlinfo = MOUSE_HL_INFO (f);
29453 int hpos = w->phys_cursor.hpos;
29454 int vpos = w->phys_cursor.vpos;
29455 bool mouse_face_here_p = false;
29456 struct glyph_matrix *active_glyphs = w->current_matrix;
29457 struct glyph_row *cursor_row;
29458 struct glyph *cursor_glyph;
29459 enum draw_glyphs_face hl;
29461 /* No cursor displayed or row invalidated => nothing to do on the
29462 screen. */
29463 if (w->phys_cursor_type == NO_CURSOR)
29464 goto mark_cursor_off;
29466 /* VPOS >= active_glyphs->nrows means that window has been resized.
29467 Don't bother to erase the cursor. */
29468 if (vpos >= active_glyphs->nrows)
29469 goto mark_cursor_off;
29471 /* If row containing cursor is marked invalid, there is nothing we
29472 can do. */
29473 cursor_row = MATRIX_ROW (active_glyphs, vpos);
29474 if (!cursor_row->enabled_p)
29475 goto mark_cursor_off;
29477 /* If line spacing is > 0, old cursor may only be partially visible in
29478 window after split-window. So adjust visible height. */
29479 cursor_row->visible_height = min (cursor_row->visible_height,
29480 window_text_bottom_y (w) - cursor_row->y);
29482 /* If row is completely invisible, don't attempt to delete a cursor which
29483 isn't there. This can happen if cursor is at top of a window, and
29484 we switch to a buffer with a header line in that window. */
29485 if (cursor_row->visible_height <= 0)
29486 goto mark_cursor_off;
29488 /* If cursor is in the fringe, erase by drawing actual bitmap there. */
29489 if (cursor_row->cursor_in_fringe_p)
29491 cursor_row->cursor_in_fringe_p = false;
29492 draw_fringe_bitmap (w, cursor_row, cursor_row->reversed_p);
29493 goto mark_cursor_off;
29496 /* This can happen when the new row is shorter than the old one.
29497 In this case, either draw_glyphs or clear_end_of_line
29498 should have cleared the cursor. Note that we wouldn't be
29499 able to erase the cursor in this case because we don't have a
29500 cursor glyph at hand. */
29501 if ((cursor_row->reversed_p
29502 ? (w->phys_cursor.hpos < 0)
29503 : (w->phys_cursor.hpos >= cursor_row->used[TEXT_AREA])))
29504 goto mark_cursor_off;
29506 /* When the window is hscrolled, cursor hpos can legitimately be out
29507 of bounds, but we draw the cursor at the corresponding window
29508 margin in that case. */
29509 if (!cursor_row->reversed_p && hpos < 0)
29510 hpos = 0;
29511 if (cursor_row->reversed_p && hpos >= cursor_row->used[TEXT_AREA])
29512 hpos = cursor_row->used[TEXT_AREA] - 1;
29514 /* If the cursor is in the mouse face area, redisplay that when
29515 we clear the cursor. */
29516 if (! NILP (hlinfo->mouse_face_window)
29517 && coords_in_mouse_face_p (w, hpos, vpos)
29518 /* Don't redraw the cursor's spot in mouse face if it is at the
29519 end of a line (on a newline). The cursor appears there, but
29520 mouse highlighting does not. */
29521 && cursor_row->used[TEXT_AREA] > hpos && hpos >= 0)
29522 mouse_face_here_p = true;
29524 /* Maybe clear the display under the cursor. */
29525 if (w->phys_cursor_type == HOLLOW_BOX_CURSOR)
29527 int x, y;
29528 int header_line_height = WINDOW_HEADER_LINE_HEIGHT (w);
29529 int width;
29531 cursor_glyph = get_phys_cursor_glyph (w);
29532 if (cursor_glyph == NULL)
29533 goto mark_cursor_off;
29535 width = cursor_glyph->pixel_width;
29536 x = w->phys_cursor.x;
29537 if (x < 0)
29539 width += x;
29540 x = 0;
29542 width = min (width, window_box_width (w, TEXT_AREA) - x);
29543 y = WINDOW_TO_FRAME_PIXEL_Y (w, max (header_line_height, cursor_row->y));
29544 x = WINDOW_TEXT_TO_FRAME_PIXEL_X (w, x);
29546 if (width > 0)
29547 FRAME_RIF (f)->clear_frame_area (f, x, y, width, cursor_row->visible_height);
29550 /* Erase the cursor by redrawing the character underneath it. */
29551 if (mouse_face_here_p)
29552 hl = DRAW_MOUSE_FACE;
29553 else
29554 hl = DRAW_NORMAL_TEXT;
29555 draw_phys_cursor_glyph (w, cursor_row, hl);
29557 mark_cursor_off:
29558 w->phys_cursor_on_p = false;
29559 w->phys_cursor_type = NO_CURSOR;
29563 /* Display or clear cursor of window W. If !ON, clear the cursor.
29564 If ON, display the cursor; where to put the cursor is specified by
29565 HPOS, VPOS, X and Y. */
29567 void
29568 display_and_set_cursor (struct window *w, bool on,
29569 int hpos, int vpos, int x, int y)
29571 struct frame *f = XFRAME (w->frame);
29572 int new_cursor_type;
29573 int new_cursor_width;
29574 bool active_cursor;
29575 struct glyph_row *glyph_row;
29576 struct glyph *glyph;
29578 /* This is pointless on invisible frames, and dangerous on garbaged
29579 windows and frames; in the latter case, the frame or window may
29580 be in the midst of changing its size, and x and y may be off the
29581 window. */
29582 if (! FRAME_VISIBLE_P (f)
29583 || vpos >= w->current_matrix->nrows
29584 || hpos >= w->current_matrix->matrix_w)
29585 return;
29587 /* If cursor is off and we want it off, return quickly. */
29588 if (!on && !w->phys_cursor_on_p)
29589 return;
29591 glyph_row = MATRIX_ROW (w->current_matrix, vpos);
29592 /* If cursor row is not enabled, we don't really know where to
29593 display the cursor. */
29594 if (!glyph_row->enabled_p)
29596 w->phys_cursor_on_p = false;
29597 return;
29600 /* A frame might be marked garbaged even though its cursor position
29601 is correct, and will not change upon subsequent redisplay. This
29602 happens in some rare situations, like toggling the sort order in
29603 Dired windows. We've already established that VPOS is valid, so
29604 it shouldn't do any harm to record the cursor position, as we are
29605 going to return without acting on it anyway. Otherwise, expose
29606 events might come in and call update_window_cursor, which will
29607 blindly use outdated values in w->phys_cursor. */
29608 if (FRAME_GARBAGED_P (f))
29610 if (on)
29612 w->phys_cursor.x = x;
29613 w->phys_cursor.y = glyph_row->y;
29614 w->phys_cursor.hpos = hpos;
29615 w->phys_cursor.vpos = vpos;
29617 return;
29620 glyph = NULL;
29621 if (0 <= hpos && hpos < glyph_row->used[TEXT_AREA])
29622 glyph = glyph_row->glyphs[TEXT_AREA] + hpos;
29624 eassert (input_blocked_p ());
29626 /* Set new_cursor_type to the cursor we want to be displayed. */
29627 new_cursor_type = get_window_cursor_type (w, glyph,
29628 &new_cursor_width, &active_cursor);
29630 /* If cursor is currently being shown and we don't want it to be or
29631 it is in the wrong place, or the cursor type is not what we want,
29632 erase it. */
29633 if (w->phys_cursor_on_p
29634 && (!on
29635 || w->phys_cursor.x != x
29636 || w->phys_cursor.y != y
29637 /* HPOS can be negative in R2L rows whose
29638 exact_window_width_line_p flag is set (i.e. their newline
29639 would "overflow into the fringe"). */
29640 || hpos < 0
29641 || new_cursor_type != w->phys_cursor_type
29642 || ((new_cursor_type == BAR_CURSOR || new_cursor_type == HBAR_CURSOR)
29643 && new_cursor_width != w->phys_cursor_width)))
29644 erase_phys_cursor (w);
29646 /* Don't check phys_cursor_on_p here because that flag is only set
29647 to false in some cases where we know that the cursor has been
29648 completely erased, to avoid the extra work of erasing the cursor
29649 twice. In other words, phys_cursor_on_p can be true and the cursor
29650 still not be visible, or it has only been partly erased. */
29651 if (on)
29653 w->phys_cursor_ascent = glyph_row->ascent;
29654 w->phys_cursor_height = glyph_row->height;
29656 /* Set phys_cursor_.* before x_draw_.* is called because some
29657 of them may need the information. */
29658 w->phys_cursor.x = x;
29659 w->phys_cursor.y = glyph_row->y;
29660 w->phys_cursor.hpos = hpos;
29661 w->phys_cursor.vpos = vpos;
29664 FRAME_RIF (f)->draw_window_cursor (w, glyph_row, x, y,
29665 new_cursor_type, new_cursor_width,
29666 on, active_cursor);
29670 /* Switch the display of W's cursor on or off, according to the value
29671 of ON. */
29673 static void
29674 update_window_cursor (struct window *w, bool on)
29676 /* Don't update cursor in windows whose frame is in the process
29677 of being deleted. */
29678 if (w->current_matrix)
29680 int hpos = w->phys_cursor.hpos;
29681 int vpos = w->phys_cursor.vpos;
29682 struct glyph_row *row;
29684 if (vpos >= w->current_matrix->nrows
29685 || hpos >= w->current_matrix->matrix_w)
29686 return;
29688 row = MATRIX_ROW (w->current_matrix, vpos);
29690 /* When the window is hscrolled, cursor hpos can legitimately be
29691 out of bounds, but we draw the cursor at the corresponding
29692 window margin in that case. */
29693 if (!row->reversed_p && hpos < 0)
29694 hpos = 0;
29695 if (row->reversed_p && hpos >= row->used[TEXT_AREA])
29696 hpos = row->used[TEXT_AREA] - 1;
29698 block_input ();
29699 display_and_set_cursor (w, on, hpos, vpos,
29700 w->phys_cursor.x, w->phys_cursor.y);
29701 unblock_input ();
29706 /* Call update_window_cursor with parameter ON_P on all leaf windows
29707 in the window tree rooted at W. */
29709 static void
29710 update_cursor_in_window_tree (struct window *w, bool on_p)
29712 while (w)
29714 if (WINDOWP (w->contents))
29715 update_cursor_in_window_tree (XWINDOW (w->contents), on_p);
29716 else
29717 update_window_cursor (w, on_p);
29719 w = NILP (w->next) ? 0 : XWINDOW (w->next);
29724 /* EXPORT:
29725 Display the cursor on window W, or clear it, according to ON_P.
29726 Don't change the cursor's position. */
29728 void
29729 x_update_cursor (struct frame *f, bool on_p)
29731 update_cursor_in_window_tree (XWINDOW (f->root_window), on_p);
29735 /* EXPORT:
29736 Clear the cursor of window W to background color, and mark the
29737 cursor as not shown. This is used when the text where the cursor
29738 is about to be rewritten. */
29740 void
29741 x_clear_cursor (struct window *w)
29743 if (FRAME_VISIBLE_P (XFRAME (w->frame)) && w->phys_cursor_on_p)
29744 update_window_cursor (w, false);
29747 #endif /* HAVE_WINDOW_SYSTEM */
29749 /* Implementation of draw_row_with_mouse_face for GUI sessions, GPM,
29750 and MSDOS. */
29751 static void
29752 draw_row_with_mouse_face (struct window *w, int start_x, struct glyph_row *row,
29753 int start_hpos, int end_hpos,
29754 enum draw_glyphs_face draw)
29756 #ifdef HAVE_WINDOW_SYSTEM
29757 if (FRAME_WINDOW_P (XFRAME (w->frame)))
29759 draw_glyphs (w, start_x, row, TEXT_AREA, start_hpos, end_hpos, draw, 0);
29760 return;
29762 #endif
29763 #if defined (HAVE_GPM) || defined (MSDOS) || defined (WINDOWSNT)
29764 tty_draw_row_with_mouse_face (w, row, start_hpos, end_hpos, draw);
29765 #endif
29768 /* Display the active region described by mouse_face_* according to DRAW. */
29770 static void
29771 show_mouse_face (Mouse_HLInfo *hlinfo, enum draw_glyphs_face draw)
29773 struct window *w = XWINDOW (hlinfo->mouse_face_window);
29774 struct frame *f = XFRAME (WINDOW_FRAME (w));
29776 if (/* If window is in the process of being destroyed, don't bother
29777 to do anything. */
29778 w->current_matrix != NULL
29779 /* Don't update mouse highlight if hidden. */
29780 && (draw != DRAW_MOUSE_FACE || !hlinfo->mouse_face_hidden)
29781 /* Recognize when we are called to operate on rows that don't exist
29782 anymore. This can happen when a window is split. */
29783 && hlinfo->mouse_face_end_row < w->current_matrix->nrows)
29785 bool phys_cursor_on_p = w->phys_cursor_on_p;
29786 struct glyph_row *row, *first, *last;
29788 first = MATRIX_ROW (w->current_matrix, hlinfo->mouse_face_beg_row);
29789 last = MATRIX_ROW (w->current_matrix, hlinfo->mouse_face_end_row);
29791 for (row = first; row <= last && row->enabled_p; ++row)
29793 int start_hpos, end_hpos, start_x;
29795 /* For all but the first row, the highlight starts at column 0. */
29796 if (row == first)
29798 /* R2L rows have BEG and END in reversed order, but the
29799 screen drawing geometry is always left to right. So
29800 we need to mirror the beginning and end of the
29801 highlighted area in R2L rows. */
29802 if (!row->reversed_p)
29804 start_hpos = hlinfo->mouse_face_beg_col;
29805 start_x = hlinfo->mouse_face_beg_x;
29807 else if (row == last)
29809 start_hpos = hlinfo->mouse_face_end_col;
29810 start_x = hlinfo->mouse_face_end_x;
29812 else
29814 start_hpos = 0;
29815 start_x = 0;
29818 else if (row->reversed_p && row == last)
29820 start_hpos = hlinfo->mouse_face_end_col;
29821 start_x = hlinfo->mouse_face_end_x;
29823 else
29825 start_hpos = 0;
29826 start_x = 0;
29829 if (row == last)
29831 if (!row->reversed_p)
29832 end_hpos = hlinfo->mouse_face_end_col;
29833 else if (row == first)
29834 end_hpos = hlinfo->mouse_face_beg_col;
29835 else
29837 end_hpos = row->used[TEXT_AREA];
29838 if (draw == DRAW_NORMAL_TEXT)
29839 row->fill_line_p = true; /* Clear to end of line. */
29842 else if (row->reversed_p && row == first)
29843 end_hpos = hlinfo->mouse_face_beg_col;
29844 else
29846 end_hpos = row->used[TEXT_AREA];
29847 if (draw == DRAW_NORMAL_TEXT)
29848 row->fill_line_p = true; /* Clear to end of line. */
29851 if (end_hpos > start_hpos)
29853 draw_row_with_mouse_face (w, start_x, row,
29854 start_hpos, end_hpos, draw);
29856 row->mouse_face_p
29857 = draw == DRAW_MOUSE_FACE || draw == DRAW_IMAGE_RAISED;
29861 /* When we've written over the cursor, arrange for it to
29862 be displayed again. */
29863 if (FRAME_WINDOW_P (f)
29864 && phys_cursor_on_p && !w->phys_cursor_on_p)
29866 #ifdef HAVE_WINDOW_SYSTEM
29867 int hpos = w->phys_cursor.hpos;
29869 /* When the window is hscrolled, cursor hpos can legitimately be
29870 out of bounds, but we draw the cursor at the corresponding
29871 window margin in that case. */
29872 if (!row->reversed_p && hpos < 0)
29873 hpos = 0;
29874 if (row->reversed_p && hpos >= row->used[TEXT_AREA])
29875 hpos = row->used[TEXT_AREA] - 1;
29877 block_input ();
29878 display_and_set_cursor (w, true, hpos, w->phys_cursor.vpos,
29879 w->phys_cursor.x, w->phys_cursor.y);
29880 unblock_input ();
29881 #endif /* HAVE_WINDOW_SYSTEM */
29885 #ifdef HAVE_WINDOW_SYSTEM
29886 /* Change the mouse cursor. */
29887 if (FRAME_WINDOW_P (f) && NILP (do_mouse_tracking))
29889 #if ! defined (USE_GTK) && ! defined (HAVE_NS)
29890 if (draw == DRAW_NORMAL_TEXT
29891 && !EQ (hlinfo->mouse_face_window, f->tool_bar_window))
29892 FRAME_RIF (f)->define_frame_cursor (f, FRAME_X_OUTPUT (f)->text_cursor);
29893 else
29894 #endif
29895 if (draw == DRAW_MOUSE_FACE)
29896 FRAME_RIF (f)->define_frame_cursor (f, FRAME_X_OUTPUT (f)->hand_cursor);
29897 else
29898 FRAME_RIF (f)->define_frame_cursor (f, FRAME_X_OUTPUT (f)->nontext_cursor);
29900 #endif /* HAVE_WINDOW_SYSTEM */
29903 /* EXPORT:
29904 Clear out the mouse-highlighted active region.
29905 Redraw it un-highlighted first. Value is true if mouse
29906 face was actually drawn unhighlighted. */
29908 bool
29909 clear_mouse_face (Mouse_HLInfo *hlinfo)
29911 bool cleared
29912 = !hlinfo->mouse_face_hidden && !NILP (hlinfo->mouse_face_window);
29913 if (cleared)
29914 show_mouse_face (hlinfo, DRAW_NORMAL_TEXT);
29915 hlinfo->mouse_face_beg_row = hlinfo->mouse_face_beg_col = -1;
29916 hlinfo->mouse_face_end_row = hlinfo->mouse_face_end_col = -1;
29917 hlinfo->mouse_face_window = Qnil;
29918 hlinfo->mouse_face_overlay = Qnil;
29919 return cleared;
29922 /* Return true if the coordinates HPOS and VPOS on windows W are
29923 within the mouse face on that window. */
29924 static bool
29925 coords_in_mouse_face_p (struct window *w, int hpos, int vpos)
29927 Mouse_HLInfo *hlinfo = MOUSE_HL_INFO (XFRAME (w->frame));
29929 /* Quickly resolve the easy cases. */
29930 if (!(WINDOWP (hlinfo->mouse_face_window)
29931 && XWINDOW (hlinfo->mouse_face_window) == w))
29932 return false;
29933 if (vpos < hlinfo->mouse_face_beg_row
29934 || vpos > hlinfo->mouse_face_end_row)
29935 return false;
29936 if (vpos > hlinfo->mouse_face_beg_row
29937 && vpos < hlinfo->mouse_face_end_row)
29938 return true;
29940 if (!MATRIX_ROW (w->current_matrix, vpos)->reversed_p)
29942 if (hlinfo->mouse_face_beg_row == hlinfo->mouse_face_end_row)
29944 if (hlinfo->mouse_face_beg_col <= hpos && hpos < hlinfo->mouse_face_end_col)
29945 return true;
29947 else if ((vpos == hlinfo->mouse_face_beg_row
29948 && hpos >= hlinfo->mouse_face_beg_col)
29949 || (vpos == hlinfo->mouse_face_end_row
29950 && hpos < hlinfo->mouse_face_end_col))
29951 return true;
29953 else
29955 if (hlinfo->mouse_face_beg_row == hlinfo->mouse_face_end_row)
29957 if (hlinfo->mouse_face_end_col < hpos && hpos <= hlinfo->mouse_face_beg_col)
29958 return true;
29960 else if ((vpos == hlinfo->mouse_face_beg_row
29961 && hpos <= hlinfo->mouse_face_beg_col)
29962 || (vpos == hlinfo->mouse_face_end_row
29963 && hpos > hlinfo->mouse_face_end_col))
29964 return true;
29966 return false;
29970 /* EXPORT:
29971 True if physical cursor of window W is within mouse face. */
29973 bool
29974 cursor_in_mouse_face_p (struct window *w)
29976 int hpos = w->phys_cursor.hpos;
29977 int vpos = w->phys_cursor.vpos;
29978 struct glyph_row *row = MATRIX_ROW (w->current_matrix, vpos);
29980 /* When the window is hscrolled, cursor hpos can legitimately be out
29981 of bounds, but we draw the cursor at the corresponding window
29982 margin in that case. */
29983 if (!row->reversed_p && hpos < 0)
29984 hpos = 0;
29985 if (row->reversed_p && hpos >= row->used[TEXT_AREA])
29986 hpos = row->used[TEXT_AREA] - 1;
29988 return coords_in_mouse_face_p (w, hpos, vpos);
29993 /* Find the glyph rows START_ROW and END_ROW of window W that display
29994 characters between buffer positions START_CHARPOS and END_CHARPOS
29995 (excluding END_CHARPOS). DISP_STRING is a display string that
29996 covers these buffer positions. This is similar to
29997 row_containing_pos, but is more accurate when bidi reordering makes
29998 buffer positions change non-linearly with glyph rows. */
29999 static void
30000 rows_from_pos_range (struct window *w,
30001 ptrdiff_t start_charpos, ptrdiff_t end_charpos,
30002 Lisp_Object disp_string,
30003 struct glyph_row **start, struct glyph_row **end)
30005 struct glyph_row *first = MATRIX_FIRST_TEXT_ROW (w->current_matrix);
30006 int last_y = window_text_bottom_y (w);
30007 struct glyph_row *row;
30009 *start = NULL;
30010 *end = NULL;
30012 while (!first->enabled_p
30013 && first < MATRIX_BOTTOM_TEXT_ROW (w->current_matrix, w))
30014 first++;
30016 /* Find the START row. */
30017 for (row = first;
30018 row->enabled_p && MATRIX_ROW_BOTTOM_Y (row) <= last_y;
30019 row++)
30021 /* A row can potentially be the START row if the range of the
30022 characters it displays intersects the range
30023 [START_CHARPOS..END_CHARPOS). */
30024 if (! ((start_charpos < MATRIX_ROW_START_CHARPOS (row)
30025 && end_charpos < MATRIX_ROW_START_CHARPOS (row))
30026 /* See the commentary in row_containing_pos, for the
30027 explanation of the complicated way to check whether
30028 some position is beyond the end of the characters
30029 displayed by a row. */
30030 || ((start_charpos > MATRIX_ROW_END_CHARPOS (row)
30031 || (start_charpos == MATRIX_ROW_END_CHARPOS (row)
30032 && !row->ends_at_zv_p
30033 && !MATRIX_ROW_ENDS_IN_MIDDLE_OF_CHAR_P (row)))
30034 && (end_charpos > MATRIX_ROW_END_CHARPOS (row)
30035 || (end_charpos == MATRIX_ROW_END_CHARPOS (row)
30036 && !row->ends_at_zv_p
30037 && !MATRIX_ROW_ENDS_IN_MIDDLE_OF_CHAR_P (row))))))
30039 /* Found a candidate row. Now make sure at least one of the
30040 glyphs it displays has a charpos from the range
30041 [START_CHARPOS..END_CHARPOS).
30043 This is not obvious because bidi reordering could make
30044 buffer positions of a row be 1,2,3,102,101,100, and if we
30045 want to highlight characters in [50..60), we don't want
30046 this row, even though [50..60) does intersect [1..103),
30047 the range of character positions given by the row's start
30048 and end positions. */
30049 struct glyph *g = row->glyphs[TEXT_AREA];
30050 struct glyph *e = g + row->used[TEXT_AREA];
30052 while (g < e)
30054 if (((BUFFERP (g->object) || NILP (g->object))
30055 && start_charpos <= g->charpos && g->charpos < end_charpos)
30056 /* A glyph that comes from DISP_STRING is by
30057 definition to be highlighted. */
30058 || EQ (g->object, disp_string))
30059 *start = row;
30060 g++;
30062 if (*start)
30063 break;
30067 /* Find the END row. */
30068 if (!*start
30069 /* If the last row is partially visible, start looking for END
30070 from that row, instead of starting from FIRST. */
30071 && !(row->enabled_p
30072 && row->y < last_y && MATRIX_ROW_BOTTOM_Y (row) > last_y))
30073 row = first;
30074 for ( ; row->enabled_p && MATRIX_ROW_BOTTOM_Y (row) <= last_y; row++)
30076 struct glyph_row *next = row + 1;
30077 ptrdiff_t next_start = MATRIX_ROW_START_CHARPOS (next);
30079 if (!next->enabled_p
30080 || next >= MATRIX_BOTTOM_TEXT_ROW (w->current_matrix, w)
30081 /* The first row >= START whose range of displayed characters
30082 does NOT intersect the range [START_CHARPOS..END_CHARPOS]
30083 is the row END + 1. */
30084 || (start_charpos < next_start
30085 && end_charpos < next_start)
30086 || ((start_charpos > MATRIX_ROW_END_CHARPOS (next)
30087 || (start_charpos == MATRIX_ROW_END_CHARPOS (next)
30088 && !next->ends_at_zv_p
30089 && !MATRIX_ROW_ENDS_IN_MIDDLE_OF_CHAR_P (next)))
30090 && (end_charpos > MATRIX_ROW_END_CHARPOS (next)
30091 || (end_charpos == MATRIX_ROW_END_CHARPOS (next)
30092 && !next->ends_at_zv_p
30093 && !MATRIX_ROW_ENDS_IN_MIDDLE_OF_CHAR_P (next)))))
30095 *end = row;
30096 break;
30098 else
30100 /* If the next row's edges intersect [START_CHARPOS..END_CHARPOS],
30101 but none of the characters it displays are in the range, it is
30102 also END + 1. */
30103 struct glyph *g = next->glyphs[TEXT_AREA];
30104 struct glyph *s = g;
30105 struct glyph *e = g + next->used[TEXT_AREA];
30107 while (g < e)
30109 if (((BUFFERP (g->object) || NILP (g->object))
30110 && ((start_charpos <= g->charpos && g->charpos < end_charpos)
30111 /* If the buffer position of the first glyph in
30112 the row is equal to END_CHARPOS, it means
30113 the last character to be highlighted is the
30114 newline of ROW, and we must consider NEXT as
30115 END, not END+1. */
30116 || (((!next->reversed_p && g == s)
30117 || (next->reversed_p && g == e - 1))
30118 && (g->charpos == end_charpos
30119 /* Special case for when NEXT is an
30120 empty line at ZV. */
30121 || (g->charpos == -1
30122 && !row->ends_at_zv_p
30123 && next_start == end_charpos)))))
30124 /* A glyph that comes from DISP_STRING is by
30125 definition to be highlighted. */
30126 || EQ (g->object, disp_string))
30127 break;
30128 g++;
30130 if (g == e)
30132 *end = row;
30133 break;
30135 /* The first row that ends at ZV must be the last to be
30136 highlighted. */
30137 else if (next->ends_at_zv_p)
30139 *end = next;
30140 break;
30146 /* This function sets the mouse_face_* elements of HLINFO, assuming
30147 the mouse cursor is on a glyph with buffer charpos MOUSE_CHARPOS in
30148 window WINDOW. START_CHARPOS and END_CHARPOS are buffer positions
30149 for the overlay or run of text properties specifying the mouse
30150 face. BEFORE_STRING and AFTER_STRING, if non-nil, are a
30151 before-string and after-string that must also be highlighted.
30152 DISP_STRING, if non-nil, is a display string that may cover some
30153 or all of the highlighted text. */
30155 static void
30156 mouse_face_from_buffer_pos (Lisp_Object window,
30157 Mouse_HLInfo *hlinfo,
30158 ptrdiff_t mouse_charpos,
30159 ptrdiff_t start_charpos,
30160 ptrdiff_t end_charpos,
30161 Lisp_Object before_string,
30162 Lisp_Object after_string,
30163 Lisp_Object disp_string)
30165 struct window *w = XWINDOW (window);
30166 struct glyph_row *first = MATRIX_FIRST_TEXT_ROW (w->current_matrix);
30167 struct glyph_row *r1, *r2;
30168 struct glyph *glyph, *end;
30169 ptrdiff_t ignore, pos;
30170 int x;
30172 eassert (NILP (disp_string) || STRINGP (disp_string));
30173 eassert (NILP (before_string) || STRINGP (before_string));
30174 eassert (NILP (after_string) || STRINGP (after_string));
30176 /* Find the rows corresponding to START_CHARPOS and END_CHARPOS. */
30177 rows_from_pos_range (w, start_charpos, end_charpos, disp_string, &r1, &r2);
30178 if (r1 == NULL)
30179 r1 = MATRIX_ROW (w->current_matrix, w->window_end_vpos);
30180 /* If the before-string or display-string contains newlines,
30181 rows_from_pos_range skips to its last row. Move back. */
30182 if (!NILP (before_string) || !NILP (disp_string))
30184 struct glyph_row *prev;
30185 while ((prev = r1 - 1, prev >= first)
30186 && MATRIX_ROW_END_CHARPOS (prev) == start_charpos
30187 && prev->used[TEXT_AREA] > 0)
30189 struct glyph *beg = prev->glyphs[TEXT_AREA];
30190 glyph = beg + prev->used[TEXT_AREA];
30191 while (--glyph >= beg && NILP (glyph->object));
30192 if (glyph < beg
30193 || !(EQ (glyph->object, before_string)
30194 || EQ (glyph->object, disp_string)))
30195 break;
30196 r1 = prev;
30199 if (r2 == NULL)
30201 r2 = MATRIX_ROW (w->current_matrix, w->window_end_vpos);
30202 hlinfo->mouse_face_past_end = true;
30204 else if (!NILP (after_string))
30206 /* If the after-string has newlines, advance to its last row. */
30207 struct glyph_row *next;
30208 struct glyph_row *last
30209 = MATRIX_ROW (w->current_matrix, w->window_end_vpos);
30211 for (next = r2 + 1;
30212 next <= last
30213 && next->used[TEXT_AREA] > 0
30214 && EQ (next->glyphs[TEXT_AREA]->object, after_string);
30215 ++next)
30216 r2 = next;
30218 /* The rest of the display engine assumes that mouse_face_beg_row is
30219 either above mouse_face_end_row or identical to it. But with
30220 bidi-reordered continued lines, the row for START_CHARPOS could
30221 be below the row for END_CHARPOS. If so, swap the rows and store
30222 them in correct order. */
30223 if (r1->y > r2->y)
30225 struct glyph_row *tem = r2;
30227 r2 = r1;
30228 r1 = tem;
30231 hlinfo->mouse_face_beg_row = MATRIX_ROW_VPOS (r1, w->current_matrix);
30232 hlinfo->mouse_face_end_row = MATRIX_ROW_VPOS (r2, w->current_matrix);
30234 /* For a bidi-reordered row, the positions of BEFORE_STRING,
30235 AFTER_STRING, DISP_STRING, START_CHARPOS, and END_CHARPOS
30236 could be anywhere in the row and in any order. The strategy
30237 below is to find the leftmost and the rightmost glyph that
30238 belongs to either of these 3 strings, or whose position is
30239 between START_CHARPOS and END_CHARPOS, and highlight all the
30240 glyphs between those two. This may cover more than just the text
30241 between START_CHARPOS and END_CHARPOS if the range of characters
30242 strides the bidi level boundary, e.g. if the beginning is in R2L
30243 text while the end is in L2R text or vice versa. */
30244 if (!r1->reversed_p)
30246 /* This row is in a left to right paragraph. Scan it left to
30247 right. */
30248 glyph = r1->glyphs[TEXT_AREA];
30249 end = glyph + r1->used[TEXT_AREA];
30250 x = r1->x;
30252 /* Skip truncation glyphs at the start of the glyph row. */
30253 if (MATRIX_ROW_DISPLAYS_TEXT_P (r1))
30254 for (; glyph < end
30255 && NILP (glyph->object)
30256 && glyph->charpos < 0;
30257 ++glyph)
30258 x += glyph->pixel_width;
30260 /* Scan the glyph row, looking for BEFORE_STRING, AFTER_STRING,
30261 or DISP_STRING, and the first glyph from buffer whose
30262 position is between START_CHARPOS and END_CHARPOS. */
30263 for (; glyph < end
30264 && !NILP (glyph->object)
30265 && !EQ (glyph->object, disp_string)
30266 && !(BUFFERP (glyph->object)
30267 && (glyph->charpos >= start_charpos
30268 && glyph->charpos < end_charpos));
30269 ++glyph)
30271 /* BEFORE_STRING or AFTER_STRING are only relevant if they
30272 are present at buffer positions between START_CHARPOS and
30273 END_CHARPOS, or if they come from an overlay. */
30274 if (EQ (glyph->object, before_string))
30276 pos = string_buffer_position (before_string,
30277 start_charpos);
30278 /* If pos == 0, it means before_string came from an
30279 overlay, not from a buffer position. */
30280 if (!pos || (pos >= start_charpos && pos < end_charpos))
30281 break;
30283 else if (EQ (glyph->object, after_string))
30285 pos = string_buffer_position (after_string, end_charpos);
30286 if (!pos || (pos >= start_charpos && pos < end_charpos))
30287 break;
30289 x += glyph->pixel_width;
30291 hlinfo->mouse_face_beg_x = x;
30292 hlinfo->mouse_face_beg_col = glyph - r1->glyphs[TEXT_AREA];
30294 else
30296 /* This row is in a right to left paragraph. Scan it right to
30297 left. */
30298 struct glyph *g;
30300 end = r1->glyphs[TEXT_AREA] - 1;
30301 glyph = end + r1->used[TEXT_AREA];
30303 /* Skip truncation glyphs at the start of the glyph row. */
30304 if (MATRIX_ROW_DISPLAYS_TEXT_P (r1))
30305 for (; glyph > end
30306 && NILP (glyph->object)
30307 && glyph->charpos < 0;
30308 --glyph)
30311 /* Scan the glyph row, looking for BEFORE_STRING, AFTER_STRING,
30312 or DISP_STRING, and the first glyph from buffer whose
30313 position is between START_CHARPOS and END_CHARPOS. */
30314 for (; glyph > end
30315 && !NILP (glyph->object)
30316 && !EQ (glyph->object, disp_string)
30317 && !(BUFFERP (glyph->object)
30318 && (glyph->charpos >= start_charpos
30319 && glyph->charpos < end_charpos));
30320 --glyph)
30322 /* BEFORE_STRING or AFTER_STRING are only relevant if they
30323 are present at buffer positions between START_CHARPOS and
30324 END_CHARPOS, or if they come from an overlay. */
30325 if (EQ (glyph->object, before_string))
30327 pos = string_buffer_position (before_string, start_charpos);
30328 /* If pos == 0, it means before_string came from an
30329 overlay, not from a buffer position. */
30330 if (!pos || (pos >= start_charpos && pos < end_charpos))
30331 break;
30333 else if (EQ (glyph->object, after_string))
30335 pos = string_buffer_position (after_string, end_charpos);
30336 if (!pos || (pos >= start_charpos && pos < end_charpos))
30337 break;
30341 glyph++; /* first glyph to the right of the highlighted area */
30342 for (g = r1->glyphs[TEXT_AREA], x = r1->x; g < glyph; g++)
30343 x += g->pixel_width;
30344 hlinfo->mouse_face_beg_x = x;
30345 hlinfo->mouse_face_beg_col = glyph - r1->glyphs[TEXT_AREA];
30348 /* If the highlight ends in a different row, compute GLYPH and END
30349 for the end row. Otherwise, reuse the values computed above for
30350 the row where the highlight begins. */
30351 if (r2 != r1)
30353 if (!r2->reversed_p)
30355 glyph = r2->glyphs[TEXT_AREA];
30356 end = glyph + r2->used[TEXT_AREA];
30357 x = r2->x;
30359 else
30361 end = r2->glyphs[TEXT_AREA] - 1;
30362 glyph = end + r2->used[TEXT_AREA];
30366 if (!r2->reversed_p)
30368 /* Skip truncation and continuation glyphs near the end of the
30369 row, and also blanks and stretch glyphs inserted by
30370 extend_face_to_end_of_line. */
30371 while (end > glyph
30372 && NILP ((end - 1)->object))
30373 --end;
30374 /* Scan the rest of the glyph row from the end, looking for the
30375 first glyph that comes from BEFORE_STRING, AFTER_STRING, or
30376 DISP_STRING, or whose position is between START_CHARPOS
30377 and END_CHARPOS */
30378 for (--end;
30379 end > glyph
30380 && !NILP (end->object)
30381 && !EQ (end->object, disp_string)
30382 && !(BUFFERP (end->object)
30383 && (end->charpos >= start_charpos
30384 && end->charpos < end_charpos));
30385 --end)
30387 /* BEFORE_STRING or AFTER_STRING are only relevant if they
30388 are present at buffer positions between START_CHARPOS and
30389 END_CHARPOS, or if they come from an overlay. */
30390 if (EQ (end->object, before_string))
30392 pos = string_buffer_position (before_string, start_charpos);
30393 if (!pos || (pos >= start_charpos && pos < end_charpos))
30394 break;
30396 else if (EQ (end->object, after_string))
30398 pos = string_buffer_position (after_string, end_charpos);
30399 if (!pos || (pos >= start_charpos && pos < end_charpos))
30400 break;
30403 /* Find the X coordinate of the last glyph to be highlighted. */
30404 for (; glyph <= end; ++glyph)
30405 x += glyph->pixel_width;
30407 hlinfo->mouse_face_end_x = x;
30408 hlinfo->mouse_face_end_col = glyph - r2->glyphs[TEXT_AREA];
30410 else
30412 /* Skip truncation and continuation glyphs near the end of the
30413 row, and also blanks and stretch glyphs inserted by
30414 extend_face_to_end_of_line. */
30415 x = r2->x;
30416 end++;
30417 while (end < glyph
30418 && NILP (end->object))
30420 x += end->pixel_width;
30421 ++end;
30423 /* Scan the rest of the glyph row from the end, looking for the
30424 first glyph that comes from BEFORE_STRING, AFTER_STRING, or
30425 DISP_STRING, or whose position is between START_CHARPOS
30426 and END_CHARPOS */
30427 for ( ;
30428 end < glyph
30429 && !NILP (end->object)
30430 && !EQ (end->object, disp_string)
30431 && !(BUFFERP (end->object)
30432 && (end->charpos >= start_charpos
30433 && end->charpos < end_charpos));
30434 ++end)
30436 /* BEFORE_STRING or AFTER_STRING are only relevant if they
30437 are present at buffer positions between START_CHARPOS and
30438 END_CHARPOS, or if they come from an overlay. */
30439 if (EQ (end->object, before_string))
30441 pos = string_buffer_position (before_string, start_charpos);
30442 if (!pos || (pos >= start_charpos && pos < end_charpos))
30443 break;
30445 else if (EQ (end->object, after_string))
30447 pos = string_buffer_position (after_string, end_charpos);
30448 if (!pos || (pos >= start_charpos && pos < end_charpos))
30449 break;
30451 x += end->pixel_width;
30453 /* If we exited the above loop because we arrived at the last
30454 glyph of the row, and its buffer position is still not in
30455 range, it means the last character in range is the preceding
30456 newline. Bump the end column and x values to get past the
30457 last glyph. */
30458 if (end == glyph
30459 && BUFFERP (end->object)
30460 && (end->charpos < start_charpos
30461 || end->charpos >= end_charpos))
30463 x += end->pixel_width;
30464 ++end;
30466 hlinfo->mouse_face_end_x = x;
30467 hlinfo->mouse_face_end_col = end - r2->glyphs[TEXT_AREA];
30470 hlinfo->mouse_face_window = window;
30471 hlinfo->mouse_face_face_id
30472 = face_at_buffer_position (w, mouse_charpos, &ignore,
30473 mouse_charpos + 1,
30474 !hlinfo->mouse_face_hidden, -1);
30475 show_mouse_face (hlinfo, DRAW_MOUSE_FACE);
30478 /* The following function is not used anymore (replaced with
30479 mouse_face_from_string_pos), but I leave it here for the time
30480 being, in case someone would. */
30482 #if false /* not used */
30484 /* Find the position of the glyph for position POS in OBJECT in
30485 window W's current matrix, and return in *X, *Y the pixel
30486 coordinates, and return in *HPOS, *VPOS the column/row of the glyph.
30488 RIGHT_P means return the position of the right edge of the glyph.
30489 !RIGHT_P means return the left edge position.
30491 If no glyph for POS exists in the matrix, return the position of
30492 the glyph with the next smaller position that is in the matrix, if
30493 RIGHT_P is false. If RIGHT_P, and no glyph for POS
30494 exists in the matrix, return the position of the glyph with the
30495 next larger position in OBJECT.
30497 Value is true if a glyph was found. */
30499 static bool
30500 fast_find_string_pos (struct window *w, ptrdiff_t pos, Lisp_Object object,
30501 int *hpos, int *vpos, int *x, int *y, bool right_p)
30503 int yb = window_text_bottom_y (w);
30504 struct glyph_row *r;
30505 struct glyph *best_glyph = NULL;
30506 struct glyph_row *best_row = NULL;
30507 int best_x = 0;
30509 for (r = MATRIX_FIRST_TEXT_ROW (w->current_matrix);
30510 r->enabled_p && r->y < yb;
30511 ++r)
30513 struct glyph *g = r->glyphs[TEXT_AREA];
30514 struct glyph *e = g + r->used[TEXT_AREA];
30515 int gx;
30517 for (gx = r->x; g < e; gx += g->pixel_width, ++g)
30518 if (EQ (g->object, object))
30520 if (g->charpos == pos)
30522 best_glyph = g;
30523 best_x = gx;
30524 best_row = r;
30525 goto found;
30527 else if (best_glyph == NULL
30528 || ((eabs (g->charpos - pos)
30529 < eabs (best_glyph->charpos - pos))
30530 && (right_p
30531 ? g->charpos < pos
30532 : g->charpos > pos)))
30534 best_glyph = g;
30535 best_x = gx;
30536 best_row = r;
30541 found:
30543 if (best_glyph)
30545 *x = best_x;
30546 *hpos = best_glyph - best_row->glyphs[TEXT_AREA];
30548 if (right_p)
30550 *x += best_glyph->pixel_width;
30551 ++*hpos;
30554 *y = best_row->y;
30555 *vpos = MATRIX_ROW_VPOS (best_row, w->current_matrix);
30558 return best_glyph != NULL;
30560 #endif /* not used */
30562 /* Find the positions of the first and the last glyphs in window W's
30563 current matrix that occlude positions [STARTPOS..ENDPOS) in OBJECT
30564 (assumed to be a string), and return in HLINFO's mouse_face_*
30565 members the pixel and column/row coordinates of those glyphs. */
30567 static void
30568 mouse_face_from_string_pos (struct window *w, Mouse_HLInfo *hlinfo,
30569 Lisp_Object object,
30570 ptrdiff_t startpos, ptrdiff_t endpos)
30572 int yb = window_text_bottom_y (w);
30573 struct glyph_row *r;
30574 struct glyph *g, *e;
30575 int gx;
30576 bool found = false;
30578 /* Find the glyph row with at least one position in the range
30579 [STARTPOS..ENDPOS), and the first glyph in that row whose
30580 position belongs to that range. */
30581 for (r = MATRIX_FIRST_TEXT_ROW (w->current_matrix);
30582 r->enabled_p && r->y < yb;
30583 ++r)
30585 if (!r->reversed_p)
30587 g = r->glyphs[TEXT_AREA];
30588 e = g + r->used[TEXT_AREA];
30589 for (gx = r->x; g < e; gx += g->pixel_width, ++g)
30590 if (EQ (g->object, object)
30591 && startpos <= g->charpos && g->charpos < endpos)
30593 hlinfo->mouse_face_beg_row
30594 = MATRIX_ROW_VPOS (r, w->current_matrix);
30595 hlinfo->mouse_face_beg_col = g - r->glyphs[TEXT_AREA];
30596 hlinfo->mouse_face_beg_x = gx;
30597 found = true;
30598 break;
30601 else
30603 struct glyph *g1;
30605 e = r->glyphs[TEXT_AREA];
30606 g = e + r->used[TEXT_AREA];
30607 for ( ; g > e; --g)
30608 if (EQ ((g-1)->object, object)
30609 && startpos <= (g-1)->charpos && (g-1)->charpos < endpos)
30611 hlinfo->mouse_face_beg_row
30612 = MATRIX_ROW_VPOS (r, w->current_matrix);
30613 hlinfo->mouse_face_beg_col = g - r->glyphs[TEXT_AREA];
30614 for (gx = r->x, g1 = r->glyphs[TEXT_AREA]; g1 < g; ++g1)
30615 gx += g1->pixel_width;
30616 hlinfo->mouse_face_beg_x = gx;
30617 found = true;
30618 break;
30621 if (found)
30622 break;
30625 if (!found)
30626 return;
30628 /* Starting with the next row, look for the first row which does NOT
30629 include any glyphs whose positions are in the range. */
30630 for (++r; r->enabled_p && r->y < yb; ++r)
30632 g = r->glyphs[TEXT_AREA];
30633 e = g + r->used[TEXT_AREA];
30634 found = false;
30635 for ( ; g < e; ++g)
30636 if (EQ (g->object, object)
30637 && startpos <= g->charpos && g->charpos < endpos)
30639 found = true;
30640 break;
30642 if (!found)
30643 break;
30646 /* The highlighted region ends on the previous row. */
30647 r--;
30649 /* Set the end row. */
30650 hlinfo->mouse_face_end_row = MATRIX_ROW_VPOS (r, w->current_matrix);
30652 /* Compute and set the end column and the end column's horizontal
30653 pixel coordinate. */
30654 if (!r->reversed_p)
30656 g = r->glyphs[TEXT_AREA];
30657 e = g + r->used[TEXT_AREA];
30658 for ( ; e > g; --e)
30659 if (EQ ((e-1)->object, object)
30660 && startpos <= (e-1)->charpos && (e-1)->charpos < endpos)
30661 break;
30662 hlinfo->mouse_face_end_col = e - g;
30664 for (gx = r->x; g < e; ++g)
30665 gx += g->pixel_width;
30666 hlinfo->mouse_face_end_x = gx;
30668 else
30670 e = r->glyphs[TEXT_AREA];
30671 g = e + r->used[TEXT_AREA];
30672 for (gx = r->x ; e < g; ++e)
30674 if (EQ (e->object, object)
30675 && startpos <= e->charpos && e->charpos < endpos)
30676 break;
30677 gx += e->pixel_width;
30679 hlinfo->mouse_face_end_col = e - r->glyphs[TEXT_AREA];
30680 hlinfo->mouse_face_end_x = gx;
30684 #ifdef HAVE_WINDOW_SYSTEM
30686 /* See if position X, Y is within a hot-spot of an image. */
30688 static bool
30689 on_hot_spot_p (Lisp_Object hot_spot, int x, int y)
30691 if (!CONSP (hot_spot))
30692 return false;
30694 if (EQ (XCAR (hot_spot), Qrect))
30696 /* CDR is (Top-Left . Bottom-Right) = ((x0 . y0) . (x1 . y1)) */
30697 Lisp_Object rect = XCDR (hot_spot);
30698 Lisp_Object tem;
30699 if (!CONSP (rect))
30700 return false;
30701 if (!CONSP (XCAR (rect)))
30702 return false;
30703 if (!CONSP (XCDR (rect)))
30704 return false;
30705 if (!(tem = XCAR (XCAR (rect)), INTEGERP (tem) && x >= XINT (tem)))
30706 return false;
30707 if (!(tem = XCDR (XCAR (rect)), INTEGERP (tem) && y >= XINT (tem)))
30708 return false;
30709 if (!(tem = XCAR (XCDR (rect)), INTEGERP (tem) && x <= XINT (tem)))
30710 return false;
30711 if (!(tem = XCDR (XCDR (rect)), INTEGERP (tem) && y <= XINT (tem)))
30712 return false;
30713 return true;
30715 else if (EQ (XCAR (hot_spot), Qcircle))
30717 /* CDR is (Center . Radius) = ((x0 . y0) . r) */
30718 Lisp_Object circ = XCDR (hot_spot);
30719 Lisp_Object lr, lx0, ly0;
30720 if (CONSP (circ)
30721 && CONSP (XCAR (circ))
30722 && (lr = XCDR (circ), NUMBERP (lr))
30723 && (lx0 = XCAR (XCAR (circ)), INTEGERP (lx0))
30724 && (ly0 = XCDR (XCAR (circ)), INTEGERP (ly0)))
30726 double r = XFLOATINT (lr);
30727 double dx = XINT (lx0) - x;
30728 double dy = XINT (ly0) - y;
30729 return (dx * dx + dy * dy <= r * r);
30732 else if (EQ (XCAR (hot_spot), Qpoly))
30734 /* CDR is [x0 y0 x1 y1 x2 y2 ...x(n-1) y(n-1)] */
30735 if (VECTORP (XCDR (hot_spot)))
30737 struct Lisp_Vector *v = XVECTOR (XCDR (hot_spot));
30738 Lisp_Object *poly = v->contents;
30739 ptrdiff_t n = v->header.size;
30740 ptrdiff_t i;
30741 bool inside = false;
30742 Lisp_Object lx, ly;
30743 int x0, y0;
30745 /* Need an even number of coordinates, and at least 3 edges. */
30746 if (n < 6 || n & 1)
30747 return false;
30749 /* Count edge segments intersecting line from (X,Y) to (X,infinity).
30750 If count is odd, we are inside polygon. Pixels on edges
30751 may or may not be included depending on actual geometry of the
30752 polygon. */
30753 if ((lx = poly[n-2], !INTEGERP (lx))
30754 || (ly = poly[n-1], !INTEGERP (lx)))
30755 return false;
30756 x0 = XINT (lx), y0 = XINT (ly);
30757 for (i = 0; i < n; i += 2)
30759 int x1 = x0, y1 = y0;
30760 if ((lx = poly[i], !INTEGERP (lx))
30761 || (ly = poly[i+1], !INTEGERP (ly)))
30762 return false;
30763 x0 = XINT (lx), y0 = XINT (ly);
30765 /* Does this segment cross the X line? */
30766 if (x0 >= x)
30768 if (x1 >= x)
30769 continue;
30771 else if (x1 < x)
30772 continue;
30773 if (y > y0 && y > y1)
30774 continue;
30775 if (y < y0 + ((y1 - y0) * (x - x0)) / (x1 - x0))
30776 inside = !inside;
30778 return inside;
30781 return false;
30784 Lisp_Object
30785 find_hot_spot (Lisp_Object map, int x, int y)
30787 while (CONSP (map))
30789 if (CONSP (XCAR (map))
30790 && on_hot_spot_p (XCAR (XCAR (map)), x, y))
30791 return XCAR (map);
30792 map = XCDR (map);
30795 return Qnil;
30798 DEFUN ("lookup-image-map", Flookup_image_map, Slookup_image_map,
30799 3, 3, 0,
30800 doc: /* Lookup in image map MAP coordinates X and Y.
30801 An image map is an alist where each element has the format (AREA ID PLIST).
30802 An AREA is specified as either a rectangle, a circle, or a polygon:
30803 A rectangle is a cons (rect . ((x0 . y0) . (x1 . y1))) specifying the
30804 pixel coordinates of the upper left and bottom right corners.
30805 A circle is a cons (circle . ((x0 . y0) . r)) specifying the center
30806 and the radius of the circle; r may be a float or integer.
30807 A polygon is a cons (poly . [x0 y0 x1 y1 ...]) where each pair in the
30808 vector describes one corner in the polygon.
30809 Returns the alist element for the first matching AREA in MAP. */)
30810 (Lisp_Object map, Lisp_Object x, Lisp_Object y)
30812 if (NILP (map))
30813 return Qnil;
30815 CHECK_NUMBER (x);
30816 CHECK_NUMBER (y);
30818 return find_hot_spot (map,
30819 clip_to_bounds (INT_MIN, XINT (x), INT_MAX),
30820 clip_to_bounds (INT_MIN, XINT (y), INT_MAX));
30822 #endif /* HAVE_WINDOW_SYSTEM */
30825 /* Display frame CURSOR, optionally using shape defined by POINTER. */
30826 static void
30827 define_frame_cursor1 (struct frame *f, Cursor cursor, Lisp_Object pointer)
30829 #ifdef HAVE_WINDOW_SYSTEM
30830 if (!FRAME_WINDOW_P (f))
30831 return;
30833 /* Do not change cursor shape while dragging mouse. */
30834 if (EQ (do_mouse_tracking, Qdragging))
30835 return;
30837 if (!NILP (pointer))
30839 if (EQ (pointer, Qarrow))
30840 cursor = FRAME_X_OUTPUT (f)->nontext_cursor;
30841 else if (EQ (pointer, Qhand))
30842 cursor = FRAME_X_OUTPUT (f)->hand_cursor;
30843 else if (EQ (pointer, Qtext))
30844 cursor = FRAME_X_OUTPUT (f)->text_cursor;
30845 else if (EQ (pointer, intern ("hdrag")))
30846 cursor = FRAME_X_OUTPUT (f)->horizontal_drag_cursor;
30847 else if (EQ (pointer, intern ("nhdrag")))
30848 cursor = FRAME_X_OUTPUT (f)->vertical_drag_cursor;
30849 # ifdef HAVE_X_WINDOWS
30850 else if (EQ (pointer, intern ("vdrag")))
30851 cursor = FRAME_DISPLAY_INFO (f)->vertical_scroll_bar_cursor;
30852 # endif
30853 else if (EQ (pointer, intern ("hourglass")))
30854 cursor = FRAME_X_OUTPUT (f)->hourglass_cursor;
30855 else if (EQ (pointer, Qmodeline))
30856 cursor = FRAME_X_OUTPUT (f)->modeline_cursor;
30857 else
30858 cursor = FRAME_X_OUTPUT (f)->nontext_cursor;
30861 if (cursor != No_Cursor)
30862 FRAME_RIF (f)->define_frame_cursor (f, cursor);
30863 #endif
30866 /* Take proper action when mouse has moved to the mode or header line
30867 or marginal area AREA of window W, x-position X and y-position Y.
30868 X is relative to the start of the text display area of W, so the
30869 width of bitmap areas and scroll bars must be subtracted to get a
30870 position relative to the start of the mode line. */
30872 static void
30873 note_mode_line_or_margin_highlight (Lisp_Object window, int x, int y,
30874 enum window_part area)
30876 struct window *w = XWINDOW (window);
30877 struct frame *f = XFRAME (w->frame);
30878 Mouse_HLInfo *hlinfo = MOUSE_HL_INFO (f);
30879 #ifdef HAVE_WINDOW_SYSTEM
30880 Display_Info *dpyinfo;
30881 #endif
30882 Cursor cursor = No_Cursor;
30883 Lisp_Object pointer = Qnil;
30884 int dx, dy, width, height;
30885 ptrdiff_t charpos;
30886 Lisp_Object string, object = Qnil;
30887 Lisp_Object pos UNINIT;
30888 Lisp_Object mouse_face;
30889 int original_x_pixel = x;
30890 struct glyph * glyph = NULL, * row_start_glyph = NULL;
30891 struct glyph_row *row UNINIT;
30893 if (area == ON_MODE_LINE || area == ON_HEADER_LINE)
30895 int x0;
30896 struct glyph *end;
30898 /* Kludge alert: mode_line_string takes X/Y in pixels, but
30899 returns them in row/column units! */
30900 string = mode_line_string (w, area, &x, &y, &charpos,
30901 &object, &dx, &dy, &width, &height);
30903 row = (area == ON_MODE_LINE
30904 ? MATRIX_MODE_LINE_ROW (w->current_matrix)
30905 : MATRIX_HEADER_LINE_ROW (w->current_matrix));
30907 /* Find the glyph under the mouse pointer. */
30908 if (row->mode_line_p && row->enabled_p)
30910 glyph = row_start_glyph = row->glyphs[TEXT_AREA];
30911 end = glyph + row->used[TEXT_AREA];
30913 for (x0 = original_x_pixel;
30914 glyph < end && x0 >= glyph->pixel_width;
30915 ++glyph)
30916 x0 -= glyph->pixel_width;
30918 if (glyph >= end)
30919 glyph = NULL;
30922 else
30924 x -= WINDOW_LEFT_SCROLL_BAR_AREA_WIDTH (w);
30925 /* Kludge alert: marginal_area_string takes X/Y in pixels, but
30926 returns them in row/column units! */
30927 string = marginal_area_string (w, area, &x, &y, &charpos,
30928 &object, &dx, &dy, &width, &height);
30931 Lisp_Object help = Qnil;
30933 #ifdef HAVE_WINDOW_SYSTEM
30934 if (IMAGEP (object))
30936 Lisp_Object image_map, hotspot;
30937 if ((image_map = Fplist_get (XCDR (object), QCmap),
30938 !NILP (image_map))
30939 && (hotspot = find_hot_spot (image_map, dx, dy),
30940 CONSP (hotspot))
30941 && (hotspot = XCDR (hotspot), CONSP (hotspot)))
30943 Lisp_Object plist;
30945 /* Could check XCAR (hotspot) to see if we enter/leave this hot-spot.
30946 If so, we could look for mouse-enter, mouse-leave
30947 properties in PLIST (and do something...). */
30948 hotspot = XCDR (hotspot);
30949 if (CONSP (hotspot)
30950 && (plist = XCAR (hotspot), CONSP (plist)))
30952 pointer = Fplist_get (plist, Qpointer);
30953 if (NILP (pointer))
30954 pointer = Qhand;
30955 help = Fplist_get (plist, Qhelp_echo);
30956 if (!NILP (help))
30958 help_echo_string = help;
30959 XSETWINDOW (help_echo_window, w);
30960 help_echo_object = w->contents;
30961 help_echo_pos = charpos;
30965 if (NILP (pointer))
30966 pointer = Fplist_get (XCDR (object), QCpointer);
30968 #endif /* HAVE_WINDOW_SYSTEM */
30970 if (STRINGP (string))
30971 pos = make_number (charpos);
30973 /* Set the help text and mouse pointer. If the mouse is on a part
30974 of the mode line without any text (e.g. past the right edge of
30975 the mode line text), use the default help text and pointer. */
30976 if (STRINGP (string) || area == ON_MODE_LINE)
30978 /* Arrange to display the help by setting the global variables
30979 help_echo_string, help_echo_object, and help_echo_pos. */
30980 if (NILP (help))
30982 if (STRINGP (string))
30983 help = Fget_text_property (pos, Qhelp_echo, string);
30985 if (!NILP (help))
30987 help_echo_string = help;
30988 XSETWINDOW (help_echo_window, w);
30989 help_echo_object = string;
30990 help_echo_pos = charpos;
30992 else if (area == ON_MODE_LINE)
30994 Lisp_Object default_help
30995 = buffer_local_value (Qmode_line_default_help_echo,
30996 w->contents);
30998 if (STRINGP (default_help))
31000 help_echo_string = default_help;
31001 XSETWINDOW (help_echo_window, w);
31002 help_echo_object = Qnil;
31003 help_echo_pos = -1;
31008 #ifdef HAVE_WINDOW_SYSTEM
31009 /* Change the mouse pointer according to what is under it. */
31010 if (FRAME_WINDOW_P (f))
31012 bool draggable = (! WINDOW_BOTTOMMOST_P (w)
31013 || minibuf_level
31014 || NILP (Vresize_mini_windows));
31016 dpyinfo = FRAME_DISPLAY_INFO (f);
31017 if (STRINGP (string))
31019 cursor = FRAME_X_OUTPUT (f)->nontext_cursor;
31021 if (NILP (pointer))
31022 pointer = Fget_text_property (pos, Qpointer, string);
31024 /* Change the mouse pointer according to what is under X/Y. */
31025 if (NILP (pointer)
31026 && ((area == ON_MODE_LINE) || (area == ON_HEADER_LINE)))
31028 Lisp_Object map;
31029 map = Fget_text_property (pos, Qlocal_map, string);
31030 if (!KEYMAPP (map))
31031 map = Fget_text_property (pos, Qkeymap, string);
31032 if (!KEYMAPP (map) && draggable)
31033 cursor = dpyinfo->vertical_scroll_bar_cursor;
31036 else if (draggable)
31037 /* Default mode-line pointer. */
31038 cursor = FRAME_DISPLAY_INFO (f)->vertical_scroll_bar_cursor;
31040 #endif
31043 /* Change the mouse face according to what is under X/Y. */
31044 bool mouse_face_shown = false;
31045 if (STRINGP (string))
31047 mouse_face = Fget_text_property (pos, Qmouse_face, string);
31048 if (!NILP (Vmouse_highlight) && !NILP (mouse_face)
31049 && ((area == ON_MODE_LINE) || (area == ON_HEADER_LINE))
31050 && glyph)
31052 Lisp_Object b, e;
31054 struct glyph * tmp_glyph;
31056 int gpos;
31057 int gseq_length;
31058 int total_pixel_width;
31059 ptrdiff_t begpos, endpos, ignore;
31061 int vpos, hpos;
31063 b = Fprevious_single_property_change (make_number (charpos + 1),
31064 Qmouse_face, string, Qnil);
31065 if (NILP (b))
31066 begpos = 0;
31067 else
31068 begpos = XINT (b);
31070 e = Fnext_single_property_change (pos, Qmouse_face, string, Qnil);
31071 if (NILP (e))
31072 endpos = SCHARS (string);
31073 else
31074 endpos = XINT (e);
31076 /* Calculate the glyph position GPOS of GLYPH in the
31077 displayed string, relative to the beginning of the
31078 highlighted part of the string.
31080 Note: GPOS is different from CHARPOS. CHARPOS is the
31081 position of GLYPH in the internal string object. A mode
31082 line string format has structures which are converted to
31083 a flattened string by the Emacs Lisp interpreter. The
31084 internal string is an element of those structures. The
31085 displayed string is the flattened string. */
31086 tmp_glyph = row_start_glyph;
31087 while (tmp_glyph < glyph
31088 && (!(EQ (tmp_glyph->object, glyph->object)
31089 && begpos <= tmp_glyph->charpos
31090 && tmp_glyph->charpos < endpos)))
31091 tmp_glyph++;
31092 gpos = glyph - tmp_glyph;
31094 /* Calculate the length GSEQ_LENGTH of the glyph sequence of
31095 the highlighted part of the displayed string to which
31096 GLYPH belongs. Note: GSEQ_LENGTH is different from
31097 SCHARS (STRING), because the latter returns the length of
31098 the internal string. */
31099 for (tmp_glyph = row->glyphs[TEXT_AREA] + row->used[TEXT_AREA] - 1;
31100 tmp_glyph > glyph
31101 && (!(EQ (tmp_glyph->object, glyph->object)
31102 && begpos <= tmp_glyph->charpos
31103 && tmp_glyph->charpos < endpos));
31104 tmp_glyph--)
31106 gseq_length = gpos + (tmp_glyph - glyph) + 1;
31108 /* Calculate the total pixel width of all the glyphs between
31109 the beginning of the highlighted area and GLYPH. */
31110 total_pixel_width = 0;
31111 for (tmp_glyph = glyph - gpos; tmp_glyph != glyph; tmp_glyph++)
31112 total_pixel_width += tmp_glyph->pixel_width;
31114 /* Pre calculation of re-rendering position. Note: X is in
31115 column units here, after the call to mode_line_string or
31116 marginal_area_string. */
31117 hpos = x - gpos;
31118 vpos = (area == ON_MODE_LINE
31119 ? (w->current_matrix)->nrows - 1
31120 : 0);
31122 /* If GLYPH's position is included in the region that is
31123 already drawn in mouse face, we have nothing to do. */
31124 if ( EQ (window, hlinfo->mouse_face_window)
31125 && (!row->reversed_p
31126 ? (hlinfo->mouse_face_beg_col <= hpos
31127 && hpos < hlinfo->mouse_face_end_col)
31128 /* In R2L rows we swap BEG and END, see below. */
31129 : (hlinfo->mouse_face_end_col <= hpos
31130 && hpos < hlinfo->mouse_face_beg_col))
31131 && hlinfo->mouse_face_beg_row == vpos )
31132 return;
31134 if (clear_mouse_face (hlinfo))
31135 cursor = No_Cursor;
31137 if (!row->reversed_p)
31139 hlinfo->mouse_face_beg_col = hpos;
31140 hlinfo->mouse_face_beg_x = original_x_pixel
31141 - (total_pixel_width + dx);
31142 hlinfo->mouse_face_end_col = hpos + gseq_length;
31143 hlinfo->mouse_face_end_x = 0;
31145 else
31147 /* In R2L rows, show_mouse_face expects BEG and END
31148 coordinates to be swapped. */
31149 hlinfo->mouse_face_end_col = hpos;
31150 hlinfo->mouse_face_end_x = original_x_pixel
31151 - (total_pixel_width + dx);
31152 hlinfo->mouse_face_beg_col = hpos + gseq_length;
31153 hlinfo->mouse_face_beg_x = 0;
31156 hlinfo->mouse_face_beg_row = vpos;
31157 hlinfo->mouse_face_end_row = hlinfo->mouse_face_beg_row;
31158 hlinfo->mouse_face_past_end = false;
31159 hlinfo->mouse_face_window = window;
31161 hlinfo->mouse_face_face_id = face_at_string_position (w, string,
31162 charpos,
31163 0, &ignore,
31164 glyph->face_id,
31165 true);
31166 show_mouse_face (hlinfo, DRAW_MOUSE_FACE);
31167 mouse_face_shown = true;
31169 if (NILP (pointer))
31170 pointer = Qhand;
31174 /* If mouse-face doesn't need to be shown, clear any existing
31175 mouse-face. */
31176 if ((area == ON_MODE_LINE || area == ON_HEADER_LINE) && !mouse_face_shown)
31177 clear_mouse_face (hlinfo);
31179 define_frame_cursor1 (f, cursor, pointer);
31183 /* EXPORT:
31184 Take proper action when the mouse has moved to position X, Y on
31185 frame F with regards to highlighting portions of display that have
31186 mouse-face properties. Also de-highlight portions of display where
31187 the mouse was before, set the mouse pointer shape as appropriate
31188 for the mouse coordinates, and activate help echo (tooltips).
31189 X and Y can be negative or out of range. */
31191 void
31192 note_mouse_highlight (struct frame *f, int x, int y)
31194 Mouse_HLInfo *hlinfo = MOUSE_HL_INFO (f);
31195 enum window_part part = ON_NOTHING;
31196 Lisp_Object window;
31197 struct window *w;
31198 Cursor cursor = No_Cursor;
31199 Lisp_Object pointer = Qnil; /* Takes precedence over cursor! */
31200 struct buffer *b;
31202 /* When a menu is active, don't highlight because this looks odd. */
31203 #if defined (USE_X_TOOLKIT) || defined (USE_GTK) || defined (HAVE_NS) || defined (MSDOS)
31204 if (popup_activated ())
31205 return;
31206 #endif
31208 if (!f->glyphs_initialized_p
31209 || f->pointer_invisible)
31210 return;
31212 hlinfo->mouse_face_mouse_x = x;
31213 hlinfo->mouse_face_mouse_y = y;
31214 hlinfo->mouse_face_mouse_frame = f;
31216 if (hlinfo->mouse_face_defer)
31217 return;
31219 /* Which window is that in? */
31220 window = window_from_coordinates (f, x, y, &part, true);
31222 /* If displaying active text in another window, clear that. */
31223 if (! EQ (window, hlinfo->mouse_face_window)
31224 /* Also clear if we move out of text area in same window. */
31225 || (!NILP (hlinfo->mouse_face_window)
31226 && !NILP (window)
31227 && part != ON_TEXT
31228 && part != ON_MODE_LINE
31229 && part != ON_HEADER_LINE))
31230 clear_mouse_face (hlinfo);
31232 /* Reset help_echo_string. It will get recomputed below. */
31233 help_echo_string = Qnil;
31235 #ifdef HAVE_WINDOW_SYSTEM
31236 /* If the cursor is on the internal border of FRAME and FRAME's
31237 internal border is draggable, provide some visual feedback. */
31238 if (FRAME_INTERNAL_BORDER_WIDTH (f) > 0
31239 && !NILP (get_frame_param (f, Qdrag_internal_border)))
31241 enum internal_border_part part = frame_internal_border_part (f, x, y);
31243 switch (part)
31245 case INTERNAL_BORDER_NONE:
31246 if (cursor != FRAME_X_OUTPUT (f)->nontext_cursor)
31247 /* Reset cursor. */
31248 cursor = FRAME_X_OUTPUT (f)->nontext_cursor;
31249 break;
31250 case INTERNAL_BORDER_LEFT_EDGE:
31251 cursor = FRAME_X_OUTPUT (f)->left_edge_cursor;
31252 break;
31253 case INTERNAL_BORDER_TOP_LEFT_CORNER:
31254 cursor = FRAME_X_OUTPUT (f)->top_left_corner_cursor;
31255 break;
31256 case INTERNAL_BORDER_TOP_EDGE:
31257 cursor = FRAME_X_OUTPUT (f)->top_edge_cursor;
31258 break;
31259 case INTERNAL_BORDER_TOP_RIGHT_CORNER:
31260 cursor = FRAME_X_OUTPUT (f)->top_right_corner_cursor;
31261 break;
31262 case INTERNAL_BORDER_RIGHT_EDGE:
31263 cursor = FRAME_X_OUTPUT (f)->right_edge_cursor;
31264 break;
31265 case INTERNAL_BORDER_BOTTOM_RIGHT_CORNER:
31266 cursor = FRAME_X_OUTPUT (f)->bottom_right_corner_cursor;
31267 break;
31268 case INTERNAL_BORDER_BOTTOM_EDGE:
31269 cursor = FRAME_X_OUTPUT (f)->bottom_edge_cursor;
31270 break;
31271 case INTERNAL_BORDER_BOTTOM_LEFT_CORNER:
31272 cursor = FRAME_X_OUTPUT (f)->bottom_left_corner_cursor;
31273 break;
31274 default:
31275 /* This should not happen. */
31276 if (cursor != FRAME_X_OUTPUT (f)->nontext_cursor)
31277 cursor = FRAME_X_OUTPUT (f)->nontext_cursor;
31280 if (cursor != FRAME_X_OUTPUT (f)->nontext_cursor)
31282 /* Do we really want a help echo here? */
31283 help_echo_string = build_string ("drag-mouse-1: resize frame");
31284 goto set_cursor;
31287 #endif /* HAVE_WINDOW_SYSTEM */
31289 /* Not on a window -> return. */
31290 if (!WINDOWP (window))
31291 return;
31293 /* Convert to window-relative pixel coordinates. */
31294 w = XWINDOW (window);
31295 frame_to_window_pixel_xy (w, &x, &y);
31297 #if defined (HAVE_WINDOW_SYSTEM) && ! defined (USE_GTK) && ! defined (HAVE_NS)
31298 /* Handle tool-bar window differently since it doesn't display a
31299 buffer. */
31300 if (EQ (window, f->tool_bar_window))
31302 note_tool_bar_highlight (f, x, y);
31303 return;
31305 #endif
31307 /* Mouse is on the mode, header line or margin? */
31308 if (part == ON_MODE_LINE || part == ON_HEADER_LINE
31309 || part == ON_LEFT_MARGIN || part == ON_RIGHT_MARGIN)
31311 note_mode_line_or_margin_highlight (window, x, y, part);
31313 #ifdef HAVE_WINDOW_SYSTEM
31314 if (part == ON_LEFT_MARGIN || part == ON_RIGHT_MARGIN)
31316 cursor = FRAME_X_OUTPUT (f)->nontext_cursor;
31317 /* Show non-text cursor (Bug#16647). */
31318 goto set_cursor;
31320 else
31321 #endif
31322 return;
31325 #ifdef HAVE_WINDOW_SYSTEM
31326 if (part == ON_VERTICAL_BORDER)
31328 cursor = FRAME_X_OUTPUT (f)->horizontal_drag_cursor;
31329 help_echo_string = build_string ("drag-mouse-1: resize");
31330 goto set_cursor;
31332 else if (part == ON_RIGHT_DIVIDER)
31334 cursor = FRAME_X_OUTPUT (f)->horizontal_drag_cursor;
31335 help_echo_string = build_string ("drag-mouse-1: resize");
31336 goto set_cursor;
31338 else if (part == ON_BOTTOM_DIVIDER)
31339 if (! WINDOW_BOTTOMMOST_P (w)
31340 || minibuf_level
31341 || NILP (Vresize_mini_windows))
31343 cursor = FRAME_X_OUTPUT (f)->vertical_drag_cursor;
31344 help_echo_string = build_string ("drag-mouse-1: resize");
31345 goto set_cursor;
31347 else
31348 cursor = FRAME_X_OUTPUT (f)->nontext_cursor;
31349 else if (part == ON_LEFT_FRINGE || part == ON_RIGHT_FRINGE
31350 || part == ON_VERTICAL_SCROLL_BAR
31351 || part == ON_HORIZONTAL_SCROLL_BAR)
31352 cursor = FRAME_X_OUTPUT (f)->nontext_cursor;
31353 else
31354 cursor = FRAME_X_OUTPUT (f)->text_cursor;
31355 #endif
31357 /* Are we in a window whose display is up to date?
31358 And verify the buffer's text has not changed. */
31359 b = XBUFFER (w->contents);
31360 if (part == ON_TEXT && w->window_end_valid && !window_outdated (w))
31362 int hpos, vpos, dx, dy, area = LAST_AREA;
31363 ptrdiff_t pos;
31364 struct glyph *glyph;
31365 Lisp_Object object;
31366 Lisp_Object mouse_face = Qnil, position;
31367 Lisp_Object *overlay_vec = NULL;
31368 ptrdiff_t i, noverlays;
31369 struct buffer *obuf;
31370 ptrdiff_t obegv, ozv;
31371 bool same_region;
31373 /* Find the glyph under X/Y. */
31374 glyph = x_y_to_hpos_vpos (w, x, y, &hpos, &vpos, &dx, &dy, &area);
31376 #ifdef HAVE_WINDOW_SYSTEM
31377 /* Look for :pointer property on image. */
31378 if (glyph != NULL && glyph->type == IMAGE_GLYPH)
31380 struct image *img = IMAGE_OPT_FROM_ID (f, glyph->u.img_id);
31381 if (img != NULL && IMAGEP (img->spec))
31383 Lisp_Object image_map, hotspot;
31384 if ((image_map = Fplist_get (XCDR (img->spec), QCmap),
31385 !NILP (image_map))
31386 && (hotspot = find_hot_spot (image_map,
31387 glyph->slice.img.x + dx,
31388 glyph->slice.img.y + dy),
31389 CONSP (hotspot))
31390 && (hotspot = XCDR (hotspot), CONSP (hotspot)))
31392 Lisp_Object plist;
31394 /* Could check XCAR (hotspot) to see if we enter/leave
31395 this hot-spot.
31396 If so, we could look for mouse-enter, mouse-leave
31397 properties in PLIST (and do something...). */
31398 hotspot = XCDR (hotspot);
31399 if (CONSP (hotspot)
31400 && (plist = XCAR (hotspot), CONSP (plist)))
31402 pointer = Fplist_get (plist, Qpointer);
31403 if (NILP (pointer))
31404 pointer = Qhand;
31405 help_echo_string = Fplist_get (plist, Qhelp_echo);
31406 if (!NILP (help_echo_string))
31408 help_echo_window = window;
31409 help_echo_object = glyph->object;
31410 help_echo_pos = glyph->charpos;
31414 if (NILP (pointer))
31415 pointer = Fplist_get (XCDR (img->spec), QCpointer);
31418 #endif /* HAVE_WINDOW_SYSTEM */
31420 /* Clear mouse face if X/Y not over text. */
31421 if (glyph == NULL
31422 || area != TEXT_AREA
31423 || !MATRIX_ROW_DISPLAYS_TEXT_P (MATRIX_ROW (w->current_matrix, vpos))
31424 /* Glyph's OBJECT is nil for glyphs inserted by the
31425 display engine for its internal purposes, like truncation
31426 and continuation glyphs and blanks beyond the end of
31427 line's text on text terminals. If we are over such a
31428 glyph, we are not over any text. */
31429 || NILP (glyph->object)
31430 /* R2L rows have a stretch glyph at their front, which
31431 stands for no text, whereas L2R rows have no glyphs at
31432 all beyond the end of text. Treat such stretch glyphs
31433 like we do with NULL glyphs in L2R rows. */
31434 || (MATRIX_ROW (w->current_matrix, vpos)->reversed_p
31435 && glyph == MATRIX_ROW_GLYPH_START (w->current_matrix, vpos)
31436 && glyph->type == STRETCH_GLYPH
31437 && glyph->avoid_cursor_p))
31439 if (clear_mouse_face (hlinfo))
31440 cursor = No_Cursor;
31441 if (FRAME_WINDOW_P (f) && NILP (pointer))
31443 #ifdef HAVE_WINDOW_SYSTEM
31444 if (area != TEXT_AREA)
31445 cursor = FRAME_X_OUTPUT (f)->nontext_cursor;
31446 else
31447 pointer = Vvoid_text_area_pointer;
31448 #endif
31450 goto set_cursor;
31453 pos = glyph->charpos;
31454 object = glyph->object;
31455 if (!STRINGP (object) && !BUFFERP (object))
31456 goto set_cursor;
31458 /* If we get an out-of-range value, return now; avoid an error. */
31459 if (BUFFERP (object) && pos > BUF_Z (b))
31460 goto set_cursor;
31462 /* Make the window's buffer temporarily current for
31463 overlays_at and compute_char_face. */
31464 obuf = current_buffer;
31465 current_buffer = b;
31466 obegv = BEGV;
31467 ozv = ZV;
31468 BEGV = BEG;
31469 ZV = Z;
31471 /* Is this char mouse-active or does it have help-echo? */
31472 position = make_number (pos);
31474 USE_SAFE_ALLOCA;
31476 if (BUFFERP (object))
31478 /* Put all the overlays we want in a vector in overlay_vec. */
31479 GET_OVERLAYS_AT (pos, overlay_vec, noverlays, NULL, false);
31480 /* Sort overlays into increasing priority order. */
31481 noverlays = sort_overlays (overlay_vec, noverlays, w);
31483 else
31484 noverlays = 0;
31486 if (NILP (Vmouse_highlight))
31488 clear_mouse_face (hlinfo);
31489 goto check_help_echo;
31492 same_region = coords_in_mouse_face_p (w, hpos, vpos);
31494 if (same_region)
31495 cursor = No_Cursor;
31497 /* Check mouse-face highlighting. */
31498 if (! same_region
31499 /* If there exists an overlay with mouse-face overlapping
31500 the one we are currently highlighting, we have to check
31501 if we enter the overlapping overlay, and then highlight
31502 only that. Skip the check when mouse-face highlighting
31503 is currently hidden to avoid Bug#30519. */
31504 || (!hlinfo->mouse_face_hidden
31505 && OVERLAYP (hlinfo->mouse_face_overlay)
31506 && mouse_face_overlay_overlaps (hlinfo->mouse_face_overlay)))
31508 /* Find the highest priority overlay with a mouse-face. */
31509 Lisp_Object overlay = Qnil;
31510 for (i = noverlays - 1; i >= 0 && NILP (overlay); --i)
31512 mouse_face = Foverlay_get (overlay_vec[i], Qmouse_face);
31513 if (!NILP (mouse_face))
31514 overlay = overlay_vec[i];
31517 /* If we're highlighting the same overlay as before, there's
31518 no need to do that again. */
31519 if (!NILP (overlay) && EQ (overlay, hlinfo->mouse_face_overlay))
31520 goto check_help_echo;
31522 /* Clear the display of the old active region, if any. */
31523 if (clear_mouse_face (hlinfo))
31524 cursor = No_Cursor;
31526 /* Record the overlay, if any, to be highlighted. */
31527 hlinfo->mouse_face_overlay = overlay;
31529 /* If no overlay applies, get a text property. */
31530 if (NILP (overlay))
31531 mouse_face = Fget_text_property (position, Qmouse_face, object);
31533 /* Next, compute the bounds of the mouse highlighting and
31534 display it. */
31535 if (!NILP (mouse_face) && STRINGP (object))
31537 /* The mouse-highlighting comes from a display string
31538 with a mouse-face. */
31539 Lisp_Object s, e;
31540 ptrdiff_t ignore;
31542 s = Fprevious_single_property_change
31543 (make_number (pos + 1), Qmouse_face, object, Qnil);
31544 e = Fnext_single_property_change
31545 (position, Qmouse_face, object, Qnil);
31546 if (NILP (s))
31547 s = make_number (0);
31548 if (NILP (e))
31549 e = make_number (SCHARS (object));
31550 mouse_face_from_string_pos (w, hlinfo, object,
31551 XINT (s), XINT (e));
31552 hlinfo->mouse_face_past_end = false;
31553 hlinfo->mouse_face_window = window;
31554 hlinfo->mouse_face_face_id
31555 = face_at_string_position (w, object, pos, 0, &ignore,
31556 glyph->face_id, true);
31557 show_mouse_face (hlinfo, DRAW_MOUSE_FACE);
31558 cursor = No_Cursor;
31560 else
31562 /* The mouse-highlighting, if any, comes from an overlay
31563 or text property in the buffer. */
31564 Lisp_Object buffer UNINIT;
31565 Lisp_Object disp_string UNINIT;
31567 if (STRINGP (object))
31569 /* If we are on a display string with no mouse-face,
31570 check if the text under it has one. */
31571 struct glyph_row *r = MATRIX_ROW (w->current_matrix, vpos);
31572 ptrdiff_t start = MATRIX_ROW_START_CHARPOS (r);
31573 pos = string_buffer_position (object, start);
31574 if (pos > 0)
31576 mouse_face = get_char_property_and_overlay
31577 (make_number (pos), Qmouse_face, w->contents, &overlay);
31578 buffer = w->contents;
31579 disp_string = object;
31582 else
31584 buffer = object;
31585 disp_string = Qnil;
31588 if (!NILP (mouse_face))
31590 Lisp_Object before, after;
31591 Lisp_Object before_string, after_string;
31592 /* To correctly find the limits of mouse highlight
31593 in a bidi-reordered buffer, we must not use the
31594 optimization of limiting the search in
31595 previous-single-property-change and
31596 next-single-property-change, because
31597 rows_from_pos_range needs the real start and end
31598 positions to DTRT in this case. That's because
31599 the first row visible in a window does not
31600 necessarily display the character whose position
31601 is the smallest. */
31602 Lisp_Object lim1
31603 = NILP (BVAR (XBUFFER (buffer), bidi_display_reordering))
31604 ? Fmarker_position (w->start)
31605 : Qnil;
31606 Lisp_Object lim2
31607 = NILP (BVAR (XBUFFER (buffer), bidi_display_reordering))
31608 ? make_number (BUF_Z (XBUFFER (buffer))
31609 - w->window_end_pos)
31610 : Qnil;
31612 if (NILP (overlay))
31614 /* Handle the text property case. */
31615 before = Fprevious_single_property_change
31616 (make_number (pos + 1), Qmouse_face, buffer, lim1);
31617 after = Fnext_single_property_change
31618 (make_number (pos), Qmouse_face, buffer, lim2);
31619 before_string = after_string = Qnil;
31621 else
31623 /* Handle the overlay case. */
31624 before = Foverlay_start (overlay);
31625 after = Foverlay_end (overlay);
31626 before_string = Foverlay_get (overlay, Qbefore_string);
31627 after_string = Foverlay_get (overlay, Qafter_string);
31629 if (!STRINGP (before_string)) before_string = Qnil;
31630 if (!STRINGP (after_string)) after_string = Qnil;
31633 mouse_face_from_buffer_pos (window, hlinfo, pos,
31634 NILP (before)
31636 : XFASTINT (before),
31637 NILP (after)
31638 ? BUF_Z (XBUFFER (buffer))
31639 : XFASTINT (after),
31640 before_string, after_string,
31641 disp_string);
31642 cursor = No_Cursor;
31647 check_help_echo:
31649 /* Look for a `help-echo' property. */
31650 if (NILP (help_echo_string)) {
31651 Lisp_Object help, overlay;
31653 /* Check overlays first. */
31654 help = overlay = Qnil;
31655 for (i = noverlays - 1; i >= 0 && NILP (help); --i)
31657 overlay = overlay_vec[i];
31658 help = Foverlay_get (overlay, Qhelp_echo);
31661 if (!NILP (help))
31663 help_echo_string = help;
31664 help_echo_window = window;
31665 help_echo_object = overlay;
31666 help_echo_pos = pos;
31668 else
31670 Lisp_Object obj = glyph->object;
31671 ptrdiff_t charpos = glyph->charpos;
31673 /* Try text properties. */
31674 if (STRINGP (obj)
31675 && charpos >= 0
31676 && charpos < SCHARS (obj))
31678 help = Fget_text_property (make_number (charpos),
31679 Qhelp_echo, obj);
31680 if (NILP (help))
31682 /* If the string itself doesn't specify a help-echo,
31683 see if the buffer text ``under'' it does. */
31684 struct glyph_row *r
31685 = MATRIX_ROW (w->current_matrix, vpos);
31686 ptrdiff_t start = MATRIX_ROW_START_CHARPOS (r);
31687 ptrdiff_t p = string_buffer_position (obj, start);
31688 if (p > 0)
31690 help = Fget_char_property (make_number (p),
31691 Qhelp_echo, w->contents);
31692 if (!NILP (help))
31694 charpos = p;
31695 obj = w->contents;
31700 else if (BUFFERP (obj)
31701 && charpos >= BEGV
31702 && charpos < ZV)
31703 help = Fget_text_property (make_number (charpos), Qhelp_echo,
31704 obj);
31706 if (!NILP (help))
31708 help_echo_string = help;
31709 help_echo_window = window;
31710 help_echo_object = obj;
31711 help_echo_pos = charpos;
31716 #ifdef HAVE_WINDOW_SYSTEM
31717 /* Look for a `pointer' property. */
31718 if (FRAME_WINDOW_P (f) && NILP (pointer))
31720 /* Check overlays first. */
31721 for (i = noverlays - 1; i >= 0 && NILP (pointer); --i)
31722 pointer = Foverlay_get (overlay_vec[i], Qpointer);
31724 if (NILP (pointer))
31726 Lisp_Object obj = glyph->object;
31727 ptrdiff_t charpos = glyph->charpos;
31729 /* Try text properties. */
31730 if (STRINGP (obj)
31731 && charpos >= 0
31732 && charpos < SCHARS (obj))
31734 pointer = Fget_text_property (make_number (charpos),
31735 Qpointer, obj);
31736 if (NILP (pointer))
31738 /* If the string itself doesn't specify a pointer,
31739 see if the buffer text ``under'' it does. */
31740 struct glyph_row *r
31741 = MATRIX_ROW (w->current_matrix, vpos);
31742 ptrdiff_t start = MATRIX_ROW_START_CHARPOS (r);
31743 ptrdiff_t p = string_buffer_position (obj, start);
31744 if (p > 0)
31745 pointer = Fget_char_property (make_number (p),
31746 Qpointer, w->contents);
31749 else if (BUFFERP (obj)
31750 && charpos >= BEGV
31751 && charpos < ZV)
31752 pointer = Fget_text_property (make_number (charpos),
31753 Qpointer, obj);
31756 #endif /* HAVE_WINDOW_SYSTEM */
31758 BEGV = obegv;
31759 ZV = ozv;
31760 current_buffer = obuf;
31761 SAFE_FREE ();
31764 set_cursor:
31765 define_frame_cursor1 (f, cursor, pointer);
31769 /* EXPORT for RIF:
31770 Clear any mouse-face on window W. This function is part of the
31771 redisplay interface, and is called from try_window_id and similar
31772 functions to ensure the mouse-highlight is off. */
31774 void
31775 x_clear_window_mouse_face (struct window *w)
31777 Mouse_HLInfo *hlinfo = MOUSE_HL_INFO (XFRAME (w->frame));
31778 Lisp_Object window;
31780 block_input ();
31781 XSETWINDOW (window, w);
31782 if (EQ (window, hlinfo->mouse_face_window))
31783 clear_mouse_face (hlinfo);
31784 unblock_input ();
31788 /* EXPORT:
31789 Just discard the mouse face information for frame F, if any.
31790 This is used when the size of F is changed. */
31792 void
31793 cancel_mouse_face (struct frame *f)
31795 Lisp_Object window;
31796 Mouse_HLInfo *hlinfo = MOUSE_HL_INFO (f);
31798 window = hlinfo->mouse_face_window;
31799 if (! NILP (window) && XFRAME (XWINDOW (window)->frame) == f)
31800 reset_mouse_highlight (hlinfo);
31805 /***********************************************************************
31806 Exposure Events
31807 ***********************************************************************/
31809 #ifdef HAVE_WINDOW_SYSTEM
31811 /* Redraw the part of glyph row area AREA of glyph row ROW on window W
31812 which intersects rectangle R. R is in window-relative coordinates. */
31814 static void
31815 expose_area (struct window *w, struct glyph_row *row, XRectangle *r,
31816 enum glyph_row_area area)
31818 struct glyph *first = row->glyphs[area];
31819 struct glyph *end = row->glyphs[area] + row->used[area];
31820 struct glyph *last;
31821 int first_x, start_x, x;
31823 if (area == TEXT_AREA && row->fill_line_p)
31824 /* If row extends face to end of line write the whole line. */
31825 draw_glyphs (w, 0, row, area,
31826 0, row->used[area],
31827 DRAW_NORMAL_TEXT, 0);
31828 else
31830 /* Set START_X to the window-relative start position for drawing glyphs of
31831 AREA. The first glyph of the text area can be partially visible.
31832 The first glyphs of other areas cannot. */
31833 start_x = window_box_left_offset (w, area);
31834 x = start_x;
31835 if (area == TEXT_AREA)
31836 x += row->x;
31838 /* Find the first glyph that must be redrawn. */
31839 while (first < end
31840 && x + first->pixel_width < r->x)
31842 x += first->pixel_width;
31843 ++first;
31846 /* Find the last one. */
31847 last = first;
31848 first_x = x;
31849 /* Use a signed int intermediate value to avoid catastrophic
31850 failures due to comparison between signed and unsigned, when
31851 x is negative (can happen for wide images that are hscrolled). */
31852 int r_end = r->x + r->width;
31853 while (last < end && x < r_end)
31855 x += last->pixel_width;
31856 ++last;
31859 /* Repaint. */
31860 if (last > first)
31861 draw_glyphs (w, first_x - start_x, row, area,
31862 first - row->glyphs[area], last - row->glyphs[area],
31863 DRAW_NORMAL_TEXT, 0);
31868 /* Redraw the parts of the glyph row ROW on window W intersecting
31869 rectangle R. R is in window-relative coordinates. Value is
31870 true if mouse-face was overwritten. */
31872 static bool
31873 expose_line (struct window *w, struct glyph_row *row, XRectangle *r)
31875 eassert (row->enabled_p);
31877 if (row->mode_line_p || w->pseudo_window_p)
31878 draw_glyphs (w, 0, row, TEXT_AREA,
31879 0, row->used[TEXT_AREA],
31880 DRAW_NORMAL_TEXT, 0);
31881 else
31883 if (row->used[LEFT_MARGIN_AREA])
31884 expose_area (w, row, r, LEFT_MARGIN_AREA);
31885 if (row->used[TEXT_AREA])
31886 expose_area (w, row, r, TEXT_AREA);
31887 if (row->used[RIGHT_MARGIN_AREA])
31888 expose_area (w, row, r, RIGHT_MARGIN_AREA);
31889 draw_row_fringe_bitmaps (w, row);
31892 return row->mouse_face_p;
31896 /* Redraw those parts of glyphs rows during expose event handling that
31897 overlap other rows. Redrawing of an exposed line writes over parts
31898 of lines overlapping that exposed line; this function fixes that.
31900 W is the window being exposed. FIRST_OVERLAPPING_ROW is the first
31901 row in W's current matrix that is exposed and overlaps other rows.
31902 LAST_OVERLAPPING_ROW is the last such row. */
31904 static void
31905 expose_overlaps (struct window *w,
31906 struct glyph_row *first_overlapping_row,
31907 struct glyph_row *last_overlapping_row,
31908 XRectangle *r)
31910 struct glyph_row *row;
31912 for (row = first_overlapping_row; row <= last_overlapping_row; ++row)
31913 if (row->overlapping_p)
31915 eassert (row->enabled_p && !row->mode_line_p);
31917 row->clip = r;
31918 if (row->used[LEFT_MARGIN_AREA])
31919 x_fix_overlapping_area (w, row, LEFT_MARGIN_AREA, OVERLAPS_BOTH);
31921 if (row->used[TEXT_AREA])
31922 x_fix_overlapping_area (w, row, TEXT_AREA, OVERLAPS_BOTH);
31924 if (row->used[RIGHT_MARGIN_AREA])
31925 x_fix_overlapping_area (w, row, RIGHT_MARGIN_AREA, OVERLAPS_BOTH);
31926 row->clip = NULL;
31931 /* Return true if W's cursor intersects rectangle R. */
31933 static bool
31934 phys_cursor_in_rect_p (struct window *w, XRectangle *r)
31936 XRectangle cr, result;
31937 struct glyph *cursor_glyph;
31938 struct glyph_row *row;
31940 if (w->phys_cursor.vpos >= 0
31941 && w->phys_cursor.vpos < w->current_matrix->nrows
31942 && (row = MATRIX_ROW (w->current_matrix, w->phys_cursor.vpos),
31943 row->enabled_p)
31944 && row->cursor_in_fringe_p)
31946 /* Cursor is in the fringe. */
31947 cr.x = window_box_right_offset (w,
31948 (WINDOW_HAS_FRINGES_OUTSIDE_MARGINS (w)
31949 ? RIGHT_MARGIN_AREA
31950 : TEXT_AREA));
31951 cr.y = row->y;
31952 cr.width = WINDOW_RIGHT_FRINGE_WIDTH (w);
31953 cr.height = row->height;
31954 return x_intersect_rectangles (&cr, r, &result);
31957 cursor_glyph = get_phys_cursor_glyph (w);
31958 if (cursor_glyph)
31960 /* r is relative to W's box, but w->phys_cursor.x is relative
31961 to left edge of W's TEXT area. Adjust it. */
31962 cr.x = window_box_left_offset (w, TEXT_AREA) + w->phys_cursor.x;
31963 cr.y = w->phys_cursor.y;
31964 cr.width = cursor_glyph->pixel_width;
31965 cr.height = w->phys_cursor_height;
31966 /* ++KFS: W32 version used W32-specific IntersectRect here, but
31967 I assume the effect is the same -- and this is portable. */
31968 return x_intersect_rectangles (&cr, r, &result);
31970 /* If we don't understand the format, pretend we're not in the hot-spot. */
31971 return false;
31975 /* EXPORT:
31976 Draw a vertical window border to the right of window W if W doesn't
31977 have vertical scroll bars. */
31979 void
31980 x_draw_vertical_border (struct window *w)
31982 struct frame *f = XFRAME (WINDOW_FRAME (w));
31984 /* We could do better, if we knew what type of scroll-bar the adjacent
31985 windows (on either side) have... But we don't :-(
31986 However, I think this works ok. ++KFS 2003-04-25 */
31988 /* Redraw borders between horizontally adjacent windows. Don't
31989 do it for frames with vertical scroll bars because either the
31990 right scroll bar of a window, or the left scroll bar of its
31991 neighbor will suffice as a border. */
31992 if (FRAME_HAS_VERTICAL_SCROLL_BARS (f) || FRAME_RIGHT_DIVIDER_WIDTH (f))
31993 return;
31995 /* Note: It is necessary to redraw both the left and the right
31996 borders, for when only this single window W is being
31997 redisplayed. */
31998 if (!WINDOW_RIGHTMOST_P (w)
31999 && !WINDOW_HAS_VERTICAL_SCROLL_BAR_ON_RIGHT (w))
32001 int x0, x1, y0, y1;
32003 window_box_edges (w, &x0, &y0, &x1, &y1);
32004 y1 -= 1;
32006 if (WINDOW_LEFT_FRINGE_WIDTH (w) == 0)
32007 x1 -= 1;
32009 FRAME_RIF (f)->draw_vertical_window_border (w, x1, y0, y1);
32012 if (!WINDOW_LEFTMOST_P (w)
32013 && !WINDOW_HAS_VERTICAL_SCROLL_BAR_ON_LEFT (w))
32015 int x0, x1, y0, y1;
32017 window_box_edges (w, &x0, &y0, &x1, &y1);
32018 y1 -= 1;
32020 if (WINDOW_LEFT_FRINGE_WIDTH (w) == 0)
32021 x0 -= 1;
32023 FRAME_RIF (f)->draw_vertical_window_border (w, x0, y0, y1);
32028 /* Draw window dividers for window W. */
32030 void
32031 x_draw_right_divider (struct window *w)
32033 struct frame *f = WINDOW_XFRAME (w);
32035 if (w->mini || w->pseudo_window_p)
32036 return;
32037 else if (WINDOW_RIGHT_DIVIDER_WIDTH (w))
32039 int x0 = WINDOW_RIGHT_EDGE_X (w) - WINDOW_RIGHT_DIVIDER_WIDTH (w);
32040 int x1 = WINDOW_RIGHT_EDGE_X (w);
32041 int y0 = WINDOW_TOP_EDGE_Y (w);
32042 int y1 = WINDOW_BOTTOM_EDGE_Y (w);
32044 /* If W is horizontally combined and has a right sibling, don't
32045 draw over any bottom divider. */
32046 if (WINDOW_BOTTOM_DIVIDER_WIDTH (w)
32047 && !NILP (w->parent)
32048 && WINDOW_HORIZONTAL_COMBINATION_P (XWINDOW (w->parent))
32049 && !NILP (w->next))
32050 y1 -= WINDOW_BOTTOM_DIVIDER_WIDTH (w);
32052 FRAME_RIF (f)->draw_window_divider (w, x0, x1, y0, y1);
32056 static void
32057 x_draw_bottom_divider (struct window *w)
32059 struct frame *f = XFRAME (WINDOW_FRAME (w));
32061 if (w->mini || w->pseudo_window_p)
32062 return;
32063 else if (WINDOW_BOTTOM_DIVIDER_WIDTH (w))
32065 int x0 = WINDOW_LEFT_EDGE_X (w);
32066 int x1 = WINDOW_RIGHT_EDGE_X (w);
32067 int y0 = WINDOW_BOTTOM_EDGE_Y (w) - WINDOW_BOTTOM_DIVIDER_WIDTH (w);
32068 int y1 = WINDOW_BOTTOM_EDGE_Y (w);
32069 struct window *p = !NILP (w->parent) ? XWINDOW (w->parent) : false;
32071 /* If W is vertically combined and has a sibling below, don't draw
32072 over any right divider. */
32073 if (WINDOW_RIGHT_DIVIDER_WIDTH (w)
32074 && p
32075 && ((WINDOW_VERTICAL_COMBINATION_P (p)
32076 && !NILP (w->next))
32077 || (WINDOW_HORIZONTAL_COMBINATION_P (p)
32078 && NILP (w->next)
32079 && !NILP (p->parent)
32080 && WINDOW_VERTICAL_COMBINATION_P (XWINDOW (p->parent))
32081 && !NILP (XWINDOW (p->parent)->next))))
32082 x1 -= WINDOW_RIGHT_DIVIDER_WIDTH (w);
32084 FRAME_RIF (f)->draw_window_divider (w, x0, x1, y0, y1);
32088 /* Redraw the part of window W intersection rectangle FR. Pixel
32089 coordinates in FR are frame-relative. Call this function with
32090 input blocked. Value is true if the exposure overwrites
32091 mouse-face. */
32093 static bool
32094 expose_window (struct window *w, XRectangle *fr)
32096 struct frame *f = XFRAME (w->frame);
32097 XRectangle wr, r;
32098 bool mouse_face_overwritten_p = false;
32100 /* If window is not yet fully initialized, do nothing. This can
32101 happen when toolkit scroll bars are used and a window is split.
32102 Reconfiguring the scroll bar will generate an expose for a newly
32103 created window. */
32104 if (w->current_matrix == NULL)
32105 return false;
32107 /* When we're currently updating the window, display and current
32108 matrix usually don't agree. Arrange for a thorough display
32109 later. */
32110 if (w->must_be_updated_p)
32112 SET_FRAME_GARBAGED (f);
32113 return false;
32116 /* Frame-relative pixel rectangle of W. */
32117 wr.x = WINDOW_LEFT_EDGE_X (w);
32118 wr.y = WINDOW_TOP_EDGE_Y (w);
32119 wr.width = WINDOW_PIXEL_WIDTH (w);
32120 wr.height = WINDOW_PIXEL_HEIGHT (w);
32122 if (x_intersect_rectangles (fr, &wr, &r))
32124 int yb = window_text_bottom_y (w);
32125 struct glyph_row *row;
32126 struct glyph_row *first_overlapping_row, *last_overlapping_row;
32128 TRACE ((stderr, "expose_window (%d, %d, %d, %d)\n",
32129 r.x, r.y, r.width, r.height));
32131 /* Convert to window coordinates. */
32132 r.x -= WINDOW_LEFT_EDGE_X (w);
32133 r.y -= WINDOW_TOP_EDGE_Y (w);
32135 /* Turn off the cursor. */
32136 bool cursor_cleared_p = (!w->pseudo_window_p
32137 && phys_cursor_in_rect_p (w, &r));
32138 if (cursor_cleared_p)
32139 x_clear_cursor (w);
32141 /* If the row containing the cursor extends face to end of line,
32142 then expose_area might overwrite the cursor outside the
32143 rectangle and thus notice_overwritten_cursor might clear
32144 w->phys_cursor_on_p. We remember the original value and
32145 check later if it is changed. */
32146 bool phys_cursor_on_p = w->phys_cursor_on_p;
32148 /* Use a signed int intermediate value to avoid catastrophic
32149 failures due to comparison between signed and unsigned, when
32150 y0 or y1 is negative (can happen for tall images). */
32151 int r_bottom = r.y + r.height;
32153 /* Update lines intersecting rectangle R. */
32154 first_overlapping_row = last_overlapping_row = NULL;
32155 for (row = w->current_matrix->rows;
32156 row->enabled_p;
32157 ++row)
32159 int y0 = row->y;
32160 int y1 = MATRIX_ROW_BOTTOM_Y (row);
32162 if ((y0 >= r.y && y0 < r_bottom)
32163 || (y1 > r.y && y1 < r_bottom)
32164 || (r.y >= y0 && r.y < y1)
32165 || (r_bottom > y0 && r_bottom < y1))
32167 /* A header line may be overlapping, but there is no need
32168 to fix overlapping areas for them. KFS 2005-02-12 */
32169 if (row->overlapping_p && !row->mode_line_p)
32171 if (first_overlapping_row == NULL)
32172 first_overlapping_row = row;
32173 last_overlapping_row = row;
32176 row->clip = fr;
32177 if (expose_line (w, row, &r))
32178 mouse_face_overwritten_p = true;
32179 row->clip = NULL;
32181 else if (row->overlapping_p)
32183 /* We must redraw a row overlapping the exposed area. */
32184 if (y0 < r.y
32185 ? y0 + row->phys_height > r.y
32186 : y0 + row->ascent - row->phys_ascent < r.y +r.height)
32188 if (first_overlapping_row == NULL)
32189 first_overlapping_row = row;
32190 last_overlapping_row = row;
32194 if (y1 >= yb)
32195 break;
32198 /* Display the mode line if there is one. */
32199 if (window_wants_mode_line (w)
32200 && (row = MATRIX_MODE_LINE_ROW (w->current_matrix),
32201 row->enabled_p)
32202 && row->y < r_bottom)
32204 if (expose_line (w, row, &r))
32205 mouse_face_overwritten_p = true;
32208 if (!w->pseudo_window_p)
32210 /* Fix the display of overlapping rows. */
32211 if (first_overlapping_row)
32212 expose_overlaps (w, first_overlapping_row, last_overlapping_row,
32213 fr);
32215 /* Draw border between windows. */
32216 if (WINDOW_RIGHT_DIVIDER_WIDTH (w))
32217 x_draw_right_divider (w);
32218 else
32219 x_draw_vertical_border (w);
32221 if (WINDOW_BOTTOM_DIVIDER_WIDTH (w))
32222 x_draw_bottom_divider (w);
32224 /* Turn the cursor on again. */
32225 if (cursor_cleared_p
32226 || (phys_cursor_on_p && !w->phys_cursor_on_p))
32227 update_window_cursor (w, true);
32231 return mouse_face_overwritten_p;
32236 /* Redraw (parts) of all windows in the window tree rooted at W that
32237 intersect R. R contains frame pixel coordinates. Value is
32238 true if the exposure overwrites mouse-face. */
32240 static bool
32241 expose_window_tree (struct window *w, XRectangle *r)
32243 struct frame *f = XFRAME (w->frame);
32244 bool mouse_face_overwritten_p = false;
32246 while (w && !FRAME_GARBAGED_P (f))
32248 mouse_face_overwritten_p
32249 |= (WINDOWP (w->contents)
32250 ? expose_window_tree (XWINDOW (w->contents), r)
32251 : expose_window (w, r));
32253 w = NILP (w->next) ? NULL : XWINDOW (w->next);
32256 return mouse_face_overwritten_p;
32260 /* EXPORT:
32261 Redisplay an exposed area of frame F. X and Y are the upper-left
32262 corner of the exposed rectangle. W and H are width and height of
32263 the exposed area. All are pixel values. W or H zero means redraw
32264 the entire frame. */
32266 void
32267 expose_frame (struct frame *f, int x, int y, int w, int h)
32269 XRectangle r;
32270 bool mouse_face_overwritten_p = false;
32272 TRACE ((stderr, "expose_frame "));
32274 /* No need to redraw if frame will be redrawn soon. */
32275 if (FRAME_GARBAGED_P (f))
32277 TRACE ((stderr, " garbaged\n"));
32278 return;
32281 /* If basic faces haven't been realized yet, there is no point in
32282 trying to redraw anything. This can happen when we get an expose
32283 event while Emacs is starting, e.g. by moving another window. */
32284 if (FRAME_FACE_CACHE (f) == NULL
32285 || FRAME_FACE_CACHE (f)->used < BASIC_FACE_ID_SENTINEL)
32287 TRACE ((stderr, " no faces\n"));
32288 return;
32291 if (w == 0 || h == 0)
32293 r.x = r.y = 0;
32294 r.width = FRAME_TEXT_WIDTH (f);
32295 r.height = FRAME_TEXT_HEIGHT (f);
32297 else
32299 r.x = x;
32300 r.y = y;
32301 r.width = w;
32302 r.height = h;
32305 TRACE ((stderr, "(%d, %d, %d, %d)\n", r.x, r.y, r.width, r.height));
32306 mouse_face_overwritten_p = expose_window_tree (XWINDOW (f->root_window), &r);
32308 #if ! defined (USE_GTK) && ! defined (HAVE_NS)
32309 if (WINDOWP (f->tool_bar_window))
32310 mouse_face_overwritten_p
32311 |= expose_window (XWINDOW (f->tool_bar_window), &r);
32312 #endif
32314 #ifdef HAVE_X_WINDOWS
32315 #ifndef MSDOS
32316 #if ! defined (USE_X_TOOLKIT) && ! defined (USE_GTK)
32317 if (WINDOWP (f->menu_bar_window))
32318 mouse_face_overwritten_p
32319 |= expose_window (XWINDOW (f->menu_bar_window), &r);
32320 #endif /* not USE_X_TOOLKIT and not USE_GTK */
32321 #endif
32322 #endif
32324 /* Some window managers support a focus-follows-mouse style with
32325 delayed raising of frames. Imagine a partially obscured frame,
32326 and moving the mouse into partially obscured mouse-face on that
32327 frame. The visible part of the mouse-face will be highlighted,
32328 then the WM raises the obscured frame. With at least one WM, KDE
32329 2.1, Emacs is not getting any event for the raising of the frame
32330 (even tried with SubstructureRedirectMask), only Expose events.
32331 These expose events will draw text normally, i.e. not
32332 highlighted. Which means we must redo the highlight here.
32333 Subsume it under ``we love X''. --gerd 2001-08-15 */
32334 /* Included in Windows version because Windows most likely does not
32335 do the right thing if any third party tool offers
32336 focus-follows-mouse with delayed raise. --jason 2001-10-12 */
32337 if (mouse_face_overwritten_p && !FRAME_GARBAGED_P (f))
32339 Mouse_HLInfo *hlinfo = MOUSE_HL_INFO (f);
32340 if (f == hlinfo->mouse_face_mouse_frame)
32342 int mouse_x = hlinfo->mouse_face_mouse_x;
32343 int mouse_y = hlinfo->mouse_face_mouse_y;
32344 clear_mouse_face (hlinfo);
32345 note_mouse_highlight (f, mouse_x, mouse_y);
32351 /* EXPORT:
32352 Determine the intersection of two rectangles R1 and R2. Return
32353 the intersection in *RESULT. Value is true if RESULT is not
32354 empty. */
32356 bool
32357 x_intersect_rectangles (XRectangle *r1, XRectangle *r2, XRectangle *result)
32359 XRectangle *left, *right;
32360 XRectangle *upper, *lower;
32361 bool intersection_p = false;
32363 /* Rearrange so that R1 is the left-most rectangle. */
32364 if (r1->x < r2->x)
32365 left = r1, right = r2;
32366 else
32367 left = r2, right = r1;
32369 /* X0 of the intersection is right.x0, if this is inside R1,
32370 otherwise there is no intersection. */
32371 if (right->x <= left->x + left->width)
32373 result->x = right->x;
32375 /* The right end of the intersection is the minimum of
32376 the right ends of left and right. */
32377 result->width = (min (left->x + left->width, right->x + right->width)
32378 - result->x);
32380 /* Same game for Y. */
32381 if (r1->y < r2->y)
32382 upper = r1, lower = r2;
32383 else
32384 upper = r2, lower = r1;
32386 /* The upper end of the intersection is lower.y0, if this is inside
32387 of upper. Otherwise, there is no intersection. */
32388 if (lower->y <= upper->y + upper->height)
32390 result->y = lower->y;
32392 /* The lower end of the intersection is the minimum of the lower
32393 ends of upper and lower. */
32394 result->height = (min (lower->y + lower->height,
32395 upper->y + upper->height)
32396 - result->y);
32397 intersection_p = true;
32401 return intersection_p;
32404 #endif /* HAVE_WINDOW_SYSTEM */
32407 /***********************************************************************
32408 Initialization
32409 ***********************************************************************/
32411 void
32412 syms_of_xdisp (void)
32414 Vwith_echo_area_save_vector = Qnil;
32415 staticpro (&Vwith_echo_area_save_vector);
32417 Vmessage_stack = Qnil;
32418 staticpro (&Vmessage_stack);
32420 /* Non-nil means don't actually do any redisplay. */
32421 DEFSYM (Qinhibit_redisplay, "inhibit-redisplay");
32423 DEFSYM (Qredisplay_internal_xC_functionx, "redisplay_internal (C function)");
32425 DEFVAR_BOOL("inhibit-message", inhibit_message,
32426 doc: /* Non-nil means calls to `message' are not displayed.
32427 They are still logged to the *Messages* buffer.
32429 Do NOT set this globally to a non-nil value, as doing that will
32430 disable messages everywhere, including in I-search and other
32431 places where they are necessary. This variable is intended to
32432 be let-bound around code that needs to disable messages temporarily. */);
32433 inhibit_message = 0;
32435 message_dolog_marker1 = Fmake_marker ();
32436 staticpro (&message_dolog_marker1);
32437 message_dolog_marker2 = Fmake_marker ();
32438 staticpro (&message_dolog_marker2);
32439 message_dolog_marker3 = Fmake_marker ();
32440 staticpro (&message_dolog_marker3);
32442 defsubr (&Sset_buffer_redisplay);
32443 #ifdef GLYPH_DEBUG
32444 defsubr (&Sdump_frame_glyph_matrix);
32445 defsubr (&Sdump_glyph_matrix);
32446 defsubr (&Sdump_glyph_row);
32447 defsubr (&Sdump_tool_bar_row);
32448 defsubr (&Strace_redisplay);
32449 defsubr (&Strace_to_stderr);
32450 #endif
32451 #ifdef HAVE_WINDOW_SYSTEM
32452 defsubr (&Stool_bar_height);
32453 defsubr (&Slookup_image_map);
32454 #endif
32455 defsubr (&Sline_pixel_height);
32456 defsubr (&Sformat_mode_line);
32457 defsubr (&Sinvisible_p);
32458 defsubr (&Scurrent_bidi_paragraph_direction);
32459 defsubr (&Swindow_text_pixel_size);
32460 defsubr (&Smove_point_visually);
32461 defsubr (&Sbidi_find_overridden_directionality);
32463 DEFSYM (Qmenu_bar_update_hook, "menu-bar-update-hook");
32464 DEFSYM (Qoverriding_terminal_local_map, "overriding-terminal-local-map");
32465 DEFSYM (Qoverriding_local_map, "overriding-local-map");
32466 DEFSYM (Qwindow_scroll_functions, "window-scroll-functions");
32467 DEFSYM (Qredisplay_end_trigger_functions, "redisplay-end-trigger-functions");
32468 DEFSYM (Qinhibit_point_motion_hooks, "inhibit-point-motion-hooks");
32469 DEFSYM (Qeval, "eval");
32470 DEFSYM (QCdata, ":data");
32472 /* Names of text properties relevant for redisplay. */
32473 DEFSYM (Qdisplay, "display");
32474 DEFSYM (Qspace_width, "space-width");
32475 DEFSYM (Qraise, "raise");
32476 DEFSYM (Qslice, "slice");
32477 DEFSYM (Qspace, "space");
32478 DEFSYM (Qmargin, "margin");
32479 DEFSYM (Qpointer, "pointer");
32480 DEFSYM (Qleft_margin, "left-margin");
32481 DEFSYM (Qright_margin, "right-margin");
32482 DEFSYM (Qcenter, "center");
32483 DEFSYM (Qline_height, "line-height");
32484 DEFSYM (QCalign_to, ":align-to");
32485 DEFSYM (QCrelative_width, ":relative-width");
32486 DEFSYM (QCrelative_height, ":relative-height");
32487 DEFSYM (QCeval, ":eval");
32488 DEFSYM (QCpropertize, ":propertize");
32489 DEFSYM (QCfile, ":file");
32490 DEFSYM (Qfontified, "fontified");
32491 DEFSYM (Qfontification_functions, "fontification-functions");
32493 /* Name of the symbol which disables Lisp evaluation in 'display'
32494 properties. This is used by enriched.el. */
32495 DEFSYM (Qdisable_eval, "disable-eval");
32497 /* Name of the face used to highlight trailing whitespace. */
32498 DEFSYM (Qtrailing_whitespace, "trailing-whitespace");
32500 /* Names of the faces used to display line numbers. */
32501 DEFSYM (Qline_number, "line-number");
32502 DEFSYM (Qline_number_current_line, "line-number-current-line");
32503 /* Name of a text property which disables line-number display. */
32504 DEFSYM (Qdisplay_line_numbers_disable, "display-line-numbers-disable");
32506 /* Name and number of the face used to highlight escape glyphs. */
32507 DEFSYM (Qescape_glyph, "escape-glyph");
32509 /* Name and number of the face used to highlight non-breaking
32510 spaces/hyphens. */
32511 DEFSYM (Qnobreak_space, "nobreak-space");
32512 DEFSYM (Qnobreak_hyphen, "nobreak-hyphen");
32514 /* The symbol 'image' which is the car of the lists used to represent
32515 images in Lisp. Also a tool bar style. */
32516 DEFSYM (Qimage, "image");
32518 /* Tool bar styles. */
32519 DEFSYM (Qtext, "text");
32520 DEFSYM (Qboth, "both");
32521 DEFSYM (Qboth_horiz, "both-horiz");
32522 DEFSYM (Qtext_image_horiz, "text-image-horiz");
32524 /* The image map types. */
32525 DEFSYM (QCmap, ":map");
32526 DEFSYM (QCpointer, ":pointer");
32527 DEFSYM (Qrect, "rect");
32528 DEFSYM (Qcircle, "circle");
32529 DEFSYM (Qpoly, "poly");
32531 DEFSYM (Qinhibit_menubar_update, "inhibit-menubar-update");
32533 DEFSYM (Qgrow_only, "grow-only");
32534 DEFSYM (Qinhibit_eval_during_redisplay, "inhibit-eval-during-redisplay");
32535 DEFSYM (Qposition, "position");
32536 DEFSYM (Qbuffer_position, "buffer-position");
32537 DEFSYM (Qobject, "object");
32539 /* Cursor shapes. */
32540 DEFSYM (Qbar, "bar");
32541 DEFSYM (Qhbar, "hbar");
32542 DEFSYM (Qbox, "box");
32543 DEFSYM (Qhollow, "hollow");
32545 /* Pointer shapes. */
32546 DEFSYM (Qhand, "hand");
32547 DEFSYM (Qarrow, "arrow");
32548 /* also Qtext */
32550 DEFSYM (Qdragging, "dragging");
32552 DEFSYM (Qinhibit_free_realized_faces, "inhibit-free-realized-faces");
32554 list_of_error = list1 (list2 (Qerror, Qvoid_variable));
32555 staticpro (&list_of_error);
32557 /* Values of those variables at last redisplay are stored as
32558 properties on 'overlay-arrow-position' symbol. However, if
32559 Voverlay_arrow_position is a marker, last-arrow-position is its
32560 numerical position. */
32561 DEFSYM (Qlast_arrow_position, "last-arrow-position");
32562 DEFSYM (Qlast_arrow_string, "last-arrow-string");
32564 /* Alternative overlay-arrow-string and overlay-arrow-bitmap
32565 properties on a symbol in overlay-arrow-variable-list. */
32566 DEFSYM (Qoverlay_arrow_string, "overlay-arrow-string");
32567 DEFSYM (Qoverlay_arrow_bitmap, "overlay-arrow-bitmap");
32569 echo_buffer[0] = echo_buffer[1] = Qnil;
32570 staticpro (&echo_buffer[0]);
32571 staticpro (&echo_buffer[1]);
32573 echo_area_buffer[0] = echo_area_buffer[1] = Qnil;
32574 staticpro (&echo_area_buffer[0]);
32575 staticpro (&echo_area_buffer[1]);
32577 Vmessages_buffer_name = build_pure_c_string ("*Messages*");
32578 staticpro (&Vmessages_buffer_name);
32580 mode_line_proptrans_alist = Qnil;
32581 staticpro (&mode_line_proptrans_alist);
32582 mode_line_string_list = Qnil;
32583 staticpro (&mode_line_string_list);
32584 mode_line_string_face = Qnil;
32585 staticpro (&mode_line_string_face);
32586 mode_line_string_face_prop = Qnil;
32587 staticpro (&mode_line_string_face_prop);
32588 Vmode_line_unwind_vector = Qnil;
32589 staticpro (&Vmode_line_unwind_vector);
32591 DEFSYM (Qmode_line_default_help_echo, "mode-line-default-help-echo");
32593 help_echo_string = Qnil;
32594 staticpro (&help_echo_string);
32595 help_echo_object = Qnil;
32596 staticpro (&help_echo_object);
32597 help_echo_window = Qnil;
32598 staticpro (&help_echo_window);
32599 previous_help_echo_string = Qnil;
32600 staticpro (&previous_help_echo_string);
32601 help_echo_pos = -1;
32603 DEFSYM (Qright_to_left, "right-to-left");
32604 DEFSYM (Qleft_to_right, "left-to-right");
32605 defsubr (&Sbidi_resolved_levels);
32607 #ifdef HAVE_WINDOW_SYSTEM
32608 DEFVAR_BOOL ("x-stretch-cursor", x_stretch_cursor_p,
32609 doc: /* Non-nil means draw block cursor as wide as the glyph under it.
32610 For example, if a block cursor is over a tab, it will be drawn as
32611 wide as that tab on the display. */);
32612 x_stretch_cursor_p = 0;
32613 #endif
32615 DEFVAR_LISP ("show-trailing-whitespace", Vshow_trailing_whitespace,
32616 doc: /* Non-nil means highlight trailing whitespace.
32617 The face used for trailing whitespace is `trailing-whitespace'. */);
32618 Vshow_trailing_whitespace = Qnil;
32620 DEFVAR_LISP ("nobreak-char-display", Vnobreak_char_display,
32621 doc: /* Control highlighting of non-ASCII space and hyphen chars.
32622 If the value is t, Emacs highlights non-ASCII chars which have the
32623 same appearance as an ASCII space or hyphen, using the `nobreak-space'
32624 or `nobreak-hyphen' face respectively.
32626 U+00A0 (no-break space), U+00AD (soft hyphen), U+2010 (hyphen), and
32627 U+2011 (non-breaking hyphen) are affected.
32629 Any other non-nil value means to display these characters as an escape
32630 glyph followed by an ordinary space or hyphen.
32632 A value of nil means no special handling of these characters. */);
32633 Vnobreak_char_display = Qt;
32635 DEFVAR_LISP ("void-text-area-pointer", Vvoid_text_area_pointer,
32636 doc: /* The pointer shape to show in void text areas.
32637 A value of nil means to show the text pointer. Other options are
32638 `arrow', `text', `hand', `vdrag', `hdrag', `nhdrag', `modeline', and
32639 `hourglass'. */);
32640 Vvoid_text_area_pointer = Qarrow;
32642 DEFVAR_LISP ("inhibit-redisplay", Vinhibit_redisplay,
32643 doc: /* Non-nil means don't actually do any redisplay.
32644 This is used for internal purposes. */);
32645 Vinhibit_redisplay = Qnil;
32647 DEFVAR_LISP ("global-mode-string", Vglobal_mode_string,
32648 doc: /* String (or mode line construct) included (normally) in `mode-line-format'. */);
32649 Vglobal_mode_string = Qnil;
32651 DEFVAR_LISP ("overlay-arrow-position", Voverlay_arrow_position,
32652 doc: /* Marker for where to display an arrow on top of the buffer text.
32653 This must be the beginning of a line in order to work.
32654 See also `overlay-arrow-string'. */);
32655 Voverlay_arrow_position = Qnil;
32657 DEFVAR_LISP ("overlay-arrow-string", Voverlay_arrow_string,
32658 doc: /* String to display as an arrow in non-window frames.
32659 See also `overlay-arrow-position'. */);
32660 Voverlay_arrow_string = build_pure_c_string ("=>");
32662 DEFVAR_LISP ("overlay-arrow-variable-list", Voverlay_arrow_variable_list,
32663 doc: /* List of variables (symbols) which hold markers for overlay arrows.
32664 The symbols on this list are examined during redisplay to determine
32665 where to display overlay arrows. */);
32666 Voverlay_arrow_variable_list
32667 = list1 (intern_c_string ("overlay-arrow-position"));
32669 DEFVAR_INT ("scroll-step", emacs_scroll_step,
32670 doc: /* The number of lines to try scrolling a window by when point moves out.
32671 If that fails to bring point back on frame, point is centered instead.
32672 If this is zero, point is always centered after it moves off frame.
32673 If you want scrolling to always be a line at a time, you should set
32674 `scroll-conservatively' to a large value rather than set this to 1. */);
32676 DEFVAR_INT ("scroll-conservatively", scroll_conservatively,
32677 doc: /* Scroll up to this many lines, to bring point back on screen.
32678 If point moves off-screen, redisplay will scroll by up to
32679 `scroll-conservatively' lines in order to bring point just barely
32680 onto the screen again. If that cannot be done, then redisplay
32681 recenters point as usual.
32683 If the value is greater than 100, redisplay will never recenter point,
32684 but will always scroll just enough text to bring point into view, even
32685 if you move far away.
32687 A value of zero means always recenter point if it moves off screen. */);
32688 scroll_conservatively = 0;
32690 DEFVAR_INT ("scroll-margin", scroll_margin,
32691 doc: /* Number of lines of margin at the top and bottom of a window.
32692 Trigger automatic scrolling whenever point gets within this many lines
32693 of the top or bottom of the window (see info node `Auto Scrolling'). */);
32694 scroll_margin = 0;
32696 DEFVAR_LISP ("maximum-scroll-margin", Vmaximum_scroll_margin,
32697 doc: /* Maximum effective value of `scroll-margin'.
32698 Given as a fraction of the current window's lines. The value should
32699 be a floating point number between 0.0 and 0.5. The effective maximum
32700 is limited to (/ (1- window-lines) 2). Non-float values for this
32701 variable are ignored and the default 0.25 is used instead. */);
32702 Vmaximum_scroll_margin = make_float (0.25);
32704 DEFVAR_LISP ("display-pixels-per-inch", Vdisplay_pixels_per_inch,
32705 doc: /* Pixels per inch value for non-window system displays.
32706 Value is a number or a cons (WIDTH-DPI . HEIGHT-DPI). */);
32707 Vdisplay_pixels_per_inch = make_float (72.0);
32709 #ifdef GLYPH_DEBUG
32710 DEFVAR_INT ("debug-end-pos", debug_end_pos, doc: /* Don't ask. */);
32711 #endif
32713 DEFVAR_LISP ("truncate-partial-width-windows",
32714 Vtruncate_partial_width_windows,
32715 doc: /* Non-nil means truncate lines in windows narrower than the frame.
32716 For an integer value, truncate lines in each window narrower than the
32717 full frame width, provided the total window width in column units is less
32718 than that integer; otherwise, respect the value of `truncate-lines'.
32719 The total width of the window is as returned by `window-total-width', it
32720 includes the fringes, the continuation and truncation glyphs, the
32721 display margins (if any), and the scroll bar
32723 For any other non-nil value, truncate lines in all windows that do
32724 not span the full frame width.
32726 A value of nil means to respect the value of `truncate-lines'.
32728 If `word-wrap' is enabled, you might want to reduce this. */);
32729 Vtruncate_partial_width_windows = make_number (50);
32731 DEFVAR_LISP ("line-number-display-limit", Vline_number_display_limit,
32732 doc: /* Maximum buffer size for which line number should be displayed.
32733 If the buffer is bigger than this, the line number does not appear
32734 in the mode line. A value of nil means no limit. */);
32735 Vline_number_display_limit = Qnil;
32737 DEFVAR_INT ("line-number-display-limit-width",
32738 line_number_display_limit_width,
32739 doc: /* Maximum line width (in characters) for line number display.
32740 If the average length of the lines near point is bigger than this, then the
32741 line number may be omitted from the mode line. */);
32742 line_number_display_limit_width = 200;
32744 DEFVAR_BOOL ("highlight-nonselected-windows", highlight_nonselected_windows,
32745 doc: /* Non-nil means highlight region even in nonselected windows. */);
32746 highlight_nonselected_windows = false;
32748 DEFVAR_BOOL ("multiple-frames", multiple_frames,
32749 doc: /* Non-nil if more than one frame is visible on this display.
32750 Minibuffer-only frames don't count, but iconified frames do.
32751 This variable is not guaranteed to be accurate except while processing
32752 `frame-title-format' and `icon-title-format'. */);
32754 DEFVAR_LISP ("frame-title-format", Vframe_title_format,
32755 doc: /* Template for displaying the title bar of visible frames.
32756 \(Assuming the window manager supports this feature.)
32758 This variable has the same structure as `mode-line-format', except that
32759 the %c, %C, and %l constructs are ignored. It is used only on frames for
32760 which no explicit name has been set (see `modify-frame-parameters'). */);
32762 DEFVAR_LISP ("icon-title-format", Vicon_title_format,
32763 doc: /* Template for displaying the title bar of an iconified frame.
32764 \(Assuming the window manager supports this feature.)
32765 This variable has the same structure as `mode-line-format' (which see),
32766 and is used only on frames for which no explicit name has been set
32767 \(see `modify-frame-parameters'). */);
32768 Vicon_title_format
32769 = Vframe_title_format
32770 = listn (CONSTYPE_PURE, 3,
32771 intern_c_string ("multiple-frames"),
32772 build_pure_c_string ("%b"),
32773 listn (CONSTYPE_PURE, 4,
32774 empty_unibyte_string,
32775 intern_c_string ("invocation-name"),
32776 build_pure_c_string ("@"),
32777 intern_c_string ("system-name")));
32779 DEFVAR_LISP ("message-log-max", Vmessage_log_max,
32780 doc: /* Maximum number of lines to keep in the message log buffer.
32781 If nil, disable message logging. If t, log messages but don't truncate
32782 the buffer when it becomes large. */);
32783 Vmessage_log_max = make_number (1000);
32785 DEFVAR_LISP ("window-scroll-functions", Vwindow_scroll_functions,
32786 doc: /* List of functions to call before redisplaying a window with scrolling.
32787 Each function is called with two arguments, the window and its new
32788 display-start position.
32789 These functions are called whenever the `window-start' marker is modified,
32790 either to point into another buffer (e.g. via `set-window-buffer') or another
32791 place in the same buffer.
32792 When each function is called, the `window-start' marker of its window
32793 argument has been already set to the new value, and the buffer which that
32794 window will display is set to be the current buffer.
32795 Note that the value of `window-end' is not valid when these functions are
32796 called.
32798 Warning: Do not use this feature to alter the way the window
32799 is scrolled. It is not designed for that, and such use probably won't
32800 work. */);
32801 Vwindow_scroll_functions = Qnil;
32803 DEFVAR_LISP ("redisplay-end-trigger-functions", Vredisplay_end_trigger_functions,
32804 doc: /* Functions called when redisplay of a window reaches the end trigger.
32805 Each function is called with two arguments, the window and the end trigger value.
32806 See `set-window-redisplay-end-trigger'. */);
32807 Vredisplay_end_trigger_functions = Qnil;
32809 DEFVAR_LISP ("mouse-autoselect-window", Vmouse_autoselect_window,
32810 doc: /* Non-nil means autoselect window with mouse pointer.
32811 If nil, do not autoselect windows.
32812 A positive number means delay autoselection by that many seconds: a
32813 window is autoselected only after the mouse has remained in that
32814 window for the duration of the delay.
32815 A negative number has a similar effect, but causes windows to be
32816 autoselected only after the mouse has stopped moving. (Because of
32817 the way Emacs compares mouse events, you will occasionally wait twice
32818 that time before the window gets selected.)
32819 Any other value means to autoselect window instantaneously when the
32820 mouse pointer enters it.
32822 Autoselection selects the minibuffer only if it is active, and never
32823 unselects the minibuffer if it is active.
32825 When customizing this variable make sure that the actual value of
32826 `focus-follows-mouse' matches the behavior of your window manager. */);
32827 Vmouse_autoselect_window = Qnil;
32829 DEFVAR_LISP ("auto-resize-tool-bars", Vauto_resize_tool_bars,
32830 doc: /* Non-nil means automatically resize tool-bars.
32831 This dynamically changes the tool-bar's height to the minimum height
32832 that is needed to make all tool-bar items visible.
32833 If value is `grow-only', the tool-bar's height is only increased
32834 automatically; to decrease the tool-bar height, use \\[recenter]. */);
32835 Vauto_resize_tool_bars = Qt;
32837 DEFVAR_BOOL ("auto-raise-tool-bar-buttons", auto_raise_tool_bar_buttons_p,
32838 doc: /* Non-nil means raise tool-bar buttons when the mouse moves over them. */);
32839 auto_raise_tool_bar_buttons_p = true;
32841 DEFVAR_BOOL ("make-cursor-line-fully-visible", make_cursor_line_fully_visible_p,
32842 doc: /* Non-nil means to scroll (recenter) cursor line if it is not fully visible. */);
32843 make_cursor_line_fully_visible_p = true;
32845 DEFVAR_LISP ("tool-bar-border", Vtool_bar_border,
32846 doc: /* Border below tool-bar in pixels.
32847 If an integer, use it as the height of the border.
32848 If it is one of `internal-border-width' or `border-width', use the
32849 value of the corresponding frame parameter.
32850 Otherwise, no border is added below the tool-bar. */);
32851 Vtool_bar_border = Qinternal_border_width;
32853 DEFVAR_LISP ("tool-bar-button-margin", Vtool_bar_button_margin,
32854 doc: /* Margin around tool-bar buttons in pixels.
32855 If an integer, use that for both horizontal and vertical margins.
32856 Otherwise, value should be a pair of integers `(HORZ . VERT)' with
32857 HORZ specifying the horizontal margin, and VERT specifying the
32858 vertical margin. */);
32859 Vtool_bar_button_margin = make_number (DEFAULT_TOOL_BAR_BUTTON_MARGIN);
32861 DEFVAR_INT ("tool-bar-button-relief", tool_bar_button_relief,
32862 doc: /* Relief thickness of tool-bar buttons. */);
32863 tool_bar_button_relief = DEFAULT_TOOL_BAR_BUTTON_RELIEF;
32865 DEFVAR_LISP ("tool-bar-style", Vtool_bar_style,
32866 doc: /* Tool bar style to use.
32867 It can be one of
32868 image - show images only
32869 text - show text only
32870 both - show both, text below image
32871 both-horiz - show text to the right of the image
32872 text-image-horiz - show text to the left of the image
32873 any other - use system default or image if no system default.
32875 This variable only affects the GTK+ toolkit version of Emacs. */);
32876 Vtool_bar_style = Qnil;
32878 DEFVAR_INT ("tool-bar-max-label-size", tool_bar_max_label_size,
32879 doc: /* Maximum number of characters a label can have to be shown.
32880 The tool bar style must also show labels for this to have any effect, see
32881 `tool-bar-style'. */);
32882 tool_bar_max_label_size = DEFAULT_TOOL_BAR_LABEL_SIZE;
32884 DEFVAR_LISP ("fontification-functions", Vfontification_functions,
32885 doc: /* List of functions to call to fontify regions of text.
32886 Each function is called with one argument POS. Functions must
32887 fontify a region starting at POS in the current buffer, and give
32888 fontified regions the property `fontified'. */);
32889 Vfontification_functions = Qnil;
32890 Fmake_variable_buffer_local (Qfontification_functions);
32892 DEFVAR_BOOL ("unibyte-display-via-language-environment",
32893 unibyte_display_via_language_environment,
32894 doc: /* Non-nil means display unibyte text according to language environment.
32895 Specifically, this means that raw bytes in the range 160-255 decimal
32896 are displayed by converting them to the equivalent multibyte characters
32897 according to the current language environment. As a result, they are
32898 displayed according to the current fontset.
32900 Note that this variable affects only how these bytes are displayed,
32901 but does not change the fact they are interpreted as raw bytes. */);
32902 unibyte_display_via_language_environment = false;
32904 DEFVAR_LISP ("max-mini-window-height", Vmax_mini_window_height,
32905 doc: /* Maximum height for resizing mini-windows (the minibuffer and the echo area).
32906 If a float, it specifies a fraction of the mini-window frame's height.
32907 If an integer, it specifies a number of lines. */);
32908 Vmax_mini_window_height = make_float (0.25);
32910 DEFVAR_LISP ("resize-mini-windows", Vresize_mini_windows,
32911 doc: /* How to resize mini-windows (the minibuffer and the echo area).
32912 A value of nil means don't automatically resize mini-windows.
32913 A value of t means resize them to fit the text displayed in them.
32914 A value of `grow-only', the default, means let mini-windows grow only;
32915 they return to their normal size when the minibuffer is closed, or the
32916 echo area becomes empty. */);
32917 /* Contrary to the doc string, we initialize this to nil, so that
32918 loading loadup.el won't try to resize windows before loading
32919 window.el, where some functions we need to call for this live.
32920 We assign the 'grow-only' value right after loading window.el
32921 during loadup. */
32922 Vresize_mini_windows = Qnil;
32924 DEFVAR_LISP ("blink-cursor-alist", Vblink_cursor_alist,
32925 doc: /* Alist specifying how to blink the cursor off.
32926 Each element has the form (ON-STATE . OFF-STATE). Whenever the
32927 `cursor-type' frame-parameter or variable equals ON-STATE,
32928 comparing using `equal', Emacs uses OFF-STATE to specify
32929 how to blink it off. ON-STATE and OFF-STATE are values for
32930 the `cursor-type' frame parameter.
32932 If a frame's ON-STATE has no entry in this list,
32933 the frame's other specifications determine how to blink the cursor off. */);
32934 Vblink_cursor_alist = Qnil;
32936 DEFVAR_LISP ("auto-hscroll-mode", automatic_hscrolling,
32937 doc: /* Allow or disallow automatic horizontal scrolling of windows.
32938 The value `current-line' means the line displaying point in each window
32939 is automatically scrolled horizontally to make point visible.
32940 Any other non-nil value means all the lines in a window are automatically
32941 scrolled horizontally to make point visible. */);
32942 automatic_hscrolling = Qt;
32943 DEFSYM (Qauto_hscroll_mode, "auto-hscroll-mode");
32944 DEFSYM (Qcurrent_line, "current-line");
32946 DEFVAR_INT ("hscroll-margin", hscroll_margin,
32947 doc: /* How many columns away from the window edge point is allowed to get
32948 before automatic hscrolling will horizontally scroll the window. */);
32949 hscroll_margin = 5;
32951 DEFVAR_LISP ("hscroll-step", Vhscroll_step,
32952 doc: /* How many columns to scroll the window when point gets too close to the edge.
32953 When point is less than `hscroll-margin' columns from the window
32954 edge, automatic hscrolling will scroll the window by the amount of columns
32955 determined by this variable. If its value is a positive integer, scroll that
32956 many columns. If it's a positive floating-point number, it specifies the
32957 fraction of the window's width to scroll. If it's nil or zero, point will be
32958 centered horizontally after the scroll. Any other value, including negative
32959 numbers, are treated as if the value were zero.
32961 Automatic hscrolling always moves point outside the scroll margin, so if
32962 point was more than scroll step columns inside the margin, the window will
32963 scroll more than the value given by the scroll step.
32965 Note that the lower bound for automatic hscrolling specified by `scroll-left'
32966 and `scroll-right' overrides this variable's effect. */);
32967 Vhscroll_step = make_number (0);
32969 DEFVAR_BOOL ("message-truncate-lines", message_truncate_lines,
32970 doc: /* If non-nil, messages are truncated instead of resizing the echo area.
32971 Bind this around calls to `message' to let it take effect. */);
32972 message_truncate_lines = false;
32974 DEFVAR_LISP ("menu-bar-update-hook", Vmenu_bar_update_hook,
32975 doc: /* Normal hook run to update the menu bar definitions.
32976 Redisplay runs this hook before it redisplays the menu bar.
32977 This is used to update menus such as Buffers, whose contents depend on
32978 various data. */);
32979 Vmenu_bar_update_hook = Qnil;
32981 DEFVAR_LISP ("menu-updating-frame", Vmenu_updating_frame,
32982 doc: /* Frame for which we are updating a menu.
32983 The enable predicate for a menu binding should check this variable. */);
32984 Vmenu_updating_frame = Qnil;
32986 DEFVAR_BOOL ("inhibit-menubar-update", inhibit_menubar_update,
32987 doc: /* Non-nil means don't update menu bars. Internal use only. */);
32988 inhibit_menubar_update = false;
32990 DEFVAR_LISP ("wrap-prefix", Vwrap_prefix,
32991 doc: /* Prefix prepended to all continuation lines at display time.
32992 The value may be a string, an image, or a stretch-glyph; it is
32993 interpreted in the same way as the value of a `display' text property.
32995 This variable is overridden by any `wrap-prefix' text or overlay
32996 property.
32998 To add a prefix to non-continuation lines, use `line-prefix'. */);
32999 Vwrap_prefix = Qnil;
33000 DEFSYM (Qwrap_prefix, "wrap-prefix");
33001 Fmake_variable_buffer_local (Qwrap_prefix);
33003 DEFVAR_LISP ("line-prefix", Vline_prefix,
33004 doc: /* Prefix prepended to all non-continuation lines at display time.
33005 The value may be a string, an image, or a stretch-glyph; it is
33006 interpreted in the same way as the value of a `display' text property.
33008 This variable is overridden by any `line-prefix' text or overlay
33009 property.
33011 To add a prefix to continuation lines, use `wrap-prefix'. */);
33012 Vline_prefix = Qnil;
33013 DEFSYM (Qline_prefix, "line-prefix");
33014 Fmake_variable_buffer_local (Qline_prefix);
33016 DEFVAR_LISP ("display-line-numbers", Vdisplay_line_numbers,
33017 doc: /* Non-nil means display line numbers.
33018 If the value is t, display the absolute number of each line of a buffer
33019 shown in a window. Absolute line numbers count from the beginning of
33020 the current narrowing, or from buffer beginning. If the value is
33021 `relative', display for each line not containing the window's point its
33022 relative number instead, i.e. the number of the line relative to the
33023 line showing the window's point.
33025 In either case, line numbers are displayed at the beginning of each
33026 non-continuation line that displays buffer text, i.e. after each newline
33027 character that comes from the buffer. The value `visual' is like
33028 `relative' but counts screen lines instead of buffer lines. In practice
33029 this means that continuation lines count as well when calculating the
33030 relative number of a line.
33032 Lisp programs can disable display of a line number of a particular
33033 buffer line by putting the `display-line-numbers-disable' text property
33034 or overlay property on the first visible character of that line. */);
33035 Vdisplay_line_numbers = Qnil;
33036 DEFSYM (Qdisplay_line_numbers, "display-line-numbers");
33037 Fmake_variable_buffer_local (Qdisplay_line_numbers);
33038 DEFSYM (Qrelative, "relative");
33039 DEFSYM (Qvisual, "visual");
33041 DEFVAR_LISP ("display-line-numbers-width", Vdisplay_line_numbers_width,
33042 doc: /* Minimum width of space reserved for line number display.
33043 A positive number means reserve that many columns for line numbers,
33044 even if the actual number needs less space.
33045 The default value of nil means compute the space dynamically.
33046 Any other value is treated as nil. */);
33047 Vdisplay_line_numbers_width = Qnil;
33048 DEFSYM (Qdisplay_line_numbers_width, "display-line-numbers-width");
33049 Fmake_variable_buffer_local (Qdisplay_line_numbers_width);
33051 DEFVAR_LISP ("display-line-numbers-current-absolute",
33052 Vdisplay_line_numbers_current_absolute,
33053 doc: /* Non-nil means display absolute number of current line.
33054 This variable has effect only when `display-line-numbers' is
33055 either `relative' or `visual'. */);
33056 Vdisplay_line_numbers_current_absolute = Qt;
33058 DEFVAR_BOOL ("display-line-numbers-widen", display_line_numbers_widen,
33059 doc: /* Non-nil means display line numbers disregarding any narrowing. */);
33060 display_line_numbers_widen = false;
33061 DEFSYM (Qdisplay_line_numbers_widen, "display-line-numbers-widen");
33062 Fmake_variable_buffer_local (Qdisplay_line_numbers_widen);
33064 DEFVAR_BOOL ("inhibit-eval-during-redisplay", inhibit_eval_during_redisplay,
33065 doc: /* Non-nil means don't eval Lisp during redisplay. */);
33066 inhibit_eval_during_redisplay = false;
33068 DEFVAR_BOOL ("inhibit-free-realized-faces", inhibit_free_realized_faces,
33069 doc: /* Non-nil means don't free realized faces. Internal use only. */);
33070 inhibit_free_realized_faces = false;
33072 DEFVAR_BOOL ("inhibit-bidi-mirroring", inhibit_bidi_mirroring,
33073 doc: /* Non-nil means don't mirror characters even when bidi context requires that.
33074 Intended for use during debugging and for testing bidi display;
33075 see biditest.el in the test suite. */);
33076 inhibit_bidi_mirroring = false;
33078 #ifdef GLYPH_DEBUG
33079 DEFVAR_BOOL ("inhibit-try-window-id", inhibit_try_window_id,
33080 doc: /* Inhibit try_window_id display optimization. */);
33081 inhibit_try_window_id = false;
33083 DEFVAR_BOOL ("inhibit-try-window-reusing", inhibit_try_window_reusing,
33084 doc: /* Inhibit try_window_reusing display optimization. */);
33085 inhibit_try_window_reusing = false;
33087 DEFVAR_BOOL ("inhibit-try-cursor-movement", inhibit_try_cursor_movement,
33088 doc: /* Inhibit try_cursor_movement display optimization. */);
33089 inhibit_try_cursor_movement = false;
33090 #endif /* GLYPH_DEBUG */
33092 DEFVAR_INT ("overline-margin", overline_margin,
33093 doc: /* Space between overline and text, in pixels.
33094 The default value is 2: the height of the overline (1 pixel) plus 1 pixel
33095 margin to the character height. */);
33096 overline_margin = 2;
33098 DEFVAR_INT ("underline-minimum-offset",
33099 underline_minimum_offset,
33100 doc: /* Minimum distance between baseline and underline.
33101 This can improve legibility of underlined text at small font sizes,
33102 particularly when using variable `x-use-underline-position-properties'
33103 with fonts that specify an UNDERLINE_POSITION relatively close to the
33104 baseline. The default value is 1. */);
33105 underline_minimum_offset = 1;
33107 DEFVAR_BOOL ("display-hourglass", display_hourglass_p,
33108 doc: /* Non-nil means show an hourglass pointer, when Emacs is busy.
33109 This feature only works when on a window system that can change
33110 cursor shapes. */);
33111 display_hourglass_p = true;
33113 DEFVAR_LISP ("hourglass-delay", Vhourglass_delay,
33114 doc: /* Seconds to wait before displaying an hourglass pointer when Emacs is busy. */);
33115 Vhourglass_delay = make_number (DEFAULT_HOURGLASS_DELAY);
33117 #ifdef HAVE_WINDOW_SYSTEM
33118 hourglass_atimer = NULL;
33119 hourglass_shown_p = false;
33120 #endif /* HAVE_WINDOW_SYSTEM */
33122 /* Name of the face used to display glyphless characters. */
33123 DEFSYM (Qglyphless_char, "glyphless-char");
33125 /* Method symbols for Vglyphless_char_display. */
33126 DEFSYM (Qhex_code, "hex-code");
33127 DEFSYM (Qempty_box, "empty-box");
33128 DEFSYM (Qthin_space, "thin-space");
33129 DEFSYM (Qzero_width, "zero-width");
33131 DEFVAR_LISP ("pre-redisplay-function", Vpre_redisplay_function,
33132 doc: /* Function run just before redisplay.
33133 It is called with one argument, which is the set of windows that are to
33134 be redisplayed. This set can be nil (meaning, only the selected window),
33135 or t (meaning all windows). */);
33136 Vpre_redisplay_function = intern ("ignore");
33138 /* Symbol for the purpose of Vglyphless_char_display. */
33139 DEFSYM (Qglyphless_char_display, "glyphless-char-display");
33140 Fput (Qglyphless_char_display, Qchar_table_extra_slots, make_number (1));
33142 DEFVAR_LISP ("glyphless-char-display", Vglyphless_char_display,
33143 doc: /* Char-table defining glyphless characters.
33144 Each element, if non-nil, should be one of the following:
33145 an ASCII acronym string: display this string in a box
33146 `hex-code': display the hexadecimal code of a character in a box
33147 `empty-box': display as an empty box
33148 `thin-space': display as 1-pixel width space
33149 `zero-width': don't display
33150 An element may also be a cons cell (GRAPHICAL . TEXT), which specifies the
33151 display method for graphical terminals and text terminals respectively.
33152 GRAPHICAL and TEXT should each have one of the values listed above.
33154 The char-table has one extra slot to control the display of a character for
33155 which no font is found. This slot only takes effect on graphical terminals.
33156 Its value should be an ASCII acronym string, `hex-code', `empty-box', or
33157 `thin-space'. The default is `empty-box'.
33159 If a character has a non-nil entry in an active display table, the
33160 display table takes effect; in this case, Emacs does not consult
33161 `glyphless-char-display' at all. */);
33162 Vglyphless_char_display = Fmake_char_table (Qglyphless_char_display, Qnil);
33163 Fset_char_table_extra_slot (Vglyphless_char_display, make_number (0),
33164 Qempty_box);
33166 DEFVAR_LISP ("debug-on-message", Vdebug_on_message,
33167 doc: /* If non-nil, debug if a message matching this regexp is displayed. */);
33168 Vdebug_on_message = Qnil;
33170 DEFVAR_LISP ("redisplay--all-windows-cause", Vredisplay__all_windows_cause,
33171 doc: /* */);
33172 Vredisplay__all_windows_cause = Fmake_hash_table (0, NULL);
33174 DEFVAR_LISP ("redisplay--mode-lines-cause", Vredisplay__mode_lines_cause,
33175 doc: /* */);
33176 Vredisplay__mode_lines_cause = Fmake_hash_table (0, NULL);
33178 DEFVAR_BOOL ("redisplay--inhibit-bidi", redisplay__inhibit_bidi,
33179 doc: /* Non-nil means it is not safe to attempt bidi reordering for display. */);
33180 /* Initialize to t, since we need to disable reordering until
33181 loadup.el successfully loads charprop.el. */
33182 redisplay__inhibit_bidi = true;
33184 DEFVAR_BOOL ("display-raw-bytes-as-hex", display_raw_bytes_as_hex,
33185 doc: /* Non-nil means display raw bytes in hexadecimal format.
33186 The default is to use octal format (\200) whereas hexadecimal (\x80)
33187 may be more familiar to users. */);
33188 display_raw_bytes_as_hex = false;
33193 /* Initialize this module when Emacs starts. */
33195 void
33196 init_xdisp (void)
33198 CHARPOS (this_line_start_pos) = 0;
33200 if (!noninteractive)
33202 struct window *m = XWINDOW (minibuf_window);
33203 Lisp_Object frame = m->frame;
33204 struct frame *f = XFRAME (frame);
33205 Lisp_Object root = FRAME_ROOT_WINDOW (f);
33206 struct window *r = XWINDOW (root);
33207 int i;
33209 echo_area_window = minibuf_window;
33211 r->top_line = FRAME_TOP_MARGIN (f);
33212 r->pixel_top = r->top_line * FRAME_LINE_HEIGHT (f);
33213 r->total_cols = FRAME_COLS (f);
33214 r->pixel_width = r->total_cols * FRAME_COLUMN_WIDTH (f);
33215 r->total_lines = FRAME_TOTAL_LINES (f) - 1 - FRAME_TOP_MARGIN (f);
33216 r->pixel_height = r->total_lines * FRAME_LINE_HEIGHT (f);
33218 m->top_line = FRAME_TOTAL_LINES (f) - 1;
33219 m->pixel_top = m->top_line * FRAME_LINE_HEIGHT (f);
33220 m->total_cols = FRAME_COLS (f);
33221 m->pixel_width = m->total_cols * FRAME_COLUMN_WIDTH (f);
33222 m->total_lines = 1;
33223 m->pixel_height = m->total_lines * FRAME_LINE_HEIGHT (f);
33225 scratch_glyph_row.glyphs[TEXT_AREA] = scratch_glyphs;
33226 scratch_glyph_row.glyphs[TEXT_AREA + 1]
33227 = scratch_glyphs + MAX_SCRATCH_GLYPHS;
33229 /* The default ellipsis glyphs `...'. */
33230 for (i = 0; i < 3; ++i)
33231 default_invis_vector[i] = make_number ('.');
33235 /* Allocate the buffer for frame titles.
33236 Also used for `format-mode-line'. */
33237 int size = 100;
33238 mode_line_noprop_buf = xmalloc (size);
33239 mode_line_noprop_buf_end = mode_line_noprop_buf + size;
33240 mode_line_noprop_ptr = mode_line_noprop_buf;
33241 mode_line_target = MODE_LINE_DISPLAY;
33244 help_echo_showing_p = false;
33247 #ifdef HAVE_WINDOW_SYSTEM
33249 /* Platform-independent portion of hourglass implementation. */
33251 /* Timer function of hourglass_atimer. */
33253 static void
33254 show_hourglass (struct atimer *timer)
33256 /* The timer implementation will cancel this timer automatically
33257 after this function has run. Set hourglass_atimer to null
33258 so that we know the timer doesn't have to be canceled. */
33259 hourglass_atimer = NULL;
33261 if (!hourglass_shown_p)
33263 Lisp_Object tail, frame;
33265 block_input ();
33267 FOR_EACH_FRAME (tail, frame)
33269 struct frame *f = XFRAME (frame);
33271 if (FRAME_LIVE_P (f) && FRAME_WINDOW_P (f)
33272 && FRAME_RIF (f)->show_hourglass)
33273 FRAME_RIF (f)->show_hourglass (f);
33276 hourglass_shown_p = true;
33277 unblock_input ();
33281 /* Cancel a currently active hourglass timer, and start a new one. */
33283 void
33284 start_hourglass (void)
33286 struct timespec delay;
33288 cancel_hourglass ();
33290 if (INTEGERP (Vhourglass_delay)
33291 && XINT (Vhourglass_delay) > 0)
33292 delay = make_timespec (min (XINT (Vhourglass_delay),
33293 TYPE_MAXIMUM (time_t)),
33295 else if (FLOATP (Vhourglass_delay)
33296 && XFLOAT_DATA (Vhourglass_delay) > 0)
33297 delay = dtotimespec (XFLOAT_DATA (Vhourglass_delay));
33298 else
33299 delay = make_timespec (DEFAULT_HOURGLASS_DELAY, 0);
33301 hourglass_atimer = start_atimer (ATIMER_RELATIVE, delay,
33302 show_hourglass, NULL);
33305 /* Cancel the hourglass cursor timer if active, hide a busy cursor if
33306 shown. */
33308 void
33309 cancel_hourglass (void)
33311 if (hourglass_atimer)
33313 cancel_atimer (hourglass_atimer);
33314 hourglass_atimer = NULL;
33317 if (hourglass_shown_p)
33319 Lisp_Object tail, frame;
33321 block_input ();
33323 FOR_EACH_FRAME (tail, frame)
33325 struct frame *f = XFRAME (frame);
33327 if (FRAME_LIVE_P (f) && FRAME_WINDOW_P (f)
33328 && FRAME_RIF (f)->hide_hourglass)
33329 FRAME_RIF (f)->hide_hourglass (f);
33330 #ifdef HAVE_NTGUI
33331 /* No cursors on non GUI frames - restore to stock arrow cursor. */
33332 else if (!FRAME_W32_P (f))
33333 w32_arrow_cursor ();
33334 #endif
33337 hourglass_shown_p = false;
33338 unblock_input ();
33342 #endif /* HAVE_WINDOW_SYSTEM */