; Fix last commit in tramp.el
[emacs.git] / src / xdisp.c
blobdf5335e4accecd175ccc439bada62458516b62d9
1 /* Display generation from window structure and buffer text.
3 Copyright (C) 1985-1988, 1993-1995, 1997-2018 Free Software Foundation,
4 Inc.
6 This file is part of GNU Emacs.
8 GNU Emacs is free software: you can redistribute it and/or modify
9 it under the terms of the GNU General Public License as published by
10 the Free Software Foundation, either version 3 of the License, or (at
11 your option) any later version.
13 GNU Emacs is distributed in the hope that it will be useful,
14 but WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 GNU General Public License for more details.
18 You should have received a copy of the GNU General Public License
19 along with GNU Emacs. If not, see <https://www.gnu.org/licenses/>. */
21 /* New redisplay written by Gerd Moellmann <gerd@gnu.org>.
23 Redisplay.
25 Emacs separates the task of updating the display from code
26 modifying global state, e.g. buffer text. This way functions
27 operating on buffers don't also have to be concerned with updating
28 the display.
30 Updating the display is triggered by the Lisp interpreter when it
31 decides it's time to do it. This is done either automatically for
32 you as part of the interpreter's command loop or as the result of
33 calling Lisp functions like `sit-for'. The C function `redisplay'
34 in xdisp.c is the only entry into the inner redisplay code.
36 The following diagram shows how redisplay code is invoked. As you
37 can see, Lisp calls redisplay and vice versa.
39 Under window systems like X, some portions of the redisplay code
40 are also called asynchronously, due to mouse movement or expose
41 events. "Asynchronously" in this context means that any C function
42 which calls maybe_quit or process_pending_signals could enter
43 redisplay via expose_frame and/or note_mouse_highlight, if X events
44 were recently reported to Emacs about mouse movements or frame(s)
45 that were exposed. And such redisplay could invoke the Lisp
46 interpreter, e.g. via the :eval forms in mode-line-format, and as
47 result the global state could change. It is therefore very
48 important that C functions which might cause such "asynchronous"
49 redisplay, but cannot tolerate the results, use
50 block_input/unblock_input around code fragments which assume that
51 global Lisp state doesn't change. If you don't follow this rule,
52 you will encounter bugs which are very hard to explain. One place
53 that needs to take such precautions is timer_check, some of whose
54 code cannot tolerate changes in timer alists while it processes
55 timers.
57 +--------------+ redisplay +----------------+
58 | Lisp machine |---------------->| Redisplay code |<--+
59 +--------------+ (xdisp.c) +----------------+ |
60 ^ | |
61 +----------------------------------+ |
62 Block input to prevent this when |
63 called asynchronously! |
65 note_mouse_highlight (asynchronous) |
67 X mouse events -----+
69 expose_frame (asynchronous) |
71 X expose events -----+
73 What does redisplay do? Obviously, it has to figure out somehow what
74 has been changed since the last time the display has been updated,
75 and to make these changes visible. Preferably it would do that in
76 a moderately intelligent way, i.e. fast.
78 Changes in buffer text can be deduced from window and buffer
79 structures, and from some global variables like `beg_unchanged' and
80 `end_unchanged'. The contents of the display are additionally
81 recorded in a `glyph matrix', a two-dimensional matrix of glyph
82 structures. Each row in such a matrix corresponds to a line on the
83 display, and each glyph in a row corresponds to a column displaying
84 a character, an image, or what else. This matrix is called the
85 `current glyph matrix' or `current matrix' in redisplay
86 terminology.
88 For buffer parts that have been changed since the last update, a
89 second glyph matrix is constructed, the so called `desired glyph
90 matrix' or short `desired matrix'. Current and desired matrix are
91 then compared to find a cheap way to update the display, e.g. by
92 reusing part of the display by scrolling lines.
94 You will find a lot of redisplay optimizations when you start
95 looking at the innards of redisplay. The overall goal of all these
96 optimizations is to make redisplay fast because it is done
97 frequently. Some of these optimizations are implemented by the
98 following functions:
100 . try_cursor_movement
102 This function tries to update the display if the text in the
103 window did not change and did not scroll, only point moved, and
104 it did not move off the displayed portion of the text.
106 . try_window_reusing_current_matrix
108 This function reuses the current matrix of a window when text
109 has not changed, but the window start changed (e.g., due to
110 scrolling).
112 . try_window_id
114 This function attempts to redisplay a window by reusing parts of
115 its existing display. It finds and reuses the part that was not
116 changed, and redraws the rest. (The "id" part in the function's
117 name stands for "insert/delete", not for "identification" or
118 somesuch.)
120 . try_window
122 This function performs the full redisplay of a single window
123 assuming that its fonts were not changed and that the cursor
124 will not end up in the scroll margins. (Loading fonts requires
125 re-adjustment of dimensions of glyph matrices, which makes this
126 method impossible to use.)
128 These optimizations are tried in sequence (some can be skipped if
129 it is known that they are not applicable). If none of the
130 optimizations were successful, redisplay calls redisplay_windows,
131 which performs a full redisplay of all windows.
133 Note that there's one more important optimization up Emacs's
134 sleeve, but it is related to actually redrawing the potentially
135 changed portions of the window/frame, not to reproducing the
136 desired matrices of those potentially changed portions. Namely,
137 the function update_frame and its subroutines, which you will find
138 in dispnew.c, compare the desired matrices with the current
139 matrices, and only redraw the portions that changed. So it could
140 happen that the functions in this file for some reason decide that
141 the entire desired matrix needs to be regenerated from scratch, and
142 still only parts of the Emacs display, or even nothing at all, will
143 be actually delivered to the glass, because update_frame has found
144 that the new and the old screen contents are similar or identical.
146 Desired matrices.
148 Desired matrices are always built per Emacs window. The function
149 `display_line' is the central function to look at if you are
150 interested. It constructs one row in a desired matrix given an
151 iterator structure containing both a buffer position and a
152 description of the environment in which the text is to be
153 displayed. But this is too early, read on.
155 Characters and pixmaps displayed for a range of buffer text depend
156 on various settings of buffers and windows, on overlays and text
157 properties, on display tables, on selective display. The good news
158 is that all this hairy stuff is hidden behind a small set of
159 interface functions taking an iterator structure (struct it)
160 argument.
162 Iteration over things to be displayed is then simple. It is
163 started by initializing an iterator with a call to init_iterator,
164 passing it the buffer position where to start iteration. For
165 iteration over strings, pass -1 as the position to init_iterator,
166 and call reseat_to_string when the string is ready, to initialize
167 the iterator for that string. Thereafter, calls to
168 get_next_display_element fill the iterator structure with relevant
169 information about the next thing to display. Calls to
170 set_iterator_to_next move the iterator to the next thing.
172 Besides this, an iterator also contains information about the
173 display environment in which glyphs for display elements are to be
174 produced. It has fields for the width and height of the display,
175 the information whether long lines are truncated or continued, a
176 current X and Y position, and lots of other stuff you can better
177 see in dispextern.h.
179 Glyphs in a desired matrix are normally constructed in a loop
180 calling get_next_display_element and then PRODUCE_GLYPHS. The call
181 to PRODUCE_GLYPHS will fill the iterator structure with pixel
182 information about the element being displayed and at the same time
183 produce glyphs for it. If the display element fits on the line
184 being displayed, set_iterator_to_next is called next, otherwise the
185 glyphs produced are discarded. The function display_line is the
186 workhorse of filling glyph rows in the desired matrix with glyphs.
187 In addition to producing glyphs, it also handles line truncation
188 and continuation, word wrap, and cursor positioning (for the
189 latter, see also set_cursor_from_row).
191 Frame matrices.
193 That just couldn't be all, could it? What about terminal types not
194 supporting operations on sub-windows of the screen? To update the
195 display on such a terminal, window-based glyph matrices are not
196 well suited. To be able to reuse part of the display (scrolling
197 lines up and down), we must instead have a view of the whole
198 screen. This is what `frame matrices' are for. They are a trick.
200 Frames on terminals like above have a glyph pool. Windows on such
201 a frame sub-allocate their glyph memory from their frame's glyph
202 pool. The frame itself is given its own glyph matrices. By
203 coincidence---or maybe something else---rows in window glyph
204 matrices are slices of corresponding rows in frame matrices. Thus
205 writing to window matrices implicitly updates a frame matrix which
206 provides us with the view of the whole screen that we originally
207 wanted to have without having to move many bytes around. To be
208 honest, there is a little bit more done, but not much more. If you
209 plan to extend that code, take a look at dispnew.c. The function
210 build_frame_matrix is a good starting point.
212 Bidirectional display.
214 Bidirectional display adds quite some hair to this already complex
215 design. The good news are that a large portion of that hairy stuff
216 is hidden in bidi.c behind only 3 interfaces. bidi.c implements a
217 reordering engine which is called by set_iterator_to_next and
218 returns the next character to display in the visual order. See
219 commentary on bidi.c for more details. As far as redisplay is
220 concerned, the effect of calling bidi_move_to_visually_next, the
221 main interface of the reordering engine, is that the iterator gets
222 magically placed on the buffer or string position that is to be
223 displayed next. In other words, a linear iteration through the
224 buffer/string is replaced with a non-linear one. All the rest of
225 the redisplay is oblivious to the bidi reordering.
227 Well, almost oblivious---there are still complications, most of
228 them due to the fact that buffer and string positions no longer
229 change monotonously with glyph indices in a glyph row. Moreover,
230 for continued lines, the buffer positions may not even be
231 monotonously changing with vertical positions. Also, accounting
232 for face changes, overlays, etc. becomes more complex because
233 non-linear iteration could potentially skip many positions with
234 changes, and then cross them again on the way back...
236 One other prominent effect of bidirectional display is that some
237 paragraphs of text need to be displayed starting at the right
238 margin of the window---the so-called right-to-left, or R2L
239 paragraphs. R2L paragraphs are displayed with R2L glyph rows,
240 which have their reversed_p flag set. The bidi reordering engine
241 produces characters in such rows starting from the character which
242 should be the rightmost on display. PRODUCE_GLYPHS then reverses
243 the order, when it fills up the glyph row whose reversed_p flag is
244 set, by prepending each new glyph to what is already there, instead
245 of appending it. When the glyph row is complete, the function
246 extend_face_to_end_of_line fills the empty space to the left of the
247 leftmost character with special glyphs, which will display as,
248 well, empty. On text terminals, these special glyphs are simply
249 blank characters. On graphics terminals, there's a single stretch
250 glyph of a suitably computed width. Both the blanks and the
251 stretch glyph are given the face of the background of the line.
252 This way, the terminal-specific back-end can still draw the glyphs
253 left to right, even for R2L lines.
255 Bidirectional display and character compositions
257 Some scripts cannot be displayed by drawing each character
258 individually, because adjacent characters change each other's shape
259 on display. For example, Arabic and Indic scripts belong to this
260 category.
262 Emacs display supports this by providing "character compositions",
263 most of which is implemented in composite.c. During the buffer
264 scan that delivers characters to PRODUCE_GLYPHS, if the next
265 character to be delivered is a composed character, the iteration
266 calls composition_reseat_it and next_element_from_composition. If
267 they succeed to compose the character with one or more of the
268 following characters, the whole sequence of characters that where
269 composed is recorded in the `struct composition_it' object that is
270 part of the buffer iterator. The composed sequence could produce
271 one or more font glyphs (called "grapheme clusters") on the screen.
272 Each of these grapheme clusters is then delivered to PRODUCE_GLYPHS
273 in the direction corresponding to the current bidi scan direction
274 (recorded in the scan_dir member of the `struct bidi_it' object
275 that is part of the buffer iterator). In particular, if the bidi
276 iterator currently scans the buffer backwards, the grapheme
277 clusters are delivered back to front. This reorders the grapheme
278 clusters as appropriate for the current bidi context. Note that
279 this means that the grapheme clusters are always stored in the
280 LGSTRING object (see composite.c) in the logical order.
282 Moving an iterator in bidirectional text
283 without producing glyphs
285 Note one important detail mentioned above: that the bidi reordering
286 engine, driven by the iterator, produces characters in R2L rows
287 starting at the character that will be the rightmost on display.
288 As far as the iterator is concerned, the geometry of such rows is
289 still left to right, i.e. the iterator "thinks" the first character
290 is at the leftmost pixel position. The iterator does not know that
291 PRODUCE_GLYPHS reverses the order of the glyphs that the iterator
292 delivers. This is important when functions from the move_it_*
293 family are used to get to certain screen position or to match
294 screen coordinates with buffer coordinates: these functions use the
295 iterator geometry, which is left to right even in R2L paragraphs.
296 This works well with most callers of move_it_*, because they need
297 to get to a specific column, and columns are still numbered in the
298 reading order, i.e. the rightmost character in a R2L paragraph is
299 still column zero. But some callers do not get well with this; a
300 notable example is mouse clicks that need to find the character
301 that corresponds to certain pixel coordinates. See
302 buffer_posn_from_coords in dispnew.c for how this is handled. */
304 #include <config.h>
305 #include <stdio.h>
306 #include <stdlib.h>
307 #include <limits.h>
308 #include <math.h>
310 #include "lisp.h"
311 #include "atimer.h"
312 #include "composite.h"
313 #include "keyboard.h"
314 #include "systime.h"
315 #include "frame.h"
316 #include "window.h"
317 #include "termchar.h"
318 #include "dispextern.h"
319 #include "character.h"
320 #include "buffer.h"
321 #include "charset.h"
322 #include "indent.h"
323 #include "commands.h"
324 #include "keymap.h"
325 #include "disptab.h"
326 #include "termhooks.h"
327 #include "termopts.h"
328 #include "intervals.h"
329 #include "coding.h"
330 #include "region-cache.h"
331 #include "font.h"
332 #include "fontset.h"
333 #include "blockinput.h"
334 #include "xwidget.h"
335 #ifdef HAVE_WINDOW_SYSTEM
336 #include TERM_HEADER
337 #endif /* HAVE_WINDOW_SYSTEM */
339 #ifndef FRAME_X_OUTPUT
340 #define FRAME_X_OUTPUT(f) ((f)->output_data.x)
341 #endif
343 #define DISP_INFINITY 10000000
345 /* Holds the list (error). */
346 static Lisp_Object list_of_error;
348 #ifdef HAVE_WINDOW_SYSTEM
350 /* Test if overflow newline into fringe. Called with iterator IT
351 at or past right window margin, and with IT->current_x set. */
353 #define IT_OVERFLOW_NEWLINE_INTO_FRINGE(IT) \
354 (!NILP (Voverflow_newline_into_fringe) \
355 && FRAME_WINDOW_P ((IT)->f) \
356 && ((IT)->bidi_it.paragraph_dir == R2L \
357 ? (WINDOW_LEFT_FRINGE_WIDTH ((IT)->w) > 0) \
358 : (WINDOW_RIGHT_FRINGE_WIDTH ((IT)->w) > 0)) \
359 && (IT)->current_x == (IT)->last_visible_x)
361 #else /* !HAVE_WINDOW_SYSTEM */
362 #define IT_OVERFLOW_NEWLINE_INTO_FRINGE(it) false
363 #endif /* HAVE_WINDOW_SYSTEM */
365 /* Test if the display element loaded in IT, or the underlying buffer
366 or string character, is a space or a TAB character. This is used
367 to determine where word wrapping can occur. */
369 #define IT_DISPLAYING_WHITESPACE(it) \
370 ((it->what == IT_CHARACTER && (it->c == ' ' || it->c == '\t')) \
371 || ((STRINGP (it->string) \
372 && (SREF (it->string, IT_STRING_BYTEPOS (*it)) == ' ' \
373 || SREF (it->string, IT_STRING_BYTEPOS (*it)) == '\t')) \
374 || (it->s \
375 && (it->s[IT_BYTEPOS (*it)] == ' ' \
376 || it->s[IT_BYTEPOS (*it)] == '\t')) \
377 || (IT_BYTEPOS (*it) < ZV_BYTE \
378 && (*BYTE_POS_ADDR (IT_BYTEPOS (*it)) == ' ' \
379 || *BYTE_POS_ADDR (IT_BYTEPOS (*it)) == '\t')))) \
381 /* True means print newline to stdout before next mini-buffer message. */
383 bool noninteractive_need_newline;
385 /* True means print newline to message log before next message. */
387 static bool message_log_need_newline;
389 /* Three markers that message_dolog uses.
390 It could allocate them itself, but that causes trouble
391 in handling memory-full errors. */
392 static Lisp_Object message_dolog_marker1;
393 static Lisp_Object message_dolog_marker2;
394 static Lisp_Object message_dolog_marker3;
396 /* The buffer position of the first character appearing entirely or
397 partially on the line of the selected window which contains the
398 cursor; <= 0 if not known. Set by set_cursor_from_row, used for
399 redisplay optimization in redisplay_internal. */
401 static struct text_pos this_line_start_pos;
403 /* Number of characters past the end of the line above, including the
404 terminating newline. */
406 static struct text_pos this_line_end_pos;
408 /* The vertical positions and the height of this line. */
410 static int this_line_vpos;
411 static int this_line_y;
412 static int this_line_pixel_height;
414 /* X position at which this display line starts. Usually zero;
415 negative if first character is partially visible. */
417 static int this_line_start_x;
419 /* The smallest character position seen by move_it_* functions as they
420 move across display lines. Used to set MATRIX_ROW_START_CHARPOS of
421 hscrolled lines, see display_line. */
423 static struct text_pos this_line_min_pos;
425 /* Buffer that this_line_.* variables are referring to. */
427 static struct buffer *this_line_buffer;
429 /* True if an overlay arrow has been displayed in this window. */
431 static bool overlay_arrow_seen;
433 /* Vector containing glyphs for an ellipsis `...'. */
435 static Lisp_Object default_invis_vector[3];
437 /* This is the window where the echo area message was displayed. It
438 is always a mini-buffer window, but it may not be the same window
439 currently active as a mini-buffer. */
441 Lisp_Object echo_area_window;
443 /* Stack of messages, which are pushed by push_message and popped and
444 displayed by restore_message. */
446 static Lisp_Object Vmessage_stack;
448 /* True means multibyte characters were enabled when the echo area
449 message was specified. */
451 static bool message_enable_multibyte;
453 /* At each redisplay cycle, we should refresh everything there is to refresh.
454 To do that efficiently, we use many optimizations that try to make sure we
455 don't waste too much time updating things that haven't changed.
456 The coarsest such optimization is that, in the most common cases, we only
457 look at the selected-window.
459 To know whether other windows should be considered for redisplay, we use the
460 variable windows_or_buffers_changed: as long as it is 0, it means that we
461 have not noticed anything that should require updating anything else than
462 the selected-window. If it is set to REDISPLAY_SOME, it means that since
463 last redisplay, some changes have been made which could impact other
464 windows. To know which ones need redisplay, every buffer, window, and frame
465 has a `redisplay' bit, which (if true) means that this object needs to be
466 redisplayed. If windows_or_buffers_changed is 0, we know there's no point
467 looking for those `redisplay' bits (actually, there might be some such bits
468 set, but then only on objects which aren't displayed anyway).
470 OTOH if it's non-zero we wil have to loop through all windows and then check
471 the `redisplay' bit of the corresponding window, frame, and buffer, in order
472 to decide whether that window needs attention or not. Note that we can't
473 just look at the frame's redisplay bit to decide that the whole frame can be
474 skipped, since even if the frame's redisplay bit is unset, some of its
475 windows's redisplay bits may be set.
477 Mostly for historical reasons, windows_or_buffers_changed can also take
478 other non-zero values. In that case, the precise value doesn't matter (it
479 encodes the cause of the setting but is only used for debugging purposes),
480 and what it means is that we shouldn't pay attention to any `redisplay' bits
481 and we should simply try and redisplay every window out there. */
483 int windows_or_buffers_changed;
485 /* Nonzero if we should redraw the mode lines on the next redisplay.
486 Similarly to `windows_or_buffers_changed', If it has value REDISPLAY_SOME,
487 then only redisplay the mode lines in those buffers/windows/frames where the
488 `redisplay' bit has been set.
489 For any other value, redisplay all mode lines (the number used is then only
490 used to track down the cause for this full-redisplay).
492 Since the frame title uses the same %-constructs as the mode line
493 (except %c, %C, and %l), if this variable is non-zero, we also consider
494 redisplaying the title of each frame, see x_consider_frame_title.
496 The `redisplay' bits are the same as those used for
497 windows_or_buffers_changed, and setting windows_or_buffers_changed also
498 causes recomputation of the mode lines of all those windows. IOW this
499 variable only has an effect if windows_or_buffers_changed is zero, in which
500 case we should only need to redisplay the mode-line of those objects with
501 a `redisplay' bit set but not the window's text content (tho we may still
502 need to refresh the text content of the selected-window). */
504 int update_mode_lines;
506 /* True after display_mode_line if %l was used and it displayed a
507 line number. */
509 static bool line_number_displayed;
511 /* The name of the *Messages* buffer, a string. */
513 static Lisp_Object Vmessages_buffer_name;
515 /* Current, index 0, and last displayed echo area message. Either
516 buffers from echo_buffers, or nil to indicate no message. */
518 Lisp_Object echo_area_buffer[2];
520 /* The buffers referenced from echo_area_buffer. */
522 static Lisp_Object echo_buffer[2];
524 /* A vector saved used in with_area_buffer to reduce consing. */
526 static Lisp_Object Vwith_echo_area_save_vector;
528 /* True means display_echo_area should display the last echo area
529 message again. Set by redisplay_preserve_echo_area. */
531 static bool display_last_displayed_message_p;
533 /* True if echo area is being used by print; false if being used by
534 message. */
536 static bool message_buf_print;
538 /* Set to true in clear_message to make redisplay_internal aware
539 of an emptied echo area. */
541 static bool message_cleared_p;
543 /* A scratch glyph row with contents used for generating truncation
544 glyphs. Also used in direct_output_for_insert. */
546 #define MAX_SCRATCH_GLYPHS 100
547 static struct glyph_row scratch_glyph_row;
548 static struct glyph scratch_glyphs[MAX_SCRATCH_GLYPHS];
550 /* Ascent and height of the last line processed by move_it_to. */
552 static int last_height;
554 /* True if there's a help-echo in the echo area. */
556 bool help_echo_showing_p;
558 /* The maximum distance to look ahead for text properties. Values
559 that are too small let us call compute_char_face and similar
560 functions too often which is expensive. Values that are too large
561 let us call compute_char_face and alike too often because we
562 might not be interested in text properties that far away. */
564 #define TEXT_PROP_DISTANCE_LIMIT 100
566 /* SAVE_IT and RESTORE_IT are called when we save a snapshot of the
567 iterator state and later restore it. This is needed because the
568 bidi iterator on bidi.c keeps a stacked cache of its states, which
569 is really a singleton. When we use scratch iterator objects to
570 move around the buffer, we can cause the bidi cache to be pushed or
571 popped, and therefore we need to restore the cache state when we
572 return to the original iterator. */
573 #define SAVE_IT(ITCOPY, ITORIG, CACHE) \
574 do { \
575 if (CACHE) \
576 bidi_unshelve_cache (CACHE, true); \
577 ITCOPY = ITORIG; \
578 CACHE = bidi_shelve_cache (); \
579 } while (false)
581 #define RESTORE_IT(pITORIG, pITCOPY, CACHE) \
582 do { \
583 if (pITORIG != pITCOPY) \
584 *(pITORIG) = *(pITCOPY); \
585 bidi_unshelve_cache (CACHE, false); \
586 CACHE = NULL; \
587 } while (false)
589 /* Functions to mark elements as needing redisplay. */
590 enum { REDISPLAY_SOME = 2}; /* Arbitrary choice. */
592 void
593 redisplay_other_windows (void)
595 if (!windows_or_buffers_changed)
596 windows_or_buffers_changed = REDISPLAY_SOME;
599 void
600 wset_redisplay (struct window *w)
602 /* Beware: selected_window can be nil during early stages. */
603 if (!EQ (make_lisp_ptr (w, Lisp_Vectorlike), selected_window))
604 redisplay_other_windows ();
605 w->redisplay = true;
608 void
609 fset_redisplay (struct frame *f)
611 redisplay_other_windows ();
612 f->redisplay = true;
615 void
616 bset_redisplay (struct buffer *b)
618 int count = buffer_window_count (b);
619 if (count > 0)
621 /* ... it's visible in other window than selected, */
622 if (count > 1 || b != XBUFFER (XWINDOW (selected_window)->contents))
623 redisplay_other_windows ();
624 /* Even if we don't set windows_or_buffers_changed, do set `redisplay'
625 so that if we later set windows_or_buffers_changed, this buffer will
626 not be omitted. */
627 b->text->redisplay = true;
631 void
632 bset_update_mode_line (struct buffer *b)
634 if (!update_mode_lines)
635 update_mode_lines = REDISPLAY_SOME;
636 b->text->redisplay = true;
639 DEFUN ("set-buffer-redisplay", Fset_buffer_redisplay,
640 Sset_buffer_redisplay, 4, 4, 0,
641 doc: /* Mark the current buffer for redisplay.
642 This function may be passed to `add-variable-watcher'. */)
643 (Lisp_Object symbol, Lisp_Object newval, Lisp_Object op, Lisp_Object where)
645 bset_update_mode_line (current_buffer);
646 current_buffer->prevent_redisplay_optimizations_p = true;
647 return Qnil;
650 #ifdef GLYPH_DEBUG
652 /* True means print traces of redisplay if compiled with
653 GLYPH_DEBUG defined. */
655 bool trace_redisplay_p;
657 #endif /* GLYPH_DEBUG */
659 #ifdef DEBUG_TRACE_MOVE
660 /* True means trace with TRACE_MOVE to stderr. */
661 static bool trace_move;
663 #define TRACE_MOVE(x) if (trace_move) fprintf x; else (void) 0
664 #else
665 #define TRACE_MOVE(x) (void) 0
666 #endif
668 /* Buffer being redisplayed -- for redisplay_window_error. */
670 static struct buffer *displayed_buffer;
672 /* Value returned from text property handlers (see below). */
674 enum prop_handled
676 HANDLED_NORMALLY,
677 HANDLED_RECOMPUTE_PROPS,
678 HANDLED_OVERLAY_STRING_CONSUMED,
679 HANDLED_RETURN
682 /* A description of text properties that redisplay is interested
683 in. */
685 struct props
687 /* The symbol index of the name of the property. */
688 short name;
690 /* A unique index for the property. */
691 enum prop_idx idx;
693 /* A handler function called to set up iterator IT from the property
694 at IT's current position. Value is used to steer handle_stop. */
695 enum prop_handled (*handler) (struct it *it);
698 static enum prop_handled handle_face_prop (struct it *);
699 static enum prop_handled handle_invisible_prop (struct it *);
700 static enum prop_handled handle_display_prop (struct it *);
701 static enum prop_handled handle_composition_prop (struct it *);
702 static enum prop_handled handle_overlay_change (struct it *);
703 static enum prop_handled handle_fontified_prop (struct it *);
705 /* Properties handled by iterators. */
707 static struct props it_props[] =
709 {SYMBOL_INDEX (Qfontified), FONTIFIED_PROP_IDX, handle_fontified_prop},
710 /* Handle `face' before `display' because some sub-properties of
711 `display' need to know the face. */
712 {SYMBOL_INDEX (Qface), FACE_PROP_IDX, handle_face_prop},
713 {SYMBOL_INDEX (Qdisplay), DISPLAY_PROP_IDX, handle_display_prop},
714 {SYMBOL_INDEX (Qinvisible), INVISIBLE_PROP_IDX, handle_invisible_prop},
715 {SYMBOL_INDEX (Qcomposition), COMPOSITION_PROP_IDX, handle_composition_prop},
716 {0, 0, NULL}
719 /* Value is the position described by X. If X is a marker, value is
720 the marker_position of X. Otherwise, value is X. */
722 #define COERCE_MARKER(X) (MARKERP ((X)) ? Fmarker_position (X) : (X))
724 /* Enumeration returned by some move_it_.* functions internally. */
726 enum move_it_result
728 /* Not used. Undefined value. */
729 MOVE_UNDEFINED,
731 /* Move ended at the requested buffer position or ZV. */
732 MOVE_POS_MATCH_OR_ZV,
734 /* Move ended at the requested X pixel position. */
735 MOVE_X_REACHED,
737 /* Move within a line ended at the end of a line that must be
738 continued. */
739 MOVE_LINE_CONTINUED,
741 /* Move within a line ended at the end of a line that would
742 be displayed truncated. */
743 MOVE_LINE_TRUNCATED,
745 /* Move within a line ended at a line end. */
746 MOVE_NEWLINE_OR_CR
749 /* This counter is used to clear the face cache every once in a while
750 in redisplay_internal. It is incremented for each redisplay.
751 Every CLEAR_FACE_CACHE_COUNT full redisplays, the face cache is
752 cleared. */
754 #define CLEAR_FACE_CACHE_COUNT 500
755 static int clear_face_cache_count;
757 /* Similarly for the image cache. */
759 #ifdef HAVE_WINDOW_SYSTEM
760 #define CLEAR_IMAGE_CACHE_COUNT 101
761 static int clear_image_cache_count;
763 /* Null glyph slice */
764 static struct glyph_slice null_glyph_slice = { 0, 0, 0, 0 };
765 #endif
767 /* True while redisplay_internal is in progress. */
769 bool redisplaying_p;
771 /* If a string, XTread_socket generates an event to display that string.
772 (The display is done in read_char.) */
774 Lisp_Object help_echo_string;
775 Lisp_Object help_echo_window;
776 Lisp_Object help_echo_object;
777 ptrdiff_t help_echo_pos;
779 /* Temporary variable for XTread_socket. */
781 Lisp_Object previous_help_echo_string;
783 /* Platform-independent portion of hourglass implementation. */
785 #ifdef HAVE_WINDOW_SYSTEM
787 /* True means an hourglass cursor is currently shown. */
788 static bool hourglass_shown_p;
790 /* If non-null, an asynchronous timer that, when it expires, displays
791 an hourglass cursor on all frames. */
792 static struct atimer *hourglass_atimer;
794 #endif /* HAVE_WINDOW_SYSTEM */
796 /* Default number of seconds to wait before displaying an hourglass
797 cursor. */
798 #define DEFAULT_HOURGLASS_DELAY 1
800 #ifdef HAVE_WINDOW_SYSTEM
802 /* Default pixel width of `thin-space' display method. */
803 #define THIN_SPACE_WIDTH 1
805 #endif /* HAVE_WINDOW_SYSTEM */
807 /* Function prototypes. */
809 static void setup_for_ellipsis (struct it *, int);
810 static void set_iterator_to_next (struct it *, bool);
811 static void mark_window_display_accurate_1 (struct window *, bool);
812 static bool row_for_charpos_p (struct glyph_row *, ptrdiff_t);
813 static bool cursor_row_p (struct glyph_row *);
814 static int redisplay_mode_lines (Lisp_Object, bool);
816 static void handle_line_prefix (struct it *);
818 static void handle_stop_backwards (struct it *, ptrdiff_t);
819 static void unwind_with_echo_area_buffer (Lisp_Object);
820 static Lisp_Object with_echo_area_buffer_unwind_data (struct window *);
821 static bool current_message_1 (ptrdiff_t, Lisp_Object);
822 static bool truncate_message_1 (ptrdiff_t, Lisp_Object);
823 static void set_message (Lisp_Object);
824 static bool set_message_1 (ptrdiff_t, Lisp_Object);
825 static bool display_echo_area_1 (ptrdiff_t, Lisp_Object);
826 static bool resize_mini_window_1 (ptrdiff_t, Lisp_Object);
827 static void unwind_redisplay (void);
828 static void extend_face_to_end_of_line (struct it *);
829 static intmax_t message_log_check_duplicate (ptrdiff_t, ptrdiff_t);
830 static void push_it (struct it *, struct text_pos *);
831 static void iterate_out_of_display_property (struct it *);
832 static void pop_it (struct it *);
833 static void redisplay_internal (void);
834 static void echo_area_display (bool);
835 static void block_buffer_flips (void);
836 static void unblock_buffer_flips (void);
837 static void redisplay_windows (Lisp_Object);
838 static void redisplay_window (Lisp_Object, bool);
839 static Lisp_Object redisplay_window_error (Lisp_Object);
840 static Lisp_Object redisplay_window_0 (Lisp_Object);
841 static Lisp_Object redisplay_window_1 (Lisp_Object);
842 static bool set_cursor_from_row (struct window *, struct glyph_row *,
843 struct glyph_matrix *, ptrdiff_t, ptrdiff_t,
844 int, int);
845 static bool cursor_row_fully_visible_p (struct window *, bool, bool);
846 static bool update_menu_bar (struct frame *, bool, bool);
847 static bool try_window_reusing_current_matrix (struct window *);
848 static int try_window_id (struct window *);
849 static void maybe_produce_line_number (struct it *);
850 static bool should_produce_line_number (struct it *);
851 static bool display_line (struct it *, int);
852 static int display_mode_lines (struct window *);
853 static int display_mode_line (struct window *, enum face_id, Lisp_Object);
854 static int display_mode_element (struct it *, int, int, int, Lisp_Object,
855 Lisp_Object, bool);
856 static int store_mode_line_string (const char *, Lisp_Object, bool, int, int,
857 Lisp_Object);
858 static const char *decode_mode_spec (struct window *, int, int, Lisp_Object *);
859 static void display_menu_bar (struct window *);
860 static ptrdiff_t display_count_lines (ptrdiff_t, ptrdiff_t, ptrdiff_t,
861 ptrdiff_t *);
862 static void pint2str (register char *, register int, register ptrdiff_t);
864 static int display_string (const char *, Lisp_Object, Lisp_Object,
865 ptrdiff_t, ptrdiff_t, struct it *, int, int, int, int);
866 static void compute_line_metrics (struct it *);
867 static void run_redisplay_end_trigger_hook (struct it *);
868 static bool get_overlay_strings (struct it *, ptrdiff_t);
869 static bool get_overlay_strings_1 (struct it *, ptrdiff_t, bool);
870 static void next_overlay_string (struct it *);
871 static void reseat (struct it *, struct text_pos, bool);
872 static void reseat_1 (struct it *, struct text_pos, bool);
873 static bool next_element_from_display_vector (struct it *);
874 static bool next_element_from_string (struct it *);
875 static bool next_element_from_c_string (struct it *);
876 static bool next_element_from_buffer (struct it *);
877 static bool next_element_from_composition (struct it *);
878 static bool next_element_from_image (struct it *);
879 static bool next_element_from_stretch (struct it *);
880 static bool next_element_from_xwidget (struct it *);
881 static void load_overlay_strings (struct it *, ptrdiff_t);
882 static bool get_next_display_element (struct it *);
883 static enum move_it_result
884 move_it_in_display_line_to (struct it *, ptrdiff_t, int,
885 enum move_operation_enum);
886 static void get_visually_first_element (struct it *);
887 static void compute_stop_pos (struct it *);
888 static int face_before_or_after_it_pos (struct it *, bool);
889 static ptrdiff_t next_overlay_change (ptrdiff_t);
890 static int handle_display_spec (struct it *, Lisp_Object, Lisp_Object,
891 Lisp_Object, struct text_pos *, ptrdiff_t, bool);
892 static int handle_single_display_spec (struct it *, Lisp_Object, Lisp_Object,
893 Lisp_Object, struct text_pos *,
894 ptrdiff_t, int, bool, bool);
895 static int underlying_face_id (struct it *);
897 #define face_before_it_pos(IT) face_before_or_after_it_pos (IT, true)
898 #define face_after_it_pos(IT) face_before_or_after_it_pos (IT, false)
900 #ifdef HAVE_WINDOW_SYSTEM
902 static void update_tool_bar (struct frame *, bool);
903 static void x_draw_bottom_divider (struct window *w);
904 static void notice_overwritten_cursor (struct window *,
905 enum glyph_row_area,
906 int, int, int, int);
907 static int normal_char_height (struct font *, int);
908 static void normal_char_ascent_descent (struct font *, int, int *, int *);
910 static void append_stretch_glyph (struct it *, Lisp_Object,
911 int, int, int);
913 static Lisp_Object get_it_property (struct it *, Lisp_Object);
914 static Lisp_Object calc_line_height_property (struct it *, Lisp_Object,
915 struct font *, int, bool);
917 #endif /* HAVE_WINDOW_SYSTEM */
919 static void produce_special_glyphs (struct it *, enum display_element_type);
920 static void show_mouse_face (Mouse_HLInfo *, enum draw_glyphs_face);
921 static bool coords_in_mouse_face_p (struct window *, int, int);
925 /***********************************************************************
926 Window display dimensions
927 ***********************************************************************/
929 /* Return the bottom boundary y-position for text lines in window W.
930 This is the first y position at which a line cannot start.
931 It is relative to the top of the window.
933 This is the height of W minus the height of a mode line, if any. */
936 window_text_bottom_y (struct window *w)
938 int height = WINDOW_PIXEL_HEIGHT (w);
940 height -= WINDOW_BOTTOM_DIVIDER_WIDTH (w);
942 if (window_wants_mode_line (w))
943 height -= CURRENT_MODE_LINE_HEIGHT (w);
945 height -= WINDOW_SCROLL_BAR_AREA_HEIGHT (w);
947 return height;
950 /* Return the pixel width of display area AREA of window W.
951 ANY_AREA means return the total width of W, not including
952 fringes to the left and right of the window. */
955 window_box_width (struct window *w, enum glyph_row_area area)
957 int width = w->pixel_width;
959 if (!w->pseudo_window_p)
961 width -= WINDOW_SCROLL_BAR_AREA_WIDTH (w);
962 width -= WINDOW_RIGHT_DIVIDER_WIDTH (w);
964 if (area == TEXT_AREA)
965 width -= (WINDOW_MARGINS_WIDTH (w)
966 + WINDOW_FRINGES_WIDTH (w));
967 else if (area == LEFT_MARGIN_AREA)
968 width = WINDOW_LEFT_MARGIN_WIDTH (w);
969 else if (area == RIGHT_MARGIN_AREA)
970 width = WINDOW_RIGHT_MARGIN_WIDTH (w);
973 /* With wide margins, fringes, etc. we might end up with a negative
974 width, correct that here. */
975 return max (0, width);
979 /* Return the pixel height of the display area of window W, not
980 including mode lines of W, if any. */
983 window_box_height (struct window *w)
985 struct frame *f = XFRAME (w->frame);
986 int height = WINDOW_PIXEL_HEIGHT (w);
988 eassert (height >= 0);
990 height -= WINDOW_BOTTOM_DIVIDER_WIDTH (w);
991 height -= WINDOW_SCROLL_BAR_AREA_HEIGHT (w);
993 /* Note: the code below that determines the mode-line/header-line
994 height is essentially the same as that contained in the macro
995 CURRENT_{MODE,HEADER}_LINE_HEIGHT, except that it checks whether
996 the appropriate glyph row has its `mode_line_p' flag set,
997 and if it doesn't, uses estimate_mode_line_height instead. */
999 if (window_wants_mode_line (w))
1001 struct glyph_row *ml_row
1002 = (w->current_matrix && w->current_matrix->rows
1003 ? MATRIX_MODE_LINE_ROW (w->current_matrix)
1004 : 0);
1005 if (ml_row && ml_row->mode_line_p)
1006 height -= ml_row->height;
1007 else
1008 height -= estimate_mode_line_height (f, CURRENT_MODE_LINE_FACE_ID (w));
1011 if (window_wants_header_line (w))
1013 struct glyph_row *hl_row
1014 = (w->current_matrix && w->current_matrix->rows
1015 ? MATRIX_HEADER_LINE_ROW (w->current_matrix)
1016 : 0);
1017 if (hl_row && hl_row->mode_line_p)
1018 height -= hl_row->height;
1019 else
1020 height -= estimate_mode_line_height (f, HEADER_LINE_FACE_ID);
1023 /* With a very small font and a mode-line that's taller than
1024 default, we might end up with a negative height. */
1025 return max (0, height);
1028 /* Return the window-relative coordinate of the left edge of display
1029 area AREA of window W. ANY_AREA means return the left edge of the
1030 whole window, to the right of the left fringe of W. */
1033 window_box_left_offset (struct window *w, enum glyph_row_area area)
1035 int x;
1037 if (w->pseudo_window_p)
1038 return 0;
1040 x = WINDOW_LEFT_SCROLL_BAR_AREA_WIDTH (w);
1042 if (area == TEXT_AREA)
1043 x += (WINDOW_LEFT_FRINGE_WIDTH (w)
1044 + window_box_width (w, LEFT_MARGIN_AREA));
1045 else if (area == RIGHT_MARGIN_AREA)
1046 x += (WINDOW_LEFT_FRINGE_WIDTH (w)
1047 + window_box_width (w, LEFT_MARGIN_AREA)
1048 + window_box_width (w, TEXT_AREA)
1049 + (WINDOW_HAS_FRINGES_OUTSIDE_MARGINS (w)
1051 : WINDOW_RIGHT_FRINGE_WIDTH (w)));
1052 else if (area == LEFT_MARGIN_AREA
1053 && WINDOW_HAS_FRINGES_OUTSIDE_MARGINS (w))
1054 x += WINDOW_LEFT_FRINGE_WIDTH (w);
1056 /* Don't return more than the window's pixel width. */
1057 return min (x, w->pixel_width);
1061 /* Return the window-relative coordinate of the right edge of display
1062 area AREA of window W. ANY_AREA means return the right edge of the
1063 whole window, to the left of the right fringe of W. */
1065 static int
1066 window_box_right_offset (struct window *w, enum glyph_row_area area)
1068 /* Don't return more than the window's pixel width. */
1069 return min (window_box_left_offset (w, area) + window_box_width (w, area),
1070 w->pixel_width);
1073 /* Return the frame-relative coordinate of the left edge of display
1074 area AREA of window W. ANY_AREA means return the left edge of the
1075 whole window, to the right of the left fringe of W. */
1078 window_box_left (struct window *w, enum glyph_row_area area)
1080 struct frame *f = XFRAME (w->frame);
1081 int x;
1083 if (w->pseudo_window_p)
1084 return FRAME_INTERNAL_BORDER_WIDTH (f);
1086 x = (WINDOW_LEFT_EDGE_X (w)
1087 + window_box_left_offset (w, area));
1089 return x;
1093 /* Return the frame-relative coordinate of the right edge of display
1094 area AREA of window W. ANY_AREA means return the right edge of the
1095 whole window, to the left of the right fringe of W. */
1098 window_box_right (struct window *w, enum glyph_row_area area)
1100 return window_box_left (w, area) + window_box_width (w, area);
1103 /* Get the bounding box of the display area AREA of window W, without
1104 mode lines, in frame-relative coordinates. ANY_AREA means the
1105 whole window, not including the left and right fringes of
1106 the window. Return in *BOX_X and *BOX_Y the frame-relative pixel
1107 coordinates of the upper-left corner of the box. Return in
1108 *BOX_WIDTH, and *BOX_HEIGHT the pixel width and height of the box. */
1110 void
1111 window_box (struct window *w, enum glyph_row_area area, int *box_x,
1112 int *box_y, int *box_width, int *box_height)
1114 if (box_width)
1115 *box_width = window_box_width (w, area);
1116 if (box_height)
1117 *box_height = window_box_height (w);
1118 if (box_x)
1119 *box_x = window_box_left (w, area);
1120 if (box_y)
1122 *box_y = WINDOW_TOP_EDGE_Y (w);
1123 if (window_wants_header_line (w))
1124 *box_y += CURRENT_HEADER_LINE_HEIGHT (w);
1128 #ifdef HAVE_WINDOW_SYSTEM
1130 /* Get the bounding box of the display area AREA of window W, without
1131 mode lines and both fringes of the window. Return in *TOP_LEFT_X
1132 and TOP_LEFT_Y the frame-relative pixel coordinates of the
1133 upper-left corner of the box. Return in *BOTTOM_RIGHT_X, and
1134 *BOTTOM_RIGHT_Y the coordinates of the bottom-right corner of the
1135 box. */
1137 static void
1138 window_box_edges (struct window *w, int *top_left_x, int *top_left_y,
1139 int *bottom_right_x, int *bottom_right_y)
1141 window_box (w, ANY_AREA, top_left_x, top_left_y,
1142 bottom_right_x, bottom_right_y);
1143 *bottom_right_x += *top_left_x;
1144 *bottom_right_y += *top_left_y;
1147 #endif /* HAVE_WINDOW_SYSTEM */
1149 /***********************************************************************
1150 Utilities
1151 ***********************************************************************/
1153 /* Return the bottom y-position of the line the iterator IT is in.
1154 This can modify IT's settings. */
1157 line_bottom_y (struct it *it)
1159 int line_height = it->max_ascent + it->max_descent;
1160 int line_top_y = it->current_y;
1162 if (line_height == 0)
1164 if (last_height)
1165 line_height = last_height;
1166 else if (IT_CHARPOS (*it) < ZV)
1168 move_it_by_lines (it, 1);
1169 line_height = (it->max_ascent || it->max_descent
1170 ? it->max_ascent + it->max_descent
1171 : last_height);
1173 else
1175 struct glyph_row *row = it->glyph_row;
1177 /* Use the default character height. */
1178 it->glyph_row = NULL;
1179 it->what = IT_CHARACTER;
1180 it->c = ' ';
1181 it->len = 1;
1182 PRODUCE_GLYPHS (it);
1183 line_height = it->ascent + it->descent;
1184 it->glyph_row = row;
1188 return line_top_y + line_height;
1191 DEFUN ("line-pixel-height", Fline_pixel_height,
1192 Sline_pixel_height, 0, 0, 0,
1193 doc: /* Return height in pixels of text line in the selected window.
1195 Value is the height in pixels of the line at point. */)
1196 (void)
1198 struct it it;
1199 struct text_pos pt;
1200 struct window *w = XWINDOW (selected_window);
1201 struct buffer *old_buffer = NULL;
1202 Lisp_Object result;
1204 if (XBUFFER (w->contents) != current_buffer)
1206 old_buffer = current_buffer;
1207 set_buffer_internal_1 (XBUFFER (w->contents));
1209 SET_TEXT_POS (pt, PT, PT_BYTE);
1210 start_display (&it, w, pt);
1211 /* Start from the beginning of the screen line, to make sure we
1212 traverse all of its display elements, and thus capture the
1213 correct metrics. */
1214 move_it_by_lines (&it, 0);
1215 it.vpos = it.current_y = 0;
1216 last_height = 0;
1217 result = make_number (line_bottom_y (&it));
1218 if (old_buffer)
1219 set_buffer_internal_1 (old_buffer);
1221 return result;
1224 /* Return the default pixel height of text lines in window W. The
1225 value is the canonical height of the W frame's default font, plus
1226 any extra space required by the line-spacing variable or frame
1227 parameter.
1229 Implementation note: this ignores any line-spacing text properties
1230 put on the newline characters. This is because those properties
1231 only affect the _screen_ line ending in the newline (i.e., in a
1232 continued line, only the last screen line will be affected), which
1233 means only a small number of lines in a buffer can ever use this
1234 feature. Since this function is used to compute the default pixel
1235 equivalent of text lines in a window, we can safely ignore those
1236 few lines. For the same reasons, we ignore the line-height
1237 properties. */
1239 default_line_pixel_height (struct window *w)
1241 struct frame *f = WINDOW_XFRAME (w);
1242 int height = FRAME_LINE_HEIGHT (f);
1244 if (!FRAME_INITIAL_P (f) && BUFFERP (w->contents))
1246 struct buffer *b = XBUFFER (w->contents);
1247 Lisp_Object val = BVAR (b, extra_line_spacing);
1249 if (NILP (val))
1250 val = BVAR (&buffer_defaults, extra_line_spacing);
1251 if (!NILP (val))
1253 if (RANGED_INTEGERP (0, val, INT_MAX))
1254 height += XFASTINT (val);
1255 else if (FLOATP (val))
1257 int addon = XFLOAT_DATA (val) * height + 0.5;
1259 if (addon >= 0)
1260 height += addon;
1263 else
1264 height += f->extra_line_spacing;
1267 return height;
1270 /* Subroutine of pos_visible_p below. Extracts a display string, if
1271 any, from the display spec given as its argument. */
1272 static Lisp_Object
1273 string_from_display_spec (Lisp_Object spec)
1275 if (VECTORP (spec))
1277 for (ptrdiff_t i = 0; i < ASIZE (spec); i++)
1278 if (STRINGP (AREF (spec, i)))
1279 return AREF (spec, i);
1281 else
1283 for (; CONSP (spec); spec = XCDR (spec))
1284 if (STRINGP (XCAR (spec)))
1285 return XCAR (spec);
1287 return spec;
1291 /* Limit insanely large values of W->hscroll on frame F to the largest
1292 value that will still prevent first_visible_x and last_visible_x of
1293 'struct it' from overflowing an int. */
1294 static int
1295 window_hscroll_limited (struct window *w, struct frame *f)
1297 ptrdiff_t window_hscroll = w->hscroll;
1298 int window_text_width = window_box_width (w, TEXT_AREA);
1299 int colwidth = FRAME_COLUMN_WIDTH (f);
1301 if (window_hscroll > (INT_MAX - window_text_width) / colwidth - 1)
1302 window_hscroll = (INT_MAX - window_text_width) / colwidth - 1;
1304 return window_hscroll;
1307 /* Return true if position CHARPOS is visible in window W.
1308 CHARPOS < 0 means return info about WINDOW_END position.
1309 If visible, set *X and *Y to pixel coordinates of top left corner.
1310 Set *RTOP and *RBOT to pixel height of an invisible area of glyph at POS.
1311 Set *ROWH and *VPOS to row's visible height and VPOS (row number). */
1313 bool
1314 pos_visible_p (struct window *w, ptrdiff_t charpos, int *x, int *y,
1315 int *rtop, int *rbot, int *rowh, int *vpos)
1317 struct it it;
1318 void *itdata = bidi_shelve_cache ();
1319 struct text_pos top;
1320 bool visible_p = false;
1321 struct buffer *old_buffer = NULL;
1322 bool r2l = false;
1324 if (FRAME_INITIAL_P (XFRAME (WINDOW_FRAME (w))))
1325 return visible_p;
1327 if (XBUFFER (w->contents) != current_buffer)
1329 old_buffer = current_buffer;
1330 set_buffer_internal_1 (XBUFFER (w->contents));
1333 SET_TEXT_POS_FROM_MARKER (top, w->start);
1334 /* Scrolling a minibuffer window via scroll bar when the echo area
1335 shows long text sometimes resets the minibuffer contents behind
1336 our backs. Also, someone might narrow-to-region and immediately
1337 call a scroll function. */
1338 if (CHARPOS (top) > ZV || CHARPOS (top) < BEGV)
1339 SET_TEXT_POS (top, BEGV, BEGV_BYTE);
1341 /* If the top of the window is after CHARPOS, the latter is surely
1342 not visible. */
1343 if (charpos >= 0 && CHARPOS (top) > charpos)
1344 return visible_p;
1346 /* Some Lisp hook could call us in the middle of redisplaying this
1347 very window. If, by some bad luck, we are retrying redisplay
1348 because we found that the mode-line height and/or header-line
1349 height needs to be updated, the assignment of mode_line_height
1350 and header_line_height below could disrupt that, due to the
1351 selected/nonselected window dance during mode-line display, and
1352 we could infloop. Avoid that. */
1353 int prev_mode_line_height = w->mode_line_height;
1354 int prev_header_line_height = w->header_line_height;
1355 /* Compute exact mode line heights. */
1356 if (window_wants_mode_line (w))
1358 Lisp_Object window_mode_line_format
1359 = window_parameter (w, Qmode_line_format);
1361 w->mode_line_height
1362 = display_mode_line (w, CURRENT_MODE_LINE_FACE_ID (w),
1363 NILP (window_mode_line_format)
1364 ? BVAR (current_buffer, mode_line_format)
1365 : window_mode_line_format);
1368 if (window_wants_header_line (w))
1370 Lisp_Object window_header_line_format
1371 = window_parameter (w, Qheader_line_format);
1373 w->header_line_height
1374 = display_mode_line (w, HEADER_LINE_FACE_ID,
1375 NILP (window_header_line_format)
1376 ? BVAR (current_buffer, header_line_format)
1377 : window_header_line_format);
1380 start_display (&it, w, top);
1381 move_it_to (&it, charpos, -1, it.last_visible_y - 1, -1,
1382 (charpos >= 0 ? MOVE_TO_POS : 0) | MOVE_TO_Y);
1384 /* Adjust for line numbers, if CHARPOS is at or beyond first_visible_x,
1385 but we didn't yet produce the line-number glyphs. */
1386 if (!NILP (Vdisplay_line_numbers)
1387 && it.current_x >= it.first_visible_x
1388 && IT_CHARPOS (it) == charpos
1389 && !it.line_number_produced_p)
1391 /* If the pixel width of line numbers was not yet known, compute
1392 it now. This usually happens in the first display line of a
1393 window. */
1394 if (!it.lnum_pixel_width)
1396 struct it it2;
1397 void *it2data = NULL;
1399 SAVE_IT (it2, it, it2data);
1400 move_it_by_lines (&it, 1);
1401 it2.lnum_pixel_width = it.lnum_pixel_width;
1402 RESTORE_IT (&it, &it2, it2data);
1404 it.current_x += it.lnum_pixel_width;
1407 if (charpos >= 0
1408 && (((!it.bidi_p || it.bidi_it.scan_dir != -1)
1409 && IT_CHARPOS (it) >= charpos)
1410 /* When scanning backwards under bidi iteration, move_it_to
1411 stops at or _before_ CHARPOS, because it stops at or to
1412 the _right_ of the character at CHARPOS. */
1413 || (it.bidi_p && it.bidi_it.scan_dir == -1
1414 && IT_CHARPOS (it) <= charpos)))
1416 /* We have reached CHARPOS, or passed it. How the call to
1417 move_it_to can overshoot: (i) If CHARPOS is on invisible text
1418 or covered by a display property, move_it_to stops at the end
1419 of the invisible text, to the right of CHARPOS. (ii) If
1420 CHARPOS is in a display vector, move_it_to stops on its last
1421 glyph. */
1422 int top_x = it.current_x;
1423 int top_y = it.current_y;
1424 int window_top_y = WINDOW_HEADER_LINE_HEIGHT (w);
1425 int bottom_y;
1426 struct it save_it;
1427 void *save_it_data = NULL;
1429 /* Calling line_bottom_y may change it.method, it.position, etc. */
1430 SAVE_IT (save_it, it, save_it_data);
1431 last_height = 0;
1432 bottom_y = line_bottom_y (&it);
1433 if (top_y < window_top_y)
1434 visible_p = bottom_y > window_top_y;
1435 else if (top_y < it.last_visible_y)
1436 visible_p = true;
1437 if (bottom_y >= it.last_visible_y
1438 && it.bidi_p && it.bidi_it.scan_dir == -1
1439 && IT_CHARPOS (it) < charpos)
1441 /* When the last line of the window is scanned backwards
1442 under bidi iteration, we could be duped into thinking
1443 that we have passed CHARPOS, when in fact move_it_to
1444 simply stopped short of CHARPOS because it reached
1445 last_visible_y. To see if that's what happened, we call
1446 move_it_to again with a slightly larger vertical limit,
1447 and see if it actually moved vertically; if it did, we
1448 didn't really reach CHARPOS, which is beyond window end. */
1449 /* Why 10? because we don't know how many canonical lines
1450 will the height of the next line(s) be. So we guess. */
1451 int ten_more_lines = 10 * default_line_pixel_height (w);
1453 move_it_to (&it, charpos, -1, bottom_y + ten_more_lines, -1,
1454 MOVE_TO_POS | MOVE_TO_Y);
1455 if (it.current_y > top_y)
1456 visible_p = false;
1459 RESTORE_IT (&it, &save_it, save_it_data);
1460 if (visible_p)
1462 if (it.method == GET_FROM_DISPLAY_VECTOR)
1464 /* We stopped on the last glyph of a display vector.
1465 Try and recompute. Hack alert! */
1466 if (charpos < 2 || top.charpos >= charpos)
1467 top_x = it.glyph_row->x;
1468 else
1470 struct it it2, it2_prev;
1471 /* The idea is to get to the previous buffer
1472 position, consume the character there, and use
1473 the pixel coordinates we get after that. But if
1474 the previous buffer position is also displayed
1475 from a display vector, we need to consume all of
1476 the glyphs from that display vector. */
1477 start_display (&it2, w, top);
1478 move_it_to (&it2, charpos - 1, -1, -1, -1, MOVE_TO_POS);
1479 /* If we didn't get to CHARPOS - 1, there's some
1480 replacing display property at that position, and
1481 we stopped after it. That is exactly the place
1482 whose coordinates we want. */
1483 if (IT_CHARPOS (it2) != charpos - 1)
1484 it2_prev = it2;
1485 else
1487 /* Iterate until we get out of the display
1488 vector that displays the character at
1489 CHARPOS - 1. */
1490 do {
1491 get_next_display_element (&it2);
1492 PRODUCE_GLYPHS (&it2);
1493 it2_prev = it2;
1494 set_iterator_to_next (&it2, true);
1495 } while (it2.method == GET_FROM_DISPLAY_VECTOR
1496 && IT_CHARPOS (it2) < charpos);
1498 if (ITERATOR_AT_END_OF_LINE_P (&it2_prev)
1499 || it2_prev.current_x > it2_prev.last_visible_x)
1500 top_x = it.glyph_row->x;
1501 else
1503 top_x = it2_prev.current_x;
1504 top_y = it2_prev.current_y;
1508 else if (IT_CHARPOS (it) != charpos)
1510 Lisp_Object cpos = make_number (charpos);
1511 Lisp_Object spec = Fget_char_property (cpos, Qdisplay, Qnil);
1512 Lisp_Object string = string_from_display_spec (spec);
1513 struct text_pos tpos;
1514 bool newline_in_string
1515 = (STRINGP (string)
1516 && memchr (SDATA (string), '\n', SBYTES (string)));
1518 SET_TEXT_POS (tpos, charpos, CHAR_TO_BYTE (charpos));
1519 bool replacing_spec_p
1520 = (!NILP (spec)
1521 && handle_display_spec (NULL, spec, Qnil, Qnil, &tpos,
1522 charpos, FRAME_WINDOW_P (it.f)));
1523 /* The tricky code below is needed because there's a
1524 discrepancy between move_it_to and how we set cursor
1525 when PT is at the beginning of a portion of text
1526 covered by a display property or an overlay with a
1527 display property, or the display line ends in a
1528 newline from a display string. move_it_to will stop
1529 _after_ such display strings, whereas
1530 set_cursor_from_row conspires with cursor_row_p to
1531 place the cursor on the first glyph produced from the
1532 display string. */
1534 /* We have overshoot PT because it is covered by a
1535 display property that replaces the text it covers.
1536 If the string includes embedded newlines, we are also
1537 in the wrong display line. Backtrack to the correct
1538 line, where the display property begins. */
1539 if (replacing_spec_p)
1541 Lisp_Object startpos, endpos;
1542 EMACS_INT start, end;
1543 struct it it3;
1545 /* Find the first and the last buffer positions
1546 covered by the display string. */
1547 endpos =
1548 Fnext_single_char_property_change (cpos, Qdisplay,
1549 Qnil, Qnil);
1550 startpos =
1551 Fprevious_single_char_property_change (endpos, Qdisplay,
1552 Qnil, Qnil);
1553 start = XFASTINT (startpos);
1554 end = XFASTINT (endpos);
1555 /* Move to the last buffer position before the
1556 display property. */
1557 start_display (&it3, w, top);
1558 if (start > CHARPOS (top))
1559 move_it_to (&it3, start - 1, -1, -1, -1, MOVE_TO_POS);
1560 /* Move forward one more line if the position before
1561 the display string is a newline or if it is the
1562 rightmost character on a line that is
1563 continued or word-wrapped. */
1564 if (it3.method == GET_FROM_BUFFER
1565 && (it3.c == '\n'
1566 || FETCH_BYTE (IT_BYTEPOS (it3)) == '\n'))
1567 move_it_by_lines (&it3, 1);
1568 else if (move_it_in_display_line_to (&it3, -1,
1569 it3.current_x
1570 + it3.pixel_width,
1571 MOVE_TO_X)
1572 == MOVE_LINE_CONTINUED)
1574 move_it_by_lines (&it3, 1);
1575 /* When we are under word-wrap, the #$@%!
1576 move_it_by_lines moves 2 lines, so we need to
1577 fix that up. */
1578 if (it3.line_wrap == WORD_WRAP)
1579 move_it_by_lines (&it3, -1);
1582 /* Record the vertical coordinate of the display
1583 line where we wound up. */
1584 top_y = it3.current_y;
1585 if (it3.bidi_p)
1587 /* When characters are reordered for display,
1588 the character displayed to the left of the
1589 display string could be _after_ the display
1590 property in the logical order. Use the
1591 smallest vertical position of these two. */
1592 start_display (&it3, w, top);
1593 move_it_to (&it3, end + 1, -1, -1, -1, MOVE_TO_POS);
1594 if (it3.current_y < top_y)
1595 top_y = it3.current_y;
1597 /* Move from the top of the window to the beginning
1598 of the display line where the display string
1599 begins. */
1600 start_display (&it3, w, top);
1601 move_it_to (&it3, -1, 0, top_y, -1, MOVE_TO_X | MOVE_TO_Y);
1602 /* If it3_moved stays false after the 'while' loop
1603 below, that means we already were at a newline
1604 before the loop (e.g., the display string begins
1605 with a newline), so we don't need to (and cannot)
1606 inspect the glyphs of it3.glyph_row, because
1607 PRODUCE_GLYPHS will not produce anything for a
1608 newline, and thus it3.glyph_row stays at its
1609 stale content it got at top of the window. */
1610 bool it3_moved = false;
1611 /* Finally, advance the iterator until we hit the
1612 first display element whose character position is
1613 CHARPOS, or until the first newline from the
1614 display string, which signals the end of the
1615 display line. */
1616 while (get_next_display_element (&it3))
1618 PRODUCE_GLYPHS (&it3);
1619 if (IT_CHARPOS (it3) == charpos
1620 || ITERATOR_AT_END_OF_LINE_P (&it3))
1621 break;
1622 it3_moved = true;
1623 set_iterator_to_next (&it3, false);
1625 top_x = it3.current_x - it3.pixel_width;
1626 /* Normally, we would exit the above loop because we
1627 found the display element whose character
1628 position is CHARPOS. For the contingency that we
1629 didn't, and stopped at the first newline from the
1630 display string, move back over the glyphs
1631 produced from the string, until we find the
1632 rightmost glyph not from the string. */
1633 if (it3_moved
1634 && newline_in_string
1635 && IT_CHARPOS (it3) != charpos && EQ (it3.object, string))
1637 struct glyph *g = it3.glyph_row->glyphs[TEXT_AREA]
1638 + it3.glyph_row->used[TEXT_AREA];
1640 while (EQ ((g - 1)->object, string))
1642 --g;
1643 top_x -= g->pixel_width;
1645 eassert (g < it3.glyph_row->glyphs[TEXT_AREA]
1646 + it3.glyph_row->used[TEXT_AREA]);
1651 *x = top_x;
1652 *y = max (top_y + max (0, it.max_ascent - it.ascent), window_top_y);
1653 *rtop = max (0, window_top_y - top_y);
1654 *rbot = max (0, bottom_y - it.last_visible_y);
1655 *rowh = max (0, (min (bottom_y, it.last_visible_y)
1656 - max (top_y, window_top_y)));
1657 *vpos = it.vpos;
1658 if (it.bidi_it.paragraph_dir == R2L)
1659 r2l = true;
1662 else
1664 /* Either we were asked to provide info about WINDOW_END, or
1665 CHARPOS is in the partially visible glyph row at end of
1666 window. */
1667 struct it it2;
1668 void *it2data = NULL;
1670 SAVE_IT (it2, it, it2data);
1671 if (IT_CHARPOS (it) < ZV && FETCH_BYTE (IT_BYTEPOS (it)) != '\n')
1672 move_it_by_lines (&it, 1);
1673 if (charpos < IT_CHARPOS (it)
1674 || (it.what == IT_EOB && charpos == IT_CHARPOS (it)))
1676 visible_p = true;
1677 RESTORE_IT (&it2, &it2, it2data);
1678 move_it_to (&it2, charpos, -1, -1, -1, MOVE_TO_POS);
1679 *x = it2.current_x;
1680 *y = it2.current_y + it2.max_ascent - it2.ascent;
1681 *rtop = max (0, -it2.current_y);
1682 *rbot = max (0, ((it2.current_y + it2.max_ascent + it2.max_descent)
1683 - it.last_visible_y));
1684 *rowh = max (0, (min (it2.current_y + it2.max_ascent + it2.max_descent,
1685 it.last_visible_y)
1686 - max (it2.current_y,
1687 WINDOW_HEADER_LINE_HEIGHT (w))));
1688 *vpos = it2.vpos;
1689 if (it2.bidi_it.paragraph_dir == R2L)
1690 r2l = true;
1692 else
1693 bidi_unshelve_cache (it2data, true);
1695 bidi_unshelve_cache (itdata, false);
1697 if (old_buffer)
1698 set_buffer_internal_1 (old_buffer);
1700 if (visible_p)
1702 if (w->hscroll > 0)
1703 *x -=
1704 window_hscroll_limited (w, WINDOW_XFRAME (w))
1705 * WINDOW_FRAME_COLUMN_WIDTH (w);
1706 /* For lines in an R2L paragraph, we need to mirror the X pixel
1707 coordinate wrt the text area. For the reasons, see the
1708 commentary in buffer_posn_from_coords and the explanation of
1709 the geometry used by the move_it_* functions at the end of
1710 the large commentary near the beginning of this file. */
1711 if (r2l)
1712 *x = window_box_width (w, TEXT_AREA) - *x - 1;
1715 #if false
1716 /* Debugging code. */
1717 if (visible_p)
1718 fprintf (stderr, "+pv pt=%d vs=%d --> x=%d y=%d rt=%d rb=%d rh=%d vp=%d\n",
1719 charpos, w->vscroll, *x, *y, *rtop, *rbot, *rowh, *vpos);
1720 else
1721 fprintf (stderr, "-pv pt=%d vs=%d\n", charpos, w->vscroll);
1722 #endif
1724 /* Restore potentially overwritten values. */
1725 w->mode_line_height = prev_mode_line_height;
1726 w->header_line_height = prev_header_line_height;
1728 return visible_p;
1732 /* Return the next character from STR. Return in *LEN the length of
1733 the character. This is like STRING_CHAR_AND_LENGTH but never
1734 returns an invalid character. If we find one, we return a `?', but
1735 with the length of the invalid character. */
1737 static int
1738 string_char_and_length (const unsigned char *str, int *len)
1740 int c;
1742 c = STRING_CHAR_AND_LENGTH (str, *len);
1743 if (!CHAR_VALID_P (c))
1744 /* We may not change the length here because other places in Emacs
1745 don't use this function, i.e. they silently accept invalid
1746 characters. */
1747 c = '?';
1749 return c;
1754 /* Given a position POS containing a valid character and byte position
1755 in STRING, return the position NCHARS ahead (NCHARS >= 0). */
1757 static struct text_pos
1758 string_pos_nchars_ahead (struct text_pos pos, Lisp_Object string, ptrdiff_t nchars)
1760 eassert (STRINGP (string) && nchars >= 0);
1762 if (STRING_MULTIBYTE (string))
1764 const unsigned char *p = SDATA (string) + BYTEPOS (pos);
1765 int len;
1767 while (nchars--)
1769 string_char_and_length (p, &len);
1770 p += len;
1771 CHARPOS (pos) += 1;
1772 BYTEPOS (pos) += len;
1775 else
1776 SET_TEXT_POS (pos, CHARPOS (pos) + nchars, BYTEPOS (pos) + nchars);
1778 return pos;
1782 /* Value is the text position, i.e. character and byte position,
1783 for character position CHARPOS in STRING. */
1785 static struct text_pos
1786 string_pos (ptrdiff_t charpos, Lisp_Object string)
1788 struct text_pos pos;
1789 eassert (STRINGP (string));
1790 eassert (charpos >= 0);
1791 SET_TEXT_POS (pos, charpos, string_char_to_byte (string, charpos));
1792 return pos;
1796 /* Value is a text position, i.e. character and byte position, for
1797 character position CHARPOS in C string S. MULTIBYTE_P
1798 means recognize multibyte characters. */
1800 static struct text_pos
1801 c_string_pos (ptrdiff_t charpos, const char *s, bool multibyte_p)
1803 struct text_pos pos;
1805 eassert (s != NULL);
1806 eassert (charpos >= 0);
1808 if (multibyte_p)
1810 int len;
1812 SET_TEXT_POS (pos, 0, 0);
1813 while (charpos--)
1815 string_char_and_length ((const unsigned char *) s, &len);
1816 s += len;
1817 CHARPOS (pos) += 1;
1818 BYTEPOS (pos) += len;
1821 else
1822 SET_TEXT_POS (pos, charpos, charpos);
1824 return pos;
1828 /* Value is the number of characters in C string S. MULTIBYTE_P
1829 means recognize multibyte characters. */
1831 static ptrdiff_t
1832 number_of_chars (const char *s, bool multibyte_p)
1834 ptrdiff_t nchars;
1836 if (multibyte_p)
1838 ptrdiff_t rest = strlen (s);
1839 int len;
1840 const unsigned char *p = (const unsigned char *) s;
1842 for (nchars = 0; rest > 0; ++nchars)
1844 string_char_and_length (p, &len);
1845 rest -= len, p += len;
1848 else
1849 nchars = strlen (s);
1851 return nchars;
1855 /* Compute byte position NEWPOS->bytepos corresponding to
1856 NEWPOS->charpos. POS is a known position in string STRING.
1857 NEWPOS->charpos must be >= POS.charpos. */
1859 static void
1860 compute_string_pos (struct text_pos *newpos, struct text_pos pos, Lisp_Object string)
1862 eassert (STRINGP (string));
1863 eassert (CHARPOS (*newpos) >= CHARPOS (pos));
1865 if (STRING_MULTIBYTE (string))
1866 *newpos = string_pos_nchars_ahead (pos, string,
1867 CHARPOS (*newpos) - CHARPOS (pos));
1868 else
1869 BYTEPOS (*newpos) = CHARPOS (*newpos);
1872 /* EXPORT:
1873 Return an estimation of the pixel height of mode or header lines on
1874 frame F. FACE_ID specifies what line's height to estimate. */
1877 estimate_mode_line_height (struct frame *f, enum face_id face_id)
1879 #ifdef HAVE_WINDOW_SYSTEM
1880 if (FRAME_WINDOW_P (f))
1882 int height = FONT_HEIGHT (FRAME_FONT (f));
1884 /* This function is called so early when Emacs starts that the face
1885 cache and mode line face are not yet initialized. */
1886 if (FRAME_FACE_CACHE (f))
1888 struct face *face = FACE_FROM_ID_OR_NULL (f, face_id);
1889 if (face)
1891 if (face->font)
1892 height = normal_char_height (face->font, -1);
1893 if (face->box_line_width > 0)
1894 height += 2 * face->box_line_width;
1898 return height;
1900 #endif
1902 return 1;
1905 /* Given a pixel position (PIX_X, PIX_Y) on frame F, return glyph
1906 co-ordinates in (*X, *Y). Set *BOUNDS to the rectangle that the
1907 glyph at X, Y occupies, if BOUNDS != 0. If NOCLIP, do
1908 not force the value into range. */
1910 void
1911 pixel_to_glyph_coords (struct frame *f, int pix_x, int pix_y, int *x, int *y,
1912 NativeRectangle *bounds, bool noclip)
1915 #ifdef HAVE_WINDOW_SYSTEM
1916 if (FRAME_WINDOW_P (f))
1918 /* Arrange for the division in FRAME_PIXEL_X_TO_COL etc. to round down
1919 even for negative values. */
1920 if (pix_x < 0)
1921 pix_x -= FRAME_COLUMN_WIDTH (f) - 1;
1922 if (pix_y < 0)
1923 pix_y -= FRAME_LINE_HEIGHT (f) - 1;
1925 pix_x = FRAME_PIXEL_X_TO_COL (f, pix_x);
1926 pix_y = FRAME_PIXEL_Y_TO_LINE (f, pix_y);
1928 if (bounds)
1929 STORE_NATIVE_RECT (*bounds,
1930 FRAME_COL_TO_PIXEL_X (f, pix_x),
1931 FRAME_LINE_TO_PIXEL_Y (f, pix_y),
1932 FRAME_COLUMN_WIDTH (f) - 1,
1933 FRAME_LINE_HEIGHT (f) - 1);
1935 /* PXW: Should we clip pixels before converting to columns/lines? */
1936 if (!noclip)
1938 if (pix_x < 0)
1939 pix_x = 0;
1940 else if (pix_x > FRAME_TOTAL_COLS (f))
1941 pix_x = FRAME_TOTAL_COLS (f);
1943 if (pix_y < 0)
1944 pix_y = 0;
1945 else if (pix_y > FRAME_TOTAL_LINES (f))
1946 pix_y = FRAME_TOTAL_LINES (f);
1949 #endif
1951 *x = pix_x;
1952 *y = pix_y;
1956 /* Find the glyph under window-relative coordinates X/Y in window W.
1957 Consider only glyphs from buffer text, i.e. no glyphs from overlay
1958 strings. Return in *HPOS and *VPOS the row and column number of
1959 the glyph found. Return in *AREA the glyph area containing X.
1960 Value is a pointer to the glyph found or null if X/Y is not on
1961 text, or we can't tell because W's current matrix is not up to
1962 date. */
1964 static struct glyph *
1965 x_y_to_hpos_vpos (struct window *w, int x, int y, int *hpos, int *vpos,
1966 int *dx, int *dy, int *area)
1968 struct glyph *glyph, *end;
1969 struct glyph_row *row = NULL;
1970 int x0, i;
1972 /* Find row containing Y. Give up if some row is not enabled. */
1973 for (i = 0; i < w->current_matrix->nrows; ++i)
1975 row = MATRIX_ROW (w->current_matrix, i);
1976 if (!row->enabled_p)
1977 return NULL;
1978 if (y >= row->y && y < MATRIX_ROW_BOTTOM_Y (row))
1979 break;
1982 *vpos = i;
1983 *hpos = 0;
1985 /* Give up if Y is not in the window. */
1986 if (i == w->current_matrix->nrows)
1987 return NULL;
1989 /* Get the glyph area containing X. */
1990 if (w->pseudo_window_p)
1992 *area = TEXT_AREA;
1993 x0 = 0;
1995 else
1997 if (x < window_box_left_offset (w, TEXT_AREA))
1999 *area = LEFT_MARGIN_AREA;
2000 x0 = window_box_left_offset (w, LEFT_MARGIN_AREA);
2002 else if (x < window_box_right_offset (w, TEXT_AREA))
2004 *area = TEXT_AREA;
2005 x0 = window_box_left_offset (w, TEXT_AREA) + min (row->x, 0);
2007 else
2009 *area = RIGHT_MARGIN_AREA;
2010 x0 = window_box_left_offset (w, RIGHT_MARGIN_AREA);
2014 /* Find glyph containing X. */
2015 glyph = row->glyphs[*area];
2016 end = glyph + row->used[*area];
2017 x -= x0;
2018 while (glyph < end && x >= glyph->pixel_width)
2020 x -= glyph->pixel_width;
2021 ++glyph;
2024 if (glyph == end)
2025 return NULL;
2027 if (dx)
2029 *dx = x;
2030 *dy = y - (row->y + row->ascent - glyph->ascent);
2033 *hpos = glyph - row->glyphs[*area];
2034 return glyph;
2037 /* Convert frame-relative x/y to coordinates relative to window W.
2038 Takes pseudo-windows into account. */
2040 static void
2041 frame_to_window_pixel_xy (struct window *w, int *x, int *y)
2043 if (w->pseudo_window_p)
2045 /* A pseudo-window is always full-width, and starts at the
2046 left edge of the frame, plus a frame border. */
2047 struct frame *f = XFRAME (w->frame);
2048 *x -= FRAME_INTERNAL_BORDER_WIDTH (f);
2049 *y = FRAME_TO_WINDOW_PIXEL_Y (w, *y);
2051 else
2053 *x -= WINDOW_LEFT_EDGE_X (w);
2054 *y = FRAME_TO_WINDOW_PIXEL_Y (w, *y);
2058 #ifdef HAVE_WINDOW_SYSTEM
2060 /* EXPORT:
2061 Return in RECTS[] at most N clipping rectangles for glyph string S.
2062 Return the number of stored rectangles. */
2065 get_glyph_string_clip_rects (struct glyph_string *s, NativeRectangle *rects, int n)
2067 XRectangle r;
2069 if (n <= 0)
2070 return 0;
2072 if (s->row->full_width_p)
2074 /* Draw full-width. X coordinates are relative to S->w->left_col. */
2075 r.x = WINDOW_LEFT_EDGE_X (s->w);
2076 if (s->row->mode_line_p)
2077 r.width = WINDOW_PIXEL_WIDTH (s->w) - WINDOW_RIGHT_DIVIDER_WIDTH (s->w);
2078 else
2079 r.width = WINDOW_PIXEL_WIDTH (s->w);
2081 /* Unless displaying a mode or menu bar line, which are always
2082 fully visible, clip to the visible part of the row. */
2083 if (s->w->pseudo_window_p)
2084 r.height = s->row->visible_height;
2085 else
2086 r.height = s->height;
2088 else
2090 /* This is a text line that may be partially visible. */
2091 r.x = window_box_left (s->w, s->area);
2092 r.width = window_box_width (s->w, s->area);
2093 r.height = s->row->visible_height;
2096 if (s->clip_head)
2097 if (r.x < s->clip_head->x)
2099 if (r.width >= s->clip_head->x - r.x)
2100 r.width -= s->clip_head->x - r.x;
2101 else
2102 r.width = 0;
2103 r.x = s->clip_head->x;
2105 if (s->clip_tail)
2106 if (r.x + r.width > s->clip_tail->x + s->clip_tail->background_width)
2108 if (s->clip_tail->x + s->clip_tail->background_width >= r.x)
2109 r.width = s->clip_tail->x + s->clip_tail->background_width - r.x;
2110 else
2111 r.width = 0;
2114 /* If S draws overlapping rows, it's sufficient to use the top and
2115 bottom of the window for clipping because this glyph string
2116 intentionally draws over other lines. */
2117 if (s->for_overlaps)
2119 r.y = WINDOW_HEADER_LINE_HEIGHT (s->w);
2120 r.height = window_text_bottom_y (s->w) - r.y;
2122 /* Alas, the above simple strategy does not work for the
2123 environments with anti-aliased text: if the same text is
2124 drawn onto the same place multiple times, it gets thicker.
2125 If the overlap we are processing is for the erased cursor, we
2126 take the intersection with the rectangle of the cursor. */
2127 if (s->for_overlaps & OVERLAPS_ERASED_CURSOR)
2129 XRectangle rc, r_save = r;
2131 rc.x = WINDOW_TEXT_TO_FRAME_PIXEL_X (s->w, s->w->phys_cursor.x);
2132 rc.y = s->w->phys_cursor.y;
2133 rc.width = s->w->phys_cursor_width;
2134 rc.height = s->w->phys_cursor_height;
2136 x_intersect_rectangles (&r_save, &rc, &r);
2139 else
2141 /* Don't use S->y for clipping because it doesn't take partially
2142 visible lines into account. For example, it can be negative for
2143 partially visible lines at the top of a window. */
2144 if (!s->row->full_width_p
2145 && MATRIX_ROW_PARTIALLY_VISIBLE_AT_TOP_P (s->w, s->row))
2146 r.y = WINDOW_HEADER_LINE_HEIGHT (s->w);
2147 else
2148 r.y = max (0, s->row->y);
2151 r.y = WINDOW_TO_FRAME_PIXEL_Y (s->w, r.y);
2153 /* If drawing the cursor, don't let glyph draw outside its
2154 advertised boundaries. Cleartype does this under some circumstances. */
2155 if (s->hl == DRAW_CURSOR)
2157 struct glyph *glyph = s->first_glyph;
2158 int height, max_y;
2160 if (s->x > r.x)
2162 if (r.width >= s->x - r.x)
2163 r.width -= s->x - r.x;
2164 else /* R2L hscrolled row with cursor outside text area */
2165 r.width = 0;
2166 r.x = s->x;
2168 r.width = min (r.width, glyph->pixel_width);
2170 /* If r.y is below window bottom, ensure that we still see a cursor. */
2171 height = min (glyph->ascent + glyph->descent,
2172 min (FRAME_LINE_HEIGHT (s->f), s->row->visible_height));
2173 max_y = window_text_bottom_y (s->w) - height;
2174 max_y = WINDOW_TO_FRAME_PIXEL_Y (s->w, max_y);
2175 if (s->ybase - glyph->ascent > max_y)
2177 r.y = max_y;
2178 r.height = height;
2180 else
2182 /* Don't draw cursor glyph taller than our actual glyph. */
2183 height = max (FRAME_LINE_HEIGHT (s->f), glyph->ascent + glyph->descent);
2184 if (height < r.height)
2186 max_y = r.y + r.height;
2187 r.y = min (max_y, max (r.y, s->ybase + glyph->descent - height));
2188 r.height = min (max_y - r.y, height);
2193 if (s->row->clip)
2195 XRectangle r_save = r;
2197 if (! x_intersect_rectangles (&r_save, s->row->clip, &r))
2198 r.width = 0;
2201 if ((s->for_overlaps & OVERLAPS_BOTH) == 0
2202 || ((s->for_overlaps & OVERLAPS_BOTH) == OVERLAPS_BOTH && n == 1))
2204 #ifdef CONVERT_FROM_XRECT
2205 CONVERT_FROM_XRECT (r, *rects);
2206 #else
2207 *rects = r;
2208 #endif
2209 return 1;
2211 else
2213 /* If we are processing overlapping and allowed to return
2214 multiple clipping rectangles, we exclude the row of the glyph
2215 string from the clipping rectangle. This is to avoid drawing
2216 the same text on the environment with anti-aliasing. */
2217 #ifdef CONVERT_FROM_XRECT
2218 XRectangle rs[2];
2219 #else
2220 XRectangle *rs = rects;
2221 #endif
2222 int i = 0, row_y = WINDOW_TO_FRAME_PIXEL_Y (s->w, s->row->y);
2224 if (s->for_overlaps & OVERLAPS_PRED)
2226 rs[i] = r;
2227 if (r.y + r.height > row_y)
2229 if (r.y < row_y)
2230 rs[i].height = row_y - r.y;
2231 else
2232 rs[i].height = 0;
2234 i++;
2236 if (s->for_overlaps & OVERLAPS_SUCC)
2238 rs[i] = r;
2239 if (r.y < row_y + s->row->visible_height)
2241 if (r.y + r.height > row_y + s->row->visible_height)
2243 rs[i].y = row_y + s->row->visible_height;
2244 rs[i].height = r.y + r.height - rs[i].y;
2246 else
2247 rs[i].height = 0;
2249 i++;
2252 n = i;
2253 #ifdef CONVERT_FROM_XRECT
2254 for (i = 0; i < n; i++)
2255 CONVERT_FROM_XRECT (rs[i], rects[i]);
2256 #endif
2257 return n;
2261 /* EXPORT:
2262 Return in *NR the clipping rectangle for glyph string S. */
2264 void
2265 get_glyph_string_clip_rect (struct glyph_string *s, NativeRectangle *nr)
2267 get_glyph_string_clip_rects (s, nr, 1);
2271 /* EXPORT:
2272 Return the position and height of the phys cursor in window W.
2273 Set w->phys_cursor_width to width of phys cursor.
2276 void
2277 get_phys_cursor_geometry (struct window *w, struct glyph_row *row,
2278 struct glyph *glyph, int *xp, int *yp, int *heightp)
2280 struct frame *f = XFRAME (WINDOW_FRAME (w));
2281 int x, y, wd, h, h0, y0, ascent;
2283 /* Compute the width of the rectangle to draw. If on a stretch
2284 glyph, and `x-stretch-block-cursor' is nil, don't draw a
2285 rectangle as wide as the glyph, but use a canonical character
2286 width instead. */
2287 wd = glyph->pixel_width;
2289 x = w->phys_cursor.x;
2290 if (x < 0)
2292 wd += x;
2293 x = 0;
2296 if (glyph->type == STRETCH_GLYPH
2297 && !x_stretch_cursor_p)
2298 wd = min (FRAME_COLUMN_WIDTH (f), wd);
2299 w->phys_cursor_width = wd;
2301 /* Don't let the hollow cursor glyph descend below the glyph row's
2302 ascent value, lest the hollow cursor looks funny. */
2303 y = w->phys_cursor.y;
2304 ascent = row->ascent;
2305 if (row->ascent < glyph->ascent)
2307 y -= glyph->ascent - row->ascent;
2308 ascent = glyph->ascent;
2311 /* If y is below window bottom, ensure that we still see a cursor. */
2312 h0 = min (FRAME_LINE_HEIGHT (f), row->visible_height);
2314 h = max (h0, ascent + glyph->descent);
2315 h0 = min (h0, ascent + glyph->descent);
2317 y0 = WINDOW_HEADER_LINE_HEIGHT (w);
2318 if (y < y0)
2320 h = max (h - (y0 - y) + 1, h0);
2321 y = y0 - 1;
2323 else
2325 y0 = window_text_bottom_y (w) - h0;
2326 if (y > y0)
2328 h += y - y0;
2329 y = y0;
2333 *xp = WINDOW_TEXT_TO_FRAME_PIXEL_X (w, x);
2334 *yp = WINDOW_TO_FRAME_PIXEL_Y (w, y);
2335 *heightp = h;
2339 * Remember which glyph the mouse is over.
2342 void
2343 remember_mouse_glyph (struct frame *f, int gx, int gy, NativeRectangle *rect)
2345 Lisp_Object window;
2346 struct window *w;
2347 struct glyph_row *r, *gr, *end_row;
2348 enum window_part part;
2349 enum glyph_row_area area;
2350 int x, y, width, height;
2352 /* Try to determine frame pixel position and size of the glyph under
2353 frame pixel coordinates X/Y on frame F. */
2355 if (window_resize_pixelwise)
2357 width = height = 1;
2358 goto virtual_glyph;
2360 else if (!f->glyphs_initialized_p
2361 || (window = window_from_coordinates (f, gx, gy, &part, false),
2362 NILP (window)))
2364 width = FRAME_SMALLEST_CHAR_WIDTH (f);
2365 height = FRAME_SMALLEST_FONT_HEIGHT (f);
2366 goto virtual_glyph;
2369 w = XWINDOW (window);
2370 width = WINDOW_FRAME_COLUMN_WIDTH (w);
2371 height = WINDOW_FRAME_LINE_HEIGHT (w);
2373 x = window_relative_x_coord (w, part, gx);
2374 y = gy - WINDOW_TOP_EDGE_Y (w);
2376 r = MATRIX_FIRST_TEXT_ROW (w->current_matrix);
2377 end_row = MATRIX_BOTTOM_TEXT_ROW (w->current_matrix, w);
2379 if (w->pseudo_window_p)
2381 area = TEXT_AREA;
2382 part = ON_MODE_LINE; /* Don't adjust margin. */
2383 goto text_glyph;
2386 switch (part)
2388 case ON_LEFT_MARGIN:
2389 area = LEFT_MARGIN_AREA;
2390 goto text_glyph;
2392 case ON_RIGHT_MARGIN:
2393 area = RIGHT_MARGIN_AREA;
2394 goto text_glyph;
2396 case ON_HEADER_LINE:
2397 case ON_MODE_LINE:
2398 gr = (part == ON_HEADER_LINE
2399 ? MATRIX_HEADER_LINE_ROW (w->current_matrix)
2400 : MATRIX_MODE_LINE_ROW (w->current_matrix));
2401 gy = gr->y;
2402 area = TEXT_AREA;
2403 goto text_glyph_row_found;
2405 case ON_TEXT:
2406 area = TEXT_AREA;
2408 text_glyph:
2409 gr = 0; gy = 0;
2410 for (; r <= end_row && r->enabled_p; ++r)
2411 if (r->y + r->height > y)
2413 gr = r; gy = r->y;
2414 break;
2417 text_glyph_row_found:
2418 if (gr && gy <= y)
2420 struct glyph *g = gr->glyphs[area];
2421 struct glyph *end = g + gr->used[area];
2423 height = gr->height;
2424 for (gx = gr->x; g < end; gx += g->pixel_width, ++g)
2425 if (gx + g->pixel_width > x)
2426 break;
2428 if (g < end)
2430 if (g->type == IMAGE_GLYPH)
2432 /* Don't remember when mouse is over image, as
2433 image may have hot-spots. */
2434 STORE_NATIVE_RECT (*rect, 0, 0, 0, 0);
2435 return;
2437 width = g->pixel_width;
2439 else
2441 /* Use nominal char spacing at end of line. */
2442 x -= gx;
2443 gx += (x / width) * width;
2446 if (part != ON_MODE_LINE && part != ON_HEADER_LINE)
2448 gx += window_box_left_offset (w, area);
2449 /* Don't expand over the modeline to make sure the vertical
2450 drag cursor is shown early enough. */
2451 height = min (height,
2452 max (0, WINDOW_BOX_HEIGHT_NO_MODE_LINE (w) - gy));
2455 else
2457 /* Use nominal line height at end of window. */
2458 gx = (x / width) * width;
2459 y -= gy;
2460 gy += (y / height) * height;
2461 if (part != ON_MODE_LINE && part != ON_HEADER_LINE)
2462 /* See comment above. */
2463 height = min (height,
2464 max (0, WINDOW_BOX_HEIGHT_NO_MODE_LINE (w) - gy));
2466 break;
2468 case ON_LEFT_FRINGE:
2469 gx = (WINDOW_HAS_FRINGES_OUTSIDE_MARGINS (w)
2470 ? WINDOW_LEFT_SCROLL_BAR_AREA_WIDTH (w)
2471 : window_box_right_offset (w, LEFT_MARGIN_AREA));
2472 width = WINDOW_LEFT_FRINGE_WIDTH (w);
2473 goto row_glyph;
2475 case ON_RIGHT_FRINGE:
2476 gx = (WINDOW_HAS_FRINGES_OUTSIDE_MARGINS (w)
2477 ? window_box_right_offset (w, RIGHT_MARGIN_AREA)
2478 : window_box_right_offset (w, TEXT_AREA));
2479 if (WINDOW_RIGHT_DIVIDER_WIDTH (w) == 0
2480 && !WINDOW_HAS_VERTICAL_SCROLL_BAR (w)
2481 && !WINDOW_RIGHTMOST_P (w))
2482 if (gx < WINDOW_PIXEL_WIDTH (w) - width)
2483 /* Make sure the vertical border can get her own glyph to the
2484 right of the one we build here. */
2485 width = WINDOW_RIGHT_FRINGE_WIDTH (w) - width;
2486 else
2487 width = WINDOW_PIXEL_WIDTH (w) - gx;
2488 else
2489 width = WINDOW_RIGHT_FRINGE_WIDTH (w);
2491 goto row_glyph;
2493 case ON_VERTICAL_BORDER:
2494 gx = WINDOW_PIXEL_WIDTH (w) - width;
2495 goto row_glyph;
2497 case ON_VERTICAL_SCROLL_BAR:
2498 gx = (WINDOW_HAS_VERTICAL_SCROLL_BAR_ON_LEFT (w)
2500 : (window_box_right_offset (w, RIGHT_MARGIN_AREA)
2501 + (WINDOW_HAS_FRINGES_OUTSIDE_MARGINS (w)
2502 ? WINDOW_RIGHT_FRINGE_WIDTH (w)
2503 : 0)));
2504 width = WINDOW_SCROLL_BAR_AREA_WIDTH (w);
2506 row_glyph:
2507 gr = 0, gy = 0;
2508 for (; r <= end_row && r->enabled_p; ++r)
2509 if (r->y + r->height > y)
2511 gr = r; gy = r->y;
2512 break;
2515 if (gr && gy <= y)
2516 height = gr->height;
2517 else
2519 /* Use nominal line height at end of window. */
2520 y -= gy;
2521 gy += (y / height) * height;
2523 break;
2525 case ON_RIGHT_DIVIDER:
2526 gx = WINDOW_PIXEL_WIDTH (w) - WINDOW_RIGHT_DIVIDER_WIDTH (w);
2527 width = WINDOW_RIGHT_DIVIDER_WIDTH (w);
2528 gy = 0;
2529 /* The bottom divider prevails. */
2530 height = WINDOW_PIXEL_HEIGHT (w) - WINDOW_BOTTOM_DIVIDER_WIDTH (w);
2531 goto add_edge;
2533 case ON_BOTTOM_DIVIDER:
2534 gx = 0;
2535 width = WINDOW_PIXEL_WIDTH (w);
2536 gy = WINDOW_PIXEL_HEIGHT (w) - WINDOW_BOTTOM_DIVIDER_WIDTH (w);
2537 height = WINDOW_BOTTOM_DIVIDER_WIDTH (w);
2538 goto add_edge;
2540 default:
2542 virtual_glyph:
2543 /* If there is no glyph under the mouse, then we divide the screen
2544 into a grid of the smallest glyph in the frame, and use that
2545 as our "glyph". */
2547 /* Arrange for the division in FRAME_PIXEL_X_TO_COL etc. to
2548 round down even for negative values. */
2549 if (gx < 0)
2550 gx -= width - 1;
2551 if (gy < 0)
2552 gy -= height - 1;
2554 gx = (gx / width) * width;
2555 gy = (gy / height) * height;
2557 goto store_rect;
2560 add_edge:
2561 gx += WINDOW_LEFT_EDGE_X (w);
2562 gy += WINDOW_TOP_EDGE_Y (w);
2564 store_rect:
2565 STORE_NATIVE_RECT (*rect, gx, gy, width, height);
2567 /* Visible feedback for debugging. */
2568 #if false && defined HAVE_X_WINDOWS
2569 XDrawRectangle (FRAME_X_DISPLAY (f), FRAME_X_DRAWABLE (f),
2570 f->output_data.x->normal_gc,
2571 gx, gy, width, height);
2572 #endif
2576 #endif /* HAVE_WINDOW_SYSTEM */
2578 static void
2579 adjust_window_ends (struct window *w, struct glyph_row *row, bool current)
2581 eassert (w);
2582 w->window_end_pos = Z - MATRIX_ROW_END_CHARPOS (row);
2583 w->window_end_bytepos = Z_BYTE - MATRIX_ROW_END_BYTEPOS (row);
2584 w->window_end_vpos
2585 = MATRIX_ROW_VPOS (row, current ? w->current_matrix : w->desired_matrix);
2588 static bool
2589 hscrolling_current_line_p (struct window *w)
2591 return (!w->suspend_auto_hscroll
2592 && EQ (Fbuffer_local_value (Qauto_hscroll_mode, w->contents),
2593 Qcurrent_line));
2596 /***********************************************************************
2597 Lisp form evaluation
2598 ***********************************************************************/
2600 /* Error handler for safe_eval and safe_call. */
2602 static Lisp_Object
2603 safe_eval_handler (Lisp_Object arg, ptrdiff_t nargs, Lisp_Object *args)
2605 add_to_log ("Error during redisplay: %S signaled %S",
2606 Flist (nargs, args), arg);
2607 return Qnil;
2610 /* Call function FUNC with the rest of NARGS - 1 arguments
2611 following. Return the result, or nil if something went
2612 wrong. Prevent redisplay during the evaluation. */
2614 static Lisp_Object
2615 safe__call (bool inhibit_quit, ptrdiff_t nargs, Lisp_Object func, va_list ap)
2617 Lisp_Object val;
2619 if (inhibit_eval_during_redisplay)
2620 val = Qnil;
2621 else
2623 ptrdiff_t i;
2624 ptrdiff_t count = SPECPDL_INDEX ();
2625 Lisp_Object *args;
2626 USE_SAFE_ALLOCA;
2627 SAFE_ALLOCA_LISP (args, nargs);
2629 args[0] = func;
2630 for (i = 1; i < nargs; i++)
2631 args[i] = va_arg (ap, Lisp_Object);
2633 specbind (Qinhibit_redisplay, Qt);
2634 if (inhibit_quit)
2635 specbind (Qinhibit_quit, Qt);
2636 /* Use Qt to ensure debugger does not run,
2637 so there is no possibility of wanting to redisplay. */
2638 val = internal_condition_case_n (Ffuncall, nargs, args, Qt,
2639 safe_eval_handler);
2640 SAFE_FREE ();
2641 val = unbind_to (count, val);
2644 return val;
2647 Lisp_Object
2648 safe_call (ptrdiff_t nargs, Lisp_Object func, ...)
2650 Lisp_Object retval;
2651 va_list ap;
2653 va_start (ap, func);
2654 retval = safe__call (false, nargs, func, ap);
2655 va_end (ap);
2656 return retval;
2659 /* Call function FN with one argument ARG.
2660 Return the result, or nil if something went wrong. */
2662 Lisp_Object
2663 safe_call1 (Lisp_Object fn, Lisp_Object arg)
2665 return safe_call (2, fn, arg);
2668 static Lisp_Object
2669 safe__call1 (bool inhibit_quit, Lisp_Object fn, ...)
2671 Lisp_Object retval;
2672 va_list ap;
2674 va_start (ap, fn);
2675 retval = safe__call (inhibit_quit, 2, fn, ap);
2676 va_end (ap);
2677 return retval;
2680 Lisp_Object
2681 safe_eval (Lisp_Object sexpr)
2683 return safe__call1 (false, Qeval, sexpr);
2686 static Lisp_Object
2687 safe__eval (bool inhibit_quit, Lisp_Object sexpr)
2689 return safe__call1 (inhibit_quit, Qeval, sexpr);
2692 /* Call function FN with two arguments ARG1 and ARG2.
2693 Return the result, or nil if something went wrong. */
2695 Lisp_Object
2696 safe_call2 (Lisp_Object fn, Lisp_Object arg1, Lisp_Object arg2)
2698 return safe_call (3, fn, arg1, arg2);
2703 /***********************************************************************
2704 Debugging
2705 ***********************************************************************/
2707 /* Define CHECK_IT to perform sanity checks on iterators.
2708 This is for debugging. It is too slow to do unconditionally. */
2710 static void
2711 CHECK_IT (struct it *it)
2713 #if false
2714 if (it->method == GET_FROM_STRING)
2716 eassert (STRINGP (it->string));
2717 eassert (IT_STRING_CHARPOS (*it) >= 0);
2719 else
2721 eassert (IT_STRING_CHARPOS (*it) < 0);
2722 if (it->method == GET_FROM_BUFFER)
2724 /* Check that character and byte positions agree. */
2725 eassert (IT_CHARPOS (*it) == BYTE_TO_CHAR (IT_BYTEPOS (*it)));
2729 if (it->dpvec)
2730 eassert (it->current.dpvec_index >= 0);
2731 else
2732 eassert (it->current.dpvec_index < 0);
2733 #endif
2737 /* Check that the window end of window W is what we expect it
2738 to be---the last row in the current matrix displaying text. */
2740 static void
2741 CHECK_WINDOW_END (struct window *w)
2743 #if defined GLYPH_DEBUG && defined ENABLE_CHECKING
2744 if (!MINI_WINDOW_P (w) && w->window_end_valid)
2746 struct glyph_row *row;
2747 eassert ((row = MATRIX_ROW (w->current_matrix, w->window_end_vpos),
2748 !row->enabled_p
2749 || MATRIX_ROW_DISPLAYS_TEXT_P (row)
2750 || MATRIX_ROW_VPOS (row, w->current_matrix) == 0));
2752 #endif
2755 /***********************************************************************
2756 Iterator initialization
2757 ***********************************************************************/
2759 /* Initialize IT for displaying current_buffer in window W, starting
2760 at character position CHARPOS. CHARPOS < 0 means that no buffer
2761 position is specified which is useful when the iterator is assigned
2762 a position later. BYTEPOS is the byte position corresponding to
2763 CHARPOS.
2765 If ROW is not null, calls to produce_glyphs with IT as parameter
2766 will produce glyphs in that row.
2768 BASE_FACE_ID is the id of a base face to use. It must be one of
2769 DEFAULT_FACE_ID for normal text, MODE_LINE_FACE_ID,
2770 MODE_LINE_INACTIVE_FACE_ID, or HEADER_LINE_FACE_ID for displaying
2771 mode lines, or TOOL_BAR_FACE_ID for displaying the tool-bar.
2773 If ROW is null and BASE_FACE_ID is equal to MODE_LINE_FACE_ID,
2774 MODE_LINE_INACTIVE_FACE_ID, or HEADER_LINE_FACE_ID, the iterator
2775 will be initialized to use the corresponding mode line glyph row of
2776 the desired matrix of W. */
2778 void
2779 init_iterator (struct it *it, struct window *w,
2780 ptrdiff_t charpos, ptrdiff_t bytepos,
2781 struct glyph_row *row, enum face_id base_face_id)
2783 enum face_id remapped_base_face_id = base_face_id;
2785 /* Some precondition checks. */
2786 eassert (w != NULL && it != NULL);
2787 eassert (charpos < 0 || (charpos >= BUF_BEG (current_buffer)
2788 && charpos <= ZV));
2790 /* If face attributes have been changed since the last redisplay,
2791 free realized faces now because they depend on face definitions
2792 that might have changed. Don't free faces while there might be
2793 desired matrices pending which reference these faces. */
2794 if (!inhibit_free_realized_faces)
2796 if (face_change)
2798 face_change = false;
2799 XFRAME (w->frame)->face_change = 0;
2800 free_all_realized_faces (Qnil);
2802 else if (XFRAME (w->frame)->face_change)
2804 XFRAME (w->frame)->face_change = 0;
2805 free_all_realized_faces (w->frame);
2809 /* Perhaps remap BASE_FACE_ID to a user-specified alternative. */
2810 if (! NILP (Vface_remapping_alist))
2811 remapped_base_face_id
2812 = lookup_basic_face (XFRAME (w->frame), base_face_id);
2814 /* Use one of the mode line rows of W's desired matrix if
2815 appropriate. */
2816 if (row == NULL)
2818 if (base_face_id == MODE_LINE_FACE_ID
2819 || base_face_id == MODE_LINE_INACTIVE_FACE_ID)
2820 row = MATRIX_MODE_LINE_ROW (w->desired_matrix);
2821 else if (base_face_id == HEADER_LINE_FACE_ID)
2822 row = MATRIX_HEADER_LINE_ROW (w->desired_matrix);
2825 /* Clear IT, and set it->object and other IT's Lisp objects to Qnil.
2826 Other parts of redisplay rely on that. */
2827 memclear (it, sizeof *it);
2828 it->current.overlay_string_index = -1;
2829 it->current.dpvec_index = -1;
2830 it->base_face_id = remapped_base_face_id;
2831 IT_STRING_CHARPOS (*it) = IT_STRING_BYTEPOS (*it) = -1;
2832 it->paragraph_embedding = L2R;
2833 it->bidi_it.w = w;
2835 /* The window in which we iterate over current_buffer: */
2836 XSETWINDOW (it->window, w);
2837 it->w = w;
2838 it->f = XFRAME (w->frame);
2840 it->cmp_it.id = -1;
2842 /* Extra space between lines (on window systems only). */
2843 if (base_face_id == DEFAULT_FACE_ID
2844 && FRAME_WINDOW_P (it->f))
2846 if (NATNUMP (BVAR (current_buffer, extra_line_spacing)))
2847 it->extra_line_spacing = XFASTINT (BVAR (current_buffer, extra_line_spacing));
2848 else if (FLOATP (BVAR (current_buffer, extra_line_spacing)))
2849 it->extra_line_spacing = (XFLOAT_DATA (BVAR (current_buffer, extra_line_spacing))
2850 * FRAME_LINE_HEIGHT (it->f));
2851 else if (it->f->extra_line_spacing > 0)
2852 it->extra_line_spacing = it->f->extra_line_spacing;
2855 /* If realized faces have been removed, e.g. because of face
2856 attribute changes of named faces, recompute them. When running
2857 in batch mode, the face cache of the initial frame is null. If
2858 we happen to get called, make a dummy face cache. */
2859 if (FRAME_FACE_CACHE (it->f) == NULL)
2860 init_frame_faces (it->f);
2861 if (FRAME_FACE_CACHE (it->f)->used == 0)
2862 recompute_basic_faces (it->f);
2864 it->override_ascent = -1;
2866 /* Are control characters displayed as `^C'? */
2867 it->ctl_arrow_p = !NILP (BVAR (current_buffer, ctl_arrow));
2869 /* -1 means everything between a CR and the following line end
2870 is invisible. >0 means lines indented more than this value are
2871 invisible. */
2872 it->selective = (INTEGERP (BVAR (current_buffer, selective_display))
2873 ? (clip_to_bounds
2874 (-1, XINT (BVAR (current_buffer, selective_display)),
2875 PTRDIFF_MAX))
2876 : (!NILP (BVAR (current_buffer, selective_display))
2877 ? -1 : 0));
2878 it->selective_display_ellipsis_p
2879 = !NILP (BVAR (current_buffer, selective_display_ellipses));
2881 /* Display table to use. */
2882 it->dp = window_display_table (w);
2884 /* Are multibyte characters enabled in current_buffer? */
2885 it->multibyte_p = !NILP (BVAR (current_buffer, enable_multibyte_characters));
2887 /* Get the position at which the redisplay_end_trigger hook should
2888 be run, if it is to be run at all. */
2889 if (MARKERP (w->redisplay_end_trigger)
2890 && XMARKER (w->redisplay_end_trigger)->buffer != 0)
2891 it->redisplay_end_trigger_charpos
2892 = marker_position (w->redisplay_end_trigger);
2893 else if (INTEGERP (w->redisplay_end_trigger))
2894 it->redisplay_end_trigger_charpos
2895 = clip_to_bounds (PTRDIFF_MIN, XINT (w->redisplay_end_trigger),
2896 PTRDIFF_MAX);
2898 it->tab_width = SANE_TAB_WIDTH (current_buffer);
2900 /* Are lines in the display truncated? */
2901 if (TRUNCATE != 0)
2902 it->line_wrap = TRUNCATE;
2903 if (base_face_id == DEFAULT_FACE_ID
2904 && !it->w->hscroll
2905 && (WINDOW_FULL_WIDTH_P (it->w)
2906 || NILP (Vtruncate_partial_width_windows)
2907 || (INTEGERP (Vtruncate_partial_width_windows)
2908 /* PXW: Shall we do something about this? */
2909 && (XINT (Vtruncate_partial_width_windows)
2910 <= WINDOW_TOTAL_COLS (it->w))))
2911 && NILP (BVAR (current_buffer, truncate_lines)))
2912 it->line_wrap = NILP (BVAR (current_buffer, word_wrap))
2913 ? WINDOW_WRAP : WORD_WRAP;
2915 /* Get dimensions of truncation and continuation glyphs. These are
2916 displayed as fringe bitmaps under X, but we need them for such
2917 frames when the fringes are turned off. The no_special_glyphs slot
2918 of the iterator's frame, when set, suppresses their display - by
2919 default for tooltip frames and when set via the 'no-special-glyphs'
2920 frame parameter. */
2921 #ifdef HAVE_WINDOW_SYSTEM
2922 if (!(FRAME_WINDOW_P (it->f) && it->f->no_special_glyphs))
2923 #endif
2925 if (it->line_wrap == TRUNCATE)
2927 /* We will need the truncation glyph. */
2928 eassert (it->glyph_row == NULL);
2929 produce_special_glyphs (it, IT_TRUNCATION);
2930 it->truncation_pixel_width = it->pixel_width;
2932 else
2934 /* We will need the continuation glyph. */
2935 eassert (it->glyph_row == NULL);
2936 produce_special_glyphs (it, IT_CONTINUATION);
2937 it->continuation_pixel_width = it->pixel_width;
2941 /* Reset these values to zero because the produce_special_glyphs
2942 above has changed them. */
2943 it->pixel_width = it->ascent = it->descent = 0;
2944 it->phys_ascent = it->phys_descent = 0;
2946 /* Set this after getting the dimensions of truncation and
2947 continuation glyphs, so that we don't produce glyphs when calling
2948 produce_special_glyphs, above. */
2949 it->glyph_row = row;
2950 it->area = TEXT_AREA;
2952 /* Get the dimensions of the display area. The display area
2953 consists of the visible window area plus a horizontally scrolled
2954 part to the left of the window. All x-values are relative to the
2955 start of this total display area. */
2956 if (base_face_id != DEFAULT_FACE_ID)
2958 /* Mode lines, menu bar in terminal frames. */
2959 it->first_visible_x = 0;
2960 it->last_visible_x = WINDOW_PIXEL_WIDTH (w);
2962 else
2964 /* When hscrolling only the current line, don't apply the
2965 hscroll here, it will be applied by display_line when it gets
2966 to laying out the line showing point. However, if the
2967 window's min_hscroll is positive, the user specified a lower
2968 bound for automatic hscrolling, so they expect the
2969 non-current lines to obey that hscroll amount. */
2970 if (hscrolling_current_line_p (w))
2972 if (w->min_hscroll > 0)
2973 it->first_visible_x = w->min_hscroll * FRAME_COLUMN_WIDTH (it->f);
2974 else
2975 it->first_visible_x = 0;
2977 else
2978 it->first_visible_x =
2979 window_hscroll_limited (w, it->f) * FRAME_COLUMN_WIDTH (it->f);
2980 it->last_visible_x = (it->first_visible_x
2981 + window_box_width (w, TEXT_AREA));
2983 /* If we truncate lines, leave room for the truncation glyph(s) at
2984 the right margin. Otherwise, leave room for the continuation
2985 glyph(s). Done only if the window has no right fringe. */
2986 if (WINDOW_RIGHT_FRINGE_WIDTH (it->w) == 0)
2988 if (it->line_wrap == TRUNCATE)
2989 it->last_visible_x -= it->truncation_pixel_width;
2990 else
2991 it->last_visible_x -= it->continuation_pixel_width;
2994 it->header_line_p = window_wants_header_line (w);
2995 it->current_y = WINDOW_HEADER_LINE_HEIGHT (w) + w->vscroll;
2998 /* Leave room for a border glyph. */
2999 if (!FRAME_WINDOW_P (it->f)
3000 && !WINDOW_RIGHTMOST_P (it->w))
3001 it->last_visible_x -= 1;
3003 it->last_visible_y = window_text_bottom_y (w);
3005 /* For mode lines and alike, arrange for the first glyph having a
3006 left box line if the face specifies a box. */
3007 if (base_face_id != DEFAULT_FACE_ID)
3009 struct face *face;
3011 it->face_id = remapped_base_face_id;
3013 /* If we have a boxed mode line, make the first character appear
3014 with a left box line. */
3015 face = FACE_FROM_ID_OR_NULL (it->f, remapped_base_face_id);
3016 if (face && face->box != FACE_NO_BOX)
3017 it->start_of_box_run_p = true;
3020 /* If a buffer position was specified, set the iterator there,
3021 getting overlays and face properties from that position. */
3022 if (charpos >= BUF_BEG (current_buffer))
3024 it->stop_charpos = charpos;
3025 it->end_charpos = ZV;
3026 eassert (charpos == BYTE_TO_CHAR (bytepos));
3027 IT_CHARPOS (*it) = charpos;
3028 IT_BYTEPOS (*it) = bytepos;
3030 /* We will rely on `reseat' to set this up properly, via
3031 handle_face_prop. */
3032 it->face_id = it->base_face_id;
3034 it->start = it->current;
3035 /* Do we need to reorder bidirectional text? Not if this is a
3036 unibyte buffer: by definition, none of the single-byte
3037 characters are strong R2L, so no reordering is needed. And
3038 bidi.c doesn't support unibyte buffers anyway. Also, don't
3039 reorder while we are loading loadup.el, since the tables of
3040 character properties needed for reordering are not yet
3041 available. */
3042 it->bidi_p =
3043 !redisplay__inhibit_bidi
3044 && !NILP (BVAR (current_buffer, bidi_display_reordering))
3045 && it->multibyte_p;
3047 /* If we are to reorder bidirectional text, init the bidi
3048 iterator. */
3049 if (it->bidi_p)
3051 /* Since we don't know at this point whether there will be
3052 any R2L lines in the window, we reserve space for
3053 truncation/continuation glyphs even if only the left
3054 fringe is absent. */
3055 if (base_face_id == DEFAULT_FACE_ID
3056 && WINDOW_LEFT_FRINGE_WIDTH (it->w) == 0
3057 && WINDOW_RIGHT_FRINGE_WIDTH (it->w) != 0)
3059 if (it->line_wrap == TRUNCATE)
3060 it->last_visible_x -= it->truncation_pixel_width;
3061 else
3062 it->last_visible_x -= it->continuation_pixel_width;
3064 /* Note the paragraph direction that this buffer wants to
3065 use. */
3066 if (EQ (BVAR (current_buffer, bidi_paragraph_direction),
3067 Qleft_to_right))
3068 it->paragraph_embedding = L2R;
3069 else if (EQ (BVAR (current_buffer, bidi_paragraph_direction),
3070 Qright_to_left))
3071 it->paragraph_embedding = R2L;
3072 else
3073 it->paragraph_embedding = NEUTRAL_DIR;
3074 bidi_unshelve_cache (NULL, false);
3075 bidi_init_it (charpos, IT_BYTEPOS (*it), FRAME_WINDOW_P (it->f),
3076 &it->bidi_it);
3079 /* Compute faces etc. */
3080 reseat (it, it->current.pos, true);
3083 CHECK_IT (it);
3087 /* Initialize IT for the display of window W with window start POS. */
3089 void
3090 start_display (struct it *it, struct window *w, struct text_pos pos)
3092 struct glyph_row *row;
3093 bool first_vpos = window_wants_header_line (w);
3095 row = w->desired_matrix->rows + first_vpos;
3096 init_iterator (it, w, CHARPOS (pos), BYTEPOS (pos), row, DEFAULT_FACE_ID);
3097 it->first_vpos = first_vpos;
3099 /* Don't reseat to previous visible line start if current start
3100 position is in a string or image. */
3101 if (it->method == GET_FROM_BUFFER && it->line_wrap != TRUNCATE)
3103 int first_y = it->current_y;
3105 /* If window start is not at a line start, skip forward to POS to
3106 get the correct continuation lines width. */
3107 bool start_at_line_beg_p = (CHARPOS (pos) == BEGV
3108 || FETCH_BYTE (BYTEPOS (pos) - 1) == '\n');
3109 if (!start_at_line_beg_p)
3111 int new_x;
3113 reseat_at_previous_visible_line_start (it);
3114 move_it_to (it, CHARPOS (pos), -1, -1, -1, MOVE_TO_POS);
3116 new_x = it->current_x + it->pixel_width;
3118 /* If lines are continued, this line may end in the middle
3119 of a multi-glyph character (e.g. a control character
3120 displayed as \003, or in the middle of an overlay
3121 string). In this case move_it_to above will not have
3122 taken us to the start of the continuation line but to the
3123 end of the continued line. */
3124 if (it->current_x > 0
3125 && it->line_wrap != TRUNCATE /* Lines are continued. */
3126 && (/* And glyph doesn't fit on the line. */
3127 new_x > it->last_visible_x
3128 /* Or it fits exactly and we're on a window
3129 system frame. */
3130 || (new_x == it->last_visible_x
3131 && FRAME_WINDOW_P (it->f)
3132 && ((it->bidi_p && it->bidi_it.paragraph_dir == R2L)
3133 ? WINDOW_LEFT_FRINGE_WIDTH (it->w)
3134 : WINDOW_RIGHT_FRINGE_WIDTH (it->w)))))
3136 if ((it->current.dpvec_index >= 0
3137 || it->current.overlay_string_index >= 0)
3138 /* If we are on a newline from a display vector or
3139 overlay string, then we are already at the end of
3140 a screen line; no need to go to the next line in
3141 that case, as this line is not really continued.
3142 (If we do go to the next line, C-e will not DTRT.) */
3143 && it->c != '\n')
3145 set_iterator_to_next (it, true);
3146 move_it_in_display_line_to (it, -1, -1, 0);
3149 it->continuation_lines_width += it->current_x;
3151 /* If the character at POS is displayed via a display
3152 vector, move_it_to above stops at the final glyph of
3153 IT->dpvec. To make the caller redisplay that character
3154 again (a.k.a. start at POS), we need to reset the
3155 dpvec_index to the beginning of IT->dpvec. */
3156 else if (it->current.dpvec_index >= 0)
3157 it->current.dpvec_index = 0;
3159 /* We're starting a new display line, not affected by the
3160 height of the continued line, so clear the appropriate
3161 fields in the iterator structure. */
3162 it->max_ascent = it->max_descent = 0;
3163 it->max_phys_ascent = it->max_phys_descent = 0;
3165 it->current_y = first_y;
3166 it->vpos = 0;
3167 it->current_x = it->hpos = 0;
3173 /* Return true if POS is a position in ellipses displayed for invisible
3174 text. W is the window we display, for text property lookup. */
3176 static bool
3177 in_ellipses_for_invisible_text_p (struct display_pos *pos, struct window *w)
3179 Lisp_Object prop, window;
3180 bool ellipses_p = false;
3181 ptrdiff_t charpos = CHARPOS (pos->pos);
3183 /* If POS specifies a position in a display vector, this might
3184 be for an ellipsis displayed for invisible text. We won't
3185 get the iterator set up for delivering that ellipsis unless
3186 we make sure that it gets aware of the invisible text. */
3187 if (pos->dpvec_index >= 0
3188 && pos->overlay_string_index < 0
3189 && CHARPOS (pos->string_pos) < 0
3190 && charpos > BEGV
3191 && (XSETWINDOW (window, w),
3192 prop = Fget_char_property (make_number (charpos),
3193 Qinvisible, window),
3194 TEXT_PROP_MEANS_INVISIBLE (prop) == 0))
3196 prop = Fget_char_property (make_number (charpos - 1), Qinvisible,
3197 window);
3198 ellipses_p = 2 == TEXT_PROP_MEANS_INVISIBLE (prop);
3201 return ellipses_p;
3205 /* Initialize IT for stepping through current_buffer in window W,
3206 starting at position POS that includes overlay string and display
3207 vector/ control character translation position information. Value
3208 is false if there are overlay strings with newlines at POS. */
3210 static bool
3211 init_from_display_pos (struct it *it, struct window *w, struct display_pos *pos)
3213 ptrdiff_t charpos = CHARPOS (pos->pos), bytepos = BYTEPOS (pos->pos);
3214 int i;
3215 bool overlay_strings_with_newlines = false;
3217 /* If POS specifies a position in a display vector, this might
3218 be for an ellipsis displayed for invisible text. We won't
3219 get the iterator set up for delivering that ellipsis unless
3220 we make sure that it gets aware of the invisible text. */
3221 if (in_ellipses_for_invisible_text_p (pos, w))
3223 --charpos;
3224 bytepos = 0;
3227 /* Keep in mind: the call to reseat in init_iterator skips invisible
3228 text, so we might end up at a position different from POS. This
3229 is only a problem when POS is a row start after a newline and an
3230 overlay starts there with an after-string, and the overlay has an
3231 invisible property. Since we don't skip invisible text in
3232 display_line and elsewhere immediately after consuming the
3233 newline before the row start, such a POS will not be in a string,
3234 but the call to init_iterator below will move us to the
3235 after-string. */
3236 init_iterator (it, w, charpos, bytepos, NULL, DEFAULT_FACE_ID);
3238 /* This only scans the current chunk -- it should scan all chunks.
3239 However, OVERLAY_STRING_CHUNK_SIZE has been increased from 3 in 21.1
3240 to 16 in 22.1 to make this a lesser problem. */
3241 for (i = 0; i < it->n_overlay_strings && i < OVERLAY_STRING_CHUNK_SIZE; ++i)
3243 const char *s = SSDATA (it->overlay_strings[i]);
3244 const char *e = s + SBYTES (it->overlay_strings[i]);
3246 while (s < e && *s != '\n')
3247 ++s;
3249 if (s < e)
3251 overlay_strings_with_newlines = true;
3252 break;
3256 /* If position is within an overlay string, set up IT to the right
3257 overlay string. */
3258 if (pos->overlay_string_index >= 0)
3260 int relative_index;
3262 /* If the first overlay string happens to have a `display'
3263 property for an image, the iterator will be set up for that
3264 image, and we have to undo that setup first before we can
3265 correct the overlay string index. */
3266 if (it->method == GET_FROM_IMAGE)
3267 pop_it (it);
3269 /* We already have the first chunk of overlay strings in
3270 IT->overlay_strings. Load more until the one for
3271 pos->overlay_string_index is in IT->overlay_strings. */
3272 if (pos->overlay_string_index >= OVERLAY_STRING_CHUNK_SIZE)
3274 ptrdiff_t n = pos->overlay_string_index / OVERLAY_STRING_CHUNK_SIZE;
3275 it->current.overlay_string_index = 0;
3276 while (n--)
3278 load_overlay_strings (it, 0);
3279 it->current.overlay_string_index += OVERLAY_STRING_CHUNK_SIZE;
3283 it->current.overlay_string_index = pos->overlay_string_index;
3284 relative_index = (it->current.overlay_string_index
3285 % OVERLAY_STRING_CHUNK_SIZE);
3286 it->string = it->overlay_strings[relative_index];
3287 eassert (STRINGP (it->string));
3288 it->current.string_pos = pos->string_pos;
3289 it->method = GET_FROM_STRING;
3290 it->end_charpos = SCHARS (it->string);
3291 /* Set up the bidi iterator for this overlay string. */
3292 if (it->bidi_p)
3294 it->bidi_it.string.lstring = it->string;
3295 it->bidi_it.string.s = NULL;
3296 it->bidi_it.string.schars = SCHARS (it->string);
3297 it->bidi_it.string.bufpos = it->overlay_strings_charpos;
3298 it->bidi_it.string.from_disp_str = it->string_from_display_prop_p;
3299 it->bidi_it.string.unibyte = !it->multibyte_p;
3300 it->bidi_it.w = it->w;
3301 bidi_init_it (IT_STRING_CHARPOS (*it), IT_STRING_BYTEPOS (*it),
3302 FRAME_WINDOW_P (it->f), &it->bidi_it);
3304 /* Synchronize the state of the bidi iterator with
3305 pos->string_pos. For any string position other than
3306 zero, this will be done automagically when we resume
3307 iteration over the string and get_visually_first_element
3308 is called. But if string_pos is zero, and the string is
3309 to be reordered for display, we need to resync manually,
3310 since it could be that the iteration state recorded in
3311 pos ended at string_pos of 0 moving backwards in string. */
3312 if (CHARPOS (pos->string_pos) == 0)
3314 get_visually_first_element (it);
3315 if (IT_STRING_CHARPOS (*it) != 0)
3316 do {
3317 /* Paranoia. */
3318 eassert (it->bidi_it.charpos < it->bidi_it.string.schars);
3319 bidi_move_to_visually_next (&it->bidi_it);
3320 } while (it->bidi_it.charpos != 0);
3322 eassert (IT_STRING_CHARPOS (*it) == it->bidi_it.charpos
3323 && IT_STRING_BYTEPOS (*it) == it->bidi_it.bytepos);
3327 if (CHARPOS (pos->string_pos) >= 0)
3329 /* Recorded position is not in an overlay string, but in another
3330 string. This can only be a string from a `display' property.
3331 IT should already be filled with that string. */
3332 it->current.string_pos = pos->string_pos;
3333 eassert (STRINGP (it->string));
3334 if (it->bidi_p)
3335 bidi_init_it (IT_STRING_CHARPOS (*it), IT_STRING_BYTEPOS (*it),
3336 FRAME_WINDOW_P (it->f), &it->bidi_it);
3339 /* Restore position in display vector translations, control
3340 character translations or ellipses. */
3341 if (pos->dpvec_index >= 0)
3343 if (it->dpvec == NULL)
3344 get_next_display_element (it);
3345 eassert (it->dpvec && it->current.dpvec_index == 0);
3346 it->current.dpvec_index = pos->dpvec_index;
3349 CHECK_IT (it);
3350 return !overlay_strings_with_newlines;
3354 /* Initialize IT for stepping through current_buffer in window W
3355 starting at ROW->start. */
3357 static void
3358 init_to_row_start (struct it *it, struct window *w, struct glyph_row *row)
3360 init_from_display_pos (it, w, &row->start);
3361 it->start = row->start;
3362 it->continuation_lines_width = row->continuation_lines_width;
3363 CHECK_IT (it);
3367 /* Initialize IT for stepping through current_buffer in window W
3368 starting in the line following ROW, i.e. starting at ROW->end.
3369 Value is false if there are overlay strings with newlines at ROW's
3370 end position. */
3372 static bool
3373 init_to_row_end (struct it *it, struct window *w, struct glyph_row *row)
3375 bool success = false;
3377 if (init_from_display_pos (it, w, &row->end))
3379 if (row->continued_p)
3380 it->continuation_lines_width
3381 = row->continuation_lines_width + row->pixel_width;
3382 CHECK_IT (it);
3383 success = true;
3386 return success;
3392 /***********************************************************************
3393 Text properties
3394 ***********************************************************************/
3396 /* Called when IT reaches IT->stop_charpos. Handle text property and
3397 overlay changes. Set IT->stop_charpos to the next position where
3398 to stop. */
3400 static void
3401 handle_stop (struct it *it)
3403 enum prop_handled handled;
3404 bool handle_overlay_change_p;
3405 struct props *p;
3407 it->dpvec = NULL;
3408 it->current.dpvec_index = -1;
3409 handle_overlay_change_p = !it->ignore_overlay_strings_at_pos_p;
3410 it->ellipsis_p = false;
3412 /* Use face of preceding text for ellipsis (if invisible) */
3413 if (it->selective_display_ellipsis_p)
3414 it->saved_face_id = it->face_id;
3416 /* Here's the description of the semantics of, and the logic behind,
3417 the various HANDLED_* statuses:
3419 HANDLED_NORMALLY means the handler did its job, and the loop
3420 should proceed to calling the next handler in order.
3422 HANDLED_RECOMPUTE_PROPS means the handler caused a significant
3423 change in the properties and overlays at current position, so the
3424 loop should be restarted, to re-invoke the handlers that were
3425 already called. This happens when fontification-functions were
3426 called by handle_fontified_prop, and actually fontified
3427 something. Another case where HANDLED_RECOMPUTE_PROPS is
3428 returned is when we discover overlay strings that need to be
3429 displayed right away. The loop below will continue for as long
3430 as the status is HANDLED_RECOMPUTE_PROPS.
3432 HANDLED_RETURN means return immediately to the caller, to
3433 continue iteration without calling any further handlers. This is
3434 used when we need to act on some property right away, for example
3435 when we need to display the ellipsis or a replacing display
3436 property, such as display string or image.
3438 HANDLED_OVERLAY_STRING_CONSUMED means an overlay string was just
3439 consumed, and the handler switched to the next overlay string.
3440 This signals the loop below to refrain from looking for more
3441 overlays before all the overlay strings of the current overlay
3442 are processed.
3444 Some of the handlers called by the loop push the iterator state
3445 onto the stack (see 'push_it'), and arrange for the iteration to
3446 continue with another object, such as an image, a display string,
3447 or an overlay string. In most such cases, it->stop_charpos is
3448 set to the first character of the string, so that when the
3449 iteration resumes, this function will immediately be called
3450 again, to examine the properties at the beginning of the string.
3452 When a display or overlay string is exhausted, the iterator state
3453 is popped (see 'pop_it'), and iteration continues with the
3454 previous object. Again, in many such cases this function is
3455 called again to find the next position where properties might
3456 change. */
3460 handled = HANDLED_NORMALLY;
3462 /* Call text property handlers. */
3463 for (p = it_props; p->handler; ++p)
3465 handled = p->handler (it);
3467 if (handled == HANDLED_RECOMPUTE_PROPS)
3468 break;
3469 else if (handled == HANDLED_RETURN)
3471 /* We still want to show before and after strings from
3472 overlays even if the actual buffer text is replaced. */
3473 if (!handle_overlay_change_p
3474 || it->sp > 1
3475 /* Don't call get_overlay_strings_1 if we already
3476 have overlay strings loaded, because doing so
3477 will load them again and push the iterator state
3478 onto the stack one more time, which is not
3479 expected by the rest of the code that processes
3480 overlay strings. */
3481 || (it->current.overlay_string_index < 0
3482 && !get_overlay_strings_1 (it, 0, false)))
3484 if (it->ellipsis_p)
3485 setup_for_ellipsis (it, 0);
3486 /* When handling a display spec, we might load an
3487 empty string. In that case, discard it here. We
3488 used to discard it in handle_single_display_spec,
3489 but that causes get_overlay_strings_1, above, to
3490 ignore overlay strings that we must check. */
3491 if (STRINGP (it->string) && !SCHARS (it->string))
3492 pop_it (it);
3493 return;
3495 else if (STRINGP (it->string) && !SCHARS (it->string))
3496 pop_it (it);
3497 else
3499 it->string_from_display_prop_p = false;
3500 it->from_disp_prop_p = false;
3501 handle_overlay_change_p = false;
3503 handled = HANDLED_RECOMPUTE_PROPS;
3504 break;
3506 else if (handled == HANDLED_OVERLAY_STRING_CONSUMED)
3507 handle_overlay_change_p = false;
3510 if (handled != HANDLED_RECOMPUTE_PROPS)
3512 /* Don't check for overlay strings below when set to deliver
3513 characters from a display vector. */
3514 if (it->method == GET_FROM_DISPLAY_VECTOR)
3515 handle_overlay_change_p = false;
3517 /* Handle overlay changes.
3518 This sets HANDLED to HANDLED_RECOMPUTE_PROPS
3519 if it finds overlays. */
3520 if (handle_overlay_change_p)
3521 handled = handle_overlay_change (it);
3524 if (it->ellipsis_p)
3526 setup_for_ellipsis (it, 0);
3527 break;
3530 while (handled == HANDLED_RECOMPUTE_PROPS);
3532 /* Determine where to stop next. */
3533 if (handled == HANDLED_NORMALLY)
3534 compute_stop_pos (it);
3538 /* Compute IT->stop_charpos from text property and overlay change
3539 information for IT's current position. */
3541 static void
3542 compute_stop_pos (struct it *it)
3544 register INTERVAL iv, next_iv;
3545 Lisp_Object object, limit, position;
3546 ptrdiff_t charpos, bytepos;
3548 if (STRINGP (it->string))
3550 /* Strings are usually short, so don't limit the search for
3551 properties. */
3552 it->stop_charpos = it->end_charpos;
3553 object = it->string;
3554 limit = Qnil;
3555 charpos = IT_STRING_CHARPOS (*it);
3556 bytepos = IT_STRING_BYTEPOS (*it);
3558 else
3560 ptrdiff_t pos;
3562 /* If end_charpos is out of range for some reason, such as a
3563 misbehaving display function, rationalize it (Bug#5984). */
3564 if (it->end_charpos > ZV)
3565 it->end_charpos = ZV;
3566 it->stop_charpos = it->end_charpos;
3568 /* If next overlay change is in front of the current stop pos
3569 (which is IT->end_charpos), stop there. Note: value of
3570 next_overlay_change is point-max if no overlay change
3571 follows. */
3572 charpos = IT_CHARPOS (*it);
3573 bytepos = IT_BYTEPOS (*it);
3574 pos = next_overlay_change (charpos);
3575 if (pos < it->stop_charpos)
3576 it->stop_charpos = pos;
3578 /* Set up variables for computing the stop position from text
3579 property changes. */
3580 XSETBUFFER (object, current_buffer);
3581 limit = make_number (IT_CHARPOS (*it) + TEXT_PROP_DISTANCE_LIMIT);
3584 /* Get the interval containing IT's position. Value is a null
3585 interval if there isn't such an interval. */
3586 position = make_number (charpos);
3587 iv = validate_interval_range (object, &position, &position, false);
3588 if (iv)
3590 Lisp_Object values_here[LAST_PROP_IDX];
3591 struct props *p;
3593 /* Get properties here. */
3594 for (p = it_props; p->handler; ++p)
3595 values_here[p->idx] = textget (iv->plist,
3596 builtin_lisp_symbol (p->name));
3598 /* Look for an interval following iv that has different
3599 properties. */
3600 for (next_iv = next_interval (iv);
3601 (next_iv
3602 && (NILP (limit)
3603 || XFASTINT (limit) > next_iv->position));
3604 next_iv = next_interval (next_iv))
3606 for (p = it_props; p->handler; ++p)
3608 Lisp_Object new_value = textget (next_iv->plist,
3609 builtin_lisp_symbol (p->name));
3610 if (!EQ (values_here[p->idx], new_value))
3611 break;
3614 if (p->handler)
3615 break;
3618 if (next_iv)
3620 if (INTEGERP (limit)
3621 && next_iv->position >= XFASTINT (limit))
3622 /* No text property change up to limit. */
3623 it->stop_charpos = min (XFASTINT (limit), it->stop_charpos);
3624 else
3625 /* Text properties change in next_iv. */
3626 it->stop_charpos = min (it->stop_charpos, next_iv->position);
3630 if (it->cmp_it.id < 0)
3632 ptrdiff_t stoppos = it->end_charpos;
3634 if (it->bidi_p && it->bidi_it.scan_dir < 0)
3635 stoppos = -1;
3636 composition_compute_stop_pos (&it->cmp_it, charpos, bytepos,
3637 stoppos, it->string);
3640 eassert (STRINGP (it->string)
3641 || (it->stop_charpos >= BEGV
3642 && it->stop_charpos >= IT_CHARPOS (*it)));
3646 /* Return the position of the next overlay change after POS in
3647 current_buffer. Value is point-max if no overlay change
3648 follows. This is like `next-overlay-change' but doesn't use
3649 xmalloc. */
3651 static ptrdiff_t
3652 next_overlay_change (ptrdiff_t pos)
3654 ptrdiff_t i, noverlays;
3655 ptrdiff_t endpos;
3656 Lisp_Object *overlays;
3657 USE_SAFE_ALLOCA;
3659 /* Get all overlays at the given position. */
3660 GET_OVERLAYS_AT (pos, overlays, noverlays, &endpos, true);
3662 /* If any of these overlays ends before endpos,
3663 use its ending point instead. */
3664 for (i = 0; i < noverlays; ++i)
3666 Lisp_Object oend;
3667 ptrdiff_t oendpos;
3669 oend = OVERLAY_END (overlays[i]);
3670 oendpos = OVERLAY_POSITION (oend);
3671 endpos = min (endpos, oendpos);
3674 SAFE_FREE ();
3675 return endpos;
3678 /* How many characters forward to search for a display property or
3679 display string. Searching too far forward makes the bidi display
3680 sluggish, especially in small windows. */
3681 #define MAX_DISP_SCAN 250
3683 /* Return the character position of a display string at or after
3684 position specified by POSITION. If no display string exists at or
3685 after POSITION, return ZV. A display string is either an overlay
3686 with `display' property whose value is a string, or a `display'
3687 text property whose value is a string. STRING is data about the
3688 string to iterate; if STRING->lstring is nil, we are iterating a
3689 buffer. FRAME_WINDOW_P is true when we are displaying a window
3690 on a GUI frame. DISP_PROP is set to zero if we searched
3691 MAX_DISP_SCAN characters forward without finding any display
3692 strings, non-zero otherwise. It is set to 2 if the display string
3693 uses any kind of `(space ...)' spec that will produce a stretch of
3694 white space in the text area. */
3695 ptrdiff_t
3696 compute_display_string_pos (struct text_pos *position,
3697 struct bidi_string_data *string,
3698 struct window *w,
3699 bool frame_window_p, int *disp_prop)
3701 /* OBJECT = nil means current buffer. */
3702 Lisp_Object object, object1;
3703 Lisp_Object pos, spec, limpos;
3704 bool string_p = string && (STRINGP (string->lstring) || string->s);
3705 ptrdiff_t eob = string_p ? string->schars : ZV;
3706 ptrdiff_t begb = string_p ? 0 : BEGV;
3707 ptrdiff_t bufpos, charpos = CHARPOS (*position);
3708 ptrdiff_t lim =
3709 (charpos < eob - MAX_DISP_SCAN) ? charpos + MAX_DISP_SCAN : eob;
3710 struct text_pos tpos;
3711 int rv = 0;
3713 if (string && STRINGP (string->lstring))
3714 object1 = object = string->lstring;
3715 else if (w && !string_p)
3717 XSETWINDOW (object, w);
3718 object1 = Qnil;
3720 else
3721 object1 = object = Qnil;
3723 *disp_prop = 1;
3725 if (charpos >= eob
3726 /* We don't support display properties whose values are strings
3727 that have display string properties. */
3728 || string->from_disp_str
3729 /* C strings cannot have display properties. */
3730 || (string->s && !STRINGP (object)))
3732 *disp_prop = 0;
3733 return eob;
3736 /* If the character at CHARPOS is where the display string begins,
3737 return CHARPOS. */
3738 pos = make_number (charpos);
3739 if (STRINGP (object))
3740 bufpos = string->bufpos;
3741 else
3742 bufpos = charpos;
3743 tpos = *position;
3744 if (!NILP (spec = Fget_char_property (pos, Qdisplay, object))
3745 && (charpos <= begb
3746 || !EQ (Fget_char_property (make_number (charpos - 1), Qdisplay,
3747 object),
3748 spec))
3749 && (rv = handle_display_spec (NULL, spec, object, Qnil, &tpos, bufpos,
3750 frame_window_p)))
3752 if (rv == 2)
3753 *disp_prop = 2;
3754 return charpos;
3757 /* Look forward for the first character with a `display' property
3758 that will replace the underlying text when displayed. */
3759 limpos = make_number (lim);
3760 do {
3761 pos = Fnext_single_char_property_change (pos, Qdisplay, object1, limpos);
3762 CHARPOS (tpos) = XFASTINT (pos);
3763 if (CHARPOS (tpos) >= lim)
3765 *disp_prop = 0;
3766 break;
3768 if (STRINGP (object))
3769 BYTEPOS (tpos) = string_char_to_byte (object, CHARPOS (tpos));
3770 else
3771 BYTEPOS (tpos) = CHAR_TO_BYTE (CHARPOS (tpos));
3772 spec = Fget_char_property (pos, Qdisplay, object);
3773 if (!STRINGP (object))
3774 bufpos = CHARPOS (tpos);
3775 } while (NILP (spec)
3776 || !(rv = handle_display_spec (NULL, spec, object, Qnil, &tpos,
3777 bufpos, frame_window_p)));
3778 if (rv == 2)
3779 *disp_prop = 2;
3781 return CHARPOS (tpos);
3784 /* Return the character position of the end of the display string that
3785 started at CHARPOS. If there's no display string at CHARPOS,
3786 return -1. A display string is either an overlay with `display'
3787 property whose value is a string or a `display' text property whose
3788 value is a string. */
3789 ptrdiff_t
3790 compute_display_string_end (ptrdiff_t charpos, struct bidi_string_data *string)
3792 /* OBJECT = nil means current buffer. */
3793 Lisp_Object object =
3794 (string && STRINGP (string->lstring)) ? string->lstring : Qnil;
3795 Lisp_Object pos = make_number (charpos);
3796 ptrdiff_t eob =
3797 (STRINGP (object) || (string && string->s)) ? string->schars : ZV;
3799 if (charpos >= eob || (string->s && !STRINGP (object)))
3800 return eob;
3802 /* It could happen that the display property or overlay was removed
3803 since we found it in compute_display_string_pos above. One way
3804 this can happen is if JIT font-lock was called (through
3805 handle_fontified_prop), and jit-lock-functions remove text
3806 properties or overlays from the portion of buffer that includes
3807 CHARPOS. Muse mode is known to do that, for example. In this
3808 case, we return -1 to the caller, to signal that no display
3809 string is actually present at CHARPOS. See bidi_fetch_char for
3810 how this is handled.
3812 An alternative would be to never look for display properties past
3813 it->stop_charpos. But neither compute_display_string_pos nor
3814 bidi_fetch_char that calls it know or care where the next
3815 stop_charpos is. */
3816 if (NILP (Fget_char_property (pos, Qdisplay, object)))
3817 return -1;
3819 /* Look forward for the first character where the `display' property
3820 changes. */
3821 pos = Fnext_single_char_property_change (pos, Qdisplay, object, Qnil);
3823 return XFASTINT (pos);
3828 /***********************************************************************
3829 Fontification
3830 ***********************************************************************/
3832 /* Handle changes in the `fontified' property of the current buffer by
3833 calling hook functions from Qfontification_functions to fontify
3834 regions of text. */
3836 static enum prop_handled
3837 handle_fontified_prop (struct it *it)
3839 Lisp_Object prop, pos;
3840 enum prop_handled handled = HANDLED_NORMALLY;
3842 if (!NILP (Vmemory_full))
3843 return handled;
3845 /* Get the value of the `fontified' property at IT's current buffer
3846 position. (The `fontified' property doesn't have a special
3847 meaning in strings.) If the value is nil, call functions from
3848 Qfontification_functions. */
3849 if (!STRINGP (it->string)
3850 && it->s == NULL
3851 && !NILP (Vfontification_functions)
3852 && !NILP (Vrun_hooks)
3853 && (pos = make_number (IT_CHARPOS (*it)),
3854 prop = Fget_char_property (pos, Qfontified, Qnil),
3855 /* Ignore the special cased nil value always present at EOB since
3856 no amount of fontifying will be able to change it. */
3857 NILP (prop) && IT_CHARPOS (*it) < Z))
3859 ptrdiff_t count = SPECPDL_INDEX ();
3860 Lisp_Object val;
3861 struct buffer *obuf = current_buffer;
3862 ptrdiff_t begv = BEGV, zv = ZV;
3863 bool old_clip_changed = current_buffer->clip_changed;
3865 val = Vfontification_functions;
3866 specbind (Qfontification_functions, Qnil);
3868 eassert (it->end_charpos == ZV);
3870 if (!CONSP (val) || EQ (XCAR (val), Qlambda))
3871 safe_call1 (val, pos);
3872 else
3874 Lisp_Object fns, fn;
3876 fns = Qnil;
3878 for (; CONSP (val); val = XCDR (val))
3880 fn = XCAR (val);
3882 if (EQ (fn, Qt))
3884 /* A value of t indicates this hook has a local
3885 binding; it means to run the global binding too.
3886 In a global value, t should not occur. If it
3887 does, we must ignore it to avoid an endless
3888 loop. */
3889 for (fns = Fdefault_value (Qfontification_functions);
3890 CONSP (fns);
3891 fns = XCDR (fns))
3893 fn = XCAR (fns);
3894 if (!EQ (fn, Qt))
3895 safe_call1 (fn, pos);
3898 else
3899 safe_call1 (fn, pos);
3903 unbind_to (count, Qnil);
3905 /* Fontification functions routinely call `save-restriction'.
3906 Normally, this tags clip_changed, which can confuse redisplay
3907 (see discussion in Bug#6671). Since we don't perform any
3908 special handling of fontification changes in the case where
3909 `save-restriction' isn't called, there's no point doing so in
3910 this case either. So, if the buffer's restrictions are
3911 actually left unchanged, reset clip_changed. */
3912 if (obuf == current_buffer)
3914 if (begv == BEGV && zv == ZV)
3915 current_buffer->clip_changed = old_clip_changed;
3917 /* There isn't much we can reasonably do to protect against
3918 misbehaving fontification, but here's a fig leaf. */
3919 else if (BUFFER_LIVE_P (obuf))
3920 set_buffer_internal_1 (obuf);
3922 /* The fontification code may have added/removed text.
3923 It could do even a lot worse, but let's at least protect against
3924 the most obvious case where only the text past `pos' gets changed',
3925 as is/was done in grep.el where some escapes sequences are turned
3926 into face properties (bug#7876). */
3927 it->end_charpos = ZV;
3929 /* Return HANDLED_RECOMPUTE_PROPS only if function fontified
3930 something. This avoids an endless loop if they failed to
3931 fontify the text for which reason ever. */
3932 if (!NILP (Fget_char_property (pos, Qfontified, Qnil)))
3933 handled = HANDLED_RECOMPUTE_PROPS;
3936 return handled;
3941 /***********************************************************************
3942 Faces
3943 ***********************************************************************/
3945 /* Set up iterator IT from face properties at its current position.
3946 Called from handle_stop. */
3948 static enum prop_handled
3949 handle_face_prop (struct it *it)
3951 int new_face_id;
3952 ptrdiff_t next_stop;
3954 if (!STRINGP (it->string))
3956 new_face_id
3957 = face_at_buffer_position (it->w,
3958 IT_CHARPOS (*it),
3959 &next_stop,
3960 (IT_CHARPOS (*it)
3961 + TEXT_PROP_DISTANCE_LIMIT),
3962 false, it->base_face_id);
3964 /* Is this a start of a run of characters with box face?
3965 Caveat: this can be called for a freshly initialized
3966 iterator; face_id is -1 in this case. We know that the new
3967 face will not change until limit, i.e. if the new face has a
3968 box, all characters up to limit will have one. But, as
3969 usual, we don't know whether limit is really the end. */
3970 if (new_face_id != it->face_id)
3972 struct face *new_face = FACE_FROM_ID (it->f, new_face_id);
3973 /* If it->face_id is -1, old_face below will be NULL, see
3974 the definition of FACE_FROM_ID_OR_NULL. This will happen
3975 if this is the initial call that gets the face. */
3976 struct face *old_face = FACE_FROM_ID_OR_NULL (it->f, it->face_id);
3978 /* If the value of face_id of the iterator is -1, we have to
3979 look in front of IT's position and see whether there is a
3980 face there that's different from new_face_id. */
3981 if (!old_face && IT_CHARPOS (*it) > BEG)
3983 int prev_face_id = face_before_it_pos (it);
3985 old_face = FACE_FROM_ID_OR_NULL (it->f, prev_face_id);
3988 /* If the new face has a box, but the old face does not,
3989 this is the start of a run of characters with box face,
3990 i.e. this character has a shadow on the left side. */
3991 it->start_of_box_run_p = (new_face->box != FACE_NO_BOX
3992 && (old_face == NULL || !old_face->box));
3993 it->face_box_p = new_face->box != FACE_NO_BOX;
3996 else
3998 int base_face_id;
3999 ptrdiff_t bufpos;
4000 int i;
4001 Lisp_Object from_overlay
4002 = (it->current.overlay_string_index >= 0
4003 ? it->string_overlays[it->current.overlay_string_index
4004 % OVERLAY_STRING_CHUNK_SIZE]
4005 : Qnil);
4007 /* See if we got to this string directly or indirectly from
4008 an overlay property. That includes the before-string or
4009 after-string of an overlay, strings in display properties
4010 provided by an overlay, their text properties, etc.
4012 FROM_OVERLAY is the overlay that brought us here, or nil if none. */
4013 if (! NILP (from_overlay))
4014 for (i = it->sp - 1; i >= 0; i--)
4016 if (it->stack[i].current.overlay_string_index >= 0)
4017 from_overlay
4018 = it->string_overlays[it->stack[i].current.overlay_string_index
4019 % OVERLAY_STRING_CHUNK_SIZE];
4020 else if (! NILP (it->stack[i].from_overlay))
4021 from_overlay = it->stack[i].from_overlay;
4023 if (!NILP (from_overlay))
4024 break;
4027 if (! NILP (from_overlay))
4029 bufpos = IT_CHARPOS (*it);
4030 /* For a string from an overlay, the base face depends
4031 only on text properties and ignores overlays. */
4032 base_face_id
4033 = face_for_overlay_string (it->w,
4034 IT_CHARPOS (*it),
4035 &next_stop,
4036 (IT_CHARPOS (*it)
4037 + TEXT_PROP_DISTANCE_LIMIT),
4038 false,
4039 from_overlay);
4041 else
4043 bufpos = 0;
4045 /* For strings from a `display' property, use the face at
4046 IT's current buffer position as the base face to merge
4047 with, so that overlay strings appear in the same face as
4048 surrounding text, unless they specify their own faces.
4049 For strings from wrap-prefix and line-prefix properties,
4050 use the default face, possibly remapped via
4051 Vface_remapping_alist. */
4052 /* Note that the fact that we use the face at _buffer_
4053 position means that a 'display' property on an overlay
4054 string will not inherit the face of that overlay string,
4055 but will instead revert to the face of buffer text
4056 covered by the overlay. This is visible, e.g., when the
4057 overlay specifies a box face, but neither the buffer nor
4058 the display string do. This sounds like a design bug,
4059 but Emacs always did that since v21.1, so changing that
4060 might be a big deal. */
4061 base_face_id = it->string_from_prefix_prop_p
4062 ? (!NILP (Vface_remapping_alist)
4063 ? lookup_basic_face (it->f, DEFAULT_FACE_ID)
4064 : DEFAULT_FACE_ID)
4065 : underlying_face_id (it);
4068 new_face_id = face_at_string_position (it->w,
4069 it->string,
4070 IT_STRING_CHARPOS (*it),
4071 bufpos,
4072 &next_stop,
4073 base_face_id, false);
4075 /* Is this a start of a run of characters with box? Caveat:
4076 this can be called for a freshly allocated iterator; face_id
4077 is -1 is this case. We know that the new face will not
4078 change until the next check pos, i.e. if the new face has a
4079 box, all characters up to that position will have a
4080 box. But, as usual, we don't know whether that position
4081 is really the end. */
4082 if (new_face_id != it->face_id)
4084 struct face *new_face = FACE_FROM_ID (it->f, new_face_id);
4085 struct face *old_face = FACE_FROM_ID_OR_NULL (it->f, it->face_id);
4087 /* If new face has a box but old face hasn't, this is the
4088 start of a run of characters with box, i.e. it has a
4089 shadow on the left side. */
4090 it->start_of_box_run_p
4091 = new_face->box && (old_face == NULL || !old_face->box);
4092 it->face_box_p = new_face->box != FACE_NO_BOX;
4096 it->face_id = new_face_id;
4097 return HANDLED_NORMALLY;
4101 /* Return the ID of the face ``underlying'' IT's current position,
4102 which is in a string. If the iterator is associated with a
4103 buffer, return the face at IT's current buffer position.
4104 Otherwise, use the iterator's base_face_id. */
4106 static int
4107 underlying_face_id (struct it *it)
4109 int face_id = it->base_face_id, i;
4111 eassert (STRINGP (it->string));
4113 for (i = it->sp - 1; i >= 0; --i)
4114 if (NILP (it->stack[i].string))
4115 face_id = it->stack[i].face_id;
4117 return face_id;
4121 /* Compute the face one character before or after the current position
4122 of IT, in the visual order. BEFORE_P means get the face
4123 in front (to the left in L2R paragraphs, to the right in R2L
4124 paragraphs) of IT's screen position. Value is the ID of the face. */
4126 static int
4127 face_before_or_after_it_pos (struct it *it, bool before_p)
4129 int face_id, limit;
4130 ptrdiff_t next_check_charpos;
4131 struct it it_copy;
4132 void *it_copy_data = NULL;
4134 eassert (it->s == NULL);
4136 if (STRINGP (it->string))
4138 ptrdiff_t bufpos, charpos;
4139 int base_face_id;
4141 /* No face change past the end of the string (for the case
4142 we are padding with spaces). No face change before the
4143 string start. */
4144 if (IT_STRING_CHARPOS (*it) >= SCHARS (it->string)
4145 || (IT_STRING_CHARPOS (*it) == 0 && before_p))
4146 return it->face_id;
4148 if (!it->bidi_p)
4150 /* Set charpos to the position before or after IT's current
4151 position, in the logical order, which in the non-bidi
4152 case is the same as the visual order. */
4153 if (before_p)
4154 charpos = IT_STRING_CHARPOS (*it) - 1;
4155 else if (it->what == IT_COMPOSITION)
4156 /* For composition, we must check the character after the
4157 composition. */
4158 charpos = IT_STRING_CHARPOS (*it) + it->cmp_it.nchars;
4159 else
4160 charpos = IT_STRING_CHARPOS (*it) + 1;
4162 else
4164 if (before_p)
4166 /* With bidi iteration, the character before the current
4167 in the visual order cannot be found by simple
4168 iteration, because "reverse" reordering is not
4169 supported. Instead, we need to start from the string
4170 beginning and go all the way to the current string
4171 position, remembering the previous position. */
4172 /* Ignore face changes before the first visible
4173 character on this display line. */
4174 if (it->current_x <= it->first_visible_x)
4175 return it->face_id;
4176 SAVE_IT (it_copy, *it, it_copy_data);
4177 IT_STRING_CHARPOS (it_copy) = 0;
4178 bidi_init_it (0, 0, FRAME_WINDOW_P (it_copy.f), &it_copy.bidi_it);
4182 charpos = IT_STRING_CHARPOS (it_copy);
4183 if (charpos >= SCHARS (it->string))
4184 break;
4185 bidi_move_to_visually_next (&it_copy.bidi_it);
4187 while (IT_STRING_CHARPOS (it_copy) != IT_STRING_CHARPOS (*it));
4189 RESTORE_IT (it, it, it_copy_data);
4191 else
4193 /* Set charpos to the string position of the character
4194 that comes after IT's current position in the visual
4195 order. */
4196 int n = (it->what == IT_COMPOSITION ? it->cmp_it.nchars : 1);
4198 it_copy = *it;
4199 while (n--)
4200 bidi_move_to_visually_next (&it_copy.bidi_it);
4202 charpos = it_copy.bidi_it.charpos;
4205 eassert (0 <= charpos && charpos <= SCHARS (it->string));
4207 if (it->current.overlay_string_index >= 0)
4208 bufpos = IT_CHARPOS (*it);
4209 else
4210 bufpos = 0;
4212 base_face_id = underlying_face_id (it);
4214 /* Get the face for ASCII, or unibyte. */
4215 face_id = face_at_string_position (it->w,
4216 it->string,
4217 charpos,
4218 bufpos,
4219 &next_check_charpos,
4220 base_face_id, false);
4222 /* Correct the face for charsets different from ASCII. Do it
4223 for the multibyte case only. The face returned above is
4224 suitable for unibyte text if IT->string is unibyte. */
4225 if (STRING_MULTIBYTE (it->string))
4227 struct text_pos pos1 = string_pos (charpos, it->string);
4228 const unsigned char *p = SDATA (it->string) + BYTEPOS (pos1);
4229 int c, len;
4230 struct face *face = FACE_FROM_ID (it->f, face_id);
4232 c = string_char_and_length (p, &len);
4233 face_id = FACE_FOR_CHAR (it->f, face, c, charpos, it->string);
4236 else
4238 struct text_pos pos;
4240 if ((IT_CHARPOS (*it) >= ZV && !before_p)
4241 || (IT_CHARPOS (*it) <= BEGV && before_p))
4242 return it->face_id;
4244 limit = IT_CHARPOS (*it) + TEXT_PROP_DISTANCE_LIMIT;
4245 pos = it->current.pos;
4247 if (!it->bidi_p)
4249 if (before_p)
4250 DEC_TEXT_POS (pos, it->multibyte_p);
4251 else
4253 if (it->what == IT_COMPOSITION)
4255 /* For composition, we must check the position after
4256 the composition. */
4257 pos.charpos += it->cmp_it.nchars;
4258 pos.bytepos += it->len;
4260 else
4261 INC_TEXT_POS (pos, it->multibyte_p);
4264 else
4266 if (before_p)
4268 int current_x;
4270 /* With bidi iteration, the character before the current
4271 in the visual order cannot be found by simple
4272 iteration, because "reverse" reordering is not
4273 supported. Instead, we need to use the move_it_*
4274 family of functions, and move to the previous
4275 character starting from the beginning of the visual
4276 line. */
4277 /* Ignore face changes before the first visible
4278 character on this display line. */
4279 if (it->current_x <= it->first_visible_x)
4280 return it->face_id;
4281 SAVE_IT (it_copy, *it, it_copy_data);
4282 /* Implementation note: Since move_it_in_display_line
4283 works in the iterator geometry, and thinks the first
4284 character is always the leftmost, even in R2L lines,
4285 we don't need to distinguish between the R2L and L2R
4286 cases here. */
4287 current_x = it_copy.current_x;
4288 move_it_vertically_backward (&it_copy, 0);
4289 move_it_in_display_line (&it_copy, ZV, current_x - 1, MOVE_TO_X);
4290 pos = it_copy.current.pos;
4291 RESTORE_IT (it, it, it_copy_data);
4293 else
4295 /* Set charpos to the buffer position of the character
4296 that comes after IT's current position in the visual
4297 order. */
4298 int n = (it->what == IT_COMPOSITION ? it->cmp_it.nchars : 1);
4300 it_copy = *it;
4301 while (n--)
4302 bidi_move_to_visually_next (&it_copy.bidi_it);
4304 SET_TEXT_POS (pos,
4305 it_copy.bidi_it.charpos, it_copy.bidi_it.bytepos);
4308 eassert (BEGV <= CHARPOS (pos) && CHARPOS (pos) <= ZV);
4310 /* Determine face for CHARSET_ASCII, or unibyte. */
4311 face_id = face_at_buffer_position (it->w,
4312 CHARPOS (pos),
4313 &next_check_charpos,
4314 limit, false, -1);
4316 /* Correct the face for charsets different from ASCII. Do it
4317 for the multibyte case only. The face returned above is
4318 suitable for unibyte text if current_buffer is unibyte. */
4319 if (it->multibyte_p)
4321 int c = FETCH_MULTIBYTE_CHAR (BYTEPOS (pos));
4322 struct face *face = FACE_FROM_ID (it->f, face_id);
4323 face_id = FACE_FOR_CHAR (it->f, face, c, CHARPOS (pos), Qnil);
4327 return face_id;
4332 /***********************************************************************
4333 Invisible text
4334 ***********************************************************************/
4336 /* Set up iterator IT from invisible properties at its current
4337 position. Called from handle_stop. */
4339 static enum prop_handled
4340 handle_invisible_prop (struct it *it)
4342 enum prop_handled handled = HANDLED_NORMALLY;
4343 int invis;
4344 Lisp_Object prop;
4346 if (STRINGP (it->string))
4348 Lisp_Object end_charpos, limit;
4350 /* Get the value of the invisible text property at the
4351 current position. Value will be nil if there is no such
4352 property. */
4353 end_charpos = make_number (IT_STRING_CHARPOS (*it));
4354 prop = Fget_text_property (end_charpos, Qinvisible, it->string);
4355 invis = TEXT_PROP_MEANS_INVISIBLE (prop);
4357 if (invis != 0 && IT_STRING_CHARPOS (*it) < it->end_charpos)
4359 /* Record whether we have to display an ellipsis for the
4360 invisible text. */
4361 bool display_ellipsis_p = (invis == 2);
4362 ptrdiff_t len, endpos;
4364 handled = HANDLED_RECOMPUTE_PROPS;
4366 /* Get the position at which the next visible text can be
4367 found in IT->string, if any. */
4368 endpos = len = SCHARS (it->string);
4369 XSETINT (limit, len);
4372 end_charpos
4373 = Fnext_single_property_change (end_charpos, Qinvisible,
4374 it->string, limit);
4375 /* Since LIMIT is always an integer, so should be the
4376 value returned by Fnext_single_property_change. */
4377 eassert (INTEGERP (end_charpos));
4378 if (INTEGERP (end_charpos))
4380 endpos = XFASTINT (end_charpos);
4381 prop = Fget_text_property (end_charpos, Qinvisible, it->string);
4382 invis = TEXT_PROP_MEANS_INVISIBLE (prop);
4383 if (invis == 2)
4384 display_ellipsis_p = true;
4386 else /* Should never happen; but if it does, exit the loop. */
4387 endpos = len;
4389 while (invis != 0 && endpos < len);
4391 if (display_ellipsis_p)
4392 it->ellipsis_p = true;
4394 if (endpos < len)
4396 /* Text at END_CHARPOS is visible. Move IT there. */
4397 struct text_pos old;
4398 ptrdiff_t oldpos;
4400 old = it->current.string_pos;
4401 oldpos = CHARPOS (old);
4402 if (it->bidi_p)
4404 if (it->bidi_it.first_elt
4405 && it->bidi_it.charpos < SCHARS (it->string))
4406 bidi_paragraph_init (it->paragraph_embedding,
4407 &it->bidi_it, true);
4408 /* Bidi-iterate out of the invisible text. */
4411 bidi_move_to_visually_next (&it->bidi_it);
4413 while (oldpos <= it->bidi_it.charpos
4414 && it->bidi_it.charpos < endpos
4415 && it->bidi_it.charpos < it->bidi_it.string.schars);
4417 IT_STRING_CHARPOS (*it) = it->bidi_it.charpos;
4418 IT_STRING_BYTEPOS (*it) = it->bidi_it.bytepos;
4419 if (IT_CHARPOS (*it) >= endpos)
4420 it->prev_stop = endpos;
4422 else
4424 IT_STRING_CHARPOS (*it) = endpos;
4425 compute_string_pos (&it->current.string_pos, old, it->string);
4428 else
4430 /* The rest of the string is invisible. If this is an
4431 overlay string, proceed with the next overlay string
4432 or whatever comes and return a character from there. */
4433 if (it->current.overlay_string_index >= 0
4434 && !display_ellipsis_p)
4436 next_overlay_string (it);
4437 /* Don't check for overlay strings when we just
4438 finished processing them. */
4439 handled = HANDLED_OVERLAY_STRING_CONSUMED;
4441 else
4443 IT_STRING_CHARPOS (*it) = SCHARS (it->string);
4444 IT_STRING_BYTEPOS (*it) = SBYTES (it->string);
4449 else
4451 ptrdiff_t newpos, next_stop, start_charpos, tem;
4452 Lisp_Object pos, overlay;
4454 /* First of all, is there invisible text at this position? */
4455 tem = start_charpos = IT_CHARPOS (*it);
4456 pos = make_number (tem);
4457 prop = get_char_property_and_overlay (pos, Qinvisible, it->window,
4458 &overlay);
4459 invis = TEXT_PROP_MEANS_INVISIBLE (prop);
4461 /* If we are on invisible text, skip over it. */
4462 if (invis != 0 && start_charpos < it->end_charpos)
4464 /* Record whether we have to display an ellipsis for the
4465 invisible text. */
4466 bool display_ellipsis_p = invis == 2;
4468 handled = HANDLED_RECOMPUTE_PROPS;
4470 /* Loop skipping over invisible text. The loop is left at
4471 ZV or with IT on the first char being visible again. */
4474 /* Try to skip some invisible text. Return value is the
4475 position reached which can be equal to where we start
4476 if there is nothing invisible there. This skips both
4477 over invisible text properties and overlays with
4478 invisible property. */
4479 newpos = skip_invisible (tem, &next_stop, ZV, it->window);
4481 /* If we skipped nothing at all we weren't at invisible
4482 text in the first place. If everything to the end of
4483 the buffer was skipped, end the loop. */
4484 if (newpos == tem || newpos >= ZV)
4485 invis = 0;
4486 else
4488 /* We skipped some characters but not necessarily
4489 all there are. Check if we ended up on visible
4490 text. Fget_char_property returns the property of
4491 the char before the given position, i.e. if we
4492 get invis = 0, this means that the char at
4493 newpos is visible. */
4494 pos = make_number (newpos);
4495 prop = Fget_char_property (pos, Qinvisible, it->window);
4496 invis = TEXT_PROP_MEANS_INVISIBLE (prop);
4499 /* If we ended up on invisible text, proceed to
4500 skip starting with next_stop. */
4501 if (invis != 0)
4502 tem = next_stop;
4504 /* If there are adjacent invisible texts, don't lose the
4505 second one's ellipsis. */
4506 if (invis == 2)
4507 display_ellipsis_p = true;
4509 while (invis != 0);
4511 /* The position newpos is now either ZV or on visible text. */
4512 if (it->bidi_p)
4514 ptrdiff_t bpos = CHAR_TO_BYTE (newpos);
4515 bool on_newline
4516 = bpos == ZV_BYTE || FETCH_BYTE (bpos) == '\n';
4517 bool after_newline
4518 = newpos <= BEGV || FETCH_BYTE (bpos - 1) == '\n';
4520 /* If the invisible text ends on a newline or on a
4521 character after a newline, we can avoid the costly,
4522 character by character, bidi iteration to NEWPOS, and
4523 instead simply reseat the iterator there. That's
4524 because all bidi reordering information is tossed at
4525 the newline. This is a big win for modes that hide
4526 complete lines, like Outline, Org, etc. */
4527 if (on_newline || after_newline)
4529 struct text_pos tpos;
4530 bidi_dir_t pdir = it->bidi_it.paragraph_dir;
4532 SET_TEXT_POS (tpos, newpos, bpos);
4533 reseat_1 (it, tpos, false);
4534 /* If we reseat on a newline/ZV, we need to prep the
4535 bidi iterator for advancing to the next character
4536 after the newline/EOB, keeping the current paragraph
4537 direction (so that PRODUCE_GLYPHS does TRT wrt
4538 prepending/appending glyphs to a glyph row). */
4539 if (on_newline)
4541 it->bidi_it.first_elt = false;
4542 it->bidi_it.paragraph_dir = pdir;
4543 it->bidi_it.ch = (bpos == ZV_BYTE) ? -1 : '\n';
4544 it->bidi_it.nchars = 1;
4545 it->bidi_it.ch_len = 1;
4548 else /* Must use the slow method. */
4550 /* With bidi iteration, the region of invisible text
4551 could start and/or end in the middle of a
4552 non-base embedding level. Therefore, we need to
4553 skip invisible text using the bidi iterator,
4554 starting at IT's current position, until we find
4555 ourselves outside of the invisible text.
4556 Skipping invisible text _after_ bidi iteration
4557 avoids affecting the visual order of the
4558 displayed text when invisible properties are
4559 added or removed. */
4560 if (it->bidi_it.first_elt && it->bidi_it.charpos < ZV)
4562 /* If we were `reseat'ed to a new paragraph,
4563 determine the paragraph base direction. We
4564 need to do it now because
4565 next_element_from_buffer may not have a
4566 chance to do it, if we are going to skip any
4567 text at the beginning, which resets the
4568 FIRST_ELT flag. */
4569 bidi_paragraph_init (it->paragraph_embedding,
4570 &it->bidi_it, true);
4574 bidi_move_to_visually_next (&it->bidi_it);
4576 while (it->stop_charpos <= it->bidi_it.charpos
4577 && it->bidi_it.charpos < newpos);
4578 IT_CHARPOS (*it) = it->bidi_it.charpos;
4579 IT_BYTEPOS (*it) = it->bidi_it.bytepos;
4580 /* If we overstepped NEWPOS, record its position in
4581 the iterator, so that we skip invisible text if
4582 later the bidi iteration lands us in the
4583 invisible region again. */
4584 if (IT_CHARPOS (*it) >= newpos)
4585 it->prev_stop = newpos;
4588 else
4590 IT_CHARPOS (*it) = newpos;
4591 IT_BYTEPOS (*it) = CHAR_TO_BYTE (newpos);
4594 if (display_ellipsis_p)
4596 /* Make sure that the glyphs of the ellipsis will get
4597 correct `charpos' values. If we would not update
4598 it->position here, the glyphs would belong to the
4599 last visible character _before_ the invisible
4600 text, which confuses `set_cursor_from_row'.
4602 We use the last invisible position instead of the
4603 first because this way the cursor is always drawn on
4604 the first "." of the ellipsis, whenever PT is inside
4605 the invisible text. Otherwise the cursor would be
4606 placed _after_ the ellipsis when the point is after the
4607 first invisible character. */
4608 if (!STRINGP (it->object))
4610 it->position.charpos = newpos - 1;
4611 it->position.bytepos = CHAR_TO_BYTE (it->position.charpos);
4615 /* If there are before-strings at the start of invisible
4616 text, and the text is invisible because of a text
4617 property, arrange to show before-strings because 20.x did
4618 it that way. (If the text is invisible because of an
4619 overlay property instead of a text property, this is
4620 already handled in the overlay code.) */
4621 if (NILP (overlay)
4622 && get_overlay_strings (it, it->stop_charpos))
4624 handled = HANDLED_RECOMPUTE_PROPS;
4625 if (it->sp > 0)
4627 it->stack[it->sp - 1].display_ellipsis_p = display_ellipsis_p;
4628 /* The call to get_overlay_strings above recomputes
4629 it->stop_charpos, but it only considers changes
4630 in properties and overlays beyond iterator's
4631 current position. This causes us to miss changes
4632 that happen exactly where the invisible property
4633 ended. So we play it safe here and force the
4634 iterator to check for potential stop positions
4635 immediately after the invisible text. Note that
4636 if get_overlay_strings returns true, it
4637 normally also pushed the iterator stack, so we
4638 need to update the stop position in the slot
4639 below the current one. */
4640 it->stack[it->sp - 1].stop_charpos
4641 = CHARPOS (it->stack[it->sp - 1].current.pos);
4644 else if (display_ellipsis_p)
4646 it->ellipsis_p = true;
4647 /* Let the ellipsis display before
4648 considering any properties of the following char.
4649 Fixes jasonr@gnu.org 01 Oct 07 bug. */
4650 handled = HANDLED_RETURN;
4655 return handled;
4659 /* Make iterator IT return `...' next.
4660 Replaces LEN characters from buffer. */
4662 static void
4663 setup_for_ellipsis (struct it *it, int len)
4665 /* Use the display table definition for `...'. Invalid glyphs
4666 will be handled by the method returning elements from dpvec. */
4667 if (it->dp && VECTORP (DISP_INVIS_VECTOR (it->dp)))
4669 struct Lisp_Vector *v = XVECTOR (DISP_INVIS_VECTOR (it->dp));
4670 it->dpvec = v->contents;
4671 it->dpend = v->contents + v->header.size;
4673 else
4675 /* Default `...'. */
4676 it->dpvec = default_invis_vector;
4677 it->dpend = default_invis_vector + 3;
4680 it->dpvec_char_len = len;
4681 it->current.dpvec_index = 0;
4682 it->dpvec_face_id = -1;
4684 /* Use IT->saved_face_id for the ellipsis, so that it has the same
4685 face as the preceding text. IT->saved_face_id was set in
4686 handle_stop to the face of the preceding character, and will be
4687 different from IT->face_id only if the invisible text skipped in
4688 handle_invisible_prop has some non-default face on its first
4689 character. We thus ignore the face of the invisible text when we
4690 display the ellipsis. IT's face is restored in set_iterator_to_next. */
4691 if (it->saved_face_id >= 0)
4692 it->face_id = it->saved_face_id;
4694 /* If the ellipsis represents buffer text, it means we advanced in
4695 the buffer, so we should no longer ignore overlay strings. */
4696 if (it->method == GET_FROM_BUFFER)
4697 it->ignore_overlay_strings_at_pos_p = false;
4699 it->method = GET_FROM_DISPLAY_VECTOR;
4700 it->ellipsis_p = true;
4705 /***********************************************************************
4706 'display' property
4707 ***********************************************************************/
4709 /* Set up iterator IT from `display' property at its current position.
4710 Called from handle_stop.
4711 We return HANDLED_RETURN if some part of the display property
4712 overrides the display of the buffer text itself.
4713 Otherwise we return HANDLED_NORMALLY. */
4715 static enum prop_handled
4716 handle_display_prop (struct it *it)
4718 Lisp_Object propval, object, overlay;
4719 struct text_pos *position;
4720 ptrdiff_t bufpos;
4721 /* Nonzero if some property replaces the display of the text itself. */
4722 int display_replaced = 0;
4724 if (STRINGP (it->string))
4726 object = it->string;
4727 position = &it->current.string_pos;
4728 bufpos = CHARPOS (it->current.pos);
4730 else
4732 XSETWINDOW (object, it->w);
4733 position = &it->current.pos;
4734 bufpos = CHARPOS (*position);
4737 /* Reset those iterator values set from display property values. */
4738 it->slice.x = it->slice.y = it->slice.width = it->slice.height = Qnil;
4739 it->space_width = Qnil;
4740 it->font_height = Qnil;
4741 it->voffset = 0;
4743 /* We don't support recursive `display' properties, i.e. string
4744 values that have a string `display' property, that have a string
4745 `display' property etc. */
4746 if (!it->string_from_display_prop_p)
4747 it->area = TEXT_AREA;
4749 propval = get_char_property_and_overlay (make_number (position->charpos),
4750 Qdisplay, object, &overlay);
4751 if (NILP (propval))
4752 return HANDLED_NORMALLY;
4753 /* Now OVERLAY is the overlay that gave us this property, or nil
4754 if it was a text property. */
4756 if (!STRINGP (it->string))
4757 object = it->w->contents;
4759 display_replaced = handle_display_spec (it, propval, object, overlay,
4760 position, bufpos,
4761 FRAME_WINDOW_P (it->f));
4762 return display_replaced != 0 ? HANDLED_RETURN : HANDLED_NORMALLY;
4765 /* Subroutine of handle_display_prop. Returns non-zero if the display
4766 specification in SPEC is a replacing specification, i.e. it would
4767 replace the text covered by `display' property with something else,
4768 such as an image or a display string. If SPEC includes any kind or
4769 `(space ...) specification, the value is 2; this is used by
4770 compute_display_string_pos, which see.
4772 See handle_single_display_spec for documentation of arguments.
4773 FRAME_WINDOW_P is true if the window being redisplayed is on a
4774 GUI frame; this argument is used only if IT is NULL, see below.
4776 IT can be NULL, if this is called by the bidi reordering code
4777 through compute_display_string_pos, which see. In that case, this
4778 function only examines SPEC, but does not otherwise "handle" it, in
4779 the sense that it doesn't set up members of IT from the display
4780 spec. */
4781 static int
4782 handle_display_spec (struct it *it, Lisp_Object spec, Lisp_Object object,
4783 Lisp_Object overlay, struct text_pos *position,
4784 ptrdiff_t bufpos, bool frame_window_p)
4786 int replacing = 0;
4787 bool enable_eval = true;
4789 /* Support (disable-eval PROP) which is used by enriched.el. */
4790 if (CONSP (spec) && EQ (XCAR (spec), Qdisable_eval))
4792 enable_eval = false;
4793 spec = XCAR (XCDR (spec));
4796 if (CONSP (spec)
4797 /* Simple specifications. */
4798 && !EQ (XCAR (spec), Qimage)
4799 #ifdef HAVE_XWIDGETS
4800 && !EQ (XCAR (spec), Qxwidget)
4801 #endif
4802 && !EQ (XCAR (spec), Qspace)
4803 && !EQ (XCAR (spec), Qwhen)
4804 && !EQ (XCAR (spec), Qslice)
4805 && !EQ (XCAR (spec), Qspace_width)
4806 && !EQ (XCAR (spec), Qheight)
4807 && !EQ (XCAR (spec), Qraise)
4808 /* Marginal area specifications. */
4809 && !(CONSP (XCAR (spec)) && EQ (XCAR (XCAR (spec)), Qmargin))
4810 && !EQ (XCAR (spec), Qleft_fringe)
4811 && !EQ (XCAR (spec), Qright_fringe)
4812 && !NILP (XCAR (spec)))
4814 for (; CONSP (spec); spec = XCDR (spec))
4816 int rv = handle_single_display_spec (it, XCAR (spec), object,
4817 overlay, position, bufpos,
4818 replacing, frame_window_p,
4819 enable_eval);
4820 if (rv != 0)
4822 replacing = rv;
4823 /* If some text in a string is replaced, `position' no
4824 longer points to the position of `object'. */
4825 if (!it || STRINGP (object))
4826 break;
4830 else if (VECTORP (spec))
4832 ptrdiff_t i;
4833 for (i = 0; i < ASIZE (spec); ++i)
4835 int rv = handle_single_display_spec (it, AREF (spec, i), object,
4836 overlay, position, bufpos,
4837 replacing, frame_window_p,
4838 enable_eval);
4839 if (rv != 0)
4841 replacing = rv;
4842 /* If some text in a string is replaced, `position' no
4843 longer points to the position of `object'. */
4844 if (!it || STRINGP (object))
4845 break;
4849 else
4850 replacing = handle_single_display_spec (it, spec, object, overlay, position,
4851 bufpos, 0, frame_window_p,
4852 enable_eval);
4853 return replacing;
4856 /* Value is the position of the end of the `display' property starting
4857 at START_POS in OBJECT. */
4859 static struct text_pos
4860 display_prop_end (struct it *it, Lisp_Object object, struct text_pos start_pos)
4862 Lisp_Object end;
4863 struct text_pos end_pos;
4865 end = Fnext_single_char_property_change (make_number (CHARPOS (start_pos)),
4866 Qdisplay, object, Qnil);
4867 CHARPOS (end_pos) = XFASTINT (end);
4868 if (STRINGP (object))
4869 compute_string_pos (&end_pos, start_pos, it->string);
4870 else
4871 BYTEPOS (end_pos) = CHAR_TO_BYTE (XFASTINT (end));
4873 return end_pos;
4877 /* Set up IT from a single `display' property specification SPEC. OBJECT
4878 is the object in which the `display' property was found. *POSITION
4879 is the position in OBJECT at which the `display' property was found.
4880 BUFPOS is the buffer position of OBJECT (different from POSITION if
4881 OBJECT is not a buffer). DISPLAY_REPLACED non-zero means that we
4882 previously saw a display specification which already replaced text
4883 display with something else, for example an image; we ignore such
4884 properties after the first one has been processed.
4886 OVERLAY is the overlay this `display' property came from,
4887 or nil if it was a text property.
4889 If SPEC is a `space' or `image' specification, and in some other
4890 cases too, set *POSITION to the position where the `display'
4891 property ends.
4893 If IT is NULL, only examine the property specification in SPEC, but
4894 don't set up IT. In that case, FRAME_WINDOW_P means SPEC
4895 is intended to be displayed in a window on a GUI frame.
4897 Enable evaluation of Lisp forms only if ENABLE_EVAL_P is true.
4899 Value is non-zero if something was found which replaces the display
4900 of buffer or string text. */
4902 static int
4903 handle_single_display_spec (struct it *it, Lisp_Object spec, Lisp_Object object,
4904 Lisp_Object overlay, struct text_pos *position,
4905 ptrdiff_t bufpos, int display_replaced,
4906 bool frame_window_p, bool enable_eval_p)
4908 Lisp_Object form;
4909 Lisp_Object location, value;
4910 struct text_pos start_pos = *position;
4912 /* If SPEC is a list of the form `(when FORM . VALUE)', evaluate FORM.
4913 If the result is non-nil, use VALUE instead of SPEC. */
4914 form = Qt;
4915 if (CONSP (spec) && EQ (XCAR (spec), Qwhen))
4917 spec = XCDR (spec);
4918 if (!CONSP (spec))
4919 return 0;
4920 form = XCAR (spec);
4921 spec = XCDR (spec);
4924 if (!NILP (form) && !EQ (form, Qt) && !enable_eval_p)
4925 form = Qnil;
4926 if (!NILP (form) && !EQ (form, Qt))
4928 ptrdiff_t count = SPECPDL_INDEX ();
4930 /* Bind `object' to the object having the `display' property, a
4931 buffer or string. Bind `position' to the position in the
4932 object where the property was found, and `buffer-position'
4933 to the current position in the buffer. */
4935 if (NILP (object))
4936 XSETBUFFER (object, current_buffer);
4937 specbind (Qobject, object);
4938 specbind (Qposition, make_number (CHARPOS (*position)));
4939 specbind (Qbuffer_position, make_number (bufpos));
4940 form = safe_eval (form);
4941 unbind_to (count, Qnil);
4944 if (NILP (form))
4945 return 0;
4947 /* Handle `(height HEIGHT)' specifications. */
4948 if (CONSP (spec)
4949 && EQ (XCAR (spec), Qheight)
4950 && CONSP (XCDR (spec)))
4952 if (it)
4954 if (!FRAME_WINDOW_P (it->f))
4955 return 0;
4957 it->font_height = XCAR (XCDR (spec));
4958 if (!NILP (it->font_height))
4960 int new_height = -1;
4962 if (CONSP (it->font_height)
4963 && (EQ (XCAR (it->font_height), Qplus)
4964 || EQ (XCAR (it->font_height), Qminus))
4965 && CONSP (XCDR (it->font_height))
4966 && RANGED_INTEGERP (0, XCAR (XCDR (it->font_height)), INT_MAX))
4968 /* `(+ N)' or `(- N)' where N is an integer. */
4969 int steps = XINT (XCAR (XCDR (it->font_height)));
4970 if (EQ (XCAR (it->font_height), Qplus))
4971 steps = - steps;
4972 it->face_id = smaller_face (it->f, it->face_id, steps);
4974 else if (FUNCTIONP (it->font_height) && enable_eval_p)
4976 /* Call function with current height as argument.
4977 Value is the new height. */
4978 struct face *face = FACE_FROM_ID (it->f, it->face_id);
4979 Lisp_Object height;
4980 height = safe_call1 (it->font_height,
4981 face->lface[LFACE_HEIGHT_INDEX]);
4982 if (NUMBERP (height))
4983 new_height = XFLOATINT (height);
4985 else if (NUMBERP (it->font_height))
4987 /* Value is a multiple of the canonical char height. */
4988 struct face *f;
4990 f = FACE_FROM_ID (it->f,
4991 lookup_basic_face (it->f, DEFAULT_FACE_ID));
4992 new_height = (XFLOATINT (it->font_height)
4993 * XINT (f->lface[LFACE_HEIGHT_INDEX]));
4995 else if (enable_eval_p)
4997 /* Evaluate IT->font_height with `height' bound to the
4998 current specified height to get the new height. */
4999 ptrdiff_t count = SPECPDL_INDEX ();
5000 struct face *face = FACE_FROM_ID (it->f, it->face_id);
5002 specbind (Qheight, face->lface[LFACE_HEIGHT_INDEX]);
5003 value = safe_eval (it->font_height);
5004 unbind_to (count, Qnil);
5006 if (NUMBERP (value))
5007 new_height = XFLOATINT (value);
5010 if (new_height > 0)
5011 it->face_id = face_with_height (it->f, it->face_id, new_height);
5015 return 0;
5018 /* Handle `(space-width WIDTH)'. */
5019 if (CONSP (spec)
5020 && EQ (XCAR (spec), Qspace_width)
5021 && CONSP (XCDR (spec)))
5023 if (it)
5025 if (!FRAME_WINDOW_P (it->f))
5026 return 0;
5028 value = XCAR (XCDR (spec));
5029 if (NUMBERP (value) && XFLOATINT (value) > 0)
5030 it->space_width = value;
5033 return 0;
5036 /* Handle `(slice X Y WIDTH HEIGHT)'. */
5037 if (CONSP (spec)
5038 && EQ (XCAR (spec), Qslice))
5040 Lisp_Object tem;
5042 if (it)
5044 if (!FRAME_WINDOW_P (it->f))
5045 return 0;
5047 if (tem = XCDR (spec), CONSP (tem))
5049 it->slice.x = XCAR (tem);
5050 if (tem = XCDR (tem), CONSP (tem))
5052 it->slice.y = XCAR (tem);
5053 if (tem = XCDR (tem), CONSP (tem))
5055 it->slice.width = XCAR (tem);
5056 if (tem = XCDR (tem), CONSP (tem))
5057 it->slice.height = XCAR (tem);
5063 return 0;
5066 /* Handle `(raise FACTOR)'. */
5067 if (CONSP (spec)
5068 && EQ (XCAR (spec), Qraise)
5069 && CONSP (XCDR (spec)))
5071 if (it)
5073 if (!FRAME_WINDOW_P (it->f))
5074 return 0;
5076 #ifdef HAVE_WINDOW_SYSTEM
5077 value = XCAR (XCDR (spec));
5078 if (NUMBERP (value))
5080 struct face *face = FACE_FROM_ID (it->f, it->face_id);
5081 it->voffset = - (XFLOATINT (value)
5082 * (normal_char_height (face->font, -1)));
5084 #endif /* HAVE_WINDOW_SYSTEM */
5087 return 0;
5090 /* Don't handle the other kinds of display specifications
5091 inside a string that we got from a `display' property. */
5092 if (it && it->string_from_display_prop_p)
5093 return 0;
5095 /* Characters having this form of property are not displayed, so
5096 we have to find the end of the property. */
5097 if (it)
5099 start_pos = *position;
5100 *position = display_prop_end (it, object, start_pos);
5101 /* If the display property comes from an overlay, don't consider
5102 any potential stop_charpos values before the end of that
5103 overlay. Since display_prop_end will happily find another
5104 'display' property coming from some other overlay or text
5105 property on buffer positions before this overlay's end, we
5106 need to ignore them, or else we risk displaying this
5107 overlay's display string/image twice. */
5108 if (!NILP (overlay))
5110 ptrdiff_t ovendpos = OVERLAY_POSITION (OVERLAY_END (overlay));
5112 /* Some borderline-sane Lisp might call us with the current
5113 buffer narrowed so that overlay-end is outside the
5114 POINT_MIN..POINT_MAX region, which will then cause
5115 various assertion violations and crashes down the road,
5116 starting with pop_it when it will attempt to use POSITION
5117 set below. Prevent that. */
5118 ovendpos = clip_to_bounds (BEGV, ovendpos, ZV);
5120 if (ovendpos > CHARPOS (*position))
5121 SET_TEXT_POS (*position, ovendpos, CHAR_TO_BYTE (ovendpos));
5124 value = Qnil;
5126 /* Stop the scan at that end position--we assume that all
5127 text properties change there. */
5128 if (it)
5129 it->stop_charpos = position->charpos;
5131 /* Handle `(left-fringe BITMAP [FACE])'
5132 and `(right-fringe BITMAP [FACE])'. */
5133 if (CONSP (spec)
5134 && (EQ (XCAR (spec), Qleft_fringe)
5135 || EQ (XCAR (spec), Qright_fringe))
5136 && CONSP (XCDR (spec)))
5138 if (it)
5140 if (!FRAME_WINDOW_P (it->f))
5141 /* If we return here, POSITION has been advanced
5142 across the text with this property. */
5144 /* Synchronize the bidi iterator with POSITION. This is
5145 needed because we are not going to push the iterator
5146 on behalf of this display property, so there will be
5147 no pop_it call to do this synchronization for us. */
5148 if (it->bidi_p)
5150 it->position = *position;
5151 iterate_out_of_display_property (it);
5152 *position = it->position;
5154 return 1;
5157 else if (!frame_window_p)
5158 return 1;
5160 #ifdef HAVE_WINDOW_SYSTEM
5161 value = XCAR (XCDR (spec));
5162 int fringe_bitmap = SYMBOLP (value) ? lookup_fringe_bitmap (value) : 0;
5163 if (! fringe_bitmap)
5164 /* If we return here, POSITION has been advanced
5165 across the text with this property. */
5167 if (it && it->bidi_p)
5169 it->position = *position;
5170 iterate_out_of_display_property (it);
5171 *position = it->position;
5173 return 1;
5176 if (it)
5178 int face_id = lookup_basic_face (it->f, DEFAULT_FACE_ID);
5180 if (CONSP (XCDR (XCDR (spec))))
5182 Lisp_Object face_name = XCAR (XCDR (XCDR (spec)));
5183 int face_id2 = lookup_derived_face (it->f, face_name,
5184 FRINGE_FACE_ID, false);
5185 if (face_id2 >= 0)
5186 face_id = face_id2;
5189 /* Save current settings of IT so that we can restore them
5190 when we are finished with the glyph property value. */
5191 push_it (it, position);
5193 it->area = TEXT_AREA;
5194 it->what = IT_IMAGE;
5195 it->image_id = -1; /* no image */
5196 it->position = start_pos;
5197 it->object = NILP (object) ? it->w->contents : object;
5198 it->method = GET_FROM_IMAGE;
5199 it->from_overlay = Qnil;
5200 it->face_id = face_id;
5201 it->from_disp_prop_p = true;
5203 /* Say that we haven't consumed the characters with
5204 `display' property yet. The call to pop_it in
5205 set_iterator_to_next will clean this up. */
5206 *position = start_pos;
5208 if (EQ (XCAR (spec), Qleft_fringe))
5210 it->left_user_fringe_bitmap = fringe_bitmap;
5211 it->left_user_fringe_face_id = face_id;
5213 else
5215 it->right_user_fringe_bitmap = fringe_bitmap;
5216 it->right_user_fringe_face_id = face_id;
5219 #endif /* HAVE_WINDOW_SYSTEM */
5220 return 1;
5223 /* Prepare to handle `((margin left-margin) ...)',
5224 `((margin right-margin) ...)' and `((margin nil) ...)'
5225 prefixes for display specifications. */
5226 location = Qunbound;
5227 if (CONSP (spec) && CONSP (XCAR (spec)))
5229 Lisp_Object tem;
5231 value = XCDR (spec);
5232 if (CONSP (value))
5233 value = XCAR (value);
5235 tem = XCAR (spec);
5236 if (EQ (XCAR (tem), Qmargin)
5237 && (tem = XCDR (tem),
5238 tem = CONSP (tem) ? XCAR (tem) : Qnil,
5239 (NILP (tem)
5240 || EQ (tem, Qleft_margin)
5241 || EQ (tem, Qright_margin))))
5242 location = tem;
5245 if (EQ (location, Qunbound))
5247 location = Qnil;
5248 value = spec;
5251 /* After this point, VALUE is the property after any
5252 margin prefix has been stripped. It must be a string,
5253 an image specification, or `(space ...)'.
5255 LOCATION specifies where to display: `left-margin',
5256 `right-margin' or nil. */
5258 bool valid_p = (STRINGP (value)
5259 #ifdef HAVE_WINDOW_SYSTEM
5260 || ((it ? FRAME_WINDOW_P (it->f) : frame_window_p)
5261 && valid_image_p (value))
5262 #endif /* not HAVE_WINDOW_SYSTEM */
5263 || (CONSP (value) && EQ (XCAR (value), Qspace))
5264 || ((it ? FRAME_WINDOW_P (it->f) : frame_window_p)
5265 && valid_xwidget_spec_p (value)));
5267 if (valid_p && display_replaced == 0)
5269 int retval = 1;
5271 if (!it)
5273 /* Callers need to know whether the display spec is any kind
5274 of `(space ...)' spec that is about to affect text-area
5275 display. */
5276 if (CONSP (value) && EQ (XCAR (value), Qspace) && NILP (location))
5277 retval = 2;
5278 return retval;
5281 /* Save current settings of IT so that we can restore them
5282 when we are finished with the glyph property value. */
5283 push_it (it, position);
5284 it->from_overlay = overlay;
5285 it->from_disp_prop_p = true;
5287 if (NILP (location))
5288 it->area = TEXT_AREA;
5289 else if (EQ (location, Qleft_margin))
5290 it->area = LEFT_MARGIN_AREA;
5291 else
5292 it->area = RIGHT_MARGIN_AREA;
5294 if (STRINGP (value))
5296 it->string = value;
5297 it->multibyte_p = STRING_MULTIBYTE (it->string);
5298 it->current.overlay_string_index = -1;
5299 IT_STRING_CHARPOS (*it) = IT_STRING_BYTEPOS (*it) = 0;
5300 it->end_charpos = it->string_nchars = SCHARS (it->string);
5301 it->method = GET_FROM_STRING;
5302 it->stop_charpos = 0;
5303 it->prev_stop = 0;
5304 it->base_level_stop = 0;
5305 it->string_from_display_prop_p = true;
5306 it->cmp_it.id = -1;
5307 /* Say that we haven't consumed the characters with
5308 `display' property yet. The call to pop_it in
5309 set_iterator_to_next will clean this up. */
5310 if (BUFFERP (object))
5311 *position = start_pos;
5313 /* Force paragraph direction to be that of the parent
5314 object. If the parent object's paragraph direction is
5315 not yet determined, default to L2R. */
5316 if (it->bidi_p && it->bidi_it.paragraph_dir == R2L)
5317 it->paragraph_embedding = it->bidi_it.paragraph_dir;
5318 else
5319 it->paragraph_embedding = L2R;
5321 /* Set up the bidi iterator for this display string. */
5322 if (it->bidi_p)
5324 it->bidi_it.string.lstring = it->string;
5325 it->bidi_it.string.s = NULL;
5326 it->bidi_it.string.schars = it->end_charpos;
5327 it->bidi_it.string.bufpos = bufpos;
5328 it->bidi_it.string.from_disp_str = true;
5329 it->bidi_it.string.unibyte = !it->multibyte_p;
5330 it->bidi_it.w = it->w;
5331 bidi_init_it (0, 0, FRAME_WINDOW_P (it->f), &it->bidi_it);
5334 else if (CONSP (value) && EQ (XCAR (value), Qspace))
5336 it->method = GET_FROM_STRETCH;
5337 it->object = value;
5338 *position = it->position = start_pos;
5339 retval = 1 + (it->area == TEXT_AREA);
5341 else if (valid_xwidget_spec_p (value))
5343 it->what = IT_XWIDGET;
5344 it->method = GET_FROM_XWIDGET;
5345 it->position = start_pos;
5346 it->object = NILP (object) ? it->w->contents : object;
5347 *position = start_pos;
5348 it->xwidget = lookup_xwidget (value);
5350 #ifdef HAVE_WINDOW_SYSTEM
5351 else
5353 it->what = IT_IMAGE;
5354 it->image_id = lookup_image (it->f, value);
5355 it->position = start_pos;
5356 it->object = NILP (object) ? it->w->contents : object;
5357 it->method = GET_FROM_IMAGE;
5359 /* Say that we haven't consumed the characters with
5360 `display' property yet. The call to pop_it in
5361 set_iterator_to_next will clean this up. */
5362 *position = start_pos;
5364 #endif /* HAVE_WINDOW_SYSTEM */
5366 return retval;
5369 /* Invalid property or property not supported. Restore
5370 POSITION to what it was before. */
5371 *position = start_pos;
5372 return 0;
5375 /* Check if PROP is a display property value whose text should be
5376 treated as intangible. OVERLAY is the overlay from which PROP
5377 came, or nil if it came from a text property. CHARPOS and BYTEPOS
5378 specify the buffer position covered by PROP. */
5380 bool
5381 display_prop_intangible_p (Lisp_Object prop, Lisp_Object overlay,
5382 ptrdiff_t charpos, ptrdiff_t bytepos)
5384 bool frame_window_p = FRAME_WINDOW_P (XFRAME (selected_frame));
5385 struct text_pos position;
5387 SET_TEXT_POS (position, charpos, bytepos);
5388 return (handle_display_spec (NULL, prop, Qnil, overlay,
5389 &position, charpos, frame_window_p)
5390 != 0);
5394 /* Return true if PROP is a display sub-property value containing STRING.
5396 Implementation note: this and the following function are really
5397 special cases of handle_display_spec and
5398 handle_single_display_spec, and should ideally use the same code.
5399 Until they do, these two pairs must be consistent and must be
5400 modified in sync. */
5402 static bool
5403 single_display_spec_string_p (Lisp_Object prop, Lisp_Object string)
5405 if (EQ (string, prop))
5406 return true;
5408 /* Skip over `when FORM'. */
5409 if (CONSP (prop) && EQ (XCAR (prop), Qwhen))
5411 prop = XCDR (prop);
5412 if (!CONSP (prop))
5413 return false;
5414 /* Actually, the condition following `when' should be eval'ed,
5415 like handle_single_display_spec does, and we should return
5416 false if it evaluates to nil. However, this function is
5417 called only when the buffer was already displayed and some
5418 glyph in the glyph matrix was found to come from a display
5419 string. Therefore, the condition was already evaluated, and
5420 the result was non-nil, otherwise the display string wouldn't
5421 have been displayed and we would have never been called for
5422 this property. Thus, we can skip the evaluation and assume
5423 its result is non-nil. */
5424 prop = XCDR (prop);
5427 if (CONSP (prop))
5428 /* Skip over `margin LOCATION'. */
5429 if (EQ (XCAR (prop), Qmargin))
5431 prop = XCDR (prop);
5432 if (!CONSP (prop))
5433 return false;
5435 prop = XCDR (prop);
5436 if (!CONSP (prop))
5437 return false;
5440 return EQ (prop, string) || (CONSP (prop) && EQ (XCAR (prop), string));
5444 /* Return true if STRING appears in the `display' property PROP. */
5446 static bool
5447 display_prop_string_p (Lisp_Object prop, Lisp_Object string)
5449 if (CONSP (prop)
5450 && !EQ (XCAR (prop), Qwhen)
5451 && !(CONSP (XCAR (prop)) && EQ (Qmargin, XCAR (XCAR (prop)))))
5453 /* A list of sub-properties. */
5454 while (CONSP (prop))
5456 if (single_display_spec_string_p (XCAR (prop), string))
5457 return true;
5458 prop = XCDR (prop);
5461 else if (VECTORP (prop))
5463 /* A vector of sub-properties. */
5464 ptrdiff_t i;
5465 for (i = 0; i < ASIZE (prop); ++i)
5466 if (single_display_spec_string_p (AREF (prop, i), string))
5467 return true;
5469 else
5470 return single_display_spec_string_p (prop, string);
5472 return false;
5475 /* Look for STRING in overlays and text properties in the current
5476 buffer, between character positions FROM and TO (excluding TO).
5477 BACK_P means look back (in this case, TO is supposed to be
5478 less than FROM).
5479 Value is the first character position where STRING was found, or
5480 zero if it wasn't found before hitting TO.
5482 This function may only use code that doesn't eval because it is
5483 called asynchronously from note_mouse_highlight. */
5485 static ptrdiff_t
5486 string_buffer_position_lim (Lisp_Object string,
5487 ptrdiff_t from, ptrdiff_t to, bool back_p)
5489 Lisp_Object limit, prop, pos;
5490 bool found = false;
5492 pos = make_number (max (from, BEGV));
5494 if (!back_p) /* looking forward */
5496 limit = make_number (min (to, ZV));
5497 while (!found && !EQ (pos, limit))
5499 prop = Fget_char_property (pos, Qdisplay, Qnil);
5500 if (!NILP (prop) && display_prop_string_p (prop, string))
5501 found = true;
5502 else
5503 pos = Fnext_single_char_property_change (pos, Qdisplay, Qnil,
5504 limit);
5507 else /* looking back */
5509 limit = make_number (max (to, BEGV));
5510 while (!found && !EQ (pos, limit))
5512 prop = Fget_char_property (pos, Qdisplay, Qnil);
5513 if (!NILP (prop) && display_prop_string_p (prop, string))
5514 found = true;
5515 else
5516 pos = Fprevious_single_char_property_change (pos, Qdisplay, Qnil,
5517 limit);
5521 return found ? XINT (pos) : 0;
5524 /* Determine which buffer position in current buffer STRING comes from.
5525 AROUND_CHARPOS is an approximate position where it could come from.
5526 Value is the buffer position or 0 if it couldn't be determined.
5528 This function is necessary because we don't record buffer positions
5529 in glyphs generated from strings (to keep struct glyph small).
5530 This function may only use code that doesn't eval because it is
5531 called asynchronously from note_mouse_highlight. */
5533 static ptrdiff_t
5534 string_buffer_position (Lisp_Object string, ptrdiff_t around_charpos)
5536 const int MAX_DISTANCE = 1000;
5537 ptrdiff_t found = string_buffer_position_lim (string, around_charpos,
5538 around_charpos + MAX_DISTANCE,
5539 false);
5541 if (!found)
5542 found = string_buffer_position_lim (string, around_charpos,
5543 around_charpos - MAX_DISTANCE, true);
5544 return found;
5549 /***********************************************************************
5550 `composition' property
5551 ***********************************************************************/
5553 /* Set up iterator IT from `composition' property at its current
5554 position. Called from handle_stop. */
5556 static enum prop_handled
5557 handle_composition_prop (struct it *it)
5559 Lisp_Object prop, string;
5560 ptrdiff_t pos, pos_byte, start, end;
5562 if (STRINGP (it->string))
5564 unsigned char *s;
5566 pos = IT_STRING_CHARPOS (*it);
5567 pos_byte = IT_STRING_BYTEPOS (*it);
5568 string = it->string;
5569 s = SDATA (string) + pos_byte;
5570 it->c = STRING_CHAR (s);
5572 else
5574 pos = IT_CHARPOS (*it);
5575 pos_byte = IT_BYTEPOS (*it);
5576 string = Qnil;
5577 it->c = FETCH_CHAR (pos_byte);
5580 /* If there's a valid composition and point is not inside of the
5581 composition (in the case that the composition is from the current
5582 buffer), draw a glyph composed from the composition components. */
5583 if (find_composition (pos, -1, &start, &end, &prop, string)
5584 && composition_valid_p (start, end, prop)
5585 && (STRINGP (it->string) || (PT <= start || PT >= end)))
5587 if (start < pos)
5588 /* As we can't handle this situation (perhaps font-lock added
5589 a new composition), we just return here hoping that next
5590 redisplay will detect this composition much earlier. */
5591 return HANDLED_NORMALLY;
5592 if (start != pos)
5594 if (STRINGP (it->string))
5595 pos_byte = string_char_to_byte (it->string, start);
5596 else
5597 pos_byte = CHAR_TO_BYTE (start);
5599 it->cmp_it.id = get_composition_id (start, pos_byte, end - start,
5600 prop, string);
5602 if (it->cmp_it.id >= 0)
5604 it->cmp_it.ch = -1;
5605 it->cmp_it.nchars = COMPOSITION_LENGTH (prop);
5606 it->cmp_it.nglyphs = -1;
5610 return HANDLED_NORMALLY;
5615 /***********************************************************************
5616 Overlay strings
5617 ***********************************************************************/
5619 /* The following structure is used to record overlay strings for
5620 later sorting in load_overlay_strings. */
5622 struct overlay_entry
5624 Lisp_Object overlay;
5625 Lisp_Object string;
5626 EMACS_INT priority;
5627 bool after_string_p;
5631 /* Set up iterator IT from overlay strings at its current position.
5632 Called from handle_stop. */
5634 static enum prop_handled
5635 handle_overlay_change (struct it *it)
5637 if (!STRINGP (it->string) && get_overlay_strings (it, 0))
5638 return HANDLED_RECOMPUTE_PROPS;
5639 else
5640 return HANDLED_NORMALLY;
5644 /* Set up the next overlay string for delivery by IT, if there is an
5645 overlay string to deliver. Called by set_iterator_to_next when the
5646 end of the current overlay string is reached. If there are more
5647 overlay strings to display, IT->string and
5648 IT->current.overlay_string_index are set appropriately here.
5649 Otherwise IT->string is set to nil. */
5651 static void
5652 next_overlay_string (struct it *it)
5654 ++it->current.overlay_string_index;
5655 if (it->current.overlay_string_index == it->n_overlay_strings)
5657 /* No more overlay strings. Restore IT's settings to what
5658 they were before overlay strings were processed, and
5659 continue to deliver from current_buffer. */
5661 it->ellipsis_p = it->stack[it->sp - 1].display_ellipsis_p;
5662 pop_it (it);
5663 eassert (it->sp > 0
5664 || (NILP (it->string)
5665 && it->method == GET_FROM_BUFFER
5666 && it->stop_charpos >= BEGV
5667 && it->stop_charpos <= it->end_charpos));
5668 it->current.overlay_string_index = -1;
5669 it->n_overlay_strings = 0;
5670 /* If there's an empty display string on the stack, pop the
5671 stack, to resync the bidi iterator with IT's position. Such
5672 empty strings are pushed onto the stack in
5673 get_overlay_strings_1. */
5674 if (it->sp > 0 && STRINGP (it->string) && !SCHARS (it->string))
5675 pop_it (it);
5677 /* Since we've exhausted overlay strings at this buffer
5678 position, set the flag to ignore overlays until we move to
5679 another position. (The flag will be reset in
5680 next_element_from_buffer.) But don't do that if the overlay
5681 strings were loaded at position other than the current one,
5682 which could happen if we called pop_it above, or if the
5683 overlay strings were loaded by handle_invisible_prop at the
5684 beginning of invisible text. */
5685 if (it->overlay_strings_charpos == IT_CHARPOS (*it))
5686 it->ignore_overlay_strings_at_pos_p = true;
5688 /* If we're at the end of the buffer, record that we have
5689 processed the overlay strings there already, so that
5690 next_element_from_buffer doesn't try it again. */
5691 if (NILP (it->string)
5692 && IT_CHARPOS (*it) >= it->end_charpos
5693 && it->overlay_strings_charpos >= it->end_charpos)
5694 it->overlay_strings_at_end_processed_p = true;
5695 /* Note: we reset overlay_strings_charpos only here, to make
5696 sure the just-processed overlays were indeed at EOB.
5697 Otherwise, overlays on text with invisible text property,
5698 which are processed with IT's position past the invisible
5699 text, might fool us into thinking the overlays at EOB were
5700 already processed (linum-mode can cause this, for
5701 example). */
5702 it->overlay_strings_charpos = -1;
5704 else
5706 /* There are more overlay strings to process. If
5707 IT->current.overlay_string_index has advanced to a position
5708 where we must load IT->overlay_strings with more strings, do
5709 it. We must load at the IT->overlay_strings_charpos where
5710 IT->n_overlay_strings was originally computed; when invisible
5711 text is present, this might not be IT_CHARPOS (Bug#7016). */
5712 int i = it->current.overlay_string_index % OVERLAY_STRING_CHUNK_SIZE;
5714 if (it->current.overlay_string_index && i == 0)
5715 load_overlay_strings (it, it->overlay_strings_charpos);
5717 /* Initialize IT to deliver display elements from the overlay
5718 string. */
5719 it->string = it->overlay_strings[i];
5720 it->multibyte_p = STRING_MULTIBYTE (it->string);
5721 SET_TEXT_POS (it->current.string_pos, 0, 0);
5722 it->method = GET_FROM_STRING;
5723 it->stop_charpos = 0;
5724 it->end_charpos = SCHARS (it->string);
5725 if (it->cmp_it.stop_pos >= 0)
5726 it->cmp_it.stop_pos = 0;
5727 it->prev_stop = 0;
5728 it->base_level_stop = 0;
5730 /* Set up the bidi iterator for this overlay string. */
5731 if (it->bidi_p)
5733 it->bidi_it.string.lstring = it->string;
5734 it->bidi_it.string.s = NULL;
5735 it->bidi_it.string.schars = SCHARS (it->string);
5736 it->bidi_it.string.bufpos = it->overlay_strings_charpos;
5737 it->bidi_it.string.from_disp_str = it->string_from_display_prop_p;
5738 it->bidi_it.string.unibyte = !it->multibyte_p;
5739 it->bidi_it.w = it->w;
5740 bidi_init_it (0, 0, FRAME_WINDOW_P (it->f), &it->bidi_it);
5744 CHECK_IT (it);
5748 /* Compare two overlay_entry structures E1 and E2. Used as a
5749 comparison function for qsort in load_overlay_strings. Overlay
5750 strings for the same position are sorted so that
5752 1. All after-strings come in front of before-strings, except
5753 when they come from the same overlay.
5755 2. Within after-strings, strings are sorted so that overlay strings
5756 from overlays with higher priorities come first.
5758 2. Within before-strings, strings are sorted so that overlay
5759 strings from overlays with higher priorities come last.
5761 Value is analogous to strcmp. */
5764 static int
5765 compare_overlay_entries (const void *e1, const void *e2)
5767 struct overlay_entry const *entry1 = e1;
5768 struct overlay_entry const *entry2 = e2;
5769 int result;
5771 if (entry1->after_string_p != entry2->after_string_p)
5773 /* Let after-strings appear in front of before-strings if
5774 they come from different overlays. */
5775 if (EQ (entry1->overlay, entry2->overlay))
5776 result = entry1->after_string_p ? 1 : -1;
5777 else
5778 result = entry1->after_string_p ? -1 : 1;
5780 else if (entry1->priority != entry2->priority)
5782 if (entry1->after_string_p)
5783 /* After-strings sorted in order of decreasing priority. */
5784 result = entry2->priority < entry1->priority ? -1 : 1;
5785 else
5786 /* Before-strings sorted in order of increasing priority. */
5787 result = entry1->priority < entry2->priority ? -1 : 1;
5789 else
5790 result = 0;
5792 return result;
5796 /* Load the vector IT->overlay_strings with overlay strings from IT's
5797 current buffer position, or from CHARPOS if that is > 0. Set
5798 IT->n_overlays to the total number of overlay strings found.
5800 Overlay strings are processed OVERLAY_STRING_CHUNK_SIZE strings at
5801 a time. On entry into load_overlay_strings,
5802 IT->current.overlay_string_index gives the number of overlay
5803 strings that have already been loaded by previous calls to this
5804 function.
5806 IT->add_overlay_start contains an additional overlay start
5807 position to consider for taking overlay strings from, if non-zero.
5808 This position comes into play when the overlay has an `invisible'
5809 property, and both before and after-strings. When we've skipped to
5810 the end of the overlay, because of its `invisible' property, we
5811 nevertheless want its before-string to appear.
5812 IT->add_overlay_start will contain the overlay start position
5813 in this case.
5815 Overlay strings are sorted so that after-string strings come in
5816 front of before-string strings. Within before and after-strings,
5817 strings are sorted by overlay priority. See also function
5818 compare_overlay_entries. */
5820 static void
5821 load_overlay_strings (struct it *it, ptrdiff_t charpos)
5823 Lisp_Object overlay, window, str, invisible;
5824 struct Lisp_Overlay *ov;
5825 ptrdiff_t start, end;
5826 ptrdiff_t n = 0, i, j;
5827 int invis;
5828 struct overlay_entry entriesbuf[20];
5829 ptrdiff_t size = ARRAYELTS (entriesbuf);
5830 struct overlay_entry *entries = entriesbuf;
5831 USE_SAFE_ALLOCA;
5833 if (charpos <= 0)
5834 charpos = IT_CHARPOS (*it);
5836 /* Append the overlay string STRING of overlay OVERLAY to vector
5837 `entries' which has size `size' and currently contains `n'
5838 elements. AFTER_P means STRING is an after-string of
5839 OVERLAY. */
5840 #define RECORD_OVERLAY_STRING(OVERLAY, STRING, AFTER_P) \
5841 do \
5843 Lisp_Object priority; \
5845 if (n == size) \
5847 struct overlay_entry *old = entries; \
5848 SAFE_NALLOCA (entries, 2, size); \
5849 memcpy (entries, old, size * sizeof *entries); \
5850 size *= 2; \
5853 entries[n].string = (STRING); \
5854 entries[n].overlay = (OVERLAY); \
5855 priority = Foverlay_get ((OVERLAY), Qpriority); \
5856 entries[n].priority = INTEGERP (priority) ? XINT (priority) : 0; \
5857 entries[n].after_string_p = (AFTER_P); \
5858 ++n; \
5860 while (false)
5862 /* Process overlay before the overlay center. */
5863 for (ov = current_buffer->overlays_before; ov; ov = ov->next)
5865 XSETMISC (overlay, ov);
5866 eassert (OVERLAYP (overlay));
5867 start = OVERLAY_POSITION (OVERLAY_START (overlay));
5868 end = OVERLAY_POSITION (OVERLAY_END (overlay));
5870 if (end < charpos)
5871 break;
5873 /* Skip this overlay if it doesn't start or end at IT's current
5874 position. */
5875 if (end != charpos && start != charpos)
5876 continue;
5878 /* Skip this overlay if it doesn't apply to IT->w. */
5879 window = Foverlay_get (overlay, Qwindow);
5880 if (WINDOWP (window) && XWINDOW (window) != it->w)
5881 continue;
5883 /* If the text ``under'' the overlay is invisible, both before-
5884 and after-strings from this overlay are visible; start and
5885 end position are indistinguishable. */
5886 invisible = Foverlay_get (overlay, Qinvisible);
5887 invis = TEXT_PROP_MEANS_INVISIBLE (invisible);
5889 /* If overlay has a non-empty before-string, record it. */
5890 if ((start == charpos || (end == charpos && invis != 0))
5891 && (str = Foverlay_get (overlay, Qbefore_string), STRINGP (str))
5892 && SCHARS (str))
5893 RECORD_OVERLAY_STRING (overlay, str, false);
5895 /* If overlay has a non-empty after-string, record it. */
5896 if ((end == charpos || (start == charpos && invis != 0))
5897 && (str = Foverlay_get (overlay, Qafter_string), STRINGP (str))
5898 && SCHARS (str))
5899 RECORD_OVERLAY_STRING (overlay, str, true);
5902 /* Process overlays after the overlay center. */
5903 for (ov = current_buffer->overlays_after; ov; ov = ov->next)
5905 XSETMISC (overlay, ov);
5906 eassert (OVERLAYP (overlay));
5907 start = OVERLAY_POSITION (OVERLAY_START (overlay));
5908 end = OVERLAY_POSITION (OVERLAY_END (overlay));
5910 if (start > charpos)
5911 break;
5913 /* Skip this overlay if it doesn't start or end at IT's current
5914 position. */
5915 if (end != charpos && start != charpos)
5916 continue;
5918 /* Skip this overlay if it doesn't apply to IT->w. */
5919 window = Foverlay_get (overlay, Qwindow);
5920 if (WINDOWP (window) && XWINDOW (window) != it->w)
5921 continue;
5923 /* If the text ``under'' the overlay is invisible, it has a zero
5924 dimension, and both before- and after-strings apply. */
5925 invisible = Foverlay_get (overlay, Qinvisible);
5926 invis = TEXT_PROP_MEANS_INVISIBLE (invisible);
5928 /* If overlay has a non-empty before-string, record it. */
5929 if ((start == charpos || (end == charpos && invis != 0))
5930 && (str = Foverlay_get (overlay, Qbefore_string), STRINGP (str))
5931 && SCHARS (str))
5932 RECORD_OVERLAY_STRING (overlay, str, false);
5934 /* If overlay has a non-empty after-string, record it. */
5935 if ((end == charpos || (start == charpos && invis != 0))
5936 && (str = Foverlay_get (overlay, Qafter_string), STRINGP (str))
5937 && SCHARS (str))
5938 RECORD_OVERLAY_STRING (overlay, str, true);
5941 #undef RECORD_OVERLAY_STRING
5943 /* Sort entries. */
5944 if (n > 1)
5945 qsort (entries, n, sizeof *entries, compare_overlay_entries);
5947 /* Record number of overlay strings, and where we computed it. */
5948 it->n_overlay_strings = n;
5949 it->overlay_strings_charpos = charpos;
5951 /* IT->current.overlay_string_index is the number of overlay strings
5952 that have already been consumed by IT. Copy some of the
5953 remaining overlay strings to IT->overlay_strings. */
5954 i = 0;
5955 j = it->current.overlay_string_index;
5956 while (i < OVERLAY_STRING_CHUNK_SIZE && j < n)
5958 it->overlay_strings[i] = entries[j].string;
5959 it->string_overlays[i++] = entries[j++].overlay;
5962 CHECK_IT (it);
5963 SAFE_FREE ();
5967 /* Get the first chunk of overlay strings at IT's current buffer
5968 position, or at CHARPOS if that is > 0. Value is true if at
5969 least one overlay string was found. */
5971 static bool
5972 get_overlay_strings_1 (struct it *it, ptrdiff_t charpos, bool compute_stop_p)
5974 /* Get the first OVERLAY_STRING_CHUNK_SIZE overlay strings to
5975 process. This fills IT->overlay_strings with strings, and sets
5976 IT->n_overlay_strings to the total number of strings to process.
5977 IT->pos.overlay_string_index has to be set temporarily to zero
5978 because load_overlay_strings needs this; it must be set to -1
5979 when no overlay strings are found because a zero value would
5980 indicate a position in the first overlay string. */
5981 it->current.overlay_string_index = 0;
5982 load_overlay_strings (it, charpos);
5984 /* If we found overlay strings, set up IT to deliver display
5985 elements from the first one. Otherwise set up IT to deliver
5986 from current_buffer. */
5987 if (it->n_overlay_strings)
5989 /* Make sure we know settings in current_buffer, so that we can
5990 restore meaningful values when we're done with the overlay
5991 strings. */
5992 if (compute_stop_p)
5993 compute_stop_pos (it);
5994 eassert (it->face_id >= 0);
5996 /* Save IT's settings. They are restored after all overlay
5997 strings have been processed. */
5998 eassert (!compute_stop_p || it->sp == 0);
6000 /* When called from handle_stop, there might be an empty display
6001 string loaded. In that case, don't bother saving it. But
6002 don't use this optimization with the bidi iterator, since we
6003 need the corresponding pop_it call to resync the bidi
6004 iterator's position with IT's position, after we are done
6005 with the overlay strings. (The corresponding call to pop_it
6006 in case of an empty display string is in
6007 next_overlay_string.) */
6008 if (!(!it->bidi_p
6009 && STRINGP (it->string) && !SCHARS (it->string)))
6010 push_it (it, NULL);
6012 /* Set up IT to deliver display elements from the first overlay
6013 string. */
6014 IT_STRING_CHARPOS (*it) = IT_STRING_BYTEPOS (*it) = 0;
6015 it->string = it->overlay_strings[0];
6016 it->from_overlay = Qnil;
6017 it->stop_charpos = 0;
6018 eassert (STRINGP (it->string));
6019 it->end_charpos = SCHARS (it->string);
6020 it->prev_stop = 0;
6021 it->base_level_stop = 0;
6022 it->multibyte_p = STRING_MULTIBYTE (it->string);
6023 it->method = GET_FROM_STRING;
6024 it->from_disp_prop_p = 0;
6025 it->cmp_it.id = -1;
6027 /* Force paragraph direction to be that of the parent
6028 buffer. */
6029 if (it->bidi_p && it->bidi_it.paragraph_dir == R2L)
6030 it->paragraph_embedding = it->bidi_it.paragraph_dir;
6031 else
6032 it->paragraph_embedding = L2R;
6034 /* Set up the bidi iterator for this overlay string. */
6035 if (it->bidi_p)
6037 ptrdiff_t pos = (charpos > 0 ? charpos : IT_CHARPOS (*it));
6039 it->bidi_it.string.lstring = it->string;
6040 it->bidi_it.string.s = NULL;
6041 it->bidi_it.string.schars = SCHARS (it->string);
6042 it->bidi_it.string.bufpos = pos;
6043 it->bidi_it.string.from_disp_str = it->string_from_display_prop_p;
6044 it->bidi_it.string.unibyte = !it->multibyte_p;
6045 it->bidi_it.w = it->w;
6046 bidi_init_it (0, 0, FRAME_WINDOW_P (it->f), &it->bidi_it);
6048 return true;
6051 it->current.overlay_string_index = -1;
6052 return false;
6055 static bool
6056 get_overlay_strings (struct it *it, ptrdiff_t charpos)
6058 it->string = Qnil;
6059 it->method = GET_FROM_BUFFER;
6061 get_overlay_strings_1 (it, charpos, true);
6063 CHECK_IT (it);
6065 /* Value is true if we found at least one overlay string. */
6066 return STRINGP (it->string);
6071 /***********************************************************************
6072 Saving and restoring state
6073 ***********************************************************************/
6075 /* Save current settings of IT on IT->stack. Called, for example,
6076 before setting up IT for an overlay string, to be able to restore
6077 IT's settings to what they were after the overlay string has been
6078 processed. If POSITION is non-NULL, it is the position to save on
6079 the stack instead of IT->position. */
6081 static void
6082 push_it (struct it *it, struct text_pos *position)
6084 struct iterator_stack_entry *p;
6086 eassert (it->sp < IT_STACK_SIZE);
6087 p = it->stack + it->sp;
6089 p->stop_charpos = it->stop_charpos;
6090 p->prev_stop = it->prev_stop;
6091 p->base_level_stop = it->base_level_stop;
6092 p->cmp_it = it->cmp_it;
6093 eassert (it->face_id >= 0);
6094 p->face_id = it->face_id;
6095 p->string = it->string;
6096 p->method = it->method;
6097 p->from_overlay = it->from_overlay;
6098 switch (p->method)
6100 case GET_FROM_IMAGE:
6101 p->u.image.object = it->object;
6102 p->u.image.image_id = it->image_id;
6103 p->u.image.slice = it->slice;
6104 break;
6105 case GET_FROM_STRETCH:
6106 p->u.stretch.object = it->object;
6107 break;
6108 case GET_FROM_XWIDGET:
6109 p->u.xwidget.object = it->object;
6110 break;
6111 case GET_FROM_BUFFER:
6112 case GET_FROM_DISPLAY_VECTOR:
6113 case GET_FROM_STRING:
6114 case GET_FROM_C_STRING:
6115 break;
6116 default:
6117 emacs_abort ();
6119 p->position = position ? *position : it->position;
6120 p->current = it->current;
6121 p->end_charpos = it->end_charpos;
6122 p->string_nchars = it->string_nchars;
6123 p->area = it->area;
6124 p->multibyte_p = it->multibyte_p;
6125 p->avoid_cursor_p = it->avoid_cursor_p;
6126 p->space_width = it->space_width;
6127 p->font_height = it->font_height;
6128 p->voffset = it->voffset;
6129 p->string_from_display_prop_p = it->string_from_display_prop_p;
6130 p->string_from_prefix_prop_p = it->string_from_prefix_prop_p;
6131 p->display_ellipsis_p = false;
6132 p->line_wrap = it->line_wrap;
6133 p->bidi_p = it->bidi_p;
6134 p->paragraph_embedding = it->paragraph_embedding;
6135 p->from_disp_prop_p = it->from_disp_prop_p;
6136 ++it->sp;
6138 /* Save the state of the bidi iterator as well. */
6139 if (it->bidi_p)
6140 bidi_push_it (&it->bidi_it);
6143 static void
6144 iterate_out_of_display_property (struct it *it)
6146 bool buffer_p = !STRINGP (it->string);
6147 ptrdiff_t eob = (buffer_p ? ZV : it->end_charpos);
6148 ptrdiff_t bob = (buffer_p ? BEGV : 0);
6150 eassert (eob >= CHARPOS (it->position) && CHARPOS (it->position) >= bob);
6152 /* Maybe initialize paragraph direction. If we are at the beginning
6153 of a new paragraph, next_element_from_buffer may not have a
6154 chance to do that. */
6155 if (it->bidi_it.first_elt && it->bidi_it.charpos < eob)
6156 bidi_paragraph_init (it->paragraph_embedding, &it->bidi_it, true);
6157 /* prev_stop can be zero, so check against BEGV as well. */
6158 while (it->bidi_it.charpos >= bob
6159 && it->prev_stop <= it->bidi_it.charpos
6160 && it->bidi_it.charpos < CHARPOS (it->position)
6161 && it->bidi_it.charpos < eob)
6162 bidi_move_to_visually_next (&it->bidi_it);
6163 /* Record the stop_pos we just crossed, for when we cross it
6164 back, maybe. */
6165 if (it->bidi_it.charpos > CHARPOS (it->position))
6166 it->prev_stop = CHARPOS (it->position);
6167 /* If we ended up not where pop_it put us, resync IT's
6168 positional members with the bidi iterator. */
6169 if (it->bidi_it.charpos != CHARPOS (it->position))
6170 SET_TEXT_POS (it->position, it->bidi_it.charpos, it->bidi_it.bytepos);
6171 if (buffer_p)
6172 it->current.pos = it->position;
6173 else
6174 it->current.string_pos = it->position;
6177 /* Restore IT's settings from IT->stack. Called, for example, when no
6178 more overlay strings must be processed, and we return to delivering
6179 display elements from a buffer, or when the end of a string from a
6180 `display' property is reached and we return to delivering display
6181 elements from an overlay string, or from a buffer. */
6183 static void
6184 pop_it (struct it *it)
6186 struct iterator_stack_entry *p;
6187 bool from_display_prop = it->from_disp_prop_p;
6188 ptrdiff_t prev_pos = IT_CHARPOS (*it);
6190 eassert (it->sp > 0);
6191 --it->sp;
6192 p = it->stack + it->sp;
6193 it->stop_charpos = p->stop_charpos;
6194 it->prev_stop = p->prev_stop;
6195 it->base_level_stop = p->base_level_stop;
6196 it->cmp_it = p->cmp_it;
6197 it->face_id = p->face_id;
6198 it->current = p->current;
6199 it->position = p->position;
6200 it->string = p->string;
6201 it->from_overlay = p->from_overlay;
6202 if (NILP (it->string))
6203 SET_TEXT_POS (it->current.string_pos, -1, -1);
6204 it->method = p->method;
6205 switch (it->method)
6207 case GET_FROM_IMAGE:
6208 it->image_id = p->u.image.image_id;
6209 it->object = p->u.image.object;
6210 it->slice = p->u.image.slice;
6211 break;
6212 case GET_FROM_XWIDGET:
6213 it->object = p->u.xwidget.object;
6214 break;
6215 case GET_FROM_STRETCH:
6216 it->object = p->u.stretch.object;
6217 break;
6218 case GET_FROM_BUFFER:
6219 it->object = it->w->contents;
6220 break;
6221 case GET_FROM_STRING:
6223 struct face *face = FACE_FROM_ID_OR_NULL (it->f, it->face_id);
6225 /* Restore the face_box_p flag, since it could have been
6226 overwritten by the face of the object that we just finished
6227 displaying. */
6228 if (face)
6229 it->face_box_p = face->box != FACE_NO_BOX;
6230 it->object = it->string;
6232 break;
6233 case GET_FROM_DISPLAY_VECTOR:
6234 if (it->s)
6235 it->method = GET_FROM_C_STRING;
6236 else if (STRINGP (it->string))
6237 it->method = GET_FROM_STRING;
6238 else
6240 it->method = GET_FROM_BUFFER;
6241 it->object = it->w->contents;
6243 break;
6244 case GET_FROM_C_STRING:
6245 break;
6246 default:
6247 emacs_abort ();
6249 it->end_charpos = p->end_charpos;
6250 it->string_nchars = p->string_nchars;
6251 it->area = p->area;
6252 it->multibyte_p = p->multibyte_p;
6253 it->avoid_cursor_p = p->avoid_cursor_p;
6254 it->space_width = p->space_width;
6255 it->font_height = p->font_height;
6256 it->voffset = p->voffset;
6257 it->string_from_display_prop_p = p->string_from_display_prop_p;
6258 it->string_from_prefix_prop_p = p->string_from_prefix_prop_p;
6259 it->line_wrap = p->line_wrap;
6260 it->bidi_p = p->bidi_p;
6261 it->paragraph_embedding = p->paragraph_embedding;
6262 it->from_disp_prop_p = p->from_disp_prop_p;
6263 if (it->bidi_p)
6265 bidi_pop_it (&it->bidi_it);
6266 /* Bidi-iterate until we get out of the portion of text, if any,
6267 covered by a `display' text property or by an overlay with
6268 `display' property. (We cannot just jump there, because the
6269 internal coherency of the bidi iterator state can not be
6270 preserved across such jumps.) We also must determine the
6271 paragraph base direction if the overlay we just processed is
6272 at the beginning of a new paragraph. */
6273 if (from_display_prop
6274 && (it->method == GET_FROM_BUFFER || it->method == GET_FROM_STRING))
6275 iterate_out_of_display_property (it);
6277 eassert ((BUFFERP (it->object)
6278 && IT_CHARPOS (*it) == it->bidi_it.charpos
6279 && IT_BYTEPOS (*it) == it->bidi_it.bytepos)
6280 || (STRINGP (it->object)
6281 && IT_STRING_CHARPOS (*it) == it->bidi_it.charpos
6282 && IT_STRING_BYTEPOS (*it) == it->bidi_it.bytepos)
6283 || (CONSP (it->object) && it->method == GET_FROM_STRETCH));
6285 /* If we move the iterator over text covered by a display property
6286 to a new buffer position, any info about previously seen overlays
6287 is no longer valid. */
6288 if (from_display_prop && it->sp == 0 && CHARPOS (it->position) != prev_pos)
6289 it->ignore_overlay_strings_at_pos_p = false;
6294 /***********************************************************************
6295 Moving over lines
6296 ***********************************************************************/
6298 /* Set IT's current position to the previous line start. */
6300 static void
6301 back_to_previous_line_start (struct it *it)
6303 ptrdiff_t cp = IT_CHARPOS (*it), bp = IT_BYTEPOS (*it);
6305 DEC_BOTH (cp, bp);
6306 IT_CHARPOS (*it) = find_newline_no_quit (cp, bp, -1, &IT_BYTEPOS (*it));
6310 /* Move IT to the next line start.
6312 Value is true if a newline was found. Set *SKIPPED_P to true if
6313 we skipped over part of the text (as opposed to moving the iterator
6314 continuously over the text). Otherwise, don't change the value
6315 of *SKIPPED_P.
6317 If BIDI_IT_PREV is non-NULL, store into it the state of the bidi
6318 iterator on the newline, if it was found.
6320 Newlines may come from buffer text, overlay strings, or strings
6321 displayed via the `display' property. That's the reason we can't
6322 simply use find_newline_no_quit.
6324 Note that this function may not skip over invisible text that is so
6325 because of text properties and immediately follows a newline. If
6326 it would, function reseat_at_next_visible_line_start, when called
6327 from set_iterator_to_next, would effectively make invisible
6328 characters following a newline part of the wrong glyph row, which
6329 leads to wrong cursor motion. */
6331 static bool
6332 forward_to_next_line_start (struct it *it, bool *skipped_p,
6333 struct bidi_it *bidi_it_prev)
6335 ptrdiff_t old_selective;
6336 bool newline_found_p = false;
6337 int n;
6338 const int MAX_NEWLINE_DISTANCE = 500;
6340 /* If already on a newline, just consume it to avoid unintended
6341 skipping over invisible text below. */
6342 if (it->what == IT_CHARACTER
6343 && it->c == '\n'
6344 && CHARPOS (it->position) == IT_CHARPOS (*it))
6346 if (it->bidi_p && bidi_it_prev)
6347 *bidi_it_prev = it->bidi_it;
6348 set_iterator_to_next (it, false);
6349 it->c = 0;
6350 return true;
6353 /* Don't handle selective display in the following. It's (a)
6354 unnecessary because it's done by the caller, and (b) leads to an
6355 infinite recursion because next_element_from_ellipsis indirectly
6356 calls this function. */
6357 old_selective = it->selective;
6358 it->selective = 0;
6360 /* Scan for a newline within MAX_NEWLINE_DISTANCE display elements
6361 from buffer text. */
6362 for (n = 0;
6363 !newline_found_p && n < MAX_NEWLINE_DISTANCE;
6364 n += !STRINGP (it->string))
6366 if (!get_next_display_element (it))
6367 return false;
6368 newline_found_p = it->what == IT_CHARACTER && it->c == '\n';
6369 if (newline_found_p && it->bidi_p && bidi_it_prev)
6370 *bidi_it_prev = it->bidi_it;
6371 set_iterator_to_next (it, false);
6374 /* If we didn't find a newline near enough, see if we can use a
6375 short-cut. */
6376 if (!newline_found_p)
6378 ptrdiff_t bytepos, start = IT_CHARPOS (*it);
6379 ptrdiff_t limit = find_newline_no_quit (start, IT_BYTEPOS (*it),
6380 1, &bytepos);
6381 Lisp_Object pos;
6383 eassert (!STRINGP (it->string));
6385 /* If there isn't any `display' property in sight, and no
6386 overlays, we can just use the position of the newline in
6387 buffer text. */
6388 if (it->stop_charpos >= limit
6389 || ((pos = Fnext_single_property_change (make_number (start),
6390 Qdisplay, Qnil,
6391 make_number (limit)),
6392 NILP (pos))
6393 && next_overlay_change (start) == ZV))
6395 if (!it->bidi_p)
6397 IT_CHARPOS (*it) = limit;
6398 IT_BYTEPOS (*it) = bytepos;
6400 else
6402 struct bidi_it bprev;
6404 /* Help bidi.c avoid expensive searches for display
6405 properties and overlays, by telling it that there are
6406 none up to `limit'. */
6407 if (it->bidi_it.disp_pos < limit)
6409 it->bidi_it.disp_pos = limit;
6410 it->bidi_it.disp_prop = 0;
6412 do {
6413 bprev = it->bidi_it;
6414 bidi_move_to_visually_next (&it->bidi_it);
6415 } while (it->bidi_it.charpos != limit);
6416 IT_CHARPOS (*it) = limit;
6417 IT_BYTEPOS (*it) = it->bidi_it.bytepos;
6418 if (bidi_it_prev)
6419 *bidi_it_prev = bprev;
6421 *skipped_p = newline_found_p = true;
6423 else
6425 while (!newline_found_p)
6427 if (!get_next_display_element (it))
6428 break;
6429 newline_found_p = ITERATOR_AT_END_OF_LINE_P (it);
6430 if (newline_found_p && it->bidi_p && bidi_it_prev)
6431 *bidi_it_prev = it->bidi_it;
6432 set_iterator_to_next (it, false);
6437 it->selective = old_selective;
6438 return newline_found_p;
6442 /* Set IT's current position to the previous visible line start. Skip
6443 invisible text that is so either due to text properties or due to
6444 selective display. Caution: this does not change IT->current_x and
6445 IT->hpos. */
6447 static void
6448 back_to_previous_visible_line_start (struct it *it)
6450 while (IT_CHARPOS (*it) > BEGV)
6452 back_to_previous_line_start (it);
6454 if (IT_CHARPOS (*it) <= BEGV)
6455 break;
6457 /* If selective > 0, then lines indented more than its value are
6458 invisible. */
6459 if (it->selective > 0
6460 && indented_beyond_p (IT_CHARPOS (*it), IT_BYTEPOS (*it),
6461 it->selective))
6462 continue;
6464 /* Check the newline before point for invisibility. */
6466 Lisp_Object prop;
6467 prop = Fget_char_property (make_number (IT_CHARPOS (*it) - 1),
6468 Qinvisible, it->window);
6469 if (TEXT_PROP_MEANS_INVISIBLE (prop) != 0)
6470 continue;
6473 if (IT_CHARPOS (*it) <= BEGV)
6474 break;
6477 struct it it2;
6478 void *it2data = NULL;
6479 ptrdiff_t pos;
6480 ptrdiff_t beg, end;
6481 Lisp_Object val, overlay;
6483 SAVE_IT (it2, *it, it2data);
6485 /* If newline is part of a composition, continue from start of composition */
6486 if (find_composition (IT_CHARPOS (*it), -1, &beg, &end, &val, Qnil)
6487 && beg < IT_CHARPOS (*it))
6488 goto replaced;
6490 /* If newline is replaced by a display property, find start of overlay
6491 or interval and continue search from that point. */
6492 pos = --IT_CHARPOS (it2);
6493 --IT_BYTEPOS (it2);
6494 it2.sp = 0;
6495 bidi_unshelve_cache (NULL, false);
6496 it2.string_from_display_prop_p = false;
6497 it2.from_disp_prop_p = false;
6498 if (handle_display_prop (&it2) == HANDLED_RETURN
6499 && !NILP (val = get_char_property_and_overlay
6500 (make_number (pos), Qdisplay, Qnil, &overlay))
6501 && (OVERLAYP (overlay)
6502 ? (beg = OVERLAY_POSITION (OVERLAY_START (overlay)))
6503 : get_property_and_range (pos, Qdisplay, &val, &beg, &end, Qnil)))
6505 RESTORE_IT (it, it, it2data);
6506 goto replaced;
6509 /* Newline is not replaced by anything -- so we are done. */
6510 RESTORE_IT (it, it, it2data);
6511 break;
6513 replaced:
6514 if (beg < BEGV)
6515 beg = BEGV;
6516 IT_CHARPOS (*it) = beg;
6517 IT_BYTEPOS (*it) = buf_charpos_to_bytepos (current_buffer, beg);
6521 it->continuation_lines_width = 0;
6523 eassert (IT_CHARPOS (*it) >= BEGV);
6524 eassert (IT_CHARPOS (*it) == BEGV
6525 || FETCH_BYTE (IT_BYTEPOS (*it) - 1) == '\n');
6526 CHECK_IT (it);
6530 /* Reseat iterator IT at the previous visible line start. Skip
6531 invisible text that is so either due to text properties or due to
6532 selective display. At the end, update IT's overlay information,
6533 face information etc. */
6535 void
6536 reseat_at_previous_visible_line_start (struct it *it)
6538 back_to_previous_visible_line_start (it);
6539 reseat (it, it->current.pos, true);
6540 CHECK_IT (it);
6544 /* Reseat iterator IT on the next visible line start in the current
6545 buffer. ON_NEWLINE_P means position IT on the newline
6546 preceding the line start. Skip over invisible text that is so
6547 because of selective display. Compute faces, overlays etc at the
6548 new position. Note that this function does not skip over text that
6549 is invisible because of text properties. */
6551 static void
6552 reseat_at_next_visible_line_start (struct it *it, bool on_newline_p)
6554 bool skipped_p = false;
6555 struct bidi_it bidi_it_prev;
6556 bool newline_found_p
6557 = forward_to_next_line_start (it, &skipped_p, &bidi_it_prev);
6559 /* Skip over lines that are invisible because they are indented
6560 more than the value of IT->selective. */
6561 if (it->selective > 0)
6562 while (IT_CHARPOS (*it) < ZV
6563 && indented_beyond_p (IT_CHARPOS (*it), IT_BYTEPOS (*it),
6564 it->selective))
6566 eassert (IT_BYTEPOS (*it) == BEGV
6567 || FETCH_BYTE (IT_BYTEPOS (*it) - 1) == '\n');
6568 newline_found_p =
6569 forward_to_next_line_start (it, &skipped_p, &bidi_it_prev);
6572 /* Position on the newline if that's what's requested. */
6573 if (on_newline_p && newline_found_p)
6575 if (STRINGP (it->string))
6577 if (IT_STRING_CHARPOS (*it) > 0)
6579 if (!it->bidi_p)
6581 --IT_STRING_CHARPOS (*it);
6582 --IT_STRING_BYTEPOS (*it);
6584 else
6586 /* We need to restore the bidi iterator to the state
6587 it had on the newline, and resync the IT's
6588 position with that. */
6589 it->bidi_it = bidi_it_prev;
6590 IT_STRING_CHARPOS (*it) = it->bidi_it.charpos;
6591 IT_STRING_BYTEPOS (*it) = it->bidi_it.bytepos;
6595 else if (IT_CHARPOS (*it) > BEGV)
6597 if (!it->bidi_p)
6599 --IT_CHARPOS (*it);
6600 --IT_BYTEPOS (*it);
6602 else
6604 /* We need to restore the bidi iterator to the state it
6605 had on the newline and resync IT with that. */
6606 it->bidi_it = bidi_it_prev;
6607 IT_CHARPOS (*it) = it->bidi_it.charpos;
6608 IT_BYTEPOS (*it) = it->bidi_it.bytepos;
6610 reseat (it, it->current.pos, false);
6613 else if (skipped_p)
6614 reseat (it, it->current.pos, false);
6616 CHECK_IT (it);
6621 /***********************************************************************
6622 Changing an iterator's position
6623 ***********************************************************************/
6625 /* Change IT's current position to POS in current_buffer.
6626 If FORCE_P, always check for text properties at the new position.
6627 Otherwise, text properties are only looked up if POS >=
6628 IT->check_charpos of a property. */
6630 static void
6631 reseat (struct it *it, struct text_pos pos, bool force_p)
6633 ptrdiff_t original_pos = IT_CHARPOS (*it);
6635 reseat_1 (it, pos, false);
6637 /* Determine where to check text properties. Avoid doing it
6638 where possible because text property lookup is very expensive. */
6639 if (force_p
6640 || CHARPOS (pos) > it->stop_charpos
6641 || CHARPOS (pos) < original_pos)
6643 if (it->bidi_p)
6645 /* For bidi iteration, we need to prime prev_stop and
6646 base_level_stop with our best estimations. */
6647 /* Implementation note: Of course, POS is not necessarily a
6648 stop position, so assigning prev_pos to it is a lie; we
6649 should have called compute_stop_backwards. However, if
6650 the current buffer does not include any R2L characters,
6651 that call would be a waste of cycles, because the
6652 iterator will never move back, and thus never cross this
6653 "fake" stop position. So we delay that backward search
6654 until the time we really need it, in next_element_from_buffer. */
6655 if (CHARPOS (pos) != it->prev_stop)
6656 it->prev_stop = CHARPOS (pos);
6657 if (CHARPOS (pos) < it->base_level_stop)
6658 it->base_level_stop = 0; /* meaning it's unknown */
6659 handle_stop (it);
6661 else
6663 handle_stop (it);
6664 it->prev_stop = it->base_level_stop = 0;
6669 CHECK_IT (it);
6673 /* Change IT's buffer position to POS. SET_STOP_P means set
6674 IT->stop_pos to POS, also. */
6676 static void
6677 reseat_1 (struct it *it, struct text_pos pos, bool set_stop_p)
6679 /* Don't call this function when scanning a C string. */
6680 eassert (it->s == NULL);
6682 /* POS must be a reasonable value. */
6683 eassert (CHARPOS (pos) >= BEGV && CHARPOS (pos) <= ZV);
6685 it->current.pos = it->position = pos;
6686 it->end_charpos = ZV;
6687 it->dpvec = NULL;
6688 it->current.dpvec_index = -1;
6689 it->current.overlay_string_index = -1;
6690 IT_STRING_CHARPOS (*it) = -1;
6691 IT_STRING_BYTEPOS (*it) = -1;
6692 it->string = Qnil;
6693 it->method = GET_FROM_BUFFER;
6694 it->object = it->w->contents;
6695 it->area = TEXT_AREA;
6696 it->multibyte_p = !NILP (BVAR (current_buffer, enable_multibyte_characters));
6697 it->sp = 0;
6698 it->string_from_display_prop_p = false;
6699 it->string_from_prefix_prop_p = false;
6701 it->from_disp_prop_p = false;
6702 it->face_before_selective_p = false;
6703 if (it->bidi_p)
6705 bidi_init_it (IT_CHARPOS (*it), IT_BYTEPOS (*it), FRAME_WINDOW_P (it->f),
6706 &it->bidi_it);
6707 bidi_unshelve_cache (NULL, false);
6708 it->bidi_it.paragraph_dir = NEUTRAL_DIR;
6709 it->bidi_it.string.s = NULL;
6710 it->bidi_it.string.lstring = Qnil;
6711 it->bidi_it.string.bufpos = 0;
6712 it->bidi_it.string.from_disp_str = false;
6713 it->bidi_it.string.unibyte = false;
6714 it->bidi_it.w = it->w;
6717 if (set_stop_p)
6719 it->stop_charpos = CHARPOS (pos);
6720 it->base_level_stop = CHARPOS (pos);
6722 /* This make the information stored in it->cmp_it invalidate. */
6723 it->cmp_it.id = -1;
6727 /* Set up IT for displaying a string, starting at CHARPOS in window W.
6728 If S is non-null, it is a C string to iterate over. Otherwise,
6729 STRING gives a Lisp string to iterate over.
6731 If PRECISION > 0, don't return more then PRECISION number of
6732 characters from the string.
6734 If FIELD_WIDTH > 0, return padding spaces until FIELD_WIDTH
6735 characters have been returned. FIELD_WIDTH < 0 means an infinite
6736 field width.
6738 MULTIBYTE = 0 means disable processing of multibyte characters,
6739 MULTIBYTE > 0 means enable it,
6740 MULTIBYTE < 0 means use IT->multibyte_p.
6742 IT must be initialized via a prior call to init_iterator before
6743 calling this function. */
6745 static void
6746 reseat_to_string (struct it *it, const char *s, Lisp_Object string,
6747 ptrdiff_t charpos, ptrdiff_t precision, int field_width,
6748 int multibyte)
6750 /* No text property checks performed by default, but see below. */
6751 it->stop_charpos = -1;
6753 /* Set iterator position and end position. */
6754 memset (&it->current, 0, sizeof it->current);
6755 it->current.overlay_string_index = -1;
6756 it->current.dpvec_index = -1;
6757 eassert (charpos >= 0);
6759 /* If STRING is specified, use its multibyteness, otherwise use the
6760 setting of MULTIBYTE, if specified. */
6761 if (multibyte >= 0)
6762 it->multibyte_p = multibyte > 0;
6764 /* Bidirectional reordering of strings is controlled by the default
6765 value of bidi-display-reordering. Don't try to reorder while
6766 loading loadup.el, as the necessary character property tables are
6767 not yet available. */
6768 it->bidi_p =
6769 !redisplay__inhibit_bidi
6770 && !NILP (BVAR (&buffer_defaults, bidi_display_reordering));
6772 if (s == NULL)
6774 eassert (STRINGP (string));
6775 it->string = string;
6776 it->s = NULL;
6777 it->end_charpos = it->string_nchars = SCHARS (string);
6778 it->method = GET_FROM_STRING;
6779 it->current.string_pos = string_pos (charpos, string);
6781 if (it->bidi_p)
6783 it->bidi_it.string.lstring = string;
6784 it->bidi_it.string.s = NULL;
6785 it->bidi_it.string.schars = it->end_charpos;
6786 it->bidi_it.string.bufpos = 0;
6787 it->bidi_it.string.from_disp_str = false;
6788 it->bidi_it.string.unibyte = !it->multibyte_p;
6789 it->bidi_it.w = it->w;
6790 bidi_init_it (charpos, IT_STRING_BYTEPOS (*it),
6791 FRAME_WINDOW_P (it->f), &it->bidi_it);
6794 else
6796 it->s = (const unsigned char *) s;
6797 it->string = Qnil;
6799 /* Note that we use IT->current.pos, not it->current.string_pos,
6800 for displaying C strings. */
6801 IT_STRING_CHARPOS (*it) = IT_STRING_BYTEPOS (*it) = -1;
6802 if (it->multibyte_p)
6804 it->current.pos = c_string_pos (charpos, s, true);
6805 it->end_charpos = it->string_nchars = number_of_chars (s, true);
6807 else
6809 IT_CHARPOS (*it) = IT_BYTEPOS (*it) = charpos;
6810 it->end_charpos = it->string_nchars = strlen (s);
6813 if (it->bidi_p)
6815 it->bidi_it.string.lstring = Qnil;
6816 it->bidi_it.string.s = (const unsigned char *) s;
6817 it->bidi_it.string.schars = it->end_charpos;
6818 it->bidi_it.string.bufpos = 0;
6819 it->bidi_it.string.from_disp_str = false;
6820 it->bidi_it.string.unibyte = !it->multibyte_p;
6821 it->bidi_it.w = it->w;
6822 bidi_init_it (charpos, IT_BYTEPOS (*it), FRAME_WINDOW_P (it->f),
6823 &it->bidi_it);
6825 it->method = GET_FROM_C_STRING;
6828 /* PRECISION > 0 means don't return more than PRECISION characters
6829 from the string. */
6830 if (precision > 0 && it->end_charpos - charpos > precision)
6832 it->end_charpos = it->string_nchars = charpos + precision;
6833 if (it->bidi_p)
6834 it->bidi_it.string.schars = it->end_charpos;
6837 /* FIELD_WIDTH > 0 means pad with spaces until FIELD_WIDTH
6838 characters have been returned. FIELD_WIDTH == 0 means don't pad,
6839 FIELD_WIDTH < 0 means infinite field width. This is useful for
6840 padding with `-' at the end of a mode line. */
6841 if (field_width < 0)
6842 field_width = DISP_INFINITY;
6843 /* Implementation note: We deliberately don't enlarge
6844 it->bidi_it.string.schars here to fit it->end_charpos, because
6845 the bidi iterator cannot produce characters out of thin air. */
6846 if (field_width > it->end_charpos - charpos)
6847 it->end_charpos = charpos + field_width;
6849 /* Use the standard display table for displaying strings. */
6850 if (DISP_TABLE_P (Vstandard_display_table))
6851 it->dp = XCHAR_TABLE (Vstandard_display_table);
6853 it->stop_charpos = charpos;
6854 it->prev_stop = charpos;
6855 it->base_level_stop = 0;
6856 if (it->bidi_p)
6858 it->bidi_it.first_elt = true;
6859 it->bidi_it.paragraph_dir = NEUTRAL_DIR;
6860 it->bidi_it.disp_pos = -1;
6862 if (s == NULL && it->multibyte_p)
6864 ptrdiff_t endpos = SCHARS (it->string);
6865 if (endpos > it->end_charpos)
6866 endpos = it->end_charpos;
6867 composition_compute_stop_pos (&it->cmp_it, charpos, -1, endpos,
6868 it->string);
6870 CHECK_IT (it);
6875 /***********************************************************************
6876 Iteration
6877 ***********************************************************************/
6879 /* Map enum it_method value to corresponding next_element_from_* function. */
6881 typedef bool (*next_element_function) (struct it *);
6883 static next_element_function const get_next_element[NUM_IT_METHODS] =
6885 next_element_from_buffer,
6886 next_element_from_display_vector,
6887 next_element_from_string,
6888 next_element_from_c_string,
6889 next_element_from_image,
6890 next_element_from_stretch,
6891 next_element_from_xwidget,
6894 #define GET_NEXT_DISPLAY_ELEMENT(it) (*get_next_element[(it)->method]) (it)
6897 /* Return true iff a character at CHARPOS (and BYTEPOS) is composed
6898 (possibly with the following characters). */
6900 #define CHAR_COMPOSED_P(IT,CHARPOS,BYTEPOS,END_CHARPOS) \
6901 ((IT)->cmp_it.id >= 0 \
6902 || ((IT)->cmp_it.stop_pos == (CHARPOS) \
6903 && composition_reseat_it (&(IT)->cmp_it, CHARPOS, BYTEPOS, \
6904 END_CHARPOS, (IT)->w, \
6905 FACE_FROM_ID_OR_NULL ((IT)->f, \
6906 (IT)->face_id), \
6907 (IT)->string)))
6910 /* Lookup the char-table Vglyphless_char_display for character C (-1
6911 if we want information for no-font case), and return the display
6912 method symbol. By side-effect, update it->what and
6913 it->glyphless_method. This function is called from
6914 get_next_display_element for each character element, and from
6915 x_produce_glyphs when no suitable font was found. */
6917 Lisp_Object
6918 lookup_glyphless_char_display (int c, struct it *it)
6920 Lisp_Object glyphless_method = Qnil;
6922 if (CHAR_TABLE_P (Vglyphless_char_display)
6923 && CHAR_TABLE_EXTRA_SLOTS (XCHAR_TABLE (Vglyphless_char_display)) >= 1)
6925 if (c >= 0)
6927 glyphless_method = CHAR_TABLE_REF (Vglyphless_char_display, c);
6928 if (CONSP (glyphless_method))
6929 glyphless_method = FRAME_WINDOW_P (it->f)
6930 ? XCAR (glyphless_method)
6931 : XCDR (glyphless_method);
6933 else
6934 glyphless_method = XCHAR_TABLE (Vglyphless_char_display)->extras[0];
6937 retry:
6938 if (NILP (glyphless_method))
6940 if (c >= 0)
6941 /* The default is to display the character by a proper font. */
6942 return Qnil;
6943 /* The default for the no-font case is to display an empty box. */
6944 glyphless_method = Qempty_box;
6946 if (EQ (glyphless_method, Qzero_width))
6948 if (c >= 0)
6949 return glyphless_method;
6950 /* This method can't be used for the no-font case. */
6951 glyphless_method = Qempty_box;
6953 if (EQ (glyphless_method, Qthin_space))
6954 it->glyphless_method = GLYPHLESS_DISPLAY_THIN_SPACE;
6955 else if (EQ (glyphless_method, Qempty_box))
6956 it->glyphless_method = GLYPHLESS_DISPLAY_EMPTY_BOX;
6957 else if (EQ (glyphless_method, Qhex_code))
6958 it->glyphless_method = GLYPHLESS_DISPLAY_HEX_CODE;
6959 else if (STRINGP (glyphless_method))
6960 it->glyphless_method = GLYPHLESS_DISPLAY_ACRONYM;
6961 else
6963 /* Invalid value. We use the default method. */
6964 glyphless_method = Qnil;
6965 goto retry;
6967 it->what = IT_GLYPHLESS;
6968 return glyphless_method;
6971 /* Merge escape glyph face and cache the result. */
6973 static struct frame *last_escape_glyph_frame = NULL;
6974 static int last_escape_glyph_face_id = (1 << FACE_ID_BITS);
6975 static int last_escape_glyph_merged_face_id = 0;
6977 static int
6978 merge_escape_glyph_face (struct it *it)
6980 int face_id;
6982 if (it->f == last_escape_glyph_frame
6983 && it->face_id == last_escape_glyph_face_id)
6984 face_id = last_escape_glyph_merged_face_id;
6985 else
6987 /* Merge the `escape-glyph' face into the current face. */
6988 face_id = merge_faces (it->f, Qescape_glyph, 0, it->face_id);
6989 last_escape_glyph_frame = it->f;
6990 last_escape_glyph_face_id = it->face_id;
6991 last_escape_glyph_merged_face_id = face_id;
6993 return face_id;
6996 /* Likewise for glyphless glyph face. */
6998 static struct frame *last_glyphless_glyph_frame = NULL;
6999 static int last_glyphless_glyph_face_id = (1 << FACE_ID_BITS);
7000 static int last_glyphless_glyph_merged_face_id = 0;
7003 merge_glyphless_glyph_face (struct it *it)
7005 int face_id;
7007 if (it->f == last_glyphless_glyph_frame
7008 && it->face_id == last_glyphless_glyph_face_id)
7009 face_id = last_glyphless_glyph_merged_face_id;
7010 else
7012 /* Merge the `glyphless-char' face into the current face. */
7013 face_id = merge_faces (it->f, Qglyphless_char, 0, it->face_id);
7014 last_glyphless_glyph_frame = it->f;
7015 last_glyphless_glyph_face_id = it->face_id;
7016 last_glyphless_glyph_merged_face_id = face_id;
7018 return face_id;
7021 /* Forget the `escape-glyph' and `glyphless-char' faces. This should
7022 be called before redisplaying windows, and when the frame's face
7023 cache is freed. */
7024 void
7025 forget_escape_and_glyphless_faces (void)
7027 last_escape_glyph_frame = NULL;
7028 last_escape_glyph_face_id = (1 << FACE_ID_BITS);
7029 last_glyphless_glyph_frame = NULL;
7030 last_glyphless_glyph_face_id = (1 << FACE_ID_BITS);
7033 /* Load IT's display element fields with information about the next
7034 display element from the current position of IT. Value is false if
7035 end of buffer (or C string) is reached. */
7037 static bool
7038 get_next_display_element (struct it *it)
7040 /* True means that we found a display element. False means that
7041 we hit the end of what we iterate over. Performance note: the
7042 function pointer `method' used here turns out to be faster than
7043 using a sequence of if-statements. */
7044 bool success_p;
7046 get_next:
7047 success_p = GET_NEXT_DISPLAY_ELEMENT (it);
7049 if (it->what == IT_CHARACTER)
7051 /* UAX#9, L4: "A character is depicted by a mirrored glyph if
7052 and only if (a) the resolved directionality of that character
7053 is R..." */
7054 /* FIXME: Do we need an exception for characters from display
7055 tables? */
7056 if (it->bidi_p && it->bidi_it.type == STRONG_R
7057 && !inhibit_bidi_mirroring)
7058 it->c = bidi_mirror_char (it->c);
7059 /* Map via display table or translate control characters.
7060 IT->c, IT->len etc. have been set to the next character by
7061 the function call above. If we have a display table, and it
7062 contains an entry for IT->c, translate it. Don't do this if
7063 IT->c itself comes from a display table, otherwise we could
7064 end up in an infinite recursion. (An alternative could be to
7065 count the recursion depth of this function and signal an
7066 error when a certain maximum depth is reached.) Is it worth
7067 it? */
7068 if (success_p && it->dpvec == NULL)
7070 Lisp_Object dv;
7071 struct charset *unibyte = CHARSET_FROM_ID (charset_unibyte);
7072 bool nonascii_space_p = false;
7073 bool nonascii_hyphen_p = false;
7074 int c = it->c; /* This is the character to display. */
7076 if (! it->multibyte_p && ! ASCII_CHAR_P (c))
7078 eassert (SINGLE_BYTE_CHAR_P (c));
7079 if (unibyte_display_via_language_environment)
7081 c = DECODE_CHAR (unibyte, c);
7082 if (c < 0)
7083 c = BYTE8_TO_CHAR (it->c);
7085 else
7086 c = BYTE8_TO_CHAR (it->c);
7089 if (it->dp
7090 && (dv = DISP_CHAR_VECTOR (it->dp, c),
7091 VECTORP (dv)))
7093 struct Lisp_Vector *v = XVECTOR (dv);
7095 /* Return the first character from the display table
7096 entry, if not empty. If empty, don't display the
7097 current character. */
7098 if (v->header.size)
7100 it->dpvec_char_len = it->len;
7101 it->dpvec = v->contents;
7102 it->dpend = v->contents + v->header.size;
7103 it->current.dpvec_index = 0;
7104 it->dpvec_face_id = -1;
7105 it->saved_face_id = it->face_id;
7106 it->method = GET_FROM_DISPLAY_VECTOR;
7107 it->ellipsis_p = false;
7109 else
7111 set_iterator_to_next (it, false);
7113 goto get_next;
7116 if (! NILP (lookup_glyphless_char_display (c, it)))
7118 if (it->what == IT_GLYPHLESS)
7119 goto done;
7120 /* Don't display this character. */
7121 set_iterator_to_next (it, false);
7122 goto get_next;
7125 /* If `nobreak-char-display' is non-nil, we display
7126 non-ASCII spaces and hyphens specially. */
7127 if (! ASCII_CHAR_P (c) && ! NILP (Vnobreak_char_display))
7129 if (c == NO_BREAK_SPACE)
7130 nonascii_space_p = true;
7131 else if (c == SOFT_HYPHEN || c == HYPHEN
7132 || c == NON_BREAKING_HYPHEN)
7133 nonascii_hyphen_p = true;
7136 /* Translate control characters into `\003' or `^C' form.
7137 Control characters coming from a display table entry are
7138 currently not translated because we use IT->dpvec to hold
7139 the translation. This could easily be changed but I
7140 don't believe that it is worth doing.
7142 The characters handled by `nobreak-char-display' must be
7143 translated too.
7145 Non-printable characters and raw-byte characters are also
7146 translated to octal or hexadecimal form. */
7147 if (((c < ' ' || c == 127) /* ASCII control chars. */
7148 ? (it->area != TEXT_AREA
7149 /* In mode line, treat \n, \t like other crl chars. */
7150 || (c != '\t'
7151 && it->glyph_row
7152 && (it->glyph_row->mode_line_p || it->avoid_cursor_p))
7153 || (c != '\n' && c != '\t'))
7154 : (nonascii_space_p
7155 || nonascii_hyphen_p
7156 || CHAR_BYTE8_P (c)
7157 || ! CHAR_PRINTABLE_P (c))))
7159 /* C is a control character, non-ASCII space/hyphen,
7160 raw-byte, or a non-printable character which must be
7161 displayed either as '\003' or as `^C' where the '\\'
7162 and '^' can be defined in the display table. Fill
7163 IT->ctl_chars with glyphs for what we have to
7164 display. Then, set IT->dpvec to these glyphs. */
7165 Lisp_Object gc;
7166 int ctl_len;
7167 int face_id;
7168 int lface_id = 0;
7169 int escape_glyph;
7171 /* Handle control characters with ^. */
7173 if (ASCII_CHAR_P (c) && it->ctl_arrow_p)
7175 int g;
7177 g = '^'; /* default glyph for Control */
7178 /* Set IT->ctl_chars[0] to the glyph for `^'. */
7179 if (it->dp
7180 && (gc = DISP_CTRL_GLYPH (it->dp), GLYPH_CODE_P (gc)))
7182 g = GLYPH_CODE_CHAR (gc);
7183 lface_id = GLYPH_CODE_FACE (gc);
7186 face_id = (lface_id
7187 ? merge_faces (it->f, Qt, lface_id, it->face_id)
7188 : merge_escape_glyph_face (it));
7190 XSETINT (it->ctl_chars[0], g);
7191 XSETINT (it->ctl_chars[1], c ^ 0100);
7192 ctl_len = 2;
7193 goto display_control;
7196 /* Handle non-ascii space in the mode where it only gets
7197 highlighting. */
7199 if (nonascii_space_p && EQ (Vnobreak_char_display, Qt))
7201 /* Merge `nobreak-space' into the current face. */
7202 face_id = merge_faces (it->f, Qnobreak_space, 0,
7203 it->face_id);
7204 XSETINT (it->ctl_chars[0], ' ');
7205 ctl_len = 1;
7206 goto display_control;
7209 /* Handle non-ascii hyphens in the mode where it only
7210 gets highlighting. */
7212 if (nonascii_hyphen_p && EQ (Vnobreak_char_display, Qt))
7214 /* Merge `nobreak-space' into the current face. */
7215 face_id = merge_faces (it->f, Qnobreak_hyphen, 0,
7216 it->face_id);
7217 XSETINT (it->ctl_chars[0], '-');
7218 ctl_len = 1;
7219 goto display_control;
7222 /* Handle sequences that start with the "escape glyph". */
7224 /* the default escape glyph is \. */
7225 escape_glyph = '\\';
7227 if (it->dp
7228 && (gc = DISP_ESCAPE_GLYPH (it->dp), GLYPH_CODE_P (gc)))
7230 escape_glyph = GLYPH_CODE_CHAR (gc);
7231 lface_id = GLYPH_CODE_FACE (gc);
7234 face_id = (lface_id
7235 ? merge_faces (it->f, Qt, lface_id, it->face_id)
7236 : merge_escape_glyph_face (it));
7238 /* Draw non-ASCII space/hyphen with escape glyph: */
7240 if (nonascii_space_p || nonascii_hyphen_p)
7242 XSETINT (it->ctl_chars[0], escape_glyph);
7243 XSETINT (it->ctl_chars[1], nonascii_space_p ? ' ' : '-');
7244 ctl_len = 2;
7245 goto display_control;
7249 char str[10];
7250 int len, i;
7252 if (CHAR_BYTE8_P (c))
7253 /* Display \200 or \x80 instead of \17777600. */
7254 c = CHAR_TO_BYTE8 (c);
7255 const char *format_string = display_raw_bytes_as_hex
7256 ? "x%02x"
7257 : "%03o";
7258 len = sprintf (str, format_string, c + 0u);
7260 XSETINT (it->ctl_chars[0], escape_glyph);
7261 for (i = 0; i < len; i++)
7262 XSETINT (it->ctl_chars[i + 1], str[i]);
7263 ctl_len = len + 1;
7266 display_control:
7267 /* Set up IT->dpvec and return first character from it. */
7268 it->dpvec_char_len = it->len;
7269 it->dpvec = it->ctl_chars;
7270 it->dpend = it->dpvec + ctl_len;
7271 it->current.dpvec_index = 0;
7272 it->dpvec_face_id = face_id;
7273 it->saved_face_id = it->face_id;
7274 it->method = GET_FROM_DISPLAY_VECTOR;
7275 it->ellipsis_p = false;
7276 goto get_next;
7278 it->char_to_display = c;
7280 else if (success_p)
7282 it->char_to_display = it->c;
7286 #ifdef HAVE_WINDOW_SYSTEM
7287 /* Adjust face id for a multibyte character. There are no multibyte
7288 character in unibyte text. */
7289 if ((it->what == IT_CHARACTER || it->what == IT_COMPOSITION)
7290 && it->multibyte_p
7291 && success_p
7292 && FRAME_WINDOW_P (it->f))
7294 struct face *face = FACE_FROM_ID (it->f, it->face_id);
7296 if (it->what == IT_COMPOSITION && it->cmp_it.ch >= 0)
7298 /* Automatic composition with glyph-string. */
7299 Lisp_Object gstring = composition_gstring_from_id (it->cmp_it.id);
7301 it->face_id = face_for_font (it->f, LGSTRING_FONT (gstring), face);
7303 else
7305 ptrdiff_t pos = (it->s ? -1
7306 : STRINGP (it->string) ? IT_STRING_CHARPOS (*it)
7307 : IT_CHARPOS (*it));
7308 int c;
7310 if (it->what == IT_CHARACTER)
7311 c = it->char_to_display;
7312 else
7314 struct composition *cmp = composition_table[it->cmp_it.id];
7315 int i;
7317 c = ' ';
7318 for (i = 0; i < cmp->glyph_len; i++)
7319 /* TAB in a composition means display glyphs with
7320 padding space on the left or right. */
7321 if ((c = COMPOSITION_GLYPH (cmp, i)) != '\t')
7322 break;
7324 it->face_id = FACE_FOR_CHAR (it->f, face, c, pos, it->string);
7327 #endif /* HAVE_WINDOW_SYSTEM */
7329 done:
7330 /* Is this character the last one of a run of characters with
7331 box? If yes, set IT->end_of_box_run_p to true. */
7332 if (it->face_box_p
7333 && it->s == NULL)
7335 if (it->method == GET_FROM_STRING && it->sp)
7337 int face_id = underlying_face_id (it);
7338 struct face *face = FACE_FROM_ID_OR_NULL (it->f, face_id);
7340 if (face)
7342 if (face->box == FACE_NO_BOX)
7344 /* If the box comes from face properties in a
7345 display string, check faces in that string. */
7346 int string_face_id = face_after_it_pos (it);
7347 it->end_of_box_run_p
7348 = (FACE_FROM_ID (it->f, string_face_id)->box
7349 == FACE_NO_BOX);
7351 /* Otherwise, the box comes from the underlying face.
7352 If this is the last string character displayed, check
7353 the next buffer location. */
7354 else if ((IT_STRING_CHARPOS (*it) >= SCHARS (it->string) - 1)
7355 /* n_overlay_strings is unreliable unless
7356 overlay_string_index is non-negative. */
7357 && ((it->current.overlay_string_index >= 0
7358 && (it->current.overlay_string_index
7359 == it->n_overlay_strings - 1))
7360 /* A string from display property. */
7361 || it->from_disp_prop_p))
7363 ptrdiff_t ignore;
7364 int next_face_id;
7365 bool text_from_string = false;
7366 /* Normally, the next buffer location is stored in
7367 IT->current.pos... */
7368 struct text_pos pos = it->current.pos;
7370 /* ...but for a string from a display property, the
7371 next buffer position is stored in the 'position'
7372 member of the iteration stack slot below the
7373 current one, see handle_single_display_spec. By
7374 contrast, it->current.pos was not yet updated to
7375 point to that buffer position; that will happen
7376 in pop_it, after we finish displaying the current
7377 string. Note that we already checked above that
7378 it->sp is positive, so subtracting one from it is
7379 safe. */
7380 if (it->from_disp_prop_p)
7382 int stackp = it->sp - 1;
7384 /* Find the stack level with data from buffer. */
7385 while (stackp >= 0
7386 && STRINGP ((it->stack + stackp)->string))
7387 stackp--;
7388 if (stackp < 0)
7390 /* If no stack slot was found for iterating
7391 a buffer, we are displaying text from a
7392 string, most probably the mode line or
7393 the header line, and that string has a
7394 display string on some of its
7395 characters. */
7396 text_from_string = true;
7397 pos = it->stack[it->sp - 1].position;
7399 else
7400 pos = (it->stack + stackp)->position;
7402 else
7403 INC_TEXT_POS (pos, it->multibyte_p);
7405 if (text_from_string)
7407 Lisp_Object base_string = it->stack[it->sp - 1].string;
7409 if (CHARPOS (pos) >= SCHARS (base_string) - 1)
7410 it->end_of_box_run_p = true;
7411 else
7413 next_face_id
7414 = face_at_string_position (it->w, base_string,
7415 CHARPOS (pos), 0,
7416 &ignore, face_id, false);
7417 it->end_of_box_run_p
7418 = (FACE_FROM_ID (it->f, next_face_id)->box
7419 == FACE_NO_BOX);
7422 else if (CHARPOS (pos) >= ZV)
7423 it->end_of_box_run_p = true;
7424 else
7426 next_face_id =
7427 face_at_buffer_position (it->w, CHARPOS (pos), &ignore,
7428 CHARPOS (pos)
7429 + TEXT_PROP_DISTANCE_LIMIT,
7430 false, -1);
7431 it->end_of_box_run_p
7432 = (FACE_FROM_ID (it->f, next_face_id)->box
7433 == FACE_NO_BOX);
7438 /* next_element_from_display_vector sets this flag according to
7439 faces of the display vector glyphs, see there. */
7440 else if (it->method != GET_FROM_DISPLAY_VECTOR)
7442 int face_id = face_after_it_pos (it);
7443 it->end_of_box_run_p
7444 = (face_id != it->face_id
7445 && FACE_FROM_ID (it->f, face_id)->box == FACE_NO_BOX);
7448 /* If we reached the end of the object we've been iterating (e.g., a
7449 display string or an overlay string), and there's something on
7450 IT->stack, proceed with what's on the stack. It doesn't make
7451 sense to return false if there's unprocessed stuff on the stack,
7452 because otherwise that stuff will never be displayed. */
7453 if (!success_p && it->sp > 0)
7455 set_iterator_to_next (it, false);
7456 success_p = get_next_display_element (it);
7459 /* Value is false if end of buffer or string reached. */
7460 return success_p;
7464 /* Move IT to the next display element.
7466 RESEAT_P means if called on a newline in buffer text,
7467 skip to the next visible line start.
7469 Functions get_next_display_element and set_iterator_to_next are
7470 separate because I find this arrangement easier to handle than a
7471 get_next_display_element function that also increments IT's
7472 position. The way it is we can first look at an iterator's current
7473 display element, decide whether it fits on a line, and if it does,
7474 increment the iterator position. The other way around we probably
7475 would either need a flag indicating whether the iterator has to be
7476 incremented the next time, or we would have to implement a
7477 decrement position function which would not be easy to write. */
7479 void
7480 set_iterator_to_next (struct it *it, bool reseat_p)
7482 /* Reset flags indicating start and end of a sequence of characters
7483 with box. Reset them at the start of this function because
7484 moving the iterator to a new position might set them. */
7485 it->start_of_box_run_p = it->end_of_box_run_p = false;
7487 switch (it->method)
7489 case GET_FROM_BUFFER:
7490 /* The current display element of IT is a character from
7491 current_buffer. Advance in the buffer, and maybe skip over
7492 invisible lines that are so because of selective display. */
7493 if (ITERATOR_AT_END_OF_LINE_P (it) && reseat_p)
7494 reseat_at_next_visible_line_start (it, false);
7495 else if (it->cmp_it.id >= 0)
7497 /* We are currently getting glyphs from a composition. */
7498 if (! it->bidi_p)
7500 IT_CHARPOS (*it) += it->cmp_it.nchars;
7501 IT_BYTEPOS (*it) += it->cmp_it.nbytes;
7503 else
7505 int i;
7507 /* Update IT's char/byte positions to point to the first
7508 character of the next grapheme cluster, or to the
7509 character visually after the current composition. */
7510 for (i = 0; i < it->cmp_it.nchars; i++)
7511 bidi_move_to_visually_next (&it->bidi_it);
7512 IT_BYTEPOS (*it) = it->bidi_it.bytepos;
7513 IT_CHARPOS (*it) = it->bidi_it.charpos;
7516 if ((! it->bidi_p || ! it->cmp_it.reversed_p)
7517 && it->cmp_it.to < it->cmp_it.nglyphs)
7519 /* Composition created while scanning forward. Proceed
7520 to the next grapheme cluster. */
7521 it->cmp_it.from = it->cmp_it.to;
7523 else if ((it->bidi_p && it->cmp_it.reversed_p)
7524 && it->cmp_it.from > 0)
7526 /* Composition created while scanning backward. Proceed
7527 to the previous grapheme cluster. */
7528 it->cmp_it.to = it->cmp_it.from;
7530 else
7532 /* No more grapheme clusters in this composition.
7533 Find the next stop position. */
7534 ptrdiff_t stop = it->end_charpos;
7536 if (it->bidi_it.scan_dir < 0)
7537 /* Now we are scanning backward and don't know
7538 where to stop. */
7539 stop = -1;
7540 composition_compute_stop_pos (&it->cmp_it, IT_CHARPOS (*it),
7541 IT_BYTEPOS (*it), stop, Qnil);
7544 else
7546 eassert (it->len != 0);
7548 if (!it->bidi_p)
7550 IT_BYTEPOS (*it) += it->len;
7551 IT_CHARPOS (*it) += 1;
7553 else
7555 int prev_scan_dir = it->bidi_it.scan_dir;
7556 /* If this is a new paragraph, determine its base
7557 direction (a.k.a. its base embedding level). */
7558 if (it->bidi_it.new_paragraph)
7559 bidi_paragraph_init (it->paragraph_embedding, &it->bidi_it,
7560 false);
7561 bidi_move_to_visually_next (&it->bidi_it);
7562 IT_BYTEPOS (*it) = it->bidi_it.bytepos;
7563 IT_CHARPOS (*it) = it->bidi_it.charpos;
7564 if (prev_scan_dir != it->bidi_it.scan_dir)
7566 /* As the scan direction was changed, we must
7567 re-compute the stop position for composition. */
7568 ptrdiff_t stop = it->end_charpos;
7569 if (it->bidi_it.scan_dir < 0)
7570 stop = -1;
7571 composition_compute_stop_pos (&it->cmp_it, IT_CHARPOS (*it),
7572 IT_BYTEPOS (*it), stop, Qnil);
7575 eassert (IT_BYTEPOS (*it) == CHAR_TO_BYTE (IT_CHARPOS (*it)));
7577 break;
7579 case GET_FROM_C_STRING:
7580 /* Current display element of IT is from a C string. */
7581 if (!it->bidi_p
7582 /* If the string position is beyond string's end, it means
7583 next_element_from_c_string is padding the string with
7584 blanks, in which case we bypass the bidi iterator,
7585 because it cannot deal with such virtual characters. */
7586 || IT_CHARPOS (*it) >= it->bidi_it.string.schars)
7588 IT_BYTEPOS (*it) += it->len;
7589 IT_CHARPOS (*it) += 1;
7591 else
7593 bidi_move_to_visually_next (&it->bidi_it);
7594 IT_BYTEPOS (*it) = it->bidi_it.bytepos;
7595 IT_CHARPOS (*it) = it->bidi_it.charpos;
7597 break;
7599 case GET_FROM_DISPLAY_VECTOR:
7600 /* Current display element of IT is from a display table entry.
7601 Advance in the display table definition. Reset it to null if
7602 end reached, and continue with characters from buffers/
7603 strings. */
7604 ++it->current.dpvec_index;
7606 /* Restore face of the iterator to what they were before the
7607 display vector entry (these entries may contain faces). */
7608 it->face_id = it->saved_face_id;
7610 if (it->dpvec + it->current.dpvec_index >= it->dpend)
7612 bool recheck_faces = it->ellipsis_p;
7614 if (it->s)
7615 it->method = GET_FROM_C_STRING;
7616 else if (STRINGP (it->string))
7617 it->method = GET_FROM_STRING;
7618 else
7620 it->method = GET_FROM_BUFFER;
7621 it->object = it->w->contents;
7624 it->dpvec = NULL;
7625 it->current.dpvec_index = -1;
7627 /* Skip over characters which were displayed via IT->dpvec. */
7628 if (it->dpvec_char_len < 0)
7629 reseat_at_next_visible_line_start (it, true);
7630 else if (it->dpvec_char_len > 0)
7632 it->len = it->dpvec_char_len;
7633 set_iterator_to_next (it, reseat_p);
7636 /* Maybe recheck faces after display vector. */
7637 if (recheck_faces)
7639 if (it->method == GET_FROM_STRING)
7640 it->stop_charpos = IT_STRING_CHARPOS (*it);
7641 else
7642 it->stop_charpos = IT_CHARPOS (*it);
7645 break;
7647 case GET_FROM_STRING:
7648 /* Current display element is a character from a Lisp string. */
7649 eassert (it->s == NULL && STRINGP (it->string));
7650 /* Don't advance past string end. These conditions are true
7651 when set_iterator_to_next is called at the end of
7652 get_next_display_element, in which case the Lisp string is
7653 already exhausted, and all we want is pop the iterator
7654 stack. */
7655 if (it->current.overlay_string_index >= 0)
7657 /* This is an overlay string, so there's no padding with
7658 spaces, and the number of characters in the string is
7659 where the string ends. */
7660 if (IT_STRING_CHARPOS (*it) >= SCHARS (it->string))
7661 goto consider_string_end;
7663 else
7665 /* Not an overlay string. There could be padding, so test
7666 against it->end_charpos. */
7667 if (IT_STRING_CHARPOS (*it) >= it->end_charpos)
7668 goto consider_string_end;
7670 if (it->cmp_it.id >= 0)
7672 /* We are delivering display elements from a composition.
7673 Update the string position past the grapheme cluster
7674 we've just processed. */
7675 if (! it->bidi_p)
7677 IT_STRING_CHARPOS (*it) += it->cmp_it.nchars;
7678 IT_STRING_BYTEPOS (*it) += it->cmp_it.nbytes;
7680 else
7682 int i;
7684 for (i = 0; i < it->cmp_it.nchars; i++)
7685 bidi_move_to_visually_next (&it->bidi_it);
7686 IT_STRING_BYTEPOS (*it) = it->bidi_it.bytepos;
7687 IT_STRING_CHARPOS (*it) = it->bidi_it.charpos;
7690 /* Did we exhaust all the grapheme clusters of this
7691 composition? */
7692 if ((! it->bidi_p || ! it->cmp_it.reversed_p)
7693 && (it->cmp_it.to < it->cmp_it.nglyphs))
7695 /* Not all the grapheme clusters were processed yet;
7696 advance to the next cluster. */
7697 it->cmp_it.from = it->cmp_it.to;
7699 else if ((it->bidi_p && it->cmp_it.reversed_p)
7700 && it->cmp_it.from > 0)
7702 /* Likewise: advance to the next cluster, but going in
7703 the reverse direction. */
7704 it->cmp_it.to = it->cmp_it.from;
7706 else
7708 /* This composition was fully processed; find the next
7709 candidate place for checking for composed
7710 characters. */
7711 /* Always limit string searches to the string length;
7712 any padding spaces are not part of the string, and
7713 there cannot be any compositions in that padding. */
7714 ptrdiff_t stop = SCHARS (it->string);
7716 if (it->bidi_p && it->bidi_it.scan_dir < 0)
7717 stop = -1;
7718 else if (it->end_charpos < stop)
7720 /* Cf. PRECISION in reseat_to_string: we might be
7721 limited in how many of the string characters we
7722 need to deliver. */
7723 stop = it->end_charpos;
7725 composition_compute_stop_pos (&it->cmp_it,
7726 IT_STRING_CHARPOS (*it),
7727 IT_STRING_BYTEPOS (*it), stop,
7728 it->string);
7731 else
7733 if (!it->bidi_p
7734 /* If the string position is beyond string's end, it
7735 means next_element_from_string is padding the string
7736 with blanks, in which case we bypass the bidi
7737 iterator, because it cannot deal with such virtual
7738 characters. */
7739 || IT_STRING_CHARPOS (*it) >= it->bidi_it.string.schars)
7741 IT_STRING_BYTEPOS (*it) += it->len;
7742 IT_STRING_CHARPOS (*it) += 1;
7744 else
7746 int prev_scan_dir = it->bidi_it.scan_dir;
7748 bidi_move_to_visually_next (&it->bidi_it);
7749 IT_STRING_BYTEPOS (*it) = it->bidi_it.bytepos;
7750 IT_STRING_CHARPOS (*it) = it->bidi_it.charpos;
7751 /* If the scan direction changes, we may need to update
7752 the place where to check for composed characters. */
7753 if (prev_scan_dir != it->bidi_it.scan_dir)
7755 ptrdiff_t stop = SCHARS (it->string);
7757 if (it->bidi_it.scan_dir < 0)
7758 stop = -1;
7759 else if (it->end_charpos < stop)
7760 stop = it->end_charpos;
7762 composition_compute_stop_pos (&it->cmp_it,
7763 IT_STRING_CHARPOS (*it),
7764 IT_STRING_BYTEPOS (*it), stop,
7765 it->string);
7770 consider_string_end:
7772 if (it->current.overlay_string_index >= 0)
7774 /* IT->string is an overlay string. Advance to the
7775 next, if there is one. */
7776 if (IT_STRING_CHARPOS (*it) >= SCHARS (it->string))
7778 it->ellipsis_p = false;
7779 next_overlay_string (it);
7780 if (it->ellipsis_p)
7781 setup_for_ellipsis (it, 0);
7784 else
7786 /* IT->string is not an overlay string. If we reached
7787 its end, and there is something on IT->stack, proceed
7788 with what is on the stack. This can be either another
7789 string, this time an overlay string, or a buffer. */
7790 if (IT_STRING_CHARPOS (*it) == SCHARS (it->string)
7791 && it->sp > 0)
7793 pop_it (it);
7794 if (it->method == GET_FROM_STRING)
7795 goto consider_string_end;
7798 break;
7800 case GET_FROM_IMAGE:
7801 case GET_FROM_STRETCH:
7802 case GET_FROM_XWIDGET:
7804 /* The position etc with which we have to proceed are on
7805 the stack. The position may be at the end of a string,
7806 if the `display' property takes up the whole string. */
7807 eassert (it->sp > 0);
7808 pop_it (it);
7809 if (it->method == GET_FROM_STRING)
7810 goto consider_string_end;
7811 break;
7813 default:
7814 /* There are no other methods defined, so this should be a bug. */
7815 emacs_abort ();
7818 eassert (it->method != GET_FROM_STRING
7819 || (STRINGP (it->string)
7820 && IT_STRING_CHARPOS (*it) >= 0));
7823 /* Load IT's display element fields with information about the next
7824 display element which comes from a display table entry or from the
7825 result of translating a control character to one of the forms `^C'
7826 or `\003'.
7828 IT->dpvec holds the glyphs to return as characters.
7829 IT->saved_face_id holds the face id before the display vector--it
7830 is restored into IT->face_id in set_iterator_to_next. */
7832 static bool
7833 next_element_from_display_vector (struct it *it)
7835 Lisp_Object gc;
7836 int prev_face_id = it->face_id;
7837 int next_face_id;
7839 /* Precondition. */
7840 eassert (it->dpvec && it->current.dpvec_index >= 0);
7842 it->face_id = it->saved_face_id;
7844 /* KFS: This code used to check ip->dpvec[0] instead of the current element.
7845 That seemed totally bogus - so I changed it... */
7846 if (it->dpend - it->dpvec > 0 /* empty dpvec[] is invalid */
7847 && (gc = it->dpvec[it->current.dpvec_index], GLYPH_CODE_P (gc)))
7849 struct face *this_face, *prev_face, *next_face;
7851 it->c = GLYPH_CODE_CHAR (gc);
7852 it->len = CHAR_BYTES (it->c);
7854 /* The entry may contain a face id to use. Such a face id is
7855 the id of a Lisp face, not a realized face. A face id of
7856 zero means no face is specified. */
7857 if (it->dpvec_face_id >= 0)
7858 it->face_id = it->dpvec_face_id;
7859 else
7861 int lface_id = GLYPH_CODE_FACE (gc);
7862 if (lface_id > 0)
7863 it->face_id = merge_faces (it->f, Qt, lface_id,
7864 it->saved_face_id);
7867 /* Glyphs in the display vector could have the box face, so we
7868 need to set the related flags in the iterator, as
7869 appropriate. */
7870 this_face = FACE_FROM_ID_OR_NULL (it->f, it->face_id);
7871 prev_face = FACE_FROM_ID_OR_NULL (it->f, prev_face_id);
7873 /* Is this character the first character of a box-face run? */
7874 it->start_of_box_run_p = (this_face && this_face->box != FACE_NO_BOX
7875 && (!prev_face
7876 || prev_face->box == FACE_NO_BOX));
7878 /* For the last character of the box-face run, we need to look
7879 either at the next glyph from the display vector, or at the
7880 face we saw before the display vector. */
7881 next_face_id = it->saved_face_id;
7882 if (it->current.dpvec_index < it->dpend - it->dpvec - 1)
7884 if (it->dpvec_face_id >= 0)
7885 next_face_id = it->dpvec_face_id;
7886 else
7888 int lface_id =
7889 GLYPH_CODE_FACE (it->dpvec[it->current.dpvec_index + 1]);
7891 if (lface_id > 0)
7892 next_face_id = merge_faces (it->f, Qt, lface_id,
7893 it->saved_face_id);
7896 next_face = FACE_FROM_ID_OR_NULL (it->f, next_face_id);
7897 it->end_of_box_run_p = (this_face && this_face->box != FACE_NO_BOX
7898 && (!next_face
7899 || next_face->box == FACE_NO_BOX));
7900 it->face_box_p = this_face && this_face->box != FACE_NO_BOX;
7902 else
7903 /* Display table entry is invalid. Return a space. */
7904 it->c = ' ', it->len = 1;
7906 /* Don't change position and object of the iterator here. They are
7907 still the values of the character that had this display table
7908 entry or was translated, and that's what we want. */
7909 it->what = IT_CHARACTER;
7910 return true;
7913 /* Get the first element of string/buffer in the visual order, after
7914 being reseated to a new position in a string or a buffer. */
7915 static void
7916 get_visually_first_element (struct it *it)
7918 bool string_p = STRINGP (it->string) || it->s;
7919 ptrdiff_t eob = (string_p ? it->bidi_it.string.schars : ZV);
7920 ptrdiff_t bob = (string_p ? 0 : BEGV);
7922 if (STRINGP (it->string))
7924 it->bidi_it.charpos = IT_STRING_CHARPOS (*it);
7925 it->bidi_it.bytepos = IT_STRING_BYTEPOS (*it);
7927 else
7929 it->bidi_it.charpos = IT_CHARPOS (*it);
7930 it->bidi_it.bytepos = IT_BYTEPOS (*it);
7933 if (it->bidi_it.charpos == eob)
7935 /* Nothing to do, but reset the FIRST_ELT flag, like
7936 bidi_paragraph_init does, because we are not going to
7937 call it. */
7938 it->bidi_it.first_elt = false;
7940 else if (it->bidi_it.charpos == bob
7941 || (!string_p
7942 && (FETCH_CHAR (it->bidi_it.bytepos - 1) == '\n'
7943 || FETCH_CHAR (it->bidi_it.bytepos) == '\n')))
7945 /* If we are at the beginning of a line/string, we can produce
7946 the next element right away. */
7947 bidi_paragraph_init (it->paragraph_embedding, &it->bidi_it, true);
7948 bidi_move_to_visually_next (&it->bidi_it);
7950 else
7952 ptrdiff_t orig_bytepos = it->bidi_it.bytepos;
7954 /* We need to prime the bidi iterator starting at the line's or
7955 string's beginning, before we will be able to produce the
7956 next element. */
7957 if (string_p)
7958 it->bidi_it.charpos = it->bidi_it.bytepos = 0;
7959 else
7960 it->bidi_it.charpos = find_newline_no_quit (IT_CHARPOS (*it),
7961 IT_BYTEPOS (*it), -1,
7962 &it->bidi_it.bytepos);
7963 bidi_paragraph_init (it->paragraph_embedding, &it->bidi_it, true);
7966 /* Now return to buffer/string position where we were asked
7967 to get the next display element, and produce that. */
7968 bidi_move_to_visually_next (&it->bidi_it);
7970 while (it->bidi_it.bytepos != orig_bytepos
7971 && it->bidi_it.charpos < eob);
7974 /* Adjust IT's position information to where we ended up. */
7975 if (STRINGP (it->string))
7977 IT_STRING_CHARPOS (*it) = it->bidi_it.charpos;
7978 IT_STRING_BYTEPOS (*it) = it->bidi_it.bytepos;
7980 else
7982 IT_CHARPOS (*it) = it->bidi_it.charpos;
7983 IT_BYTEPOS (*it) = it->bidi_it.bytepos;
7986 if (STRINGP (it->string) || !it->s)
7988 ptrdiff_t stop, charpos, bytepos;
7990 if (STRINGP (it->string))
7992 eassert (!it->s);
7993 stop = SCHARS (it->string);
7994 if (stop > it->end_charpos)
7995 stop = it->end_charpos;
7996 charpos = IT_STRING_CHARPOS (*it);
7997 bytepos = IT_STRING_BYTEPOS (*it);
7999 else
8001 stop = it->end_charpos;
8002 charpos = IT_CHARPOS (*it);
8003 bytepos = IT_BYTEPOS (*it);
8005 if (it->bidi_it.scan_dir < 0)
8006 stop = -1;
8007 composition_compute_stop_pos (&it->cmp_it, charpos, bytepos, stop,
8008 it->string);
8012 /* Load IT with the next display element from Lisp string IT->string.
8013 IT->current.string_pos is the current position within the string.
8014 If IT->current.overlay_string_index >= 0, the Lisp string is an
8015 overlay string. */
8017 static bool
8018 next_element_from_string (struct it *it)
8020 struct text_pos position;
8022 eassert (STRINGP (it->string));
8023 eassert (!it->bidi_p || EQ (it->string, it->bidi_it.string.lstring));
8024 eassert (IT_STRING_CHARPOS (*it) >= 0);
8025 position = it->current.string_pos;
8027 /* With bidi reordering, the character to display might not be the
8028 character at IT_STRING_CHARPOS. BIDI_IT.FIRST_ELT means
8029 that we were reseat()ed to a new string, whose paragraph
8030 direction is not known. */
8031 if (it->bidi_p && it->bidi_it.first_elt)
8033 get_visually_first_element (it);
8034 SET_TEXT_POS (position, IT_STRING_CHARPOS (*it), IT_STRING_BYTEPOS (*it));
8037 /* Time to check for invisible text? */
8038 if (IT_STRING_CHARPOS (*it) < it->end_charpos)
8040 if (IT_STRING_CHARPOS (*it) >= it->stop_charpos)
8042 if (!(!it->bidi_p
8043 || BIDI_AT_BASE_LEVEL (it->bidi_it)
8044 || IT_STRING_CHARPOS (*it) == it->stop_charpos))
8046 /* With bidi non-linear iteration, we could find
8047 ourselves far beyond the last computed stop_charpos,
8048 with several other stop positions in between that we
8049 missed. Scan them all now, in buffer's logical
8050 order, until we find and handle the last stop_charpos
8051 that precedes our current position. */
8052 handle_stop_backwards (it, it->stop_charpos);
8053 return GET_NEXT_DISPLAY_ELEMENT (it);
8055 else
8057 if (it->bidi_p)
8059 /* Take note of the stop position we just moved
8060 across, for when we will move back across it. */
8061 it->prev_stop = it->stop_charpos;
8062 /* If we are at base paragraph embedding level, take
8063 note of the last stop position seen at this
8064 level. */
8065 if (BIDI_AT_BASE_LEVEL (it->bidi_it))
8066 it->base_level_stop = it->stop_charpos;
8068 handle_stop (it);
8070 /* Since a handler may have changed IT->method, we must
8071 recurse here. */
8072 return GET_NEXT_DISPLAY_ELEMENT (it);
8075 else if (it->bidi_p
8076 /* If we are before prev_stop, we may have overstepped
8077 on our way backwards a stop_pos, and if so, we need
8078 to handle that stop_pos. */
8079 && IT_STRING_CHARPOS (*it) < it->prev_stop
8080 /* We can sometimes back up for reasons that have nothing
8081 to do with bidi reordering. E.g., compositions. The
8082 code below is only needed when we are above the base
8083 embedding level, so test for that explicitly. */
8084 && !BIDI_AT_BASE_LEVEL (it->bidi_it))
8086 /* If we lost track of base_level_stop, we have no better
8087 place for handle_stop_backwards to start from than string
8088 beginning. This happens, e.g., when we were reseated to
8089 the previous screenful of text by vertical-motion. */
8090 if (it->base_level_stop <= 0
8091 || IT_STRING_CHARPOS (*it) < it->base_level_stop)
8092 it->base_level_stop = 0;
8093 handle_stop_backwards (it, it->base_level_stop);
8094 return GET_NEXT_DISPLAY_ELEMENT (it);
8098 if (it->current.overlay_string_index >= 0)
8100 /* Get the next character from an overlay string. In overlay
8101 strings, there is no field width or padding with spaces to
8102 do. */
8103 if (IT_STRING_CHARPOS (*it) >= SCHARS (it->string))
8105 it->what = IT_EOB;
8106 return false;
8108 else if (CHAR_COMPOSED_P (it, IT_STRING_CHARPOS (*it),
8109 IT_STRING_BYTEPOS (*it),
8110 it->bidi_it.scan_dir < 0
8111 ? -1
8112 : SCHARS (it->string))
8113 && next_element_from_composition (it))
8115 return true;
8117 else if (STRING_MULTIBYTE (it->string))
8119 const unsigned char *s = (SDATA (it->string)
8120 + IT_STRING_BYTEPOS (*it));
8121 it->c = string_char_and_length (s, &it->len);
8123 else
8125 it->c = SREF (it->string, IT_STRING_BYTEPOS (*it));
8126 it->len = 1;
8129 else
8131 /* Get the next character from a Lisp string that is not an
8132 overlay string. Such strings come from the mode line, for
8133 example. We may have to pad with spaces, or truncate the
8134 string. See also next_element_from_c_string. */
8135 if (IT_STRING_CHARPOS (*it) >= it->end_charpos)
8137 it->what = IT_EOB;
8138 return false;
8140 else if (IT_STRING_CHARPOS (*it) >= it->string_nchars)
8142 /* Pad with spaces. */
8143 it->c = ' ', it->len = 1;
8144 CHARPOS (position) = BYTEPOS (position) = -1;
8146 else if (CHAR_COMPOSED_P (it, IT_STRING_CHARPOS (*it),
8147 IT_STRING_BYTEPOS (*it),
8148 it->bidi_it.scan_dir < 0
8149 ? -1
8150 : it->string_nchars)
8151 && next_element_from_composition (it))
8153 return true;
8155 else if (STRING_MULTIBYTE (it->string))
8157 const unsigned char *s = (SDATA (it->string)
8158 + IT_STRING_BYTEPOS (*it));
8159 it->c = string_char_and_length (s, &it->len);
8161 else
8163 it->c = SREF (it->string, IT_STRING_BYTEPOS (*it));
8164 it->len = 1;
8168 /* Record what we have and where it came from. */
8169 it->what = IT_CHARACTER;
8170 it->object = it->string;
8171 it->position = position;
8172 return true;
8176 /* Load IT with next display element from C string IT->s.
8177 IT->string_nchars is the maximum number of characters to return
8178 from the string. IT->end_charpos may be greater than
8179 IT->string_nchars when this function is called, in which case we
8180 may have to return padding spaces. Value is false if end of string
8181 reached, including padding spaces. */
8183 static bool
8184 next_element_from_c_string (struct it *it)
8186 bool success_p = true;
8188 eassert (it->s);
8189 eassert (!it->bidi_p || it->s == it->bidi_it.string.s);
8190 it->what = IT_CHARACTER;
8191 BYTEPOS (it->position) = CHARPOS (it->position) = 0;
8192 it->object = make_number (0);
8194 /* With bidi reordering, the character to display might not be the
8195 character at IT_CHARPOS. BIDI_IT.FIRST_ELT means that
8196 we were reseated to a new string, whose paragraph direction is
8197 not known. */
8198 if (it->bidi_p && it->bidi_it.first_elt)
8199 get_visually_first_element (it);
8201 /* IT's position can be greater than IT->string_nchars in case a
8202 field width or precision has been specified when the iterator was
8203 initialized. */
8204 if (IT_CHARPOS (*it) >= it->end_charpos)
8206 /* End of the game. */
8207 it->what = IT_EOB;
8208 success_p = false;
8210 else if (IT_CHARPOS (*it) >= it->string_nchars)
8212 /* Pad with spaces. */
8213 it->c = ' ', it->len = 1;
8214 BYTEPOS (it->position) = CHARPOS (it->position) = -1;
8216 else if (it->multibyte_p)
8217 it->c = string_char_and_length (it->s + IT_BYTEPOS (*it), &it->len);
8218 else
8219 it->c = it->s[IT_BYTEPOS (*it)], it->len = 1;
8221 return success_p;
8225 /* Set up IT to return characters from an ellipsis, if appropriate.
8226 The definition of the ellipsis glyphs may come from a display table
8227 entry. This function fills IT with the first glyph from the
8228 ellipsis if an ellipsis is to be displayed. */
8230 static bool
8231 next_element_from_ellipsis (struct it *it)
8233 if (it->selective_display_ellipsis_p)
8234 setup_for_ellipsis (it, it->len);
8235 else
8237 /* The face at the current position may be different from the
8238 face we find after the invisible text. Remember what it
8239 was in IT->saved_face_id, and signal that it's there by
8240 setting face_before_selective_p. */
8241 it->saved_face_id = it->face_id;
8242 it->method = GET_FROM_BUFFER;
8243 it->object = it->w->contents;
8244 reseat_at_next_visible_line_start (it, true);
8245 it->face_before_selective_p = true;
8248 return GET_NEXT_DISPLAY_ELEMENT (it);
8252 /* Deliver an image display element. The iterator IT is already
8253 filled with image information (done in handle_display_prop). Value
8254 is always true. */
8257 static bool
8258 next_element_from_image (struct it *it)
8260 it->what = IT_IMAGE;
8261 return true;
8264 static bool
8265 next_element_from_xwidget (struct it *it)
8267 it->what = IT_XWIDGET;
8268 return true;
8272 /* Fill iterator IT with next display element from a stretch glyph
8273 property. IT->object is the value of the text property. Value is
8274 always true. */
8276 static bool
8277 next_element_from_stretch (struct it *it)
8279 it->what = IT_STRETCH;
8280 return true;
8283 /* Scan backwards from IT's current position until we find a stop
8284 position, or until BEGV. This is called when we find ourself
8285 before both the last known prev_stop and base_level_stop while
8286 reordering bidirectional text. */
8288 static void
8289 compute_stop_pos_backwards (struct it *it)
8291 const int SCAN_BACK_LIMIT = 1000;
8292 struct text_pos pos;
8293 struct display_pos save_current = it->current;
8294 struct text_pos save_position = it->position;
8295 ptrdiff_t charpos = IT_CHARPOS (*it);
8296 ptrdiff_t where_we_are = charpos;
8297 ptrdiff_t save_stop_pos = it->stop_charpos;
8298 ptrdiff_t save_end_pos = it->end_charpos;
8300 eassert (NILP (it->string) && !it->s);
8301 eassert (it->bidi_p);
8302 it->bidi_p = false;
8305 it->end_charpos = min (charpos + 1, ZV);
8306 charpos = max (charpos - SCAN_BACK_LIMIT, BEGV);
8307 SET_TEXT_POS (pos, charpos, CHAR_TO_BYTE (charpos));
8308 reseat_1 (it, pos, false);
8309 compute_stop_pos (it);
8310 /* We must advance forward, right? */
8311 if (it->stop_charpos <= charpos)
8312 emacs_abort ();
8314 while (charpos > BEGV && it->stop_charpos >= it->end_charpos);
8316 if (it->stop_charpos <= where_we_are)
8317 it->prev_stop = it->stop_charpos;
8318 else
8319 it->prev_stop = BEGV;
8320 it->bidi_p = true;
8321 it->current = save_current;
8322 it->position = save_position;
8323 it->stop_charpos = save_stop_pos;
8324 it->end_charpos = save_end_pos;
8327 /* Scan forward from CHARPOS in the current buffer/string, until we
8328 find a stop position > current IT's position. Then handle the stop
8329 position before that. This is called when we bump into a stop
8330 position while reordering bidirectional text. CHARPOS should be
8331 the last previously processed stop_pos (or BEGV/0, if none were
8332 processed yet) whose position is less that IT's current
8333 position. */
8335 static void
8336 handle_stop_backwards (struct it *it, ptrdiff_t charpos)
8338 bool bufp = !STRINGP (it->string);
8339 ptrdiff_t where_we_are = (bufp ? IT_CHARPOS (*it) : IT_STRING_CHARPOS (*it));
8340 struct display_pos save_current = it->current;
8341 struct text_pos save_position = it->position;
8342 struct text_pos pos1;
8343 ptrdiff_t next_stop;
8345 /* Scan in strict logical order. */
8346 eassert (it->bidi_p);
8347 it->bidi_p = false;
8350 it->prev_stop = charpos;
8351 if (bufp)
8353 SET_TEXT_POS (pos1, charpos, CHAR_TO_BYTE (charpos));
8354 reseat_1 (it, pos1, false);
8356 else
8357 it->current.string_pos = string_pos (charpos, it->string);
8358 compute_stop_pos (it);
8359 /* We must advance forward, right? */
8360 if (it->stop_charpos <= it->prev_stop)
8361 emacs_abort ();
8362 charpos = it->stop_charpos;
8364 while (charpos <= where_we_are);
8366 it->bidi_p = true;
8367 it->current = save_current;
8368 it->position = save_position;
8369 next_stop = it->stop_charpos;
8370 it->stop_charpos = it->prev_stop;
8371 handle_stop (it);
8372 it->stop_charpos = next_stop;
8375 /* Load IT with the next display element from current_buffer. Value
8376 is false if end of buffer reached. IT->stop_charpos is the next
8377 position at which to stop and check for text properties or buffer
8378 end. */
8380 static bool
8381 next_element_from_buffer (struct it *it)
8383 bool success_p = true;
8385 eassert (IT_CHARPOS (*it) >= BEGV);
8386 eassert (NILP (it->string) && !it->s);
8387 eassert (!it->bidi_p
8388 || (EQ (it->bidi_it.string.lstring, Qnil)
8389 && it->bidi_it.string.s == NULL));
8391 /* With bidi reordering, the character to display might not be the
8392 character at IT_CHARPOS. BIDI_IT.FIRST_ELT means that
8393 we were reseat()ed to a new buffer position, which is potentially
8394 a different paragraph. */
8395 if (it->bidi_p && it->bidi_it.first_elt)
8397 get_visually_first_element (it);
8398 SET_TEXT_POS (it->position, IT_CHARPOS (*it), IT_BYTEPOS (*it));
8401 if (IT_CHARPOS (*it) >= it->stop_charpos)
8403 if (IT_CHARPOS (*it) >= it->end_charpos)
8405 bool overlay_strings_follow_p;
8407 /* End of the game, except when overlay strings follow that
8408 haven't been returned yet. */
8409 if (it->overlay_strings_at_end_processed_p)
8410 overlay_strings_follow_p = false;
8411 else
8413 it->overlay_strings_at_end_processed_p = true;
8414 overlay_strings_follow_p = get_overlay_strings (it, 0);
8417 if (overlay_strings_follow_p)
8418 success_p = GET_NEXT_DISPLAY_ELEMENT (it);
8419 else
8421 it->what = IT_EOB;
8422 it->position = it->current.pos;
8423 success_p = false;
8426 else if (!(!it->bidi_p
8427 || BIDI_AT_BASE_LEVEL (it->bidi_it)
8428 || IT_CHARPOS (*it) == it->stop_charpos))
8430 /* With bidi non-linear iteration, we could find ourselves
8431 far beyond the last computed stop_charpos, with several
8432 other stop positions in between that we missed. Scan
8433 them all now, in buffer's logical order, until we find
8434 and handle the last stop_charpos that precedes our
8435 current position. */
8436 handle_stop_backwards (it, it->stop_charpos);
8437 it->ignore_overlay_strings_at_pos_p = false;
8438 return GET_NEXT_DISPLAY_ELEMENT (it);
8440 else
8442 if (it->bidi_p)
8444 /* Take note of the stop position we just moved across,
8445 for when we will move back across it. */
8446 it->prev_stop = it->stop_charpos;
8447 /* If we are at base paragraph embedding level, take
8448 note of the last stop position seen at this
8449 level. */
8450 if (BIDI_AT_BASE_LEVEL (it->bidi_it))
8451 it->base_level_stop = it->stop_charpos;
8453 handle_stop (it);
8454 it->ignore_overlay_strings_at_pos_p = false;
8455 return GET_NEXT_DISPLAY_ELEMENT (it);
8458 else if (it->bidi_p
8459 /* If we are before prev_stop, we may have overstepped on
8460 our way backwards a stop_pos, and if so, we need to
8461 handle that stop_pos. */
8462 && IT_CHARPOS (*it) < it->prev_stop
8463 /* We can sometimes back up for reasons that have nothing
8464 to do with bidi reordering. E.g., compositions. The
8465 code below is only needed when we are above the base
8466 embedding level, so test for that explicitly. */
8467 && !BIDI_AT_BASE_LEVEL (it->bidi_it))
8469 if (it->base_level_stop <= 0
8470 || IT_CHARPOS (*it) < it->base_level_stop)
8472 /* If we lost track of base_level_stop, we need to find
8473 prev_stop by looking backwards. This happens, e.g., when
8474 we were reseated to the previous screenful of text by
8475 vertical-motion. */
8476 it->base_level_stop = BEGV;
8477 compute_stop_pos_backwards (it);
8478 handle_stop_backwards (it, it->prev_stop);
8480 else
8481 handle_stop_backwards (it, it->base_level_stop);
8482 it->ignore_overlay_strings_at_pos_p = false;
8483 return GET_NEXT_DISPLAY_ELEMENT (it);
8485 else
8487 /* No face changes, overlays etc. in sight, so just return a
8488 character from current_buffer. */
8489 unsigned char *p;
8490 ptrdiff_t stop;
8492 /* We moved to the next buffer position, so any info about
8493 previously seen overlays is no longer valid. */
8494 it->ignore_overlay_strings_at_pos_p = false;
8496 /* Maybe run the redisplay end trigger hook. Performance note:
8497 This doesn't seem to cost measurable time. */
8498 if (it->redisplay_end_trigger_charpos
8499 && it->glyph_row
8500 && IT_CHARPOS (*it) >= it->redisplay_end_trigger_charpos)
8501 run_redisplay_end_trigger_hook (it);
8503 stop = it->bidi_it.scan_dir < 0 ? -1 : it->end_charpos;
8504 if (CHAR_COMPOSED_P (it, IT_CHARPOS (*it), IT_BYTEPOS (*it),
8505 stop)
8506 && next_element_from_composition (it))
8508 return true;
8511 /* Get the next character, maybe multibyte. */
8512 p = BYTE_POS_ADDR (IT_BYTEPOS (*it));
8513 if (it->multibyte_p && !ASCII_CHAR_P (*p))
8514 it->c = STRING_CHAR_AND_LENGTH (p, it->len);
8515 else
8516 it->c = *p, it->len = 1;
8518 /* Record what we have and where it came from. */
8519 it->what = IT_CHARACTER;
8520 it->object = it->w->contents;
8521 it->position = it->current.pos;
8523 /* Normally we return the character found above, except when we
8524 really want to return an ellipsis for selective display. */
8525 if (it->selective)
8527 if (it->c == '\n')
8529 /* A value of selective > 0 means hide lines indented more
8530 than that number of columns. */
8531 if (it->selective > 0
8532 && IT_CHARPOS (*it) + 1 < ZV
8533 && indented_beyond_p (IT_CHARPOS (*it) + 1,
8534 IT_BYTEPOS (*it) + 1,
8535 it->selective))
8537 success_p = next_element_from_ellipsis (it);
8538 it->dpvec_char_len = -1;
8541 else if (it->c == '\r' && it->selective == -1)
8543 /* A value of selective == -1 means that everything from the
8544 CR to the end of the line is invisible, with maybe an
8545 ellipsis displayed for it. */
8546 success_p = next_element_from_ellipsis (it);
8547 it->dpvec_char_len = -1;
8552 /* Value is false if end of buffer reached. */
8553 eassert (!success_p || it->what != IT_CHARACTER || it->len > 0);
8554 return success_p;
8558 /* Run the redisplay end trigger hook for IT. */
8560 static void
8561 run_redisplay_end_trigger_hook (struct it *it)
8563 /* IT->glyph_row should be non-null, i.e. we should be actually
8564 displaying something, or otherwise we should not run the hook. */
8565 eassert (it->glyph_row);
8567 ptrdiff_t charpos = it->redisplay_end_trigger_charpos;
8568 it->redisplay_end_trigger_charpos = 0;
8570 /* Since we are *trying* to run these functions, don't try to run
8571 them again, even if they get an error. */
8572 wset_redisplay_end_trigger (it->w, Qnil);
8573 CALLN (Frun_hook_with_args, Qredisplay_end_trigger_functions, it->window,
8574 make_number (charpos));
8576 /* Notice if it changed the face of the character we are on. */
8577 handle_face_prop (it);
8581 /* Deliver a composition display element. Unlike the other
8582 next_element_from_XXX, this function is not registered in the array
8583 get_next_element[]. It is called from next_element_from_buffer and
8584 next_element_from_string when necessary. */
8586 static bool
8587 next_element_from_composition (struct it *it)
8589 it->what = IT_COMPOSITION;
8590 it->len = it->cmp_it.nbytes;
8591 if (STRINGP (it->string))
8593 if (it->c < 0)
8595 IT_STRING_CHARPOS (*it) += it->cmp_it.nchars;
8596 IT_STRING_BYTEPOS (*it) += it->cmp_it.nbytes;
8597 return false;
8599 it->position = it->current.string_pos;
8600 it->object = it->string;
8601 it->c = composition_update_it (&it->cmp_it, IT_STRING_CHARPOS (*it),
8602 IT_STRING_BYTEPOS (*it), it->string);
8604 else
8606 if (it->c < 0)
8608 IT_CHARPOS (*it) += it->cmp_it.nchars;
8609 IT_BYTEPOS (*it) += it->cmp_it.nbytes;
8610 if (it->bidi_p)
8612 if (it->bidi_it.new_paragraph)
8613 bidi_paragraph_init (it->paragraph_embedding, &it->bidi_it,
8614 false);
8615 /* Resync the bidi iterator with IT's new position.
8616 FIXME: this doesn't support bidirectional text. */
8617 while (it->bidi_it.charpos < IT_CHARPOS (*it))
8618 bidi_move_to_visually_next (&it->bidi_it);
8620 return false;
8622 it->position = it->current.pos;
8623 it->object = it->w->contents;
8624 it->c = composition_update_it (&it->cmp_it, IT_CHARPOS (*it),
8625 IT_BYTEPOS (*it), Qnil);
8627 return true;
8632 /***********************************************************************
8633 Moving an iterator without producing glyphs
8634 ***********************************************************************/
8636 /* Check if iterator is at a position corresponding to a valid buffer
8637 position after some move_it_ call. */
8639 #define IT_POS_VALID_AFTER_MOVE_P(it) \
8640 ((it)->method != GET_FROM_STRING || IT_STRING_CHARPOS (*it) == 0)
8643 /* Move iterator IT to a specified buffer or X position within one
8644 line on the display without producing glyphs.
8646 OP should be a bit mask including some or all of these bits:
8647 MOVE_TO_X: Stop upon reaching x-position TO_X.
8648 MOVE_TO_POS: Stop upon reaching buffer or string position TO_CHARPOS.
8649 Regardless of OP's value, stop upon reaching the end of the display line.
8651 TO_X is normally a value 0 <= TO_X <= IT->last_visible_x.
8652 This means, in particular, that TO_X includes window's horizontal
8653 scroll amount.
8655 The return value has several possible values that
8656 say what condition caused the scan to stop:
8658 MOVE_POS_MATCH_OR_ZV
8659 - when TO_POS or ZV was reached.
8661 MOVE_X_REACHED
8662 -when TO_X was reached before TO_POS or ZV were reached.
8664 MOVE_LINE_CONTINUED
8665 - when we reached the end of the display area and the line must
8666 be continued.
8668 MOVE_LINE_TRUNCATED
8669 - when we reached the end of the display area and the line is
8670 truncated.
8672 MOVE_NEWLINE_OR_CR
8673 - when we stopped at a line end, i.e. a newline or a CR and selective
8674 display is on. */
8676 static enum move_it_result
8677 move_it_in_display_line_to (struct it *it,
8678 ptrdiff_t to_charpos, int to_x,
8679 enum move_operation_enum op)
8681 enum move_it_result result = MOVE_UNDEFINED;
8682 struct glyph_row *saved_glyph_row;
8683 struct it wrap_it, atpos_it, atx_it, ppos_it;
8684 void *wrap_data = NULL, *atpos_data = NULL, *atx_data = NULL;
8685 void *ppos_data = NULL;
8686 bool may_wrap = false;
8687 enum it_method prev_method = it->method;
8688 ptrdiff_t closest_pos UNINIT;
8689 ptrdiff_t prev_pos = IT_CHARPOS (*it);
8690 bool saw_smaller_pos = prev_pos < to_charpos;
8691 bool line_number_pending = false;
8693 /* Don't produce glyphs in produce_glyphs. */
8694 saved_glyph_row = it->glyph_row;
8695 it->glyph_row = NULL;
8697 /* Use wrap_it to save a copy of IT wherever a word wrap could
8698 occur. Use atpos_it to save a copy of IT at the desired buffer
8699 position, if found, so that we can scan ahead and check if the
8700 word later overshoots the window edge. Use atx_it similarly, for
8701 pixel positions. */
8702 wrap_it.sp = -1;
8703 atpos_it.sp = -1;
8704 atx_it.sp = -1;
8706 /* Use ppos_it under bidi reordering to save a copy of IT for the
8707 initial position. We restore that position in IT when we have
8708 scanned the entire display line without finding a match for
8709 TO_CHARPOS and all the character positions are greater than
8710 TO_CHARPOS. We then restart the scan from the initial position,
8711 and stop at CLOSEST_POS, which is a position > TO_CHARPOS that is
8712 the closest to TO_CHARPOS. */
8713 if (it->bidi_p)
8715 if ((op & MOVE_TO_POS) && IT_CHARPOS (*it) >= to_charpos)
8717 SAVE_IT (ppos_it, *it, ppos_data);
8718 closest_pos = IT_CHARPOS (*it);
8720 else
8721 closest_pos = ZV;
8724 #define BUFFER_POS_REACHED_P() \
8725 ((op & MOVE_TO_POS) != 0 \
8726 && BUFFERP (it->object) \
8727 && (IT_CHARPOS (*it) == to_charpos \
8728 || ((!it->bidi_p \
8729 || BIDI_AT_BASE_LEVEL (it->bidi_it)) \
8730 && IT_CHARPOS (*it) > to_charpos) \
8731 || (it->what == IT_COMPOSITION \
8732 && ((IT_CHARPOS (*it) > to_charpos \
8733 && to_charpos >= it->cmp_it.charpos) \
8734 || (IT_CHARPOS (*it) < to_charpos \
8735 && to_charpos <= it->cmp_it.charpos)))) \
8736 && (it->method == GET_FROM_BUFFER \
8737 || (it->method == GET_FROM_DISPLAY_VECTOR \
8738 && it->dpvec + it->current.dpvec_index + 1 >= it->dpend)))
8740 if (it->hpos == 0)
8742 /* If line numbers are being displayed, produce a line number.
8743 But don't do that if we are to reach first_visible_x, because
8744 line numbers are not relevant to stuff that is not visible on
8745 display. */
8746 if (!((op && MOVE_TO_X) && to_x == it->first_visible_x)
8747 && should_produce_line_number (it))
8749 if (it->current_x == it->first_visible_x)
8750 maybe_produce_line_number (it);
8751 else
8752 line_number_pending = true;
8754 /* If there's a line-/wrap-prefix, handle it. */
8755 if (it->method == GET_FROM_BUFFER)
8756 handle_line_prefix (it);
8759 if (IT_CHARPOS (*it) < CHARPOS (this_line_min_pos))
8760 SET_TEXT_POS (this_line_min_pos, IT_CHARPOS (*it), IT_BYTEPOS (*it));
8762 while (true)
8764 int x, i, ascent = 0, descent = 0;
8766 /* Utility macro to reset an iterator with x, ascent, and descent. */
8767 #define IT_RESET_X_ASCENT_DESCENT(IT) \
8768 ((IT)->current_x = x, (IT)->max_ascent = ascent, \
8769 (IT)->max_descent = descent)
8771 /* Stop if we move beyond TO_CHARPOS (after an image or a
8772 display string or stretch glyph). */
8773 if ((op & MOVE_TO_POS) != 0
8774 && BUFFERP (it->object)
8775 && it->method == GET_FROM_BUFFER
8776 && (((!it->bidi_p
8777 /* When the iterator is at base embedding level, we
8778 are guaranteed that characters are delivered for
8779 display in strictly increasing order of their
8780 buffer positions. */
8781 || BIDI_AT_BASE_LEVEL (it->bidi_it))
8782 && IT_CHARPOS (*it) > to_charpos)
8783 || (it->bidi_p
8784 && (prev_method == GET_FROM_IMAGE
8785 || prev_method == GET_FROM_STRETCH
8786 || prev_method == GET_FROM_STRING)
8787 /* Passed TO_CHARPOS from left to right. */
8788 && ((prev_pos < to_charpos
8789 && IT_CHARPOS (*it) > to_charpos)
8790 /* Passed TO_CHARPOS from right to left. */
8791 || (prev_pos > to_charpos
8792 && IT_CHARPOS (*it) < to_charpos)))))
8794 if (it->line_wrap != WORD_WRAP || wrap_it.sp < 0)
8796 result = MOVE_POS_MATCH_OR_ZV;
8797 break;
8799 else if (it->line_wrap == WORD_WRAP && atpos_it.sp < 0)
8800 /* If wrap_it is valid, the current position might be in a
8801 word that is wrapped. So, save the iterator in
8802 atpos_it and continue to see if wrapping happens. */
8803 SAVE_IT (atpos_it, *it, atpos_data);
8806 /* Stop when ZV reached.
8807 We used to stop here when TO_CHARPOS reached as well, but that is
8808 too soon if this glyph does not fit on this line. So we handle it
8809 explicitly below. */
8810 if (!get_next_display_element (it))
8812 result = MOVE_POS_MATCH_OR_ZV;
8813 break;
8816 if (it->line_wrap == TRUNCATE)
8818 /* If it->pixel_width is zero, the last PRODUCE_GLYPHS call
8819 produced something that doesn't consume any screen estate
8820 in the text area, so we don't want to exit the loop at
8821 TO_CHARPOS, before we produce the glyph for that buffer
8822 position. This happens, e.g., when there's an overlay at
8823 TO_CHARPOS that draws a fringe bitmap. */
8824 if (BUFFER_POS_REACHED_P ()
8825 && (it->pixel_width > 0
8826 || IT_CHARPOS (*it) > to_charpos
8827 || it->area != TEXT_AREA))
8829 result = MOVE_POS_MATCH_OR_ZV;
8830 break;
8833 else
8835 if (it->line_wrap == WORD_WRAP && it->area == TEXT_AREA)
8837 if (IT_DISPLAYING_WHITESPACE (it))
8838 may_wrap = true;
8839 else if (may_wrap)
8841 /* We have reached a glyph that follows one or more
8842 whitespace characters. If the position is
8843 already found, we are done. */
8844 if (atpos_it.sp >= 0)
8846 RESTORE_IT (it, &atpos_it, atpos_data);
8847 result = MOVE_POS_MATCH_OR_ZV;
8848 goto done;
8850 if (atx_it.sp >= 0)
8852 RESTORE_IT (it, &atx_it, atx_data);
8853 result = MOVE_X_REACHED;
8854 goto done;
8856 /* Otherwise, we can wrap here. */
8857 SAVE_IT (wrap_it, *it, wrap_data);
8858 may_wrap = false;
8863 /* Remember the line height for the current line, in case
8864 the next element doesn't fit on the line. */
8865 ascent = it->max_ascent;
8866 descent = it->max_descent;
8868 /* The call to produce_glyphs will get the metrics of the
8869 display element IT is loaded with. Record the x-position
8870 before this display element, in case it doesn't fit on the
8871 line. */
8872 x = it->current_x;
8874 PRODUCE_GLYPHS (it);
8876 if (it->area != TEXT_AREA)
8878 prev_method = it->method;
8879 if (it->method == GET_FROM_BUFFER)
8880 prev_pos = IT_CHARPOS (*it);
8881 set_iterator_to_next (it, true);
8882 if (IT_CHARPOS (*it) < CHARPOS (this_line_min_pos))
8883 SET_TEXT_POS (this_line_min_pos,
8884 IT_CHARPOS (*it), IT_BYTEPOS (*it));
8885 if (it->bidi_p
8886 && (op & MOVE_TO_POS)
8887 && IT_CHARPOS (*it) > to_charpos
8888 && IT_CHARPOS (*it) < closest_pos)
8889 closest_pos = IT_CHARPOS (*it);
8890 continue;
8893 /* The number of glyphs we get back in IT->nglyphs will normally
8894 be 1 except when IT->c is (i) a TAB, or (ii) a multi-glyph
8895 character on a terminal frame, or (iii) a line end. For the
8896 second case, IT->nglyphs - 1 padding glyphs will be present.
8897 (On X frames, there is only one glyph produced for a
8898 composite character.)
8900 The behavior implemented below means, for continuation lines,
8901 that as many spaces of a TAB as fit on the current line are
8902 displayed there. For terminal frames, as many glyphs of a
8903 multi-glyph character are displayed in the current line, too.
8904 This is what the old redisplay code did, and we keep it that
8905 way. Under X, the whole shape of a complex character must
8906 fit on the line or it will be completely displayed in the
8907 next line.
8909 Note that both for tabs and padding glyphs, all glyphs have
8910 the same width. */
8911 if (it->nglyphs)
8913 /* More than one glyph or glyph doesn't fit on line. All
8914 glyphs have the same width. */
8915 int single_glyph_width = it->pixel_width / it->nglyphs;
8916 int new_x;
8917 int x_before_this_char = x;
8918 int hpos_before_this_char = it->hpos;
8920 for (i = 0; i < it->nglyphs; ++i, x = new_x)
8922 new_x = x + single_glyph_width;
8924 /* We want to leave anything reaching TO_X to the caller. */
8925 if ((op & MOVE_TO_X) && new_x > to_x)
8927 if (BUFFER_POS_REACHED_P ())
8929 if (it->line_wrap != WORD_WRAP || wrap_it.sp < 0)
8930 goto buffer_pos_reached;
8931 if (atpos_it.sp < 0)
8933 SAVE_IT (atpos_it, *it, atpos_data);
8934 IT_RESET_X_ASCENT_DESCENT (&atpos_it);
8937 else
8939 if (it->line_wrap != WORD_WRAP || wrap_it.sp < 0)
8941 it->current_x = x;
8942 result = MOVE_X_REACHED;
8943 break;
8945 if (atx_it.sp < 0)
8947 SAVE_IT (atx_it, *it, atx_data);
8948 IT_RESET_X_ASCENT_DESCENT (&atx_it);
8953 if (/* Lines are continued. */
8954 it->line_wrap != TRUNCATE
8955 && (/* And glyph doesn't fit on the line. */
8956 new_x > it->last_visible_x
8957 /* Or it fits exactly and we're on a window
8958 system frame. */
8959 || (new_x == it->last_visible_x
8960 && FRAME_WINDOW_P (it->f)
8961 && ((it->bidi_p && it->bidi_it.paragraph_dir == R2L)
8962 ? WINDOW_LEFT_FRINGE_WIDTH (it->w)
8963 : WINDOW_RIGHT_FRINGE_WIDTH (it->w)))))
8965 bool moved_forward = false;
8967 if (/* IT->hpos == 0 means the very first glyph
8968 doesn't fit on the line, e.g. a wide image. */
8969 it->hpos == 0
8970 || (new_x == it->last_visible_x
8971 && FRAME_WINDOW_P (it->f)))
8973 ++it->hpos;
8974 it->current_x = new_x;
8976 /* The character's last glyph just barely fits
8977 in this row. */
8978 if (i == it->nglyphs - 1)
8980 /* If this is the destination position,
8981 return a position *before* it in this row,
8982 now that we know it fits in this row. */
8983 if (BUFFER_POS_REACHED_P ())
8985 bool can_wrap = true;
8987 /* If we are at a whitespace character
8988 that barely fits on this screen line,
8989 but the next character is also
8990 whitespace, we cannot wrap here. */
8991 if (it->line_wrap == WORD_WRAP
8992 && wrap_it.sp >= 0
8993 && may_wrap
8994 && IT_OVERFLOW_NEWLINE_INTO_FRINGE (it))
8996 struct it tem_it;
8997 void *tem_data = NULL;
8999 SAVE_IT (tem_it, *it, tem_data);
9000 set_iterator_to_next (it, true);
9001 if (get_next_display_element (it)
9002 && IT_DISPLAYING_WHITESPACE (it))
9003 can_wrap = false;
9004 RESTORE_IT (it, &tem_it, tem_data);
9006 if (it->line_wrap != WORD_WRAP
9007 || wrap_it.sp < 0
9008 /* If we've just found whitespace
9009 where we can wrap, effectively
9010 ignore the previous wrap point --
9011 it is no longer relevant, but we
9012 won't have an opportunity to
9013 update it, since we've reached
9014 the edge of this screen line. */
9015 || (may_wrap && can_wrap
9016 && IT_OVERFLOW_NEWLINE_INTO_FRINGE (it)))
9018 it->hpos = hpos_before_this_char;
9019 it->current_x = x_before_this_char;
9020 result = MOVE_POS_MATCH_OR_ZV;
9021 break;
9023 if (it->line_wrap == WORD_WRAP
9024 && atpos_it.sp < 0)
9026 SAVE_IT (atpos_it, *it, atpos_data);
9027 atpos_it.current_x = x_before_this_char;
9028 atpos_it.hpos = hpos_before_this_char;
9032 prev_method = it->method;
9033 if (it->method == GET_FROM_BUFFER)
9034 prev_pos = IT_CHARPOS (*it);
9035 set_iterator_to_next (it, true);
9036 if (IT_CHARPOS (*it) < CHARPOS (this_line_min_pos))
9037 SET_TEXT_POS (this_line_min_pos,
9038 IT_CHARPOS (*it), IT_BYTEPOS (*it));
9039 /* On graphical terminals, newlines may
9040 "overflow" into the fringe if
9041 overflow-newline-into-fringe is non-nil.
9042 On text terminals, and on graphical
9043 terminals with no right margin, newlines
9044 may overflow into the last glyph on the
9045 display line.*/
9046 if (!FRAME_WINDOW_P (it->f)
9047 || ((it->bidi_p
9048 && it->bidi_it.paragraph_dir == R2L)
9049 ? WINDOW_LEFT_FRINGE_WIDTH (it->w)
9050 : WINDOW_RIGHT_FRINGE_WIDTH (it->w)) == 0
9051 || IT_OVERFLOW_NEWLINE_INTO_FRINGE (it))
9053 if (!get_next_display_element (it))
9055 result = MOVE_POS_MATCH_OR_ZV;
9056 break;
9058 moved_forward = true;
9059 if (BUFFER_POS_REACHED_P ())
9061 if (ITERATOR_AT_END_OF_LINE_P (it))
9062 result = MOVE_POS_MATCH_OR_ZV;
9063 else
9064 result = MOVE_LINE_CONTINUED;
9065 break;
9067 if (ITERATOR_AT_END_OF_LINE_P (it)
9068 && (it->line_wrap != WORD_WRAP
9069 || wrap_it.sp < 0
9070 || IT_OVERFLOW_NEWLINE_INTO_FRINGE (it)))
9072 result = MOVE_NEWLINE_OR_CR;
9073 break;
9078 else
9079 IT_RESET_X_ASCENT_DESCENT (it);
9081 /* If the screen line ends with whitespace, and we
9082 are under word-wrap, don't use wrap_it: it is no
9083 longer relevant, but we won't have an opportunity
9084 to update it, since we are done with this screen
9085 line. */
9086 if (may_wrap && IT_OVERFLOW_NEWLINE_INTO_FRINGE (it)
9087 /* If the character after the one which set the
9088 may_wrap flag is also whitespace, we can't
9089 wrap here, since the screen line cannot be
9090 wrapped in the middle of whitespace.
9091 Therefore, wrap_it _is_ relevant in that
9092 case. */
9093 && !(moved_forward && IT_DISPLAYING_WHITESPACE (it)))
9095 /* If we've found TO_X, go back there, as we now
9096 know the last word fits on this screen line. */
9097 if ((op & MOVE_TO_X) && new_x == it->last_visible_x
9098 && atx_it.sp >= 0)
9100 RESTORE_IT (it, &atx_it, atx_data);
9101 atpos_it.sp = -1;
9102 atx_it.sp = -1;
9103 result = MOVE_X_REACHED;
9104 break;
9107 else if (wrap_it.sp >= 0)
9109 RESTORE_IT (it, &wrap_it, wrap_data);
9110 atpos_it.sp = -1;
9111 atx_it.sp = -1;
9114 TRACE_MOVE ((stderr, "move_it_in: continued at %d\n",
9115 IT_CHARPOS (*it)));
9116 result = MOVE_LINE_CONTINUED;
9117 break;
9120 if (BUFFER_POS_REACHED_P ())
9122 if (it->line_wrap != WORD_WRAP || wrap_it.sp < 0)
9123 goto buffer_pos_reached;
9124 if (it->line_wrap == WORD_WRAP && atpos_it.sp < 0)
9126 SAVE_IT (atpos_it, *it, atpos_data);
9127 IT_RESET_X_ASCENT_DESCENT (&atpos_it);
9131 if (new_x > it->first_visible_x)
9133 /* If we have reached the visible portion of the
9134 screen line, produce the line number if needed. */
9135 if (line_number_pending)
9137 line_number_pending = false;
9138 it->current_x = it->first_visible_x;
9139 maybe_produce_line_number (it);
9140 it->current_x += new_x - it->first_visible_x;
9142 /* Glyph is visible. Increment number of glyphs that
9143 would be displayed. */
9144 ++it->hpos;
9148 if (result != MOVE_UNDEFINED)
9149 break;
9151 else if (BUFFER_POS_REACHED_P ())
9153 buffer_pos_reached:
9154 IT_RESET_X_ASCENT_DESCENT (it);
9155 result = MOVE_POS_MATCH_OR_ZV;
9156 break;
9158 else if ((op & MOVE_TO_X) && it->current_x >= to_x)
9160 /* Stop when TO_X specified and reached. This check is
9161 necessary here because of lines consisting of a line end,
9162 only. The line end will not produce any glyphs and we
9163 would never get MOVE_X_REACHED. */
9164 eassert (it->nglyphs == 0);
9165 result = MOVE_X_REACHED;
9166 break;
9169 /* Is this a line end? If yes, we're done. */
9170 if (ITERATOR_AT_END_OF_LINE_P (it))
9172 /* If we are past TO_CHARPOS, but never saw any character
9173 positions smaller than TO_CHARPOS, return
9174 MOVE_POS_MATCH_OR_ZV, like the unidirectional display
9175 did. */
9176 if (it->bidi_p && (op & MOVE_TO_POS) != 0)
9178 if (!saw_smaller_pos && IT_CHARPOS (*it) > to_charpos)
9180 if (closest_pos < ZV)
9182 RESTORE_IT (it, &ppos_it, ppos_data);
9183 /* Don't recurse if closest_pos is equal to
9184 to_charpos, since we have just tried that. */
9185 if (closest_pos != to_charpos)
9186 move_it_in_display_line_to (it, closest_pos, -1,
9187 MOVE_TO_POS);
9188 result = MOVE_POS_MATCH_OR_ZV;
9190 else
9191 goto buffer_pos_reached;
9193 else if (it->line_wrap == WORD_WRAP && atpos_it.sp >= 0
9194 && IT_CHARPOS (*it) > to_charpos)
9195 goto buffer_pos_reached;
9196 else
9197 result = MOVE_NEWLINE_OR_CR;
9199 else
9200 result = MOVE_NEWLINE_OR_CR;
9201 /* If we've processed the newline, make sure this flag is
9202 reset, as it must only be set when the newline itself is
9203 processed. */
9204 if (result == MOVE_NEWLINE_OR_CR)
9205 it->constrain_row_ascent_descent_p = false;
9206 break;
9209 prev_method = it->method;
9210 if (it->method == GET_FROM_BUFFER)
9211 prev_pos = IT_CHARPOS (*it);
9212 /* The current display element has been consumed. Advance
9213 to the next. */
9214 set_iterator_to_next (it, true);
9215 if (IT_CHARPOS (*it) < CHARPOS (this_line_min_pos))
9216 SET_TEXT_POS (this_line_min_pos, IT_CHARPOS (*it), IT_BYTEPOS (*it));
9217 if (IT_CHARPOS (*it) < to_charpos)
9218 saw_smaller_pos = true;
9219 if (it->bidi_p
9220 && (op & MOVE_TO_POS)
9221 && IT_CHARPOS (*it) >= to_charpos
9222 && IT_CHARPOS (*it) < closest_pos)
9223 closest_pos = IT_CHARPOS (*it);
9225 /* Stop if lines are truncated and IT's current x-position is
9226 past the right edge of the window now. */
9227 if (it->line_wrap == TRUNCATE
9228 && it->current_x >= it->last_visible_x)
9230 if (!FRAME_WINDOW_P (it->f)
9231 || ((it->bidi_p && it->bidi_it.paragraph_dir == R2L)
9232 ? WINDOW_LEFT_FRINGE_WIDTH (it->w)
9233 : WINDOW_RIGHT_FRINGE_WIDTH (it->w)) == 0
9234 || IT_OVERFLOW_NEWLINE_INTO_FRINGE (it))
9236 bool at_eob_p = false;
9238 if ((at_eob_p = !get_next_display_element (it))
9239 || BUFFER_POS_REACHED_P ()
9240 /* If we are past TO_CHARPOS, but never saw any
9241 character positions smaller than TO_CHARPOS,
9242 return MOVE_POS_MATCH_OR_ZV, like the
9243 unidirectional display did. */
9244 || (it->bidi_p && (op & MOVE_TO_POS) != 0
9245 && !saw_smaller_pos
9246 && IT_CHARPOS (*it) > to_charpos))
9248 if (it->bidi_p
9249 && !BUFFER_POS_REACHED_P ()
9250 && !at_eob_p && closest_pos < ZV)
9252 RESTORE_IT (it, &ppos_it, ppos_data);
9253 if (closest_pos != to_charpos)
9254 move_it_in_display_line_to (it, closest_pos, -1,
9255 MOVE_TO_POS);
9257 result = MOVE_POS_MATCH_OR_ZV;
9258 break;
9260 if (ITERATOR_AT_END_OF_LINE_P (it))
9262 result = MOVE_NEWLINE_OR_CR;
9263 break;
9266 else if (it->bidi_p && (op & MOVE_TO_POS) != 0
9267 && !saw_smaller_pos
9268 && IT_CHARPOS (*it) > to_charpos)
9270 if (closest_pos < ZV)
9272 RESTORE_IT (it, &ppos_it, ppos_data);
9273 if (closest_pos != to_charpos)
9274 move_it_in_display_line_to (it, closest_pos, -1,
9275 MOVE_TO_POS);
9277 result = MOVE_POS_MATCH_OR_ZV;
9278 break;
9280 result = MOVE_LINE_TRUNCATED;
9281 break;
9283 #undef IT_RESET_X_ASCENT_DESCENT
9286 #undef BUFFER_POS_REACHED_P
9288 /* If we scanned beyond TO_POS, restore the saved iterator either to
9289 the wrap point (if found), or to atpos/atx location. We decide which
9290 data to use to restore the saved iterator state by their X coordinates,
9291 since buffer positions might increase non-monotonically with screen
9292 coordinates due to bidi reordering. */
9293 if (result == MOVE_LINE_CONTINUED
9294 && it->line_wrap == WORD_WRAP
9295 && wrap_it.sp >= 0
9296 && ((atpos_it.sp >= 0 && wrap_it.current_x < atpos_it.current_x)
9297 || (atx_it.sp >= 0 && wrap_it.current_x < atx_it.current_x)))
9298 RESTORE_IT (it, &wrap_it, wrap_data);
9299 else if (atpos_it.sp >= 0)
9300 RESTORE_IT (it, &atpos_it, atpos_data);
9301 else if (atx_it.sp >= 0)
9302 RESTORE_IT (it, &atx_it, atx_data);
9304 done:
9306 if (atpos_data)
9307 bidi_unshelve_cache (atpos_data, true);
9308 if (atx_data)
9309 bidi_unshelve_cache (atx_data, true);
9310 if (wrap_data)
9311 bidi_unshelve_cache (wrap_data, true);
9312 if (ppos_data)
9313 bidi_unshelve_cache (ppos_data, true);
9315 /* Restore the iterator settings altered at the beginning of this
9316 function. */
9317 it->glyph_row = saved_glyph_row;
9318 return result;
9321 /* For external use. */
9322 void
9323 move_it_in_display_line (struct it *it,
9324 ptrdiff_t to_charpos, int to_x,
9325 enum move_operation_enum op)
9327 if (it->line_wrap == WORD_WRAP
9328 && (op & MOVE_TO_X))
9330 struct it save_it;
9331 void *save_data = NULL;
9332 int skip;
9334 SAVE_IT (save_it, *it, save_data);
9335 skip = move_it_in_display_line_to (it, to_charpos, to_x, op);
9336 /* When word-wrap is on, TO_X may lie past the end
9337 of a wrapped line. Then it->current is the
9338 character on the next line, so backtrack to the
9339 space before the wrap point. */
9340 if (skip == MOVE_LINE_CONTINUED)
9342 int prev_x = max (it->current_x - 1, 0);
9343 RESTORE_IT (it, &save_it, save_data);
9344 move_it_in_display_line_to
9345 (it, -1, prev_x, MOVE_TO_X);
9347 else
9348 bidi_unshelve_cache (save_data, true);
9350 else
9351 move_it_in_display_line_to (it, to_charpos, to_x, op);
9355 /* Move IT forward until it satisfies one or more of the criteria in
9356 TO_CHARPOS, TO_X, TO_Y, and TO_VPOS.
9358 OP is a bit-mask that specifies where to stop, and in particular,
9359 which of those four position arguments makes a difference. See the
9360 description of enum move_operation_enum.
9362 If TO_CHARPOS is in invisible text, e.g. a truncated part of a
9363 screen line, this function will set IT to the next position that is
9364 displayed to the right of TO_CHARPOS on the screen.
9366 Return the maximum pixel length of any line scanned but never more
9367 than it.last_visible_x. */
9370 move_it_to (struct it *it, ptrdiff_t to_charpos, int to_x, int to_y, int to_vpos, int op)
9372 enum move_it_result skip, skip2 = MOVE_X_REACHED;
9373 int line_height, line_start_x = 0, reached = 0;
9374 int max_current_x = 0;
9375 void *backup_data = NULL;
9377 for (;;)
9379 if (op & MOVE_TO_VPOS)
9381 /* If no TO_CHARPOS and no TO_X specified, stop at the
9382 start of the line TO_VPOS. */
9383 if ((op & (MOVE_TO_X | MOVE_TO_POS)) == 0)
9385 if (it->vpos == to_vpos)
9387 reached = 1;
9388 break;
9390 else
9391 skip = move_it_in_display_line_to (it, -1, -1, 0);
9393 else
9395 /* TO_VPOS >= 0 means stop at TO_X in the line at
9396 TO_VPOS, or at TO_POS, whichever comes first. */
9397 if (it->vpos == to_vpos)
9399 reached = 2;
9400 break;
9403 skip = move_it_in_display_line_to (it, to_charpos, to_x, op);
9405 if (skip == MOVE_POS_MATCH_OR_ZV || it->vpos == to_vpos)
9407 reached = 3;
9408 break;
9410 else if (skip == MOVE_X_REACHED && it->vpos != to_vpos)
9412 /* We have reached TO_X but not in the line we want. */
9413 skip = move_it_in_display_line_to (it, to_charpos,
9414 -1, MOVE_TO_POS);
9415 if (skip == MOVE_POS_MATCH_OR_ZV)
9417 reached = 4;
9418 break;
9423 else if (op & MOVE_TO_Y)
9425 struct it it_backup;
9427 if (it->line_wrap == WORD_WRAP)
9428 SAVE_IT (it_backup, *it, backup_data);
9430 /* TO_Y specified means stop at TO_X in the line containing
9431 TO_Y---or at TO_CHARPOS if this is reached first. The
9432 problem is that we can't really tell whether the line
9433 contains TO_Y before we have completely scanned it, and
9434 this may skip past TO_X. What we do is to first scan to
9435 TO_X.
9437 If TO_X is not specified, use a TO_X of zero. The reason
9438 is to make the outcome of this function more predictable.
9439 If we didn't use TO_X == 0, we would stop at the end of
9440 the line which is probably not what a caller would expect
9441 to happen. */
9442 skip = move_it_in_display_line_to
9443 (it, to_charpos, ((op & MOVE_TO_X) ? to_x : 0),
9444 (MOVE_TO_X | (op & MOVE_TO_POS)));
9446 /* If TO_CHARPOS is reached or ZV, we don't have to do more. */
9447 if (skip == MOVE_POS_MATCH_OR_ZV)
9448 reached = 5;
9449 else if (skip == MOVE_X_REACHED)
9451 /* If TO_X was reached, we want to know whether TO_Y is
9452 in the line. We know this is the case if the already
9453 scanned glyphs make the line tall enough. Otherwise,
9454 we must check by scanning the rest of the line. */
9455 line_height = it->max_ascent + it->max_descent;
9456 if (to_y >= it->current_y
9457 && to_y < it->current_y + line_height)
9459 reached = 6;
9460 break;
9462 SAVE_IT (it_backup, *it, backup_data);
9463 TRACE_MOVE ((stderr, "move_it: from %d\n", IT_CHARPOS (*it)));
9464 skip2 = move_it_in_display_line_to (it, to_charpos, -1,
9465 op & MOVE_TO_POS);
9466 TRACE_MOVE ((stderr, "move_it: to %d\n", IT_CHARPOS (*it)));
9467 line_height = it->max_ascent + it->max_descent;
9468 TRACE_MOVE ((stderr, "move_it: line_height = %d\n", line_height));
9470 if (to_y >= it->current_y
9471 && to_y < it->current_y + line_height)
9473 /* If TO_Y is in this line and TO_X was reached
9474 above, we scanned too far. We have to restore
9475 IT's settings to the ones before skipping. But
9476 keep the more accurate values of max_ascent and
9477 max_descent we've found while skipping the rest
9478 of the line, for the sake of callers, such as
9479 pos_visible_p, that need to know the line
9480 height. */
9481 int max_ascent = it->max_ascent;
9482 int max_descent = it->max_descent;
9484 RESTORE_IT (it, &it_backup, backup_data);
9485 it->max_ascent = max_ascent;
9486 it->max_descent = max_descent;
9487 reached = 6;
9489 else
9491 skip = skip2;
9492 if (skip == MOVE_POS_MATCH_OR_ZV)
9493 reached = 7;
9496 else
9498 /* Check whether TO_Y is in this line. */
9499 line_height = it->max_ascent + it->max_descent;
9500 TRACE_MOVE ((stderr, "move_it: line_height = %d\n", line_height));
9502 if (to_y >= it->current_y
9503 && to_y < it->current_y + line_height)
9505 if (to_y > it->current_y)
9506 max_current_x = max (it->current_x, max_current_x);
9508 /* When word-wrap is on, TO_X may lie past the end
9509 of a wrapped line. Then it->current is the
9510 character on the next line, so backtrack to the
9511 space before the wrap point. */
9512 if (skip == MOVE_LINE_CONTINUED
9513 && it->line_wrap == WORD_WRAP)
9515 int prev_x = max (it->current_x - 1, 0);
9516 RESTORE_IT (it, &it_backup, backup_data);
9517 skip = move_it_in_display_line_to
9518 (it, -1, prev_x, MOVE_TO_X);
9521 reached = 6;
9525 if (reached)
9527 max_current_x = max (it->current_x, max_current_x);
9528 break;
9531 else if (BUFFERP (it->object)
9532 && (it->method == GET_FROM_BUFFER
9533 || it->method == GET_FROM_STRETCH)
9534 && IT_CHARPOS (*it) >= to_charpos
9535 /* Under bidi iteration, a call to set_iterator_to_next
9536 can scan far beyond to_charpos if the initial
9537 portion of the next line needs to be reordered. In
9538 that case, give move_it_in_display_line_to another
9539 chance below. */
9540 && !(it->bidi_p
9541 && it->bidi_it.scan_dir == -1))
9542 skip = MOVE_POS_MATCH_OR_ZV;
9543 else
9544 skip = move_it_in_display_line_to (it, to_charpos, -1, MOVE_TO_POS);
9546 switch (skip)
9548 case MOVE_POS_MATCH_OR_ZV:
9549 max_current_x = max (it->current_x, max_current_x);
9550 reached = 8;
9551 goto out;
9553 case MOVE_NEWLINE_OR_CR:
9554 max_current_x = max (it->current_x, max_current_x);
9555 set_iterator_to_next (it, true);
9556 it->continuation_lines_width = 0;
9557 break;
9559 case MOVE_LINE_TRUNCATED:
9560 max_current_x = it->last_visible_x;
9561 it->continuation_lines_width = 0;
9562 reseat_at_next_visible_line_start (it, false);
9563 if ((op & MOVE_TO_POS) != 0
9564 && IT_CHARPOS (*it) > to_charpos)
9566 reached = 9;
9567 goto out;
9569 break;
9571 case MOVE_LINE_CONTINUED:
9572 max_current_x = it->last_visible_x;
9573 /* For continued lines ending in a tab, some of the glyphs
9574 associated with the tab are displayed on the current
9575 line. Since it->current_x does not include these glyphs,
9576 we use it->last_visible_x instead. */
9577 if (it->c == '\t')
9579 it->continuation_lines_width += it->last_visible_x;
9580 /* When moving by vpos, ensure that the iterator really
9581 advances to the next line (bug#847, bug#969). Fixme:
9582 do we need to do this in other circumstances? */
9583 if (it->current_x != it->last_visible_x
9584 && (op & MOVE_TO_VPOS)
9585 && !(op & (MOVE_TO_X | MOVE_TO_POS)))
9587 line_start_x = it->current_x + it->pixel_width
9588 - it->last_visible_x;
9589 if (FRAME_WINDOW_P (it->f))
9591 struct face *face = FACE_FROM_ID (it->f, it->face_id);
9592 struct font *face_font = face->font;
9594 /* When display_line produces a continued line
9595 that ends in a TAB, it skips a tab stop that
9596 is closer than the font's space character
9597 width (see x_produce_glyphs where it produces
9598 the stretch glyph which represents a TAB).
9599 We need to reproduce the same logic here. */
9600 eassert (face_font);
9601 if (face_font)
9603 if (line_start_x < face_font->space_width)
9604 line_start_x
9605 += it->tab_width * face_font->space_width;
9608 set_iterator_to_next (it, false);
9611 else
9612 it->continuation_lines_width += it->current_x;
9613 break;
9615 default:
9616 emacs_abort ();
9619 /* Reset/increment for the next run. */
9620 recenter_overlay_lists (current_buffer, IT_CHARPOS (*it));
9621 it->current_x = line_start_x;
9622 line_start_x = 0;
9623 it->hpos = 0;
9624 it->line_number_produced_p = false;
9625 it->current_y += it->max_ascent + it->max_descent;
9626 ++it->vpos;
9627 last_height = it->max_ascent + it->max_descent;
9628 it->max_ascent = it->max_descent = 0;
9631 out:
9633 /* On text terminals, we may stop at the end of a line in the middle
9634 of a multi-character glyph. If the glyph itself is continued,
9635 i.e. it is actually displayed on the next line, don't treat this
9636 stopping point as valid; move to the next line instead (unless
9637 that brings us offscreen). */
9638 if (!FRAME_WINDOW_P (it->f)
9639 && op & MOVE_TO_POS
9640 && IT_CHARPOS (*it) == to_charpos
9641 && it->what == IT_CHARACTER
9642 && it->nglyphs > 1
9643 && it->line_wrap == WINDOW_WRAP
9644 && it->current_x == it->last_visible_x - 1
9645 && it->c != '\n'
9646 && it->c != '\t'
9647 && it->w->window_end_valid
9648 && it->vpos < it->w->window_end_vpos)
9650 it->continuation_lines_width += it->current_x;
9651 it->current_x = it->hpos = it->max_ascent = it->max_descent = 0;
9652 it->current_y += it->max_ascent + it->max_descent;
9653 ++it->vpos;
9654 last_height = it->max_ascent + it->max_descent;
9657 if (backup_data)
9658 bidi_unshelve_cache (backup_data, true);
9660 TRACE_MOVE ((stderr, "move_it_to: reached %d\n", reached));
9662 return max_current_x;
9666 /* Move iterator IT backward by a specified y-distance DY, DY >= 0.
9668 If DY > 0, move IT backward at least that many pixels. DY = 0
9669 means move IT backward to the preceding line start or BEGV. This
9670 function may move over more than DY pixels if IT->current_y - DY
9671 ends up in the middle of a line; in this case IT->current_y will be
9672 set to the top of the line moved to. */
9674 void
9675 move_it_vertically_backward (struct it *it, int dy)
9677 int nlines, h;
9678 struct it it2, it3;
9679 void *it2data = NULL, *it3data = NULL;
9680 ptrdiff_t start_pos;
9681 int nchars_per_row
9682 = (it->last_visible_x - it->first_visible_x) / FRAME_COLUMN_WIDTH (it->f);
9683 ptrdiff_t pos_limit;
9685 move_further_back:
9686 eassert (dy >= 0);
9688 start_pos = IT_CHARPOS (*it);
9690 /* Estimate how many newlines we must move back. */
9691 nlines = max (1, dy / default_line_pixel_height (it->w));
9692 if (it->line_wrap == TRUNCATE || nchars_per_row == 0)
9693 pos_limit = BEGV;
9694 else
9695 pos_limit = max (start_pos - nlines * nchars_per_row, BEGV);
9697 /* Set the iterator's position that many lines back. But don't go
9698 back more than NLINES full screen lines -- this wins a day with
9699 buffers which have very long lines. */
9700 while (nlines-- && IT_CHARPOS (*it) > pos_limit)
9701 back_to_previous_visible_line_start (it);
9703 /* Reseat the iterator here. When moving backward, we don't want
9704 reseat to skip forward over invisible text, set up the iterator
9705 to deliver from overlay strings at the new position etc. So,
9706 use reseat_1 here. */
9707 reseat_1 (it, it->current.pos, true);
9709 /* We are now surely at a line start. */
9710 it->current_x = it->hpos = 0; /* FIXME: this is incorrect when bidi
9711 reordering is in effect. */
9712 it->continuation_lines_width = 0;
9714 /* Move forward and see what y-distance we moved. First move to the
9715 start of the next line so that we get its height. We need this
9716 height to be able to tell whether we reached the specified
9717 y-distance. */
9718 SAVE_IT (it2, *it, it2data);
9719 it2.max_ascent = it2.max_descent = 0;
9722 move_it_to (&it2, start_pos, -1, -1, it2.vpos + 1,
9723 MOVE_TO_POS | MOVE_TO_VPOS);
9725 while (!(IT_POS_VALID_AFTER_MOVE_P (&it2)
9726 /* If we are in a display string which starts at START_POS,
9727 and that display string includes a newline, and we are
9728 right after that newline (i.e. at the beginning of a
9729 display line), exit the loop, because otherwise we will
9730 infloop, since move_it_to will see that it is already at
9731 START_POS and will not move. */
9732 || (it2.method == GET_FROM_STRING
9733 && IT_CHARPOS (it2) == start_pos
9734 && SREF (it2.string, IT_STRING_BYTEPOS (it2) - 1) == '\n')));
9735 eassert (IT_CHARPOS (*it) >= BEGV);
9736 SAVE_IT (it3, it2, it3data);
9738 move_it_to (&it2, start_pos, -1, -1, -1, MOVE_TO_POS);
9739 eassert (IT_CHARPOS (*it) >= BEGV);
9740 /* H is the actual vertical distance from the position in *IT
9741 and the starting position. */
9742 h = it2.current_y - it->current_y;
9743 /* NLINES is the distance in number of lines. */
9744 nlines = it2.vpos - it->vpos;
9746 /* Correct IT's y and vpos position
9747 so that they are relative to the starting point. */
9748 it->vpos -= nlines;
9749 it->current_y -= h;
9751 if (dy == 0)
9753 /* DY == 0 means move to the start of the screen line. The
9754 value of nlines is > 0 if continuation lines were involved,
9755 or if the original IT position was at start of a line. */
9756 RESTORE_IT (it, it, it2data);
9757 if (nlines > 0)
9758 move_it_by_lines (it, nlines);
9759 /* The above code moves us to some position NLINES down,
9760 usually to its first glyph (leftmost in an L2R line), but
9761 that's not necessarily the start of the line, under bidi
9762 reordering. We want to get to the character position
9763 that is immediately after the newline of the previous
9764 line. */
9765 if (it->bidi_p
9766 && !it->continuation_lines_width
9767 && !STRINGP (it->string)
9768 && IT_CHARPOS (*it) > BEGV
9769 && FETCH_BYTE (IT_BYTEPOS (*it) - 1) != '\n')
9771 ptrdiff_t cp = IT_CHARPOS (*it), bp = IT_BYTEPOS (*it);
9773 DEC_BOTH (cp, bp);
9774 cp = find_newline_no_quit (cp, bp, -1, NULL);
9775 move_it_to (it, cp, -1, -1, -1, MOVE_TO_POS);
9777 bidi_unshelve_cache (it3data, true);
9779 else
9781 /* The y-position we try to reach, relative to *IT.
9782 Note that H has been subtracted in front of the if-statement. */
9783 int target_y = it->current_y + h - dy;
9784 int y0 = it3.current_y;
9785 int y1;
9786 int line_height;
9788 RESTORE_IT (&it3, &it3, it3data);
9789 y1 = line_bottom_y (&it3);
9790 line_height = y1 - y0;
9791 RESTORE_IT (it, it, it2data);
9792 /* If we did not reach target_y, try to move further backward if
9793 we can. If we moved too far backward, try to move forward. */
9794 if (target_y < it->current_y
9795 /* This is heuristic. In a window that's 3 lines high, with
9796 a line height of 13 pixels each, recentering with point
9797 on the bottom line will try to move -39/2 = 19 pixels
9798 backward. Try to avoid moving into the first line. */
9799 && (it->current_y - target_y
9800 > min (window_box_height (it->w), line_height * 2 / 3))
9801 && IT_CHARPOS (*it) > BEGV)
9803 TRACE_MOVE ((stderr, " not far enough -> move_vert %d\n",
9804 target_y - it->current_y));
9805 dy = it->current_y - target_y;
9806 goto move_further_back;
9808 else if (target_y >= it->current_y + line_height
9809 && IT_CHARPOS (*it) < ZV)
9811 /* Should move forward by at least one line, maybe more.
9813 Note: Calling move_it_by_lines can be expensive on
9814 terminal frames, where compute_motion is used (via
9815 vmotion) to do the job, when there are very long lines
9816 and truncate-lines is nil. That's the reason for
9817 treating terminal frames specially here. */
9819 if (!FRAME_WINDOW_P (it->f))
9820 move_it_vertically (it, target_y - it->current_y);
9821 else
9825 move_it_by_lines (it, 1);
9827 while (target_y >= line_bottom_y (it) && IT_CHARPOS (*it) < ZV);
9834 /* Move IT by a specified amount of pixel lines DY. DY negative means
9835 move backwards. DY = 0 means move to start of screen line. At the
9836 end, IT will be on the start of a screen line. */
9838 void
9839 move_it_vertically (struct it *it, int dy)
9841 if (dy <= 0)
9842 move_it_vertically_backward (it, -dy);
9843 else
9845 TRACE_MOVE ((stderr, "move_it_v: from %d, %d\n", IT_CHARPOS (*it), dy));
9846 move_it_to (it, ZV, -1, it->current_y + dy, -1,
9847 MOVE_TO_POS | MOVE_TO_Y);
9848 TRACE_MOVE ((stderr, "move_it_v: to %d\n", IT_CHARPOS (*it)));
9850 /* If buffer ends in ZV without a newline, move to the start of
9851 the line to satisfy the post-condition. */
9852 if (IT_CHARPOS (*it) == ZV
9853 && ZV > BEGV
9854 && FETCH_BYTE (IT_BYTEPOS (*it) - 1) != '\n')
9855 move_it_by_lines (it, 0);
9860 /* Move iterator IT past the end of the text line it is in. */
9862 void
9863 move_it_past_eol (struct it *it)
9865 enum move_it_result rc;
9867 rc = move_it_in_display_line_to (it, Z, 0, MOVE_TO_POS);
9868 if (rc == MOVE_NEWLINE_OR_CR)
9869 set_iterator_to_next (it, false);
9873 /* Move IT by a specified number DVPOS of screen lines down. DVPOS
9874 negative means move up. DVPOS == 0 means move to the start of the
9875 screen line.
9877 Optimization idea: If we would know that IT->f doesn't use
9878 a face with proportional font, we could be faster for
9879 truncate-lines nil. */
9881 void
9882 move_it_by_lines (struct it *it, ptrdiff_t dvpos)
9885 /* The commented-out optimization uses vmotion on terminals. This
9886 gives bad results, because elements like it->what, on which
9887 callers such as pos_visible_p rely, aren't updated. */
9888 /* struct position pos;
9889 if (!FRAME_WINDOW_P (it->f))
9891 struct text_pos textpos;
9893 pos = *vmotion (IT_CHARPOS (*it), dvpos, it->w);
9894 SET_TEXT_POS (textpos, pos.bufpos, pos.bytepos);
9895 reseat (it, textpos, true);
9896 it->vpos += pos.vpos;
9897 it->current_y += pos.vpos;
9899 else */
9901 if (dvpos == 0)
9903 /* DVPOS == 0 means move to the start of the screen line. */
9904 move_it_vertically_backward (it, 0);
9905 /* Let next call to line_bottom_y calculate real line height. */
9906 last_height = 0;
9908 else if (dvpos > 0)
9910 move_it_to (it, -1, -1, -1, it->vpos + dvpos, MOVE_TO_VPOS);
9911 if (!IT_POS_VALID_AFTER_MOVE_P (it))
9913 /* Only move to the next buffer position if we ended up in a
9914 string from display property, not in an overlay string
9915 (before-string or after-string). That is because the
9916 latter don't conceal the underlying buffer position, so
9917 we can ask to move the iterator to the exact position we
9918 are interested in. Note that, even if we are already at
9919 IT_CHARPOS (*it), the call below is not a no-op, as it
9920 will detect that we are at the end of the string, pop the
9921 iterator, and compute it->current_x and it->hpos
9922 correctly. */
9923 move_it_to (it, IT_CHARPOS (*it) + it->string_from_display_prop_p,
9924 -1, -1, -1, MOVE_TO_POS);
9927 else
9929 struct it it2;
9930 void *it2data = NULL;
9931 ptrdiff_t start_charpos, i;
9932 int nchars_per_row
9933 = (it->last_visible_x - it->first_visible_x) / FRAME_COLUMN_WIDTH (it->f);
9934 bool hit_pos_limit = false;
9935 ptrdiff_t pos_limit;
9937 /* Start at the beginning of the screen line containing IT's
9938 position. This may actually move vertically backwards,
9939 in case of overlays, so adjust dvpos accordingly. */
9940 dvpos += it->vpos;
9941 move_it_vertically_backward (it, 0);
9942 dvpos -= it->vpos;
9944 /* Go back -DVPOS buffer lines, but no farther than -DVPOS full
9945 screen lines, and reseat the iterator there. */
9946 start_charpos = IT_CHARPOS (*it);
9947 if (it->line_wrap == TRUNCATE || nchars_per_row == 0)
9948 pos_limit = BEGV;
9949 else
9950 pos_limit = max (start_charpos + dvpos * nchars_per_row, BEGV);
9952 for (i = -dvpos; i > 0 && IT_CHARPOS (*it) > pos_limit; --i)
9953 back_to_previous_visible_line_start (it);
9954 if (i > 0 && IT_CHARPOS (*it) <= pos_limit)
9955 hit_pos_limit = true;
9956 reseat (it, it->current.pos, true);
9958 /* Move further back if we end up in a string or an image. */
9959 while (!IT_POS_VALID_AFTER_MOVE_P (it))
9961 /* First try to move to start of display line. */
9962 dvpos += it->vpos;
9963 move_it_vertically_backward (it, 0);
9964 dvpos -= it->vpos;
9965 if (IT_POS_VALID_AFTER_MOVE_P (it))
9966 break;
9967 /* If start of line is still in string or image,
9968 move further back. */
9969 back_to_previous_visible_line_start (it);
9970 reseat (it, it->current.pos, true);
9971 dvpos--;
9974 it->current_x = it->hpos = 0;
9976 /* Above call may have moved too far if continuation lines
9977 are involved. Scan forward and see if it did. */
9978 SAVE_IT (it2, *it, it2data);
9979 it2.vpos = it2.current_y = 0;
9980 move_it_to (&it2, start_charpos, -1, -1, -1, MOVE_TO_POS);
9981 it->vpos -= it2.vpos;
9982 it->current_y -= it2.current_y;
9983 it->current_x = it->hpos = 0;
9985 /* If we moved too far back, move IT some lines forward. */
9986 if (it2.vpos > -dvpos)
9988 int delta = it2.vpos + dvpos;
9990 RESTORE_IT (&it2, &it2, it2data);
9991 SAVE_IT (it2, *it, it2data);
9992 move_it_to (it, -1, -1, -1, it->vpos + delta, MOVE_TO_VPOS);
9993 /* Move back again if we got too far ahead. */
9994 if (IT_CHARPOS (*it) >= start_charpos)
9995 RESTORE_IT (it, &it2, it2data);
9996 else
9997 bidi_unshelve_cache (it2data, true);
9999 else if (hit_pos_limit && pos_limit > BEGV
10000 && dvpos < 0 && it2.vpos < -dvpos)
10002 /* If we hit the limit, but still didn't make it far enough
10003 back, that means there's a display string with a newline
10004 covering a large chunk of text, and that caused
10005 back_to_previous_visible_line_start try to go too far.
10006 Punish those who commit such atrocities by going back
10007 until we've reached DVPOS, after lifting the limit, which
10008 could make it slow for very long lines. "If it hurts,
10009 don't do that!" */
10010 dvpos += it2.vpos;
10011 RESTORE_IT (it, it, it2data);
10012 for (i = -dvpos; i > 0; --i)
10014 back_to_previous_visible_line_start (it);
10015 it->vpos--;
10017 reseat_1 (it, it->current.pos, true);
10019 else
10020 RESTORE_IT (it, it, it2data);
10025 partial_line_height (struct it *it_origin)
10027 int partial_height;
10028 void *it_data = NULL;
10029 struct it it;
10030 SAVE_IT (it, *it_origin, it_data);
10031 move_it_to (&it, ZV, -1, it.last_visible_y, -1,
10032 MOVE_TO_POS | MOVE_TO_Y);
10033 if (it.what == IT_EOB)
10035 int vis_height = it.last_visible_y - it.current_y;
10036 int height = it.ascent + it.descent;
10037 partial_height = (vis_height < height) ? vis_height : 0;
10039 else
10041 int last_line_y = it.current_y;
10042 move_it_by_lines (&it, 1);
10043 partial_height = (it.current_y > it.last_visible_y)
10044 ? it.last_visible_y - last_line_y : 0;
10046 RESTORE_IT (&it, &it, it_data);
10047 return partial_height;
10050 /* Return true if IT points into the middle of a display vector. */
10052 bool
10053 in_display_vector_p (struct it *it)
10055 return (it->method == GET_FROM_DISPLAY_VECTOR
10056 && it->current.dpvec_index > 0
10057 && it->dpvec + it->current.dpvec_index != it->dpend);
10060 DEFUN ("window-text-pixel-size", Fwindow_text_pixel_size, Swindow_text_pixel_size, 0, 6, 0,
10061 doc: /* Return the size of the text of WINDOW's buffer in pixels.
10062 WINDOW must be a live window and defaults to the selected one. The
10063 return value is a cons of the maximum pixel-width of any text line and
10064 the maximum pixel-height of all text lines.
10066 The optional argument FROM, if non-nil, specifies the first text
10067 position and defaults to the minimum accessible position of the buffer.
10068 If FROM is t, use the minimum accessible position that starts a
10069 non-empty line. TO, if non-nil, specifies the last text position and
10070 defaults to the maximum accessible position of the buffer. If TO is t,
10071 use the maximum accessible position that ends a non-empty line.
10073 The optional argument X-LIMIT, if non-nil, specifies the maximum text
10074 width that can be returned. X-LIMIT nil or omitted, means to use the
10075 pixel-width of WINDOW's body; use this if you want to know how high
10076 WINDOW should be become in order to fit all of its buffer's text with
10077 the width of WINDOW unaltered. Use the maximum width WINDOW may assume
10078 if you intend to change WINDOW's width. In any case, text whose
10079 x-coordinate is beyond X-LIMIT is ignored. Since calculating the width
10080 of long lines can take some time, it's always a good idea to make this
10081 argument as small as possible; in particular, if the buffer contains
10082 long lines that shall be truncated anyway.
10084 The optional argument Y-LIMIT, if non-nil, specifies the maximum text
10085 height (excluding the height of the mode- or header-line, if any) that
10086 can be returned. Text lines whose y-coordinate is beyond Y-LIMIT are
10087 ignored. Since calculating the text height of a large buffer can take
10088 some time, it makes sense to specify this argument if the size of the
10089 buffer is large or unknown.
10091 Optional argument MODE-AND-HEADER-LINE nil or omitted means do not
10092 include the height of the mode- or header-line of WINDOW in the return
10093 value. If it is either the symbol `mode-line' or `header-line', include
10094 only the height of that line, if present, in the return value. If t,
10095 include the height of both, if present, in the return value. */)
10096 (Lisp_Object window, Lisp_Object from, Lisp_Object to, Lisp_Object x_limit,
10097 Lisp_Object y_limit, Lisp_Object mode_and_header_line)
10099 struct window *w = decode_live_window (window);
10100 Lisp_Object buffer = w->contents;
10101 struct buffer *b;
10102 struct it it;
10103 struct buffer *old_b = NULL;
10104 ptrdiff_t start, end, pos;
10105 struct text_pos startp;
10106 void *itdata = NULL;
10107 int c, max_x = 0, max_y = 0, x = 0, y = 0;
10109 CHECK_BUFFER (buffer);
10110 b = XBUFFER (buffer);
10112 if (b != current_buffer)
10114 old_b = current_buffer;
10115 set_buffer_internal (b);
10118 if (NILP (from))
10119 start = BEGV;
10120 else if (EQ (from, Qt))
10122 start = pos = BEGV;
10123 while ((pos++ < ZV) && (c = FETCH_CHAR (pos))
10124 && (c == ' ' || c == '\t' || c == '\n' || c == '\r'))
10125 start = pos;
10126 while ((pos-- > BEGV) && (c = FETCH_CHAR (pos)) && (c == ' ' || c == '\t'))
10127 start = pos;
10129 else
10131 CHECK_NUMBER_COERCE_MARKER (from);
10132 start = min (max (XINT (from), BEGV), ZV);
10135 if (NILP (to))
10136 end = ZV;
10137 else if (EQ (to, Qt))
10139 end = pos = ZV;
10140 while ((pos-- > BEGV) && (c = FETCH_CHAR (pos))
10141 && (c == ' ' || c == '\t' || c == '\n' || c == '\r'))
10142 end = pos;
10143 while ((pos++ < ZV) && (c = FETCH_CHAR (pos)) && (c == ' ' || c == '\t'))
10144 end = pos;
10146 else
10148 CHECK_NUMBER_COERCE_MARKER (to);
10149 end = max (start, min (XINT (to), ZV));
10152 if (!NILP (x_limit) && RANGED_INTEGERP (0, x_limit, INT_MAX))
10153 max_x = XINT (x_limit);
10155 if (NILP (y_limit))
10156 max_y = INT_MAX;
10157 else if (RANGED_INTEGERP (0, y_limit, INT_MAX))
10158 max_y = XINT (y_limit);
10160 itdata = bidi_shelve_cache ();
10161 SET_TEXT_POS (startp, start, CHAR_TO_BYTE (start));
10162 start_display (&it, w, startp);
10163 /* It makes no sense to measure dimensions of region of text that
10164 crosses the point where bidi reordering changes scan direction.
10165 By using unidirectional movement here we at least support the use
10166 case of measuring regions of text that have a uniformly R2L
10167 directionality, and regions that begin and end in text of the
10168 same directionality. */
10169 it.bidi_p = false;
10171 int move_op = MOVE_TO_POS | MOVE_TO_Y;
10172 int to_x = -1;
10173 if (!NILP (x_limit))
10175 it.last_visible_x = max_x;
10176 /* Actually, we never want move_it_to stop at to_x. But to make
10177 sure that move_it_in_display_line_to always moves far enough,
10178 we set to_x to INT_MAX and specify MOVE_TO_X. */
10179 move_op |= MOVE_TO_X;
10180 to_x = INT_MAX;
10183 void *it2data = NULL;
10184 struct it it2;
10185 SAVE_IT (it2, it, it2data);
10187 x = move_it_to (&it, end, to_x, max_y, -1, move_op);
10189 /* We could have a display property at END, in which case asking
10190 move_it_to to stop at END will overshoot and stop at position
10191 after END. So we try again, stopping before END, and account for
10192 the width of the last buffer position manually. */
10193 if (IT_CHARPOS (it) > end)
10195 end--;
10196 RESTORE_IT (&it, &it2, it2data);
10197 x = move_it_to (&it, end, to_x, max_y, -1, move_op);
10198 /* Add the width of the thing at TO, but only if we didn't
10199 overshoot it; if we did, it is already accounted for. Also,
10200 account for the height of the thing at TO. */
10201 if (IT_CHARPOS (it) == end)
10203 x += it.pixel_width;
10204 it.max_ascent = max (it.max_ascent, it.ascent);
10205 it.max_descent = max (it.max_descent, it.descent);
10208 if (!NILP (x_limit))
10210 /* Don't return more than X-LIMIT. */
10211 if (x > max_x)
10212 x = max_x;
10215 /* Subtract height of header-line which was counted automatically by
10216 start_display. */
10217 y = it.current_y + it.max_ascent + it.max_descent
10218 - WINDOW_HEADER_LINE_HEIGHT (w);
10219 /* Don't return more than Y-LIMIT. */
10220 if (y > max_y)
10221 y = max_y;
10223 if (EQ (mode_and_header_line, Qheader_line)
10224 || EQ (mode_and_header_line, Qt))
10225 /* Re-add height of header-line as requested. */
10226 y = y + WINDOW_HEADER_LINE_HEIGHT (w);
10228 if (EQ (mode_and_header_line, Qmode_line)
10229 || EQ (mode_and_header_line, Qt))
10230 /* Add height of mode-line as requested. */
10231 y = y + WINDOW_MODE_LINE_HEIGHT (w);
10233 bidi_unshelve_cache (itdata, false);
10235 if (old_b)
10236 set_buffer_internal (old_b);
10238 return Fcons (make_number (x), make_number (y));
10241 /***********************************************************************
10242 Messages
10243 ***********************************************************************/
10245 /* Return the number of arguments the format string FORMAT needs. */
10247 static ptrdiff_t
10248 format_nargs (char const *format)
10250 ptrdiff_t nargs = 0;
10251 for (char const *p = format; (p = strchr (p, '%')); p++)
10252 if (p[1] == '%')
10253 p++;
10254 else
10255 nargs++;
10256 return nargs;
10259 /* Add a message with format string FORMAT and formatted arguments
10260 to *Messages*. */
10262 void
10263 add_to_log (const char *format, ...)
10265 va_list ap;
10266 va_start (ap, format);
10267 vadd_to_log (format, ap);
10268 va_end (ap);
10271 void
10272 vadd_to_log (char const *format, va_list ap)
10274 ptrdiff_t form_nargs = format_nargs (format);
10275 ptrdiff_t nargs = 1 + form_nargs;
10276 Lisp_Object args[10];
10277 eassert (nargs <= ARRAYELTS (args));
10278 AUTO_STRING (args0, format);
10279 args[0] = args0;
10280 for (ptrdiff_t i = 1; i <= nargs; i++)
10281 args[i] = va_arg (ap, Lisp_Object);
10282 Lisp_Object msg = Qnil;
10283 msg = Fformat_message (nargs, args);
10285 ptrdiff_t len = SBYTES (msg) + 1;
10286 USE_SAFE_ALLOCA;
10287 char *buffer = SAFE_ALLOCA (len);
10288 memcpy (buffer, SDATA (msg), len);
10290 message_dolog (buffer, len - 1, true, STRING_MULTIBYTE (msg));
10291 SAFE_FREE ();
10295 /* Output a newline in the *Messages* buffer if "needs" one. */
10297 void
10298 message_log_maybe_newline (void)
10300 if (message_log_need_newline)
10301 message_dolog ("", 0, true, false);
10305 /* Add a string M of length NBYTES to the message log, optionally
10306 terminated with a newline when NLFLAG is true. MULTIBYTE, if
10307 true, means interpret the contents of M as multibyte. This
10308 function calls low-level routines in order to bypass text property
10309 hooks, etc. which might not be safe to run.
10311 This may GC (insert may run before/after change hooks),
10312 so the buffer M must NOT point to a Lisp string. */
10314 void
10315 message_dolog (const char *m, ptrdiff_t nbytes, bool nlflag, bool multibyte)
10317 const unsigned char *msg = (const unsigned char *) m;
10319 if (!NILP (Vmemory_full))
10320 return;
10322 if (!NILP (Vmessage_log_max))
10324 struct buffer *oldbuf;
10325 Lisp_Object oldpoint, oldbegv, oldzv;
10326 int old_windows_or_buffers_changed = windows_or_buffers_changed;
10327 ptrdiff_t point_at_end = 0;
10328 ptrdiff_t zv_at_end = 0;
10329 Lisp_Object old_deactivate_mark;
10331 old_deactivate_mark = Vdeactivate_mark;
10332 oldbuf = current_buffer;
10334 /* Ensure the Messages buffer exists, and switch to it.
10335 If we created it, set the major-mode. */
10336 bool newbuffer = NILP (Fget_buffer (Vmessages_buffer_name));
10337 Fset_buffer (Fget_buffer_create (Vmessages_buffer_name));
10338 if (newbuffer
10339 && !NILP (Ffboundp (intern ("messages-buffer-mode"))))
10340 call0 (intern ("messages-buffer-mode"));
10342 bset_undo_list (current_buffer, Qt);
10343 bset_cache_long_scans (current_buffer, Qnil);
10345 oldpoint = message_dolog_marker1;
10346 set_marker_restricted_both (oldpoint, Qnil, PT, PT_BYTE);
10347 oldbegv = message_dolog_marker2;
10348 set_marker_restricted_both (oldbegv, Qnil, BEGV, BEGV_BYTE);
10349 oldzv = message_dolog_marker3;
10350 set_marker_restricted_both (oldzv, Qnil, ZV, ZV_BYTE);
10352 if (PT == Z)
10353 point_at_end = 1;
10354 if (ZV == Z)
10355 zv_at_end = 1;
10357 BEGV = BEG;
10358 BEGV_BYTE = BEG_BYTE;
10359 ZV = Z;
10360 ZV_BYTE = Z_BYTE;
10361 TEMP_SET_PT_BOTH (Z, Z_BYTE);
10363 /* Insert the string--maybe converting multibyte to single byte
10364 or vice versa, so that all the text fits the buffer. */
10365 if (multibyte
10366 && NILP (BVAR (current_buffer, enable_multibyte_characters)))
10368 ptrdiff_t i;
10369 int c, char_bytes;
10370 char work[1];
10372 /* Convert a multibyte string to single-byte
10373 for the *Message* buffer. */
10374 for (i = 0; i < nbytes; i += char_bytes)
10376 c = string_char_and_length (msg + i, &char_bytes);
10377 work[0] = CHAR_TO_BYTE8 (c);
10378 insert_1_both (work, 1, 1, true, false, false);
10381 else if (! multibyte
10382 && ! NILP (BVAR (current_buffer, enable_multibyte_characters)))
10384 ptrdiff_t i;
10385 int c, char_bytes;
10386 unsigned char str[MAX_MULTIBYTE_LENGTH];
10387 /* Convert a single-byte string to multibyte
10388 for the *Message* buffer. */
10389 for (i = 0; i < nbytes; i++)
10391 c = msg[i];
10392 MAKE_CHAR_MULTIBYTE (c);
10393 char_bytes = CHAR_STRING (c, str);
10394 insert_1_both ((char *) str, 1, char_bytes, true, false, false);
10397 else if (nbytes)
10398 insert_1_both (m, chars_in_text (msg, nbytes), nbytes,
10399 true, false, false);
10401 if (nlflag)
10403 ptrdiff_t this_bol, this_bol_byte, prev_bol, prev_bol_byte;
10404 printmax_t dups;
10406 insert_1_both ("\n", 1, 1, true, false, false);
10408 scan_newline (Z, Z_BYTE, BEG, BEG_BYTE, -2, false);
10409 this_bol = PT;
10410 this_bol_byte = PT_BYTE;
10412 /* See if this line duplicates the previous one.
10413 If so, combine duplicates. */
10414 if (this_bol > BEG)
10416 scan_newline (PT, PT_BYTE, BEG, BEG_BYTE, -2, false);
10417 prev_bol = PT;
10418 prev_bol_byte = PT_BYTE;
10420 dups = message_log_check_duplicate (prev_bol_byte,
10421 this_bol_byte);
10422 if (dups)
10424 del_range_both (prev_bol, prev_bol_byte,
10425 this_bol, this_bol_byte, false);
10426 if (dups > 1)
10428 char dupstr[sizeof " [ times]"
10429 + INT_STRLEN_BOUND (printmax_t)];
10431 /* If you change this format, don't forget to also
10432 change message_log_check_duplicate. */
10433 int duplen = sprintf (dupstr, " [%"pMd" times]", dups);
10434 TEMP_SET_PT_BOTH (Z - 1, Z_BYTE - 1);
10435 insert_1_both (dupstr, duplen, duplen,
10436 true, false, true);
10441 /* If we have more than the desired maximum number of lines
10442 in the *Messages* buffer now, delete the oldest ones.
10443 This is safe because we don't have undo in this buffer. */
10445 if (NATNUMP (Vmessage_log_max))
10447 scan_newline (Z, Z_BYTE, BEG, BEG_BYTE,
10448 -XFASTINT (Vmessage_log_max) - 1, false);
10449 del_range_both (BEG, BEG_BYTE, PT, PT_BYTE, false);
10452 BEGV = marker_position (oldbegv);
10453 BEGV_BYTE = marker_byte_position (oldbegv);
10455 if (zv_at_end)
10457 ZV = Z;
10458 ZV_BYTE = Z_BYTE;
10460 else
10462 ZV = marker_position (oldzv);
10463 ZV_BYTE = marker_byte_position (oldzv);
10466 if (point_at_end)
10467 TEMP_SET_PT_BOTH (Z, Z_BYTE);
10468 else
10469 /* We can't do Fgoto_char (oldpoint) because it will run some
10470 Lisp code. */
10471 TEMP_SET_PT_BOTH (marker_position (oldpoint),
10472 marker_byte_position (oldpoint));
10474 unchain_marker (XMARKER (oldpoint));
10475 unchain_marker (XMARKER (oldbegv));
10476 unchain_marker (XMARKER (oldzv));
10478 /* We called insert_1_both above with its 5th argument (PREPARE)
10479 false, which prevents insert_1_both from calling
10480 prepare_to_modify_buffer, which in turns prevents us from
10481 incrementing windows_or_buffers_changed even if *Messages* is
10482 shown in some window. So we must manually set
10483 windows_or_buffers_changed here to make up for that. */
10484 windows_or_buffers_changed = old_windows_or_buffers_changed;
10485 bset_redisplay (current_buffer);
10487 set_buffer_internal (oldbuf);
10489 message_log_need_newline = !nlflag;
10490 Vdeactivate_mark = old_deactivate_mark;
10495 /* We are at the end of the buffer after just having inserted a newline.
10496 (Note: We depend on the fact we won't be crossing the gap.)
10497 Check to see if the most recent message looks a lot like the previous one.
10498 Return 0 if different, 1 if the new one should just replace it, or a
10499 value N > 1 if we should also append " [N times]". */
10501 static intmax_t
10502 message_log_check_duplicate (ptrdiff_t prev_bol_byte, ptrdiff_t this_bol_byte)
10504 ptrdiff_t i;
10505 ptrdiff_t len = Z_BYTE - 1 - this_bol_byte;
10506 bool seen_dots = false;
10507 unsigned char *p1 = BUF_BYTE_ADDRESS (current_buffer, prev_bol_byte);
10508 unsigned char *p2 = BUF_BYTE_ADDRESS (current_buffer, this_bol_byte);
10510 for (i = 0; i < len; i++)
10512 if (i >= 3 && p1[i - 3] == '.' && p1[i - 2] == '.' && p1[i - 1] == '.')
10513 seen_dots = true;
10514 if (p1[i] != p2[i])
10515 return seen_dots;
10517 p1 += len;
10518 if (*p1 == '\n')
10519 return 2;
10520 if (*p1++ == ' ' && *p1++ == '[')
10522 char *pend;
10523 intmax_t n = strtoimax ((char *) p1, &pend, 10);
10524 if (0 < n && n < INTMAX_MAX && strncmp (pend, " times]\n", 8) == 0)
10525 return n + 1;
10527 return 0;
10531 /* Display an echo area message M with a specified length of NBYTES
10532 bytes. The string may include null characters. If M is not a
10533 string, clear out any existing message, and let the mini-buffer
10534 text show through.
10536 This function cancels echoing. */
10538 void
10539 message3 (Lisp_Object m)
10541 clear_message (true, true);
10542 cancel_echoing ();
10544 /* First flush out any partial line written with print. */
10545 message_log_maybe_newline ();
10546 if (STRINGP (m))
10548 ptrdiff_t nbytes = SBYTES (m);
10549 bool multibyte = STRING_MULTIBYTE (m);
10550 char *buffer;
10551 USE_SAFE_ALLOCA;
10552 SAFE_ALLOCA_STRING (buffer, m);
10553 message_dolog (buffer, nbytes, true, multibyte);
10554 SAFE_FREE ();
10556 if (! inhibit_message)
10557 message3_nolog (m);
10560 /* Log the message M to stderr. Log an empty line if M is not a string. */
10562 static void
10563 message_to_stderr (Lisp_Object m)
10565 if (noninteractive_need_newline)
10567 noninteractive_need_newline = false;
10568 fputc ('\n', stderr);
10570 if (STRINGP (m))
10572 Lisp_Object coding_system = Vlocale_coding_system;
10573 Lisp_Object s;
10575 if (!NILP (Vcoding_system_for_write))
10576 coding_system = Vcoding_system_for_write;
10577 if (!NILP (coding_system))
10578 s = code_convert_string_norecord (m, coding_system, true);
10579 else
10580 s = m;
10582 fwrite (SDATA (s), SBYTES (s), 1, stderr);
10584 if (!cursor_in_echo_area)
10585 fputc ('\n', stderr);
10586 fflush (stderr);
10589 /* The non-logging version of message3.
10590 This does not cancel echoing, because it is used for echoing.
10591 Perhaps we need to make a separate function for echoing
10592 and make this cancel echoing. */
10594 void
10595 message3_nolog (Lisp_Object m)
10597 struct frame *sf = SELECTED_FRAME ();
10599 if (FRAME_INITIAL_P (sf))
10600 message_to_stderr (m);
10601 /* Error messages get reported properly by cmd_error, so this must be just an
10602 informative message; if the frame hasn't really been initialized yet, just
10603 toss it. */
10604 else if (INTERACTIVE && sf->glyphs_initialized_p)
10606 /* Get the frame containing the mini-buffer
10607 that the selected frame is using. */
10608 Lisp_Object mini_window = FRAME_MINIBUF_WINDOW (sf);
10609 Lisp_Object frame = XWINDOW (mini_window)->frame;
10610 struct frame *f = XFRAME (frame);
10612 if (FRAME_VISIBLE_P (sf) && !FRAME_VISIBLE_P (f))
10613 Fmake_frame_visible (frame);
10615 if (STRINGP (m) && SCHARS (m) > 0)
10617 set_message (m);
10618 if (minibuffer_auto_raise)
10619 Fraise_frame (frame);
10620 /* Assume we are not echoing.
10621 (If we are, echo_now will override this.) */
10622 echo_message_buffer = Qnil;
10624 else
10625 clear_message (true, true);
10627 do_pending_window_change (false);
10628 echo_area_display (true);
10629 do_pending_window_change (false);
10630 if (FRAME_TERMINAL (f)->frame_up_to_date_hook)
10631 (*FRAME_TERMINAL (f)->frame_up_to_date_hook) (f);
10636 /* Display a null-terminated echo area message M. If M is 0, clear
10637 out any existing message, and let the mini-buffer text show through.
10639 The buffer M must continue to exist until after the echo area gets
10640 cleared or some other message gets displayed there. Do not pass
10641 text that is stored in a Lisp string. Do not pass text in a buffer
10642 that was alloca'd. */
10644 void
10645 message1 (const char *m)
10647 message3 (m ? build_unibyte_string (m) : Qnil);
10651 /* The non-logging counterpart of message1. */
10653 void
10654 message1_nolog (const char *m)
10656 message3_nolog (m ? build_unibyte_string (m) : Qnil);
10659 /* Display a message M which contains a single %s
10660 which gets replaced with STRING. */
10662 void
10663 message_with_string (const char *m, Lisp_Object string, bool log)
10665 CHECK_STRING (string);
10667 bool need_message;
10668 if (noninteractive)
10669 need_message = !!m;
10670 else if (!INTERACTIVE)
10671 need_message = false;
10672 else
10674 /* The frame whose minibuffer we're going to display the message on.
10675 It may be larger than the selected frame, so we need
10676 to use its buffer, not the selected frame's buffer. */
10677 Lisp_Object mini_window;
10678 struct frame *f, *sf = SELECTED_FRAME ();
10680 /* Get the frame containing the minibuffer
10681 that the selected frame is using. */
10682 mini_window = FRAME_MINIBUF_WINDOW (sf);
10683 f = XFRAME (WINDOW_FRAME (XWINDOW (mini_window)));
10685 /* Error messages get reported properly by cmd_error, so this must be
10686 just an informative message; if the frame hasn't really been
10687 initialized yet, just toss it. */
10688 need_message = f->glyphs_initialized_p;
10691 if (need_message)
10693 AUTO_STRING (fmt, m);
10694 Lisp_Object msg = CALLN (Fformat_message, fmt, string);
10696 if (noninteractive)
10697 message_to_stderr (msg);
10698 else
10700 if (log)
10701 message3 (msg);
10702 else
10703 message3_nolog (msg);
10705 /* Print should start at the beginning of the message
10706 buffer next time. */
10707 message_buf_print = false;
10713 /* Dump an informative message to the minibuf. If M is 0, clear out
10714 any existing message, and let the mini-buffer text show through.
10716 The message must be safe ASCII (because when Emacs is
10717 non-interactive the message is sent straight to stderr without
10718 encoding first) and the format must not contain ` or ' (because
10719 this function does not account for `text-quoting-style'). If your
10720 message and format do not fit into this category, convert your
10721 arguments to Lisp objects and use Fmessage instead. */
10723 static void ATTRIBUTE_FORMAT_PRINTF (1, 0)
10724 vmessage (const char *m, va_list ap)
10726 if (noninteractive)
10728 if (m)
10730 if (noninteractive_need_newline)
10731 putc ('\n', stderr);
10732 noninteractive_need_newline = false;
10733 vfprintf (stderr, m, ap);
10734 if (!cursor_in_echo_area)
10735 fprintf (stderr, "\n");
10736 fflush (stderr);
10739 else if (INTERACTIVE)
10741 /* The frame whose mini-buffer we're going to display the message
10742 on. It may be larger than the selected frame, so we need to
10743 use its buffer, not the selected frame's buffer. */
10744 Lisp_Object mini_window;
10745 struct frame *f, *sf = SELECTED_FRAME ();
10747 /* Get the frame containing the mini-buffer
10748 that the selected frame is using. */
10749 mini_window = FRAME_MINIBUF_WINDOW (sf);
10750 f = XFRAME (WINDOW_FRAME (XWINDOW (mini_window)));
10752 /* Error messages get reported properly by cmd_error, so this must be
10753 just an informative message; if the frame hasn't really been
10754 initialized yet, just toss it. */
10755 if (f->glyphs_initialized_p)
10757 if (m)
10759 ptrdiff_t len;
10760 ptrdiff_t maxsize = FRAME_MESSAGE_BUF_SIZE (f);
10761 USE_SAFE_ALLOCA;
10762 char *message_buf = SAFE_ALLOCA (maxsize + 1);
10764 len = doprnt (message_buf, maxsize, m, 0, ap);
10766 message3 (make_string (message_buf, len));
10767 SAFE_FREE ();
10769 else
10770 message1 (0);
10772 /* Print should start at the beginning of the message
10773 buffer next time. */
10774 message_buf_print = false;
10779 /* See vmessage for restrictions on the text of the message. */
10780 void
10781 message (const char *m, ...)
10783 va_list ap;
10784 va_start (ap, m);
10785 vmessage (m, ap);
10786 va_end (ap);
10790 /* Display the current message in the current mini-buffer. This is
10791 only called from error handlers in process.c, and is not time
10792 critical. */
10794 void
10795 update_echo_area (void)
10797 if (!NILP (echo_area_buffer[0]))
10799 Lisp_Object string;
10800 string = Fcurrent_message ();
10801 message3 (string);
10806 /* Make sure echo area buffers in `echo_buffers' are live.
10807 If they aren't, make new ones. */
10809 static void
10810 ensure_echo_area_buffers (void)
10812 for (int i = 0; i < 2; i++)
10813 if (!BUFFERP (echo_buffer[i])
10814 || !BUFFER_LIVE_P (XBUFFER (echo_buffer[i])))
10816 Lisp_Object old_buffer = echo_buffer[i];
10817 static char const name_fmt[] = " *Echo Area %d*";
10818 char name[sizeof name_fmt + INT_STRLEN_BOUND (int)];
10819 AUTO_STRING_WITH_LEN (lname, name, sprintf (name, name_fmt, i));
10820 echo_buffer[i] = Fget_buffer_create (lname);
10821 bset_truncate_lines (XBUFFER (echo_buffer[i]), Qnil);
10822 /* to force word wrap in echo area -
10823 it was decided to postpone this*/
10824 /* XBUFFER (echo_buffer[i])->word_wrap = Qt; */
10826 for (int j = 0; j < 2; j++)
10827 if (EQ (old_buffer, echo_area_buffer[j]))
10828 echo_area_buffer[j] = echo_buffer[i];
10833 /* Call FN with args A1..A2 with either the current or last displayed
10834 echo_area_buffer as current buffer.
10836 WHICH zero means use the current message buffer
10837 echo_area_buffer[0]. If that is nil, choose a suitable buffer
10838 from echo_buffer[] and clear it.
10840 WHICH > 0 means use echo_area_buffer[1]. If that is nil, choose a
10841 suitable buffer from echo_buffer[] and clear it.
10843 If WHICH < 0, set echo_area_buffer[1] to echo_area_buffer[0], so
10844 that the current message becomes the last displayed one, choose a
10845 suitable buffer for echo_area_buffer[0], and clear it.
10847 Value is what FN returns. */
10849 static bool
10850 with_echo_area_buffer (struct window *w, int which,
10851 bool (*fn) (ptrdiff_t, Lisp_Object),
10852 ptrdiff_t a1, Lisp_Object a2)
10854 Lisp_Object buffer;
10855 bool this_one, the_other, clear_buffer_p, rc;
10856 ptrdiff_t count = SPECPDL_INDEX ();
10858 /* If buffers aren't live, make new ones. */
10859 ensure_echo_area_buffers ();
10861 clear_buffer_p = false;
10863 if (which == 0)
10864 this_one = false, the_other = true;
10865 else if (which > 0)
10866 this_one = true, the_other = false;
10867 else
10869 this_one = false, the_other = true;
10870 clear_buffer_p = true;
10872 /* We need a fresh one in case the current echo buffer equals
10873 the one containing the last displayed echo area message. */
10874 if (!NILP (echo_area_buffer[this_one])
10875 && EQ (echo_area_buffer[this_one], echo_area_buffer[the_other]))
10876 echo_area_buffer[this_one] = Qnil;
10879 /* Choose a suitable buffer from echo_buffer[] if we don't
10880 have one. */
10881 if (NILP (echo_area_buffer[this_one]))
10883 echo_area_buffer[this_one]
10884 = (EQ (echo_area_buffer[the_other], echo_buffer[this_one])
10885 ? echo_buffer[the_other]
10886 : echo_buffer[this_one]);
10887 clear_buffer_p = true;
10890 buffer = echo_area_buffer[this_one];
10892 /* Don't get confused by reusing the buffer used for echoing
10893 for a different purpose. */
10894 if (echo_kboard == NULL && EQ (buffer, echo_message_buffer))
10895 cancel_echoing ();
10897 record_unwind_protect (unwind_with_echo_area_buffer,
10898 with_echo_area_buffer_unwind_data (w));
10900 /* Make the echo area buffer current. Note that for display
10901 purposes, it is not necessary that the displayed window's buffer
10902 == current_buffer, except for text property lookup. So, let's
10903 only set that buffer temporarily here without doing a full
10904 Fset_window_buffer. We must also change w->pointm, though,
10905 because otherwise an assertions in unshow_buffer fails, and Emacs
10906 aborts. */
10907 set_buffer_internal_1 (XBUFFER (buffer));
10908 if (w)
10910 wset_buffer (w, buffer);
10911 set_marker_both (w->pointm, buffer, BEG, BEG_BYTE);
10912 set_marker_both (w->old_pointm, buffer, BEG, BEG_BYTE);
10915 bset_undo_list (current_buffer, Qt);
10916 bset_read_only (current_buffer, Qnil);
10917 specbind (Qinhibit_read_only, Qt);
10918 specbind (Qinhibit_modification_hooks, Qt);
10920 if (clear_buffer_p && Z > BEG)
10921 del_range (BEG, Z);
10923 eassert (BEGV >= BEG);
10924 eassert (ZV <= Z && ZV >= BEGV);
10926 rc = fn (a1, a2);
10928 eassert (BEGV >= BEG);
10929 eassert (ZV <= Z && ZV >= BEGV);
10931 unbind_to (count, Qnil);
10932 return rc;
10936 /* Save state that should be preserved around the call to the function
10937 FN called in with_echo_area_buffer. */
10939 static Lisp_Object
10940 with_echo_area_buffer_unwind_data (struct window *w)
10942 int i = 0;
10943 Lisp_Object vector, tmp;
10945 /* Reduce consing by keeping one vector in
10946 Vwith_echo_area_save_vector. */
10947 vector = Vwith_echo_area_save_vector;
10948 Vwith_echo_area_save_vector = Qnil;
10950 if (NILP (vector))
10951 vector = Fmake_vector (make_number (11), Qnil);
10953 XSETBUFFER (tmp, current_buffer); ASET (vector, i, tmp); ++i;
10954 ASET (vector, i, Vdeactivate_mark); ++i;
10955 ASET (vector, i, make_number (windows_or_buffers_changed)); ++i;
10957 if (w)
10959 XSETWINDOW (tmp, w); ASET (vector, i, tmp); ++i;
10960 ASET (vector, i, w->contents); ++i;
10961 ASET (vector, i, make_number (marker_position (w->pointm))); ++i;
10962 ASET (vector, i, make_number (marker_byte_position (w->pointm))); ++i;
10963 ASET (vector, i, make_number (marker_position (w->old_pointm))); ++i;
10964 ASET (vector, i, make_number (marker_byte_position (w->old_pointm))); ++i;
10965 ASET (vector, i, make_number (marker_position (w->start))); ++i;
10966 ASET (vector, i, make_number (marker_byte_position (w->start))); ++i;
10968 else
10970 int end = i + 8;
10971 for (; i < end; ++i)
10972 ASET (vector, i, Qnil);
10975 eassert (i == ASIZE (vector));
10976 return vector;
10980 /* Restore global state from VECTOR which was created by
10981 with_echo_area_buffer_unwind_data. */
10983 static void
10984 unwind_with_echo_area_buffer (Lisp_Object vector)
10986 set_buffer_internal_1 (XBUFFER (AREF (vector, 0)));
10987 Vdeactivate_mark = AREF (vector, 1);
10988 windows_or_buffers_changed = XFASTINT (AREF (vector, 2));
10990 if (WINDOWP (AREF (vector, 3)))
10992 struct window *w;
10993 Lisp_Object buffer;
10995 w = XWINDOW (AREF (vector, 3));
10996 buffer = AREF (vector, 4);
10998 wset_buffer (w, buffer);
10999 set_marker_both (w->pointm, buffer,
11000 XFASTINT (AREF (vector, 5)),
11001 XFASTINT (AREF (vector, 6)));
11002 set_marker_both (w->old_pointm, buffer,
11003 XFASTINT (AREF (vector, 7)),
11004 XFASTINT (AREF (vector, 8)));
11005 set_marker_both (w->start, buffer,
11006 XFASTINT (AREF (vector, 9)),
11007 XFASTINT (AREF (vector, 10)));
11010 Vwith_echo_area_save_vector = vector;
11014 /* Set up the echo area for use by print functions. MULTIBYTE_P
11015 means we will print multibyte. */
11017 void
11018 setup_echo_area_for_printing (bool multibyte_p)
11020 /* If we can't find an echo area any more, exit. */
11021 if (! FRAME_LIVE_P (XFRAME (selected_frame)))
11022 Fkill_emacs (Qnil);
11024 ensure_echo_area_buffers ();
11026 if (!message_buf_print)
11028 /* A message has been output since the last time we printed.
11029 Choose a fresh echo area buffer. */
11030 if (EQ (echo_area_buffer[1], echo_buffer[0]))
11031 echo_area_buffer[0] = echo_buffer[1];
11032 else
11033 echo_area_buffer[0] = echo_buffer[0];
11035 /* Switch to that buffer and clear it. */
11036 set_buffer_internal (XBUFFER (echo_area_buffer[0]));
11037 bset_truncate_lines (current_buffer, Qnil);
11039 if (Z > BEG)
11041 ptrdiff_t count = SPECPDL_INDEX ();
11042 specbind (Qinhibit_read_only, Qt);
11043 /* Note that undo recording is always disabled. */
11044 del_range (BEG, Z);
11045 unbind_to (count, Qnil);
11047 TEMP_SET_PT_BOTH (BEG, BEG_BYTE);
11049 /* Set up the buffer for the multibyteness we need. We always
11050 set it to be multibyte, except when
11051 unibyte-display-via-language-environment is non-nil and the
11052 buffer from which we are called is unibyte, because in that
11053 case unibyte characters should not be displayed as octal
11054 escapes. */
11055 if (unibyte_display_via_language_environment
11056 && !multibyte_p
11057 && !NILP (BVAR (current_buffer, enable_multibyte_characters)))
11058 Fset_buffer_multibyte (Qnil);
11059 else if (NILP (BVAR (current_buffer, enable_multibyte_characters)))
11060 Fset_buffer_multibyte (Qt);
11062 /* Raise the frame containing the echo area. */
11063 if (minibuffer_auto_raise)
11065 struct frame *sf = SELECTED_FRAME ();
11066 Lisp_Object mini_window;
11067 mini_window = FRAME_MINIBUF_WINDOW (sf);
11068 Fraise_frame (WINDOW_FRAME (XWINDOW (mini_window)));
11071 message_log_maybe_newline ();
11072 message_buf_print = true;
11074 else
11076 if (NILP (echo_area_buffer[0]))
11078 if (EQ (echo_area_buffer[1], echo_buffer[0]))
11079 echo_area_buffer[0] = echo_buffer[1];
11080 else
11081 echo_area_buffer[0] = echo_buffer[0];
11084 if (current_buffer != XBUFFER (echo_area_buffer[0]))
11086 /* Someone switched buffers between print requests. */
11087 set_buffer_internal (XBUFFER (echo_area_buffer[0]));
11088 bset_truncate_lines (current_buffer, Qnil);
11094 /* Display an echo area message in window W. Value is true if W's
11095 height is changed. If display_last_displayed_message_p,
11096 display the message that was last displayed, otherwise
11097 display the current message. */
11099 static bool
11100 display_echo_area (struct window *w)
11102 bool no_message_p, window_height_changed_p;
11104 /* Temporarily disable garbage collections while displaying the echo
11105 area. This is done because a GC can print a message itself.
11106 That message would modify the echo area buffer's contents while a
11107 redisplay of the buffer is going on, and seriously confuse
11108 redisplay. */
11109 ptrdiff_t count = inhibit_garbage_collection ();
11111 /* If there is no message, we must call display_echo_area_1
11112 nevertheless because it resizes the window. But we will have to
11113 reset the echo_area_buffer in question to nil at the end because
11114 with_echo_area_buffer will sets it to an empty buffer. */
11115 bool i = display_last_displayed_message_p;
11116 /* According to the C99, C11 and C++11 standards, the integral value
11117 of a "bool" is always 0 or 1, so this array access is safe here,
11118 if oddly typed. */
11119 no_message_p = NILP (echo_area_buffer[i]);
11121 window_height_changed_p
11122 = with_echo_area_buffer (w, display_last_displayed_message_p,
11123 display_echo_area_1,
11124 (intptr_t) w, Qnil);
11126 if (no_message_p)
11127 echo_area_buffer[i] = Qnil;
11129 unbind_to (count, Qnil);
11130 return window_height_changed_p;
11134 /* Helper for display_echo_area. Display the current buffer which
11135 contains the current echo area message in window W, a mini-window,
11136 a pointer to which is passed in A1. A2..A4 are currently not used.
11137 Change the height of W so that all of the message is displayed.
11138 Value is true if height of W was changed. */
11140 static bool
11141 display_echo_area_1 (ptrdiff_t a1, Lisp_Object a2)
11143 intptr_t i1 = a1;
11144 struct window *w = (struct window *) i1;
11145 Lisp_Object window;
11146 struct text_pos start;
11148 /* We are about to enter redisplay without going through
11149 redisplay_internal, so we need to forget these faces by hand
11150 here. */
11151 forget_escape_and_glyphless_faces ();
11153 /* Do this before displaying, so that we have a large enough glyph
11154 matrix for the display. If we can't get enough space for the
11155 whole text, display the last N lines. That works by setting w->start. */
11156 bool window_height_changed_p = resize_mini_window (w, false);
11158 /* Use the starting position chosen by resize_mini_window. */
11159 SET_TEXT_POS_FROM_MARKER (start, w->start);
11161 /* Display. */
11162 clear_glyph_matrix (w->desired_matrix);
11163 XSETWINDOW (window, w);
11164 try_window (window, start, 0);
11166 return window_height_changed_p;
11170 /* Resize the echo area window to exactly the size needed for the
11171 currently displayed message, if there is one. If a mini-buffer
11172 is active, don't shrink it. */
11174 void
11175 resize_echo_area_exactly (void)
11177 if (BUFFERP (echo_area_buffer[0])
11178 && WINDOWP (echo_area_window))
11180 struct window *w = XWINDOW (echo_area_window);
11181 Lisp_Object resize_exactly = (minibuf_level == 0 ? Qt : Qnil);
11182 bool resized_p = with_echo_area_buffer (w, 0, resize_mini_window_1,
11183 (intptr_t) w, resize_exactly);
11184 if (resized_p)
11186 windows_or_buffers_changed = 42;
11187 update_mode_lines = 30;
11188 redisplay_internal ();
11194 /* Callback function for with_echo_area_buffer, when used from
11195 resize_echo_area_exactly. A1 contains a pointer to the window to
11196 resize, EXACTLY non-nil means resize the mini-window exactly to the
11197 size of the text displayed. A3 and A4 are not used. Value is what
11198 resize_mini_window returns. */
11200 static bool
11201 resize_mini_window_1 (ptrdiff_t a1, Lisp_Object exactly)
11203 intptr_t i1 = a1;
11204 return resize_mini_window ((struct window *) i1, !NILP (exactly));
11208 /* Resize mini-window W to fit the size of its contents. EXACT_P
11209 means size the window exactly to the size needed. Otherwise, it's
11210 only enlarged until W's buffer is empty.
11212 Set W->start to the right place to begin display. If the whole
11213 contents fit, start at the beginning. Otherwise, start so as
11214 to make the end of the contents appear. This is particularly
11215 important for y-or-n-p, but seems desirable generally.
11217 Value is true if the window height has been changed. */
11219 bool
11220 resize_mini_window (struct window *w, bool exact_p)
11222 struct frame *f = XFRAME (w->frame);
11223 bool window_height_changed_p = false;
11225 eassert (MINI_WINDOW_P (w));
11227 /* By default, start display at the beginning. */
11228 set_marker_both (w->start, w->contents,
11229 BUF_BEGV (XBUFFER (w->contents)),
11230 BUF_BEGV_BYTE (XBUFFER (w->contents)));
11232 /* Don't resize windows while redisplaying a window; it would
11233 confuse redisplay functions when the size of the window they are
11234 displaying changes from under them. Such a resizing can happen,
11235 for instance, when which-func prints a long message while
11236 we are running fontification-functions. We're running these
11237 functions with safe_call which binds inhibit-redisplay to t. */
11238 if (!NILP (Vinhibit_redisplay))
11239 return false;
11241 /* Nil means don't try to resize. */
11242 if (NILP (Vresize_mini_windows)
11243 || (FRAME_X_P (f) && FRAME_X_OUTPUT (f) == NULL))
11244 return false;
11246 if (!FRAME_MINIBUF_ONLY_P (f))
11248 struct it it;
11249 int total_height = (WINDOW_PIXEL_HEIGHT (XWINDOW (FRAME_ROOT_WINDOW (f)))
11250 + WINDOW_PIXEL_HEIGHT (w));
11251 int unit = FRAME_LINE_HEIGHT (f);
11252 int height, max_height;
11253 struct text_pos start;
11254 struct buffer *old_current_buffer = NULL;
11256 if (current_buffer != XBUFFER (w->contents))
11258 old_current_buffer = current_buffer;
11259 set_buffer_internal (XBUFFER (w->contents));
11262 init_iterator (&it, w, BEGV, BEGV_BYTE, NULL, DEFAULT_FACE_ID);
11264 /* Compute the max. number of lines specified by the user. */
11265 if (FLOATP (Vmax_mini_window_height))
11266 max_height = XFLOAT_DATA (Vmax_mini_window_height) * total_height;
11267 else if (INTEGERP (Vmax_mini_window_height))
11268 max_height = XINT (Vmax_mini_window_height) * unit;
11269 else
11270 max_height = total_height / 4;
11272 /* Correct that max. height if it's bogus. */
11273 max_height = clip_to_bounds (unit, max_height, total_height);
11275 /* Find out the height of the text in the window. */
11276 if (it.line_wrap == TRUNCATE)
11277 height = unit;
11278 else
11280 last_height = 0;
11281 move_it_to (&it, ZV, -1, -1, -1, MOVE_TO_POS);
11282 if (it.max_ascent == 0 && it.max_descent == 0)
11283 height = it.current_y + last_height;
11284 else
11285 height = it.current_y + it.max_ascent + it.max_descent;
11286 height -= min (it.extra_line_spacing, it.max_extra_line_spacing);
11289 /* Compute a suitable window start. */
11290 if (height > max_height)
11292 height = (max_height / unit) * unit;
11293 init_iterator (&it, w, ZV, ZV_BYTE, NULL, DEFAULT_FACE_ID);
11294 move_it_vertically_backward (&it, height - unit);
11295 start = it.current.pos;
11297 else
11298 SET_TEXT_POS (start, BEGV, BEGV_BYTE);
11299 SET_MARKER_FROM_TEXT_POS (w->start, start);
11301 if (EQ (Vresize_mini_windows, Qgrow_only))
11303 /* Let it grow only, until we display an empty message, in which
11304 case the window shrinks again. */
11305 if (height > WINDOW_PIXEL_HEIGHT (w))
11307 int old_height = WINDOW_PIXEL_HEIGHT (w);
11309 FRAME_WINDOWS_FROZEN (f) = true;
11310 grow_mini_window (w, height - WINDOW_PIXEL_HEIGHT (w), true);
11311 window_height_changed_p = WINDOW_PIXEL_HEIGHT (w) != old_height;
11313 else if (height < WINDOW_PIXEL_HEIGHT (w)
11314 && (exact_p || BEGV == ZV))
11316 int old_height = WINDOW_PIXEL_HEIGHT (w);
11318 FRAME_WINDOWS_FROZEN (f) = false;
11319 shrink_mini_window (w, true);
11320 window_height_changed_p = WINDOW_PIXEL_HEIGHT (w) != old_height;
11323 else
11325 /* Always resize to exact size needed. */
11326 if (height > WINDOW_PIXEL_HEIGHT (w))
11328 int old_height = WINDOW_PIXEL_HEIGHT (w);
11330 FRAME_WINDOWS_FROZEN (f) = true;
11331 grow_mini_window (w, height - WINDOW_PIXEL_HEIGHT (w), true);
11332 window_height_changed_p = WINDOW_PIXEL_HEIGHT (w) != old_height;
11334 else if (height < WINDOW_PIXEL_HEIGHT (w))
11336 int old_height = WINDOW_PIXEL_HEIGHT (w);
11338 FRAME_WINDOWS_FROZEN (f) = false;
11339 shrink_mini_window (w, true);
11341 if (height)
11343 FRAME_WINDOWS_FROZEN (f) = true;
11344 grow_mini_window (w, height - WINDOW_PIXEL_HEIGHT (w), true);
11347 window_height_changed_p = WINDOW_PIXEL_HEIGHT (w) != old_height;
11351 if (old_current_buffer)
11352 set_buffer_internal (old_current_buffer);
11355 return window_height_changed_p;
11359 /* Value is the current message, a string, or nil if there is no
11360 current message. */
11362 Lisp_Object
11363 current_message (void)
11365 Lisp_Object msg;
11367 if (!BUFFERP (echo_area_buffer[0]))
11368 msg = Qnil;
11369 else
11371 with_echo_area_buffer (0, 0, current_message_1,
11372 (intptr_t) &msg, Qnil);
11373 if (NILP (msg))
11374 echo_area_buffer[0] = Qnil;
11377 return msg;
11381 static bool
11382 current_message_1 (ptrdiff_t a1, Lisp_Object a2)
11384 intptr_t i1 = a1;
11385 Lisp_Object *msg = (Lisp_Object *) i1;
11387 if (Z > BEG)
11388 *msg = make_buffer_string (BEG, Z, true);
11389 else
11390 *msg = Qnil;
11391 return false;
11395 /* Push the current message on Vmessage_stack for later restoration
11396 by restore_message. Value is true if the current message isn't
11397 empty. This is a relatively infrequent operation, so it's not
11398 worth optimizing. */
11400 bool
11401 push_message (void)
11403 Lisp_Object msg = current_message ();
11404 Vmessage_stack = Fcons (msg, Vmessage_stack);
11405 return STRINGP (msg);
11409 /* Restore message display from the top of Vmessage_stack. */
11411 void
11412 restore_message (void)
11414 eassert (CONSP (Vmessage_stack));
11415 message3_nolog (XCAR (Vmessage_stack));
11419 /* Handler for unwind-protect calling pop_message. */
11421 void
11422 pop_message_unwind (void)
11424 /* Pop the top-most entry off Vmessage_stack. */
11425 eassert (CONSP (Vmessage_stack));
11426 Vmessage_stack = XCDR (Vmessage_stack);
11430 /* Check that Vmessage_stack is nil. Called from emacs.c when Emacs
11431 exits. If the stack is not empty, we have a missing pop_message
11432 somewhere. */
11434 void
11435 check_message_stack (void)
11437 if (!NILP (Vmessage_stack))
11438 emacs_abort ();
11442 /* Truncate to NCHARS what will be displayed in the echo area the next
11443 time we display it---but don't redisplay it now. */
11445 void
11446 truncate_echo_area (ptrdiff_t nchars)
11448 if (nchars == 0)
11449 echo_area_buffer[0] = Qnil;
11450 else if (!noninteractive
11451 && INTERACTIVE
11452 && !NILP (echo_area_buffer[0]))
11454 struct frame *sf = SELECTED_FRAME ();
11455 /* Error messages get reported properly by cmd_error, so this must be
11456 just an informative message; if the frame hasn't really been
11457 initialized yet, just toss it. */
11458 if (sf->glyphs_initialized_p)
11459 with_echo_area_buffer (0, 0, truncate_message_1, nchars, Qnil);
11464 /* Helper function for truncate_echo_area. Truncate the current
11465 message to at most NCHARS characters. */
11467 static bool
11468 truncate_message_1 (ptrdiff_t nchars, Lisp_Object a2)
11470 if (BEG + nchars < Z)
11471 del_range (BEG + nchars, Z);
11472 if (Z == BEG)
11473 echo_area_buffer[0] = Qnil;
11474 return false;
11477 /* Set the current message to STRING. */
11479 static void
11480 set_message (Lisp_Object string)
11482 eassert (STRINGP (string));
11484 message_enable_multibyte = STRING_MULTIBYTE (string);
11486 with_echo_area_buffer (0, -1, set_message_1, 0, string);
11487 message_buf_print = false;
11488 help_echo_showing_p = false;
11490 if (STRINGP (Vdebug_on_message)
11491 && STRINGP (string)
11492 && fast_string_match (Vdebug_on_message, string) >= 0)
11493 call_debugger (list2 (Qerror, string));
11497 /* Helper function for set_message. First argument is ignored and second
11498 argument has the same meaning as for set_message.
11499 This function is called with the echo area buffer being current. */
11501 static bool
11502 set_message_1 (ptrdiff_t a1, Lisp_Object string)
11504 eassert (STRINGP (string));
11506 /* Change multibyteness of the echo buffer appropriately. We always
11507 set it to be multibyte, except when
11508 unibyte-display-via-language-environment is non-nil and the
11509 string to display is unibyte, because in that case unibyte
11510 characters should not be displayed as octal escapes. */
11511 if (!message_enable_multibyte
11512 && unibyte_display_via_language_environment
11513 && !NILP (BVAR (current_buffer, enable_multibyte_characters)))
11514 Fset_buffer_multibyte (Qnil);
11515 else if (NILP (BVAR (current_buffer, enable_multibyte_characters)))
11516 Fset_buffer_multibyte (Qt);
11518 bset_truncate_lines (current_buffer, message_truncate_lines ? Qt : Qnil);
11519 if (!NILP (BVAR (current_buffer, bidi_display_reordering)))
11520 bset_bidi_paragraph_direction (current_buffer, Qleft_to_right);
11522 /* Insert new message at BEG. */
11523 TEMP_SET_PT_BOTH (BEG, BEG_BYTE);
11525 /* This function takes care of single/multibyte conversion.
11526 We just have to ensure that the echo area buffer has the right
11527 setting of enable_multibyte_characters. */
11528 insert_from_string (string, 0, 0, SCHARS (string), SBYTES (string), true);
11530 return false;
11534 /* Clear messages. CURRENT_P means clear the current message.
11535 LAST_DISPLAYED_P means clear the message last displayed. */
11537 void
11538 clear_message (bool current_p, bool last_displayed_p)
11540 if (current_p)
11542 echo_area_buffer[0] = Qnil;
11543 message_cleared_p = true;
11546 if (last_displayed_p)
11547 echo_area_buffer[1] = Qnil;
11549 message_buf_print = false;
11552 /* Clear garbaged frames.
11554 This function is used where the old redisplay called
11555 redraw_garbaged_frames which in turn called redraw_frame which in
11556 turn called clear_frame. The call to clear_frame was a source of
11557 flickering. I believe a clear_frame is not necessary. It should
11558 suffice in the new redisplay to invalidate all current matrices,
11559 and ensure a complete redisplay of all windows. */
11561 static void
11562 clear_garbaged_frames (void)
11564 if (frame_garbaged)
11566 Lisp_Object tail, frame;
11567 struct frame *sf = SELECTED_FRAME ();
11569 FOR_EACH_FRAME (tail, frame)
11571 struct frame *f = XFRAME (frame);
11573 if (FRAME_VISIBLE_P (f) && FRAME_GARBAGED_P (f))
11575 if (f->resized_p
11576 /* It makes no sense to redraw a non-selected TTY
11577 frame, since that will actually clear the
11578 selected frame, and might leave the selected
11579 frame with corrupted display, if it happens not
11580 to be marked garbaged. */
11581 && !(f != sf && (FRAME_TERMCAP_P (f) || FRAME_MSDOS_P (f))))
11582 redraw_frame (f);
11583 else
11584 clear_current_matrices (f);
11586 #if defined (HAVE_WINDOW_SYSTEM) && !defined (HAVE_NS)
11587 x_clear_under_internal_border (f);
11588 #endif /* HAVE_WINDOW_SYSTEM && !HAVE_NS */
11590 fset_redisplay (f);
11591 f->garbaged = false;
11592 f->resized_p = false;
11596 frame_garbaged = false;
11601 /* Redisplay the echo area of the selected frame. If UPDATE_FRAME_P, update
11602 selected_frame. */
11604 static void
11605 echo_area_display (bool update_frame_p)
11607 Lisp_Object mini_window;
11608 struct window *w;
11609 struct frame *f;
11610 bool window_height_changed_p = false;
11611 struct frame *sf = SELECTED_FRAME ();
11613 mini_window = FRAME_MINIBUF_WINDOW (sf);
11614 if (NILP (mini_window))
11615 return;
11617 w = XWINDOW (mini_window);
11618 f = XFRAME (WINDOW_FRAME (w));
11620 /* Don't display if frame is invisible or not yet initialized. */
11621 if (!FRAME_VISIBLE_P (f) || !f->glyphs_initialized_p)
11622 return;
11624 #ifdef HAVE_WINDOW_SYSTEM
11625 /* When Emacs starts, selected_frame may be the initial terminal
11626 frame. If we let this through, a message would be displayed on
11627 the terminal. */
11628 if (FRAME_INITIAL_P (XFRAME (selected_frame)))
11629 return;
11630 #endif /* HAVE_WINDOW_SYSTEM */
11632 /* Redraw garbaged frames. */
11633 clear_garbaged_frames ();
11635 if (!NILP (echo_area_buffer[0]) || minibuf_level == 0)
11637 echo_area_window = mini_window;
11638 window_height_changed_p = display_echo_area (w);
11639 w->must_be_updated_p = true;
11641 /* Update the display, unless called from redisplay_internal.
11642 Also don't update the screen during redisplay itself. The
11643 update will happen at the end of redisplay, and an update
11644 here could cause confusion. */
11645 if (update_frame_p && !redisplaying_p)
11647 int n = 0;
11649 /* If the display update has been interrupted by pending
11650 input, update mode lines in the frame. Due to the
11651 pending input, it might have been that redisplay hasn't
11652 been called, so that mode lines above the echo area are
11653 garbaged. This looks odd, so we prevent it here. */
11654 if (!display_completed)
11656 n = redisplay_mode_lines (FRAME_ROOT_WINDOW (f), false);
11658 #if defined (HAVE_WINDOW_SYSTEM) && !defined (HAVE_NS)
11659 x_clear_under_internal_border (f);
11660 #endif /* HAVE_WINDOW_SYSTEM && !HAVE_NS */
11664 if (window_height_changed_p
11665 /* Don't do this if Emacs is shutting down. Redisplay
11666 needs to run hooks. */
11667 && !NILP (Vrun_hooks))
11669 /* Must update other windows. Likewise as in other
11670 cases, don't let this update be interrupted by
11671 pending input. */
11672 ptrdiff_t count = SPECPDL_INDEX ();
11673 specbind (Qredisplay_dont_pause, Qt);
11674 fset_redisplay (f);
11675 redisplay_internal ();
11676 unbind_to (count, Qnil);
11678 else if (FRAME_WINDOW_P (f) && n == 0)
11680 /* Window configuration is the same as before.
11681 Can do with a display update of the echo area,
11682 unless we displayed some mode lines. */
11683 update_single_window (w);
11684 flush_frame (f);
11686 else
11687 update_frame (f, true, true);
11689 /* If cursor is in the echo area, make sure that the next
11690 redisplay displays the minibuffer, so that the cursor will
11691 be replaced with what the minibuffer wants. */
11692 if (cursor_in_echo_area)
11693 wset_redisplay (XWINDOW (mini_window));
11696 else if (!EQ (mini_window, selected_window))
11697 wset_redisplay (XWINDOW (mini_window));
11699 /* Last displayed message is now the current message. */
11700 echo_area_buffer[1] = echo_area_buffer[0];
11701 /* Inform read_char that we're not echoing. */
11702 echo_message_buffer = Qnil;
11704 /* Prevent redisplay optimization in redisplay_internal by resetting
11705 this_line_start_pos. This is done because the mini-buffer now
11706 displays the message instead of its buffer text. */
11707 if (EQ (mini_window, selected_window))
11708 CHARPOS (this_line_start_pos) = 0;
11710 if (window_height_changed_p)
11712 fset_redisplay (f);
11714 /* If window configuration was changed, frames may have been
11715 marked garbaged. Clear them or we will experience
11716 surprises wrt scrolling.
11717 FIXME: How/why/when? */
11718 clear_garbaged_frames ();
11722 /* True if W's buffer was changed but not saved. */
11724 static bool
11725 window_buffer_changed (struct window *w)
11727 struct buffer *b = XBUFFER (w->contents);
11729 eassert (BUFFER_LIVE_P (b));
11731 return (BUF_SAVE_MODIFF (b) < BUF_MODIFF (b)) != w->last_had_star;
11734 /* True if W has %c or %C in its mode line and mode line should be updated. */
11736 static bool
11737 mode_line_update_needed (struct window *w)
11739 return (w->column_number_displayed != -1
11740 && !(PT == w->last_point && !window_outdated (w))
11741 && (w->column_number_displayed != current_column ()));
11744 /* True if window start of W is frozen and may not be changed during
11745 redisplay. */
11747 static bool
11748 window_frozen_p (struct window *w)
11750 if (FRAME_WINDOWS_FROZEN (XFRAME (WINDOW_FRAME (w))))
11752 Lisp_Object window;
11754 XSETWINDOW (window, w);
11755 if (MINI_WINDOW_P (w))
11756 return false;
11757 else if (EQ (window, selected_window))
11758 return false;
11759 else if (MINI_WINDOW_P (XWINDOW (selected_window))
11760 && EQ (window, Vminibuf_scroll_window))
11761 /* This special window can't be frozen too. */
11762 return false;
11763 else
11764 return true;
11766 return false;
11769 /***********************************************************************
11770 Mode Lines and Frame Titles
11771 ***********************************************************************/
11773 /* A buffer for constructing non-propertized mode-line strings and
11774 frame titles in it; allocated from the heap in init_xdisp and
11775 resized as needed in store_mode_line_noprop_char. */
11777 static char *mode_line_noprop_buf;
11779 /* The buffer's end, and a current output position in it. */
11781 static char *mode_line_noprop_buf_end;
11782 static char *mode_line_noprop_ptr;
11784 #define MODE_LINE_NOPROP_LEN(start) \
11785 ((mode_line_noprop_ptr - mode_line_noprop_buf) - start)
11787 static enum {
11788 MODE_LINE_DISPLAY = 0,
11789 MODE_LINE_TITLE,
11790 MODE_LINE_NOPROP,
11791 MODE_LINE_STRING
11792 } mode_line_target;
11794 /* Alist that caches the results of :propertize.
11795 Each element is (PROPERTIZED-STRING . PROPERTY-LIST). */
11796 static Lisp_Object mode_line_proptrans_alist;
11798 /* List of strings making up the mode-line. */
11799 static Lisp_Object mode_line_string_list;
11801 /* Base face property when building propertized mode line string. */
11802 static Lisp_Object mode_line_string_face;
11803 static Lisp_Object mode_line_string_face_prop;
11806 /* Unwind data for mode line strings */
11808 static Lisp_Object Vmode_line_unwind_vector;
11810 static Lisp_Object
11811 format_mode_line_unwind_data (struct frame *target_frame,
11812 struct buffer *obuf,
11813 Lisp_Object owin,
11814 bool save_proptrans)
11816 Lisp_Object vector, tmp;
11818 /* Reduce consing by keeping one vector in
11819 Vwith_echo_area_save_vector. */
11820 vector = Vmode_line_unwind_vector;
11821 Vmode_line_unwind_vector = Qnil;
11823 if (NILP (vector))
11824 vector = Fmake_vector (make_number (10), Qnil);
11826 ASET (vector, 0, make_number (mode_line_target));
11827 ASET (vector, 1, make_number (MODE_LINE_NOPROP_LEN (0)));
11828 ASET (vector, 2, mode_line_string_list);
11829 ASET (vector, 3, save_proptrans ? mode_line_proptrans_alist : Qt);
11830 ASET (vector, 4, mode_line_string_face);
11831 ASET (vector, 5, mode_line_string_face_prop);
11833 if (obuf)
11834 XSETBUFFER (tmp, obuf);
11835 else
11836 tmp = Qnil;
11837 ASET (vector, 6, tmp);
11838 ASET (vector, 7, owin);
11839 if (target_frame)
11841 /* Similarly to `with-selected-window', if the operation selects
11842 a window on another frame, we must restore that frame's
11843 selected window, and (for a tty) the top-frame. */
11844 ASET (vector, 8, target_frame->selected_window);
11845 if (FRAME_TERMCAP_P (target_frame))
11846 ASET (vector, 9, FRAME_TTY (target_frame)->top_frame);
11849 return vector;
11852 static void
11853 unwind_format_mode_line (Lisp_Object vector)
11855 Lisp_Object old_window = AREF (vector, 7);
11856 Lisp_Object target_frame_window = AREF (vector, 8);
11857 Lisp_Object old_top_frame = AREF (vector, 9);
11859 mode_line_target = XINT (AREF (vector, 0));
11860 mode_line_noprop_ptr = mode_line_noprop_buf + XINT (AREF (vector, 1));
11861 mode_line_string_list = AREF (vector, 2);
11862 if (! EQ (AREF (vector, 3), Qt))
11863 mode_line_proptrans_alist = AREF (vector, 3);
11864 mode_line_string_face = AREF (vector, 4);
11865 mode_line_string_face_prop = AREF (vector, 5);
11867 /* Select window before buffer, since it may change the buffer. */
11868 if (!NILP (old_window))
11870 /* If the operation that we are unwinding had selected a window
11871 on a different frame, reset its frame-selected-window. For a
11872 text terminal, reset its top-frame if necessary. */
11873 if (!NILP (target_frame_window))
11875 Lisp_Object frame
11876 = WINDOW_FRAME (XWINDOW (target_frame_window));
11878 if (!EQ (frame, WINDOW_FRAME (XWINDOW (old_window))))
11879 Fselect_window (target_frame_window, Qt);
11881 if (!NILP (old_top_frame) && !EQ (old_top_frame, frame))
11882 Fselect_frame (old_top_frame, Qt);
11885 Fselect_window (old_window, Qt);
11888 if (!NILP (AREF (vector, 6)))
11890 set_buffer_internal_1 (XBUFFER (AREF (vector, 6)));
11891 ASET (vector, 6, Qnil);
11894 Vmode_line_unwind_vector = vector;
11898 /* Store a single character C for the frame title in mode_line_noprop_buf.
11899 Re-allocate mode_line_noprop_buf if necessary. */
11901 static void
11902 store_mode_line_noprop_char (char c)
11904 /* If output position has reached the end of the allocated buffer,
11905 increase the buffer's size. */
11906 if (mode_line_noprop_ptr == mode_line_noprop_buf_end)
11908 ptrdiff_t len = MODE_LINE_NOPROP_LEN (0);
11909 ptrdiff_t size = len;
11910 mode_line_noprop_buf =
11911 xpalloc (mode_line_noprop_buf, &size, 1, STRING_BYTES_BOUND, 1);
11912 mode_line_noprop_buf_end = mode_line_noprop_buf + size;
11913 mode_line_noprop_ptr = mode_line_noprop_buf + len;
11916 *mode_line_noprop_ptr++ = c;
11920 /* Store part of a frame title in mode_line_noprop_buf, beginning at
11921 mode_line_noprop_ptr. STRING is the string to store. Do not copy
11922 characters that yield more columns than PRECISION; PRECISION <= 0
11923 means copy the whole string. Pad with spaces until FIELD_WIDTH
11924 number of characters have been copied; FIELD_WIDTH <= 0 means don't
11925 pad. Called from display_mode_element when it is used to build a
11926 frame title. */
11928 static int
11929 store_mode_line_noprop (const char *string, int field_width, int precision)
11931 const unsigned char *str = (const unsigned char *) string;
11932 int n = 0;
11933 ptrdiff_t dummy, nbytes;
11935 /* Copy at most PRECISION chars from STR. */
11936 nbytes = strlen (string);
11937 n += c_string_width (str, nbytes, precision, &dummy, &nbytes);
11938 while (nbytes--)
11939 store_mode_line_noprop_char (*str++);
11941 /* Fill up with spaces until FIELD_WIDTH reached. */
11942 while (field_width > 0
11943 && n < field_width)
11945 store_mode_line_noprop_char (' ');
11946 ++n;
11949 return n;
11952 /***********************************************************************
11953 Frame Titles
11954 ***********************************************************************/
11956 #ifdef HAVE_WINDOW_SYSTEM
11958 /* Set the title of FRAME, if it has changed. The title format is
11959 Vicon_title_format if FRAME is iconified, otherwise it is
11960 frame_title_format. */
11962 static void
11963 x_consider_frame_title (Lisp_Object frame)
11965 struct frame *f = XFRAME (frame);
11967 if ((FRAME_WINDOW_P (f)
11968 || FRAME_MINIBUF_ONLY_P (f)
11969 || f->explicit_name)
11970 && !FRAME_TOOLTIP_P (f))
11972 /* Do we have more than one visible frame on this X display? */
11973 Lisp_Object tail, other_frame, fmt;
11974 ptrdiff_t title_start;
11975 char *title;
11976 ptrdiff_t len;
11977 struct it it;
11978 ptrdiff_t count = SPECPDL_INDEX ();
11980 FOR_EACH_FRAME (tail, other_frame)
11982 struct frame *tf = XFRAME (other_frame);
11984 if (tf != f
11985 && FRAME_KBOARD (tf) == FRAME_KBOARD (f)
11986 && !FRAME_MINIBUF_ONLY_P (tf)
11987 && !FRAME_PARENT_FRAME (tf)
11988 && !FRAME_TOOLTIP_P (tf)
11989 && (FRAME_VISIBLE_P (tf) || FRAME_ICONIFIED_P (tf)))
11990 break;
11993 /* Set global variable indicating that multiple frames exist. */
11994 multiple_frames = CONSP (tail);
11996 /* Switch to the buffer of selected window of the frame. Set up
11997 mode_line_target so that display_mode_element will output into
11998 mode_line_noprop_buf; then display the title. */
11999 record_unwind_protect (unwind_format_mode_line,
12000 format_mode_line_unwind_data
12001 (f, current_buffer, selected_window, false));
12002 /* select-frame calls resize_mini_window, which could resize the
12003 mini-window and by that undo the effect of this redisplay
12004 cycle wrt minibuffer and echo-area display. Binding
12005 inhibit-redisplay to t makes the call to resize_mini_window a
12006 no-op, thus avoiding the adverse side effects. */
12007 specbind (Qinhibit_redisplay, Qt);
12009 Fselect_window (f->selected_window, Qt);
12010 set_buffer_internal_1
12011 (XBUFFER (XWINDOW (f->selected_window)->contents));
12012 fmt = FRAME_ICONIFIED_P (f) ? Vicon_title_format : Vframe_title_format;
12014 mode_line_target = MODE_LINE_TITLE;
12015 title_start = MODE_LINE_NOPROP_LEN (0);
12016 init_iterator (&it, XWINDOW (f->selected_window), -1, -1,
12017 NULL, DEFAULT_FACE_ID);
12018 display_mode_element (&it, 0, -1, -1, fmt, Qnil, false);
12019 len = MODE_LINE_NOPROP_LEN (title_start);
12020 title = mode_line_noprop_buf + title_start;
12021 unbind_to (count, Qnil);
12023 /* Set the title only if it's changed. This avoids consing in
12024 the common case where it hasn't. (If it turns out that we've
12025 already wasted too much time by walking through the list with
12026 display_mode_element, then we might need to optimize at a
12027 higher level than this.) */
12028 if (! STRINGP (f->name)
12029 || SBYTES (f->name) != len
12030 || memcmp (title, SDATA (f->name), len) != 0)
12031 x_implicitly_set_name (f, make_string (title, len), Qnil);
12035 #endif /* not HAVE_WINDOW_SYSTEM */
12038 /***********************************************************************
12039 Menu Bars
12040 ***********************************************************************/
12042 /* True if we will not redisplay all visible windows. */
12043 #define REDISPLAY_SOME_P() \
12044 ((windows_or_buffers_changed == 0 \
12045 || windows_or_buffers_changed == REDISPLAY_SOME) \
12046 && (update_mode_lines == 0 \
12047 || update_mode_lines == REDISPLAY_SOME))
12049 /* Prepare for redisplay by updating menu-bar item lists when
12050 appropriate. This can call eval. */
12052 static void
12053 prepare_menu_bars (void)
12055 bool all_windows = windows_or_buffers_changed || update_mode_lines;
12056 bool some_windows = REDISPLAY_SOME_P ();
12058 if (FUNCTIONP (Vpre_redisplay_function))
12060 Lisp_Object windows = all_windows ? Qt : Qnil;
12061 if (all_windows && some_windows)
12063 Lisp_Object ws = window_list ();
12064 for (windows = Qnil; CONSP (ws); ws = XCDR (ws))
12066 Lisp_Object this = XCAR (ws);
12067 struct window *w = XWINDOW (this);
12068 if (w->redisplay
12069 || XFRAME (w->frame)->redisplay
12070 || XBUFFER (w->contents)->text->redisplay)
12072 windows = Fcons (this, windows);
12076 safe__call1 (true, Vpre_redisplay_function, windows);
12079 /* Update all frame titles based on their buffer names, etc. We do
12080 this before the menu bars so that the buffer-menu will show the
12081 up-to-date frame titles. */
12082 #ifdef HAVE_WINDOW_SYSTEM
12083 if (all_windows)
12085 Lisp_Object tail, frame;
12087 FOR_EACH_FRAME (tail, frame)
12089 struct frame *f = XFRAME (frame);
12090 struct window *w = XWINDOW (FRAME_SELECTED_WINDOW (f));
12091 if (some_windows
12092 && !f->redisplay
12093 && !w->redisplay
12094 && !XBUFFER (w->contents)->text->redisplay)
12095 continue;
12097 if (!FRAME_TOOLTIP_P (f)
12098 && !FRAME_PARENT_FRAME (f)
12099 && (FRAME_ICONIFIED_P (f)
12100 || FRAME_VISIBLE_P (f) == 1
12101 /* Exclude TTY frames that are obscured because they
12102 are not the top frame on their console. This is
12103 because x_consider_frame_title actually switches
12104 to the frame, which for TTY frames means it is
12105 marked as garbaged, and will be completely
12106 redrawn on the next redisplay cycle. This causes
12107 TTY frames to be completely redrawn, when there
12108 are more than one of them, even though nothing
12109 should be changed on display. */
12110 || (FRAME_VISIBLE_P (f) == 2 && FRAME_WINDOW_P (f))))
12111 x_consider_frame_title (frame);
12114 #endif /* HAVE_WINDOW_SYSTEM */
12116 /* Update the menu bar item lists, if appropriate. This has to be
12117 done before any actual redisplay or generation of display lines. */
12119 if (all_windows)
12121 Lisp_Object tail, frame;
12122 ptrdiff_t count = SPECPDL_INDEX ();
12123 /* True means that update_menu_bar has run its hooks
12124 so any further calls to update_menu_bar shouldn't do so again. */
12125 bool menu_bar_hooks_run = false;
12127 record_unwind_save_match_data ();
12129 FOR_EACH_FRAME (tail, frame)
12131 struct frame *f = XFRAME (frame);
12132 struct window *w = XWINDOW (FRAME_SELECTED_WINDOW (f));
12134 /* Ignore tooltip frame. */
12135 if (FRAME_TOOLTIP_P (f))
12136 continue;
12138 if (some_windows
12139 && !f->redisplay
12140 && !w->redisplay
12141 && !XBUFFER (w->contents)->text->redisplay)
12142 continue;
12144 run_window_size_change_functions (frame);
12146 if (FRAME_PARENT_FRAME (f))
12147 continue;
12149 menu_bar_hooks_run = update_menu_bar (f, false, menu_bar_hooks_run);
12150 #ifdef HAVE_WINDOW_SYSTEM
12151 update_tool_bar (f, false);
12152 #endif
12155 unbind_to (count, Qnil);
12157 else
12159 struct frame *sf = SELECTED_FRAME ();
12160 update_menu_bar (sf, true, false);
12161 #ifdef HAVE_WINDOW_SYSTEM
12162 update_tool_bar (sf, true);
12163 #endif
12168 /* Update the menu bar item list for frame F. This has to be done
12169 before we start to fill in any display lines, because it can call
12170 eval.
12172 If SAVE_MATCH_DATA, we must save and restore it here.
12174 If HOOKS_RUN, a previous call to update_menu_bar
12175 already ran the menu bar hooks for this redisplay, so there
12176 is no need to run them again. The return value is the
12177 updated value of this flag, to pass to the next call. */
12179 static bool
12180 update_menu_bar (struct frame *f, bool save_match_data, bool hooks_run)
12182 Lisp_Object window;
12183 struct window *w;
12185 /* If called recursively during a menu update, do nothing. This can
12186 happen when, for instance, an activate-menubar-hook causes a
12187 redisplay. */
12188 if (inhibit_menubar_update)
12189 return hooks_run;
12191 window = FRAME_SELECTED_WINDOW (f);
12192 w = XWINDOW (window);
12194 if (FRAME_WINDOW_P (f)
12196 #if defined (USE_X_TOOLKIT) || defined (HAVE_NTGUI) \
12197 || defined (HAVE_NS) || defined (USE_GTK)
12198 FRAME_EXTERNAL_MENU_BAR (f)
12199 #else
12200 FRAME_MENU_BAR_LINES (f) > 0
12201 #endif
12202 : FRAME_MENU_BAR_LINES (f) > 0)
12204 /* If the user has switched buffers or windows, we need to
12205 recompute to reflect the new bindings. But we'll
12206 recompute when update_mode_lines is set too; that means
12207 that people can use force-mode-line-update to request
12208 that the menu bar be recomputed. The adverse effect on
12209 the rest of the redisplay algorithm is about the same as
12210 windows_or_buffers_changed anyway. */
12211 if (windows_or_buffers_changed
12212 /* This used to test w->update_mode_line, but we believe
12213 there is no need to recompute the menu in that case. */
12214 || update_mode_lines
12215 || window_buffer_changed (w))
12217 struct buffer *prev = current_buffer;
12218 ptrdiff_t count = SPECPDL_INDEX ();
12220 specbind (Qinhibit_menubar_update, Qt);
12222 set_buffer_internal_1 (XBUFFER (w->contents));
12223 if (save_match_data)
12224 record_unwind_save_match_data ();
12225 if (NILP (Voverriding_local_map_menu_flag))
12227 specbind (Qoverriding_terminal_local_map, Qnil);
12228 specbind (Qoverriding_local_map, Qnil);
12231 if (!hooks_run)
12233 /* Run the Lucid hook. */
12234 safe_run_hooks (Qactivate_menubar_hook);
12236 /* If it has changed current-menubar from previous value,
12237 really recompute the menu-bar from the value. */
12238 if (! NILP (Vlucid_menu_bar_dirty_flag))
12239 call0 (Qrecompute_lucid_menubar);
12241 safe_run_hooks (Qmenu_bar_update_hook);
12243 hooks_run = true;
12246 XSETFRAME (Vmenu_updating_frame, f);
12247 fset_menu_bar_items (f, menu_bar_items (FRAME_MENU_BAR_ITEMS (f)));
12249 /* Redisplay the menu bar in case we changed it. */
12250 #if defined (USE_X_TOOLKIT) || defined (HAVE_NTGUI) \
12251 || defined (HAVE_NS) || defined (USE_GTK)
12252 if (FRAME_WINDOW_P (f))
12254 #if defined (HAVE_NS)
12255 /* All frames on Mac OS share the same menubar. So only
12256 the selected frame should be allowed to set it. */
12257 if (f == SELECTED_FRAME ())
12258 #endif
12259 set_frame_menubar (f, false, false);
12261 else
12262 /* On a terminal screen, the menu bar is an ordinary screen
12263 line, and this makes it get updated. */
12264 w->update_mode_line = true;
12265 #else /* ! (USE_X_TOOLKIT || HAVE_NTGUI || HAVE_NS || USE_GTK) */
12266 /* In the non-toolkit version, the menu bar is an ordinary screen
12267 line, and this makes it get updated. */
12268 w->update_mode_line = true;
12269 #endif /* ! (USE_X_TOOLKIT || HAVE_NTGUI || HAVE_NS || USE_GTK) */
12271 unbind_to (count, Qnil);
12272 set_buffer_internal_1 (prev);
12276 return hooks_run;
12279 /***********************************************************************
12280 Tool-bars
12281 ***********************************************************************/
12283 #ifdef HAVE_WINDOW_SYSTEM
12285 /* Select `frame' temporarily without running all the code in
12286 do_switch_frame.
12287 FIXME: Maybe do_switch_frame should be trimmed down similarly
12288 when `norecord' is set. */
12289 static void
12290 fast_set_selected_frame (Lisp_Object frame)
12292 if (!EQ (selected_frame, frame))
12294 selected_frame = frame;
12295 selected_window = XFRAME (frame)->selected_window;
12299 /* Update the tool-bar item list for frame F. This has to be done
12300 before we start to fill in any display lines. Called from
12301 prepare_menu_bars. If SAVE_MATCH_DATA, we must save
12302 and restore it here. */
12304 static void
12305 update_tool_bar (struct frame *f, bool save_match_data)
12307 #if defined (USE_GTK) || defined (HAVE_NS)
12308 bool do_update = FRAME_EXTERNAL_TOOL_BAR (f);
12309 #else
12310 bool do_update = (WINDOWP (f->tool_bar_window)
12311 && WINDOW_TOTAL_LINES (XWINDOW (f->tool_bar_window)) > 0);
12312 #endif
12314 if (do_update)
12316 Lisp_Object window;
12317 struct window *w;
12319 window = FRAME_SELECTED_WINDOW (f);
12320 w = XWINDOW (window);
12322 /* If the user has switched buffers or windows, we need to
12323 recompute to reflect the new bindings. But we'll
12324 recompute when update_mode_lines is set too; that means
12325 that people can use force-mode-line-update to request
12326 that the menu bar be recomputed. The adverse effect on
12327 the rest of the redisplay algorithm is about the same as
12328 windows_or_buffers_changed anyway. */
12329 if (windows_or_buffers_changed
12330 || w->update_mode_line
12331 || update_mode_lines
12332 || window_buffer_changed (w))
12334 struct buffer *prev = current_buffer;
12335 ptrdiff_t count = SPECPDL_INDEX ();
12336 Lisp_Object frame, new_tool_bar;
12337 int new_n_tool_bar;
12339 /* Set current_buffer to the buffer of the selected
12340 window of the frame, so that we get the right local
12341 keymaps. */
12342 set_buffer_internal_1 (XBUFFER (w->contents));
12344 /* Save match data, if we must. */
12345 if (save_match_data)
12346 record_unwind_save_match_data ();
12348 /* Make sure that we don't accidentally use bogus keymaps. */
12349 if (NILP (Voverriding_local_map_menu_flag))
12351 specbind (Qoverriding_terminal_local_map, Qnil);
12352 specbind (Qoverriding_local_map, Qnil);
12355 /* We must temporarily set the selected frame to this frame
12356 before calling tool_bar_items, because the calculation of
12357 the tool-bar keymap uses the selected frame (see
12358 `tool-bar-make-keymap' in tool-bar.el). */
12359 eassert (EQ (selected_window,
12360 /* Since we only explicitly preserve selected_frame,
12361 check that selected_window would be redundant. */
12362 XFRAME (selected_frame)->selected_window));
12363 record_unwind_protect (fast_set_selected_frame, selected_frame);
12364 XSETFRAME (frame, f);
12365 fast_set_selected_frame (frame);
12367 /* Build desired tool-bar items from keymaps. */
12368 new_tool_bar
12369 = tool_bar_items (Fcopy_sequence (f->tool_bar_items),
12370 &new_n_tool_bar);
12372 /* Redisplay the tool-bar if we changed it. */
12373 if (new_n_tool_bar != f->n_tool_bar_items
12374 || NILP (Fequal (new_tool_bar, f->tool_bar_items)))
12376 /* Redisplay that happens asynchronously due to an expose event
12377 may access f->tool_bar_items. Make sure we update both
12378 variables within BLOCK_INPUT so no such event interrupts. */
12379 block_input ();
12380 fset_tool_bar_items (f, new_tool_bar);
12381 f->n_tool_bar_items = new_n_tool_bar;
12382 w->update_mode_line = true;
12383 unblock_input ();
12386 unbind_to (count, Qnil);
12387 set_buffer_internal_1 (prev);
12392 #if ! defined (USE_GTK) && ! defined (HAVE_NS)
12394 /* Set F->desired_tool_bar_string to a Lisp string representing frame
12395 F's desired tool-bar contents. F->tool_bar_items must have
12396 been set up previously by calling prepare_menu_bars. */
12398 static void
12399 build_desired_tool_bar_string (struct frame *f)
12401 int i, size, size_needed;
12402 Lisp_Object image, plist;
12404 image = plist = Qnil;
12406 /* Prepare F->desired_tool_bar_string. If we can reuse it, do so.
12407 Otherwise, make a new string. */
12409 /* The size of the string we might be able to reuse. */
12410 size = (STRINGP (f->desired_tool_bar_string)
12411 ? SCHARS (f->desired_tool_bar_string)
12412 : 0);
12414 /* We need one space in the string for each image. */
12415 size_needed = f->n_tool_bar_items;
12417 /* Reuse f->desired_tool_bar_string, if possible. */
12418 if (size < size_needed || NILP (f->desired_tool_bar_string))
12419 fset_desired_tool_bar_string
12420 (f, Fmake_string (make_number (size_needed), make_number (' '), Qnil));
12421 else
12423 AUTO_LIST4 (props, Qdisplay, Qnil, Qmenu_item, Qnil);
12424 Fremove_text_properties (make_number (0), make_number (size),
12425 props, f->desired_tool_bar_string);
12428 /* Put a `display' property on the string for the images to display,
12429 put a `menu_item' property on tool-bar items with a value that
12430 is the index of the item in F's tool-bar item vector. */
12431 for (i = 0; i < f->n_tool_bar_items; ++i)
12433 #define PROP(IDX) \
12434 AREF (f->tool_bar_items, i * TOOL_BAR_ITEM_NSLOTS + (IDX))
12436 bool enabled_p = !NILP (PROP (TOOL_BAR_ITEM_ENABLED_P));
12437 bool selected_p = !NILP (PROP (TOOL_BAR_ITEM_SELECTED_P));
12438 int hmargin, vmargin, relief, idx, end;
12440 /* If image is a vector, choose the image according to the
12441 button state. */
12442 image = PROP (TOOL_BAR_ITEM_IMAGES);
12443 if (VECTORP (image))
12445 if (enabled_p)
12446 idx = (selected_p
12447 ? TOOL_BAR_IMAGE_ENABLED_SELECTED
12448 : TOOL_BAR_IMAGE_ENABLED_DESELECTED);
12449 else
12450 idx = (selected_p
12451 ? TOOL_BAR_IMAGE_DISABLED_SELECTED
12452 : TOOL_BAR_IMAGE_DISABLED_DESELECTED);
12454 eassert (ASIZE (image) >= idx);
12455 image = AREF (image, idx);
12457 else
12458 idx = -1;
12460 /* Ignore invalid image specifications. */
12461 if (!valid_image_p (image))
12462 continue;
12464 /* Display the tool-bar button pressed, or depressed. */
12465 plist = Fcopy_sequence (XCDR (image));
12467 /* Compute margin and relief to draw. */
12468 relief = (tool_bar_button_relief >= 0
12469 ? tool_bar_button_relief
12470 : DEFAULT_TOOL_BAR_BUTTON_RELIEF);
12471 hmargin = vmargin = relief;
12473 if (RANGED_INTEGERP (1, Vtool_bar_button_margin,
12474 INT_MAX - max (hmargin, vmargin)))
12476 hmargin += XFASTINT (Vtool_bar_button_margin);
12477 vmargin += XFASTINT (Vtool_bar_button_margin);
12479 else if (CONSP (Vtool_bar_button_margin))
12481 if (RANGED_INTEGERP (1, XCAR (Vtool_bar_button_margin),
12482 INT_MAX - hmargin))
12483 hmargin += XFASTINT (XCAR (Vtool_bar_button_margin));
12485 if (RANGED_INTEGERP (1, XCDR (Vtool_bar_button_margin),
12486 INT_MAX - vmargin))
12487 vmargin += XFASTINT (XCDR (Vtool_bar_button_margin));
12490 if (auto_raise_tool_bar_buttons_p)
12492 /* Add a `:relief' property to the image spec if the item is
12493 selected. */
12494 if (selected_p)
12496 plist = Fplist_put (plist, QCrelief, make_number (-relief));
12497 hmargin -= relief;
12498 vmargin -= relief;
12501 else
12503 /* If image is selected, display it pressed, i.e. with a
12504 negative relief. If it's not selected, display it with a
12505 raised relief. */
12506 plist = Fplist_put (plist, QCrelief,
12507 (selected_p
12508 ? make_number (-relief)
12509 : make_number (relief)));
12510 hmargin -= relief;
12511 vmargin -= relief;
12514 /* Put a margin around the image. */
12515 if (hmargin || vmargin)
12517 if (hmargin == vmargin)
12518 plist = Fplist_put (plist, QCmargin, make_number (hmargin));
12519 else
12520 plist = Fplist_put (plist, QCmargin,
12521 Fcons (make_number (hmargin),
12522 make_number (vmargin)));
12525 /* If button is not enabled, and we don't have special images
12526 for the disabled state, make the image appear disabled by
12527 applying an appropriate algorithm to it. */
12528 if (!enabled_p && idx < 0)
12529 plist = Fplist_put (plist, QCconversion, Qdisabled);
12531 /* Put a `display' text property on the string for the image to
12532 display. Put a `menu-item' property on the string that gives
12533 the start of this item's properties in the tool-bar items
12534 vector. */
12535 image = Fcons (Qimage, plist);
12536 AUTO_LIST4 (props, Qdisplay, image, Qmenu_item,
12537 make_number (i * TOOL_BAR_ITEM_NSLOTS));
12539 /* Let the last image hide all remaining spaces in the tool bar
12540 string. The string can be longer than needed when we reuse a
12541 previous string. */
12542 if (i + 1 == f->n_tool_bar_items)
12543 end = SCHARS (f->desired_tool_bar_string);
12544 else
12545 end = i + 1;
12546 Fadd_text_properties (make_number (i), make_number (end),
12547 props, f->desired_tool_bar_string);
12548 #undef PROP
12553 /* Display one line of the tool-bar of frame IT->f.
12555 HEIGHT specifies the desired height of the tool-bar line.
12556 If the actual height of the glyph row is less than HEIGHT, the
12557 row's height is increased to HEIGHT, and the icons are centered
12558 vertically in the new height.
12560 If HEIGHT is -1, we are counting needed tool-bar lines, so don't
12561 count a final empty row in case the tool-bar width exactly matches
12562 the window width.
12565 static void
12566 display_tool_bar_line (struct it *it, int height)
12568 struct glyph_row *row = it->glyph_row;
12569 int max_x = it->last_visible_x;
12570 struct glyph *last;
12572 /* Don't extend on a previously drawn tool bar items (Bug#16058). */
12573 clear_glyph_row (row);
12574 row->enabled_p = true;
12575 row->y = it->current_y;
12577 /* Note that this isn't made use of if the face hasn't a box,
12578 so there's no need to check the face here. */
12579 it->start_of_box_run_p = true;
12581 while (it->current_x < max_x)
12583 int x, n_glyphs_before, i, nglyphs;
12584 struct it it_before;
12586 /* Get the next display element. */
12587 if (!get_next_display_element (it))
12589 /* Don't count empty row if we are counting needed tool-bar lines. */
12590 if (height < 0 && !it->hpos)
12591 return;
12592 break;
12595 /* Produce glyphs. */
12596 n_glyphs_before = row->used[TEXT_AREA];
12597 it_before = *it;
12599 PRODUCE_GLYPHS (it);
12601 nglyphs = row->used[TEXT_AREA] - n_glyphs_before;
12602 i = 0;
12603 x = it_before.current_x;
12604 while (i < nglyphs)
12606 struct glyph *glyph = row->glyphs[TEXT_AREA] + n_glyphs_before + i;
12608 if (x + glyph->pixel_width > max_x)
12610 /* Glyph doesn't fit on line. Backtrack. */
12611 row->used[TEXT_AREA] = n_glyphs_before;
12612 *it = it_before;
12613 /* If this is the only glyph on this line, it will never fit on the
12614 tool-bar, so skip it. But ensure there is at least one glyph,
12615 so we don't accidentally disable the tool-bar. */
12616 if (n_glyphs_before == 0
12617 && (it->vpos > 0 || IT_STRING_CHARPOS (*it) < it->end_charpos-1))
12618 break;
12619 goto out;
12622 ++it->hpos;
12623 x += glyph->pixel_width;
12624 ++i;
12627 /* Stop at line end. */
12628 if (ITERATOR_AT_END_OF_LINE_P (it))
12629 break;
12631 set_iterator_to_next (it, true);
12634 out:;
12636 row->displays_text_p = row->used[TEXT_AREA] != 0;
12638 /* Use default face for the border below the tool bar.
12640 FIXME: When auto-resize-tool-bars is grow-only, there is
12641 no additional border below the possibly empty tool-bar lines.
12642 So to make the extra empty lines look "normal", we have to
12643 use the tool-bar face for the border too. */
12644 if (!MATRIX_ROW_DISPLAYS_TEXT_P (row)
12645 && !EQ (Vauto_resize_tool_bars, Qgrow_only))
12646 it->face_id = DEFAULT_FACE_ID;
12648 extend_face_to_end_of_line (it);
12649 last = row->glyphs[TEXT_AREA] + row->used[TEXT_AREA] - 1;
12650 last->right_box_line_p = true;
12651 if (last == row->glyphs[TEXT_AREA])
12652 last->left_box_line_p = true;
12654 /* Make line the desired height and center it vertically. */
12655 if ((height -= it->max_ascent + it->max_descent) > 0)
12657 /* Don't add more than one line height. */
12658 height %= FRAME_LINE_HEIGHT (it->f);
12659 it->max_ascent += height / 2;
12660 it->max_descent += (height + 1) / 2;
12663 compute_line_metrics (it);
12665 /* If line is empty, make it occupy the rest of the tool-bar. */
12666 if (!MATRIX_ROW_DISPLAYS_TEXT_P (row))
12668 row->height = row->phys_height = it->last_visible_y - row->y;
12669 row->visible_height = row->height;
12670 row->ascent = row->phys_ascent = 0;
12671 row->extra_line_spacing = 0;
12674 row->full_width_p = true;
12675 row->continued_p = false;
12676 row->truncated_on_left_p = false;
12677 row->truncated_on_right_p = false;
12679 it->current_x = it->hpos = 0;
12680 it->current_y += row->height;
12681 ++it->vpos;
12682 ++it->glyph_row;
12686 /* Value is the number of pixels needed to make all tool-bar items of
12687 frame F visible. The actual number of glyph rows needed is
12688 returned in *N_ROWS if non-NULL. */
12689 static int
12690 tool_bar_height (struct frame *f, int *n_rows, bool pixelwise)
12692 struct window *w = XWINDOW (f->tool_bar_window);
12693 struct it it;
12694 /* tool_bar_height is called from redisplay_tool_bar after building
12695 the desired matrix, so use (unused) mode-line row as temporary row to
12696 avoid destroying the first tool-bar row. */
12697 struct glyph_row *temp_row = MATRIX_MODE_LINE_ROW (w->desired_matrix);
12699 /* Initialize an iterator for iteration over
12700 F->desired_tool_bar_string in the tool-bar window of frame F. */
12701 init_iterator (&it, w, -1, -1, temp_row, TOOL_BAR_FACE_ID);
12702 temp_row->reversed_p = false;
12703 it.first_visible_x = 0;
12704 it.last_visible_x = WINDOW_PIXEL_WIDTH (w);
12705 reseat_to_string (&it, NULL, f->desired_tool_bar_string, 0, 0, 0, -1);
12706 it.paragraph_embedding = L2R;
12708 while (!ITERATOR_AT_END_P (&it))
12710 clear_glyph_row (temp_row);
12711 it.glyph_row = temp_row;
12712 display_tool_bar_line (&it, -1);
12714 clear_glyph_row (temp_row);
12716 /* f->n_tool_bar_rows == 0 means "unknown"; -1 means no tool-bar. */
12717 if (n_rows)
12718 *n_rows = it.vpos > 0 ? it.vpos : -1;
12720 if (pixelwise)
12721 return it.current_y;
12722 else
12723 return (it.current_y + FRAME_LINE_HEIGHT (f) - 1) / FRAME_LINE_HEIGHT (f);
12726 #endif /* !USE_GTK && !HAVE_NS */
12728 DEFUN ("tool-bar-height", Ftool_bar_height, Stool_bar_height,
12729 0, 2, 0,
12730 doc: /* Return the number of lines occupied by the tool bar of FRAME.
12731 If FRAME is nil or omitted, use the selected frame. Optional argument
12732 PIXELWISE non-nil means return the height of the tool bar in pixels. */)
12733 (Lisp_Object frame, Lisp_Object pixelwise)
12735 int height = 0;
12737 #if ! defined (USE_GTK) && ! defined (HAVE_NS)
12738 struct frame *f = decode_any_frame (frame);
12740 if (WINDOWP (f->tool_bar_window)
12741 && WINDOW_PIXEL_HEIGHT (XWINDOW (f->tool_bar_window)) > 0)
12743 update_tool_bar (f, true);
12744 if (f->n_tool_bar_items)
12746 build_desired_tool_bar_string (f);
12747 height = tool_bar_height (f, NULL, !NILP (pixelwise));
12750 #endif
12752 return make_number (height);
12756 /* Display the tool-bar of frame F. Value is true if tool-bar's
12757 height should be changed. */
12758 static bool
12759 redisplay_tool_bar (struct frame *f)
12761 f->tool_bar_redisplayed = true;
12762 #if defined (USE_GTK) || defined (HAVE_NS)
12764 if (FRAME_EXTERNAL_TOOL_BAR (f))
12765 update_frame_tool_bar (f);
12766 return false;
12768 #else /* !USE_GTK && !HAVE_NS */
12770 struct window *w;
12771 struct it it;
12772 struct glyph_row *row;
12774 /* If frame hasn't a tool-bar window or if it is zero-height, don't
12775 do anything. This means you must start with tool-bar-lines
12776 non-zero to get the auto-sizing effect. Or in other words, you
12777 can turn off tool-bars by specifying tool-bar-lines zero. */
12778 if (!WINDOWP (f->tool_bar_window)
12779 || (w = XWINDOW (f->tool_bar_window),
12780 WINDOW_TOTAL_LINES (w) == 0))
12781 return false;
12783 /* Set up an iterator for the tool-bar window. */
12784 init_iterator (&it, w, -1, -1, w->desired_matrix->rows, TOOL_BAR_FACE_ID);
12785 it.first_visible_x = 0;
12786 it.last_visible_x = WINDOW_PIXEL_WIDTH (w);
12787 row = it.glyph_row;
12788 row->reversed_p = false;
12790 /* Build a string that represents the contents of the tool-bar. */
12791 build_desired_tool_bar_string (f);
12792 reseat_to_string (&it, NULL, f->desired_tool_bar_string, 0, 0, 0, -1);
12793 /* FIXME: This should be controlled by a user option. But it
12794 doesn't make sense to have an R2L tool bar if the menu bar cannot
12795 be drawn also R2L, and making the menu bar R2L is tricky due
12796 toolkit-specific code that implements it. If an R2L tool bar is
12797 ever supported, display_tool_bar_line should also be augmented to
12798 call unproduce_glyphs like display_line and display_string
12799 do. */
12800 it.paragraph_embedding = L2R;
12802 if (f->n_tool_bar_rows == 0)
12804 int new_height = tool_bar_height (f, &f->n_tool_bar_rows, true);
12806 if (new_height != WINDOW_PIXEL_HEIGHT (w))
12808 x_change_tool_bar_height (f, new_height);
12809 frame_default_tool_bar_height = new_height;
12810 /* Always do that now. */
12811 clear_glyph_matrix (w->desired_matrix);
12812 f->fonts_changed = true;
12813 return true;
12817 /* Display as many lines as needed to display all tool-bar items. */
12819 if (f->n_tool_bar_rows > 0)
12821 int border, rows, height, extra;
12823 if (TYPE_RANGED_INTEGERP (int, Vtool_bar_border))
12824 border = XINT (Vtool_bar_border);
12825 else if (EQ (Vtool_bar_border, Qinternal_border_width))
12826 border = FRAME_INTERNAL_BORDER_WIDTH (f);
12827 else if (EQ (Vtool_bar_border, Qborder_width))
12828 border = f->border_width;
12829 else
12830 border = 0;
12831 if (border < 0)
12832 border = 0;
12834 rows = f->n_tool_bar_rows;
12835 height = max (1, (it.last_visible_y - border) / rows);
12836 extra = it.last_visible_y - border - height * rows;
12838 while (it.current_y < it.last_visible_y)
12840 int h = 0;
12841 if (extra > 0 && rows-- > 0)
12843 h = (extra + rows - 1) / rows;
12844 extra -= h;
12846 display_tool_bar_line (&it, height + h);
12849 else
12851 while (it.current_y < it.last_visible_y)
12852 display_tool_bar_line (&it, 0);
12855 /* It doesn't make much sense to try scrolling in the tool-bar
12856 window, so don't do it. */
12857 w->desired_matrix->no_scrolling_p = true;
12858 w->must_be_updated_p = true;
12860 if (!NILP (Vauto_resize_tool_bars))
12862 bool change_height_p = true;
12864 /* If we couldn't display everything, change the tool-bar's
12865 height if there is room for more. */
12866 if (IT_STRING_CHARPOS (it) < it.end_charpos)
12867 change_height_p = true;
12869 /* We subtract 1 because display_tool_bar_line advances the
12870 glyph_row pointer before returning to its caller. We want to
12871 examine the last glyph row produced by
12872 display_tool_bar_line. */
12873 row = it.glyph_row - 1;
12875 /* If there are blank lines at the end, except for a partially
12876 visible blank line at the end that is smaller than
12877 FRAME_LINE_HEIGHT, change the tool-bar's height. */
12878 if (!MATRIX_ROW_DISPLAYS_TEXT_P (row)
12879 && row->height >= FRAME_LINE_HEIGHT (f))
12880 change_height_p = true;
12882 /* If row displays tool-bar items, but is partially visible,
12883 change the tool-bar's height. */
12884 if (MATRIX_ROW_DISPLAYS_TEXT_P (row)
12885 && MATRIX_ROW_BOTTOM_Y (row) > it.last_visible_y)
12886 change_height_p = true;
12888 /* Resize windows as needed by changing the `tool-bar-lines'
12889 frame parameter. */
12890 if (change_height_p)
12892 int nrows;
12893 int new_height = tool_bar_height (f, &nrows, true);
12895 change_height_p = ((EQ (Vauto_resize_tool_bars, Qgrow_only)
12896 && !f->minimize_tool_bar_window_p)
12897 ? (new_height > WINDOW_PIXEL_HEIGHT (w))
12898 : (new_height != WINDOW_PIXEL_HEIGHT (w)));
12899 f->minimize_tool_bar_window_p = false;
12901 if (change_height_p)
12903 x_change_tool_bar_height (f, new_height);
12904 frame_default_tool_bar_height = new_height;
12905 clear_glyph_matrix (w->desired_matrix);
12906 f->n_tool_bar_rows = nrows;
12907 f->fonts_changed = true;
12909 return true;
12914 f->minimize_tool_bar_window_p = false;
12915 return false;
12917 #endif /* USE_GTK || HAVE_NS */
12920 #if ! defined (USE_GTK) && ! defined (HAVE_NS)
12922 /* Get information about the tool-bar item which is displayed in GLYPH
12923 on frame F. Return in *PROP_IDX the index where tool-bar item
12924 properties start in F->tool_bar_items. Value is false if
12925 GLYPH doesn't display a tool-bar item. */
12927 static bool
12928 tool_bar_item_info (struct frame *f, struct glyph *glyph, int *prop_idx)
12930 Lisp_Object prop;
12931 int charpos;
12933 /* This function can be called asynchronously, which means we must
12934 exclude any possibility that Fget_text_property signals an
12935 error. */
12936 charpos = min (SCHARS (f->current_tool_bar_string), glyph->charpos);
12937 charpos = max (0, charpos);
12939 /* Get the text property `menu-item' at pos. The value of that
12940 property is the start index of this item's properties in
12941 F->tool_bar_items. */
12942 prop = Fget_text_property (make_number (charpos),
12943 Qmenu_item, f->current_tool_bar_string);
12944 if (! INTEGERP (prop))
12945 return false;
12946 *prop_idx = XINT (prop);
12947 return true;
12951 /* Get information about the tool-bar item at position X/Y on frame F.
12952 Return in *GLYPH a pointer to the glyph of the tool-bar item in
12953 the current matrix of the tool-bar window of F, or NULL if not
12954 on a tool-bar item. Return in *PROP_IDX the index of the tool-bar
12955 item in F->tool_bar_items. Value is
12957 -1 if X/Y is not on a tool-bar item
12958 0 if X/Y is on the same item that was highlighted before.
12959 1 otherwise. */
12961 static int
12962 get_tool_bar_item (struct frame *f, int x, int y, struct glyph **glyph,
12963 int *hpos, int *vpos, int *prop_idx)
12965 Mouse_HLInfo *hlinfo = MOUSE_HL_INFO (f);
12966 struct window *w = XWINDOW (f->tool_bar_window);
12967 int area;
12969 /* Find the glyph under X/Y. */
12970 *glyph = x_y_to_hpos_vpos (w, x, y, hpos, vpos, 0, 0, &area);
12971 if (*glyph == NULL)
12972 return -1;
12974 /* Get the start of this tool-bar item's properties in
12975 f->tool_bar_items. */
12976 if (!tool_bar_item_info (f, *glyph, prop_idx))
12977 return -1;
12979 /* Is mouse on the highlighted item? */
12980 if (EQ (f->tool_bar_window, hlinfo->mouse_face_window)
12981 && *vpos >= hlinfo->mouse_face_beg_row
12982 && *vpos <= hlinfo->mouse_face_end_row
12983 && (*vpos > hlinfo->mouse_face_beg_row
12984 || *hpos >= hlinfo->mouse_face_beg_col)
12985 && (*vpos < hlinfo->mouse_face_end_row
12986 || *hpos < hlinfo->mouse_face_end_col
12987 || hlinfo->mouse_face_past_end))
12988 return 0;
12990 return 1;
12994 /* EXPORT:
12995 Handle mouse button event on the tool-bar of frame F, at
12996 frame-relative coordinates X/Y. DOWN_P is true for a button press,
12997 false for button release. MODIFIERS is event modifiers for button
12998 release. */
13000 void
13001 handle_tool_bar_click (struct frame *f, int x, int y, bool down_p,
13002 int modifiers)
13004 Mouse_HLInfo *hlinfo = MOUSE_HL_INFO (f);
13005 struct window *w = XWINDOW (f->tool_bar_window);
13006 int hpos, vpos, prop_idx;
13007 struct glyph *glyph;
13008 Lisp_Object enabled_p;
13009 int ts;
13011 /* If not on the highlighted tool-bar item, and mouse-highlight is
13012 non-nil, return. This is so we generate the tool-bar button
13013 click only when the mouse button is released on the same item as
13014 where it was pressed. However, when mouse-highlight is disabled,
13015 generate the click when the button is released regardless of the
13016 highlight, since tool-bar items are not highlighted in that
13017 case. */
13018 frame_to_window_pixel_xy (w, &x, &y);
13019 ts = get_tool_bar_item (f, x, y, &glyph, &hpos, &vpos, &prop_idx);
13020 if (ts == -1
13021 || (ts != 0 && !NILP (Vmouse_highlight)))
13022 return;
13024 /* When mouse-highlight is off, generate the click for the item
13025 where the button was pressed, disregarding where it was
13026 released. */
13027 if (NILP (Vmouse_highlight) && !down_p)
13028 prop_idx = f->last_tool_bar_item;
13030 /* If item is disabled, do nothing. */
13031 enabled_p = AREF (f->tool_bar_items, prop_idx + TOOL_BAR_ITEM_ENABLED_P);
13032 if (NILP (enabled_p))
13033 return;
13035 if (down_p)
13037 /* Show item in pressed state. */
13038 if (!NILP (Vmouse_highlight))
13039 show_mouse_face (hlinfo, DRAW_IMAGE_SUNKEN);
13040 f->last_tool_bar_item = prop_idx;
13042 else
13044 Lisp_Object key, frame;
13045 struct input_event event;
13046 EVENT_INIT (event);
13048 /* Show item in released state. */
13049 if (!NILP (Vmouse_highlight))
13050 show_mouse_face (hlinfo, DRAW_IMAGE_RAISED);
13052 key = AREF (f->tool_bar_items, prop_idx + TOOL_BAR_ITEM_KEY);
13054 XSETFRAME (frame, f);
13055 event.kind = TOOL_BAR_EVENT;
13056 event.frame_or_window = frame;
13057 event.arg = frame;
13058 kbd_buffer_store_event (&event);
13060 event.kind = TOOL_BAR_EVENT;
13061 event.frame_or_window = frame;
13062 event.arg = key;
13063 event.modifiers = modifiers;
13064 kbd_buffer_store_event (&event);
13065 f->last_tool_bar_item = -1;
13070 /* Possibly highlight a tool-bar item on frame F when mouse moves to
13071 tool-bar window-relative coordinates X/Y. Called from
13072 note_mouse_highlight. */
13074 static void
13075 note_tool_bar_highlight (struct frame *f, int x, int y)
13077 Lisp_Object window = f->tool_bar_window;
13078 struct window *w = XWINDOW (window);
13079 Display_Info *dpyinfo = FRAME_DISPLAY_INFO (f);
13080 Mouse_HLInfo *hlinfo = MOUSE_HL_INFO (f);
13081 int hpos, vpos;
13082 struct glyph *glyph;
13083 struct glyph_row *row;
13084 int i;
13085 Lisp_Object enabled_p;
13086 int prop_idx;
13087 enum draw_glyphs_face draw = DRAW_IMAGE_RAISED;
13088 bool mouse_down_p;
13089 int rc;
13091 /* Function note_mouse_highlight is called with negative X/Y
13092 values when mouse moves outside of the frame. */
13093 if (x <= 0 || y <= 0)
13095 clear_mouse_face (hlinfo);
13096 return;
13099 rc = get_tool_bar_item (f, x, y, &glyph, &hpos, &vpos, &prop_idx);
13100 if (rc < 0)
13102 /* Not on tool-bar item. */
13103 clear_mouse_face (hlinfo);
13104 return;
13106 else if (rc == 0)
13107 /* On same tool-bar item as before. */
13108 goto set_help_echo;
13110 clear_mouse_face (hlinfo);
13112 /* Mouse is down, but on different tool-bar item? */
13113 mouse_down_p = (x_mouse_grabbed (dpyinfo)
13114 && f == dpyinfo->last_mouse_frame);
13116 if (mouse_down_p && f->last_tool_bar_item != prop_idx)
13117 return;
13119 draw = mouse_down_p ? DRAW_IMAGE_SUNKEN : DRAW_IMAGE_RAISED;
13121 /* If tool-bar item is not enabled, don't highlight it. */
13122 enabled_p = AREF (f->tool_bar_items, prop_idx + TOOL_BAR_ITEM_ENABLED_P);
13123 if (!NILP (enabled_p) && !NILP (Vmouse_highlight))
13125 /* Compute the x-position of the glyph. In front and past the
13126 image is a space. We include this in the highlighted area. */
13127 row = MATRIX_ROW (w->current_matrix, vpos);
13128 for (i = x = 0; i < hpos; ++i)
13129 x += row->glyphs[TEXT_AREA][i].pixel_width;
13131 /* Record this as the current active region. */
13132 hlinfo->mouse_face_beg_col = hpos;
13133 hlinfo->mouse_face_beg_row = vpos;
13134 hlinfo->mouse_face_beg_x = x;
13135 hlinfo->mouse_face_past_end = false;
13137 hlinfo->mouse_face_end_col = hpos + 1;
13138 hlinfo->mouse_face_end_row = vpos;
13139 hlinfo->mouse_face_end_x = x + glyph->pixel_width;
13140 hlinfo->mouse_face_window = window;
13141 hlinfo->mouse_face_face_id = TOOL_BAR_FACE_ID;
13143 /* Display it as active. */
13144 show_mouse_face (hlinfo, draw);
13147 set_help_echo:
13149 /* Set help_echo_string to a help string to display for this tool-bar item.
13150 XTread_socket does the rest. */
13151 help_echo_object = help_echo_window = Qnil;
13152 help_echo_pos = -1;
13153 help_echo_string = AREF (f->tool_bar_items, prop_idx + TOOL_BAR_ITEM_HELP);
13154 if (NILP (help_echo_string))
13155 help_echo_string = AREF (f->tool_bar_items, prop_idx + TOOL_BAR_ITEM_CAPTION);
13158 #endif /* !USE_GTK && !HAVE_NS */
13160 #endif /* HAVE_WINDOW_SYSTEM */
13164 /************************************************************************
13165 Horizontal scrolling
13166 ************************************************************************/
13168 /* For all leaf windows in the window tree rooted at WINDOW, set their
13169 hscroll value so that PT is (i) visible in the window, and (ii) so
13170 that it is not within a certain margin at the window's left and
13171 right border. Value is true if any window's hscroll has been
13172 changed. */
13174 static bool
13175 hscroll_window_tree (Lisp_Object window)
13177 bool hscrolled_p = false;
13178 bool hscroll_relative_p = FLOATP (Vhscroll_step);
13179 int hscroll_step_abs = 0;
13180 double hscroll_step_rel = 0;
13182 if (hscroll_relative_p)
13184 hscroll_step_rel = XFLOAT_DATA (Vhscroll_step);
13185 if (hscroll_step_rel < 0)
13187 hscroll_relative_p = false;
13188 hscroll_step_abs = 0;
13191 else if (TYPE_RANGED_INTEGERP (int, Vhscroll_step))
13193 hscroll_step_abs = XINT (Vhscroll_step);
13194 if (hscroll_step_abs < 0)
13195 hscroll_step_abs = 0;
13197 else
13198 hscroll_step_abs = 0;
13200 while (WINDOWP (window))
13202 struct window *w = XWINDOW (window);
13204 if (WINDOWP (w->contents))
13205 hscrolled_p |= hscroll_window_tree (w->contents);
13206 else if (w->cursor.vpos >= 0)
13208 int h_margin;
13209 int text_area_width;
13210 struct glyph_row *cursor_row;
13211 struct glyph_row *bottom_row;
13213 bottom_row = MATRIX_BOTTOM_TEXT_ROW (w->desired_matrix, w);
13214 if (w->cursor.vpos < bottom_row - w->desired_matrix->rows)
13215 cursor_row = MATRIX_ROW (w->desired_matrix, w->cursor.vpos);
13216 else
13217 cursor_row = bottom_row - 1;
13219 if (!cursor_row->enabled_p)
13221 bottom_row = MATRIX_BOTTOM_TEXT_ROW (w->current_matrix, w);
13222 if (w->cursor.vpos < bottom_row - w->current_matrix->rows)
13223 cursor_row = MATRIX_ROW (w->current_matrix, w->cursor.vpos);
13224 else
13225 cursor_row = bottom_row - 1;
13227 bool row_r2l_p = cursor_row->reversed_p;
13228 bool hscl = hscrolling_current_line_p (w);
13229 int x_offset = 0;
13230 /* When line numbers are displayed, we need to account for
13231 the horizontal space they consume. */
13232 if (!NILP (Vdisplay_line_numbers))
13234 struct glyph *g;
13235 if (!row_r2l_p)
13237 for (g = cursor_row->glyphs[TEXT_AREA];
13238 g < cursor_row->glyphs[TEXT_AREA]
13239 + cursor_row->used[TEXT_AREA];
13240 g++)
13242 if (!(NILP (g->object) && g->charpos < 0))
13243 break;
13244 x_offset += g->pixel_width;
13247 else
13249 for (g = cursor_row->glyphs[TEXT_AREA]
13250 + cursor_row->used[TEXT_AREA];
13251 g > cursor_row->glyphs[TEXT_AREA];
13252 g--)
13254 if (!(NILP ((g - 1)->object) && (g - 1)->charpos < 0))
13255 break;
13256 x_offset += (g - 1)->pixel_width;
13260 if (cursor_row->truncated_on_left_p)
13262 /* On TTY frames, don't count the left truncation glyph. */
13263 struct frame *f = XFRAME (WINDOW_FRAME (w));
13264 x_offset -= (FRAME_TERMCAP_P (f) || FRAME_MSDOS_P (f));
13267 text_area_width = window_box_width (w, TEXT_AREA);
13269 /* Scroll when cursor is inside this scroll margin. */
13270 h_margin = hscroll_margin * WINDOW_FRAME_COLUMN_WIDTH (w);
13272 /* If the position of this window's point has explicitly
13273 changed, no more suspend auto hscrolling. */
13274 if (w->suspend_auto_hscroll
13275 && NILP (Fequal (Fwindow_point (window),
13276 Fwindow_old_point (window))))
13278 w->suspend_auto_hscroll = false;
13279 /* When hscrolling just the current line, and the rest
13280 of lines were temporarily hscrolled, but no longer
13281 are, force thorough redisplay of this window, to show
13282 the effect of disabling hscroll suspension immediately. */
13283 if (w->min_hscroll == 0 && w->hscroll > 0
13284 && EQ (Fbuffer_local_value (Qauto_hscroll_mode, w->contents),
13285 Qcurrent_line))
13286 SET_FRAME_GARBAGED (XFRAME (w->frame));
13289 /* Remember window point. */
13290 Fset_marker (w->old_pointm,
13291 ((w == XWINDOW (selected_window))
13292 ? make_number (BUF_PT (XBUFFER (w->contents)))
13293 : Fmarker_position (w->pointm)),
13294 w->contents);
13296 if (!NILP (Fbuffer_local_value (Qauto_hscroll_mode, w->contents))
13297 && !w->suspend_auto_hscroll
13298 /* In some pathological cases, like restoring a window
13299 configuration into a frame that is much smaller than
13300 the one from which the configuration was saved, we
13301 get glyph rows whose start and end have zero buffer
13302 positions, which we cannot handle below. Just skip
13303 such windows. */
13304 && CHARPOS (cursor_row->start.pos) >= BUF_BEG (w->contents)
13305 /* For left-to-right rows, hscroll when cursor is either
13306 (i) inside the right hscroll margin, or (ii) if it is
13307 inside the left margin and the window is already
13308 hscrolled. */
13309 && ((!row_r2l_p
13310 && ((w->hscroll && w->cursor.x <= h_margin + x_offset)
13311 || (cursor_row->enabled_p
13312 && cursor_row->truncated_on_right_p
13313 && (w->cursor.x >= text_area_width - h_margin))))
13314 /* For right-to-left rows, the logic is similar,
13315 except that rules for scrolling to left and right
13316 are reversed. E.g., if cursor.x <= h_margin, we
13317 need to hscroll "to the right" unconditionally,
13318 and that will scroll the screen to the left so as
13319 to reveal the next portion of the row. */
13320 || (row_r2l_p
13321 && ((cursor_row->enabled_p
13322 /* FIXME: It is confusing to set the
13323 truncated_on_right_p flag when R2L rows
13324 are actually truncated on the left. */
13325 && cursor_row->truncated_on_right_p
13326 && w->cursor.x <= h_margin)
13327 || (w->hscroll
13328 && (w->cursor.x >= (text_area_width - h_margin
13329 - x_offset)))))
13330 /* This last condition is needed when moving
13331 vertically from an hscrolled line to a short line
13332 that doesn't need to be hscrolled. If we omit
13333 this condition, the line from which we move will
13334 remain hscrolled. */
13335 || (hscl
13336 && w->hscroll != w->min_hscroll
13337 && !cursor_row->truncated_on_left_p)))
13339 struct it it;
13340 ptrdiff_t hscroll;
13341 struct buffer *saved_current_buffer;
13342 ptrdiff_t pt;
13343 int wanted_x;
13345 /* Find point in a display of infinite width. */
13346 saved_current_buffer = current_buffer;
13347 current_buffer = XBUFFER (w->contents);
13349 if (w == XWINDOW (selected_window))
13350 pt = PT;
13351 else
13352 pt = clip_to_bounds (BEGV, marker_position (w->pointm), ZV);
13354 /* Move iterator to pt starting at cursor_row->start in
13355 a line with infinite width. */
13356 init_to_row_start (&it, w, cursor_row);
13357 if (hscl)
13358 it.first_visible_x = window_hscroll_limited (w, it.f)
13359 * FRAME_COLUMN_WIDTH (it.f);
13360 it.last_visible_x = DISP_INFINITY;
13361 move_it_in_display_line_to (&it, pt, -1, MOVE_TO_POS);
13362 /* If the line ends in an overlay string with a newline,
13363 we might infloop, because displaying the window will
13364 want to put the cursor after the overlay, i.e. at X
13365 coordinate of zero on the next screen line. So we
13366 use the buffer position prior to the overlay string
13367 instead. */
13368 if (it.method == GET_FROM_STRING && pt > 1)
13370 init_to_row_start (&it, w, cursor_row);
13371 if (hscl)
13372 it.first_visible_x = (window_hscroll_limited (w, it.f)
13373 * FRAME_COLUMN_WIDTH (it.f));
13374 move_it_in_display_line_to (&it, pt - 1, -1, MOVE_TO_POS);
13376 current_buffer = saved_current_buffer;
13378 /* Position cursor in window. */
13379 if (!hscroll_relative_p && hscroll_step_abs == 0)
13380 hscroll = max (0, (it.current_x
13381 - (ITERATOR_AT_END_OF_LINE_P (&it)
13382 ? (text_area_width - 4 * FRAME_COLUMN_WIDTH (it.f))
13383 : (text_area_width / 2))))
13384 / FRAME_COLUMN_WIDTH (it.f);
13385 else if ((!row_r2l_p
13386 && w->cursor.x >= text_area_width - h_margin)
13387 || (row_r2l_p && w->cursor.x <= h_margin))
13389 if (hscroll_relative_p)
13390 wanted_x = text_area_width * (1 - hscroll_step_rel)
13391 - h_margin;
13392 else
13393 wanted_x = text_area_width
13394 - hscroll_step_abs * FRAME_COLUMN_WIDTH (it.f)
13395 - h_margin;
13396 hscroll
13397 = max (0, it.current_x - wanted_x) / FRAME_COLUMN_WIDTH (it.f);
13399 else
13401 if (hscroll_relative_p)
13402 wanted_x = text_area_width * hscroll_step_rel
13403 + h_margin;
13404 else
13405 wanted_x = hscroll_step_abs * FRAME_COLUMN_WIDTH (it.f)
13406 + h_margin;
13407 hscroll
13408 = max (0, it.current_x - wanted_x) / FRAME_COLUMN_WIDTH (it.f);
13410 hscroll = max (hscroll, w->min_hscroll);
13412 /* Don't prevent redisplay optimizations if hscroll
13413 hasn't changed, as it will unnecessarily slow down
13414 redisplay. */
13415 if (w->hscroll != hscroll
13416 /* When hscrolling only the current line, we need to
13417 report hscroll even if its value is equal to the
13418 previous one, because the new line might need a
13419 different value. */
13420 || (hscl && w->last_cursor_vpos != w->cursor.vpos))
13422 struct buffer *b = XBUFFER (w->contents);
13423 b->prevent_redisplay_optimizations_p = true;
13424 w->hscroll = hscroll;
13425 hscrolled_p = true;
13430 window = w->next;
13433 /* Value is true if hscroll of any leaf window has been changed. */
13434 return hscrolled_p;
13438 /* Set hscroll so that cursor is visible and not inside horizontal
13439 scroll margins for all windows in the tree rooted at WINDOW. See
13440 also hscroll_window_tree above. Value is true if any window's
13441 hscroll has been changed. If it has, desired matrices on the frame
13442 of WINDOW are cleared. */
13444 static bool
13445 hscroll_windows (Lisp_Object window)
13447 bool hscrolled_p = hscroll_window_tree (window);
13448 if (hscrolled_p)
13449 clear_desired_matrices (XFRAME (WINDOW_FRAME (XWINDOW (window))));
13450 return hscrolled_p;
13455 /************************************************************************
13456 Redisplay
13457 ************************************************************************/
13459 /* Variables holding some state of redisplay if GLYPH_DEBUG is defined.
13460 This is sometimes handy to have in a debugger session. */
13462 #ifdef GLYPH_DEBUG
13464 /* First and last unchanged row for try_window_id. */
13466 static int debug_first_unchanged_at_end_vpos;
13467 static int debug_last_unchanged_at_beg_vpos;
13469 /* Delta vpos and y. */
13471 static int debug_dvpos, debug_dy;
13473 /* Delta in characters and bytes for try_window_id. */
13475 static ptrdiff_t debug_delta, debug_delta_bytes;
13477 /* Values of window_end_pos and window_end_vpos at the end of
13478 try_window_id. */
13480 static ptrdiff_t debug_end_vpos;
13482 /* Append a string to W->desired_matrix->method. FMT is a printf
13483 format string. If trace_redisplay_p is true also printf the
13484 resulting string to stderr. */
13486 static void debug_method_add (struct window *, char const *, ...)
13487 ATTRIBUTE_FORMAT_PRINTF (2, 3);
13489 static void
13490 debug_method_add (struct window *w, char const *fmt, ...)
13492 void *ptr = w;
13493 char *method = w->desired_matrix->method;
13494 int len = strlen (method);
13495 int size = sizeof w->desired_matrix->method;
13496 int remaining = size - len - 1;
13497 va_list ap;
13499 if (len && remaining)
13501 method[len] = '|';
13502 --remaining, ++len;
13505 va_start (ap, fmt);
13506 vsnprintf (method + len, remaining + 1, fmt, ap);
13507 va_end (ap);
13509 if (trace_redisplay_p)
13510 fprintf (stderr, "%p (%s): %s\n",
13511 ptr,
13512 ((BUFFERP (w->contents)
13513 && STRINGP (BVAR (XBUFFER (w->contents), name)))
13514 ? SSDATA (BVAR (XBUFFER (w->contents), name))
13515 : "no buffer"),
13516 method + len);
13519 #endif /* GLYPH_DEBUG */
13522 /* Value is true if all changes in window W, which displays
13523 current_buffer, are in the text between START and END. START is a
13524 buffer position, END is given as a distance from Z. Used in
13525 redisplay_internal for display optimization. */
13527 static bool
13528 text_outside_line_unchanged_p (struct window *w,
13529 ptrdiff_t start, ptrdiff_t end)
13531 bool unchanged_p = true;
13533 /* If text or overlays have changed, see where. */
13534 if (window_outdated (w))
13536 /* Gap in the line? */
13537 if (GPT < start || Z - GPT < end)
13538 unchanged_p = false;
13540 /* Changes start in front of the line, or end after it? */
13541 if (unchanged_p
13542 && (BEG_UNCHANGED < start - 1
13543 || END_UNCHANGED < end))
13544 unchanged_p = false;
13546 /* If selective display, can't optimize if changes start at the
13547 beginning of the line. */
13548 if (unchanged_p
13549 && INTEGERP (BVAR (current_buffer, selective_display))
13550 && XINT (BVAR (current_buffer, selective_display)) > 0
13551 && (BEG_UNCHANGED < start || GPT <= start))
13552 unchanged_p = false;
13554 /* If there are overlays at the start or end of the line, these
13555 may have overlay strings with newlines in them. A change at
13556 START, for instance, may actually concern the display of such
13557 overlay strings as well, and they are displayed on different
13558 lines. So, quickly rule out this case. (For the future, it
13559 might be desirable to implement something more telling than
13560 just BEG/END_UNCHANGED.) */
13561 if (unchanged_p)
13563 if (BEG + BEG_UNCHANGED == start
13564 && overlay_touches_p (start))
13565 unchanged_p = false;
13566 if (END_UNCHANGED == end
13567 && overlay_touches_p (Z - end))
13568 unchanged_p = false;
13571 /* Under bidi reordering, adding or deleting a character in the
13572 beginning of a paragraph, before the first strong directional
13573 character, can change the base direction of the paragraph (unless
13574 the buffer specifies a fixed paragraph direction), which will
13575 require redisplaying the whole paragraph. It might be worthwhile
13576 to find the paragraph limits and widen the range of redisplayed
13577 lines to that, but for now just give up this optimization. */
13578 if (!NILP (BVAR (XBUFFER (w->contents), bidi_display_reordering))
13579 && NILP (BVAR (XBUFFER (w->contents), bidi_paragraph_direction)))
13580 unchanged_p = false;
13583 return unchanged_p;
13587 /* Do a frame update, taking possible shortcuts into account. This is
13588 the main external entry point for redisplay.
13590 If the last redisplay displayed an echo area message and that message
13591 is no longer requested, we clear the echo area or bring back the
13592 mini-buffer if that is in use. */
13594 void
13595 redisplay (void)
13597 redisplay_internal ();
13601 static Lisp_Object
13602 overlay_arrow_string_or_property (Lisp_Object var)
13604 Lisp_Object val;
13606 if (val = Fget (var, Qoverlay_arrow_string), STRINGP (val))
13607 return val;
13609 return Voverlay_arrow_string;
13612 /* Return true if there are any overlay-arrows in current_buffer. */
13613 static bool
13614 overlay_arrow_in_current_buffer_p (void)
13616 Lisp_Object vlist;
13618 for (vlist = Voverlay_arrow_variable_list;
13619 CONSP (vlist);
13620 vlist = XCDR (vlist))
13622 Lisp_Object var = XCAR (vlist);
13623 Lisp_Object val;
13625 if (!SYMBOLP (var))
13626 continue;
13627 val = find_symbol_value (var);
13628 if (MARKERP (val)
13629 && current_buffer == XMARKER (val)->buffer)
13630 return true;
13632 return false;
13636 /* Return true if any overlay_arrows have moved or overlay-arrow-string
13637 has changed.
13638 If SET_REDISPLAY is true, additionally, set the `redisplay' bit in those
13639 buffers that are affected. */
13641 static bool
13642 overlay_arrows_changed_p (bool set_redisplay)
13644 Lisp_Object vlist;
13645 bool changed = false;
13647 for (vlist = Voverlay_arrow_variable_list;
13648 CONSP (vlist);
13649 vlist = XCDR (vlist))
13651 Lisp_Object var = XCAR (vlist);
13652 Lisp_Object val, pstr;
13654 if (!SYMBOLP (var))
13655 continue;
13656 val = find_symbol_value (var);
13657 if (!MARKERP (val))
13658 continue;
13659 if (! EQ (COERCE_MARKER (val),
13660 /* FIXME: Don't we have a problem, using such a global
13661 * "last-position" if the variable is buffer-local? */
13662 Fget (var, Qlast_arrow_position))
13663 || ! (pstr = overlay_arrow_string_or_property (var),
13664 EQ (pstr, Fget (var, Qlast_arrow_string))))
13666 struct buffer *buf = XMARKER (val)->buffer;
13668 if (set_redisplay)
13670 if (buf)
13671 bset_redisplay (buf);
13672 changed = true;
13674 else
13675 return true;
13678 return changed;
13681 /* Mark overlay arrows to be updated on next redisplay. */
13683 static void
13684 update_overlay_arrows (int up_to_date)
13686 Lisp_Object vlist;
13688 for (vlist = Voverlay_arrow_variable_list;
13689 CONSP (vlist);
13690 vlist = XCDR (vlist))
13692 Lisp_Object var = XCAR (vlist);
13694 if (!SYMBOLP (var))
13695 continue;
13697 if (up_to_date > 0)
13699 Lisp_Object val = find_symbol_value (var);
13700 if (!MARKERP (val))
13701 continue;
13702 Fput (var, Qlast_arrow_position,
13703 COERCE_MARKER (val));
13704 Fput (var, Qlast_arrow_string,
13705 overlay_arrow_string_or_property (var));
13707 else if (up_to_date < 0
13708 || !NILP (Fget (var, Qlast_arrow_position)))
13710 Fput (var, Qlast_arrow_position, Qt);
13711 Fput (var, Qlast_arrow_string, Qt);
13717 /* Return overlay arrow string to display at row.
13718 Return integer (bitmap number) for arrow bitmap in left fringe.
13719 Return nil if no overlay arrow. */
13721 static Lisp_Object
13722 overlay_arrow_at_row (struct it *it, struct glyph_row *row)
13724 Lisp_Object vlist;
13726 for (vlist = Voverlay_arrow_variable_list;
13727 CONSP (vlist);
13728 vlist = XCDR (vlist))
13730 Lisp_Object var = XCAR (vlist);
13731 Lisp_Object val;
13733 if (!SYMBOLP (var))
13734 continue;
13736 val = find_symbol_value (var);
13738 if (MARKERP (val)
13739 && current_buffer == XMARKER (val)->buffer
13740 && (MATRIX_ROW_START_CHARPOS (row) == marker_position (val)))
13742 if (FRAME_WINDOW_P (it->f)
13743 /* FIXME: if ROW->reversed_p is set, this should test
13744 the right fringe, not the left one. */
13745 && WINDOW_LEFT_FRINGE_WIDTH (it->w) > 0)
13747 #ifdef HAVE_WINDOW_SYSTEM
13748 if (val = Fget (var, Qoverlay_arrow_bitmap), SYMBOLP (val))
13750 int fringe_bitmap = lookup_fringe_bitmap (val);
13751 if (fringe_bitmap != 0)
13752 return make_number (fringe_bitmap);
13754 #endif
13755 return make_number (-1); /* Use default arrow bitmap. */
13757 return overlay_arrow_string_or_property (var);
13761 return Qnil;
13764 /* Return true if point moved out of or into a composition. Otherwise
13765 return false. PREV_BUF and PREV_PT are the last point buffer and
13766 position. BUF and PT are the current point buffer and position. */
13768 static bool
13769 check_point_in_composition (struct buffer *prev_buf, ptrdiff_t prev_pt,
13770 struct buffer *buf, ptrdiff_t pt)
13772 ptrdiff_t start, end;
13773 Lisp_Object prop;
13774 Lisp_Object buffer;
13776 XSETBUFFER (buffer, buf);
13777 /* Check a composition at the last point if point moved within the
13778 same buffer. */
13779 if (prev_buf == buf)
13781 if (prev_pt == pt)
13782 /* Point didn't move. */
13783 return false;
13785 if (prev_pt > BUF_BEGV (buf) && prev_pt < BUF_ZV (buf)
13786 && find_composition (prev_pt, -1, &start, &end, &prop, buffer)
13787 && composition_valid_p (start, end, prop)
13788 && start < prev_pt && end > prev_pt)
13789 /* The last point was within the composition. Return true iff
13790 point moved out of the composition. */
13791 return (pt <= start || pt >= end);
13794 /* Check a composition at the current point. */
13795 return (pt > BUF_BEGV (buf) && pt < BUF_ZV (buf)
13796 && find_composition (pt, -1, &start, &end, &prop, buffer)
13797 && composition_valid_p (start, end, prop)
13798 && start < pt && end > pt);
13801 /* Reconsider the clip changes of buffer which is displayed in W. */
13803 static void
13804 reconsider_clip_changes (struct window *w)
13806 struct buffer *b = XBUFFER (w->contents);
13808 if (b->clip_changed
13809 && w->window_end_valid
13810 && w->current_matrix->buffer == b
13811 && w->current_matrix->zv == BUF_ZV (b)
13812 && w->current_matrix->begv == BUF_BEGV (b))
13813 b->clip_changed = false;
13815 /* If display wasn't paused, and W is not a tool bar window, see if
13816 point has been moved into or out of a composition. In that case,
13817 set b->clip_changed to force updating the screen. If
13818 b->clip_changed has already been set, skip this check. */
13819 if (!b->clip_changed && w->window_end_valid)
13821 ptrdiff_t pt = (w == XWINDOW (selected_window)
13822 ? PT : marker_position (w->pointm));
13824 if ((w->current_matrix->buffer != b || pt != w->last_point)
13825 && check_point_in_composition (w->current_matrix->buffer,
13826 w->last_point, b, pt))
13827 b->clip_changed = true;
13831 static void
13832 propagate_buffer_redisplay (void)
13833 { /* Resetting b->text->redisplay is problematic!
13834 We can't just reset it in the case that some window that displays
13835 it has not been redisplayed; and such a window can stay
13836 unredisplayed for a long time if it's currently invisible.
13837 But we do want to reset it at the end of redisplay otherwise
13838 its displayed windows will keep being redisplayed over and over
13839 again.
13840 So we copy all b->text->redisplay flags up to their windows here,
13841 such that mark_window_display_accurate can safely reset
13842 b->text->redisplay. */
13843 Lisp_Object ws = window_list ();
13844 for (; CONSP (ws); ws = XCDR (ws))
13846 struct window *thisw = XWINDOW (XCAR (ws));
13847 struct buffer *thisb = XBUFFER (thisw->contents);
13848 if (thisb->text->redisplay)
13849 thisw->redisplay = true;
13853 #define STOP_POLLING \
13854 do { if (! polling_stopped_here) stop_polling (); \
13855 polling_stopped_here = true; } while (false)
13857 #define RESUME_POLLING \
13858 do { if (polling_stopped_here) start_polling (); \
13859 polling_stopped_here = false; } while (false)
13862 /* Perhaps in the future avoid recentering windows if it
13863 is not necessary; currently that causes some problems. */
13865 static void
13866 redisplay_internal (void)
13868 struct window *w = XWINDOW (selected_window);
13869 struct window *sw;
13870 struct frame *fr;
13871 bool pending;
13872 bool must_finish = false, match_p;
13873 struct text_pos tlbufpos, tlendpos;
13874 int number_of_visible_frames;
13875 ptrdiff_t count;
13876 struct frame *sf;
13877 bool polling_stopped_here = false;
13878 Lisp_Object tail, frame;
13880 /* Set a limit to the number of retries we perform due to horizontal
13881 scrolling, this avoids getting stuck in an uninterruptible
13882 infinite loop (Bug #24633). */
13883 enum { MAX_HSCROLL_RETRIES = 16 };
13884 int hscroll_retries = 0;
13886 /* Limit the number of retries for when frame(s) become garbaged as
13887 result of redisplaying them. Some packages set various redisplay
13888 hooks, such as window-scroll-functions, to run Lisp that always
13889 calls APIs which cause the frame's garbaged flag to become set,
13890 so we loop indefinitely. */
13891 enum {MAX_GARBAGED_FRAME_RETRIES = 2 };
13892 int garbaged_frame_retries = 0;
13894 /* True means redisplay has to consider all windows on all
13895 frames. False, only selected_window is considered. */
13896 bool consider_all_windows_p;
13898 /* True means redisplay has to redisplay the miniwindow. */
13899 bool update_miniwindow_p = false;
13901 TRACE ((stderr, "redisplay_internal %d\n", redisplaying_p));
13903 /* No redisplay if running in batch mode or frame is not yet fully
13904 initialized, or redisplay is explicitly turned off by setting
13905 Vinhibit_redisplay. */
13906 if (FRAME_INITIAL_P (SELECTED_FRAME ())
13907 || !NILP (Vinhibit_redisplay))
13908 return;
13910 /* Don't examine these until after testing Vinhibit_redisplay.
13911 When Emacs is shutting down, perhaps because its connection to
13912 X has dropped, we should not look at them at all. */
13913 fr = XFRAME (w->frame);
13914 sf = SELECTED_FRAME ();
13916 if (!fr->glyphs_initialized_p)
13917 return;
13919 #if defined (USE_X_TOOLKIT) || defined (USE_GTK) || defined (HAVE_NS)
13920 if (popup_activated ())
13922 #ifdef NS_IMPL_COCOA
13923 /* On macOS we may have disabled screen updates due to window
13924 resizing. We should re-enable them so the popup can be
13925 displayed. */
13926 ns_enable_screen_updates ();
13927 #endif
13928 return;
13930 #endif
13932 /* I don't think this happens but let's be paranoid. */
13933 if (redisplaying_p)
13934 return;
13936 /* Record a function that clears redisplaying_p
13937 when we leave this function. */
13938 count = SPECPDL_INDEX ();
13939 record_unwind_protect_void (unwind_redisplay);
13940 redisplaying_p = true;
13941 block_buffer_flips ();
13942 specbind (Qinhibit_free_realized_faces, Qnil);
13944 /* Record this function, so it appears on the profiler's backtraces. */
13945 record_in_backtrace (Qredisplay_internal_xC_functionx, 0, 0);
13947 FOR_EACH_FRAME (tail, frame)
13948 XFRAME (frame)->already_hscrolled_p = false;
13950 retry:
13951 /* Remember the currently selected window. */
13952 sw = w;
13954 pending = false;
13955 forget_escape_and_glyphless_faces ();
13957 inhibit_free_realized_faces = false;
13959 /* If face_change, init_iterator will free all realized faces, which
13960 includes the faces referenced from current matrices. So, we
13961 can't reuse current matrices in this case. */
13962 if (face_change)
13963 windows_or_buffers_changed = 47;
13965 if ((FRAME_TERMCAP_P (sf) || FRAME_MSDOS_P (sf))
13966 && FRAME_TTY (sf)->previous_frame != sf)
13968 /* Since frames on a single ASCII terminal share the same
13969 display area, displaying a different frame means redisplay
13970 the whole thing. */
13971 SET_FRAME_GARBAGED (sf);
13972 #ifndef DOS_NT
13973 set_tty_color_mode (FRAME_TTY (sf), sf);
13974 #endif
13975 FRAME_TTY (sf)->previous_frame = sf;
13978 /* Set the visible flags for all frames. Do this before checking for
13979 resized or garbaged frames; they want to know if their frames are
13980 visible. See the comment in frame.h for FRAME_SAMPLE_VISIBILITY. */
13981 number_of_visible_frames = 0;
13983 FOR_EACH_FRAME (tail, frame)
13985 struct frame *f = XFRAME (frame);
13987 if (FRAME_VISIBLE_P (f))
13989 ++number_of_visible_frames;
13990 /* Adjust matrices for visible frames only. */
13991 if (f->fonts_changed)
13993 adjust_frame_glyphs (f);
13994 /* Disable all redisplay optimizations for this frame.
13995 This is because adjust_frame_glyphs resets the
13996 enabled_p flag for all glyph rows of all windows, so
13997 many optimizations will fail anyway, and some might
13998 fail to test that flag and do bogus things as
13999 result. */
14000 SET_FRAME_GARBAGED (f);
14001 f->fonts_changed = false;
14003 /* If cursor type has been changed on the frame
14004 other than selected, consider all frames. */
14005 if (f != sf && f->cursor_type_changed)
14006 fset_redisplay (f);
14008 clear_desired_matrices (f);
14011 /* Notice any pending interrupt request to change frame size. */
14012 do_pending_window_change (true);
14014 /* do_pending_window_change could change the selected_window due to
14015 frame resizing which makes the selected window too small. */
14016 if (WINDOWP (selected_window) && (w = XWINDOW (selected_window)) != sw)
14017 sw = w;
14019 /* Clear frames marked as garbaged. */
14020 clear_garbaged_frames ();
14022 /* Build menubar and tool-bar items. */
14023 if (NILP (Vmemory_full))
14024 prepare_menu_bars ();
14026 reconsider_clip_changes (w);
14028 /* In most cases selected window displays current buffer. */
14029 match_p = XBUFFER (w->contents) == current_buffer;
14030 if (match_p)
14032 /* Detect case that we need to write or remove a star in the mode line. */
14033 if ((SAVE_MODIFF < MODIFF) != w->last_had_star)
14034 w->update_mode_line = true;
14036 if (mode_line_update_needed (w))
14037 w->update_mode_line = true;
14039 /* If reconsider_clip_changes above decided that the narrowing
14040 in the current buffer changed, make sure all other windows
14041 showing that buffer will be redisplayed. */
14042 if (current_buffer->clip_changed)
14043 bset_update_mode_line (current_buffer);
14046 /* Normally the message* functions will have already displayed and
14047 updated the echo area, but the frame may have been trashed, or
14048 the update may have been preempted, so display the echo area
14049 again here. Checking message_cleared_p captures the case that
14050 the echo area should be cleared. */
14051 if ((!NILP (echo_area_buffer[0]) && !display_last_displayed_message_p)
14052 || (!NILP (echo_area_buffer[1]) && display_last_displayed_message_p)
14053 || (message_cleared_p
14054 && minibuf_level == 0
14055 /* If the mini-window is currently selected, this means the
14056 echo-area doesn't show through. */
14057 && !MINI_WINDOW_P (XWINDOW (selected_window))))
14059 echo_area_display (false);
14061 /* If echo_area_display resizes the mini-window, the redisplay and
14062 window_sizes_changed flags of the selected frame are set, but
14063 it's too late for the hooks in window-size-change-functions,
14064 which have been examined already in prepare_menu_bars. So in
14065 that case we call the hooks here only for the selected frame. */
14066 if (sf->redisplay)
14068 ptrdiff_t count1 = SPECPDL_INDEX ();
14070 record_unwind_save_match_data ();
14071 run_window_size_change_functions (selected_frame);
14072 unbind_to (count1, Qnil);
14075 if (message_cleared_p)
14076 update_miniwindow_p = true;
14078 must_finish = true;
14080 /* If we don't display the current message, don't clear the
14081 message_cleared_p flag, because, if we did, we wouldn't clear
14082 the echo area in the next redisplay which doesn't preserve
14083 the echo area. */
14084 if (!display_last_displayed_message_p)
14085 message_cleared_p = false;
14087 else if (EQ (selected_window, minibuf_window)
14088 && (current_buffer->clip_changed || window_outdated (w))
14089 && resize_mini_window (w, false))
14091 if (sf->redisplay)
14093 ptrdiff_t count1 = SPECPDL_INDEX ();
14095 record_unwind_save_match_data ();
14096 run_window_size_change_functions (selected_frame);
14097 unbind_to (count1, Qnil);
14100 /* Resized active mini-window to fit the size of what it is
14101 showing if its contents might have changed. */
14102 must_finish = true;
14104 /* If window configuration was changed, frames may have been
14105 marked garbaged. Clear them or we will experience
14106 surprises wrt scrolling. */
14107 clear_garbaged_frames ();
14110 if (windows_or_buffers_changed && !update_mode_lines)
14111 /* Code that sets windows_or_buffers_changed doesn't distinguish whether
14112 only the windows's contents needs to be refreshed, or whether the
14113 mode-lines also need a refresh. */
14114 update_mode_lines = (windows_or_buffers_changed == REDISPLAY_SOME
14115 ? REDISPLAY_SOME : 32);
14117 /* If specs for an arrow have changed, do thorough redisplay
14118 to ensure we remove any arrow that should no longer exist. */
14119 /* Apparently, this is the only case where we update other windows,
14120 without updating other mode-lines. */
14121 overlay_arrows_changed_p (true);
14123 consider_all_windows_p = (update_mode_lines
14124 || windows_or_buffers_changed);
14126 #define AINC(a,i) \
14128 Lisp_Object entry = Fgethash (make_number (i), a, make_number (0)); \
14129 if (INTEGERP (entry)) \
14130 Fputhash (make_number (i), make_number (1 + XINT (entry)), a); \
14133 AINC (Vredisplay__all_windows_cause, windows_or_buffers_changed);
14134 AINC (Vredisplay__mode_lines_cause, update_mode_lines);
14136 /* Optimize the case that only the line containing the cursor in the
14137 selected window has changed. Variables starting with this_ are
14138 set in display_line and record information about the line
14139 containing the cursor. */
14140 tlbufpos = this_line_start_pos;
14141 tlendpos = this_line_end_pos;
14142 if (!consider_all_windows_p
14143 && CHARPOS (tlbufpos) > 0
14144 && !w->update_mode_line
14145 && !current_buffer->clip_changed
14146 && !current_buffer->prevent_redisplay_optimizations_p
14147 && FRAME_VISIBLE_P (XFRAME (w->frame))
14148 && !FRAME_OBSCURED_P (XFRAME (w->frame))
14149 && !XFRAME (w->frame)->cursor_type_changed
14150 && !XFRAME (w->frame)->face_change
14151 /* Make sure recorded data applies to current buffer, etc. */
14152 && this_line_buffer == current_buffer
14153 && match_p
14154 && !w->force_start
14155 && !w->optional_new_start
14156 /* Point must be on the line that we have info recorded about. */
14157 && PT >= CHARPOS (tlbufpos)
14158 && PT <= Z - CHARPOS (tlendpos)
14159 /* All text outside that line, including its final newline,
14160 must be unchanged. */
14161 && text_outside_line_unchanged_p (w, CHARPOS (tlbufpos),
14162 CHARPOS (tlendpos)))
14164 if (CHARPOS (tlbufpos) > BEGV
14165 && FETCH_BYTE (BYTEPOS (tlbufpos) - 1) != '\n'
14166 && (CHARPOS (tlbufpos) == ZV
14167 || FETCH_BYTE (BYTEPOS (tlbufpos)) == '\n'))
14168 /* Former continuation line has disappeared by becoming empty. */
14169 goto cancel;
14170 else if (window_outdated (w) || MINI_WINDOW_P (w))
14172 /* We have to handle the case of continuation around a
14173 wide-column character (see the comment in indent.c around
14174 line 1340).
14176 For instance, in the following case:
14178 -------- Insert --------
14179 K_A_N_\\ `a' K_A_N_a\ `X_' are wide-column chars.
14180 J_I_ ==> J_I_ `^^' are cursors.
14181 ^^ ^^
14182 -------- --------
14184 As we have to redraw the line above, we cannot use this
14185 optimization. */
14187 struct it it;
14188 int line_height_before = this_line_pixel_height;
14190 /* Note that start_display will handle the case that the
14191 line starting at tlbufpos is a continuation line. */
14192 start_display (&it, w, tlbufpos);
14194 /* Implementation note: It this still necessary? */
14195 if (it.current_x != this_line_start_x)
14196 goto cancel;
14198 TRACE ((stderr, "trying display optimization 1\n"));
14199 w->cursor.vpos = -1;
14200 overlay_arrow_seen = false;
14201 it.vpos = this_line_vpos;
14202 it.current_y = this_line_y;
14203 it.glyph_row = MATRIX_ROW (w->desired_matrix, this_line_vpos);
14204 display_line (&it, -1);
14206 /* If line contains point, is not continued,
14207 and ends at same distance from eob as before, we win. */
14208 if (w->cursor.vpos >= 0
14209 /* Line is not continued, otherwise this_line_start_pos
14210 would have been set to 0 in display_line. */
14211 && CHARPOS (this_line_start_pos)
14212 /* Line ends as before. */
14213 && CHARPOS (this_line_end_pos) == CHARPOS (tlendpos)
14214 /* Line has same height as before. Otherwise other lines
14215 would have to be shifted up or down. */
14216 && this_line_pixel_height == line_height_before)
14218 /* If this is not the window's last line, we must adjust
14219 the charstarts of the lines below. */
14220 if (it.current_y < it.last_visible_y)
14222 struct glyph_row *row
14223 = MATRIX_ROW (w->current_matrix, this_line_vpos + 1);
14224 ptrdiff_t delta, delta_bytes;
14226 /* We used to distinguish between two cases here,
14227 conditioned by Z - CHARPOS (tlendpos) == ZV, for
14228 when the line ends in a newline or the end of the
14229 buffer's accessible portion. But both cases did
14230 the same, so they were collapsed. */
14231 delta = (Z
14232 - CHARPOS (tlendpos)
14233 - MATRIX_ROW_START_CHARPOS (row));
14234 delta_bytes = (Z_BYTE
14235 - BYTEPOS (tlendpos)
14236 - MATRIX_ROW_START_BYTEPOS (row));
14238 increment_matrix_positions (w->current_matrix,
14239 this_line_vpos + 1,
14240 w->current_matrix->nrows,
14241 delta, delta_bytes);
14244 /* If this row displays text now but previously didn't,
14245 or vice versa, w->window_end_vpos may have to be
14246 adjusted. */
14247 if (MATRIX_ROW_DISPLAYS_TEXT_P (it.glyph_row - 1))
14249 if (w->window_end_vpos < this_line_vpos)
14250 w->window_end_vpos = this_line_vpos;
14252 else if (w->window_end_vpos == this_line_vpos
14253 && this_line_vpos > 0)
14254 w->window_end_vpos = this_line_vpos - 1;
14255 w->window_end_valid = false;
14257 /* Update hint: No need to try to scroll in update_window. */
14258 w->desired_matrix->no_scrolling_p = true;
14260 #ifdef GLYPH_DEBUG
14261 *w->desired_matrix->method = 0;
14262 debug_method_add (w, "optimization 1");
14263 #endif
14264 #ifdef HAVE_WINDOW_SYSTEM
14265 update_window_fringes (w, false);
14266 #endif
14267 goto update;
14269 else
14270 goto cancel;
14272 else if (/* Cursor position hasn't changed. */
14273 PT == w->last_point
14274 /* Make sure the cursor was last displayed
14275 in this window. Otherwise we have to reposition it. */
14277 /* PXW: Must be converted to pixels, probably. */
14278 && 0 <= w->cursor.vpos
14279 && w->cursor.vpos < WINDOW_TOTAL_LINES (w))
14281 if (!must_finish)
14283 do_pending_window_change (true);
14284 /* If selected_window changed, redisplay again. */
14285 if (WINDOWP (selected_window)
14286 && (w = XWINDOW (selected_window)) != sw)
14287 goto retry;
14289 /* We used to always goto end_of_redisplay here, but this
14290 isn't enough if we have a blinking cursor. */
14291 if (w->cursor_off_p == w->last_cursor_off_p)
14292 goto end_of_redisplay;
14294 goto update;
14296 /* If highlighting the region, or if the cursor is in the echo area,
14297 then we can't just move the cursor. */
14298 else if (NILP (Vshow_trailing_whitespace)
14299 && !cursor_in_echo_area)
14301 struct it it;
14302 struct glyph_row *row;
14304 /* Skip from tlbufpos to PT and see where it is. Note that
14305 PT may be in invisible text. If so, we will end at the
14306 next visible position. */
14307 init_iterator (&it, w, CHARPOS (tlbufpos), BYTEPOS (tlbufpos),
14308 NULL, DEFAULT_FACE_ID);
14309 it.current_x = this_line_start_x;
14310 it.current_y = this_line_y;
14311 it.vpos = this_line_vpos;
14313 /* The call to move_it_to stops in front of PT, but
14314 moves over before-strings. */
14315 move_it_to (&it, PT, -1, -1, -1, MOVE_TO_POS);
14317 if (it.vpos == this_line_vpos
14318 && (row = MATRIX_ROW (w->current_matrix, this_line_vpos),
14319 row->enabled_p))
14321 eassert (this_line_vpos == it.vpos);
14322 eassert (this_line_y == it.current_y);
14323 set_cursor_from_row (w, row, w->current_matrix, 0, 0, 0, 0);
14324 if (cursor_row_fully_visible_p (w, false, true))
14326 #ifdef GLYPH_DEBUG
14327 *w->desired_matrix->method = 0;
14328 debug_method_add (w, "optimization 3");
14329 #endif
14330 goto update;
14332 else
14333 goto cancel;
14335 else
14336 goto cancel;
14339 cancel:
14340 /* Text changed drastically or point moved off of line. */
14341 SET_MATRIX_ROW_ENABLED_P (w->desired_matrix, this_line_vpos, false);
14344 CHARPOS (this_line_start_pos) = 0;
14345 ++clear_face_cache_count;
14346 #ifdef HAVE_WINDOW_SYSTEM
14347 ++clear_image_cache_count;
14348 #endif
14350 /* Build desired matrices, and update the display. If
14351 consider_all_windows_p, do it for all windows on all frames that
14352 require redisplay, as specified by their 'redisplay' flag.
14353 Otherwise do it for selected_window, only. */
14355 if (consider_all_windows_p)
14357 FOR_EACH_FRAME (tail, frame)
14358 XFRAME (frame)->updated_p = false;
14360 propagate_buffer_redisplay ();
14362 FOR_EACH_FRAME (tail, frame)
14364 struct frame *f = XFRAME (frame);
14366 /* We don't have to do anything for unselected terminal
14367 frames. */
14368 if ((FRAME_TERMCAP_P (f) || FRAME_MSDOS_P (f))
14369 && !EQ (FRAME_TTY (f)->top_frame, frame))
14370 continue;
14372 retry_frame:
14373 if (FRAME_WINDOW_P (f) || FRAME_TERMCAP_P (f) || f == sf)
14375 bool gcscrollbars
14376 /* Only GC scrollbars when we redisplay the whole frame. */
14377 = f->redisplay || !REDISPLAY_SOME_P ();
14378 bool f_redisplay_flag = f->redisplay;
14379 /* Mark all the scroll bars to be removed; we'll redeem
14380 the ones we want when we redisplay their windows. */
14381 if (gcscrollbars && FRAME_TERMINAL (f)->condemn_scroll_bars_hook)
14382 FRAME_TERMINAL (f)->condemn_scroll_bars_hook (f);
14384 if (FRAME_VISIBLE_P (f) && !FRAME_OBSCURED_P (f))
14385 redisplay_windows (FRAME_ROOT_WINDOW (f));
14386 /* Remember that the invisible frames need to be redisplayed next
14387 time they're visible. */
14388 else if (!REDISPLAY_SOME_P ())
14389 f->redisplay = true;
14391 /* The X error handler may have deleted that frame. */
14392 if (!FRAME_LIVE_P (f))
14393 continue;
14395 /* Any scroll bars which redisplay_windows should have
14396 nuked should now go away. */
14397 if (gcscrollbars && FRAME_TERMINAL (f)->judge_scroll_bars_hook)
14398 FRAME_TERMINAL (f)->judge_scroll_bars_hook (f);
14400 if (FRAME_VISIBLE_P (f) && !FRAME_OBSCURED_P (f))
14402 /* If fonts changed on visible frame, display again. */
14403 if (f->fonts_changed)
14405 adjust_frame_glyphs (f);
14406 /* Disable all redisplay optimizations for this
14407 frame. For the reasons, see the comment near
14408 the previous call to adjust_frame_glyphs above. */
14409 SET_FRAME_GARBAGED (f);
14410 f->fonts_changed = false;
14411 goto retry_frame;
14414 /* See if we have to hscroll. */
14415 if (!f->already_hscrolled_p)
14417 f->already_hscrolled_p = true;
14418 if (hscroll_retries <= MAX_HSCROLL_RETRIES
14419 && hscroll_windows (f->root_window))
14421 hscroll_retries++;
14422 goto retry_frame;
14426 /* If the frame's redisplay flag was not set before
14427 we went about redisplaying its windows, but it is
14428 set now, that means we employed some redisplay
14429 optimizations inside redisplay_windows, and
14430 bypassed producing some screen lines. But if
14431 f->redisplay is now set, it might mean the old
14432 faces are no longer valid (e.g., if redisplaying
14433 some window called some Lisp which defined a new
14434 face or redefined an existing face), so trying to
14435 use them in update_frame will segfault.
14436 Therefore, we must redisplay this frame. */
14437 if (!f_redisplay_flag && f->redisplay)
14438 goto retry_frame;
14439 /* In some case (e.g., window resize), we notice
14440 only during window updating that the window
14441 content changed unpredictably (e.g., a GTK
14442 scrollbar moved, or some Lisp hook that winds up
14443 calling adjust_frame_glyphs) and that our
14444 previous estimation of the frame content was
14445 garbage. We have to start over. These cases
14446 should be rare, so going all the way back to the
14447 top of redisplay should be good enough. */
14448 if (FRAME_GARBAGED_P (f)
14449 && garbaged_frame_retries++ < MAX_GARBAGED_FRAME_RETRIES)
14450 goto retry;
14452 #if defined (HAVE_WINDOW_SYSTEM) && !defined (HAVE_NS)
14453 x_clear_under_internal_border (f);
14454 #endif /* HAVE_WINDOW_SYSTEM && !HAVE_NS */
14456 /* Prevent various kinds of signals during display
14457 update. stdio is not robust about handling
14458 signals, which can cause an apparent I/O error. */
14459 if (interrupt_input)
14460 unrequest_sigio ();
14461 STOP_POLLING;
14463 pending |= update_frame (f, false, false);
14464 f->cursor_type_changed = false;
14465 f->updated_p = true;
14470 eassert (EQ (XFRAME (selected_frame)->selected_window, selected_window));
14472 if (!pending)
14474 /* Do the mark_window_display_accurate after all windows have
14475 been redisplayed because this call resets flags in buffers
14476 which are needed for proper redisplay. */
14477 FOR_EACH_FRAME (tail, frame)
14479 struct frame *f = XFRAME (frame);
14480 if (f->updated_p)
14482 f->redisplay = false;
14483 f->garbaged = false;
14484 mark_window_display_accurate (f->root_window, true);
14485 if (FRAME_TERMINAL (f)->frame_up_to_date_hook)
14486 FRAME_TERMINAL (f)->frame_up_to_date_hook (f);
14491 else if (FRAME_VISIBLE_P (sf) && !FRAME_OBSCURED_P (sf))
14493 displayed_buffer = XBUFFER (XWINDOW (selected_window)->contents);
14494 /* Use list_of_error, not Qerror, so that
14495 we catch only errors and don't run the debugger. */
14496 internal_condition_case_1 (redisplay_window_1, selected_window,
14497 list_of_error,
14498 redisplay_window_error);
14499 if (update_miniwindow_p)
14500 internal_condition_case_1 (redisplay_window_1,
14501 FRAME_MINIBUF_WINDOW (sf), list_of_error,
14502 redisplay_window_error);
14504 /* Compare desired and current matrices, perform output. */
14506 update:
14507 /* If fonts changed, display again. Likewise if redisplay_window_1
14508 above caused some change (e.g., a change in faces) that requires
14509 considering the entire frame again. */
14510 if (sf->fonts_changed || sf->redisplay)
14512 if (sf->redisplay)
14514 /* Set this to force a more thorough redisplay.
14515 Otherwise, we might immediately loop back to the
14516 above "else-if" clause (since all the conditions that
14517 led here might still be true), and we will then
14518 infloop, because the selected-frame's redisplay flag
14519 is not (and cannot be) reset. */
14520 windows_or_buffers_changed = 50;
14522 goto retry;
14525 /* Prevent freeing of realized faces, since desired matrices are
14526 pending that reference the faces we computed and cached. */
14527 inhibit_free_realized_faces = true;
14529 /* Prevent various kinds of signals during display update.
14530 stdio is not robust about handling signals,
14531 which can cause an apparent I/O error. */
14532 if (interrupt_input)
14533 unrequest_sigio ();
14534 STOP_POLLING;
14536 if (FRAME_VISIBLE_P (sf) && !FRAME_OBSCURED_P (sf))
14538 if (hscroll_retries <= MAX_HSCROLL_RETRIES
14539 && hscroll_windows (selected_window))
14541 hscroll_retries++;
14542 goto retry;
14545 XWINDOW (selected_window)->must_be_updated_p = true;
14546 pending = update_frame (sf, false, false);
14547 sf->cursor_type_changed = false;
14550 /* We may have called echo_area_display at the top of this
14551 function. If the echo area is on another frame, that may
14552 have put text on a frame other than the selected one, so the
14553 above call to update_frame would not have caught it. Catch
14554 it here. */
14555 Lisp_Object mini_window = FRAME_MINIBUF_WINDOW (sf);
14556 struct frame *mini_frame = XFRAME (WINDOW_FRAME (XWINDOW (mini_window)));
14558 if (mini_frame != sf && FRAME_WINDOW_P (mini_frame))
14560 XWINDOW (mini_window)->must_be_updated_p = true;
14561 pending |= update_frame (mini_frame, false, false);
14562 mini_frame->cursor_type_changed = false;
14563 if (!pending && hscroll_retries <= MAX_HSCROLL_RETRIES
14564 && hscroll_windows (mini_window))
14566 hscroll_retries++;
14567 goto retry;
14572 /* If display was paused because of pending input, make sure we do a
14573 thorough update the next time. */
14574 if (pending)
14576 /* Prevent the optimization at the beginning of
14577 redisplay_internal that tries a single-line update of the
14578 line containing the cursor in the selected window. */
14579 CHARPOS (this_line_start_pos) = 0;
14581 /* Let the overlay arrow be updated the next time. */
14582 update_overlay_arrows (0);
14584 /* If we pause after scrolling, some rows in the current
14585 matrices of some windows are not valid. */
14586 if (!WINDOW_FULL_WIDTH_P (w)
14587 && !FRAME_WINDOW_P (XFRAME (w->frame)))
14588 update_mode_lines = 36;
14590 else
14592 if (!consider_all_windows_p)
14594 /* This has already been done above if
14595 consider_all_windows_p is set. */
14596 if (XBUFFER (w->contents)->text->redisplay
14597 && buffer_window_count (XBUFFER (w->contents)) > 1)
14598 /* This can happen if b->text->redisplay was set during
14599 jit-lock. */
14600 propagate_buffer_redisplay ();
14601 mark_window_display_accurate_1 (w, true);
14603 /* Say overlay arrows are up to date. */
14604 update_overlay_arrows (1);
14606 if (FRAME_TERMINAL (sf)->frame_up_to_date_hook != 0)
14607 FRAME_TERMINAL (sf)->frame_up_to_date_hook (sf);
14610 update_mode_lines = 0;
14611 windows_or_buffers_changed = 0;
14614 /* Start SIGIO interrupts coming again. Having them off during the
14615 code above makes it less likely one will discard output, but not
14616 impossible, since there might be stuff in the system buffer here.
14617 But it is much hairier to try to do anything about that. */
14618 if (interrupt_input)
14619 request_sigio ();
14620 RESUME_POLLING;
14622 /* If a frame has become visible which was not before, redisplay
14623 again, so that we display it. Expose events for such a frame
14624 (which it gets when becoming visible) don't call the parts of
14625 redisplay constructing glyphs, so simply exposing a frame won't
14626 display anything in this case. So, we have to display these
14627 frames here explicitly. */
14628 if (!pending)
14630 int new_count = 0;
14632 FOR_EACH_FRAME (tail, frame)
14634 if (XFRAME (frame)->visible)
14635 new_count++;
14638 if (new_count != number_of_visible_frames)
14639 windows_or_buffers_changed = 52;
14642 /* Change frame size now if a change is pending. */
14643 do_pending_window_change (true);
14645 /* If we just did a pending size change, or have additional
14646 visible frames, or selected_window changed, redisplay again. */
14647 if ((windows_or_buffers_changed && !pending)
14648 || (WINDOWP (selected_window) && (w = XWINDOW (selected_window)) != sw))
14649 goto retry;
14651 /* Clear the face and image caches.
14653 We used to do this only if consider_all_windows_p. But the cache
14654 needs to be cleared if a timer creates images in the current
14655 buffer (e.g. the test case in Bug#6230). */
14657 if (clear_face_cache_count > CLEAR_FACE_CACHE_COUNT)
14659 clear_face_cache (false);
14660 clear_face_cache_count = 0;
14663 #ifdef HAVE_WINDOW_SYSTEM
14664 if (clear_image_cache_count > CLEAR_IMAGE_CACHE_COUNT)
14666 clear_image_caches (Qnil);
14667 clear_image_cache_count = 0;
14669 #endif /* HAVE_WINDOW_SYSTEM */
14671 end_of_redisplay:
14672 #ifdef HAVE_NS
14673 ns_set_doc_edited ();
14674 #endif
14675 if (interrupt_input && interrupts_deferred)
14676 request_sigio ();
14678 unbind_to (count, Qnil);
14679 RESUME_POLLING;
14682 static void
14683 unwind_redisplay_preserve_echo_area (void)
14685 unblock_buffer_flips ();
14688 /* Redisplay, but leave alone any recent echo area message unless
14689 another message has been requested in its place.
14691 This is useful in situations where you need to redisplay but no
14692 user action has occurred, making it inappropriate for the message
14693 area to be cleared. See tracking_off and
14694 wait_reading_process_output for examples of these situations.
14696 FROM_WHERE is an integer saying from where this function was
14697 called. This is useful for debugging. */
14699 void
14700 redisplay_preserve_echo_area (int from_where)
14702 TRACE ((stderr, "redisplay_preserve_echo_area (%d)\n", from_where));
14704 block_input ();
14705 ptrdiff_t count = SPECPDL_INDEX ();
14706 record_unwind_protect_void (unwind_redisplay_preserve_echo_area);
14707 block_buffer_flips ();
14708 unblock_input ();
14710 if (!NILP (echo_area_buffer[1]))
14712 /* We have a previously displayed message, but no current
14713 message. Redisplay the previous message. */
14714 display_last_displayed_message_p = true;
14715 redisplay_internal ();
14716 display_last_displayed_message_p = false;
14718 else
14719 redisplay_internal ();
14721 flush_frame (SELECTED_FRAME ());
14722 unbind_to (count, Qnil);
14726 /* Function registered with record_unwind_protect in redisplay_internal. */
14728 static void
14729 unwind_redisplay (void)
14731 redisplaying_p = false;
14732 unblock_buffer_flips ();
14733 #ifdef NS_IMPL_COCOA
14734 /* On macOS we may have disabled screen updates due to window
14735 resizing. When redisplay completes we want to re-enable
14736 them. */
14737 ns_enable_screen_updates ();
14738 #endif
14742 /* Mark the display of leaf window W as accurate or inaccurate.
14743 If ACCURATE_P, mark display of W as accurate.
14744 If !ACCURATE_P, arrange for W to be redisplayed the next
14745 time redisplay_internal is called. */
14747 static void
14748 mark_window_display_accurate_1 (struct window *w, bool accurate_p)
14750 struct buffer *b = XBUFFER (w->contents);
14752 w->last_modified = accurate_p ? BUF_MODIFF (b) : 0;
14753 w->last_overlay_modified = accurate_p ? BUF_OVERLAY_MODIFF (b) : 0;
14754 w->last_had_star = BUF_MODIFF (b) > BUF_SAVE_MODIFF (b);
14756 if (accurate_p)
14758 b->clip_changed = false;
14759 b->prevent_redisplay_optimizations_p = false;
14760 eassert (buffer_window_count (b) > 0);
14761 /* Resetting b->text->redisplay is problematic!
14762 In order to make it safer to do it here, redisplay_internal must
14763 have copied all b->text->redisplay to their respective windows. */
14764 b->text->redisplay = false;
14766 BUF_UNCHANGED_MODIFIED (b) = BUF_MODIFF (b);
14767 BUF_OVERLAY_UNCHANGED_MODIFIED (b) = BUF_OVERLAY_MODIFF (b);
14768 BUF_BEG_UNCHANGED (b) = BUF_GPT (b) - BUF_BEG (b);
14769 BUF_END_UNCHANGED (b) = BUF_Z (b) - BUF_GPT (b);
14771 w->current_matrix->buffer = b;
14772 w->current_matrix->begv = BUF_BEGV (b);
14773 w->current_matrix->zv = BUF_ZV (b);
14775 w->last_cursor_vpos = w->cursor.vpos;
14776 w->last_cursor_off_p = w->cursor_off_p;
14778 if (w == XWINDOW (selected_window))
14779 w->last_point = BUF_PT (b);
14780 else
14781 w->last_point = marker_position (w->pointm);
14783 w->window_end_valid = true;
14784 w->update_mode_line = false;
14787 w->redisplay = !accurate_p;
14791 /* Mark the display of windows in the window tree rooted at WINDOW as
14792 accurate or inaccurate. If ACCURATE_P, mark display of
14793 windows as accurate. If !ACCURATE_P, arrange for windows to
14794 be redisplayed the next time redisplay_internal is called. */
14796 void
14797 mark_window_display_accurate (Lisp_Object window, bool accurate_p)
14799 struct window *w;
14801 for (; !NILP (window); window = w->next)
14803 w = XWINDOW (window);
14804 if (WINDOWP (w->contents))
14805 mark_window_display_accurate (w->contents, accurate_p);
14806 else
14807 mark_window_display_accurate_1 (w, accurate_p);
14810 if (accurate_p)
14811 update_overlay_arrows (1);
14812 else
14813 /* Force a thorough redisplay the next time by setting
14814 last_arrow_position and last_arrow_string to t, which is
14815 unequal to any useful value of Voverlay_arrow_... */
14816 update_overlay_arrows (-1);
14820 /* Return value in display table DP (Lisp_Char_Table *) for character
14821 C. Since a display table doesn't have any parent, we don't have to
14822 follow parent. Do not call this function directly but use the
14823 macro DISP_CHAR_VECTOR. */
14825 Lisp_Object
14826 disp_char_vector (struct Lisp_Char_Table *dp, int c)
14828 Lisp_Object val;
14830 if (ASCII_CHAR_P (c))
14832 val = dp->ascii;
14833 if (SUB_CHAR_TABLE_P (val))
14834 val = XSUB_CHAR_TABLE (val)->contents[c];
14836 else
14838 Lisp_Object table;
14840 XSETCHAR_TABLE (table, dp);
14841 val = char_table_ref (table, c);
14843 if (NILP (val))
14844 val = dp->defalt;
14845 return val;
14848 static int buffer_flip_blocked_depth;
14850 static void
14851 block_buffer_flips (void)
14853 eassert (buffer_flip_blocked_depth >= 0);
14854 buffer_flip_blocked_depth++;
14857 static void
14858 unblock_buffer_flips (void)
14860 eassert (buffer_flip_blocked_depth > 0);
14861 if (--buffer_flip_blocked_depth == 0)
14863 Lisp_Object tail, frame;
14864 block_input ();
14865 FOR_EACH_FRAME (tail, frame)
14867 struct frame *f = XFRAME (frame);
14868 if (FRAME_TERMINAL (f)->buffer_flipping_unblocked_hook)
14869 (*FRAME_TERMINAL (f)->buffer_flipping_unblocked_hook) (f);
14871 unblock_input ();
14875 bool
14876 buffer_flipping_blocked_p (void)
14878 return buffer_flip_blocked_depth > 0;
14882 /***********************************************************************
14883 Window Redisplay
14884 ***********************************************************************/
14886 /* Redisplay all leaf windows in the window tree rooted at WINDOW. */
14888 static void
14889 redisplay_windows (Lisp_Object window)
14891 while (!NILP (window))
14893 struct window *w = XWINDOW (window);
14895 if (WINDOWP (w->contents))
14896 redisplay_windows (w->contents);
14897 else if (BUFFERP (w->contents))
14899 displayed_buffer = XBUFFER (w->contents);
14900 /* Use list_of_error, not Qerror, so that
14901 we catch only errors and don't run the debugger. */
14902 internal_condition_case_1 (redisplay_window_0, window,
14903 list_of_error,
14904 redisplay_window_error);
14907 window = w->next;
14911 static Lisp_Object
14912 redisplay_window_error (Lisp_Object ignore)
14914 displayed_buffer->display_error_modiff = BUF_MODIFF (displayed_buffer);
14915 return Qnil;
14918 static Lisp_Object
14919 redisplay_window_0 (Lisp_Object window)
14921 if (displayed_buffer->display_error_modiff < BUF_MODIFF (displayed_buffer))
14922 redisplay_window (window, false);
14923 return Qnil;
14926 static Lisp_Object
14927 redisplay_window_1 (Lisp_Object window)
14929 if (displayed_buffer->display_error_modiff < BUF_MODIFF (displayed_buffer))
14930 redisplay_window (window, true);
14931 return Qnil;
14935 /* Set cursor position of W. PT is assumed to be displayed in ROW.
14936 DELTA and DELTA_BYTES are the numbers of characters and bytes by
14937 which positions recorded in ROW differ from current buffer
14938 positions.
14940 Return true iff cursor is on this row. */
14942 static bool
14943 set_cursor_from_row (struct window *w, struct glyph_row *row,
14944 struct glyph_matrix *matrix,
14945 ptrdiff_t delta, ptrdiff_t delta_bytes,
14946 int dy, int dvpos)
14948 struct glyph *glyph = row->glyphs[TEXT_AREA];
14949 struct glyph *end = glyph + row->used[TEXT_AREA];
14950 struct glyph *cursor = NULL;
14951 /* The last known character position in row. */
14952 ptrdiff_t last_pos = MATRIX_ROW_START_CHARPOS (row) + delta;
14953 int x = row->x;
14954 ptrdiff_t pt_old = PT - delta;
14955 ptrdiff_t pos_before = MATRIX_ROW_START_CHARPOS (row) + delta;
14956 ptrdiff_t pos_after = MATRIX_ROW_END_CHARPOS (row) + delta;
14957 struct glyph *glyph_before = glyph - 1, *glyph_after = end;
14958 /* A glyph beyond the edge of TEXT_AREA which we should never
14959 touch. */
14960 struct glyph *glyphs_end = end;
14961 /* True means we've found a match for cursor position, but that
14962 glyph has the avoid_cursor_p flag set. */
14963 bool match_with_avoid_cursor = false;
14964 /* True means we've seen at least one glyph that came from a
14965 display string. */
14966 bool string_seen = false;
14967 /* Largest and smallest buffer positions seen so far during scan of
14968 glyph row. */
14969 ptrdiff_t bpos_max = pos_before;
14970 ptrdiff_t bpos_min = pos_after;
14971 /* Last buffer position covered by an overlay string with an integer
14972 `cursor' property. */
14973 ptrdiff_t bpos_covered = 0;
14974 /* True means the display string on which to display the cursor
14975 comes from a text property, not from an overlay. */
14976 bool string_from_text_prop = false;
14978 /* Don't even try doing anything if called for a mode-line or
14979 header-line row, since the rest of the code isn't prepared to
14980 deal with such calamities. */
14981 eassert (!row->mode_line_p);
14982 if (row->mode_line_p)
14983 return false;
14985 /* Skip over glyphs not having an object at the start and the end of
14986 the row. These are special glyphs like truncation marks on
14987 terminal frames. */
14988 if (MATRIX_ROW_DISPLAYS_TEXT_P (row))
14990 if (!row->reversed_p)
14992 while (glyph < end
14993 && NILP (glyph->object)
14994 && glyph->charpos < 0)
14996 x += glyph->pixel_width;
14997 ++glyph;
14999 while (end > glyph
15000 && NILP ((end - 1)->object)
15001 /* CHARPOS is zero for blanks and stretch glyphs
15002 inserted by extend_face_to_end_of_line. */
15003 && (end - 1)->charpos <= 0)
15004 --end;
15005 glyph_before = glyph - 1;
15006 glyph_after = end;
15008 else
15010 struct glyph *g;
15012 /* If the glyph row is reversed, we need to process it from back
15013 to front, so swap the edge pointers. */
15014 glyphs_end = end = glyph - 1;
15015 glyph += row->used[TEXT_AREA] - 1;
15017 while (glyph > end + 1
15018 && NILP (glyph->object)
15019 && glyph->charpos < 0)
15020 --glyph;
15021 if (NILP (glyph->object) && glyph->charpos < 0)
15022 --glyph;
15023 /* By default, in reversed rows we put the cursor on the
15024 rightmost (first in the reading order) glyph. */
15025 for (x = 0, g = end + 1; g < glyph; g++)
15026 x += g->pixel_width;
15027 while (end < glyph
15028 && NILP ((end + 1)->object)
15029 && (end + 1)->charpos <= 0)
15030 ++end;
15031 glyph_before = glyph + 1;
15032 glyph_after = end;
15035 else if (row->reversed_p)
15037 /* In R2L rows that don't display text, put the cursor on the
15038 rightmost glyph. Case in point: an empty last line that is
15039 part of an R2L paragraph. */
15040 cursor = end - 1;
15041 /* Avoid placing the cursor on the last glyph of the row, where
15042 on terminal frames we hold the vertical border between
15043 adjacent windows. */
15044 if (!FRAME_WINDOW_P (WINDOW_XFRAME (w))
15045 && !WINDOW_RIGHTMOST_P (w)
15046 && cursor == row->glyphs[LAST_AREA] - 1)
15047 cursor--;
15048 x = -1; /* will be computed below, at label compute_x */
15051 /* Step 1: Try to find the glyph whose character position
15052 corresponds to point. If that's not possible, find 2 glyphs
15053 whose character positions are the closest to point, one before
15054 point, the other after it. */
15055 if (!row->reversed_p)
15056 while (/* not marched to end of glyph row */
15057 glyph < end
15058 /* glyph was not inserted by redisplay for internal purposes */
15059 && !NILP (glyph->object))
15061 if (BUFFERP (glyph->object))
15063 ptrdiff_t dpos = glyph->charpos - pt_old;
15065 if (glyph->charpos > bpos_max)
15066 bpos_max = glyph->charpos;
15067 if (glyph->charpos < bpos_min)
15068 bpos_min = glyph->charpos;
15069 if (!glyph->avoid_cursor_p)
15071 /* If we hit point, we've found the glyph on which to
15072 display the cursor. */
15073 if (dpos == 0)
15075 match_with_avoid_cursor = false;
15076 break;
15078 /* See if we've found a better approximation to
15079 POS_BEFORE or to POS_AFTER. */
15080 if (0 > dpos && dpos > pos_before - pt_old)
15082 pos_before = glyph->charpos;
15083 glyph_before = glyph;
15085 else if (0 < dpos && dpos < pos_after - pt_old)
15087 pos_after = glyph->charpos;
15088 glyph_after = glyph;
15091 else if (dpos == 0)
15092 match_with_avoid_cursor = true;
15094 else if (STRINGP (glyph->object))
15096 Lisp_Object chprop;
15097 ptrdiff_t glyph_pos = glyph->charpos;
15099 chprop = Fget_char_property (make_number (glyph_pos), Qcursor,
15100 glyph->object);
15101 if (!NILP (chprop))
15103 /* If the string came from a `display' text property,
15104 look up the buffer position of that property and
15105 use that position to update bpos_max, as if we
15106 actually saw such a position in one of the row's
15107 glyphs. This helps with supporting integer values
15108 of `cursor' property on the display string in
15109 situations where most or all of the row's buffer
15110 text is completely covered by display properties,
15111 so that no glyph with valid buffer positions is
15112 ever seen in the row. */
15113 ptrdiff_t prop_pos =
15114 string_buffer_position_lim (glyph->object, pos_before,
15115 pos_after, false);
15117 if (prop_pos >= pos_before)
15118 bpos_max = prop_pos;
15120 if (INTEGERP (chprop))
15122 bpos_covered = bpos_max + XINT (chprop);
15123 /* If the `cursor' property covers buffer positions up
15124 to and including point, we should display cursor on
15125 this glyph. Note that, if a `cursor' property on one
15126 of the string's characters has an integer value, we
15127 will break out of the loop below _before_ we get to
15128 the position match above. IOW, integer values of
15129 the `cursor' property override the "exact match for
15130 point" strategy of positioning the cursor. */
15131 /* Implementation note: bpos_max == pt_old when, e.g.,
15132 we are in an empty line, where bpos_max is set to
15133 MATRIX_ROW_START_CHARPOS, see above. */
15134 if (bpos_max <= pt_old && bpos_covered >= pt_old)
15136 cursor = glyph;
15137 break;
15141 string_seen = true;
15143 x += glyph->pixel_width;
15144 ++glyph;
15146 else if (glyph > end) /* row is reversed */
15147 while (!NILP (glyph->object))
15149 if (BUFFERP (glyph->object))
15151 ptrdiff_t dpos = glyph->charpos - pt_old;
15153 if (glyph->charpos > bpos_max)
15154 bpos_max = glyph->charpos;
15155 if (glyph->charpos < bpos_min)
15156 bpos_min = glyph->charpos;
15157 if (!glyph->avoid_cursor_p)
15159 if (dpos == 0)
15161 match_with_avoid_cursor = false;
15162 break;
15164 if (0 > dpos && dpos > pos_before - pt_old)
15166 pos_before = glyph->charpos;
15167 glyph_before = glyph;
15169 else if (0 < dpos && dpos < pos_after - pt_old)
15171 pos_after = glyph->charpos;
15172 glyph_after = glyph;
15175 else if (dpos == 0)
15176 match_with_avoid_cursor = true;
15178 else if (STRINGP (glyph->object))
15180 Lisp_Object chprop;
15181 ptrdiff_t glyph_pos = glyph->charpos;
15183 chprop = Fget_char_property (make_number (glyph_pos), Qcursor,
15184 glyph->object);
15185 if (!NILP (chprop))
15187 ptrdiff_t prop_pos =
15188 string_buffer_position_lim (glyph->object, pos_before,
15189 pos_after, false);
15191 if (prop_pos >= pos_before)
15192 bpos_max = prop_pos;
15194 if (INTEGERP (chprop))
15196 bpos_covered = bpos_max + XINT (chprop);
15197 /* If the `cursor' property covers buffer positions up
15198 to and including point, we should display cursor on
15199 this glyph. */
15200 if (bpos_max <= pt_old && bpos_covered >= pt_old)
15202 cursor = glyph;
15203 break;
15206 string_seen = true;
15208 --glyph;
15209 if (glyph == glyphs_end) /* don't dereference outside TEXT_AREA */
15211 x--; /* can't use any pixel_width */
15212 break;
15214 x -= glyph->pixel_width;
15217 /* Step 2: If we didn't find an exact match for point, we need to
15218 look for a proper place to put the cursor among glyphs between
15219 GLYPH_BEFORE and GLYPH_AFTER. */
15220 if (!((row->reversed_p ? glyph > glyphs_end : glyph < glyphs_end)
15221 && BUFFERP (glyph->object) && glyph->charpos == pt_old)
15222 && !(bpos_max <= pt_old && pt_old <= bpos_covered))
15224 /* An empty line has a single glyph whose OBJECT is nil and
15225 whose CHARPOS is the position of a newline on that line.
15226 Note that on a TTY, there are more glyphs after that, which
15227 were produced by extend_face_to_end_of_line, but their
15228 CHARPOS is zero or negative. */
15229 bool empty_line_p =
15230 ((row->reversed_p ? glyph > glyphs_end : glyph < glyphs_end)
15231 && NILP (glyph->object) && glyph->charpos > 0
15232 /* On a TTY, continued and truncated rows also have a glyph at
15233 their end whose OBJECT is nil and whose CHARPOS is
15234 positive (the continuation and truncation glyphs), but such
15235 rows are obviously not "empty". */
15236 && !(row->continued_p || row->truncated_on_right_p));
15238 if (row->ends_in_ellipsis_p && pos_after == last_pos)
15240 ptrdiff_t ellipsis_pos;
15242 /* Scan back over the ellipsis glyphs. */
15243 if (!row->reversed_p)
15245 ellipsis_pos = (glyph - 1)->charpos;
15246 while (glyph > row->glyphs[TEXT_AREA]
15247 && (glyph - 1)->charpos == ellipsis_pos)
15248 glyph--, x -= glyph->pixel_width;
15249 /* That loop always goes one position too far, including
15250 the glyph before the ellipsis. So scan forward over
15251 that one. */
15252 x += glyph->pixel_width;
15253 glyph++;
15255 else /* row is reversed */
15257 ellipsis_pos = (glyph + 1)->charpos;
15258 while (glyph < row->glyphs[TEXT_AREA] + row->used[TEXT_AREA] - 1
15259 && (glyph + 1)->charpos == ellipsis_pos)
15260 glyph++, x += glyph->pixel_width;
15261 x -= glyph->pixel_width;
15262 glyph--;
15265 else if (match_with_avoid_cursor)
15267 cursor = glyph_after;
15268 x = -1;
15270 else if (string_seen)
15272 int incr = row->reversed_p ? -1 : +1;
15274 /* Need to find the glyph that came out of a string which is
15275 present at point. That glyph is somewhere between
15276 GLYPH_BEFORE and GLYPH_AFTER, and it came from a string
15277 positioned between POS_BEFORE and POS_AFTER in the
15278 buffer. */
15279 struct glyph *start, *stop;
15280 ptrdiff_t pos = pos_before;
15282 x = -1;
15284 /* If the row ends in a newline from a display string,
15285 reordering could have moved the glyphs belonging to the
15286 string out of the [GLYPH_BEFORE..GLYPH_AFTER] range. So
15287 in this case we extend the search to the last glyph in
15288 the row that was not inserted by redisplay. */
15289 if (row->ends_in_newline_from_string_p)
15291 glyph_after = end;
15292 pos_after = MATRIX_ROW_END_CHARPOS (row) + delta;
15295 /* GLYPH_BEFORE and GLYPH_AFTER are the glyphs that
15296 correspond to POS_BEFORE and POS_AFTER, respectively. We
15297 need START and STOP in the order that corresponds to the
15298 row's direction as given by its reversed_p flag. If the
15299 directionality of characters between POS_BEFORE and
15300 POS_AFTER is the opposite of the row's base direction,
15301 these characters will have been reordered for display,
15302 and we need to reverse START and STOP. */
15303 if (!row->reversed_p)
15305 start = min (glyph_before, glyph_after);
15306 stop = max (glyph_before, glyph_after);
15308 else
15310 start = max (glyph_before, glyph_after);
15311 stop = min (glyph_before, glyph_after);
15313 for (glyph = start + incr;
15314 row->reversed_p ? glyph > stop : glyph < stop; )
15317 /* Any glyphs that come from the buffer are here because
15318 of bidi reordering. Skip them, and only pay
15319 attention to glyphs that came from some string. */
15320 if (STRINGP (glyph->object))
15322 Lisp_Object str;
15323 ptrdiff_t tem;
15324 /* If the display property covers the newline, we
15325 need to search for it one position farther. */
15326 ptrdiff_t lim = pos_after
15327 + (pos_after == MATRIX_ROW_END_CHARPOS (row) + delta);
15329 string_from_text_prop = false;
15330 str = glyph->object;
15331 tem = string_buffer_position_lim (str, pos, lim, false);
15332 if (tem == 0 /* from overlay */
15333 || pos <= tem)
15335 /* If the string from which this glyph came is
15336 found in the buffer at point, or at position
15337 that is closer to point than pos_after, then
15338 we've found the glyph we've been looking for.
15339 If it comes from an overlay (tem == 0), and
15340 it has the `cursor' property on one of its
15341 glyphs, record that glyph as a candidate for
15342 displaying the cursor. (As in the
15343 unidirectional version, we will display the
15344 cursor on the last candidate we find.) */
15345 if (tem == 0
15346 || tem == pt_old
15347 || (tem - pt_old > 0 && tem < pos_after))
15349 /* The glyphs from this string could have
15350 been reordered. Find the one with the
15351 smallest string position. Or there could
15352 be a character in the string with the
15353 `cursor' property, which means display
15354 cursor on that character's glyph. */
15355 ptrdiff_t strpos = glyph->charpos;
15357 if (tem)
15359 cursor = glyph;
15360 string_from_text_prop = true;
15362 for ( ;
15363 (row->reversed_p ? glyph > stop : glyph < stop)
15364 && EQ (glyph->object, str);
15365 glyph += incr)
15367 Lisp_Object cprop;
15368 ptrdiff_t gpos = glyph->charpos;
15370 cprop = Fget_char_property (make_number (gpos),
15371 Qcursor,
15372 glyph->object);
15373 if (!NILP (cprop))
15375 cursor = glyph;
15376 break;
15378 if (tem && glyph->charpos < strpos)
15380 strpos = glyph->charpos;
15381 cursor = glyph;
15385 if (tem == pt_old
15386 || (tem - pt_old > 0 && tem < pos_after))
15387 goto compute_x;
15389 if (tem)
15390 pos = tem + 1; /* don't find previous instances */
15392 /* This string is not what we want; skip all of the
15393 glyphs that came from it. */
15394 while ((row->reversed_p ? glyph > stop : glyph < stop)
15395 && EQ (glyph->object, str))
15396 glyph += incr;
15398 else
15399 glyph += incr;
15402 /* If we reached the end of the line, and END was from a string,
15403 the cursor is not on this line. */
15404 if (cursor == NULL
15405 && (row->reversed_p ? glyph <= end : glyph >= end)
15406 && (row->reversed_p ? end > glyphs_end : end < glyphs_end)
15407 && STRINGP (end->object)
15408 && row->continued_p)
15409 return false;
15411 /* A truncated row may not include PT among its character positions.
15412 Setting the cursor inside the scroll margin will trigger
15413 recalculation of hscroll in hscroll_window_tree. But if a
15414 display string covers point, defer to the string-handling
15415 code below to figure this out. */
15416 else if (row->truncated_on_left_p && pt_old < bpos_min)
15418 cursor = glyph_before;
15419 x = -1;
15421 else if ((row->truncated_on_right_p && pt_old > bpos_max)
15422 /* Zero-width characters produce no glyphs. */
15423 || (!empty_line_p
15424 && (row->reversed_p
15425 ? glyph_after > glyphs_end
15426 : glyph_after < glyphs_end)))
15428 cursor = glyph_after;
15429 x = -1;
15433 compute_x:
15434 if (cursor != NULL)
15435 glyph = cursor;
15436 else if (glyph == glyphs_end
15437 && pos_before == pos_after
15438 && STRINGP ((row->reversed_p
15439 ? row->glyphs[TEXT_AREA] + row->used[TEXT_AREA] - 1
15440 : row->glyphs[TEXT_AREA])->object))
15442 /* If all the glyphs of this row came from strings, put the
15443 cursor on the first glyph of the row. This avoids having the
15444 cursor outside of the text area in this very rare and hard
15445 use case. */
15446 glyph =
15447 row->reversed_p
15448 ? row->glyphs[TEXT_AREA] + row->used[TEXT_AREA] - 1
15449 : row->glyphs[TEXT_AREA];
15451 if (x < 0)
15453 struct glyph *g;
15455 /* Need to compute x that corresponds to GLYPH. */
15456 for (g = row->glyphs[TEXT_AREA], x = row->x; g < glyph; g++)
15458 if (g >= row->glyphs[TEXT_AREA] + row->used[TEXT_AREA])
15459 emacs_abort ();
15460 x += g->pixel_width;
15464 /* ROW could be part of a continued line, which, under bidi
15465 reordering, might have other rows whose start and end charpos
15466 occlude point. Only set w->cursor if we found a better
15467 approximation to the cursor position than we have from previously
15468 examined candidate rows belonging to the same continued line. */
15469 if (/* We already have a candidate row. */
15470 w->cursor.vpos >= 0
15471 /* That candidate is not the row we are processing. */
15472 && MATRIX_ROW (matrix, w->cursor.vpos) != row
15473 /* Make sure cursor.vpos specifies a row whose start and end
15474 charpos occlude point, and it is valid candidate for being a
15475 cursor-row. This is because some callers of this function
15476 leave cursor.vpos at the row where the cursor was displayed
15477 during the last redisplay cycle. */
15478 && MATRIX_ROW_START_CHARPOS (MATRIX_ROW (matrix, w->cursor.vpos)) <= pt_old
15479 && pt_old <= MATRIX_ROW_END_CHARPOS (MATRIX_ROW (matrix, w->cursor.vpos))
15480 && cursor_row_p (MATRIX_ROW (matrix, w->cursor.vpos)))
15482 struct glyph *g1
15483 = MATRIX_ROW_GLYPH_START (matrix, w->cursor.vpos) + w->cursor.hpos;
15485 /* Don't consider glyphs that are outside TEXT_AREA. */
15486 if (!(row->reversed_p ? glyph > glyphs_end : glyph < glyphs_end))
15487 return false;
15488 /* Keep the candidate whose buffer position is the closest to
15489 point or has the `cursor' property. */
15490 if (/* Previous candidate is a glyph in TEXT_AREA of that row. */
15491 w->cursor.hpos >= 0
15492 && w->cursor.hpos < MATRIX_ROW_USED (matrix, w->cursor.vpos)
15493 && ((BUFFERP (g1->object)
15494 && (g1->charpos == pt_old /* An exact match always wins. */
15495 || (BUFFERP (glyph->object)
15496 && eabs (g1->charpos - pt_old)
15497 < eabs (glyph->charpos - pt_old))))
15498 /* Previous candidate is a glyph from a string that has
15499 a non-nil `cursor' property. */
15500 || (STRINGP (g1->object)
15501 && (!NILP (Fget_char_property (make_number (g1->charpos),
15502 Qcursor, g1->object))
15503 /* Previous candidate is from the same display
15504 string as this one, and the display string
15505 came from a text property. */
15506 || (EQ (g1->object, glyph->object)
15507 && string_from_text_prop)
15508 /* this candidate is from newline and its
15509 position is not an exact match */
15510 || (NILP (glyph->object)
15511 && glyph->charpos != pt_old)))))
15512 return false;
15513 /* If this candidate gives an exact match, use that. */
15514 if (!((BUFFERP (glyph->object) && glyph->charpos == pt_old)
15515 /* If this candidate is a glyph created for the
15516 terminating newline of a line, and point is on that
15517 newline, it wins because it's an exact match. */
15518 || (!row->continued_p
15519 && NILP (glyph->object)
15520 && glyph->charpos == 0
15521 && pt_old == MATRIX_ROW_END_CHARPOS (row) - 1))
15522 /* Otherwise, keep the candidate that comes from a row
15523 spanning less buffer positions. This may win when one or
15524 both candidate positions are on glyphs that came from
15525 display strings, for which we cannot compare buffer
15526 positions. */
15527 && MATRIX_ROW_END_CHARPOS (MATRIX_ROW (matrix, w->cursor.vpos))
15528 - MATRIX_ROW_START_CHARPOS (MATRIX_ROW (matrix, w->cursor.vpos))
15529 < MATRIX_ROW_END_CHARPOS (row) - MATRIX_ROW_START_CHARPOS (row))
15530 return false;
15532 w->cursor.hpos = glyph - row->glyphs[TEXT_AREA];
15533 w->cursor.x = x;
15534 w->cursor.vpos = MATRIX_ROW_VPOS (row, matrix) + dvpos;
15535 w->cursor.y = row->y + dy;
15537 if (w == XWINDOW (selected_window))
15539 if (!row->continued_p
15540 && !MATRIX_ROW_CONTINUATION_LINE_P (row)
15541 && row->x == 0)
15543 this_line_buffer = XBUFFER (w->contents);
15545 CHARPOS (this_line_start_pos)
15546 = MATRIX_ROW_START_CHARPOS (row) + delta;
15547 BYTEPOS (this_line_start_pos)
15548 = MATRIX_ROW_START_BYTEPOS (row) + delta_bytes;
15550 CHARPOS (this_line_end_pos)
15551 = Z - (MATRIX_ROW_END_CHARPOS (row) + delta);
15552 BYTEPOS (this_line_end_pos)
15553 = Z_BYTE - (MATRIX_ROW_END_BYTEPOS (row) + delta_bytes);
15555 this_line_y = w->cursor.y;
15556 this_line_pixel_height = row->height;
15557 this_line_vpos = w->cursor.vpos;
15558 this_line_start_x = row->x;
15560 else
15561 CHARPOS (this_line_start_pos) = 0;
15564 return true;
15568 /* Run window scroll functions, if any, for WINDOW with new window
15569 start STARTP. Sets the window start of WINDOW to that position.
15571 We assume that the window's buffer is really current. */
15573 static struct text_pos
15574 run_window_scroll_functions (Lisp_Object window, struct text_pos startp)
15576 struct window *w = XWINDOW (window);
15577 SET_MARKER_FROM_TEXT_POS (w->start, startp);
15579 eassert (current_buffer == XBUFFER (w->contents));
15581 if (!NILP (Vwindow_scroll_functions))
15583 run_hook_with_args_2 (Qwindow_scroll_functions, window,
15584 make_number (CHARPOS (startp)));
15585 SET_TEXT_POS_FROM_MARKER (startp, w->start);
15586 /* In case the hook functions switch buffers. */
15587 set_buffer_internal (XBUFFER (w->contents));
15590 return startp;
15594 /* Make sure the line containing the cursor is fully visible.
15595 A value of true means there is nothing to be done.
15596 (Either the line is fully visible, or it cannot be made so,
15597 or we cannot tell.)
15599 If FORCE_P, return false even if partial visible cursor row
15600 is higher than window.
15602 If CURRENT_MATRIX_P, use the information from the
15603 window's current glyph matrix; otherwise use the desired glyph
15604 matrix.
15606 A value of false means the caller should do scrolling
15607 as if point had gone off the screen. */
15609 static bool
15610 cursor_row_fully_visible_p (struct window *w, bool force_p,
15611 bool current_matrix_p)
15613 struct glyph_matrix *matrix;
15614 struct glyph_row *row;
15615 int window_height;
15617 if (!make_cursor_line_fully_visible_p)
15618 return true;
15620 /* It's not always possible to find the cursor, e.g, when a window
15621 is full of overlay strings. Don't do anything in that case. */
15622 if (w->cursor.vpos < 0)
15623 return true;
15625 matrix = current_matrix_p ? w->current_matrix : w->desired_matrix;
15626 row = MATRIX_ROW (matrix, w->cursor.vpos);
15628 /* If the cursor row is not partially visible, there's nothing to do. */
15629 if (!MATRIX_ROW_PARTIALLY_VISIBLE_P (w, row))
15630 return true;
15632 /* If the row the cursor is in is taller than the window's height,
15633 it's not clear what to do, so do nothing. */
15634 window_height = window_box_height (w);
15635 if (row->height >= window_height)
15637 if (!force_p || MINI_WINDOW_P (w)
15638 || w->vscroll || w->cursor.vpos == 0)
15639 return true;
15641 return false;
15645 /* Try scrolling PT into view in window WINDOW. JUST_THIS_ONE_P
15646 means only WINDOW is redisplayed in redisplay_internal.
15647 TEMP_SCROLL_STEP has the same meaning as emacs_scroll_step, and is used
15648 in redisplay_window to bring a partially visible line into view in
15649 the case that only the cursor has moved.
15651 LAST_LINE_MISFIT should be true if we're scrolling because the
15652 last screen line's vertical height extends past the end of the screen.
15654 Value is
15656 1 if scrolling succeeded
15658 0 if scrolling didn't find point.
15660 -1 if new fonts have been loaded so that we must interrupt
15661 redisplay, adjust glyph matrices, and try again. */
15663 enum
15665 SCROLLING_SUCCESS,
15666 SCROLLING_FAILED,
15667 SCROLLING_NEED_LARGER_MATRICES
15670 /* If scroll-conservatively is more than this, never recenter.
15672 If you change this, don't forget to update the doc string of
15673 `scroll-conservatively' and the Emacs manual. */
15674 #define SCROLL_LIMIT 100
15676 static int
15677 try_scrolling (Lisp_Object window, bool just_this_one_p,
15678 ptrdiff_t arg_scroll_conservatively, ptrdiff_t scroll_step,
15679 bool temp_scroll_step, bool last_line_misfit)
15681 struct window *w = XWINDOW (window);
15682 struct text_pos pos, startp;
15683 struct it it;
15684 int this_scroll_margin, scroll_max, rc, height;
15685 int dy = 0, amount_to_scroll = 0;
15686 bool scroll_down_p = false;
15687 int extra_scroll_margin_lines = last_line_misfit;
15688 Lisp_Object aggressive;
15689 /* We will never try scrolling more than this number of lines. */
15690 int scroll_limit = SCROLL_LIMIT;
15691 int frame_line_height = default_line_pixel_height (w);
15693 #ifdef GLYPH_DEBUG
15694 debug_method_add (w, "try_scrolling");
15695 #endif
15697 SET_TEXT_POS_FROM_MARKER (startp, w->start);
15699 this_scroll_margin = window_scroll_margin (w, MARGIN_IN_PIXELS);
15701 /* Force arg_scroll_conservatively to have a reasonable value, to
15702 avoid scrolling too far away with slow move_it_* functions. Note
15703 that the user can supply scroll-conservatively equal to
15704 `most-positive-fixnum', which can be larger than INT_MAX. */
15705 if (arg_scroll_conservatively > scroll_limit)
15707 arg_scroll_conservatively = scroll_limit + 1;
15708 scroll_max = scroll_limit * frame_line_height;
15710 else if (scroll_step || arg_scroll_conservatively || temp_scroll_step)
15711 /* Compute how much we should try to scroll maximally to bring
15712 point into view. */
15713 scroll_max = (max (scroll_step,
15714 max (arg_scroll_conservatively, temp_scroll_step))
15715 * frame_line_height);
15716 else if (NUMBERP (BVAR (current_buffer, scroll_down_aggressively))
15717 || NUMBERP (BVAR (current_buffer, scroll_up_aggressively)))
15718 /* We're trying to scroll because of aggressive scrolling but no
15719 scroll_step is set. Choose an arbitrary one. */
15720 scroll_max = 10 * frame_line_height;
15721 else
15722 scroll_max = 0;
15724 too_near_end:
15726 /* Decide whether to scroll down. */
15727 if (PT > CHARPOS (startp))
15729 int scroll_margin_y;
15731 /* Compute the pixel ypos of the scroll margin, then move IT to
15732 either that ypos or PT, whichever comes first. */
15733 start_display (&it, w, startp);
15734 scroll_margin_y = it.last_visible_y - partial_line_height (&it)
15735 - this_scroll_margin
15736 - frame_line_height * extra_scroll_margin_lines;
15737 move_it_to (&it, PT, -1, scroll_margin_y - 1, -1,
15738 (MOVE_TO_POS | MOVE_TO_Y));
15740 if (PT > CHARPOS (it.current.pos))
15742 int y0 = line_bottom_y (&it);
15743 /* Compute how many pixels below window bottom to stop searching
15744 for PT. This avoids costly search for PT that is far away if
15745 the user limited scrolling by a small number of lines, but
15746 always finds PT if scroll_conservatively is set to a large
15747 number, such as most-positive-fixnum. */
15748 int slack = max (scroll_max, 10 * frame_line_height);
15749 int y_to_move = it.last_visible_y + slack;
15751 /* Compute the distance from the scroll margin to PT or to
15752 the scroll limit, whichever comes first. This should
15753 include the height of the cursor line, to make that line
15754 fully visible. */
15755 move_it_to (&it, PT, -1, y_to_move,
15756 -1, MOVE_TO_POS | MOVE_TO_Y);
15757 dy = line_bottom_y (&it) - y0;
15759 if (dy > scroll_max)
15760 return SCROLLING_FAILED;
15762 if (dy > 0)
15763 scroll_down_p = true;
15765 else if (PT == IT_CHARPOS (it)
15766 && IT_CHARPOS (it) < ZV
15767 && it.method == GET_FROM_STRING
15768 && arg_scroll_conservatively > scroll_limit
15769 && it.current_x == 0)
15771 enum move_it_result skip;
15772 int y1 = it.current_y;
15773 int vpos;
15775 /* A before-string that includes newlines and is displayed
15776 on the last visible screen line could fail us under
15777 scroll-conservatively > 100, because we will be unable to
15778 position the cursor on that last visible line. Try to
15779 recover by finding the first screen line that has some
15780 glyphs coming from the buffer text. */
15781 do {
15782 skip = move_it_in_display_line_to (&it, ZV, -1, MOVE_TO_POS);
15783 if (skip != MOVE_NEWLINE_OR_CR
15784 || IT_CHARPOS (it) != PT
15785 || it.method == GET_FROM_BUFFER)
15786 break;
15787 vpos = it.vpos;
15788 move_it_to (&it, -1, -1, -1, vpos + 1, MOVE_TO_VPOS);
15789 } while (it.vpos > vpos);
15791 dy = it.current_y - y1;
15793 if (dy > scroll_max)
15794 return SCROLLING_FAILED;
15796 if (dy > 0)
15797 scroll_down_p = true;
15801 if (scroll_down_p)
15803 /* Point is in or below the bottom scroll margin, so move the
15804 window start down. If scrolling conservatively, move it just
15805 enough down to make point visible. If scroll_step is set,
15806 move it down by scroll_step. */
15807 if (arg_scroll_conservatively)
15808 amount_to_scroll
15809 = min (max (dy, frame_line_height),
15810 frame_line_height * arg_scroll_conservatively);
15811 else if (scroll_step || temp_scroll_step)
15812 amount_to_scroll = scroll_max;
15813 else
15815 aggressive = BVAR (current_buffer, scroll_up_aggressively);
15816 height = WINDOW_BOX_TEXT_HEIGHT (w);
15817 if (NUMBERP (aggressive))
15819 double float_amount = XFLOATINT (aggressive) * height;
15820 int aggressive_scroll = float_amount;
15821 if (aggressive_scroll == 0 && float_amount > 0)
15822 aggressive_scroll = 1;
15823 /* Don't let point enter the scroll margin near top of
15824 the window. This could happen if the value of
15825 scroll_up_aggressively is too large and there are
15826 non-zero margins, because scroll_up_aggressively
15827 means put point that fraction of window height
15828 _from_the_bottom_margin_. */
15829 if (aggressive_scroll + 2 * this_scroll_margin > height)
15830 aggressive_scroll = height - 2 * this_scroll_margin;
15831 amount_to_scroll = dy + aggressive_scroll;
15835 if (amount_to_scroll <= 0)
15836 return SCROLLING_FAILED;
15838 start_display (&it, w, startp);
15839 if (arg_scroll_conservatively <= scroll_limit)
15840 move_it_vertically (&it, amount_to_scroll);
15841 else
15843 /* Extra precision for users who set scroll-conservatively
15844 to a large number: make sure the amount we scroll
15845 the window start is never less than amount_to_scroll,
15846 which was computed as distance from window bottom to
15847 point. This matters when lines at window top and lines
15848 below window bottom have different height. */
15849 struct it it1;
15850 void *it1data = NULL;
15851 /* We use a temporary it1 because line_bottom_y can modify
15852 its argument, if it moves one line down; see there. */
15853 int start_y;
15855 SAVE_IT (it1, it, it1data);
15856 start_y = line_bottom_y (&it1);
15857 do {
15858 RESTORE_IT (&it, &it, it1data);
15859 move_it_by_lines (&it, 1);
15860 SAVE_IT (it1, it, it1data);
15861 } while (IT_CHARPOS (it) < ZV
15862 && line_bottom_y (&it1) - start_y < amount_to_scroll);
15863 bidi_unshelve_cache (it1data, true);
15866 /* If STARTP is unchanged, move it down another screen line. */
15867 if (IT_CHARPOS (it) == CHARPOS (startp))
15868 move_it_by_lines (&it, 1);
15869 startp = it.current.pos;
15871 else
15873 struct text_pos scroll_margin_pos = startp;
15874 int y_offset = 0;
15876 /* See if point is inside the scroll margin at the top of the
15877 window. */
15878 if (this_scroll_margin)
15880 int y_start;
15882 start_display (&it, w, startp);
15883 y_start = it.current_y;
15884 move_it_vertically (&it, this_scroll_margin);
15885 scroll_margin_pos = it.current.pos;
15886 /* If we didn't move enough before hitting ZV, request
15887 additional amount of scroll, to move point out of the
15888 scroll margin. */
15889 if (IT_CHARPOS (it) == ZV
15890 && it.current_y - y_start < this_scroll_margin)
15891 y_offset = this_scroll_margin - (it.current_y - y_start);
15894 if (PT < CHARPOS (scroll_margin_pos))
15896 /* Point is in the scroll margin at the top of the window or
15897 above what is displayed in the window. */
15898 int y0, y_to_move;
15900 /* Compute the vertical distance from PT to the scroll
15901 margin position. Move as far as scroll_max allows, or
15902 one screenful, or 10 screen lines, whichever is largest.
15903 Give up if distance is greater than scroll_max or if we
15904 didn't reach the scroll margin position. */
15905 SET_TEXT_POS (pos, PT, PT_BYTE);
15906 start_display (&it, w, pos);
15907 y0 = it.current_y;
15908 y_to_move = max (it.last_visible_y,
15909 max (scroll_max, 10 * frame_line_height));
15910 move_it_to (&it, CHARPOS (scroll_margin_pos), 0,
15911 y_to_move, -1,
15912 MOVE_TO_POS | MOVE_TO_X | MOVE_TO_Y);
15913 dy = it.current_y - y0;
15914 if (dy > scroll_max
15915 || IT_CHARPOS (it) < CHARPOS (scroll_margin_pos))
15916 return SCROLLING_FAILED;
15918 /* Additional scroll for when ZV was too close to point. */
15919 dy += y_offset;
15921 /* Compute new window start. */
15922 start_display (&it, w, startp);
15924 if (arg_scroll_conservatively)
15925 amount_to_scroll = max (dy, frame_line_height
15926 * max (scroll_step, temp_scroll_step));
15927 else if (scroll_step || temp_scroll_step)
15928 amount_to_scroll = scroll_max;
15929 else
15931 aggressive = BVAR (current_buffer, scroll_down_aggressively);
15932 height = WINDOW_BOX_TEXT_HEIGHT (w);
15933 if (NUMBERP (aggressive))
15935 double float_amount = XFLOATINT (aggressive) * height;
15936 int aggressive_scroll = float_amount;
15937 if (aggressive_scroll == 0 && float_amount > 0)
15938 aggressive_scroll = 1;
15939 /* Don't let point enter the scroll margin near
15940 bottom of the window, if the value of
15941 scroll_down_aggressively happens to be too
15942 large. */
15943 if (aggressive_scroll + 2 * this_scroll_margin > height)
15944 aggressive_scroll = height - 2 * this_scroll_margin;
15945 amount_to_scroll = dy + aggressive_scroll;
15949 if (amount_to_scroll <= 0)
15950 return SCROLLING_FAILED;
15952 move_it_vertically_backward (&it, amount_to_scroll);
15953 startp = it.current.pos;
15957 /* Run window scroll functions. */
15958 startp = run_window_scroll_functions (window, startp);
15960 /* Display the window. Give up if new fonts are loaded, or if point
15961 doesn't appear. */
15962 if (!try_window (window, startp, 0))
15963 rc = SCROLLING_NEED_LARGER_MATRICES;
15964 else if (w->cursor.vpos < 0)
15966 clear_glyph_matrix (w->desired_matrix);
15967 rc = SCROLLING_FAILED;
15969 else
15971 /* Maybe forget recorded base line for line number display. */
15972 if (!just_this_one_p
15973 || current_buffer->clip_changed
15974 || BEG_UNCHANGED < CHARPOS (startp))
15975 w->base_line_number = 0;
15977 /* If cursor ends up on a partially visible line,
15978 treat that as being off the bottom of the screen. */
15979 if (! cursor_row_fully_visible_p (w, extra_scroll_margin_lines <= 1,
15980 false)
15981 /* It's possible that the cursor is on the first line of the
15982 buffer, which is partially obscured due to a vscroll
15983 (Bug#7537). In that case, avoid looping forever. */
15984 && extra_scroll_margin_lines < w->desired_matrix->nrows - 1)
15986 clear_glyph_matrix (w->desired_matrix);
15987 ++extra_scroll_margin_lines;
15988 goto too_near_end;
15990 rc = SCROLLING_SUCCESS;
15993 return rc;
15997 /* Compute a suitable window start for window W if display of W starts
15998 on a continuation line. Value is true if a new window start
15999 was computed.
16001 The new window start will be computed, based on W's width, starting
16002 from the start of the continued line. It is the start of the
16003 screen line with the minimum distance from the old start W->start,
16004 which is still before point (otherwise point will definitely not
16005 be visible in the window). */
16007 static bool
16008 compute_window_start_on_continuation_line (struct window *w)
16010 struct text_pos pos, start_pos, pos_before_pt;
16011 bool window_start_changed_p = false;
16013 SET_TEXT_POS_FROM_MARKER (start_pos, w->start);
16015 /* If window start is on a continuation line... Window start may be
16016 < BEGV in case there's invisible text at the start of the
16017 buffer (M-x rmail, for example). */
16018 if (CHARPOS (start_pos) > BEGV
16019 && FETCH_BYTE (BYTEPOS (start_pos) - 1) != '\n')
16021 struct it it;
16022 struct glyph_row *row;
16024 /* Handle the case that the window start is out of range. */
16025 if (CHARPOS (start_pos) < BEGV)
16026 SET_TEXT_POS (start_pos, BEGV, BEGV_BYTE);
16027 else if (CHARPOS (start_pos) > ZV)
16028 SET_TEXT_POS (start_pos, ZV, ZV_BYTE);
16030 /* Find the start of the continued line. This should be fast
16031 because find_newline is fast (newline cache). */
16032 row = w->desired_matrix->rows + window_wants_header_line (w);
16033 init_iterator (&it, w, CHARPOS (start_pos), BYTEPOS (start_pos),
16034 row, DEFAULT_FACE_ID);
16035 reseat_at_previous_visible_line_start (&it);
16037 /* If the line start is "too far" away from the window start,
16038 say it takes too much time to compute a new window start.
16039 Also, give up if the line start is after point, as in that
16040 case point will not be visible with any window start we
16041 compute. */
16042 if (IT_CHARPOS (it) <= PT
16043 || (CHARPOS (start_pos) - IT_CHARPOS (it)
16044 /* PXW: Do we need upper bounds here? */
16045 < WINDOW_TOTAL_LINES (w) * WINDOW_TOTAL_COLS (w)))
16047 int min_distance, distance;
16049 /* Move forward by display lines to find the new window
16050 start. If window width was enlarged, the new start can
16051 be expected to be > the old start. If window width was
16052 decreased, the new window start will be < the old start.
16053 So, we're looking for the display line start with the
16054 minimum distance from the old window start. */
16055 pos_before_pt = pos = it.current.pos;
16056 min_distance = DISP_INFINITY;
16057 while ((distance = eabs (CHARPOS (start_pos) - IT_CHARPOS (it))),
16058 distance < min_distance)
16060 min_distance = distance;
16061 if (CHARPOS (pos) <= PT)
16062 pos_before_pt = pos;
16063 pos = it.current.pos;
16064 if (it.line_wrap == WORD_WRAP)
16066 /* Under WORD_WRAP, move_it_by_lines is likely to
16067 overshoot and stop not at the first, but the
16068 second character from the left margin. So in
16069 that case, we need a more tight control on the X
16070 coordinate of the iterator than move_it_by_lines
16071 promises in its contract. The method is to first
16072 go to the last (rightmost) visible character of a
16073 line, then move to the leftmost character on the
16074 next line in a separate call. */
16075 move_it_to (&it, ZV, it.last_visible_x, it.current_y, -1,
16076 MOVE_TO_POS | MOVE_TO_X | MOVE_TO_Y);
16077 move_it_to (&it, ZV, 0,
16078 it.current_y + it.max_ascent + it.max_descent, -1,
16079 MOVE_TO_POS | MOVE_TO_X | MOVE_TO_Y);
16081 else
16082 move_it_by_lines (&it, 1);
16085 /* It makes very little sense to make the new window start
16086 after point, as point won't be visible. If that's what
16087 the loop above finds, fall back on the candidate before
16088 or at point that is closest to the old window start. */
16089 if (CHARPOS (pos) > PT)
16090 pos = pos_before_pt;
16092 /* Set the window start there. */
16093 SET_MARKER_FROM_TEXT_POS (w->start, pos);
16094 window_start_changed_p = true;
16098 return window_start_changed_p;
16102 /* Try cursor movement in case text has not changed in window WINDOW,
16103 with window start STARTP. Value is
16105 CURSOR_MOVEMENT_SUCCESS if successful
16107 CURSOR_MOVEMENT_CANNOT_BE_USED if this method cannot be used
16109 CURSOR_MOVEMENT_MUST_SCROLL if we know we have to scroll the
16110 display. *SCROLL_STEP is set to true, under certain circumstances, if
16111 we want to scroll as if scroll-step were set to 1. See the code.
16113 CURSOR_MOVEMENT_NEED_LARGER_MATRICES if we need larger matrices, in
16114 which case we have to abort this redisplay, and adjust matrices
16115 first. */
16117 enum
16119 CURSOR_MOVEMENT_SUCCESS,
16120 CURSOR_MOVEMENT_CANNOT_BE_USED,
16121 CURSOR_MOVEMENT_MUST_SCROLL,
16122 CURSOR_MOVEMENT_NEED_LARGER_MATRICES
16125 static int
16126 try_cursor_movement (Lisp_Object window, struct text_pos startp,
16127 bool *scroll_step)
16129 struct window *w = XWINDOW (window);
16130 struct frame *f = XFRAME (w->frame);
16131 int rc = CURSOR_MOVEMENT_CANNOT_BE_USED;
16133 #ifdef GLYPH_DEBUG
16134 if (inhibit_try_cursor_movement)
16135 return rc;
16136 #endif
16138 /* Previously, there was a check for Lisp integer in the
16139 if-statement below. Now, this field is converted to
16140 ptrdiff_t, thus zero means invalid position in a buffer. */
16141 eassert (w->last_point > 0);
16142 /* Likewise there was a check whether window_end_vpos is nil or larger
16143 than the window. Now window_end_vpos is int and so never nil, but
16144 let's leave eassert to check whether it fits in the window. */
16145 eassert (!w->window_end_valid
16146 || w->window_end_vpos < w->current_matrix->nrows);
16148 /* Handle case where text has not changed, only point, and it has
16149 not moved off the frame. */
16150 if (/* Point may be in this window. */
16151 PT >= CHARPOS (startp)
16152 /* Selective display hasn't changed. */
16153 && !current_buffer->clip_changed
16154 /* Function force-mode-line-update is used to force a thorough
16155 redisplay. It sets either windows_or_buffers_changed or
16156 update_mode_lines. So don't take a shortcut here for these
16157 cases. */
16158 && !update_mode_lines
16159 && !windows_or_buffers_changed
16160 && !f->cursor_type_changed
16161 && NILP (Vshow_trailing_whitespace)
16162 /* When display-line-numbers is in relative mode, moving point
16163 requires to redraw the entire window. */
16164 && !EQ (Vdisplay_line_numbers, Qrelative)
16165 && !EQ (Vdisplay_line_numbers, Qvisual)
16166 /* When the current line number should be displayed in a
16167 distinct face, moving point cannot be handled in optimized
16168 way as below. */
16169 && !(!NILP (Vdisplay_line_numbers)
16170 && NILP (Finternal_lisp_face_equal_p (Qline_number,
16171 Qline_number_current_line,
16172 w->frame)))
16173 /* This code is not used for mini-buffer for the sake of the case
16174 of redisplaying to replace an echo area message; since in
16175 that case the mini-buffer contents per se are usually
16176 unchanged. This code is of no real use in the mini-buffer
16177 since the handling of this_line_start_pos, etc., in redisplay
16178 handles the same cases. */
16179 && !EQ (window, minibuf_window)
16180 /* When overlay arrow is shown in current buffer, point movement
16181 is no longer "simple", as it typically causes the overlay
16182 arrow to move as well. */
16183 && !overlay_arrow_in_current_buffer_p ())
16185 int this_scroll_margin, top_scroll_margin;
16186 struct glyph_row *row = NULL;
16188 #ifdef GLYPH_DEBUG
16189 debug_method_add (w, "cursor movement");
16190 #endif
16192 this_scroll_margin = window_scroll_margin (w, MARGIN_IN_PIXELS);
16194 top_scroll_margin = this_scroll_margin;
16195 if (window_wants_header_line (w))
16196 top_scroll_margin += CURRENT_HEADER_LINE_HEIGHT (w);
16198 /* Start with the row the cursor was displayed during the last
16199 not paused redisplay. Give up if that row is not valid. */
16200 if (w->last_cursor_vpos < 0
16201 || w->last_cursor_vpos >= w->current_matrix->nrows)
16202 rc = CURSOR_MOVEMENT_MUST_SCROLL;
16203 else
16205 row = MATRIX_ROW (w->current_matrix, w->last_cursor_vpos);
16206 if (row->mode_line_p)
16207 ++row;
16208 if (!row->enabled_p)
16209 rc = CURSOR_MOVEMENT_MUST_SCROLL;
16212 if (rc == CURSOR_MOVEMENT_CANNOT_BE_USED)
16214 bool scroll_p = false, must_scroll = false;
16215 int last_y = window_text_bottom_y (w) - this_scroll_margin;
16217 if (PT > w->last_point)
16219 /* Point has moved forward. */
16220 while (MATRIX_ROW_END_CHARPOS (row) < PT
16221 && MATRIX_ROW_BOTTOM_Y (row) < last_y)
16223 eassert (row->enabled_p);
16224 ++row;
16227 /* If the end position of a row equals the start
16228 position of the next row, and PT is at that position,
16229 we would rather display cursor in the next line. */
16230 while (MATRIX_ROW_BOTTOM_Y (row) < last_y
16231 && MATRIX_ROW_END_CHARPOS (row) == PT
16232 && row < MATRIX_MODE_LINE_ROW (w->current_matrix)
16233 && MATRIX_ROW_START_CHARPOS (row+1) == PT
16234 && !cursor_row_p (row))
16235 ++row;
16237 /* If within the scroll margin, scroll. Note that
16238 MATRIX_ROW_BOTTOM_Y gives the pixel position at which
16239 the next line would be drawn, and that
16240 this_scroll_margin can be zero. */
16241 if (MATRIX_ROW_BOTTOM_Y (row) > last_y
16242 || PT > MATRIX_ROW_END_CHARPOS (row)
16243 /* Line is completely visible last line in window
16244 and PT is to be set in the next line. */
16245 || (MATRIX_ROW_BOTTOM_Y (row) == last_y
16246 && PT == MATRIX_ROW_END_CHARPOS (row)
16247 && !row->ends_at_zv_p
16248 && !MATRIX_ROW_ENDS_IN_MIDDLE_OF_CHAR_P (row)))
16249 scroll_p = true;
16251 else if (PT < w->last_point)
16253 /* Cursor has to be moved backward. Note that PT >=
16254 CHARPOS (startp) because of the outer if-statement. */
16255 while (!row->mode_line_p
16256 && (MATRIX_ROW_START_CHARPOS (row) > PT
16257 || (MATRIX_ROW_START_CHARPOS (row) == PT
16258 && (MATRIX_ROW_STARTS_IN_MIDDLE_OF_CHAR_P (row)
16259 || (/* STARTS_IN_MIDDLE_OF_STRING_P (row) */
16260 row > w->current_matrix->rows
16261 && (row-1)->ends_in_newline_from_string_p))))
16262 && (row->y > top_scroll_margin
16263 || CHARPOS (startp) == BEGV))
16265 eassert (row->enabled_p);
16266 --row;
16269 /* Consider the following case: Window starts at BEGV,
16270 there is invisible, intangible text at BEGV, so that
16271 display starts at some point START > BEGV. It can
16272 happen that we are called with PT somewhere between
16273 BEGV and START. Try to handle that case. */
16274 if (row < w->current_matrix->rows
16275 || row->mode_line_p)
16277 row = w->current_matrix->rows;
16278 if (row->mode_line_p)
16279 ++row;
16282 /* Due to newlines in overlay strings, we may have to
16283 skip forward over overlay strings. */
16284 while (MATRIX_ROW_BOTTOM_Y (row) < last_y
16285 && MATRIX_ROW_END_CHARPOS (row) == PT
16286 && !cursor_row_p (row))
16287 ++row;
16289 /* If within the scroll margin, scroll. */
16290 if (row->y < top_scroll_margin
16291 && CHARPOS (startp) != BEGV)
16292 scroll_p = true;
16294 else
16296 /* Cursor did not move. So don't scroll even if cursor line
16297 is partially visible, as it was so before. */
16298 rc = CURSOR_MOVEMENT_SUCCESS;
16301 if (PT < MATRIX_ROW_START_CHARPOS (row)
16302 || PT > MATRIX_ROW_END_CHARPOS (row))
16304 /* if PT is not in the glyph row, give up. */
16305 rc = CURSOR_MOVEMENT_MUST_SCROLL;
16306 must_scroll = true;
16308 else if (rc != CURSOR_MOVEMENT_SUCCESS
16309 && !NILP (BVAR (XBUFFER (w->contents), bidi_display_reordering)))
16311 struct glyph_row *row1;
16313 /* If rows are bidi-reordered and point moved, back up
16314 until we find a row that does not belong to a
16315 continuation line. This is because we must consider
16316 all rows of a continued line as candidates for the
16317 new cursor positioning, since row start and end
16318 positions change non-linearly with vertical position
16319 in such rows. */
16320 /* FIXME: Revisit this when glyph ``spilling'' in
16321 continuation lines' rows is implemented for
16322 bidi-reordered rows. */
16323 for (row1 = MATRIX_FIRST_TEXT_ROW (w->current_matrix);
16324 MATRIX_ROW_CONTINUATION_LINE_P (row);
16325 --row)
16327 /* If we hit the beginning of the displayed portion
16328 without finding the first row of a continued
16329 line, give up. */
16330 if (row <= row1)
16332 rc = CURSOR_MOVEMENT_MUST_SCROLL;
16333 break;
16335 eassert (row->enabled_p);
16338 if (must_scroll)
16340 else if (rc != CURSOR_MOVEMENT_SUCCESS
16341 && MATRIX_ROW_PARTIALLY_VISIBLE_P (w, row)
16342 /* Make sure this isn't a header line by any chance, since
16343 then MATRIX_ROW_PARTIALLY_VISIBLE_P might yield true. */
16344 && !row->mode_line_p
16345 && make_cursor_line_fully_visible_p)
16347 if (PT == MATRIX_ROW_END_CHARPOS (row)
16348 && !row->ends_at_zv_p
16349 && !MATRIX_ROW_ENDS_IN_MIDDLE_OF_CHAR_P (row))
16350 rc = CURSOR_MOVEMENT_MUST_SCROLL;
16351 else if (row->height > window_box_height (w))
16353 /* If we end up in a partially visible line, let's
16354 make it fully visible, except when it's taller
16355 than the window, in which case we can't do much
16356 about it. */
16357 *scroll_step = true;
16358 rc = CURSOR_MOVEMENT_MUST_SCROLL;
16360 else
16362 set_cursor_from_row (w, row, w->current_matrix, 0, 0, 0, 0);
16363 if (!cursor_row_fully_visible_p (w, false, true))
16364 rc = CURSOR_MOVEMENT_MUST_SCROLL;
16365 else
16366 rc = CURSOR_MOVEMENT_SUCCESS;
16369 else if (scroll_p)
16370 rc = CURSOR_MOVEMENT_MUST_SCROLL;
16371 else if (rc != CURSOR_MOVEMENT_SUCCESS
16372 && !NILP (BVAR (XBUFFER (w->contents), bidi_display_reordering)))
16374 /* With bidi-reordered rows, there could be more than
16375 one candidate row whose start and end positions
16376 occlude point. We need to let set_cursor_from_row
16377 find the best candidate. */
16378 /* FIXME: Revisit this when glyph ``spilling'' in
16379 continuation lines' rows is implemented for
16380 bidi-reordered rows. */
16381 bool rv = false;
16385 bool at_zv_p = false, exact_match_p = false;
16387 if (MATRIX_ROW_START_CHARPOS (row) <= PT
16388 && PT <= MATRIX_ROW_END_CHARPOS (row)
16389 && cursor_row_p (row))
16390 rv |= set_cursor_from_row (w, row, w->current_matrix,
16391 0, 0, 0, 0);
16392 /* As soon as we've found the exact match for point,
16393 or the first suitable row whose ends_at_zv_p flag
16394 is set, we are done. */
16395 if (rv)
16397 at_zv_p = MATRIX_ROW (w->current_matrix,
16398 w->cursor.vpos)->ends_at_zv_p;
16399 if (!at_zv_p
16400 && w->cursor.hpos >= 0
16401 && w->cursor.hpos < MATRIX_ROW_USED (w->current_matrix,
16402 w->cursor.vpos))
16404 struct glyph_row *candidate =
16405 MATRIX_ROW (w->current_matrix, w->cursor.vpos);
16406 struct glyph *g =
16407 candidate->glyphs[TEXT_AREA] + w->cursor.hpos;
16408 ptrdiff_t endpos = MATRIX_ROW_END_CHARPOS (candidate);
16410 exact_match_p =
16411 (BUFFERP (g->object) && g->charpos == PT)
16412 || (NILP (g->object)
16413 && (g->charpos == PT
16414 || (g->charpos == 0 && endpos - 1 == PT)));
16416 if (at_zv_p || exact_match_p)
16418 rc = CURSOR_MOVEMENT_SUCCESS;
16419 break;
16422 if (MATRIX_ROW_BOTTOM_Y (row) == last_y)
16423 break;
16424 ++row;
16426 while (((MATRIX_ROW_CONTINUATION_LINE_P (row)
16427 || row->continued_p)
16428 && MATRIX_ROW_BOTTOM_Y (row) <= last_y)
16429 || (MATRIX_ROW_START_CHARPOS (row) == PT
16430 && MATRIX_ROW_BOTTOM_Y (row) < last_y));
16431 /* If we didn't find any candidate rows, or exited the
16432 loop before all the candidates were examined, signal
16433 to the caller that this method failed. */
16434 if (rc != CURSOR_MOVEMENT_SUCCESS
16435 && !(rv
16436 && !MATRIX_ROW_CONTINUATION_LINE_P (row)
16437 && !row->continued_p))
16438 rc = CURSOR_MOVEMENT_MUST_SCROLL;
16439 else if (rv)
16440 rc = CURSOR_MOVEMENT_SUCCESS;
16442 else
16446 if (set_cursor_from_row (w, row, w->current_matrix, 0, 0, 0, 0))
16448 rc = CURSOR_MOVEMENT_SUCCESS;
16449 break;
16451 ++row;
16453 while (MATRIX_ROW_BOTTOM_Y (row) < last_y
16454 && MATRIX_ROW_START_CHARPOS (row) == PT
16455 && cursor_row_p (row));
16460 return rc;
16464 void
16465 set_vertical_scroll_bar (struct window *w)
16467 ptrdiff_t start, end, whole;
16469 /* Calculate the start and end positions for the current window.
16470 At some point, it would be nice to choose between scrollbars
16471 which reflect the whole buffer size, with special markers
16472 indicating narrowing, and scrollbars which reflect only the
16473 visible region.
16475 Note that mini-buffers sometimes aren't displaying any text. */
16476 if (!MINI_WINDOW_P (w)
16477 || (w == XWINDOW (minibuf_window)
16478 && NILP (echo_area_buffer[0])))
16480 struct buffer *buf = XBUFFER (w->contents);
16481 whole = BUF_ZV (buf) - BUF_BEGV (buf);
16482 start = marker_position (w->start) - BUF_BEGV (buf);
16483 /* I don't think this is guaranteed to be right. For the
16484 moment, we'll pretend it is. */
16485 end = BUF_Z (buf) - w->window_end_pos - BUF_BEGV (buf);
16487 if (end < start)
16488 end = start;
16489 if (whole < (end - start))
16490 whole = end - start;
16492 else
16493 start = end = whole = 0;
16495 /* Indicate what this scroll bar ought to be displaying now. */
16496 if (FRAME_TERMINAL (XFRAME (w->frame))->set_vertical_scroll_bar_hook)
16497 (*FRAME_TERMINAL (XFRAME (w->frame))->set_vertical_scroll_bar_hook)
16498 (w, end - start, whole, start);
16502 void
16503 set_horizontal_scroll_bar (struct window *w)
16505 int start, end, whole, portion;
16507 if (!MINI_WINDOW_P (w)
16508 || (w == XWINDOW (minibuf_window)
16509 && NILP (echo_area_buffer[0])))
16511 struct buffer *b = XBUFFER (w->contents);
16512 struct buffer *old_buffer = NULL;
16513 struct it it;
16514 struct text_pos startp;
16516 if (b != current_buffer)
16518 old_buffer = current_buffer;
16519 set_buffer_internal (b);
16522 SET_TEXT_POS_FROM_MARKER (startp, w->start);
16523 start_display (&it, w, startp);
16524 it.last_visible_x = INT_MAX;
16525 whole = move_it_to (&it, -1, INT_MAX, window_box_height (w), -1,
16526 MOVE_TO_X | MOVE_TO_Y);
16527 /* whole = move_it_to (&it, w->window_end_pos, INT_MAX,
16528 window_box_height (w), -1,
16529 MOVE_TO_POS | MOVE_TO_X | MOVE_TO_Y); */
16531 start = w->hscroll * FRAME_COLUMN_WIDTH (WINDOW_XFRAME (w));
16532 end = start + window_box_width (w, TEXT_AREA);
16533 portion = end - start;
16534 /* After enlarging a horizontally scrolled window such that it
16535 gets at least as wide as the text it contains, make sure that
16536 the thumb doesn't fill the entire scroll bar so we can still
16537 drag it back to see the entire text. */
16538 whole = max (whole, end);
16540 if (it.bidi_p)
16542 Lisp_Object pdir;
16544 pdir = Fcurrent_bidi_paragraph_direction (Qnil);
16545 if (EQ (pdir, Qright_to_left))
16547 start = whole - end;
16548 end = start + portion;
16552 if (old_buffer)
16553 set_buffer_internal (old_buffer);
16555 else
16556 start = end = whole = portion = 0;
16558 w->hscroll_whole = whole;
16560 /* Indicate what this scroll bar ought to be displaying now. */
16561 if (FRAME_TERMINAL (XFRAME (w->frame))->set_horizontal_scroll_bar_hook)
16562 (*FRAME_TERMINAL (XFRAME (w->frame))->set_horizontal_scroll_bar_hook)
16563 (w, portion, whole, start);
16567 /* Redisplay leaf window WINDOW. JUST_THIS_ONE_P means only
16568 selected_window is redisplayed.
16570 We can return without actually redisplaying the window if fonts has been
16571 changed on window's frame. In that case, redisplay_internal will retry.
16573 As one of the important parts of redisplaying a window, we need to
16574 decide whether the previous window-start position (stored in the
16575 window's w->start marker position) is still valid, and if it isn't,
16576 recompute it. Some details about that:
16578 . The previous window-start could be in a continuation line, in
16579 which case we need to recompute it when the window width
16580 changes. See compute_window_start_on_continuation_line and its
16581 call below.
16583 . The text that changed since last redisplay could include the
16584 previous window-start position. In that case, we try to salvage
16585 what we can from the current glyph matrix by calling
16586 try_scrolling, which see.
16588 . Some Emacs command could force us to use a specific window-start
16589 position by setting the window's force_start flag, or gently
16590 propose doing that by setting the window's optional_new_start
16591 flag. In these cases, we try using the specified start point if
16592 that succeeds (i.e. the window desired matrix is successfully
16593 recomputed, and point location is within the window). In case
16594 of optional_new_start, we first check if the specified start
16595 position is feasible, i.e. if it will allow point to be
16596 displayed in the window. If using the specified start point
16597 fails, e.g., if new fonts are needed to be loaded, we abort the
16598 redisplay cycle and leave it up to the next cycle to figure out
16599 things.
16601 . Note that the window's force_start flag is sometimes set by
16602 redisplay itself, when it decides that the previous window start
16603 point is fine and should be kept. Search for "goto force_start"
16604 below to see the details. Like the values of window-start
16605 specified outside of redisplay, these internally-deduced values
16606 are tested for feasibility, and ignored if found to be
16607 unfeasible.
16609 . Note that the function try_window, used to completely redisplay
16610 a window, accepts the window's start point as its argument.
16611 This is used several times in the redisplay code to control
16612 where the window start will be, according to user options such
16613 as scroll-conservatively, and also to ensure the screen line
16614 showing point will be fully (as opposed to partially) visible on
16615 display. */
16617 static void
16618 redisplay_window (Lisp_Object window, bool just_this_one_p)
16620 struct window *w = XWINDOW (window);
16621 struct frame *f = XFRAME (w->frame);
16622 struct buffer *buffer = XBUFFER (w->contents);
16623 struct buffer *old = current_buffer;
16624 struct text_pos lpoint, opoint, startp;
16625 bool update_mode_line;
16626 int tem;
16627 struct it it;
16628 /* Record it now because it's overwritten. */
16629 bool current_matrix_up_to_date_p = false;
16630 bool used_current_matrix_p = false;
16631 /* This is less strict than current_matrix_up_to_date_p.
16632 It indicates that the buffer contents and narrowing are unchanged. */
16633 bool buffer_unchanged_p = false;
16634 bool temp_scroll_step = false;
16635 ptrdiff_t count = SPECPDL_INDEX ();
16636 int rc;
16637 int centering_position = -1;
16638 bool last_line_misfit = false;
16639 ptrdiff_t beg_unchanged, end_unchanged;
16640 int frame_line_height, margin;
16641 bool use_desired_matrix;
16642 void *itdata = NULL;
16644 SET_TEXT_POS (lpoint, PT, PT_BYTE);
16645 opoint = lpoint;
16647 #ifdef GLYPH_DEBUG
16648 *w->desired_matrix->method = 0;
16649 #endif
16651 if (!just_this_one_p
16652 && REDISPLAY_SOME_P ()
16653 && !w->redisplay
16654 && !w->update_mode_line
16655 && !f->face_change
16656 && !f->redisplay
16657 && !buffer->text->redisplay
16658 && BUF_PT (buffer) == w->last_point)
16659 return;
16661 /* Make sure that both W's markers are valid. */
16662 eassert (XMARKER (w->start)->buffer == buffer);
16663 eassert (XMARKER (w->pointm)->buffer == buffer);
16665 reconsider_clip_changes (w);
16666 frame_line_height = default_line_pixel_height (w);
16667 margin = window_scroll_margin (w, MARGIN_IN_LINES);
16670 /* Has the mode line to be updated? */
16671 update_mode_line = (w->update_mode_line
16672 || update_mode_lines
16673 || buffer->clip_changed
16674 || buffer->prevent_redisplay_optimizations_p);
16676 if (!just_this_one_p)
16677 /* If `just_this_one_p' is set, we apparently set must_be_updated_p more
16678 cleverly elsewhere. */
16679 w->must_be_updated_p = true;
16681 if (MINI_WINDOW_P (w))
16683 if (w == XWINDOW (echo_area_window)
16684 && !NILP (echo_area_buffer[0]))
16686 if (update_mode_line)
16687 /* We may have to update a tty frame's menu bar or a
16688 tool-bar. Example `M-x C-h C-h C-g'. */
16689 goto finish_menu_bars;
16690 else
16691 /* We've already displayed the echo area glyphs in this window. */
16692 goto finish_scroll_bars;
16694 else if ((w != XWINDOW (minibuf_window)
16695 || minibuf_level == 0)
16696 /* When buffer is nonempty, redisplay window normally. */
16697 && BUF_Z (XBUFFER (w->contents)) == BUF_BEG (XBUFFER (w->contents))
16698 /* Quail displays non-mini buffers in minibuffer window.
16699 In that case, redisplay the window normally. */
16700 && !NILP (Fmemq (w->contents, Vminibuffer_list)))
16702 /* W is a mini-buffer window, but it's not active, so clear
16703 it. */
16704 int yb = window_text_bottom_y (w);
16705 struct glyph_row *row;
16706 int y;
16708 for (y = 0, row = w->desired_matrix->rows;
16709 y < yb;
16710 y += row->height, ++row)
16711 blank_row (w, row, y);
16712 goto finish_scroll_bars;
16715 clear_glyph_matrix (w->desired_matrix);
16718 /* Otherwise set up data on this window; select its buffer and point
16719 value. */
16720 /* Really select the buffer, for the sake of buffer-local
16721 variables. */
16722 set_buffer_internal_1 (XBUFFER (w->contents));
16724 current_matrix_up_to_date_p
16725 = (w->window_end_valid
16726 && !current_buffer->clip_changed
16727 && !current_buffer->prevent_redisplay_optimizations_p
16728 && !window_outdated (w)
16729 && !hscrolling_current_line_p (w));
16731 beg_unchanged = BEG_UNCHANGED;
16732 end_unchanged = END_UNCHANGED;
16734 SET_TEXT_POS (opoint, PT, PT_BYTE);
16736 specbind (Qinhibit_point_motion_hooks, Qt);
16738 buffer_unchanged_p
16739 = (w->window_end_valid
16740 && !current_buffer->clip_changed
16741 && !window_outdated (w));
16743 /* When windows_or_buffers_changed is non-zero, we can't rely
16744 on the window end being valid, so set it to zero there. */
16745 if (windows_or_buffers_changed)
16747 /* If window starts on a continuation line, maybe adjust the
16748 window start in case the window's width changed. */
16749 if (XMARKER (w->start)->buffer == current_buffer)
16750 compute_window_start_on_continuation_line (w);
16752 w->window_end_valid = false;
16753 /* If so, we also can't rely on current matrix
16754 and should not fool try_cursor_movement below. */
16755 current_matrix_up_to_date_p = false;
16758 /* Some sanity checks. */
16759 CHECK_WINDOW_END (w);
16760 if (Z == Z_BYTE && CHARPOS (opoint) != BYTEPOS (opoint))
16761 emacs_abort ();
16762 if (BYTEPOS (opoint) < CHARPOS (opoint))
16763 emacs_abort ();
16765 if (mode_line_update_needed (w))
16766 update_mode_line = true;
16768 /* Point refers normally to the selected window. For any other
16769 window, set up appropriate value. */
16770 if (!EQ (window, selected_window))
16772 ptrdiff_t new_pt = marker_position (w->pointm);
16773 ptrdiff_t new_pt_byte = marker_byte_position (w->pointm);
16775 if (new_pt < BEGV)
16777 new_pt = BEGV;
16778 new_pt_byte = BEGV_BYTE;
16779 set_marker_both (w->pointm, Qnil, BEGV, BEGV_BYTE);
16781 else if (new_pt > (ZV - 1))
16783 new_pt = ZV;
16784 new_pt_byte = ZV_BYTE;
16785 set_marker_both (w->pointm, Qnil, ZV, ZV_BYTE);
16788 /* We don't use SET_PT so that the point-motion hooks don't run. */
16789 TEMP_SET_PT_BOTH (new_pt, new_pt_byte);
16792 /* If any of the character widths specified in the display table
16793 have changed, invalidate the width run cache. It's true that
16794 this may be a bit late to catch such changes, but the rest of
16795 redisplay goes (non-fatally) haywire when the display table is
16796 changed, so why should we worry about doing any better? */
16797 if (current_buffer->width_run_cache
16798 || (current_buffer->base_buffer
16799 && current_buffer->base_buffer->width_run_cache))
16801 struct Lisp_Char_Table *disptab = buffer_display_table ();
16803 if (! disptab_matches_widthtab
16804 (disptab, XVECTOR (BVAR (current_buffer, width_table))))
16806 struct buffer *buf = current_buffer;
16808 if (buf->base_buffer)
16809 buf = buf->base_buffer;
16810 invalidate_region_cache (buf, buf->width_run_cache, BEG, Z);
16811 recompute_width_table (current_buffer, disptab);
16815 /* If window-start is screwed up, choose a new one. */
16816 if (XMARKER (w->start)->buffer != current_buffer)
16817 goto recenter;
16819 SET_TEXT_POS_FROM_MARKER (startp, w->start);
16821 /* If someone specified a new starting point but did not insist,
16822 check whether it can be used. */
16823 if ((w->optional_new_start || window_frozen_p (w))
16824 && CHARPOS (startp) >= BEGV
16825 && CHARPOS (startp) <= ZV)
16827 ptrdiff_t it_charpos;
16829 w->optional_new_start = false;
16830 start_display (&it, w, startp);
16831 move_it_to (&it, PT, 0, it.last_visible_y, -1,
16832 MOVE_TO_POS | MOVE_TO_X | MOVE_TO_Y);
16833 /* Record IT's position now, since line_bottom_y might change
16834 that. */
16835 it_charpos = IT_CHARPOS (it);
16836 /* Make sure we set the force_start flag only if the cursor row
16837 will be fully visible. Otherwise, the code under force_start
16838 label below will try to move point back into view, which is
16839 not what the code which sets optional_new_start wants. */
16840 if ((it.current_y == 0 || line_bottom_y (&it) < it.last_visible_y)
16841 && !w->force_start)
16843 if (it_charpos == PT)
16844 w->force_start = true;
16845 /* IT may overshoot PT if text at PT is invisible. */
16846 else if (it_charpos > PT && CHARPOS (startp) <= PT)
16847 w->force_start = true;
16848 #ifdef GLYPH_DEBUG
16849 if (w->force_start)
16851 if (window_frozen_p (w))
16852 debug_method_add (w, "set force_start from frozen window start");
16853 else
16854 debug_method_add (w, "set force_start from optional_new_start");
16856 #endif
16860 force_start:
16862 /* Handle case where place to start displaying has been specified,
16863 unless the specified location is outside the accessible range. */
16864 if (w->force_start)
16866 /* We set this later on if we have to adjust point. */
16867 int new_vpos = -1;
16869 w->force_start = false;
16870 w->vscroll = 0;
16871 w->window_end_valid = false;
16873 /* Forget any recorded base line for line number display. */
16874 if (!buffer_unchanged_p)
16875 w->base_line_number = 0;
16877 /* Redisplay the mode line. Select the buffer properly for that.
16878 Also, run the hook window-scroll-functions
16879 because we have scrolled. */
16880 /* Note, we do this after clearing force_start because
16881 if there's an error, it is better to forget about force_start
16882 than to get into an infinite loop calling the hook functions
16883 and having them get more errors. */
16884 if (!update_mode_line
16885 || ! NILP (Vwindow_scroll_functions))
16887 update_mode_line = true;
16888 w->update_mode_line = true;
16889 startp = run_window_scroll_functions (window, startp);
16892 if (CHARPOS (startp) < BEGV)
16893 SET_TEXT_POS (startp, BEGV, BEGV_BYTE);
16894 else if (CHARPOS (startp) > ZV)
16895 SET_TEXT_POS (startp, ZV, ZV_BYTE);
16897 /* Redisplay, then check if cursor has been set during the
16898 redisplay. Give up if new fonts were loaded. */
16899 /* We used to issue a CHECK_MARGINS argument to try_window here,
16900 but this causes scrolling to fail when point begins inside
16901 the scroll margin (bug#148) -- cyd */
16902 if (!try_window (window, startp, 0))
16904 w->force_start = true;
16905 clear_glyph_matrix (w->desired_matrix);
16906 goto need_larger_matrices;
16909 if (w->cursor.vpos < 0)
16911 /* If point does not appear, try to move point so it does
16912 appear. The desired matrix has been built above, so we
16913 can use it here. First see if point is in invisible
16914 text, and if so, move it to the first visible buffer
16915 position past that. */
16916 struct glyph_row *r = NULL;
16917 Lisp_Object invprop =
16918 get_char_property_and_overlay (make_number (PT), Qinvisible,
16919 Qnil, NULL);
16921 if (TEXT_PROP_MEANS_INVISIBLE (invprop) != 0)
16923 ptrdiff_t alt_pt;
16924 Lisp_Object invprop_end =
16925 Fnext_single_char_property_change (make_number (PT), Qinvisible,
16926 Qnil, Qnil);
16928 if (NATNUMP (invprop_end))
16929 alt_pt = XFASTINT (invprop_end);
16930 else
16931 alt_pt = ZV;
16932 r = row_containing_pos (w, alt_pt, w->desired_matrix->rows,
16933 NULL, 0);
16935 if (r)
16936 new_vpos = MATRIX_ROW_BOTTOM_Y (r);
16937 else /* Give up and just move to the middle of the window. */
16938 new_vpos = window_box_height (w) / 2;
16941 if (!cursor_row_fully_visible_p (w, false, false))
16943 /* Point does appear, but on a line partly visible at end of window.
16944 Move it back to a fully-visible line. */
16945 new_vpos = window_box_height (w);
16946 /* But if window_box_height suggests a Y coordinate that is
16947 not less than we already have, that line will clearly not
16948 be fully visible, so give up and scroll the display.
16949 This can happen when the default face uses a font whose
16950 dimensions are different from the frame's default
16951 font. */
16952 if (new_vpos >= w->cursor.y)
16954 w->cursor.vpos = -1;
16955 clear_glyph_matrix (w->desired_matrix);
16956 goto try_to_scroll;
16959 else if (w->cursor.vpos >= 0)
16961 /* Some people insist on not letting point enter the scroll
16962 margin, even though this part handles windows that didn't
16963 scroll at all. */
16964 int pixel_margin = margin * frame_line_height;
16965 bool header_line = window_wants_header_line (w);
16967 /* Note: We add an extra FRAME_LINE_HEIGHT, because the loop
16968 below, which finds the row to move point to, advances by
16969 the Y coordinate of the _next_ row, see the definition of
16970 MATRIX_ROW_BOTTOM_Y. */
16971 if (w->cursor.vpos < margin + header_line)
16973 w->cursor.vpos = -1;
16974 clear_glyph_matrix (w->desired_matrix);
16975 goto try_to_scroll;
16977 else
16979 int window_height = window_box_height (w);
16981 if (header_line)
16982 window_height += CURRENT_HEADER_LINE_HEIGHT (w);
16983 if (w->cursor.y >= window_height - pixel_margin)
16985 w->cursor.vpos = -1;
16986 clear_glyph_matrix (w->desired_matrix);
16987 goto try_to_scroll;
16992 /* If we need to move point for either of the above reasons,
16993 now actually do it. */
16994 if (new_vpos >= 0)
16996 struct glyph_row *row;
16998 row = MATRIX_FIRST_TEXT_ROW (w->desired_matrix);
16999 while (MATRIX_ROW_BOTTOM_Y (row) < new_vpos)
17000 ++row;
17002 TEMP_SET_PT_BOTH (MATRIX_ROW_START_CHARPOS (row),
17003 MATRIX_ROW_START_BYTEPOS (row));
17005 if (w != XWINDOW (selected_window))
17006 set_marker_both (w->pointm, Qnil, PT, PT_BYTE);
17007 else if (current_buffer == old)
17008 SET_TEXT_POS (lpoint, PT, PT_BYTE);
17010 set_cursor_from_row (w, row, w->desired_matrix, 0, 0, 0, 0);
17012 /* Re-run pre-redisplay-function so it can update the region
17013 according to the new position of point. */
17014 /* Other than the cursor, w's redisplay is done so we can set its
17015 redisplay to false. Also the buffer's redisplay can be set to
17016 false, since propagate_buffer_redisplay should have already
17017 propagated its info to `w' anyway. */
17018 w->redisplay = false;
17019 XBUFFER (w->contents)->text->redisplay = false;
17020 safe__call1 (true, Vpre_redisplay_function, Fcons (window, Qnil));
17022 if (w->redisplay || XBUFFER (w->contents)->text->redisplay
17023 || ((EQ (Vdisplay_line_numbers, Qrelative)
17024 || EQ (Vdisplay_line_numbers, Qvisual))
17025 && row != MATRIX_FIRST_TEXT_ROW (w->desired_matrix)))
17027 /* Either pre-redisplay-function made changes (e.g. move
17028 the region), or we moved point in a window that is
17029 under display-line-numbers = relative mode. We need
17030 another round of redisplay. */
17031 clear_glyph_matrix (w->desired_matrix);
17032 if (!try_window (window, startp, 0))
17033 goto need_larger_matrices;
17036 if (w->cursor.vpos < 0 || !cursor_row_fully_visible_p (w, false, false))
17038 clear_glyph_matrix (w->desired_matrix);
17039 goto try_to_scroll;
17042 #ifdef GLYPH_DEBUG
17043 debug_method_add (w, "forced window start");
17044 #endif
17045 goto done;
17048 /* Handle case where text has not changed, only point, and it has
17049 not moved off the frame, and we are not retrying after hscroll.
17050 (current_matrix_up_to_date_p is true when retrying.) */
17051 if (current_matrix_up_to_date_p
17052 && (rc = try_cursor_movement (window, startp, &temp_scroll_step),
17053 rc != CURSOR_MOVEMENT_CANNOT_BE_USED))
17055 switch (rc)
17057 case CURSOR_MOVEMENT_SUCCESS:
17058 used_current_matrix_p = true;
17059 goto done;
17061 case CURSOR_MOVEMENT_MUST_SCROLL:
17062 goto try_to_scroll;
17064 default:
17065 emacs_abort ();
17068 /* If current starting point was originally the beginning of a line
17069 but no longer is, find a new starting point. */
17070 else if (w->start_at_line_beg
17071 && !(CHARPOS (startp) <= BEGV
17072 || FETCH_BYTE (BYTEPOS (startp) - 1) == '\n'))
17074 #ifdef GLYPH_DEBUG
17075 debug_method_add (w, "recenter 1");
17076 #endif
17077 goto recenter;
17080 /* Try scrolling with try_window_id. Value is > 0 if update has
17081 been done, it is -1 if we know that the same window start will
17082 not work. It is 0 if unsuccessful for some other reason. */
17083 else if ((tem = try_window_id (w)) != 0)
17085 #ifdef GLYPH_DEBUG
17086 debug_method_add (w, "try_window_id %d", tem);
17087 #endif
17089 if (f->fonts_changed)
17090 goto need_larger_matrices;
17091 if (tem > 0)
17092 goto done;
17094 /* Otherwise try_window_id has returned -1 which means that we
17095 don't want the alternative below this comment to execute. */
17097 else if (CHARPOS (startp) >= BEGV
17098 && CHARPOS (startp) <= ZV
17099 && PT >= CHARPOS (startp)
17100 && (CHARPOS (startp) < ZV
17101 /* Avoid starting at end of buffer. */
17102 || CHARPOS (startp) == BEGV
17103 || !window_outdated (w)))
17105 int d1, d2, d5, d6;
17106 int rtop, rbot;
17108 /* If first window line is a continuation line, and window start
17109 is inside the modified region, but the first change is before
17110 current window start, we must select a new window start.
17112 However, if this is the result of a down-mouse event (e.g. by
17113 extending the mouse-drag-overlay), we don't want to select a
17114 new window start, since that would change the position under
17115 the mouse, resulting in an unwanted mouse-movement rather
17116 than a simple mouse-click. */
17117 if (!w->start_at_line_beg
17118 && NILP (do_mouse_tracking)
17119 && CHARPOS (startp) > BEGV
17120 && CHARPOS (startp) > BEG + beg_unchanged
17121 && CHARPOS (startp) <= Z - end_unchanged
17122 /* Even if w->start_at_line_beg is nil, a new window may
17123 start at a line_beg, since that's how set_buffer_window
17124 sets it. So, we need to check the return value of
17125 compute_window_start_on_continuation_line. (See also
17126 bug#197). */
17127 && XMARKER (w->start)->buffer == current_buffer
17128 && compute_window_start_on_continuation_line (w)
17129 /* It doesn't make sense to force the window start like we
17130 do at label force_start if it is already known that point
17131 will not be fully visible in the resulting window, because
17132 doing so will move point from its correct position
17133 instead of scrolling the window to bring point into view.
17134 See bug#9324. */
17135 && pos_visible_p (w, PT, &d1, &d2, &rtop, &rbot, &d5, &d6)
17136 /* A very tall row could need more than the window height,
17137 in which case we accept that it is partially visible. */
17138 && (rtop != 0) == (rbot != 0))
17140 w->force_start = true;
17141 SET_TEXT_POS_FROM_MARKER (startp, w->start);
17142 #ifdef GLYPH_DEBUG
17143 debug_method_add (w, "recomputed window start in continuation line");
17144 #endif
17145 goto force_start;
17148 #ifdef GLYPH_DEBUG
17149 debug_method_add (w, "same window start");
17150 #endif
17152 /* Try to redisplay starting at same place as before.
17153 If point has not moved off frame, accept the results. */
17154 if (!current_matrix_up_to_date_p
17155 /* Don't use try_window_reusing_current_matrix in this case
17156 because a window scroll function can have changed the
17157 buffer. */
17158 || !NILP (Vwindow_scroll_functions)
17159 || MINI_WINDOW_P (w)
17160 || !(used_current_matrix_p
17161 = try_window_reusing_current_matrix (w)))
17163 IF_DEBUG (debug_method_add (w, "1"));
17164 clear_glyph_matrix (w->desired_matrix);
17165 if (try_window (window, startp, TRY_WINDOW_CHECK_MARGINS) < 0)
17166 /* -1 means we need to scroll.
17167 0 means we need new matrices, but fonts_changed
17168 is set in that case, so we will detect it below. */
17169 goto try_to_scroll;
17172 if (f->fonts_changed)
17173 goto need_larger_matrices;
17175 if (w->cursor.vpos >= 0)
17177 if (!just_this_one_p
17178 || current_buffer->clip_changed
17179 || BEG_UNCHANGED < CHARPOS (startp))
17180 /* Forget any recorded base line for line number display. */
17181 w->base_line_number = 0;
17183 if (!cursor_row_fully_visible_p (w, true, false))
17185 clear_glyph_matrix (w->desired_matrix);
17186 last_line_misfit = true;
17188 /* Drop through and scroll. */
17189 else
17190 goto done;
17192 else
17193 clear_glyph_matrix (w->desired_matrix);
17196 try_to_scroll:
17198 /* Redisplay the mode line. Select the buffer properly for that. */
17199 if (!update_mode_line)
17201 update_mode_line = true;
17202 w->update_mode_line = true;
17205 /* Try to scroll by specified few lines. */
17206 if ((scroll_conservatively
17207 || emacs_scroll_step
17208 || temp_scroll_step
17209 || NUMBERP (BVAR (current_buffer, scroll_up_aggressively))
17210 || NUMBERP (BVAR (current_buffer, scroll_down_aggressively)))
17211 && CHARPOS (startp) >= BEGV
17212 && CHARPOS (startp) <= ZV)
17214 /* The function returns -1 if new fonts were loaded, 1 if
17215 successful, 0 if not successful. */
17216 int ss = try_scrolling (window, just_this_one_p,
17217 scroll_conservatively,
17218 emacs_scroll_step,
17219 temp_scroll_step, last_line_misfit);
17220 switch (ss)
17222 case SCROLLING_SUCCESS:
17223 goto done;
17225 case SCROLLING_NEED_LARGER_MATRICES:
17226 goto need_larger_matrices;
17228 case SCROLLING_FAILED:
17229 break;
17231 default:
17232 emacs_abort ();
17236 /* Finally, just choose a place to start which positions point
17237 according to user preferences. */
17239 recenter:
17241 #ifdef GLYPH_DEBUG
17242 debug_method_add (w, "recenter");
17243 #endif
17245 /* Forget any previously recorded base line for line number display. */
17246 if (!buffer_unchanged_p)
17247 w->base_line_number = 0;
17249 /* Determine the window start relative to point. */
17250 init_iterator (&it, w, PT, PT_BYTE, NULL, DEFAULT_FACE_ID);
17251 it.current_y = it.last_visible_y;
17252 if (centering_position < 0)
17254 ptrdiff_t margin_pos = CHARPOS (startp);
17255 Lisp_Object aggressive;
17256 bool scrolling_up;
17258 /* If there is a scroll margin at the top of the window, find
17259 its character position. */
17260 if (margin
17261 /* Cannot call start_display if startp is not in the
17262 accessible region of the buffer. This can happen when we
17263 have just switched to a different buffer and/or changed
17264 its restriction. In that case, startp is initialized to
17265 the character position 1 (BEGV) because we did not yet
17266 have chance to display the buffer even once. */
17267 && BEGV <= CHARPOS (startp) && CHARPOS (startp) <= ZV)
17269 struct it it1;
17270 void *it1data = NULL;
17272 SAVE_IT (it1, it, it1data);
17273 start_display (&it1, w, startp);
17274 move_it_vertically (&it1, margin * frame_line_height);
17275 margin_pos = IT_CHARPOS (it1);
17276 RESTORE_IT (&it, &it, it1data);
17278 scrolling_up = PT > margin_pos;
17279 aggressive =
17280 scrolling_up
17281 ? BVAR (current_buffer, scroll_up_aggressively)
17282 : BVAR (current_buffer, scroll_down_aggressively);
17284 if (!MINI_WINDOW_P (w)
17285 && (scroll_conservatively > SCROLL_LIMIT || NUMBERP (aggressive)))
17287 int pt_offset = 0;
17289 /* Setting scroll-conservatively overrides
17290 scroll-*-aggressively. */
17291 if (!scroll_conservatively && NUMBERP (aggressive))
17293 double float_amount = XFLOATINT (aggressive);
17295 pt_offset = float_amount * WINDOW_BOX_TEXT_HEIGHT (w);
17296 if (pt_offset == 0 && float_amount > 0)
17297 pt_offset = 1;
17298 if (pt_offset && margin > 0)
17299 margin -= 1;
17301 /* Compute how much to move the window start backward from
17302 point so that point will be displayed where the user
17303 wants it. */
17304 if (scrolling_up)
17306 centering_position = it.last_visible_y;
17307 if (pt_offset)
17308 centering_position -= pt_offset;
17309 centering_position -=
17310 (frame_line_height * (1 + margin + last_line_misfit)
17311 + WINDOW_HEADER_LINE_HEIGHT (w));
17312 /* Don't let point enter the scroll margin near top of
17313 the window. */
17314 if (centering_position < margin * frame_line_height)
17315 centering_position = margin * frame_line_height;
17317 else
17318 centering_position = margin * frame_line_height + pt_offset;
17320 else
17321 /* Set the window start half the height of the window backward
17322 from point. */
17323 centering_position = window_box_height (w) / 2;
17325 move_it_vertically_backward (&it, centering_position);
17327 eassert (IT_CHARPOS (it) >= BEGV);
17329 /* The function move_it_vertically_backward may move over more
17330 than the specified y-distance. If it->w is small, e.g. a
17331 mini-buffer window, we may end up in front of the window's
17332 display area. Start displaying at the start of the line
17333 containing PT in this case. */
17334 if (it.current_y <= 0)
17336 init_iterator (&it, w, PT, PT_BYTE, NULL, DEFAULT_FACE_ID);
17337 move_it_vertically_backward (&it, 0);
17338 it.current_y = 0;
17341 it.current_x = it.hpos = 0;
17343 /* Set the window start position here explicitly, to avoid an
17344 infinite loop in case the functions in window-scroll-functions
17345 get errors. */
17346 set_marker_both (w->start, Qnil, IT_CHARPOS (it), IT_BYTEPOS (it));
17348 /* Run scroll hooks. */
17349 startp = run_window_scroll_functions (window, it.current.pos);
17351 /* We invoke try_window and try_window_reusing_current_matrix below,
17352 and they manipulate the bidi cache. Save and restore the cache
17353 state of our iterator, so we could continue using it after that. */
17354 itdata = bidi_shelve_cache ();
17356 /* Redisplay the window. */
17357 use_desired_matrix = false;
17358 if (!current_matrix_up_to_date_p
17359 || windows_or_buffers_changed
17360 || f->cursor_type_changed
17361 /* Don't use try_window_reusing_current_matrix in this case
17362 because it can have changed the buffer. */
17363 || !NILP (Vwindow_scroll_functions)
17364 || !just_this_one_p
17365 || MINI_WINDOW_P (w)
17366 || !(used_current_matrix_p
17367 = try_window_reusing_current_matrix (w)))
17368 use_desired_matrix = (try_window (window, startp, 0) == 1);
17370 bidi_unshelve_cache (itdata, false);
17372 /* If new fonts have been loaded (due to fontsets), give up. We
17373 have to start a new redisplay since we need to re-adjust glyph
17374 matrices. */
17375 if (f->fonts_changed)
17376 goto need_larger_matrices;
17378 /* If cursor did not appear assume that the middle of the window is
17379 in the first line of the window. Do it again with the next line.
17380 (Imagine a window of height 100, displaying two lines of height
17381 60. Moving back 50 from it->last_visible_y will end in the first
17382 line.) */
17383 if (w->cursor.vpos < 0)
17385 if (w->window_end_valid && PT >= Z - w->window_end_pos)
17387 clear_glyph_matrix (w->desired_matrix);
17388 move_it_by_lines (&it, 1);
17389 try_window (window, it.current.pos, 0);
17391 else if (PT < IT_CHARPOS (it))
17393 clear_glyph_matrix (w->desired_matrix);
17394 move_it_by_lines (&it, -1);
17395 try_window (window, it.current.pos, 0);
17397 else if (scroll_conservatively > SCROLL_LIMIT
17398 && (it.method == GET_FROM_STRING
17399 || overlay_touches_p (IT_CHARPOS (it)))
17400 && IT_CHARPOS (it) < ZV)
17402 /* If the window starts with a before-string that spans more
17403 than one screen line, using that position to display the
17404 window might fail to bring point into the view, because
17405 start_display will always start by displaying the string,
17406 whereas the code above determines where to set w->start
17407 by the buffer position of the place where it takes screen
17408 coordinates. Try to recover by finding the next screen
17409 line that displays buffer text. */
17410 ptrdiff_t pos0 = IT_CHARPOS (it);
17412 clear_glyph_matrix (w->desired_matrix);
17413 do {
17414 move_it_by_lines (&it, 1);
17415 } while (IT_CHARPOS (it) == pos0);
17416 try_window (window, it.current.pos, 0);
17418 else
17420 /* Not much we can do about it. */
17424 /* Consider the following case: Window starts at BEGV, there is
17425 invisible, intangible text at BEGV, so that display starts at
17426 some point START > BEGV. It can happen that we are called with
17427 PT somewhere between BEGV and START. Try to handle that case,
17428 and similar ones. */
17429 if (w->cursor.vpos < 0)
17431 /* Prefer the desired matrix to the current matrix, if possible,
17432 in the fallback calculations below. This is because using
17433 the current matrix might completely goof, e.g. if its first
17434 row is after point. */
17435 struct glyph_matrix *matrix =
17436 use_desired_matrix ? w->desired_matrix : w->current_matrix;
17437 /* First, try locating the proper glyph row for PT. */
17438 struct glyph_row *row =
17439 row_containing_pos (w, PT, matrix->rows, NULL, 0);
17441 /* Sometimes point is at the beginning of invisible text that is
17442 before the 1st character displayed in the row. In that case,
17443 row_containing_pos fails to find the row, because no glyphs
17444 with appropriate buffer positions are present in the row.
17445 Therefore, we next try to find the row which shows the 1st
17446 position after the invisible text. */
17447 if (!row)
17449 Lisp_Object val =
17450 get_char_property_and_overlay (make_number (PT), Qinvisible,
17451 Qnil, NULL);
17453 if (TEXT_PROP_MEANS_INVISIBLE (val) != 0)
17455 ptrdiff_t alt_pos;
17456 Lisp_Object invis_end =
17457 Fnext_single_char_property_change (make_number (PT), Qinvisible,
17458 Qnil, Qnil);
17460 if (NATNUMP (invis_end))
17461 alt_pos = XFASTINT (invis_end);
17462 else
17463 alt_pos = ZV;
17464 row = row_containing_pos (w, alt_pos, matrix->rows, NULL, 0);
17467 /* Finally, fall back on the first row of the window after the
17468 header line (if any). This is slightly better than not
17469 displaying the cursor at all. */
17470 if (!row)
17472 row = matrix->rows;
17473 if (row->mode_line_p)
17474 ++row;
17476 set_cursor_from_row (w, row, matrix, 0, 0, 0, 0);
17479 if (!cursor_row_fully_visible_p (w, false, false))
17481 /* If vscroll is enabled, disable it and try again. */
17482 if (w->vscroll)
17484 w->vscroll = 0;
17485 clear_glyph_matrix (w->desired_matrix);
17486 goto recenter;
17489 /* Users who set scroll-conservatively to a large number want
17490 point just above/below the scroll margin. If we ended up
17491 with point's row partially visible, move the window start to
17492 make that row fully visible and out of the margin. */
17493 if (scroll_conservatively > SCROLL_LIMIT)
17495 int window_total_lines
17496 = WINDOW_TOTAL_LINES (w) * FRAME_LINE_HEIGHT (f) / frame_line_height;
17497 bool move_down = w->cursor.vpos >= window_total_lines / 2;
17499 move_it_by_lines (&it, move_down ? margin + 1 : -(margin + 1));
17500 clear_glyph_matrix (w->desired_matrix);
17501 if (1 == try_window (window, it.current.pos,
17502 TRY_WINDOW_CHECK_MARGINS))
17503 goto done;
17506 /* If centering point failed to make the whole line visible,
17507 put point at the top instead. That has to make the whole line
17508 visible, if it can be done. */
17509 if (centering_position == 0)
17510 goto done;
17512 clear_glyph_matrix (w->desired_matrix);
17513 centering_position = 0;
17514 goto recenter;
17517 done:
17519 SET_TEXT_POS_FROM_MARKER (startp, w->start);
17520 w->start_at_line_beg = (CHARPOS (startp) == BEGV
17521 || FETCH_BYTE (BYTEPOS (startp) - 1) == '\n');
17523 /* Display the mode line, if we must. */
17524 if ((update_mode_line
17525 /* If window not full width, must redo its mode line
17526 if (a) the window to its side is being redone and
17527 (b) we do a frame-based redisplay. This is a consequence
17528 of how inverted lines are drawn in frame-based redisplay. */
17529 || (!just_this_one_p
17530 && !FRAME_WINDOW_P (f)
17531 && !WINDOW_FULL_WIDTH_P (w))
17532 /* Line number to display. */
17533 || w->base_line_pos > 0
17534 /* Column number is displayed and different from the one displayed. */
17535 || (w->column_number_displayed != -1
17536 && (w->column_number_displayed != current_column ())))
17537 /* This means that the window has a mode line. */
17538 && (window_wants_mode_line (w)
17539 || window_wants_header_line (w)))
17542 display_mode_lines (w);
17544 /* If mode line height has changed, arrange for a thorough
17545 immediate redisplay using the correct mode line height. */
17546 if (window_wants_mode_line (w)
17547 && CURRENT_MODE_LINE_HEIGHT (w) != DESIRED_MODE_LINE_HEIGHT (w))
17549 f->fonts_changed = true;
17550 w->mode_line_height = -1;
17551 MATRIX_MODE_LINE_ROW (w->current_matrix)->height
17552 = DESIRED_MODE_LINE_HEIGHT (w);
17555 /* If header line height has changed, arrange for a thorough
17556 immediate redisplay using the correct header line height. */
17557 if (window_wants_header_line (w)
17558 && CURRENT_HEADER_LINE_HEIGHT (w) != DESIRED_HEADER_LINE_HEIGHT (w))
17560 f->fonts_changed = true;
17561 w->header_line_height = -1;
17562 MATRIX_HEADER_LINE_ROW (w->current_matrix)->height
17563 = DESIRED_HEADER_LINE_HEIGHT (w);
17566 if (f->fonts_changed)
17567 goto need_larger_matrices;
17570 if (!line_number_displayed && w->base_line_pos != -1)
17572 w->base_line_pos = 0;
17573 w->base_line_number = 0;
17576 finish_menu_bars:
17578 /* When we reach a frame's selected window, redo the frame's menu
17579 bar and the frame's title. */
17580 if (update_mode_line
17581 && EQ (FRAME_SELECTED_WINDOW (f), window))
17583 bool redisplay_menu_p;
17585 if (FRAME_WINDOW_P (f))
17587 #if defined (USE_X_TOOLKIT) || defined (HAVE_NTGUI) \
17588 || defined (HAVE_NS) || defined (USE_GTK)
17589 redisplay_menu_p = FRAME_EXTERNAL_MENU_BAR (f);
17590 #else
17591 redisplay_menu_p = FRAME_MENU_BAR_LINES (f) > 0;
17592 #endif
17594 else
17595 redisplay_menu_p = FRAME_MENU_BAR_LINES (f) > 0;
17597 if (redisplay_menu_p)
17598 display_menu_bar (w);
17600 #ifdef HAVE_WINDOW_SYSTEM
17601 if (FRAME_WINDOW_P (f))
17603 #if defined (USE_GTK) || defined (HAVE_NS)
17604 if (FRAME_EXTERNAL_TOOL_BAR (f))
17605 redisplay_tool_bar (f);
17606 #else
17607 if (WINDOWP (f->tool_bar_window)
17608 && (FRAME_TOOL_BAR_LINES (f) > 0
17609 || !NILP (Vauto_resize_tool_bars))
17610 && redisplay_tool_bar (f))
17611 ignore_mouse_drag_p = true;
17612 #endif
17614 x_consider_frame_title (w->frame);
17615 #endif
17618 #ifdef HAVE_WINDOW_SYSTEM
17619 if (FRAME_WINDOW_P (f)
17620 && update_window_fringes (w, (just_this_one_p
17621 || (!used_current_matrix_p && !overlay_arrow_seen)
17622 || w->pseudo_window_p)))
17624 update_begin (f);
17625 block_input ();
17626 if (draw_window_fringes (w, true))
17628 if (WINDOW_RIGHT_DIVIDER_WIDTH (w))
17629 x_draw_right_divider (w);
17630 else
17631 x_draw_vertical_border (w);
17633 unblock_input ();
17634 update_end (f);
17637 if (WINDOW_BOTTOM_DIVIDER_WIDTH (w))
17638 x_draw_bottom_divider (w);
17639 #endif /* HAVE_WINDOW_SYSTEM */
17641 /* We go to this label, with fonts_changed set, if it is
17642 necessary to try again using larger glyph matrices.
17643 We have to redeem the scroll bar even in this case,
17644 because the loop in redisplay_internal expects that. */
17645 need_larger_matrices:
17647 finish_scroll_bars:
17649 if (WINDOW_HAS_VERTICAL_SCROLL_BAR (w) || WINDOW_HAS_HORIZONTAL_SCROLL_BAR (w))
17651 if (WINDOW_HAS_VERTICAL_SCROLL_BAR (w))
17652 /* Set the thumb's position and size. */
17653 set_vertical_scroll_bar (w);
17655 if (WINDOW_HAS_HORIZONTAL_SCROLL_BAR (w))
17656 /* Set the thumb's position and size. */
17657 set_horizontal_scroll_bar (w);
17659 /* Note that we actually used the scroll bar attached to this
17660 window, so it shouldn't be deleted at the end of redisplay. */
17661 if (FRAME_TERMINAL (f)->redeem_scroll_bar_hook)
17662 (*FRAME_TERMINAL (f)->redeem_scroll_bar_hook) (w);
17665 /* Restore current_buffer and value of point in it. The window
17666 update may have changed the buffer, so first make sure `opoint'
17667 is still valid (Bug#6177). */
17668 if (CHARPOS (opoint) < BEGV)
17669 TEMP_SET_PT_BOTH (BEGV, BEGV_BYTE);
17670 else if (CHARPOS (opoint) > ZV)
17671 TEMP_SET_PT_BOTH (Z, Z_BYTE);
17672 else
17673 TEMP_SET_PT_BOTH (CHARPOS (opoint), BYTEPOS (opoint));
17675 set_buffer_internal_1 (old);
17676 /* Avoid an abort in TEMP_SET_PT_BOTH if the buffer has become
17677 shorter. This can be caused by log truncation in *Messages*. */
17678 if (CHARPOS (lpoint) <= ZV)
17679 TEMP_SET_PT_BOTH (CHARPOS (lpoint), BYTEPOS (lpoint));
17681 unbind_to (count, Qnil);
17685 /* Build the complete desired matrix of WINDOW with a window start
17686 buffer position POS.
17688 Value is 1 if successful. It is zero if fonts were loaded during
17689 redisplay which makes re-adjusting glyph matrices necessary, and -1
17690 if point would appear in the scroll margins.
17691 (We check the former only if TRY_WINDOW_IGNORE_FONTS_CHANGE is
17692 unset in FLAGS, and the latter only if TRY_WINDOW_CHECK_MARGINS is
17693 set in FLAGS.) */
17696 try_window (Lisp_Object window, struct text_pos pos, int flags)
17698 struct window *w = XWINDOW (window);
17699 struct it it;
17700 struct glyph_row *last_text_row = NULL;
17701 struct frame *f = XFRAME (w->frame);
17702 int cursor_vpos = w->cursor.vpos;
17704 /* Make POS the new window start. */
17705 set_marker_both (w->start, Qnil, CHARPOS (pos), BYTEPOS (pos));
17707 /* Mark cursor position as unknown. No overlay arrow seen. */
17708 w->cursor.vpos = -1;
17709 overlay_arrow_seen = false;
17711 /* Initialize iterator and info to start at POS. */
17712 start_display (&it, w, pos);
17713 it.glyph_row->reversed_p = false;
17715 /* Display all lines of W. */
17716 while (it.current_y < it.last_visible_y)
17718 if (display_line (&it, cursor_vpos))
17719 last_text_row = it.glyph_row - 1;
17720 if (f->fonts_changed && !(flags & TRY_WINDOW_IGNORE_FONTS_CHANGE))
17721 return 0;
17724 /* Save the character position of 'it' before we call
17725 'start_display' again. */
17726 ptrdiff_t it_charpos = IT_CHARPOS (it);
17728 /* Don't let the cursor end in the scroll margins. */
17729 if ((flags & TRY_WINDOW_CHECK_MARGINS)
17730 && !MINI_WINDOW_P (w))
17732 int this_scroll_margin = window_scroll_margin (w, MARGIN_IN_PIXELS);
17733 start_display (&it, w, pos);
17735 if ((w->cursor.y >= 0 /* not vscrolled */
17736 && w->cursor.y < this_scroll_margin
17737 && CHARPOS (pos) > BEGV
17738 && it_charpos < ZV)
17739 /* rms: considering make_cursor_line_fully_visible_p here
17740 seems to give wrong results. We don't want to recenter
17741 when the last line is partly visible, we want to allow
17742 that case to be handled in the usual way. */
17743 || w->cursor.y > (it.last_visible_y - partial_line_height (&it)
17744 - this_scroll_margin - 1))
17746 w->cursor.vpos = -1;
17747 clear_glyph_matrix (w->desired_matrix);
17748 return -1;
17752 /* If bottom moved off end of frame, change mode line percentage. */
17753 if (w->window_end_pos <= 0 && Z != it_charpos)
17754 w->update_mode_line = true;
17756 /* Set window_end_pos to the offset of the last character displayed
17757 on the window from the end of current_buffer. Set
17758 window_end_vpos to its row number. */
17759 if (last_text_row)
17761 eassert (MATRIX_ROW_DISPLAYS_TEXT_P (last_text_row));
17762 adjust_window_ends (w, last_text_row, false);
17763 eassert
17764 (MATRIX_ROW_DISPLAYS_TEXT_P (MATRIX_ROW (w->desired_matrix,
17765 w->window_end_vpos)));
17767 else
17769 w->window_end_bytepos = Z_BYTE - ZV_BYTE;
17770 w->window_end_pos = Z - ZV;
17771 w->window_end_vpos = 0;
17774 /* But that is not valid info until redisplay finishes. */
17775 w->window_end_valid = false;
17776 return 1;
17781 /************************************************************************
17782 Window redisplay reusing current matrix when buffer has not changed
17783 ************************************************************************/
17785 /* Try redisplay of window W showing an unchanged buffer with a
17786 different window start than the last time it was displayed by
17787 reusing its current matrix. Value is true if successful.
17788 W->start is the new window start. */
17790 static bool
17791 try_window_reusing_current_matrix (struct window *w)
17793 struct frame *f = XFRAME (w->frame);
17794 struct glyph_row *bottom_row;
17795 struct it it;
17796 struct run run;
17797 struct text_pos start, new_start;
17798 int nrows_scrolled, i;
17799 struct glyph_row *last_text_row;
17800 struct glyph_row *last_reused_text_row;
17801 struct glyph_row *start_row;
17802 int start_vpos, min_y, max_y;
17804 #ifdef GLYPH_DEBUG
17805 if (inhibit_try_window_reusing)
17806 return false;
17807 #endif
17809 if (/* This function doesn't handle terminal frames. */
17810 !FRAME_WINDOW_P (f)
17811 /* Don't try to reuse the display if windows have been split
17812 or such. */
17813 || windows_or_buffers_changed
17814 || f->cursor_type_changed
17815 /* This function cannot handle buffers where the overlay arrow
17816 is shown on the fringes, because if the arrow position
17817 changes, we cannot just reuse the current matrix. */
17818 || overlay_arrow_in_current_buffer_p ())
17819 return false;
17821 /* Can't do this if showing trailing whitespace. */
17822 if (!NILP (Vshow_trailing_whitespace))
17823 return false;
17825 /* If top-line visibility has changed, give up. */
17826 if (window_wants_header_line (w)
17827 != MATRIX_HEADER_LINE_ROW (w->current_matrix)->mode_line_p)
17828 return false;
17830 /* Give up if old or new display is scrolled vertically. We could
17831 make this function handle this, but right now it doesn't. */
17832 start_row = MATRIX_FIRST_TEXT_ROW (w->current_matrix);
17833 if (w->vscroll || MATRIX_ROW_PARTIALLY_VISIBLE_P (w, start_row))
17834 return false;
17836 /* Clear the desired matrix for the display below. */
17837 clear_glyph_matrix (w->desired_matrix);
17839 /* Give up if line numbers are being displayed, because reusing the
17840 current matrix might use the wrong width for line-number
17841 display. */
17842 if (!NILP (Vdisplay_line_numbers))
17843 return false;
17845 /* The variable new_start now holds the new window start. The old
17846 start `start' can be determined from the current matrix. */
17847 SET_TEXT_POS_FROM_MARKER (new_start, w->start);
17848 start = start_row->minpos;
17849 start_vpos = MATRIX_ROW_VPOS (start_row, w->current_matrix);
17851 if (CHARPOS (new_start) <= CHARPOS (start))
17853 /* Don't use this method if the display starts with an ellipsis
17854 displayed for invisible text. It's not easy to handle that case
17855 below, and it's certainly not worth the effort since this is
17856 not a frequent case. */
17857 if (in_ellipses_for_invisible_text_p (&start_row->start, w))
17858 return false;
17860 IF_DEBUG (debug_method_add (w, "twu1"));
17862 /* Display up to a row that can be reused. The variable
17863 last_text_row is set to the last row displayed that displays
17864 text. Note that it.vpos == 0 if or if not there is a
17865 header-line; it's not the same as the MATRIX_ROW_VPOS! */
17866 start_display (&it, w, new_start);
17867 w->cursor.vpos = -1;
17868 last_text_row = last_reused_text_row = NULL;
17870 while (it.current_y < it.last_visible_y && !f->fonts_changed)
17872 /* If we have reached into the characters in the START row,
17873 that means the line boundaries have changed. So we
17874 can't start copying with the row START. Maybe it will
17875 work to start copying with the following row. */
17876 while (IT_CHARPOS (it) > CHARPOS (start))
17878 /* Advance to the next row as the "start". */
17879 start_row++;
17880 start = start_row->minpos;
17881 /* If there are no more rows to try, or just one, give up. */
17882 if (start_row == MATRIX_MODE_LINE_ROW (w->current_matrix) - 1
17883 || w->vscroll || MATRIX_ROW_PARTIALLY_VISIBLE_P (w, start_row)
17884 || CHARPOS (start) == ZV)
17886 clear_glyph_matrix (w->desired_matrix);
17887 return false;
17890 start_vpos = MATRIX_ROW_VPOS (start_row, w->current_matrix);
17892 /* If we have reached alignment, we can copy the rest of the
17893 rows. */
17894 if (IT_CHARPOS (it) == CHARPOS (start)
17895 /* Don't accept "alignment" inside a display vector,
17896 since start_row could have started in the middle of
17897 that same display vector (thus their character
17898 positions match), and we have no way of telling if
17899 that is the case. */
17900 && it.current.dpvec_index < 0)
17901 break;
17903 it.glyph_row->reversed_p = false;
17904 if (display_line (&it, -1))
17905 last_text_row = it.glyph_row - 1;
17909 /* A value of current_y < last_visible_y means that we stopped
17910 at the previous window start, which in turn means that we
17911 have at least one reusable row. */
17912 if (it.current_y < it.last_visible_y)
17914 struct glyph_row *row;
17916 /* IT.vpos always starts from 0; it counts text lines. */
17917 nrows_scrolled = it.vpos - (start_row - MATRIX_FIRST_TEXT_ROW (w->current_matrix));
17919 /* Find PT if not already found in the lines displayed. */
17920 if (w->cursor.vpos < 0)
17922 int dy = it.current_y - start_row->y;
17924 row = MATRIX_FIRST_TEXT_ROW (w->current_matrix);
17925 row = row_containing_pos (w, PT, row, NULL, dy);
17926 if (row)
17927 set_cursor_from_row (w, row, w->current_matrix, 0, 0,
17928 dy, nrows_scrolled);
17929 else
17931 clear_glyph_matrix (w->desired_matrix);
17932 return false;
17936 /* Scroll the display. Do it before the current matrix is
17937 changed. The problem here is that update has not yet
17938 run, i.e. part of the current matrix is not up to date.
17939 scroll_run_hook will clear the cursor, and use the
17940 current matrix to get the height of the row the cursor is
17941 in. */
17942 run.current_y = start_row->y;
17943 run.desired_y = it.current_y;
17944 run.height = it.last_visible_y - it.current_y;
17946 if (run.height > 0 && run.current_y != run.desired_y)
17948 update_begin (f);
17949 FRAME_RIF (f)->update_window_begin_hook (w);
17950 FRAME_RIF (f)->clear_window_mouse_face (w);
17951 FRAME_RIF (f)->scroll_run_hook (w, &run);
17952 FRAME_RIF (f)->update_window_end_hook (w, false, false);
17953 update_end (f);
17956 /* Shift current matrix down by nrows_scrolled lines. */
17957 bottom_row = MATRIX_BOTTOM_TEXT_ROW (w->current_matrix, w);
17958 rotate_matrix (w->current_matrix,
17959 start_vpos,
17960 MATRIX_ROW_VPOS (bottom_row, w->current_matrix),
17961 nrows_scrolled);
17963 /* Disable lines that must be updated. */
17964 for (i = 0; i < nrows_scrolled; ++i)
17965 (start_row + i)->enabled_p = false;
17967 /* Re-compute Y positions. */
17968 min_y = WINDOW_HEADER_LINE_HEIGHT (w);
17969 max_y = it.last_visible_y;
17970 for (row = start_row + nrows_scrolled;
17971 row < bottom_row;
17972 ++row)
17974 row->y = it.current_y;
17975 row->visible_height = row->height;
17977 if (row->y < min_y)
17978 row->visible_height -= min_y - row->y;
17979 if (row->y + row->height > max_y)
17980 row->visible_height -= row->y + row->height - max_y;
17981 if (row->fringe_bitmap_periodic_p)
17982 row->redraw_fringe_bitmaps_p = true;
17984 it.current_y += row->height;
17986 if (MATRIX_ROW_DISPLAYS_TEXT_P (row))
17987 last_reused_text_row = row;
17988 if (MATRIX_ROW_BOTTOM_Y (row) >= it.last_visible_y)
17989 break;
17992 /* Disable lines in the current matrix which are now
17993 below the window. */
17994 for (++row; row < bottom_row; ++row)
17995 row->enabled_p = row->mode_line_p = false;
17998 /* Update window_end_pos etc.; last_reused_text_row is the last
17999 reused row from the current matrix containing text, if any.
18000 The value of last_text_row is the last displayed line
18001 containing text. */
18002 if (last_reused_text_row)
18003 adjust_window_ends (w, last_reused_text_row, true);
18004 else if (last_text_row)
18005 adjust_window_ends (w, last_text_row, false);
18006 else
18008 /* This window must be completely empty. */
18009 w->window_end_bytepos = Z_BYTE - ZV_BYTE;
18010 w->window_end_pos = Z - ZV;
18011 w->window_end_vpos = 0;
18013 w->window_end_valid = false;
18015 /* Update hint: don't try scrolling again in update_window. */
18016 w->desired_matrix->no_scrolling_p = true;
18018 #ifdef GLYPH_DEBUG
18019 debug_method_add (w, "try_window_reusing_current_matrix 1");
18020 #endif
18021 return true;
18023 else if (CHARPOS (new_start) > CHARPOS (start))
18025 struct glyph_row *pt_row, *row;
18026 struct glyph_row *first_reusable_row;
18027 struct glyph_row *first_row_to_display;
18028 int dy;
18029 int yb = window_text_bottom_y (w);
18031 /* Find the row starting at new_start, if there is one. Don't
18032 reuse a partially visible line at the end. */
18033 first_reusable_row = start_row;
18034 while (first_reusable_row->enabled_p
18035 && MATRIX_ROW_BOTTOM_Y (first_reusable_row) < yb
18036 && (MATRIX_ROW_START_CHARPOS (first_reusable_row)
18037 < CHARPOS (new_start)))
18038 ++first_reusable_row;
18040 /* Give up if there is no row to reuse. */
18041 if (MATRIX_ROW_BOTTOM_Y (first_reusable_row) >= yb
18042 || !first_reusable_row->enabled_p
18043 || (MATRIX_ROW_START_CHARPOS (first_reusable_row)
18044 != CHARPOS (new_start)))
18045 return false;
18047 /* We can reuse fully visible rows beginning with
18048 first_reusable_row to the end of the window. Set
18049 first_row_to_display to the first row that cannot be reused.
18050 Set pt_row to the row containing point, if there is any. */
18051 pt_row = NULL;
18052 for (first_row_to_display = first_reusable_row;
18053 MATRIX_ROW_BOTTOM_Y (first_row_to_display) < yb;
18054 ++first_row_to_display)
18056 if (PT >= MATRIX_ROW_START_CHARPOS (first_row_to_display)
18057 && (PT < MATRIX_ROW_END_CHARPOS (first_row_to_display)
18058 || (PT == MATRIX_ROW_END_CHARPOS (first_row_to_display)
18059 && first_row_to_display->ends_at_zv_p
18060 && pt_row == NULL)))
18061 pt_row = first_row_to_display;
18064 /* Start displaying at the start of first_row_to_display. */
18065 eassert (first_row_to_display->y < yb);
18066 init_to_row_start (&it, w, first_row_to_display);
18068 nrows_scrolled = (MATRIX_ROW_VPOS (first_reusable_row, w->current_matrix)
18069 - start_vpos);
18070 it.vpos = (MATRIX_ROW_VPOS (first_row_to_display, w->current_matrix)
18071 - nrows_scrolled);
18072 it.current_y = (first_row_to_display->y - first_reusable_row->y
18073 + WINDOW_HEADER_LINE_HEIGHT (w));
18075 /* Display lines beginning with first_row_to_display in the
18076 desired matrix. Set last_text_row to the last row displayed
18077 that displays text. */
18078 it.glyph_row = MATRIX_ROW (w->desired_matrix, it.vpos);
18079 if (pt_row == NULL)
18080 w->cursor.vpos = -1;
18081 last_text_row = NULL;
18082 while (it.current_y < it.last_visible_y && !f->fonts_changed)
18083 if (display_line (&it, w->cursor.vpos))
18084 last_text_row = it.glyph_row - 1;
18086 /* If point is in a reused row, adjust y and vpos of the cursor
18087 position. */
18088 if (pt_row)
18090 w->cursor.vpos -= nrows_scrolled;
18091 w->cursor.y -= first_reusable_row->y - start_row->y;
18094 /* Give up if point isn't in a row displayed or reused. (This
18095 also handles the case where w->cursor.vpos < nrows_scrolled
18096 after the calls to display_line, which can happen with scroll
18097 margins. See bug#1295.) */
18098 if (w->cursor.vpos < 0)
18100 clear_glyph_matrix (w->desired_matrix);
18101 return false;
18104 /* Scroll the display. */
18105 run.current_y = first_reusable_row->y;
18106 run.desired_y = WINDOW_HEADER_LINE_HEIGHT (w);
18107 run.height = it.last_visible_y - run.current_y;
18108 dy = run.current_y - run.desired_y;
18110 if (run.height)
18112 update_begin (f);
18113 FRAME_RIF (f)->update_window_begin_hook (w);
18114 FRAME_RIF (f)->clear_window_mouse_face (w);
18115 FRAME_RIF (f)->scroll_run_hook (w, &run);
18116 FRAME_RIF (f)->update_window_end_hook (w, false, false);
18117 update_end (f);
18120 /* Adjust Y positions of reused rows. */
18121 bottom_row = MATRIX_BOTTOM_TEXT_ROW (w->current_matrix, w);
18122 min_y = WINDOW_HEADER_LINE_HEIGHT (w);
18123 max_y = it.last_visible_y;
18124 for (row = first_reusable_row; row < first_row_to_display; ++row)
18126 row->y -= dy;
18127 row->visible_height = row->height;
18128 if (row->y < min_y)
18129 row->visible_height -= min_y - row->y;
18130 if (row->y + row->height > max_y)
18131 row->visible_height -= row->y + row->height - max_y;
18132 if (row->fringe_bitmap_periodic_p)
18133 row->redraw_fringe_bitmaps_p = true;
18136 /* Scroll the current matrix. */
18137 eassert (nrows_scrolled > 0);
18138 rotate_matrix (w->current_matrix,
18139 start_vpos,
18140 MATRIX_ROW_VPOS (bottom_row, w->current_matrix),
18141 -nrows_scrolled);
18143 /* Disable rows not reused. */
18144 for (row -= nrows_scrolled; row < bottom_row; ++row)
18145 row->enabled_p = false;
18147 /* Point may have moved to a different line, so we cannot assume that
18148 the previous cursor position is valid; locate the correct row. */
18149 if (pt_row)
18151 for (row = MATRIX_ROW (w->current_matrix, w->cursor.vpos);
18152 row < bottom_row
18153 && PT >= MATRIX_ROW_END_CHARPOS (row)
18154 && !row->ends_at_zv_p;
18155 row++)
18157 w->cursor.vpos++;
18158 w->cursor.y = row->y;
18160 if (row < bottom_row)
18162 /* Can't simply scan the row for point with
18163 bidi-reordered glyph rows. Let set_cursor_from_row
18164 figure out where to put the cursor, and if it fails,
18165 give up. */
18166 if (!NILP (BVAR (XBUFFER (w->contents), bidi_display_reordering)))
18168 if (!set_cursor_from_row (w, row, w->current_matrix,
18169 0, 0, 0, 0))
18171 clear_glyph_matrix (w->desired_matrix);
18172 return false;
18175 else
18177 struct glyph *glyph = row->glyphs[TEXT_AREA] + w->cursor.hpos;
18178 struct glyph *end = row->glyphs[TEXT_AREA] + row->used[TEXT_AREA];
18180 for (; glyph < end
18181 && (!BUFFERP (glyph->object)
18182 || glyph->charpos < PT);
18183 glyph++)
18185 w->cursor.hpos++;
18186 w->cursor.x += glyph->pixel_width;
18192 /* Adjust window end. A null value of last_text_row means that
18193 the window end is in reused rows which in turn means that
18194 only its vpos can have changed. */
18195 if (last_text_row)
18196 adjust_window_ends (w, last_text_row, false);
18197 else
18198 w->window_end_vpos -= nrows_scrolled;
18200 w->window_end_valid = false;
18201 w->desired_matrix->no_scrolling_p = true;
18203 #ifdef GLYPH_DEBUG
18204 debug_method_add (w, "try_window_reusing_current_matrix 2");
18205 #endif
18206 return true;
18209 return false;
18214 /************************************************************************
18215 Window redisplay reusing current matrix when buffer has changed
18216 ************************************************************************/
18218 static struct glyph_row *find_last_unchanged_at_beg_row (struct window *);
18219 static struct glyph_row *find_first_unchanged_at_end_row (struct window *,
18220 ptrdiff_t *, ptrdiff_t *);
18221 static struct glyph_row *
18222 find_last_row_displaying_text (struct glyph_matrix *, struct it *,
18223 struct glyph_row *);
18226 /* Return the last row in MATRIX displaying text. If row START is
18227 non-null, start searching with that row. IT gives the dimensions
18228 of the display. Value is null if matrix is empty; otherwise it is
18229 a pointer to the row found. */
18231 static struct glyph_row *
18232 find_last_row_displaying_text (struct glyph_matrix *matrix, struct it *it,
18233 struct glyph_row *start)
18235 struct glyph_row *row, *row_found;
18237 /* Set row_found to the last row in IT->w's current matrix
18238 displaying text. The loop looks funny but think of partially
18239 visible lines. */
18240 row_found = NULL;
18241 row = start ? start : MATRIX_FIRST_TEXT_ROW (matrix);
18242 while (MATRIX_ROW_DISPLAYS_TEXT_P (row))
18244 eassert (row->enabled_p);
18245 row_found = row;
18246 if (MATRIX_ROW_BOTTOM_Y (row) >= it->last_visible_y)
18247 break;
18248 ++row;
18251 return row_found;
18255 /* Return the last row in the current matrix of W that is not affected
18256 by changes at the start of current_buffer that occurred since W's
18257 current matrix was built. Value is null if no such row exists.
18259 BEG_UNCHANGED us the number of characters unchanged at the start of
18260 current_buffer. BEG + BEG_UNCHANGED is the buffer position of the
18261 first changed character in current_buffer. Characters at positions <
18262 BEG + BEG_UNCHANGED are at the same buffer positions as they were
18263 when the current matrix was built. */
18265 static struct glyph_row *
18266 find_last_unchanged_at_beg_row (struct window *w)
18268 ptrdiff_t first_changed_pos = BEG + BEG_UNCHANGED;
18269 struct glyph_row *row;
18270 struct glyph_row *row_found = NULL;
18271 int yb = window_text_bottom_y (w);
18273 /* Find the last row displaying unchanged text. */
18274 for (row = MATRIX_FIRST_TEXT_ROW (w->current_matrix);
18275 MATRIX_ROW_DISPLAYS_TEXT_P (row)
18276 && MATRIX_ROW_START_CHARPOS (row) < first_changed_pos;
18277 ++row)
18279 if (/* If row ends before first_changed_pos, it is unchanged,
18280 except in some case. */
18281 MATRIX_ROW_END_CHARPOS (row) <= first_changed_pos
18282 /* When row ends in ZV and we write at ZV it is not
18283 unchanged. */
18284 && !row->ends_at_zv_p
18285 /* When first_changed_pos is the end of a continued line,
18286 row is not unchanged because it may be no longer
18287 continued. */
18288 && !(MATRIX_ROW_END_CHARPOS (row) == first_changed_pos
18289 && (row->continued_p
18290 || row->exact_window_width_line_p))
18291 /* If ROW->end is beyond ZV, then ROW->end is outdated and
18292 needs to be recomputed, so don't consider this row as
18293 unchanged. This happens when the last line was
18294 bidi-reordered and was killed immediately before this
18295 redisplay cycle. In that case, ROW->end stores the
18296 buffer position of the first visual-order character of
18297 the killed text, which is now beyond ZV. */
18298 && CHARPOS (row->end.pos) <= ZV)
18299 row_found = row;
18301 /* Stop if last visible row. */
18302 if (MATRIX_ROW_BOTTOM_Y (row) >= yb)
18303 break;
18306 return row_found;
18310 /* Find the first glyph row in the current matrix of W that is not
18311 affected by changes at the end of current_buffer since the
18312 time W's current matrix was built.
18314 Return in *DELTA the number of chars by which buffer positions in
18315 unchanged text at the end of current_buffer must be adjusted.
18317 Return in *DELTA_BYTES the corresponding number of bytes.
18319 Value is null if no such row exists, i.e. all rows are affected by
18320 changes. */
18322 static struct glyph_row *
18323 find_first_unchanged_at_end_row (struct window *w,
18324 ptrdiff_t *delta, ptrdiff_t *delta_bytes)
18326 struct glyph_row *row;
18327 struct glyph_row *row_found = NULL;
18329 *delta = *delta_bytes = 0;
18331 /* Display must not have been paused, otherwise the current matrix
18332 is not up to date. */
18333 eassert (w->window_end_valid);
18335 /* A value of window_end_pos >= END_UNCHANGED means that the window
18336 end is in the range of changed text. If so, there is no
18337 unchanged row at the end of W's current matrix. */
18338 if (w->window_end_pos >= END_UNCHANGED)
18339 return NULL;
18341 /* Set row to the last row in W's current matrix displaying text. */
18342 row = MATRIX_ROW (w->current_matrix, w->window_end_vpos);
18344 /* If matrix is entirely empty, no unchanged row exists. */
18345 if (MATRIX_ROW_DISPLAYS_TEXT_P (row))
18347 /* The value of row is the last glyph row in the matrix having a
18348 meaningful buffer position in it. The end position of row
18349 corresponds to window_end_pos. This allows us to translate
18350 buffer positions in the current matrix to current buffer
18351 positions for characters not in changed text. */
18352 ptrdiff_t Z_old =
18353 MATRIX_ROW_END_CHARPOS (row) + w->window_end_pos;
18354 ptrdiff_t Z_BYTE_old =
18355 MATRIX_ROW_END_BYTEPOS (row) + w->window_end_bytepos;
18356 ptrdiff_t last_unchanged_pos, last_unchanged_pos_old;
18357 struct glyph_row *first_text_row
18358 = MATRIX_FIRST_TEXT_ROW (w->current_matrix);
18360 *delta = Z - Z_old;
18361 *delta_bytes = Z_BYTE - Z_BYTE_old;
18363 /* Set last_unchanged_pos to the buffer position of the last
18364 character in the buffer that has not been changed. Z is the
18365 index + 1 of the last character in current_buffer, i.e. by
18366 subtracting END_UNCHANGED we get the index of the last
18367 unchanged character, and we have to add BEG to get its buffer
18368 position. */
18369 last_unchanged_pos = Z - END_UNCHANGED + BEG;
18370 last_unchanged_pos_old = last_unchanged_pos - *delta;
18372 /* Search backward from ROW for a row displaying a line that
18373 starts at a minimum position >= last_unchanged_pos_old. */
18374 for (; row > first_text_row; --row)
18376 /* This used to abort, but it can happen.
18377 It is ok to just stop the search instead here. KFS. */
18378 if (!row->enabled_p || !MATRIX_ROW_DISPLAYS_TEXT_P (row))
18379 break;
18381 if (MATRIX_ROW_START_CHARPOS (row) >= last_unchanged_pos_old)
18382 row_found = row;
18386 eassert (!row_found || MATRIX_ROW_DISPLAYS_TEXT_P (row_found));
18388 return row_found;
18392 /* Make sure that glyph rows in the current matrix of window W
18393 reference the same glyph memory as corresponding rows in the
18394 frame's frame matrix. This function is called after scrolling W's
18395 current matrix on a terminal frame in try_window_id and
18396 try_window_reusing_current_matrix. */
18398 static void
18399 sync_frame_with_window_matrix_rows (struct window *w)
18401 struct frame *f = XFRAME (w->frame);
18402 struct glyph_row *window_row, *window_row_end, *frame_row;
18404 /* Preconditions: W must be a leaf window and full-width. Its frame
18405 must have a frame matrix. */
18406 eassert (BUFFERP (w->contents));
18407 eassert (WINDOW_FULL_WIDTH_P (w));
18408 eassert (!FRAME_WINDOW_P (f));
18410 /* If W is a full-width window, glyph pointers in W's current matrix
18411 have, by definition, to be the same as glyph pointers in the
18412 corresponding frame matrix. Note that frame matrices have no
18413 marginal areas (see build_frame_matrix). */
18414 window_row = w->current_matrix->rows;
18415 window_row_end = window_row + w->current_matrix->nrows;
18416 frame_row = f->current_matrix->rows + WINDOW_TOP_EDGE_LINE (w);
18417 while (window_row < window_row_end)
18419 struct glyph *start = window_row->glyphs[LEFT_MARGIN_AREA];
18420 struct glyph *end = window_row->glyphs[LAST_AREA];
18422 frame_row->glyphs[LEFT_MARGIN_AREA] = start;
18423 frame_row->glyphs[TEXT_AREA] = start;
18424 frame_row->glyphs[RIGHT_MARGIN_AREA] = end;
18425 frame_row->glyphs[LAST_AREA] = end;
18427 /* Disable frame rows whose corresponding window rows have
18428 been disabled in try_window_id. */
18429 if (!window_row->enabled_p)
18430 frame_row->enabled_p = false;
18432 ++window_row, ++frame_row;
18437 /* Find the glyph row in window W containing CHARPOS. Consider all
18438 rows between START and END (not inclusive). END null means search
18439 all rows to the end of the display area of W. Value is the row
18440 containing CHARPOS or null. */
18442 struct glyph_row *
18443 row_containing_pos (struct window *w, ptrdiff_t charpos,
18444 struct glyph_row *start, struct glyph_row *end, int dy)
18446 struct glyph_row *row = start;
18447 struct glyph_row *best_row = NULL;
18448 ptrdiff_t mindif = BUF_ZV (XBUFFER (w->contents)) + 1;
18449 int last_y;
18451 /* If we happen to start on a header-line, skip that. */
18452 if (row->mode_line_p)
18453 ++row;
18455 if ((end && row >= end) || !row->enabled_p)
18456 return NULL;
18458 last_y = window_text_bottom_y (w) - dy;
18460 while (true)
18462 /* Give up if we have gone too far. */
18463 if ((end && row >= end) || !row->enabled_p)
18464 return NULL;
18465 /* This formerly returned if they were equal.
18466 I think that both quantities are of a "last plus one" type;
18467 if so, when they are equal, the row is within the screen. -- rms. */
18468 if (MATRIX_ROW_BOTTOM_Y (row) > last_y)
18469 return NULL;
18471 /* If it is in this row, return this row. */
18472 if (! (MATRIX_ROW_END_CHARPOS (row) < charpos
18473 || (MATRIX_ROW_END_CHARPOS (row) == charpos
18474 /* The end position of a row equals the start
18475 position of the next row. If CHARPOS is there, we
18476 would rather consider it displayed in the next
18477 line, except when this line ends in ZV. */
18478 && !row_for_charpos_p (row, charpos)))
18479 && charpos >= MATRIX_ROW_START_CHARPOS (row))
18481 struct glyph *g;
18483 if (NILP (BVAR (XBUFFER (w->contents), bidi_display_reordering))
18484 || (!best_row && !row->continued_p))
18485 return row;
18486 /* In bidi-reordered rows, there could be several rows whose
18487 edges surround CHARPOS, all of these rows belonging to
18488 the same continued line. We need to find the row which
18489 fits CHARPOS the best. */
18490 for (g = row->glyphs[TEXT_AREA];
18491 g < row->glyphs[TEXT_AREA] + row->used[TEXT_AREA];
18492 g++)
18494 if (!STRINGP (g->object))
18496 if (g->charpos > 0 && eabs (g->charpos - charpos) < mindif)
18498 mindif = eabs (g->charpos - charpos);
18499 best_row = row;
18500 /* Exact match always wins. */
18501 if (mindif == 0)
18502 return best_row;
18507 else if (best_row && !row->continued_p)
18508 return best_row;
18509 ++row;
18514 /* Try to redisplay window W by reusing its existing display. W's
18515 current matrix must be up to date when this function is called,
18516 i.e., window_end_valid must be true.
18518 Value is
18520 >= 1 if successful, i.e. display has been updated
18521 specifically:
18522 1 means the changes were in front of a newline that precedes
18523 the window start, and the whole current matrix was reused
18524 2 means the changes were after the last position displayed
18525 in the window, and the whole current matrix was reused
18526 3 means portions of the current matrix were reused, while
18527 some of the screen lines were redrawn
18528 -1 if redisplay with same window start is known not to succeed
18529 0 if otherwise unsuccessful
18531 The following steps are performed:
18533 1. Find the last row in the current matrix of W that is not
18534 affected by changes at the start of current_buffer. If no such row
18535 is found, give up.
18537 2. Find the first row in W's current matrix that is not affected by
18538 changes at the end of current_buffer. Maybe there is no such row.
18540 3. Display lines beginning with the row + 1 found in step 1 to the
18541 row found in step 2 or, if step 2 didn't find a row, to the end of
18542 the window.
18544 4. If cursor is not known to appear on the window, give up.
18546 5. If display stopped at the row found in step 2, scroll the
18547 display and current matrix as needed.
18549 6. Maybe display some lines at the end of W, if we must. This can
18550 happen under various circumstances, like a partially visible line
18551 becoming fully visible, or because newly displayed lines are displayed
18552 in smaller font sizes.
18554 7. Update W's window end information. */
18556 static int
18557 try_window_id (struct window *w)
18559 struct frame *f = XFRAME (w->frame);
18560 struct glyph_matrix *current_matrix = w->current_matrix;
18561 struct glyph_matrix *desired_matrix = w->desired_matrix;
18562 struct glyph_row *last_unchanged_at_beg_row;
18563 struct glyph_row *first_unchanged_at_end_row;
18564 struct glyph_row *row;
18565 struct glyph_row *bottom_row;
18566 int bottom_vpos;
18567 struct it it;
18568 ptrdiff_t delta = 0, delta_bytes = 0, stop_pos;
18569 int dvpos, dy;
18570 struct text_pos start_pos;
18571 struct run run;
18572 int first_unchanged_at_end_vpos = 0;
18573 struct glyph_row *last_text_row, *last_text_row_at_end;
18574 struct text_pos start;
18575 ptrdiff_t first_changed_charpos, last_changed_charpos;
18577 #ifdef GLYPH_DEBUG
18578 if (inhibit_try_window_id)
18579 return 0;
18580 #endif
18582 /* This is handy for debugging. */
18583 #if false
18584 #define GIVE_UP(X) \
18585 do { \
18586 TRACE ((stderr, "try_window_id give up %d\n", (X))); \
18587 return 0; \
18588 } while (false)
18589 #else
18590 #define GIVE_UP(X) return 0
18591 #endif
18593 SET_TEXT_POS_FROM_MARKER (start, w->start);
18595 /* Don't use this for mini-windows because these can show
18596 messages and mini-buffers, and we don't handle that here. */
18597 if (MINI_WINDOW_P (w))
18598 GIVE_UP (1);
18600 /* This flag is used to prevent redisplay optimizations. */
18601 if (windows_or_buffers_changed || f->cursor_type_changed)
18602 GIVE_UP (2);
18604 /* This function's optimizations cannot be used if overlays have
18605 changed in the buffer displayed by the window, so give up if they
18606 have. */
18607 if (w->last_overlay_modified != OVERLAY_MODIFF)
18608 GIVE_UP (200);
18610 /* Verify that narrowing has not changed.
18611 Also verify that we were not told to prevent redisplay optimizations.
18612 It would be nice to further
18613 reduce the number of cases where this prevents try_window_id. */
18614 if (current_buffer->clip_changed
18615 || current_buffer->prevent_redisplay_optimizations_p)
18616 GIVE_UP (3);
18618 /* Window must either use window-based redisplay or be full width. */
18619 if (!FRAME_WINDOW_P (f)
18620 && (!FRAME_LINE_INS_DEL_OK (f)
18621 || !WINDOW_FULL_WIDTH_P (w)))
18622 GIVE_UP (4);
18624 /* Give up if point is known NOT to appear in W. */
18625 if (PT < CHARPOS (start))
18626 GIVE_UP (5);
18628 /* Another way to prevent redisplay optimizations. */
18629 if (w->last_modified == 0)
18630 GIVE_UP (6);
18632 /* Verify that window is not hscrolled. */
18633 if (w->hscroll != 0)
18634 GIVE_UP (7);
18636 /* Verify that display wasn't paused. */
18637 if (!w->window_end_valid)
18638 GIVE_UP (8);
18640 /* Likewise if highlighting trailing whitespace. */
18641 if (!NILP (Vshow_trailing_whitespace))
18642 GIVE_UP (11);
18644 /* Can't use this if overlay arrow position and/or string have
18645 changed. */
18646 if (overlay_arrows_changed_p (false))
18647 GIVE_UP (12);
18649 /* When word-wrap is on, adding a space to the first word of a
18650 wrapped line can change the wrap position, altering the line
18651 above it. It might be worthwhile to handle this more
18652 intelligently, but for now just redisplay from scratch. */
18653 if (!NILP (BVAR (XBUFFER (w->contents), word_wrap)))
18654 GIVE_UP (21);
18656 /* Under bidi reordering, adding or deleting a character in the
18657 beginning of a paragraph, before the first strong directional
18658 character, can change the base direction of the paragraph (unless
18659 the buffer specifies a fixed paragraph direction), which will
18660 require redisplaying the whole paragraph. It might be worthwhile
18661 to find the paragraph limits and widen the range of redisplayed
18662 lines to that, but for now just give up this optimization and
18663 redisplay from scratch. */
18664 if (!NILP (BVAR (XBUFFER (w->contents), bidi_display_reordering))
18665 && NILP (BVAR (XBUFFER (w->contents), bidi_paragraph_direction)))
18666 GIVE_UP (22);
18668 /* Give up if the buffer has line-spacing set, as Lisp-level changes
18669 to that variable require thorough redisplay. */
18670 if (!NILP (BVAR (XBUFFER (w->contents), extra_line_spacing)))
18671 GIVE_UP (23);
18673 /* Give up if display-line-numbers is in relative mode, or when the
18674 current line's number needs to be displayed in a distinct face. */
18675 if (EQ (Vdisplay_line_numbers, Qrelative)
18676 || EQ (Vdisplay_line_numbers, Qvisual)
18677 || (!NILP (Vdisplay_line_numbers)
18678 && NILP (Finternal_lisp_face_equal_p (Qline_number,
18679 Qline_number_current_line,
18680 w->frame))))
18681 GIVE_UP (24);
18683 /* Make sure beg_unchanged and end_unchanged are up to date. Do it
18684 only if buffer has really changed. The reason is that the gap is
18685 initially at Z for freshly visited files. The code below would
18686 set end_unchanged to 0 in that case. */
18687 if (MODIFF > SAVE_MODIFF
18688 /* This seems to happen sometimes after saving a buffer. */
18689 || BEG_UNCHANGED + END_UNCHANGED > Z_BYTE)
18691 if (GPT - BEG < BEG_UNCHANGED)
18692 BEG_UNCHANGED = GPT - BEG;
18693 if (Z - GPT < END_UNCHANGED)
18694 END_UNCHANGED = Z - GPT;
18697 /* The position of the first and last character that has been changed. */
18698 first_changed_charpos = BEG + BEG_UNCHANGED;
18699 last_changed_charpos = Z - END_UNCHANGED;
18701 /* If window starts after a line end, and the last change is in
18702 front of that newline, then changes don't affect the display.
18703 This case happens with stealth-fontification. Note that although
18704 the display is unchanged, glyph positions in the matrix have to
18705 be adjusted, of course. */
18706 row = MATRIX_ROW (w->current_matrix, w->window_end_vpos);
18707 if (MATRIX_ROW_DISPLAYS_TEXT_P (row)
18708 && ((last_changed_charpos < CHARPOS (start)
18709 && CHARPOS (start) == BEGV)
18710 || (last_changed_charpos < CHARPOS (start) - 1
18711 && FETCH_BYTE (BYTEPOS (start) - 1) == '\n')))
18713 ptrdiff_t Z_old, Z_delta, Z_BYTE_old, Z_delta_bytes;
18714 struct glyph_row *r0;
18716 /* Compute how many chars/bytes have been added to or removed
18717 from the buffer. */
18718 Z_old = MATRIX_ROW_END_CHARPOS (row) + w->window_end_pos;
18719 Z_BYTE_old = MATRIX_ROW_END_BYTEPOS (row) + w->window_end_bytepos;
18720 Z_delta = Z - Z_old;
18721 Z_delta_bytes = Z_BYTE - Z_BYTE_old;
18723 /* Give up if PT is not in the window. Note that it already has
18724 been checked at the start of try_window_id that PT is not in
18725 front of the window start. */
18726 if (PT >= MATRIX_ROW_END_CHARPOS (row) + Z_delta)
18727 GIVE_UP (13);
18729 /* If window start is unchanged, we can reuse the whole matrix
18730 as is, after adjusting glyph positions. No need to compute
18731 the window end again, since its offset from Z hasn't changed. */
18732 r0 = MATRIX_FIRST_TEXT_ROW (current_matrix);
18733 if (CHARPOS (start) == MATRIX_ROW_START_CHARPOS (r0) + Z_delta
18734 && BYTEPOS (start) == MATRIX_ROW_START_BYTEPOS (r0) + Z_delta_bytes
18735 /* PT must not be in a partially visible line. */
18736 && !(PT >= MATRIX_ROW_START_CHARPOS (row) + Z_delta
18737 && MATRIX_ROW_BOTTOM_Y (row) > window_text_bottom_y (w)))
18739 /* Adjust positions in the glyph matrix. */
18740 if (Z_delta || Z_delta_bytes)
18742 struct glyph_row *r1
18743 = MATRIX_BOTTOM_TEXT_ROW (current_matrix, w);
18744 increment_matrix_positions (w->current_matrix,
18745 MATRIX_ROW_VPOS (r0, current_matrix),
18746 MATRIX_ROW_VPOS (r1, current_matrix),
18747 Z_delta, Z_delta_bytes);
18750 /* Set the cursor. */
18751 row = row_containing_pos (w, PT, r0, NULL, 0);
18752 if (row)
18753 set_cursor_from_row (w, row, current_matrix, 0, 0, 0, 0);
18754 return 1;
18758 /* Handle the case that changes are all below what is displayed in
18759 the window, and that PT is in the window. This shortcut cannot
18760 be taken if ZV is visible in the window, and text has been added
18761 there that is visible in the window. */
18762 if (first_changed_charpos >= MATRIX_ROW_END_CHARPOS (row)
18763 /* ZV is not visible in the window, or there are no
18764 changes at ZV, actually. */
18765 && (current_matrix->zv > MATRIX_ROW_END_CHARPOS (row)
18766 || first_changed_charpos == last_changed_charpos))
18768 struct glyph_row *r0;
18770 /* Give up if PT is not in the window. Note that it already has
18771 been checked at the start of try_window_id that PT is not in
18772 front of the window start. */
18773 if (PT >= MATRIX_ROW_END_CHARPOS (row))
18774 GIVE_UP (14);
18776 /* If window start is unchanged, we can reuse the whole matrix
18777 as is, without changing glyph positions since no text has
18778 been added/removed in front of the window end. */
18779 r0 = MATRIX_FIRST_TEXT_ROW (current_matrix);
18780 if (TEXT_POS_EQUAL_P (start, r0->minpos)
18781 /* PT must not be in a partially visible line. */
18782 && !(PT >= MATRIX_ROW_START_CHARPOS (row)
18783 && MATRIX_ROW_BOTTOM_Y (row) > window_text_bottom_y (w)))
18785 /* We have to compute the window end anew since text
18786 could have been added/removed after it. */
18787 w->window_end_pos = Z - MATRIX_ROW_END_CHARPOS (row);
18788 w->window_end_bytepos = Z_BYTE - MATRIX_ROW_END_BYTEPOS (row);
18790 /* Set the cursor. */
18791 row = row_containing_pos (w, PT, r0, NULL, 0);
18792 if (row)
18793 set_cursor_from_row (w, row, current_matrix, 0, 0, 0, 0);
18794 return 2;
18798 /* Give up if window start is in the changed area.
18800 The condition used to read
18802 (BEG_UNCHANGED + END_UNCHANGED != Z - BEG && ...)
18804 but why that was tested escapes me at the moment. */
18805 if (CHARPOS (start) >= first_changed_charpos
18806 && CHARPOS (start) <= last_changed_charpos)
18807 GIVE_UP (15);
18809 /* Check that window start agrees with the start of the first glyph
18810 row in its current matrix. Check this after we know the window
18811 start is not in changed text, otherwise positions would not be
18812 comparable. */
18813 row = MATRIX_FIRST_TEXT_ROW (current_matrix);
18814 if (!TEXT_POS_EQUAL_P (start, row->minpos))
18815 GIVE_UP (16);
18817 /* Give up if the window ends in strings. Overlay strings
18818 at the end are difficult to handle, so don't try. */
18819 row = MATRIX_ROW (current_matrix, w->window_end_vpos);
18820 if (MATRIX_ROW_START_CHARPOS (row) == MATRIX_ROW_END_CHARPOS (row))
18821 GIVE_UP (20);
18823 /* Compute the position at which we have to start displaying new
18824 lines. Some of the lines at the top of the window might be
18825 reusable because they are not displaying changed text. Find the
18826 last row in W's current matrix not affected by changes at the
18827 start of current_buffer. Value is null if changes start in the
18828 first line of window. */
18829 last_unchanged_at_beg_row = find_last_unchanged_at_beg_row (w);
18830 if (last_unchanged_at_beg_row)
18832 /* Avoid starting to display in the middle of a character, a TAB
18833 for instance. This is easier than to set up the iterator
18834 exactly, and it's not a frequent case, so the additional
18835 effort wouldn't really pay off. */
18836 while ((MATRIX_ROW_ENDS_IN_MIDDLE_OF_CHAR_P (last_unchanged_at_beg_row)
18837 || last_unchanged_at_beg_row->ends_in_newline_from_string_p)
18838 && last_unchanged_at_beg_row > w->current_matrix->rows)
18839 --last_unchanged_at_beg_row;
18841 if (MATRIX_ROW_ENDS_IN_MIDDLE_OF_CHAR_P (last_unchanged_at_beg_row))
18842 GIVE_UP (17);
18844 if (! init_to_row_end (&it, w, last_unchanged_at_beg_row))
18845 GIVE_UP (18);
18846 start_pos = it.current.pos;
18848 /* Start displaying new lines in the desired matrix at the same
18849 vpos we would use in the current matrix, i.e. below
18850 last_unchanged_at_beg_row. */
18851 it.vpos = 1 + MATRIX_ROW_VPOS (last_unchanged_at_beg_row,
18852 current_matrix);
18853 it.glyph_row = MATRIX_ROW (desired_matrix, it.vpos);
18854 it.current_y = MATRIX_ROW_BOTTOM_Y (last_unchanged_at_beg_row);
18856 eassert (it.hpos == 0 && it.current_x == 0);
18858 else
18860 /* There are no reusable lines at the start of the window.
18861 Start displaying in the first text line. */
18862 start_display (&it, w, start);
18863 it.vpos = it.first_vpos;
18864 start_pos = it.current.pos;
18867 /* Find the first row that is not affected by changes at the end of
18868 the buffer. Value will be null if there is no unchanged row, in
18869 which case we must redisplay to the end of the window. delta
18870 will be set to the value by which buffer positions beginning with
18871 first_unchanged_at_end_row have to be adjusted due to text
18872 changes. */
18873 first_unchanged_at_end_row
18874 = find_first_unchanged_at_end_row (w, &delta, &delta_bytes);
18875 IF_DEBUG (debug_delta = delta);
18876 IF_DEBUG (debug_delta_bytes = delta_bytes);
18878 /* Set stop_pos to the buffer position up to which we will have to
18879 display new lines. If first_unchanged_at_end_row != NULL, this
18880 is the buffer position of the start of the line displayed in that
18881 row. For first_unchanged_at_end_row == NULL, use 0 to indicate
18882 that we don't stop at a buffer position. */
18883 stop_pos = 0;
18884 if (first_unchanged_at_end_row)
18886 eassert (last_unchanged_at_beg_row == NULL
18887 || first_unchanged_at_end_row >= last_unchanged_at_beg_row);
18889 /* If this is a continuation line, move forward to the next one
18890 that isn't. Changes in lines above affect this line.
18891 Caution: this may move first_unchanged_at_end_row to a row
18892 not displaying text. */
18893 while (MATRIX_ROW_CONTINUATION_LINE_P (first_unchanged_at_end_row)
18894 && MATRIX_ROW_DISPLAYS_TEXT_P (first_unchanged_at_end_row)
18895 && (MATRIX_ROW_BOTTOM_Y (first_unchanged_at_end_row)
18896 < it.last_visible_y))
18897 ++first_unchanged_at_end_row;
18899 if (!MATRIX_ROW_DISPLAYS_TEXT_P (first_unchanged_at_end_row)
18900 || (MATRIX_ROW_BOTTOM_Y (first_unchanged_at_end_row)
18901 >= it.last_visible_y))
18902 first_unchanged_at_end_row = NULL;
18903 else
18905 stop_pos = (MATRIX_ROW_START_CHARPOS (first_unchanged_at_end_row)
18906 + delta);
18907 first_unchanged_at_end_vpos
18908 = MATRIX_ROW_VPOS (first_unchanged_at_end_row, current_matrix);
18909 eassert (stop_pos >= Z - END_UNCHANGED);
18912 else if (last_unchanged_at_beg_row == NULL)
18913 GIVE_UP (19);
18916 #ifdef GLYPH_DEBUG
18918 /* Either there is no unchanged row at the end, or the one we have
18919 now displays text. This is a necessary condition for the window
18920 end pos calculation at the end of this function. */
18921 eassert (first_unchanged_at_end_row == NULL
18922 || MATRIX_ROW_DISPLAYS_TEXT_P (first_unchanged_at_end_row));
18924 debug_last_unchanged_at_beg_vpos
18925 = (last_unchanged_at_beg_row
18926 ? MATRIX_ROW_VPOS (last_unchanged_at_beg_row, current_matrix)
18927 : -1);
18928 debug_first_unchanged_at_end_vpos = first_unchanged_at_end_vpos;
18930 #endif /* GLYPH_DEBUG */
18933 /* Display new lines. Set last_text_row to the last new line
18934 displayed which has text on it, i.e. might end up as being the
18935 line where the window_end_vpos is. */
18936 w->cursor.vpos = -1;
18937 last_text_row = NULL;
18938 overlay_arrow_seen = false;
18939 if (it.current_y < it.last_visible_y
18940 && !f->fonts_changed
18941 && (first_unchanged_at_end_row == NULL
18942 || IT_CHARPOS (it) < stop_pos))
18943 it.glyph_row->reversed_p = false;
18944 while (it.current_y < it.last_visible_y
18945 && !f->fonts_changed
18946 && (first_unchanged_at_end_row == NULL
18947 || IT_CHARPOS (it) < stop_pos))
18949 if (display_line (&it, -1))
18950 last_text_row = it.glyph_row - 1;
18953 if (f->fonts_changed)
18954 return -1;
18956 /* The redisplay iterations in display_line above could have
18957 triggered font-lock, which could have done something that
18958 invalidates IT->w window's end-point information, on which we
18959 rely below. E.g., one package, which will remain unnamed, used
18960 to install a font-lock-fontify-region-function that called
18961 bury-buffer, whose side effect is to switch the buffer displayed
18962 by IT->w, and that predictably resets IT->w's window_end_valid
18963 flag, which we already tested at the entry to this function.
18964 Amply punish such packages/modes by giving up on this
18965 optimization in those cases. */
18966 if (!w->window_end_valid)
18968 clear_glyph_matrix (w->desired_matrix);
18969 return -1;
18972 /* Compute differences in buffer positions, y-positions etc. for
18973 lines reused at the bottom of the window. Compute what we can
18974 scroll. */
18975 if (first_unchanged_at_end_row
18976 /* No lines reused because we displayed everything up to the
18977 bottom of the window. */
18978 && it.current_y < it.last_visible_y)
18980 dvpos = (it.vpos
18981 - MATRIX_ROW_VPOS (first_unchanged_at_end_row,
18982 current_matrix));
18983 dy = it.current_y - first_unchanged_at_end_row->y;
18984 run.current_y = first_unchanged_at_end_row->y;
18985 run.desired_y = run.current_y + dy;
18986 run.height = it.last_visible_y - max (run.current_y, run.desired_y);
18988 else
18990 delta = delta_bytes = dvpos = dy
18991 = run.current_y = run.desired_y = run.height = 0;
18992 first_unchanged_at_end_row = NULL;
18994 IF_DEBUG ((debug_dvpos = dvpos, debug_dy = dy));
18997 /* Find the cursor if not already found. We have to decide whether
18998 PT will appear on this window (it sometimes doesn't, but this is
18999 not a very frequent case.) This decision has to be made before
19000 the current matrix is altered. A value of cursor.vpos < 0 means
19001 that PT is either in one of the lines beginning at
19002 first_unchanged_at_end_row or below the window. Don't care for
19003 lines that might be displayed later at the window end; as
19004 mentioned, this is not a frequent case. */
19005 if (w->cursor.vpos < 0)
19007 /* Cursor in unchanged rows at the top? */
19008 if (PT < CHARPOS (start_pos)
19009 && last_unchanged_at_beg_row)
19011 row = row_containing_pos (w, PT,
19012 MATRIX_FIRST_TEXT_ROW (w->current_matrix),
19013 last_unchanged_at_beg_row + 1, 0);
19014 if (row)
19015 set_cursor_from_row (w, row, w->current_matrix, 0, 0, 0, 0);
19018 /* Start from first_unchanged_at_end_row looking for PT. */
19019 else if (first_unchanged_at_end_row)
19021 row = row_containing_pos (w, PT - delta,
19022 first_unchanged_at_end_row, NULL, 0);
19023 if (row)
19024 set_cursor_from_row (w, row, w->current_matrix, delta,
19025 delta_bytes, dy, dvpos);
19028 /* Give up if cursor was not found. */
19029 if (w->cursor.vpos < 0)
19031 clear_glyph_matrix (w->desired_matrix);
19032 return -1;
19036 /* Don't let the cursor end in the scroll margins. */
19038 int this_scroll_margin = window_scroll_margin (w, MARGIN_IN_PIXELS);
19039 int cursor_height = MATRIX_ROW (w->desired_matrix, w->cursor.vpos)->height;
19041 if ((w->cursor.y < this_scroll_margin
19042 && CHARPOS (start) > BEGV)
19043 /* Old redisplay didn't take scroll margin into account at the bottom,
19044 but then global-hl-line-mode doesn't scroll. KFS 2004-06-14 */
19045 || (w->cursor.y + (make_cursor_line_fully_visible_p
19046 ? cursor_height + this_scroll_margin
19047 : 1)) > it.last_visible_y)
19049 w->cursor.vpos = -1;
19050 clear_glyph_matrix (w->desired_matrix);
19051 return -1;
19055 /* Scroll the display. Do it before changing the current matrix so
19056 that xterm.c doesn't get confused about where the cursor glyph is
19057 found. */
19058 if (dy && run.height)
19060 update_begin (f);
19062 if (FRAME_WINDOW_P (f))
19064 FRAME_RIF (f)->update_window_begin_hook (w);
19065 FRAME_RIF (f)->clear_window_mouse_face (w);
19066 FRAME_RIF (f)->scroll_run_hook (w, &run);
19067 FRAME_RIF (f)->update_window_end_hook (w, false, false);
19069 else
19071 /* Terminal frame. In this case, dvpos gives the number of
19072 lines to scroll by; dvpos < 0 means scroll up. */
19073 int from_vpos
19074 = MATRIX_ROW_VPOS (first_unchanged_at_end_row, w->current_matrix);
19075 int from = WINDOW_TOP_EDGE_LINE (w) + from_vpos;
19076 int end = (WINDOW_TOP_EDGE_LINE (w)
19077 + window_wants_header_line (w)
19078 + window_internal_height (w));
19080 #if defined (HAVE_GPM) || defined (MSDOS)
19081 x_clear_window_mouse_face (w);
19082 #endif
19083 /* Perform the operation on the screen. */
19084 if (dvpos > 0)
19086 /* Scroll last_unchanged_at_beg_row to the end of the
19087 window down dvpos lines. */
19088 set_terminal_window (f, end);
19090 /* On dumb terminals delete dvpos lines at the end
19091 before inserting dvpos empty lines. */
19092 if (!FRAME_SCROLL_REGION_OK (f))
19093 ins_del_lines (f, end - dvpos, -dvpos);
19095 /* Insert dvpos empty lines in front of
19096 last_unchanged_at_beg_row. */
19097 ins_del_lines (f, from, dvpos);
19099 else if (dvpos < 0)
19101 /* Scroll up last_unchanged_at_beg_vpos to the end of
19102 the window to last_unchanged_at_beg_vpos - |dvpos|. */
19103 set_terminal_window (f, end);
19105 /* Delete dvpos lines in front of
19106 last_unchanged_at_beg_vpos. ins_del_lines will set
19107 the cursor to the given vpos and emit |dvpos| delete
19108 line sequences. */
19109 ins_del_lines (f, from + dvpos, dvpos);
19111 /* On a dumb terminal insert dvpos empty lines at the
19112 end. */
19113 if (!FRAME_SCROLL_REGION_OK (f))
19114 ins_del_lines (f, end + dvpos, -dvpos);
19117 set_terminal_window (f, 0);
19120 update_end (f);
19123 /* Shift reused rows of the current matrix to the right position.
19124 BOTTOM_ROW is the last + 1 row in the current matrix reserved for
19125 text. */
19126 bottom_row = MATRIX_BOTTOM_TEXT_ROW (current_matrix, w);
19127 bottom_vpos = MATRIX_ROW_VPOS (bottom_row, current_matrix);
19128 if (dvpos < 0)
19130 rotate_matrix (current_matrix, first_unchanged_at_end_vpos + dvpos,
19131 bottom_vpos, dvpos);
19132 clear_glyph_matrix_rows (current_matrix, bottom_vpos + dvpos,
19133 bottom_vpos);
19135 else if (dvpos > 0)
19137 rotate_matrix (current_matrix, first_unchanged_at_end_vpos,
19138 bottom_vpos, dvpos);
19139 clear_glyph_matrix_rows (current_matrix, first_unchanged_at_end_vpos,
19140 first_unchanged_at_end_vpos + dvpos);
19143 /* For frame-based redisplay, make sure that current frame and window
19144 matrix are in sync with respect to glyph memory. */
19145 if (!FRAME_WINDOW_P (f))
19146 sync_frame_with_window_matrix_rows (w);
19148 /* Adjust buffer positions in reused rows. */
19149 if (delta || delta_bytes)
19150 increment_matrix_positions (current_matrix,
19151 first_unchanged_at_end_vpos + dvpos,
19152 bottom_vpos, delta, delta_bytes);
19154 /* Adjust Y positions. */
19155 if (dy)
19156 shift_glyph_matrix (w, current_matrix,
19157 first_unchanged_at_end_vpos + dvpos,
19158 bottom_vpos, dy);
19160 if (first_unchanged_at_end_row)
19162 first_unchanged_at_end_row += dvpos;
19163 if (first_unchanged_at_end_row->y >= it.last_visible_y
19164 || !MATRIX_ROW_DISPLAYS_TEXT_P (first_unchanged_at_end_row))
19165 first_unchanged_at_end_row = NULL;
19168 /* If scrolling up, there may be some lines to display at the end of
19169 the window. */
19170 last_text_row_at_end = NULL;
19171 if (dy < 0)
19173 /* Scrolling up can leave for example a partially visible line
19174 at the end of the window to be redisplayed. */
19175 /* Set last_row to the glyph row in the current matrix where the
19176 window end line is found. It has been moved up or down in
19177 the matrix by dvpos. */
19178 int last_vpos = w->window_end_vpos + dvpos;
19179 struct glyph_row *last_row = MATRIX_ROW (current_matrix, last_vpos);
19181 /* If last_row is the window end line, it should display text. */
19182 eassert (MATRIX_ROW_DISPLAYS_TEXT_P (last_row));
19184 /* If window end line was partially visible before, begin
19185 displaying at that line. Otherwise begin displaying with the
19186 line following it. */
19187 if (MATRIX_ROW_BOTTOM_Y (last_row) - dy >= it.last_visible_y)
19189 init_to_row_start (&it, w, last_row);
19190 it.vpos = last_vpos;
19191 it.current_y = last_row->y;
19193 else
19195 init_to_row_end (&it, w, last_row);
19196 it.vpos = 1 + last_vpos;
19197 it.current_y = MATRIX_ROW_BOTTOM_Y (last_row);
19198 ++last_row;
19201 /* We may start in a continuation line. If so, we have to
19202 get the right continuation_lines_width and current_x. */
19203 it.continuation_lines_width = last_row->continuation_lines_width;
19204 it.hpos = it.current_x = 0;
19206 /* Display the rest of the lines at the window end. */
19207 it.glyph_row = MATRIX_ROW (desired_matrix, it.vpos);
19208 while (it.current_y < it.last_visible_y && !f->fonts_changed)
19210 /* Is it always sure that the display agrees with lines in
19211 the current matrix? I don't think so, so we mark rows
19212 displayed invalid in the current matrix by setting their
19213 enabled_p flag to false. */
19214 SET_MATRIX_ROW_ENABLED_P (w->current_matrix, it.vpos, false);
19215 if (display_line (&it, w->cursor.vpos))
19216 last_text_row_at_end = it.glyph_row - 1;
19220 /* Update window_end_pos and window_end_vpos. */
19221 if (first_unchanged_at_end_row && !last_text_row_at_end)
19223 /* Window end line if one of the preserved rows from the current
19224 matrix. Set row to the last row displaying text in current
19225 matrix starting at first_unchanged_at_end_row, after
19226 scrolling. */
19227 eassert (MATRIX_ROW_DISPLAYS_TEXT_P (first_unchanged_at_end_row));
19228 row = find_last_row_displaying_text (w->current_matrix, &it,
19229 first_unchanged_at_end_row);
19230 eassume (row && MATRIX_ROW_DISPLAYS_TEXT_P (row));
19231 adjust_window_ends (w, row, true);
19232 eassert (w->window_end_bytepos >= 0);
19233 IF_DEBUG (debug_method_add (w, "A"));
19235 else if (last_text_row_at_end)
19237 adjust_window_ends (w, last_text_row_at_end, false);
19238 eassert (w->window_end_bytepos >= 0);
19239 IF_DEBUG (debug_method_add (w, "B"));
19241 else if (last_text_row)
19243 /* We have displayed either to the end of the window or at the
19244 end of the window, i.e. the last row with text is to be found
19245 in the desired matrix. */
19246 adjust_window_ends (w, last_text_row, false);
19247 eassert (w->window_end_bytepos >= 0);
19249 else if (first_unchanged_at_end_row == NULL
19250 && last_text_row == NULL
19251 && last_text_row_at_end == NULL)
19253 /* Displayed to end of window, but no line containing text was
19254 displayed. Lines were deleted at the end of the window. */
19255 bool first_vpos = window_wants_header_line (w);
19256 int vpos = w->window_end_vpos;
19257 struct glyph_row *current_row = current_matrix->rows + vpos;
19258 struct glyph_row *desired_row = desired_matrix->rows + vpos;
19260 for (row = NULL; !row; --vpos, --current_row, --desired_row)
19262 eassert (first_vpos <= vpos);
19263 if (desired_row->enabled_p)
19265 if (MATRIX_ROW_DISPLAYS_TEXT_P (desired_row))
19266 row = desired_row;
19268 else if (MATRIX_ROW_DISPLAYS_TEXT_P (current_row))
19269 row = current_row;
19272 w->window_end_vpos = vpos + 1;
19273 w->window_end_pos = Z - MATRIX_ROW_END_CHARPOS (row);
19274 w->window_end_bytepos = Z_BYTE - MATRIX_ROW_END_BYTEPOS (row);
19275 eassert (w->window_end_bytepos >= 0);
19276 IF_DEBUG (debug_method_add (w, "C"));
19278 else
19279 emacs_abort ();
19281 IF_DEBUG ((debug_end_pos = w->window_end_pos,
19282 debug_end_vpos = w->window_end_vpos));
19284 /* Record that display has not been completed. */
19285 w->window_end_valid = false;
19286 w->desired_matrix->no_scrolling_p = true;
19287 return 3;
19289 #undef GIVE_UP
19294 /***********************************************************************
19295 More debugging support
19296 ***********************************************************************/
19298 #ifdef GLYPH_DEBUG
19300 void dump_glyph_row (struct glyph_row *, int, int) EXTERNALLY_VISIBLE;
19301 void dump_glyph_matrix (struct glyph_matrix *, int) EXTERNALLY_VISIBLE;
19302 void dump_glyph (struct glyph_row *, struct glyph *, int) EXTERNALLY_VISIBLE;
19305 /* Dump the contents of glyph matrix MATRIX on stderr.
19307 GLYPHS 0 means don't show glyph contents.
19308 GLYPHS 1 means show glyphs in short form
19309 GLYPHS > 1 means show glyphs in long form. */
19311 void
19312 dump_glyph_matrix (struct glyph_matrix *matrix, int glyphs)
19314 int i;
19315 for (i = 0; i < matrix->nrows; ++i)
19316 dump_glyph_row (MATRIX_ROW (matrix, i), i, glyphs);
19320 /* Dump contents of glyph GLYPH to stderr. ROW and AREA are
19321 the glyph row and area where the glyph comes from. */
19323 void
19324 dump_glyph (struct glyph_row *row, struct glyph *glyph, int area)
19326 if (glyph->type == CHAR_GLYPH
19327 || glyph->type == GLYPHLESS_GLYPH)
19329 fprintf (stderr,
19330 " %5"pD"d %c %9"pD"d %c %3d 0x%06x %c %4d %1.1d%1.1d\n",
19331 glyph - row->glyphs[TEXT_AREA],
19332 (glyph->type == CHAR_GLYPH
19333 ? 'C'
19334 : 'G'),
19335 glyph->charpos,
19336 (BUFFERP (glyph->object)
19337 ? 'B'
19338 : (STRINGP (glyph->object)
19339 ? 'S'
19340 : (NILP (glyph->object)
19341 ? '0'
19342 : '-'))),
19343 glyph->pixel_width,
19344 glyph->u.ch,
19345 (glyph->u.ch < 0x80 && glyph->u.ch >= ' '
19346 ? (int) glyph->u.ch
19347 : '.'),
19348 glyph->face_id,
19349 glyph->left_box_line_p,
19350 glyph->right_box_line_p);
19352 else if (glyph->type == STRETCH_GLYPH)
19354 fprintf (stderr,
19355 " %5"pD"d %c %9"pD"d %c %3d 0x%06x %c %4d %1.1d%1.1d\n",
19356 glyph - row->glyphs[TEXT_AREA],
19357 'S',
19358 glyph->charpos,
19359 (BUFFERP (glyph->object)
19360 ? 'B'
19361 : (STRINGP (glyph->object)
19362 ? 'S'
19363 : (NILP (glyph->object)
19364 ? '0'
19365 : '-'))),
19366 glyph->pixel_width,
19368 ' ',
19369 glyph->face_id,
19370 glyph->left_box_line_p,
19371 glyph->right_box_line_p);
19373 else if (glyph->type == IMAGE_GLYPH)
19375 fprintf (stderr,
19376 " %5"pD"d %c %9"pD"d %c %3d 0x%06x %c %4d %1.1d%1.1d\n",
19377 glyph - row->glyphs[TEXT_AREA],
19378 'I',
19379 glyph->charpos,
19380 (BUFFERP (glyph->object)
19381 ? 'B'
19382 : (STRINGP (glyph->object)
19383 ? 'S'
19384 : (NILP (glyph->object)
19385 ? '0'
19386 : '-'))),
19387 glyph->pixel_width,
19388 (unsigned int) glyph->u.img_id,
19389 '.',
19390 glyph->face_id,
19391 glyph->left_box_line_p,
19392 glyph->right_box_line_p);
19394 else if (glyph->type == COMPOSITE_GLYPH)
19396 fprintf (stderr,
19397 " %5"pD"d %c %9"pD"d %c %3d 0x%06x",
19398 glyph - row->glyphs[TEXT_AREA],
19399 '+',
19400 glyph->charpos,
19401 (BUFFERP (glyph->object)
19402 ? 'B'
19403 : (STRINGP (glyph->object)
19404 ? 'S'
19405 : (NILP (glyph->object)
19406 ? '0'
19407 : '-'))),
19408 glyph->pixel_width,
19409 (unsigned int) glyph->u.cmp.id);
19410 if (glyph->u.cmp.automatic)
19411 fprintf (stderr,
19412 "[%d-%d]",
19413 glyph->slice.cmp.from, glyph->slice.cmp.to);
19414 fprintf (stderr, " . %4d %1.1d%1.1d\n",
19415 glyph->face_id,
19416 glyph->left_box_line_p,
19417 glyph->right_box_line_p);
19419 else if (glyph->type == XWIDGET_GLYPH)
19421 #ifndef HAVE_XWIDGETS
19422 eassume (false);
19423 #else
19424 fprintf (stderr,
19425 " %5d %4c %6d %c %3d 0x%05x %c %4d %1.1d%1.1d\n",
19426 glyph - row->glyphs[TEXT_AREA],
19427 'X',
19428 glyph->charpos,
19429 (BUFFERP (glyph->object)
19430 ? 'B'
19431 : (STRINGP (glyph->object)
19432 ? 'S'
19433 : '-')),
19434 glyph->pixel_width,
19435 glyph->u.xwidget,
19436 '.',
19437 glyph->face_id,
19438 glyph->left_box_line_p,
19439 glyph->right_box_line_p);
19440 #endif
19445 /* Dump the contents of glyph row at VPOS in MATRIX to stderr.
19446 GLYPHS 0 means don't show glyph contents.
19447 GLYPHS 1 means show glyphs in short form
19448 GLYPHS > 1 means show glyphs in long form. */
19450 void
19451 dump_glyph_row (struct glyph_row *row, int vpos, int glyphs)
19453 if (glyphs != 1)
19455 fprintf (stderr, "Row Start End Used oE><\\CTZFesm X Y W H V A P\n");
19456 fprintf (stderr, "==============================================================================\n");
19458 fprintf (stderr, "%3d %9"pD"d %9"pD"d %4d %1.1d%1.1d%1.1d%1.1d\
19459 %1.1d%1.1d%1.1d%1.1d%1.1d%1.1d%1.1d%1.1d %4d %4d %4d %4d %4d %4d %4d\n",
19460 vpos,
19461 MATRIX_ROW_START_CHARPOS (row),
19462 MATRIX_ROW_END_CHARPOS (row),
19463 row->used[TEXT_AREA],
19464 row->contains_overlapping_glyphs_p,
19465 row->enabled_p,
19466 row->truncated_on_left_p,
19467 row->truncated_on_right_p,
19468 row->continued_p,
19469 MATRIX_ROW_CONTINUATION_LINE_P (row),
19470 MATRIX_ROW_DISPLAYS_TEXT_P (row),
19471 row->ends_at_zv_p,
19472 row->fill_line_p,
19473 row->ends_in_middle_of_char_p,
19474 row->starts_in_middle_of_char_p,
19475 row->mouse_face_p,
19476 row->x,
19477 row->y,
19478 row->pixel_width,
19479 row->height,
19480 row->visible_height,
19481 row->ascent,
19482 row->phys_ascent);
19483 /* The next 3 lines should align to "Start" in the header. */
19484 fprintf (stderr, " %9"pD"d %9"pD"d\t%5d\n", row->start.overlay_string_index,
19485 row->end.overlay_string_index,
19486 row->continuation_lines_width);
19487 fprintf (stderr, " %9"pD"d %9"pD"d\n",
19488 CHARPOS (row->start.string_pos),
19489 CHARPOS (row->end.string_pos));
19490 fprintf (stderr, " %9d %9d\n", row->start.dpvec_index,
19491 row->end.dpvec_index);
19494 if (glyphs > 1)
19496 int area;
19498 for (area = LEFT_MARGIN_AREA; area < LAST_AREA; ++area)
19500 struct glyph *glyph = row->glyphs[area];
19501 struct glyph *glyph_end = glyph + row->used[area];
19503 /* Glyph for a line end in text. */
19504 if (area == TEXT_AREA && glyph == glyph_end && glyph->charpos > 0)
19505 ++glyph_end;
19507 if (glyph < glyph_end)
19508 fprintf (stderr, " Glyph# Type Pos O W Code C Face LR\n");
19510 for (; glyph < glyph_end; ++glyph)
19511 dump_glyph (row, glyph, area);
19514 else if (glyphs == 1)
19516 int area;
19517 char s[SHRT_MAX + 4];
19519 for (area = LEFT_MARGIN_AREA; area < LAST_AREA; ++area)
19521 int i;
19523 for (i = 0; i < row->used[area]; ++i)
19525 struct glyph *glyph = row->glyphs[area] + i;
19526 if (i == row->used[area] - 1
19527 && area == TEXT_AREA
19528 && NILP (glyph->object)
19529 && glyph->type == CHAR_GLYPH
19530 && glyph->u.ch == ' ')
19532 strcpy (&s[i], "[\\n]");
19533 i += 4;
19535 else if (glyph->type == CHAR_GLYPH
19536 && glyph->u.ch < 0x80
19537 && glyph->u.ch >= ' ')
19538 s[i] = glyph->u.ch;
19539 else
19540 s[i] = '.';
19543 s[i] = '\0';
19544 fprintf (stderr, "%3d: (%d) '%s'\n", vpos, row->enabled_p, s);
19550 DEFUN ("dump-glyph-matrix", Fdump_glyph_matrix,
19551 Sdump_glyph_matrix, 0, 1, "p",
19552 doc: /* Dump the current matrix of the selected window to stderr.
19553 Shows contents of glyph row structures. With non-nil
19554 parameter GLYPHS, dump glyphs as well. If GLYPHS is 1 show
19555 glyphs in short form, otherwise show glyphs in long form.
19557 Interactively, no argument means show glyphs in short form;
19558 with numeric argument, its value is passed as the GLYPHS flag. */)
19559 (Lisp_Object glyphs)
19561 struct window *w = XWINDOW (selected_window);
19562 struct buffer *buffer = XBUFFER (w->contents);
19564 fprintf (stderr, "PT = %"pD"d, BEGV = %"pD"d. ZV = %"pD"d\n",
19565 BUF_PT (buffer), BUF_BEGV (buffer), BUF_ZV (buffer));
19566 fprintf (stderr, "Cursor x = %d, y = %d, hpos = %d, vpos = %d\n",
19567 w->cursor.x, w->cursor.y, w->cursor.hpos, w->cursor.vpos);
19568 fprintf (stderr, "=============================================\n");
19569 dump_glyph_matrix (w->current_matrix,
19570 TYPE_RANGED_INTEGERP (int, glyphs) ? XINT (glyphs) : 0);
19571 return Qnil;
19575 DEFUN ("dump-frame-glyph-matrix", Fdump_frame_glyph_matrix,
19576 Sdump_frame_glyph_matrix, 0, 0, "", doc: /* Dump the current glyph matrix of the selected frame to stderr.
19577 Only text-mode frames have frame glyph matrices. */)
19578 (void)
19580 struct frame *f = XFRAME (selected_frame);
19582 if (f->current_matrix)
19583 dump_glyph_matrix (f->current_matrix, 1);
19584 else
19585 fprintf (stderr, "*** This frame doesn't have a frame glyph matrix ***\n");
19586 return Qnil;
19590 DEFUN ("dump-glyph-row", Fdump_glyph_row, Sdump_glyph_row, 1, 2, "P",
19591 doc: /* Dump glyph row ROW to stderr.
19592 Interactively, ROW is the prefix numeric argument and defaults to
19593 the row which displays point.
19594 Optional argument GLYPHS 0 means don't dump glyphs.
19595 GLYPHS 1 means dump glyphs in short form.
19596 GLYPHS > 1 or omitted means dump glyphs in long form. */)
19597 (Lisp_Object row, Lisp_Object glyphs)
19599 struct glyph_matrix *matrix;
19600 EMACS_INT vpos;
19602 if (NILP (row))
19604 int d1, d2, d3, d4, d5, ypos;
19605 bool visible_p = pos_visible_p (XWINDOW (selected_window), PT,
19606 &d1, &d2, &d3, &d4, &d5, &ypos);
19607 if (visible_p)
19608 vpos = ypos;
19609 else
19610 vpos = 0;
19612 else
19614 CHECK_NUMBER (row);
19615 vpos = XINT (row);
19617 matrix = XWINDOW (selected_window)->current_matrix;
19618 if (vpos >= 0 && vpos < matrix->nrows)
19619 dump_glyph_row (MATRIX_ROW (matrix, vpos),
19620 vpos,
19621 TYPE_RANGED_INTEGERP (int, glyphs) ? XINT (glyphs) : 2);
19622 return Qnil;
19626 DEFUN ("dump-tool-bar-row", Fdump_tool_bar_row, Sdump_tool_bar_row, 1, 2, "P",
19627 doc: /* Dump glyph row ROW of the tool-bar of the current frame to stderr.
19628 Interactively, ROW is the prefix numeric argument and defaults to zero.
19629 GLYPHS 0 means don't dump glyphs.
19630 GLYPHS 1 means dump glyphs in short form.
19631 GLYPHS > 1 or omitted means dump glyphs in long form.
19633 If there's no tool-bar, or if the tool-bar is not drawn by Emacs,
19634 do nothing. */)
19635 (Lisp_Object row, Lisp_Object glyphs)
19637 #if defined (HAVE_WINDOW_SYSTEM) && ! defined (USE_GTK) && ! defined (HAVE_NS)
19638 struct frame *sf = SELECTED_FRAME ();
19639 struct glyph_matrix *m = XWINDOW (sf->tool_bar_window)->current_matrix;
19640 EMACS_INT vpos;
19642 if (NILP (row))
19643 vpos = 0;
19644 else
19646 CHECK_NUMBER (row);
19647 vpos = XINT (row);
19649 if (vpos >= 0 && vpos < m->nrows)
19650 dump_glyph_row (MATRIX_ROW (m, vpos), vpos,
19651 TYPE_RANGED_INTEGERP (int, glyphs) ? XINT (glyphs) : 2);
19652 #endif
19653 return Qnil;
19657 DEFUN ("trace-redisplay", Ftrace_redisplay, Strace_redisplay, 0, 1, "P",
19658 doc: /* Toggle tracing of redisplay.
19659 With ARG, turn tracing on if and only if ARG is positive. */)
19660 (Lisp_Object arg)
19662 if (NILP (arg))
19663 trace_redisplay_p = !trace_redisplay_p;
19664 else
19666 arg = Fprefix_numeric_value (arg);
19667 trace_redisplay_p = XINT (arg) > 0;
19670 return Qnil;
19674 DEFUN ("trace-to-stderr", Ftrace_to_stderr, Strace_to_stderr, 1, MANY, "",
19675 doc: /* Like `format', but print result to stderr.
19676 usage: (trace-to-stderr STRING &rest OBJECTS) */)
19677 (ptrdiff_t nargs, Lisp_Object *args)
19679 Lisp_Object s = Fformat (nargs, args);
19680 fwrite (SDATA (s), 1, SBYTES (s), stderr);
19681 return Qnil;
19684 #endif /* GLYPH_DEBUG */
19688 /***********************************************************************
19689 Building Desired Matrix Rows
19690 ***********************************************************************/
19692 /* Return a temporary glyph row holding the glyphs of an overlay arrow.
19693 Used for non-window-redisplay windows, and for windows w/o left fringe. */
19695 static struct glyph_row *
19696 get_overlay_arrow_glyph_row (struct window *w, Lisp_Object overlay_arrow_string)
19698 struct frame *f = XFRAME (WINDOW_FRAME (w));
19699 struct buffer *buffer = XBUFFER (w->contents);
19700 struct buffer *old = current_buffer;
19701 const unsigned char *arrow_string = SDATA (overlay_arrow_string);
19702 ptrdiff_t arrow_len = SCHARS (overlay_arrow_string);
19703 const unsigned char *arrow_end = arrow_string + arrow_len;
19704 const unsigned char *p;
19705 struct it it;
19706 bool multibyte_p;
19707 int n_glyphs_before;
19709 set_buffer_temp (buffer);
19710 init_iterator (&it, w, -1, -1, &scratch_glyph_row, DEFAULT_FACE_ID);
19711 scratch_glyph_row.reversed_p = false;
19712 it.glyph_row->used[TEXT_AREA] = 0;
19713 SET_TEXT_POS (it.position, 0, 0);
19715 multibyte_p = !NILP (BVAR (buffer, enable_multibyte_characters));
19716 p = arrow_string;
19717 while (p < arrow_end)
19719 Lisp_Object face, ilisp;
19721 /* Get the next character. */
19722 if (multibyte_p)
19723 it.c = it.char_to_display = string_char_and_length (p, &it.len);
19724 else
19726 it.c = it.char_to_display = *p, it.len = 1;
19727 if (! ASCII_CHAR_P (it.c))
19728 it.char_to_display = BYTE8_TO_CHAR (it.c);
19730 p += it.len;
19732 /* Get its face. */
19733 ilisp = make_number (p - arrow_string);
19734 face = Fget_text_property (ilisp, Qface, overlay_arrow_string);
19735 it.face_id = compute_char_face (f, it.char_to_display, face);
19737 /* Compute its width, get its glyphs. */
19738 n_glyphs_before = it.glyph_row->used[TEXT_AREA];
19739 SET_TEXT_POS (it.position, -1, -1);
19740 PRODUCE_GLYPHS (&it);
19742 /* If this character doesn't fit any more in the line, we have
19743 to remove some glyphs. */
19744 if (it.current_x > it.last_visible_x)
19746 it.glyph_row->used[TEXT_AREA] = n_glyphs_before;
19747 break;
19751 set_buffer_temp (old);
19752 return it.glyph_row;
19756 /* Insert truncation glyphs at the start of IT->glyph_row. Which
19757 glyphs to insert is determined by produce_special_glyphs. */
19759 static void
19760 insert_left_trunc_glyphs (struct it *it)
19762 struct it truncate_it;
19763 struct glyph *from, *end, *to, *toend;
19765 eassert (!FRAME_WINDOW_P (it->f)
19766 || (!it->glyph_row->reversed_p
19767 && WINDOW_LEFT_FRINGE_WIDTH (it->w) == 0)
19768 || (it->glyph_row->reversed_p
19769 && WINDOW_RIGHT_FRINGE_WIDTH (it->w) == 0));
19771 /* Get the truncation glyphs. */
19772 truncate_it = *it;
19773 truncate_it.current_x = 0;
19774 truncate_it.face_id = DEFAULT_FACE_ID;
19775 truncate_it.glyph_row = &scratch_glyph_row;
19776 truncate_it.area = TEXT_AREA;
19777 truncate_it.glyph_row->used[TEXT_AREA] = 0;
19778 CHARPOS (truncate_it.position) = BYTEPOS (truncate_it.position) = -1;
19779 truncate_it.object = Qnil;
19780 produce_special_glyphs (&truncate_it, IT_TRUNCATION);
19782 /* Overwrite glyphs from IT with truncation glyphs. */
19783 if (!it->glyph_row->reversed_p)
19785 short tused = truncate_it.glyph_row->used[TEXT_AREA];
19787 from = truncate_it.glyph_row->glyphs[TEXT_AREA];
19788 end = from + tused;
19789 to = it->glyph_row->glyphs[TEXT_AREA];
19790 toend = to + it->glyph_row->used[TEXT_AREA];
19791 if (FRAME_WINDOW_P (it->f))
19793 /* On GUI frames, when variable-size fonts are displayed,
19794 the truncation glyphs may need more pixels than the row's
19795 glyphs they overwrite. We overwrite more glyphs to free
19796 enough screen real estate, and enlarge the stretch glyph
19797 on the right (see display_line), if there is one, to
19798 preserve the screen position of the truncation glyphs on
19799 the right. */
19800 int w = 0;
19801 struct glyph *g = to;
19802 short used;
19804 /* The first glyph could be partially visible, in which case
19805 it->glyph_row->x will be negative. But we want the left
19806 truncation glyphs to be aligned at the left margin of the
19807 window, so we override the x coordinate at which the row
19808 will begin. */
19809 it->glyph_row->x = 0;
19810 while (g < toend && w < it->truncation_pixel_width)
19812 w += g->pixel_width;
19813 ++g;
19815 if (g - to - tused > 0)
19817 memmove (to + tused, g, (toend - g) * sizeof(*g));
19818 it->glyph_row->used[TEXT_AREA] -= g - to - tused;
19820 used = it->glyph_row->used[TEXT_AREA];
19821 if (it->glyph_row->truncated_on_right_p
19822 && WINDOW_RIGHT_FRINGE_WIDTH (it->w) == 0
19823 && it->glyph_row->glyphs[TEXT_AREA][used - 2].type
19824 == STRETCH_GLYPH)
19826 int extra = w - it->truncation_pixel_width;
19828 it->glyph_row->glyphs[TEXT_AREA][used - 2].pixel_width += extra;
19832 while (from < end)
19833 *to++ = *from++;
19835 /* There may be padding glyphs left over. Overwrite them too. */
19836 if (!FRAME_WINDOW_P (it->f))
19838 while (to < toend && CHAR_GLYPH_PADDING_P (*to))
19840 from = truncate_it.glyph_row->glyphs[TEXT_AREA];
19841 while (from < end)
19842 *to++ = *from++;
19846 if (to > toend)
19847 it->glyph_row->used[TEXT_AREA] = to - it->glyph_row->glyphs[TEXT_AREA];
19849 else
19851 short tused = truncate_it.glyph_row->used[TEXT_AREA];
19853 /* In R2L rows, overwrite the last (rightmost) glyphs, and do
19854 that back to front. */
19855 end = truncate_it.glyph_row->glyphs[TEXT_AREA];
19856 from = end + truncate_it.glyph_row->used[TEXT_AREA] - 1;
19857 toend = it->glyph_row->glyphs[TEXT_AREA];
19858 to = toend + it->glyph_row->used[TEXT_AREA] - 1;
19859 if (FRAME_WINDOW_P (it->f))
19861 int w = 0;
19862 struct glyph *g = to;
19864 while (g >= toend && w < it->truncation_pixel_width)
19866 w += g->pixel_width;
19867 --g;
19869 if (to - g - tused > 0)
19870 to = g + tused;
19871 if (it->glyph_row->truncated_on_right_p
19872 && WINDOW_LEFT_FRINGE_WIDTH (it->w) == 0
19873 && it->glyph_row->glyphs[TEXT_AREA][1].type == STRETCH_GLYPH)
19875 int extra = w - it->truncation_pixel_width;
19877 it->glyph_row->glyphs[TEXT_AREA][1].pixel_width += extra;
19881 while (from >= end && to >= toend)
19882 *to-- = *from--;
19883 if (!FRAME_WINDOW_P (it->f))
19885 while (to >= toend && CHAR_GLYPH_PADDING_P (*to))
19887 from =
19888 truncate_it.glyph_row->glyphs[TEXT_AREA]
19889 + truncate_it.glyph_row->used[TEXT_AREA] - 1;
19890 while (from >= end && to >= toend)
19891 *to-- = *from--;
19894 if (from >= end)
19896 /* Need to free some room before prepending additional
19897 glyphs. */
19898 int move_by = from - end + 1;
19899 struct glyph *g0 = it->glyph_row->glyphs[TEXT_AREA];
19900 struct glyph *g = g0 + it->glyph_row->used[TEXT_AREA] - 1;
19902 for ( ; g >= g0; g--)
19903 g[move_by] = *g;
19904 while (from >= end)
19905 *to-- = *from--;
19906 it->glyph_row->used[TEXT_AREA] += move_by;
19911 /* Compute the hash code for ROW. */
19912 unsigned
19913 row_hash (struct glyph_row *row)
19915 int area, k;
19916 unsigned hashval = 0;
19918 for (area = LEFT_MARGIN_AREA; area < LAST_AREA; ++area)
19919 for (k = 0; k < row->used[area]; ++k)
19920 hashval = ((((hashval << 4) + (hashval >> 24)) & 0x0fffffff)
19921 + row->glyphs[area][k].u.val
19922 + row->glyphs[area][k].face_id
19923 + row->glyphs[area][k].padding_p
19924 + (row->glyphs[area][k].type << 2));
19926 return hashval;
19929 /* Compute the pixel height and width of IT->glyph_row.
19931 Most of the time, ascent and height of a display line will be equal
19932 to the max_ascent and max_height values of the display iterator
19933 structure. This is not the case if
19935 1. We hit ZV without displaying anything. In this case, max_ascent
19936 and max_height will be zero.
19938 2. We have some glyphs that don't contribute to the line height.
19939 (The glyph row flag contributes_to_line_height_p is for future
19940 pixmap extensions).
19942 The first case is easily covered by using default values because in
19943 these cases, the line height does not really matter, except that it
19944 must not be zero. */
19946 static void
19947 compute_line_metrics (struct it *it)
19949 struct glyph_row *row = it->glyph_row;
19951 if (FRAME_WINDOW_P (it->f))
19953 int i, min_y, max_y;
19955 /* The line may consist of one space only, that was added to
19956 place the cursor on it. If so, the row's height hasn't been
19957 computed yet. */
19958 if (row->height == 0)
19960 if (it->max_ascent + it->max_descent == 0)
19961 it->max_descent = it->max_phys_descent = FRAME_LINE_HEIGHT (it->f);
19962 row->ascent = it->max_ascent;
19963 row->height = it->max_ascent + it->max_descent;
19964 row->phys_ascent = it->max_phys_ascent;
19965 row->phys_height = it->max_phys_ascent + it->max_phys_descent;
19966 row->extra_line_spacing = it->max_extra_line_spacing;
19969 /* Compute the width of this line. */
19970 row->pixel_width = row->x;
19971 for (i = 0; i < row->used[TEXT_AREA]; ++i)
19972 row->pixel_width += row->glyphs[TEXT_AREA][i].pixel_width;
19974 eassert (row->pixel_width >= 0);
19975 eassert (row->ascent >= 0 && row->height > 0);
19977 row->overlapping_p = (MATRIX_ROW_OVERLAPS_SUCC_P (row)
19978 || MATRIX_ROW_OVERLAPS_PRED_P (row));
19980 /* If first line's physical ascent is larger than its logical
19981 ascent, use the physical ascent, and make the row taller.
19982 This makes accented characters fully visible. */
19983 if (row == MATRIX_FIRST_TEXT_ROW (it->w->desired_matrix)
19984 && row->phys_ascent > row->ascent)
19986 row->height += row->phys_ascent - row->ascent;
19987 row->ascent = row->phys_ascent;
19990 /* Compute how much of the line is visible. */
19991 row->visible_height = row->height;
19993 min_y = WINDOW_HEADER_LINE_HEIGHT (it->w);
19994 max_y = WINDOW_BOX_HEIGHT_NO_MODE_LINE (it->w);
19996 if (row->y < min_y)
19997 row->visible_height -= min_y - row->y;
19998 if (row->y + row->height > max_y)
19999 row->visible_height -= row->y + row->height - max_y;
20001 else
20003 row->pixel_width = row->used[TEXT_AREA];
20004 if (row->continued_p)
20005 row->pixel_width -= it->continuation_pixel_width;
20006 else if (row->truncated_on_right_p)
20007 row->pixel_width -= it->truncation_pixel_width;
20008 row->ascent = row->phys_ascent = 0;
20009 row->height = row->phys_height = row->visible_height = 1;
20010 row->extra_line_spacing = 0;
20013 /* Compute a hash code for this row. */
20014 row->hash = row_hash (row);
20016 it->max_ascent = it->max_descent = 0;
20017 it->max_phys_ascent = it->max_phys_descent = 0;
20021 /* Append one space to the glyph row of iterator IT if doing a
20022 window-based redisplay. The space has the same face as
20023 IT->face_id. Value is true if a space was added.
20025 This function is called to make sure that there is always one glyph
20026 at the end of a glyph row that the cursor can be set on under
20027 window-systems. (If there weren't such a glyph we would not know
20028 how wide and tall a box cursor should be displayed).
20030 At the same time this space let's a nicely handle clearing to the
20031 end of the line if the row ends in italic text. */
20033 static bool
20034 append_space_for_newline (struct it *it, bool default_face_p)
20036 if (FRAME_WINDOW_P (it->f))
20038 int n = it->glyph_row->used[TEXT_AREA];
20040 if (it->glyph_row->glyphs[TEXT_AREA] + n
20041 < it->glyph_row->glyphs[1 + TEXT_AREA])
20043 /* Save some values that must not be changed.
20044 Must save IT->c and IT->len because otherwise
20045 ITERATOR_AT_END_P wouldn't work anymore after
20046 append_space_for_newline has been called. */
20047 enum display_element_type saved_what = it->what;
20048 int saved_c = it->c, saved_len = it->len;
20049 int saved_char_to_display = it->char_to_display;
20050 int saved_x = it->current_x;
20051 int saved_face_id = it->face_id;
20052 bool saved_box_end = it->end_of_box_run_p;
20053 struct text_pos saved_pos;
20054 Lisp_Object saved_object;
20055 struct face *face;
20057 saved_object = it->object;
20058 saved_pos = it->position;
20060 it->what = IT_CHARACTER;
20061 memset (&it->position, 0, sizeof it->position);
20062 it->object = Qnil;
20063 it->c = it->char_to_display = ' ';
20064 it->len = 1;
20066 /* If the default face was remapped, be sure to use the
20067 remapped face for the appended newline. */
20068 if (default_face_p)
20069 it->face_id = lookup_basic_face (it->f, DEFAULT_FACE_ID);
20070 else if (it->face_before_selective_p)
20071 it->face_id = it->saved_face_id;
20072 face = FACE_FROM_ID (it->f, it->face_id);
20073 it->face_id = FACE_FOR_CHAR (it->f, face, 0, -1, Qnil);
20074 /* In R2L rows, we will prepend a stretch glyph that will
20075 have the end_of_box_run_p flag set for it, so there's no
20076 need for the appended newline glyph to have that flag
20077 set. */
20078 if (it->glyph_row->reversed_p
20079 /* But if the appended newline glyph goes all the way to
20080 the end of the row, there will be no stretch glyph,
20081 so leave the box flag set. */
20082 && saved_x + FRAME_COLUMN_WIDTH (it->f) < it->last_visible_x)
20083 it->end_of_box_run_p = false;
20085 PRODUCE_GLYPHS (it);
20087 #ifdef HAVE_WINDOW_SYSTEM
20088 /* Make sure this space glyph has the right ascent and
20089 descent values, or else cursor at end of line will look
20090 funny, and height of empty lines will be incorrect. */
20091 struct glyph *g = it->glyph_row->glyphs[TEXT_AREA] + n;
20092 struct font *font = face->font ? face->font : FRAME_FONT (it->f);
20093 if (n == 0)
20095 Lisp_Object height, total_height;
20096 int extra_line_spacing = it->extra_line_spacing;
20097 int boff = font->baseline_offset;
20099 if (font->vertical_centering)
20100 boff = VCENTER_BASELINE_OFFSET (font, it->f) - boff;
20102 it->object = saved_object; /* get_it_property needs this */
20103 normal_char_ascent_descent (font, -1, &it->ascent, &it->descent);
20104 /* Must do a subset of line height processing from
20105 x_produce_glyph for newline characters. */
20106 height = get_it_property (it, Qline_height);
20107 if (CONSP (height)
20108 && CONSP (XCDR (height))
20109 && NILP (XCDR (XCDR (height))))
20111 total_height = XCAR (XCDR (height));
20112 height = XCAR (height);
20114 else
20115 total_height = Qnil;
20116 height = calc_line_height_property (it, height, font, boff, true);
20118 if (it->override_ascent >= 0)
20120 it->ascent = it->override_ascent;
20121 it->descent = it->override_descent;
20122 boff = it->override_boff;
20124 if (EQ (height, Qt))
20125 extra_line_spacing = 0;
20126 else
20128 Lisp_Object spacing;
20130 it->phys_ascent = it->ascent;
20131 it->phys_descent = it->descent;
20132 if (!NILP (height)
20133 && XINT (height) > it->ascent + it->descent)
20134 it->ascent = XINT (height) - it->descent;
20136 if (!NILP (total_height))
20137 spacing = calc_line_height_property (it, total_height, font,
20138 boff, false);
20139 else
20141 spacing = get_it_property (it, Qline_spacing);
20142 spacing = calc_line_height_property (it, spacing, font,
20143 boff, false);
20145 if (INTEGERP (spacing))
20147 extra_line_spacing = XINT (spacing);
20148 if (!NILP (total_height))
20149 extra_line_spacing -= (it->phys_ascent + it->phys_descent);
20152 if (extra_line_spacing > 0)
20154 it->descent += extra_line_spacing;
20155 if (extra_line_spacing > it->max_extra_line_spacing)
20156 it->max_extra_line_spacing = extra_line_spacing;
20158 it->max_ascent = it->ascent;
20159 it->max_descent = it->descent;
20160 /* Make sure compute_line_metrics recomputes the row height. */
20161 it->glyph_row->height = 0;
20164 g->ascent = it->max_ascent;
20165 g->descent = it->max_descent;
20166 #endif
20168 it->override_ascent = -1;
20169 it->constrain_row_ascent_descent_p = false;
20170 it->current_x = saved_x;
20171 it->object = saved_object;
20172 it->position = saved_pos;
20173 it->what = saved_what;
20174 it->face_id = saved_face_id;
20175 it->len = saved_len;
20176 it->c = saved_c;
20177 it->char_to_display = saved_char_to_display;
20178 it->end_of_box_run_p = saved_box_end;
20179 return true;
20183 return false;
20187 /* Extend the face of the last glyph in the text area of IT->glyph_row
20188 to the end of the display line. Called from display_line. If the
20189 glyph row is empty, add a space glyph to it so that we know the
20190 face to draw. Set the glyph row flag fill_line_p. If the glyph
20191 row is R2L, prepend a stretch glyph to cover the empty space to the
20192 left of the leftmost glyph. */
20194 static void
20195 extend_face_to_end_of_line (struct it *it)
20197 struct face *face, *default_face;
20198 struct frame *f = it->f;
20200 /* If line is already filled, do nothing. Non window-system frames
20201 get a grace of one more ``pixel'' because their characters are
20202 1-``pixel'' wide, so they hit the equality too early. This grace
20203 is needed only for R2L rows that are not continued, to produce
20204 one extra blank where we could display the cursor. */
20205 if ((it->current_x >= it->last_visible_x
20206 + (!FRAME_WINDOW_P (f)
20207 && it->glyph_row->reversed_p
20208 && !it->glyph_row->continued_p))
20209 /* If the window has display margins, we will need to extend
20210 their face even if the text area is filled. */
20211 && !(WINDOW_LEFT_MARGIN_WIDTH (it->w) > 0
20212 || WINDOW_RIGHT_MARGIN_WIDTH (it->w) > 0))
20213 return;
20215 /* The default face, possibly remapped. */
20216 default_face = FACE_FROM_ID_OR_NULL (f,
20217 lookup_basic_face (f, DEFAULT_FACE_ID));
20219 /* Face extension extends the background and box of IT->face_id
20220 to the end of the line. If the background equals the background
20221 of the frame, we don't have to do anything. */
20222 face = FACE_FROM_ID (f, (it->face_before_selective_p
20223 ? it->saved_face_id
20224 : it->face_id));
20226 if (FRAME_WINDOW_P (f)
20227 && MATRIX_ROW_DISPLAYS_TEXT_P (it->glyph_row)
20228 && face->box == FACE_NO_BOX
20229 && face->background == FRAME_BACKGROUND_PIXEL (f)
20230 #ifdef HAVE_WINDOW_SYSTEM
20231 && !face->stipple
20232 #endif
20233 && !it->glyph_row->reversed_p)
20234 return;
20236 /* Set the glyph row flag indicating that the face of the last glyph
20237 in the text area has to be drawn to the end of the text area. */
20238 it->glyph_row->fill_line_p = true;
20240 /* If current character of IT is not ASCII, make sure we have the
20241 ASCII face. This will be automatically undone the next time
20242 get_next_display_element returns a multibyte character. Note
20243 that the character will always be single byte in unibyte
20244 text. */
20245 if (!ASCII_CHAR_P (it->c))
20247 it->face_id = FACE_FOR_CHAR (f, face, 0, -1, Qnil);
20250 if (FRAME_WINDOW_P (f))
20252 /* If the row is empty, add a space with the current face of IT,
20253 so that we know which face to draw. */
20254 if (it->glyph_row->used[TEXT_AREA] == 0)
20256 it->glyph_row->glyphs[TEXT_AREA][0] = space_glyph;
20257 it->glyph_row->glyphs[TEXT_AREA][0].face_id = face->id;
20258 it->glyph_row->used[TEXT_AREA] = 1;
20260 /* Mode line and the header line don't have margins, and
20261 likewise the frame's tool-bar window, if there is any. */
20262 if (!(it->glyph_row->mode_line_p
20263 #if defined (HAVE_WINDOW_SYSTEM) && ! defined (USE_GTK) && ! defined (HAVE_NS)
20264 || (WINDOWP (f->tool_bar_window)
20265 && it->w == XWINDOW (f->tool_bar_window))
20266 #endif
20269 if (WINDOW_LEFT_MARGIN_WIDTH (it->w) > 0
20270 && it->glyph_row->used[LEFT_MARGIN_AREA] == 0)
20272 it->glyph_row->glyphs[LEFT_MARGIN_AREA][0] = space_glyph;
20273 it->glyph_row->glyphs[LEFT_MARGIN_AREA][0].face_id =
20274 default_face->id;
20275 it->glyph_row->used[LEFT_MARGIN_AREA] = 1;
20277 if (WINDOW_RIGHT_MARGIN_WIDTH (it->w) > 0
20278 && it->glyph_row->used[RIGHT_MARGIN_AREA] == 0)
20280 it->glyph_row->glyphs[RIGHT_MARGIN_AREA][0] = space_glyph;
20281 it->glyph_row->glyphs[RIGHT_MARGIN_AREA][0].face_id =
20282 default_face->id;
20283 it->glyph_row->used[RIGHT_MARGIN_AREA] = 1;
20286 #ifdef HAVE_WINDOW_SYSTEM
20287 if (it->glyph_row->reversed_p)
20289 /* Prepend a stretch glyph to the row, such that the
20290 rightmost glyph will be drawn flushed all the way to the
20291 right margin of the window. The stretch glyph that will
20292 occupy the empty space, if any, to the left of the
20293 glyphs. */
20294 struct font *font = face->font ? face->font : FRAME_FONT (f);
20295 struct glyph *row_start = it->glyph_row->glyphs[TEXT_AREA];
20296 struct glyph *row_end = row_start + it->glyph_row->used[TEXT_AREA];
20297 struct glyph *g;
20298 int row_width, stretch_ascent, stretch_width;
20299 struct text_pos saved_pos;
20300 int saved_face_id;
20301 bool saved_avoid_cursor, saved_box_start;
20303 for (row_width = 0, g = row_start; g < row_end; g++)
20304 row_width += g->pixel_width;
20306 /* FIXME: There are various minor display glitches in R2L
20307 rows when only one of the fringes is missing. The
20308 strange condition below produces the least bad effect. */
20309 if ((WINDOW_LEFT_FRINGE_WIDTH (it->w) == 0)
20310 == (WINDOW_RIGHT_FRINGE_WIDTH (it->w) == 0)
20311 || WINDOW_RIGHT_FRINGE_WIDTH (it->w) != 0)
20312 stretch_width = window_box_width (it->w, TEXT_AREA);
20313 else
20314 stretch_width = it->last_visible_x - it->first_visible_x;
20315 stretch_width -= row_width;
20317 if (stretch_width > 0)
20319 stretch_ascent =
20320 (((it->ascent + it->descent)
20321 * FONT_BASE (font)) / FONT_HEIGHT (font));
20322 saved_pos = it->position;
20323 memset (&it->position, 0, sizeof it->position);
20324 saved_avoid_cursor = it->avoid_cursor_p;
20325 it->avoid_cursor_p = true;
20326 saved_face_id = it->face_id;
20327 saved_box_start = it->start_of_box_run_p;
20328 /* The last row's stretch glyph should get the default
20329 face, to avoid painting the rest of the window with
20330 the region face, if the region ends at ZV. */
20331 if (it->glyph_row->ends_at_zv_p)
20332 it->face_id = default_face->id;
20333 else
20334 it->face_id = face->id;
20335 it->start_of_box_run_p = false;
20336 append_stretch_glyph (it, Qnil, stretch_width,
20337 it->ascent + it->descent, stretch_ascent);
20338 it->position = saved_pos;
20339 it->avoid_cursor_p = saved_avoid_cursor;
20340 it->face_id = saved_face_id;
20341 it->start_of_box_run_p = saved_box_start;
20343 /* If stretch_width comes out negative, it means that the
20344 last glyph is only partially visible. In R2L rows, we
20345 want the leftmost glyph to be partially visible, so we
20346 need to give the row the corresponding left offset. */
20347 if (stretch_width < 0)
20348 it->glyph_row->x = stretch_width;
20350 #endif /* HAVE_WINDOW_SYSTEM */
20352 else
20354 /* Save some values that must not be changed. */
20355 int saved_x = it->current_x;
20356 struct text_pos saved_pos;
20357 Lisp_Object saved_object;
20358 enum display_element_type saved_what = it->what;
20359 int saved_face_id = it->face_id;
20361 saved_object = it->object;
20362 saved_pos = it->position;
20364 it->what = IT_CHARACTER;
20365 memset (&it->position, 0, sizeof it->position);
20366 it->object = Qnil;
20367 it->c = it->char_to_display = ' ';
20368 it->len = 1;
20370 if (WINDOW_LEFT_MARGIN_WIDTH (it->w) > 0
20371 && (it->glyph_row->used[LEFT_MARGIN_AREA]
20372 < WINDOW_LEFT_MARGIN_WIDTH (it->w))
20373 && !it->glyph_row->mode_line_p
20374 && default_face->background != FRAME_BACKGROUND_PIXEL (f))
20376 struct glyph *g = it->glyph_row->glyphs[LEFT_MARGIN_AREA];
20377 struct glyph *e = g + it->glyph_row->used[LEFT_MARGIN_AREA];
20379 for (it->current_x = 0; g < e; g++)
20380 it->current_x += g->pixel_width;
20382 it->area = LEFT_MARGIN_AREA;
20383 it->face_id = default_face->id;
20384 while (it->glyph_row->used[LEFT_MARGIN_AREA]
20385 < WINDOW_LEFT_MARGIN_WIDTH (it->w)
20386 && g < it->glyph_row->glyphs[TEXT_AREA])
20388 PRODUCE_GLYPHS (it);
20389 /* term.c:produce_glyphs advances it->current_x only for
20390 TEXT_AREA. */
20391 it->current_x += it->pixel_width;
20392 g++;
20395 it->current_x = saved_x;
20396 it->area = TEXT_AREA;
20399 /* The last row's blank glyphs should get the default face, to
20400 avoid painting the rest of the window with the region face,
20401 if the region ends at ZV. */
20402 if (it->glyph_row->ends_at_zv_p)
20403 it->face_id = default_face->id;
20404 else
20405 it->face_id = face->id;
20406 PRODUCE_GLYPHS (it);
20408 while (it->current_x <= it->last_visible_x)
20409 PRODUCE_GLYPHS (it);
20411 if (WINDOW_RIGHT_MARGIN_WIDTH (it->w) > 0
20412 && (it->glyph_row->used[RIGHT_MARGIN_AREA]
20413 < WINDOW_RIGHT_MARGIN_WIDTH (it->w))
20414 && !it->glyph_row->mode_line_p
20415 && default_face->background != FRAME_BACKGROUND_PIXEL (f))
20417 struct glyph *g = it->glyph_row->glyphs[RIGHT_MARGIN_AREA];
20418 struct glyph *e = g + it->glyph_row->used[RIGHT_MARGIN_AREA];
20420 for ( ; g < e; g++)
20421 it->current_x += g->pixel_width;
20423 it->area = RIGHT_MARGIN_AREA;
20424 it->face_id = default_face->id;
20425 while (it->glyph_row->used[RIGHT_MARGIN_AREA]
20426 < WINDOW_RIGHT_MARGIN_WIDTH (it->w)
20427 && g < it->glyph_row->glyphs[LAST_AREA])
20429 PRODUCE_GLYPHS (it);
20430 it->current_x += it->pixel_width;
20431 g++;
20434 it->area = TEXT_AREA;
20437 /* Don't count these blanks really. It would let us insert a left
20438 truncation glyph below and make us set the cursor on them, maybe. */
20439 it->current_x = saved_x;
20440 it->object = saved_object;
20441 it->position = saved_pos;
20442 it->what = saved_what;
20443 it->face_id = saved_face_id;
20448 /* Value is true if text starting at CHARPOS in current_buffer is
20449 trailing whitespace. */
20451 static bool
20452 trailing_whitespace_p (ptrdiff_t charpos)
20454 ptrdiff_t bytepos = CHAR_TO_BYTE (charpos);
20455 int c = 0;
20457 while (bytepos < ZV_BYTE
20458 && (c = FETCH_CHAR (bytepos),
20459 c == ' ' || c == '\t'))
20460 ++bytepos;
20462 if (bytepos >= ZV_BYTE || c == '\n' || c == '\r')
20464 if (bytepos != PT_BYTE)
20465 return true;
20467 return false;
20471 /* Highlight trailing whitespace, if any, in ROW. */
20473 static void
20474 highlight_trailing_whitespace (struct frame *f, struct glyph_row *row)
20476 int used = row->used[TEXT_AREA];
20478 if (used)
20480 struct glyph *start = row->glyphs[TEXT_AREA];
20481 struct glyph *glyph = start + used - 1;
20483 if (row->reversed_p)
20485 /* Right-to-left rows need to be processed in the opposite
20486 direction, so swap the edge pointers. */
20487 glyph = start;
20488 start = row->glyphs[TEXT_AREA] + used - 1;
20491 /* Skip over glyphs inserted to display the cursor at the
20492 end of a line, for extending the face of the last glyph
20493 to the end of the line on terminals, and for truncation
20494 and continuation glyphs. */
20495 if (!row->reversed_p)
20497 while (glyph >= start
20498 && glyph->type == CHAR_GLYPH
20499 && NILP (glyph->object))
20500 --glyph;
20502 else
20504 while (glyph <= start
20505 && glyph->type == CHAR_GLYPH
20506 && NILP (glyph->object))
20507 ++glyph;
20510 /* If last glyph is a space or stretch, and it's trailing
20511 whitespace, set the face of all trailing whitespace glyphs in
20512 IT->glyph_row to `trailing-whitespace'. */
20513 if ((row->reversed_p ? glyph <= start : glyph >= start)
20514 && BUFFERP (glyph->object)
20515 && (glyph->type == STRETCH_GLYPH
20516 || (glyph->type == CHAR_GLYPH
20517 && glyph->u.ch == ' '))
20518 && trailing_whitespace_p (glyph->charpos))
20520 int face_id = lookup_named_face (f, Qtrailing_whitespace, false);
20521 if (face_id < 0)
20522 return;
20524 if (!row->reversed_p)
20526 while (glyph >= start
20527 && BUFFERP (glyph->object)
20528 && (glyph->type == STRETCH_GLYPH
20529 || (glyph->type == CHAR_GLYPH
20530 && glyph->u.ch == ' ')))
20531 (glyph--)->face_id = face_id;
20533 else
20535 while (glyph <= start
20536 && BUFFERP (glyph->object)
20537 && (glyph->type == STRETCH_GLYPH
20538 || (glyph->type == CHAR_GLYPH
20539 && glyph->u.ch == ' ')))
20540 (glyph++)->face_id = face_id;
20547 /* Value is true if glyph row ROW should be
20548 considered to hold the buffer position CHARPOS. */
20550 static bool
20551 row_for_charpos_p (struct glyph_row *row, ptrdiff_t charpos)
20553 bool result = true;
20555 if (charpos == CHARPOS (row->end.pos)
20556 || charpos == MATRIX_ROW_END_CHARPOS (row))
20558 /* Suppose the row ends on a string.
20559 Unless the row is continued, that means it ends on a newline
20560 in the string. If it's anything other than a display string
20561 (e.g., a before-string from an overlay), we don't want the
20562 cursor there. (This heuristic seems to give the optimal
20563 behavior for the various types of multi-line strings.)
20564 One exception: if the string has `cursor' property on one of
20565 its characters, we _do_ want the cursor there. */
20566 if (CHARPOS (row->end.string_pos) >= 0)
20568 if (row->continued_p)
20569 result = true;
20570 else
20572 /* Check for `display' property. */
20573 struct glyph *beg = row->glyphs[TEXT_AREA];
20574 struct glyph *end = beg + row->used[TEXT_AREA] - 1;
20575 struct glyph *glyph;
20577 result = false;
20578 for (glyph = end; glyph >= beg; --glyph)
20579 if (STRINGP (glyph->object))
20581 Lisp_Object prop
20582 = Fget_char_property (make_number (charpos),
20583 Qdisplay, Qnil);
20584 result =
20585 (!NILP (prop)
20586 && display_prop_string_p (prop, glyph->object));
20587 /* If there's a `cursor' property on one of the
20588 string's characters, this row is a cursor row,
20589 even though this is not a display string. */
20590 if (!result)
20592 Lisp_Object s = glyph->object;
20594 for ( ; glyph >= beg && EQ (glyph->object, s); --glyph)
20596 ptrdiff_t gpos = glyph->charpos;
20598 if (!NILP (Fget_char_property (make_number (gpos),
20599 Qcursor, s)))
20601 result = true;
20602 break;
20606 break;
20610 else if (MATRIX_ROW_ENDS_IN_MIDDLE_OF_CHAR_P (row))
20612 /* If the row ends in middle of a real character,
20613 and the line is continued, we want the cursor here.
20614 That's because CHARPOS (ROW->end.pos) would equal
20615 PT if PT is before the character. */
20616 if (!row->ends_in_ellipsis_p)
20617 result = row->continued_p;
20618 else
20619 /* If the row ends in an ellipsis, then
20620 CHARPOS (ROW->end.pos) will equal point after the
20621 invisible text. We want that position to be displayed
20622 after the ellipsis. */
20623 result = false;
20625 /* If the row ends at ZV, display the cursor at the end of that
20626 row instead of at the start of the row below. */
20627 else
20628 result = row->ends_at_zv_p;
20631 return result;
20634 /* Value is true if glyph row ROW should be
20635 used to hold the cursor. */
20637 static bool
20638 cursor_row_p (struct glyph_row *row)
20640 return row_for_charpos_p (row, PT);
20645 /* Push the property PROP so that it will be rendered at the current
20646 position in IT. Return true if PROP was successfully pushed, false
20647 otherwise. Called from handle_line_prefix to handle the
20648 `line-prefix' and `wrap-prefix' properties. */
20650 static bool
20651 push_prefix_prop (struct it *it, Lisp_Object prop)
20653 struct text_pos pos =
20654 STRINGP (it->string) ? it->current.string_pos : it->current.pos;
20656 eassert (it->method == GET_FROM_BUFFER
20657 || it->method == GET_FROM_DISPLAY_VECTOR
20658 || it->method == GET_FROM_STRING
20659 || it->method == GET_FROM_IMAGE);
20661 /* We need to save the current buffer/string position, so it will be
20662 restored by pop_it, because iterate_out_of_display_property
20663 depends on that being set correctly, but some situations leave
20664 it->position not yet set when this function is called. */
20665 push_it (it, &pos);
20667 if (STRINGP (prop))
20669 if (SCHARS (prop) == 0)
20671 pop_it (it);
20672 return false;
20675 it->string = prop;
20676 it->string_from_prefix_prop_p = true;
20677 it->multibyte_p = STRING_MULTIBYTE (it->string);
20678 it->current.overlay_string_index = -1;
20679 IT_STRING_CHARPOS (*it) = IT_STRING_BYTEPOS (*it) = 0;
20680 it->end_charpos = it->string_nchars = SCHARS (it->string);
20681 it->method = GET_FROM_STRING;
20682 it->stop_charpos = 0;
20683 it->prev_stop = 0;
20684 it->base_level_stop = 0;
20685 it->cmp_it.id = -1;
20687 /* Force paragraph direction to be that of the parent
20688 buffer/string. */
20689 if (it->bidi_p && it->bidi_it.paragraph_dir == R2L)
20690 it->paragraph_embedding = it->bidi_it.paragraph_dir;
20691 else
20692 it->paragraph_embedding = L2R;
20694 /* Set up the bidi iterator for this display string. */
20695 if (it->bidi_p)
20697 it->bidi_it.string.lstring = it->string;
20698 it->bidi_it.string.s = NULL;
20699 it->bidi_it.string.schars = it->end_charpos;
20700 it->bidi_it.string.bufpos = IT_CHARPOS (*it);
20701 it->bidi_it.string.from_disp_str = it->string_from_display_prop_p;
20702 it->bidi_it.string.unibyte = !it->multibyte_p;
20703 it->bidi_it.w = it->w;
20704 bidi_init_it (0, 0, FRAME_WINDOW_P (it->f), &it->bidi_it);
20707 else if (CONSP (prop) && EQ (XCAR (prop), Qspace))
20709 it->method = GET_FROM_STRETCH;
20710 it->object = prop;
20712 #ifdef HAVE_WINDOW_SYSTEM
20713 else if (IMAGEP (prop))
20715 it->what = IT_IMAGE;
20716 it->image_id = lookup_image (it->f, prop);
20717 it->method = GET_FROM_IMAGE;
20719 #endif /* HAVE_WINDOW_SYSTEM */
20720 else
20722 pop_it (it); /* bogus display property, give up */
20723 return false;
20726 return true;
20729 /* Return the character-property PROP at the current position in IT. */
20731 static Lisp_Object
20732 get_it_property (struct it *it, Lisp_Object prop)
20734 Lisp_Object position, object = it->object;
20736 if (STRINGP (object))
20737 position = make_number (IT_STRING_CHARPOS (*it));
20738 else if (BUFFERP (object))
20740 position = make_number (IT_CHARPOS (*it));
20741 object = it->window;
20743 else
20744 return Qnil;
20746 return Fget_char_property (position, prop, object);
20749 /* See if there's a line- or wrap-prefix, and if so, push it on IT. */
20751 static void
20752 handle_line_prefix (struct it *it)
20754 Lisp_Object prefix;
20756 if (it->continuation_lines_width > 0)
20758 prefix = get_it_property (it, Qwrap_prefix);
20759 if (NILP (prefix))
20760 prefix = Vwrap_prefix;
20762 else
20764 prefix = get_it_property (it, Qline_prefix);
20765 if (NILP (prefix))
20766 prefix = Vline_prefix;
20768 if (! NILP (prefix) && push_prefix_prop (it, prefix))
20770 /* If the prefix is wider than the window, and we try to wrap
20771 it, it would acquire its own wrap prefix, and so on till the
20772 iterator stack overflows. So, don't wrap the prefix. */
20773 it->line_wrap = TRUNCATE;
20774 it->avoid_cursor_p = true;
20780 /* Remove N glyphs at the start of a reversed IT->glyph_row. Called
20781 only for R2L lines from display_line and display_string, when they
20782 decide that too many glyphs were produced by PRODUCE_GLYPHS, and
20783 the line/string needs to be continued on the next glyph row. */
20784 static void
20785 unproduce_glyphs (struct it *it, int n)
20787 struct glyph *glyph, *end;
20789 eassert (it->glyph_row);
20790 eassert (it->glyph_row->reversed_p);
20791 eassert (it->area == TEXT_AREA);
20792 eassert (n <= it->glyph_row->used[TEXT_AREA]);
20794 if (n > it->glyph_row->used[TEXT_AREA])
20795 n = it->glyph_row->used[TEXT_AREA];
20796 glyph = it->glyph_row->glyphs[TEXT_AREA] + n;
20797 end = it->glyph_row->glyphs[TEXT_AREA] + it->glyph_row->used[TEXT_AREA];
20798 for ( ; glyph < end; glyph++)
20799 glyph[-n] = *glyph;
20802 /* Find the positions in a bidi-reordered ROW to serve as ROW->minpos
20803 and ROW->maxpos. */
20804 static void
20805 find_row_edges (struct it *it, struct glyph_row *row,
20806 ptrdiff_t min_pos, ptrdiff_t min_bpos,
20807 ptrdiff_t max_pos, ptrdiff_t max_bpos)
20809 /* FIXME: Revisit this when glyph ``spilling'' in continuation
20810 lines' rows is implemented for bidi-reordered rows. */
20812 /* ROW->minpos is the value of min_pos, the minimal buffer position
20813 we have in ROW, or ROW->start.pos if that is smaller. */
20814 if (min_pos <= ZV && min_pos < row->start.pos.charpos)
20815 SET_TEXT_POS (row->minpos, min_pos, min_bpos);
20816 else
20817 /* We didn't find buffer positions smaller than ROW->start, or
20818 didn't find _any_ valid buffer positions in any of the glyphs,
20819 so we must trust the iterator's computed positions. */
20820 row->minpos = row->start.pos;
20821 if (max_pos <= 0)
20823 max_pos = CHARPOS (it->current.pos);
20824 max_bpos = BYTEPOS (it->current.pos);
20827 /* Here are the various use-cases for ending the row, and the
20828 corresponding values for ROW->maxpos:
20830 Line ends in a newline from buffer eol_pos + 1
20831 Line is continued from buffer max_pos + 1
20832 Line is truncated on right it->current.pos
20833 Line ends in a newline from string max_pos + 1(*)
20834 (*) + 1 only when line ends in a forward scan
20835 Line is continued from string max_pos
20836 Line is continued from display vector max_pos
20837 Line is entirely from a string min_pos == max_pos
20838 Line is entirely from a display vector min_pos == max_pos
20839 Line that ends at ZV ZV
20841 If you discover other use-cases, please add them here as
20842 appropriate. */
20843 if (row->ends_at_zv_p)
20844 row->maxpos = it->current.pos;
20845 else if (row->used[TEXT_AREA])
20847 bool seen_this_string = false;
20848 struct glyph_row *r1 = row - 1;
20850 /* Did we see the same display string on the previous row? */
20851 if (STRINGP (it->object)
20852 /* this is not the first row */
20853 && row > it->w->desired_matrix->rows
20854 /* previous row is not the header line */
20855 && !r1->mode_line_p
20856 /* previous row also ends in a newline from a string */
20857 && r1->ends_in_newline_from_string_p)
20859 struct glyph *start, *end;
20861 /* Search for the last glyph of the previous row that came
20862 from buffer or string. Depending on whether the row is
20863 L2R or R2L, we need to process it front to back or the
20864 other way round. */
20865 if (!r1->reversed_p)
20867 start = r1->glyphs[TEXT_AREA];
20868 end = start + r1->used[TEXT_AREA];
20869 /* Glyphs inserted by redisplay have nil as their object. */
20870 while (end > start
20871 && NILP ((end - 1)->object)
20872 && (end - 1)->charpos <= 0)
20873 --end;
20874 if (end > start)
20876 if (EQ ((end - 1)->object, it->object))
20877 seen_this_string = true;
20879 else
20880 /* If all the glyphs of the previous row were inserted
20881 by redisplay, it means the previous row was
20882 produced from a single newline, which is only
20883 possible if that newline came from the same string
20884 as the one which produced this ROW. */
20885 seen_this_string = true;
20887 else
20889 end = r1->glyphs[TEXT_AREA] - 1;
20890 start = end + r1->used[TEXT_AREA];
20891 while (end < start
20892 && NILP ((end + 1)->object)
20893 && (end + 1)->charpos <= 0)
20894 ++end;
20895 if (end < start)
20897 if (EQ ((end + 1)->object, it->object))
20898 seen_this_string = true;
20900 else
20901 seen_this_string = true;
20904 /* Take note of each display string that covers a newline only
20905 once, the first time we see it. This is for when a display
20906 string includes more than one newline in it. */
20907 if (row->ends_in_newline_from_string_p && !seen_this_string)
20909 /* If we were scanning the buffer forward when we displayed
20910 the string, we want to account for at least one buffer
20911 position that belongs to this row (position covered by
20912 the display string), so that cursor positioning will
20913 consider this row as a candidate when point is at the end
20914 of the visual line represented by this row. This is not
20915 required when scanning back, because max_pos will already
20916 have a much larger value. */
20917 if (CHARPOS (row->end.pos) > max_pos)
20918 INC_BOTH (max_pos, max_bpos);
20919 SET_TEXT_POS (row->maxpos, max_pos, max_bpos);
20921 else if (CHARPOS (it->eol_pos) > 0)
20922 SET_TEXT_POS (row->maxpos,
20923 CHARPOS (it->eol_pos) + 1, BYTEPOS (it->eol_pos) + 1);
20924 else if (row->continued_p)
20926 /* If max_pos is different from IT's current position, it
20927 means IT->method does not belong to the display element
20928 at max_pos. However, it also means that the display
20929 element at max_pos was displayed in its entirety on this
20930 line, which is equivalent to saying that the next line
20931 starts at the next buffer position. */
20932 if (IT_CHARPOS (*it) == max_pos && it->method != GET_FROM_BUFFER)
20933 SET_TEXT_POS (row->maxpos, max_pos, max_bpos);
20934 else
20936 INC_BOTH (max_pos, max_bpos);
20937 SET_TEXT_POS (row->maxpos, max_pos, max_bpos);
20940 else if (row->truncated_on_right_p)
20941 /* display_line already called reseat_at_next_visible_line_start,
20942 which puts the iterator at the beginning of the next line, in
20943 the logical order. */
20944 row->maxpos = it->current.pos;
20945 else if (max_pos == min_pos && it->method != GET_FROM_BUFFER)
20946 /* A line that is entirely from a string/image/stretch... */
20947 row->maxpos = row->minpos;
20948 else
20949 emacs_abort ();
20951 else
20952 row->maxpos = it->current.pos;
20955 /* Like display_count_lines, but capable of counting outside of the
20956 current narrowed region. */
20957 static ptrdiff_t
20958 display_count_lines_logically (ptrdiff_t start_byte, ptrdiff_t limit_byte,
20959 ptrdiff_t count, ptrdiff_t *byte_pos_ptr)
20961 if (!display_line_numbers_widen || (BEGV == BEG && ZV == Z))
20962 return display_count_lines (start_byte, limit_byte, count, byte_pos_ptr);
20964 ptrdiff_t val;
20965 ptrdiff_t pdl_count = SPECPDL_INDEX ();
20966 record_unwind_protect (save_restriction_restore, save_restriction_save ());
20967 Fwiden ();
20968 val = display_count_lines (start_byte, limit_byte, count, byte_pos_ptr);
20969 unbind_to (pdl_count, Qnil);
20970 return val;
20973 /* Count the number of screen lines in window IT->w between character
20974 position IT_CHARPOS(*IT) and the line showing that window's point. */
20975 static ptrdiff_t
20976 display_count_lines_visually (struct it *it)
20978 struct it tem_it;
20979 ptrdiff_t to;
20980 struct text_pos from;
20982 /* If we already calculated a relative line number, use that. This
20983 trick relies on the fact that visual lines (a.k.a. "glyph rows")
20984 are laid out sequentially, one by one, for each sequence of calls
20985 to display_line or other similar function that follows a call to
20986 init_iterator. */
20987 if (it->lnum_bytepos > 0)
20988 return it->lnum + 1;
20989 else
20991 ptrdiff_t count = SPECPDL_INDEX ();
20993 if (IT_CHARPOS (*it) <= PT)
20995 from = it->current.pos;
20996 to = PT;
20998 else
21000 SET_TEXT_POS (from, PT, PT_BYTE);
21001 to = IT_CHARPOS (*it);
21003 start_display (&tem_it, it->w, from);
21004 /* Need to disable visual mode temporarily, since otherwise the
21005 call to move_it_to will cause infinite recursion. */
21006 specbind (Qdisplay_line_numbers, Qrelative);
21007 /* Some redisplay optimizations could invoke us very far from
21008 PT, which will make the caller painfully slow. There should
21009 be no need to go too far beyond the window's bottom, as any
21010 such optimization will fail to show point anyway. */
21011 move_it_to (&tem_it, to, -1,
21012 tem_it.last_visible_y
21013 + (SCROLL_LIMIT + 10) * FRAME_LINE_HEIGHT (tem_it.f),
21014 -1, MOVE_TO_POS | MOVE_TO_Y);
21015 unbind_to (count, Qnil);
21016 return IT_CHARPOS (*it) <= PT ? -tem_it.vpos : tem_it.vpos;
21020 /* Produce the line-number glyphs for the current glyph_row. If
21021 IT->glyph_row is non-NULL, populate the row with the produced
21022 glyphs. */
21023 static void
21024 maybe_produce_line_number (struct it *it)
21026 ptrdiff_t last_line = it->lnum;
21027 ptrdiff_t start_from, bytepos;
21028 ptrdiff_t this_line;
21029 bool first_time = false;
21030 ptrdiff_t beg_byte = display_line_numbers_widen ? BEG_BYTE : BEGV_BYTE;
21031 ptrdiff_t z_byte = display_line_numbers_widen ? Z_BYTE : ZV_BYTE;
21032 void *itdata = bidi_shelve_cache ();
21034 if (EQ (Vdisplay_line_numbers, Qvisual))
21035 this_line = display_count_lines_visually (it);
21036 else
21038 if (!last_line)
21040 /* If possible, reuse data cached by line-number-mode. */
21041 if (it->w->base_line_number > 0
21042 && it->w->base_line_pos > 0
21043 && it->w->base_line_pos <= IT_CHARPOS (*it)
21044 /* line-number-mode always displays narrowed line
21045 numbers, so we cannot use its data if the user wants
21046 line numbers that disregard narrowing, or if the
21047 buffer's narrowing has just changed. */
21048 && !(display_line_numbers_widen
21049 && (BEG_BYTE != BEGV_BYTE || Z_BYTE != ZV_BYTE))
21050 && !current_buffer->clip_changed)
21052 start_from = CHAR_TO_BYTE (it->w->base_line_pos);
21053 last_line = it->w->base_line_number - 1;
21055 else
21056 start_from = beg_byte;
21057 if (!it->lnum_bytepos)
21058 first_time = true;
21060 else
21061 start_from = it->lnum_bytepos;
21063 /* Paranoia: what if someone changes the narrowing since the
21064 last time display_line was called? Shouldn't really happen,
21065 but who knows what some crazy Lisp invoked by :eval could do? */
21066 if (!(beg_byte <= start_from && start_from <= z_byte))
21068 last_line = 0;
21069 start_from = beg_byte;
21072 this_line =
21073 last_line + display_count_lines_logically (start_from,
21074 IT_BYTEPOS (*it),
21075 IT_CHARPOS (*it), &bytepos);
21076 eassert (this_line > 0 || (this_line == 0 && start_from == beg_byte));
21077 eassert (bytepos == IT_BYTEPOS (*it));
21080 /* Record the line number information. */
21081 if (this_line != last_line || !it->lnum_bytepos)
21083 it->lnum = this_line;
21084 it->lnum_bytepos = IT_BYTEPOS (*it);
21087 /* Produce the glyphs for the line number. */
21088 struct it tem_it;
21089 char lnum_buf[INT_STRLEN_BOUND (ptrdiff_t) + 1];
21090 bool beyond_zv = IT_BYTEPOS (*it) >= ZV_BYTE ? true : false;
21091 ptrdiff_t lnum_offset = -1; /* to produce 1-based line numbers */
21092 int lnum_face_id = merge_faces (it->f, Qline_number, 0, DEFAULT_FACE_ID);
21093 int current_lnum_face_id
21094 = merge_faces (it->f, Qline_number_current_line, 0, DEFAULT_FACE_ID);
21095 /* Compute point's line number if needed. */
21096 if ((EQ (Vdisplay_line_numbers, Qrelative)
21097 || EQ (Vdisplay_line_numbers, Qvisual)
21098 || lnum_face_id != current_lnum_face_id)
21099 && !it->pt_lnum)
21101 ptrdiff_t ignored;
21102 if (PT_BYTE > it->lnum_bytepos && !EQ (Vdisplay_line_numbers, Qvisual))
21103 it->pt_lnum =
21104 this_line + display_count_lines_logically (it->lnum_bytepos, PT_BYTE,
21105 PT, &ignored);
21106 else
21107 it->pt_lnum = display_count_lines_logically (beg_byte, PT_BYTE, PT,
21108 &ignored);
21110 /* Compute the required width if needed. */
21111 if (!it->lnum_width)
21113 if (NATNUMP (Vdisplay_line_numbers_width))
21114 it->lnum_width = XFASTINT (Vdisplay_line_numbers_width);
21116 /* Max line number to be displayed cannot be more than the one
21117 corresponding to the last row of the desired matrix. */
21118 ptrdiff_t max_lnum;
21120 if (NILP (Vdisplay_line_numbers_current_absolute)
21121 && (EQ (Vdisplay_line_numbers, Qrelative)
21122 || EQ (Vdisplay_line_numbers, Qvisual)))
21123 /* We subtract one more because the current line is always
21124 zero in this mode. */
21125 max_lnum = it->w->desired_matrix->nrows - 2;
21126 else if (EQ (Vdisplay_line_numbers, Qvisual))
21127 max_lnum = it->pt_lnum + it->w->desired_matrix->nrows - 1;
21128 else
21129 max_lnum = this_line + it->w->desired_matrix->nrows - 1 - it->vpos;
21130 max_lnum = max (1, max_lnum);
21131 it->lnum_width = max (it->lnum_width, log10 (max_lnum) + 1);
21132 eassert (it->lnum_width > 0);
21134 if (EQ (Vdisplay_line_numbers, Qrelative))
21135 lnum_offset = it->pt_lnum;
21136 else if (EQ (Vdisplay_line_numbers, Qvisual))
21137 lnum_offset = 0;
21139 /* Under 'relative', display the absolute line number for the
21140 current line, unless the user requests otherwise. */
21141 ptrdiff_t lnum_to_display = eabs (this_line - lnum_offset);
21142 if ((EQ (Vdisplay_line_numbers, Qrelative)
21143 || EQ (Vdisplay_line_numbers, Qvisual))
21144 && lnum_to_display == 0
21145 && !NILP (Vdisplay_line_numbers_current_absolute))
21146 lnum_to_display = it->pt_lnum + 1;
21147 /* In L2R rows we need to append the blank separator, in R2L
21148 rows we need to prepend it. But this function is usually
21149 called when no display elements were produced from the
21150 following line, so the paragraph direction might be unknown.
21151 Therefore we cheat and add 2 blanks, one on either side. */
21152 pint2str (lnum_buf, it->lnum_width + 1, lnum_to_display);
21153 strcat (lnum_buf, " ");
21155 /* Setup for producing the glyphs. */
21156 init_iterator (&tem_it, it->w, -1, -1, &scratch_glyph_row,
21157 /* FIXME: Use specialized face. */
21158 DEFAULT_FACE_ID);
21159 scratch_glyph_row.reversed_p = false;
21160 scratch_glyph_row.used[TEXT_AREA] = 0;
21161 SET_TEXT_POS (tem_it.position, 0, 0);
21162 tem_it.avoid_cursor_p = true;
21163 tem_it.bidi_p = true;
21164 tem_it.bidi_it.type = WEAK_EN;
21165 /* According to UAX#9, EN goes up 2 levels in L2R paragraph and
21166 1 level in R2L paragraphs. Emulate that, assuming we are in
21167 an L2R paragraph. */
21168 tem_it.bidi_it.resolved_level = 2;
21170 /* Produce glyphs for the line number in a scratch glyph_row. */
21171 int n_glyphs_before;
21172 for (const char *p = lnum_buf; *p; p++)
21174 /* For continuation lines and lines after ZV, instead of a line
21175 number, produce a blank prefix of the same width. Use the
21176 default face for the blank field beyond ZV. */
21177 if (beyond_zv)
21178 tem_it.face_id = it->base_face_id;
21179 else if (lnum_face_id != current_lnum_face_id
21180 && (EQ (Vdisplay_line_numbers, Qvisual)
21181 ? this_line == 0
21182 : this_line == it->pt_lnum))
21183 tem_it.face_id = current_lnum_face_id;
21184 else
21185 tem_it.face_id = lnum_face_id;
21186 if (beyond_zv
21187 /* Don't display the same line number more than once. */
21188 || (!EQ (Vdisplay_line_numbers, Qvisual)
21189 && (it->continuation_lines_width > 0
21190 || (this_line == last_line && !first_time))))
21191 tem_it.c = tem_it.char_to_display = ' ';
21192 else
21193 tem_it.c = tem_it.char_to_display = *p;
21194 tem_it.len = 1;
21195 n_glyphs_before = scratch_glyph_row.used[TEXT_AREA];
21196 /* Make sure these glyphs will have a "position" of -1. */
21197 SET_TEXT_POS (tem_it.position, -1, -1);
21198 PRODUCE_GLYPHS (&tem_it);
21200 /* Stop producing glyphs if we don't have enough space on
21201 this line. FIXME: should we refrain from producing the
21202 line number at all in that case? */
21203 if (tem_it.current_x > tem_it.last_visible_x)
21205 scratch_glyph_row.used[TEXT_AREA] = n_glyphs_before;
21206 break;
21210 /* Record the width in pixels we need for the line number display. */
21211 it->lnum_pixel_width = tem_it.current_x;
21212 /* Copy the produced glyphs into IT's glyph_row. */
21213 struct glyph *g = scratch_glyph_row.glyphs[TEXT_AREA];
21214 struct glyph *e = g + scratch_glyph_row.used[TEXT_AREA];
21215 struct glyph *p = it->glyph_row ? it->glyph_row->glyphs[TEXT_AREA] : NULL;
21216 short *u = it->glyph_row ? &it->glyph_row->used[TEXT_AREA] : NULL;
21218 eassert (it->glyph_row == NULL || it->glyph_row->used[TEXT_AREA] == 0);
21220 for ( ; g < e; g++)
21222 it->current_x += g->pixel_width;
21223 /* The following is important when this function is called
21224 from move_it_in_display_line_to: HPOS is incremented only
21225 when we are in the visible portion of the glyph row. */
21226 if (it->current_x > it->first_visible_x)
21227 it->hpos++;
21228 if (p)
21230 *p++ = *g;
21231 (*u)++;
21235 /* Update IT's metrics due to glyphs produced for line numbers. */
21236 if (it->glyph_row)
21238 struct glyph_row *row = it->glyph_row;
21240 it->max_ascent = max (row->ascent, tem_it.max_ascent);
21241 it->max_descent = max (row->height - row->ascent, tem_it.max_descent);
21242 it->max_phys_ascent = max (row->phys_ascent, tem_it.max_phys_ascent);
21243 it->max_phys_descent = max (row->phys_height - row->phys_ascent,
21244 tem_it.max_phys_descent);
21246 else
21248 it->max_ascent = max (it->max_ascent, tem_it.max_ascent);
21249 it->max_descent = max (it->max_descent, tem_it.max_descent);
21250 it->max_phys_ascent = max (it->max_phys_ascent, tem_it.max_phys_ascent);
21251 it->max_phys_descent = max (it->max_phys_descent, tem_it.max_phys_descent);
21254 it->line_number_produced_p = true;
21256 bidi_unshelve_cache (itdata, false);
21259 /* Return true if this glyph row needs a line number to be produced
21260 for it. */
21261 static bool
21262 should_produce_line_number (struct it *it)
21264 if (NILP (Vdisplay_line_numbers))
21265 return false;
21267 /* Don't display line numbers in minibuffer windows. */
21268 if (MINI_WINDOW_P (it->w))
21269 return false;
21271 #ifdef HAVE_WINDOW_SYSTEM
21272 /* Don't display line number in tooltip frames. */
21273 if (FRAME_TOOLTIP_P (XFRAME (WINDOW_FRAME (it->w))))
21274 return false;
21275 #endif
21277 /* If the character at current position has a non-nil special
21278 property, disable line numbers for this row. This is for
21279 packages such as company-mode, which need this for their tricky
21280 layout, where line numbers get in the way. */
21281 Lisp_Object val = Fget_char_property (make_number (IT_CHARPOS (*it)),
21282 Qdisplay_line_numbers_disable,
21283 it->window);
21284 /* For ZV, we need to also look in empty overlays at that point,
21285 because get-char-property always returns nil for ZV, except if
21286 the property is in 'default-text-properties'. */
21287 if (NILP (val) && IT_CHARPOS (*it) >= ZV)
21288 val = disable_line_numbers_overlay_at_eob ();
21289 return NILP (val) ? true : false;
21292 /* Return true if ROW has no glyphs except those inserted by the
21293 display engine. This is needed for indicate-empty-lines and
21294 similar features when the glyph row starts with glyphs which didn't
21295 come from buffer or string. */
21296 static bool
21297 row_text_area_empty (struct glyph_row *row)
21299 if (!row->reversed_p)
21301 for (struct glyph *g = row->glyphs[TEXT_AREA];
21302 g < row->glyphs[TEXT_AREA] + row->used[TEXT_AREA];
21303 g++)
21304 if (!NILP (g->object) || g->charpos > 0)
21305 return false;
21307 else
21309 for (struct glyph *g = row->glyphs[TEXT_AREA] + row->used[TEXT_AREA] - 1;
21310 g > row->glyphs[TEXT_AREA];
21311 g--)
21312 if (!NILP ((g - 1)->object) || (g - 1)->charpos > 0)
21313 return false;
21316 return true;
21319 /* Construct the glyph row IT->glyph_row in the desired matrix of
21320 IT->w from text at the current position of IT. See dispextern.h
21321 for an overview of struct it. Value is true if
21322 IT->glyph_row displays text, as opposed to a line displaying ZV
21323 only. CURSOR_VPOS is the window-relative vertical position of
21324 the glyph row displaying the cursor, or -1 if unknown. */
21326 static bool
21327 display_line (struct it *it, int cursor_vpos)
21329 struct glyph_row *row = it->glyph_row;
21330 Lisp_Object overlay_arrow_string;
21331 struct it wrap_it;
21332 void *wrap_data = NULL;
21333 bool may_wrap = false;
21334 int wrap_x UNINIT;
21335 int wrap_row_used = -1;
21336 int wrap_row_ascent UNINIT, wrap_row_height UNINIT;
21337 int wrap_row_phys_ascent UNINIT, wrap_row_phys_height UNINIT;
21338 int wrap_row_extra_line_spacing UNINIT;
21339 ptrdiff_t wrap_row_min_pos UNINIT, wrap_row_min_bpos UNINIT;
21340 ptrdiff_t wrap_row_max_pos UNINIT, wrap_row_max_bpos UNINIT;
21341 int cvpos;
21342 ptrdiff_t min_pos = ZV + 1, max_pos = 0;
21343 ptrdiff_t min_bpos UNINIT, max_bpos UNINIT;
21344 bool pending_handle_line_prefix = false;
21345 int header_line = window_wants_header_line (it->w);
21346 bool hscroll_this_line = (cursor_vpos >= 0
21347 && it->vpos == cursor_vpos - header_line
21348 && hscrolling_current_line_p (it->w));
21349 int first_visible_x = it->first_visible_x;
21350 int last_visible_x = it->last_visible_x;
21351 int x_incr = 0;
21353 /* We always start displaying at hpos zero even if hscrolled. */
21354 eassert (it->hpos == 0 && it->current_x == 0);
21356 if (MATRIX_ROW_VPOS (row, it->w->desired_matrix)
21357 >= it->w->desired_matrix->nrows)
21359 it->w->nrows_scale_factor++;
21360 it->f->fonts_changed = true;
21361 return false;
21364 /* Clear the result glyph row and enable it. */
21365 prepare_desired_row (it->w, row, false);
21367 row->y = it->current_y;
21368 row->start = it->start;
21369 row->continuation_lines_width = it->continuation_lines_width;
21370 row->displays_text_p = true;
21371 row->starts_in_middle_of_char_p = it->starts_in_middle_of_char_p;
21372 it->starts_in_middle_of_char_p = false;
21373 it->tab_offset = 0;
21374 it->line_number_produced_p = false;
21376 /* Arrange the overlays nicely for our purposes. Usually, we call
21377 display_line on only one line at a time, in which case this
21378 can't really hurt too much, or we call it on lines which appear
21379 one after another in the buffer, in which case all calls to
21380 recenter_overlay_lists but the first will be pretty cheap. */
21381 recenter_overlay_lists (current_buffer, IT_CHARPOS (*it));
21383 /* If we are going to display the cursor's line, account for the
21384 hscroll of that line. We subtract the window's min_hscroll,
21385 because that was already accounted for in init_iterator. */
21386 if (hscroll_this_line)
21387 x_incr =
21388 (window_hscroll_limited (it->w, it->f) - it->w->min_hscroll)
21389 * FRAME_COLUMN_WIDTH (it->f);
21391 bool line_number_needed = should_produce_line_number (it);
21393 /* Move over display elements that are not visible because we are
21394 hscrolled. This may stop at an x-position < first_visible_x
21395 if the first glyph is partially visible or if we hit a line end. */
21396 if (it->current_x < it->first_visible_x + x_incr)
21398 enum move_it_result move_result;
21400 this_line_min_pos = row->start.pos;
21401 if (hscroll_this_line)
21403 it->first_visible_x += x_incr;
21404 it->last_visible_x += x_incr;
21406 move_result = move_it_in_display_line_to (it, ZV, it->first_visible_x,
21407 MOVE_TO_POS | MOVE_TO_X);
21408 /* If we are under a large hscroll, move_it_in_display_line_to
21409 could hit the end of the line without reaching
21410 first_visible_x. Pretend that we did reach it. This is
21411 especially important on a TTY, where we will call
21412 extend_face_to_end_of_line, which needs to know how many
21413 blank glyphs to produce. */
21414 if (it->current_x < it->first_visible_x
21415 && (move_result == MOVE_NEWLINE_OR_CR
21416 || move_result == MOVE_POS_MATCH_OR_ZV))
21417 it->current_x = it->first_visible_x;
21419 /* In case move_it_in_display_line_to above "produced" the line
21420 number. */
21421 it->line_number_produced_p = false;
21423 /* Record the smallest positions seen while we moved over
21424 display elements that are not visible. This is needed by
21425 redisplay_internal for optimizing the case where the cursor
21426 stays inside the same line. The rest of this function only
21427 considers positions that are actually displayed, so
21428 RECORD_MAX_MIN_POS will not otherwise record positions that
21429 are hscrolled to the left of the left edge of the window. */
21430 min_pos = CHARPOS (this_line_min_pos);
21431 min_bpos = BYTEPOS (this_line_min_pos);
21433 /* Produce line number, if needed. */
21434 if (line_number_needed)
21435 maybe_produce_line_number (it);
21437 else if (it->area == TEXT_AREA)
21439 /* Line numbers should precede the line-prefix or wrap-prefix. */
21440 if (line_number_needed)
21441 maybe_produce_line_number (it);
21443 /* We only do this when not calling move_it_in_display_line_to
21444 above, because that function calls itself handle_line_prefix. */
21445 handle_line_prefix (it);
21447 else
21449 /* Line-prefix and wrap-prefix are always displayed in the text
21450 area. But if this is the first call to display_line after
21451 init_iterator, the iterator might have been set up to write
21452 into a marginal area, e.g. if the line begins with some
21453 display property that writes to the margins. So we need to
21454 wait with the call to handle_line_prefix until whatever
21455 writes to the margin has done its job. */
21456 pending_handle_line_prefix = true;
21459 /* Get the initial row height. This is either the height of the
21460 text hscrolled, if there is any, or zero. */
21461 row->ascent = it->max_ascent;
21462 row->height = it->max_ascent + it->max_descent;
21463 row->phys_ascent = it->max_phys_ascent;
21464 row->phys_height = it->max_phys_ascent + it->max_phys_descent;
21465 row->extra_line_spacing = it->max_extra_line_spacing;
21467 /* Utility macro to record max and min buffer positions seen until now. */
21468 #define RECORD_MAX_MIN_POS(IT) \
21469 do \
21471 bool composition_p \
21472 = !STRINGP ((IT)->string) && ((IT)->what == IT_COMPOSITION); \
21473 ptrdiff_t current_pos = \
21474 composition_p ? (IT)->cmp_it.charpos \
21475 : IT_CHARPOS (*(IT)); \
21476 ptrdiff_t current_bpos = \
21477 composition_p ? CHAR_TO_BYTE (current_pos) \
21478 : IT_BYTEPOS (*(IT)); \
21479 if (current_pos < min_pos) \
21481 min_pos = current_pos; \
21482 min_bpos = current_bpos; \
21484 if (IT_CHARPOS (*it) > max_pos) \
21486 max_pos = IT_CHARPOS (*it); \
21487 max_bpos = IT_BYTEPOS (*it); \
21490 while (false)
21492 /* Loop generating characters. The loop is left with IT on the next
21493 character to display. */
21494 while (true)
21496 int n_glyphs_before, hpos_before, x_before;
21497 int x, nglyphs;
21498 int ascent = 0, descent = 0, phys_ascent = 0, phys_descent = 0;
21500 /* Retrieve the next thing to display. Value is false if end of
21501 buffer reached. */
21502 if (!get_next_display_element (it))
21504 bool row_has_glyphs = false;
21505 /* Maybe add a space at the end of this line that is used to
21506 display the cursor there under X. Set the charpos of the
21507 first glyph of blank lines not corresponding to any text
21508 to -1. */
21509 if (IT_OVERFLOW_NEWLINE_INTO_FRINGE (it))
21510 row->exact_window_width_line_p = true;
21511 else if ((append_space_for_newline (it, true)
21512 && row->used[TEXT_AREA] == 1)
21513 || row->used[TEXT_AREA] == 0
21514 || (row_has_glyphs = row_text_area_empty (row)))
21516 row->glyphs[TEXT_AREA]->charpos = -1;
21517 /* Don't reset the displays_text_p flag if we are
21518 displaying line numbers or line-prefix. */
21519 if (!row_has_glyphs)
21520 row->displays_text_p = false;
21522 if (!NILP (BVAR (XBUFFER (it->w->contents), indicate_empty_lines))
21523 && (!MINI_WINDOW_P (it->w)))
21524 row->indicate_empty_line_p = true;
21527 it->continuation_lines_width = 0;
21528 /* Reset those iterator values set from display property
21529 values. This is for the case when the display property
21530 ends at ZV, and is not a replacing property, so pop_it is
21531 not called. */
21532 it->font_height = Qnil;
21533 it->voffset = 0;
21534 row->ends_at_zv_p = true;
21535 /* A row that displays right-to-left text must always have
21536 its last face extended all the way to the end of line,
21537 even if this row ends in ZV, because we still write to
21538 the screen left to right. We also need to extend the
21539 last face if the default face is remapped to some
21540 different face, otherwise the functions that clear
21541 portions of the screen will clear with the default face's
21542 background color. */
21543 if (row->reversed_p
21544 || lookup_basic_face (it->f, DEFAULT_FACE_ID) != DEFAULT_FACE_ID)
21545 extend_face_to_end_of_line (it);
21546 break;
21549 /* Now, get the metrics of what we want to display. This also
21550 generates glyphs in `row' (which is IT->glyph_row). */
21551 n_glyphs_before = row->used[TEXT_AREA];
21552 x = it->current_x;
21554 /* Remember the line height so far in case the next element doesn't
21555 fit on the line. */
21556 if (it->line_wrap != TRUNCATE)
21558 ascent = it->max_ascent;
21559 descent = it->max_descent;
21560 phys_ascent = it->max_phys_ascent;
21561 phys_descent = it->max_phys_descent;
21563 if (it->line_wrap == WORD_WRAP && it->area == TEXT_AREA)
21565 if (IT_DISPLAYING_WHITESPACE (it))
21566 may_wrap = true;
21567 else if (may_wrap)
21569 SAVE_IT (wrap_it, *it, wrap_data);
21570 wrap_x = x;
21571 wrap_row_used = row->used[TEXT_AREA];
21572 wrap_row_ascent = row->ascent;
21573 wrap_row_height = row->height;
21574 wrap_row_phys_ascent = row->phys_ascent;
21575 wrap_row_phys_height = row->phys_height;
21576 wrap_row_extra_line_spacing = row->extra_line_spacing;
21577 wrap_row_min_pos = min_pos;
21578 wrap_row_min_bpos = min_bpos;
21579 wrap_row_max_pos = max_pos;
21580 wrap_row_max_bpos = max_bpos;
21581 may_wrap = false;
21586 PRODUCE_GLYPHS (it);
21588 /* If this display element was in marginal areas, continue with
21589 the next one. */
21590 if (it->area != TEXT_AREA)
21592 row->ascent = max (row->ascent, it->max_ascent);
21593 row->height = max (row->height, it->max_ascent + it->max_descent);
21594 row->phys_ascent = max (row->phys_ascent, it->max_phys_ascent);
21595 row->phys_height = max (row->phys_height,
21596 it->max_phys_ascent + it->max_phys_descent);
21597 row->extra_line_spacing = max (row->extra_line_spacing,
21598 it->max_extra_line_spacing);
21599 set_iterator_to_next (it, true);
21600 /* If we didn't handle the line/wrap prefix above, and the
21601 call to set_iterator_to_next just switched to TEXT_AREA,
21602 process the prefix now. */
21603 if (it->area == TEXT_AREA && pending_handle_line_prefix)
21605 /* Line numbers should precede the line-prefix or wrap-prefix. */
21606 if (line_number_needed)
21607 maybe_produce_line_number (it);
21609 pending_handle_line_prefix = false;
21610 handle_line_prefix (it);
21612 continue;
21615 /* Does the display element fit on the line? If we truncate
21616 lines, we should draw past the right edge of the window. If
21617 we don't truncate, we want to stop so that we can display the
21618 continuation glyph before the right margin. If lines are
21619 continued, there are two possible strategies for characters
21620 resulting in more than 1 glyph (e.g. tabs): Display as many
21621 glyphs as possible in this line and leave the rest for the
21622 continuation line, or display the whole element in the next
21623 line. Original redisplay did the former, so we do it also. */
21624 nglyphs = row->used[TEXT_AREA] - n_glyphs_before;
21625 hpos_before = it->hpos;
21626 x_before = x;
21628 if (/* Not a newline. */
21629 nglyphs > 0
21630 /* Glyphs produced fit entirely in the line. */
21631 && it->current_x < it->last_visible_x)
21633 it->hpos += nglyphs;
21634 row->ascent = max (row->ascent, it->max_ascent);
21635 row->height = max (row->height, it->max_ascent + it->max_descent);
21636 row->phys_ascent = max (row->phys_ascent, it->max_phys_ascent);
21637 row->phys_height = max (row->phys_height,
21638 it->max_phys_ascent + it->max_phys_descent);
21639 row->extra_line_spacing = max (row->extra_line_spacing,
21640 it->max_extra_line_spacing);
21641 if (it->current_x - it->pixel_width < it->first_visible_x
21642 /* When line numbers are displayed, row->x should not be
21643 offset, as the first glyph after the line number can
21644 never be partially visible. */
21645 && !line_number_needed
21646 /* In R2L rows, we arrange in extend_face_to_end_of_line
21647 to add a right offset to the line, by a suitable
21648 change to the stretch glyph that is the leftmost
21649 glyph of the line. */
21650 && !row->reversed_p)
21651 row->x = x - it->first_visible_x;
21652 /* Record the maximum and minimum buffer positions seen so
21653 far in glyphs that will be displayed by this row. */
21654 if (it->bidi_p)
21655 RECORD_MAX_MIN_POS (it);
21657 else
21659 int i, new_x;
21660 struct glyph *glyph;
21662 for (i = 0; i < nglyphs; ++i, x = new_x)
21664 /* Identify the glyphs added by the last call to
21665 PRODUCE_GLYPHS. In R2L rows, they are prepended to
21666 the previous glyphs. */
21667 if (!row->reversed_p)
21668 glyph = row->glyphs[TEXT_AREA] + n_glyphs_before + i;
21669 else
21670 glyph = row->glyphs[TEXT_AREA] + nglyphs - 1 - i;
21671 new_x = x + glyph->pixel_width;
21673 if (/* Lines are continued. */
21674 it->line_wrap != TRUNCATE
21675 && (/* Glyph doesn't fit on the line. */
21676 new_x > it->last_visible_x
21677 /* Or it fits exactly on a window system frame. */
21678 || (new_x == it->last_visible_x
21679 && FRAME_WINDOW_P (it->f)
21680 && (row->reversed_p
21681 ? WINDOW_LEFT_FRINGE_WIDTH (it->w)
21682 : WINDOW_RIGHT_FRINGE_WIDTH (it->w)))))
21684 /* End of a continued line. */
21686 if (it->hpos == 0
21687 || (new_x == it->last_visible_x
21688 && FRAME_WINDOW_P (it->f)
21689 && (row->reversed_p
21690 ? WINDOW_LEFT_FRINGE_WIDTH (it->w)
21691 : WINDOW_RIGHT_FRINGE_WIDTH (it->w))))
21693 /* Current glyph is the only one on the line or
21694 fits exactly on the line. We must continue
21695 the line because we can't draw the cursor
21696 after the glyph. */
21697 row->continued_p = true;
21698 it->current_x = new_x;
21699 it->continuation_lines_width += new_x;
21700 ++it->hpos;
21701 if (i == nglyphs - 1)
21703 /* If line-wrap is on, check if a previous
21704 wrap point was found. */
21705 if (!IT_OVERFLOW_NEWLINE_INTO_FRINGE (it)
21706 && wrap_row_used > 0
21707 /* Even if there is a previous wrap
21708 point, continue the line here as
21709 usual, if (i) the previous character
21710 was a space or tab AND (ii) the
21711 current character is not. */
21712 && (!may_wrap
21713 || IT_DISPLAYING_WHITESPACE (it)))
21714 goto back_to_wrap;
21716 /* Record the maximum and minimum buffer
21717 positions seen so far in glyphs that will be
21718 displayed by this row. */
21719 if (it->bidi_p)
21720 RECORD_MAX_MIN_POS (it);
21721 set_iterator_to_next (it, true);
21722 if (IT_OVERFLOW_NEWLINE_INTO_FRINGE (it))
21724 if (!get_next_display_element (it))
21726 row->exact_window_width_line_p = true;
21727 it->continuation_lines_width = 0;
21728 it->font_height = Qnil;
21729 it->voffset = 0;
21730 row->continued_p = false;
21731 row->ends_at_zv_p = true;
21733 else if (ITERATOR_AT_END_OF_LINE_P (it))
21735 row->continued_p = false;
21736 row->exact_window_width_line_p = true;
21738 /* If line-wrap is on, check if a
21739 previous wrap point was found. */
21740 else if (wrap_row_used > 0
21741 /* Even if there is a previous wrap
21742 point, continue the line here as
21743 usual, if (i) the previous character
21744 was a space or tab AND (ii) the
21745 current character is not. */
21746 && (!may_wrap
21747 || IT_DISPLAYING_WHITESPACE (it)))
21748 goto back_to_wrap;
21752 else if (it->bidi_p)
21753 RECORD_MAX_MIN_POS (it);
21754 if (WINDOW_LEFT_MARGIN_WIDTH (it->w) > 0
21755 || WINDOW_RIGHT_MARGIN_WIDTH (it->w) > 0)
21756 extend_face_to_end_of_line (it);
21758 else if (CHAR_GLYPH_PADDING_P (*glyph)
21759 && !FRAME_WINDOW_P (it->f))
21761 /* A padding glyph that doesn't fit on this line.
21762 This means the whole character doesn't fit
21763 on the line. */
21764 if (row->reversed_p)
21765 unproduce_glyphs (it, row->used[TEXT_AREA]
21766 - n_glyphs_before);
21767 row->used[TEXT_AREA] = n_glyphs_before;
21769 /* Fill the rest of the row with continuation
21770 glyphs like in 20.x. */
21771 while (row->glyphs[TEXT_AREA] + row->used[TEXT_AREA]
21772 < row->glyphs[1 + TEXT_AREA])
21773 produce_special_glyphs (it, IT_CONTINUATION);
21775 row->continued_p = true;
21776 it->current_x = x_before;
21777 it->continuation_lines_width += x_before;
21779 /* Restore the height to what it was before the
21780 element not fitting on the line. */
21781 it->max_ascent = ascent;
21782 it->max_descent = descent;
21783 it->max_phys_ascent = phys_ascent;
21784 it->max_phys_descent = phys_descent;
21785 if (WINDOW_LEFT_MARGIN_WIDTH (it->w) > 0
21786 || WINDOW_RIGHT_MARGIN_WIDTH (it->w) > 0)
21787 extend_face_to_end_of_line (it);
21789 else if (wrap_row_used > 0)
21791 back_to_wrap:
21792 if (row->reversed_p)
21793 unproduce_glyphs (it,
21794 row->used[TEXT_AREA] - wrap_row_used);
21795 RESTORE_IT (it, &wrap_it, wrap_data);
21796 it->continuation_lines_width += wrap_x;
21797 row->used[TEXT_AREA] = wrap_row_used;
21798 row->ascent = wrap_row_ascent;
21799 row->height = wrap_row_height;
21800 row->phys_ascent = wrap_row_phys_ascent;
21801 row->phys_height = wrap_row_phys_height;
21802 row->extra_line_spacing = wrap_row_extra_line_spacing;
21803 min_pos = wrap_row_min_pos;
21804 min_bpos = wrap_row_min_bpos;
21805 max_pos = wrap_row_max_pos;
21806 max_bpos = wrap_row_max_bpos;
21807 row->continued_p = true;
21808 row->ends_at_zv_p = false;
21809 row->exact_window_width_line_p = false;
21811 /* Make sure that a non-default face is extended
21812 up to the right margin of the window. */
21813 extend_face_to_end_of_line (it);
21815 else if ((it->what == IT_CHARACTER
21816 || it->what == IT_STRETCH
21817 || it->what == IT_COMPOSITION)
21818 && it->c == '\t' && FRAME_WINDOW_P (it->f))
21820 /* A TAB that extends past the right edge of the
21821 window. This produces a single glyph on
21822 window system frames. We leave the glyph in
21823 this row and let it fill the row, but don't
21824 consume the TAB. */
21825 if ((row->reversed_p
21826 ? WINDOW_LEFT_FRINGE_WIDTH (it->w)
21827 : WINDOW_RIGHT_FRINGE_WIDTH (it->w)) == 0)
21828 produce_special_glyphs (it, IT_CONTINUATION);
21829 it->continuation_lines_width += it->last_visible_x;
21830 row->ends_in_middle_of_char_p = true;
21831 row->continued_p = true;
21832 glyph->pixel_width = it->last_visible_x - x;
21833 it->starts_in_middle_of_char_p = true;
21834 if (WINDOW_LEFT_MARGIN_WIDTH (it->w) > 0
21835 || WINDOW_RIGHT_MARGIN_WIDTH (it->w) > 0)
21836 extend_face_to_end_of_line (it);
21838 else
21840 /* Something other than a TAB that draws past
21841 the right edge of the window. Restore
21842 positions to values before the element. */
21843 if (row->reversed_p)
21844 unproduce_glyphs (it, row->used[TEXT_AREA]
21845 - (n_glyphs_before + i));
21846 row->used[TEXT_AREA] = n_glyphs_before + i;
21848 /* Display continuation glyphs. */
21849 it->current_x = x_before;
21850 it->continuation_lines_width += x;
21851 if (!FRAME_WINDOW_P (it->f)
21852 || (row->reversed_p
21853 ? WINDOW_LEFT_FRINGE_WIDTH (it->w)
21854 : WINDOW_RIGHT_FRINGE_WIDTH (it->w)) == 0)
21855 produce_special_glyphs (it, IT_CONTINUATION);
21856 row->continued_p = true;
21858 extend_face_to_end_of_line (it);
21860 if (nglyphs > 1 && i > 0)
21862 row->ends_in_middle_of_char_p = true;
21863 it->starts_in_middle_of_char_p = true;
21866 /* Restore the height to what it was before the
21867 element not fitting on the line. */
21868 it->max_ascent = ascent;
21869 it->max_descent = descent;
21870 it->max_phys_ascent = phys_ascent;
21871 it->max_phys_descent = phys_descent;
21874 break;
21876 else if (new_x > it->first_visible_x)
21878 /* Increment number of glyphs actually displayed. */
21879 ++it->hpos;
21881 /* Record the maximum and minimum buffer positions
21882 seen so far in glyphs that will be displayed by
21883 this row. */
21884 if (it->bidi_p)
21885 RECORD_MAX_MIN_POS (it);
21887 if (x < it->first_visible_x && !row->reversed_p
21888 && !line_number_needed)
21889 /* Glyph is partially visible, i.e. row starts at
21890 negative X position. Don't do that in R2L
21891 rows, where we arrange to add a right offset to
21892 the line in extend_face_to_end_of_line, by a
21893 suitable change to the stretch glyph that is
21894 the leftmost glyph of the line. */
21895 row->x = x - it->first_visible_x;
21896 /* When the last glyph of an R2L row only fits
21897 partially on the line, we need to set row->x to a
21898 negative offset, so that the leftmost glyph is
21899 the one that is partially visible. But if we are
21900 going to produce the truncation glyph, this will
21901 be taken care of in produce_special_glyphs. */
21902 if (row->reversed_p
21903 && new_x > it->last_visible_x
21904 && !line_number_needed
21905 && !(it->line_wrap == TRUNCATE
21906 && WINDOW_LEFT_FRINGE_WIDTH (it->w) == 0))
21908 eassert (FRAME_WINDOW_P (it->f));
21909 row->x = it->last_visible_x - new_x;
21912 else
21914 /* Glyph is completely off the left margin of the
21915 window. This should not happen because of the
21916 move_it_in_display_line at the start of this
21917 function, unless the text display area of the
21918 window is empty. */
21919 eassert (it->first_visible_x <= it->last_visible_x);
21922 /* Even if this display element produced no glyphs at all,
21923 we want to record its position. */
21924 if (it->bidi_p && nglyphs == 0)
21925 RECORD_MAX_MIN_POS (it);
21927 row->ascent = max (row->ascent, it->max_ascent);
21928 row->height = max (row->height, it->max_ascent + it->max_descent);
21929 row->phys_ascent = max (row->phys_ascent, it->max_phys_ascent);
21930 row->phys_height = max (row->phys_height,
21931 it->max_phys_ascent + it->max_phys_descent);
21932 row->extra_line_spacing = max (row->extra_line_spacing,
21933 it->max_extra_line_spacing);
21935 /* End of this display line if row is continued. */
21936 if (row->continued_p || row->ends_at_zv_p)
21937 break;
21940 at_end_of_line:
21941 /* Is this a line end? If yes, we're also done, after making
21942 sure that a non-default face is extended up to the right
21943 margin of the window. */
21944 if (ITERATOR_AT_END_OF_LINE_P (it))
21946 int used_before = row->used[TEXT_AREA];
21948 row->ends_in_newline_from_string_p = STRINGP (it->object);
21950 /* Add a space at the end of the line that is used to
21951 display the cursor there. */
21952 if (!IT_OVERFLOW_NEWLINE_INTO_FRINGE (it))
21953 append_space_for_newline (it, false);
21955 /* Extend the face to the end of the line. */
21956 extend_face_to_end_of_line (it);
21958 /* Make sure we have the position. */
21959 if (used_before == 0)
21960 row->glyphs[TEXT_AREA]->charpos = CHARPOS (it->position);
21962 /* Record the position of the newline, for use in
21963 find_row_edges. */
21964 it->eol_pos = it->current.pos;
21966 /* Consume the line end. This skips over invisible lines. */
21967 set_iterator_to_next (it, true);
21968 it->continuation_lines_width = 0;
21969 break;
21972 /* Detect overly-wide wrap-prefixes made of (space ...) display
21973 properties. When such a wrap prefix reaches past the right
21974 margin of the window, we need to avoid the call to
21975 set_iterator_to_next below, so that it->line_wrap is left at
21976 its TRUNCATE value wisely set by handle_line_prefix.
21977 Otherwise, set_iterator_to_next will pop the iterator stack,
21978 restore it->line_wrap, and redisplay might infloop. */
21979 bool overwide_wrap_prefix =
21980 CONSP (it->object) && EQ (XCAR (it->object), Qspace)
21981 && it->sp > 0 && it->method == GET_FROM_STRETCH
21982 && it->current_x >= it->last_visible_x
21983 && it->continuation_lines_width > 0
21984 && it->line_wrap == TRUNCATE && it->stack[0].line_wrap != TRUNCATE;
21986 /* Proceed with next display element. Note that this skips
21987 over lines invisible because of selective display. */
21988 if (!overwide_wrap_prefix)
21989 set_iterator_to_next (it, true);
21991 /* If we truncate lines, we are done when the last displayed
21992 glyphs reach past the right margin of the window. */
21993 if (it->line_wrap == TRUNCATE
21994 && ((FRAME_WINDOW_P (it->f)
21995 /* Images are preprocessed in produce_image_glyph such
21996 that they are cropped at the right edge of the
21997 window, so an image glyph will always end exactly at
21998 last_visible_x, even if there's no right fringe. */
21999 && ((row->reversed_p
22000 ? WINDOW_LEFT_FRINGE_WIDTH (it->w)
22001 : WINDOW_RIGHT_FRINGE_WIDTH (it->w))
22002 || it->what == IT_IMAGE))
22003 ? (it->current_x >= it->last_visible_x)
22004 : (it->current_x > it->last_visible_x)))
22006 /* Maybe add truncation glyphs. */
22007 if (!FRAME_WINDOW_P (it->f)
22008 || (row->reversed_p
22009 ? WINDOW_LEFT_FRINGE_WIDTH (it->w)
22010 : WINDOW_RIGHT_FRINGE_WIDTH (it->w)) == 0)
22012 int i, n;
22014 if (!row->reversed_p)
22016 for (i = row->used[TEXT_AREA] - 1; i > 0; --i)
22017 if (!CHAR_GLYPH_PADDING_P (row->glyphs[TEXT_AREA][i]))
22018 break;
22020 else
22022 for (i = 0; i < row->used[TEXT_AREA]; i++)
22023 if (!CHAR_GLYPH_PADDING_P (row->glyphs[TEXT_AREA][i]))
22024 break;
22025 /* Remove any padding glyphs at the front of ROW, to
22026 make room for the truncation glyphs we will be
22027 adding below. The loop below always inserts at
22028 least one truncation glyph, so also remove the
22029 last glyph added to ROW. */
22030 unproduce_glyphs (it, i + 1);
22031 /* Adjust i for the loop below. */
22032 i = row->used[TEXT_AREA] - (i + 1);
22035 /* produce_special_glyphs overwrites the last glyph, so
22036 we don't want that if we want to keep that last
22037 glyph, which means it's an image. */
22038 if (it->current_x > it->last_visible_x)
22040 it->current_x = x_before;
22041 if (!FRAME_WINDOW_P (it->f))
22043 for (n = row->used[TEXT_AREA]; i < n; ++i)
22045 row->used[TEXT_AREA] = i;
22046 produce_special_glyphs (it, IT_TRUNCATION);
22049 else
22051 row->used[TEXT_AREA] = i;
22052 produce_special_glyphs (it, IT_TRUNCATION);
22054 it->hpos = hpos_before;
22057 else if (IT_OVERFLOW_NEWLINE_INTO_FRINGE (it))
22059 /* Don't truncate if we can overflow newline into fringe. */
22060 if (!get_next_display_element (it))
22062 it->continuation_lines_width = 0;
22063 it->font_height = Qnil;
22064 it->voffset = 0;
22065 row->ends_at_zv_p = true;
22066 row->exact_window_width_line_p = true;
22067 break;
22069 if (ITERATOR_AT_END_OF_LINE_P (it))
22071 row->exact_window_width_line_p = true;
22072 goto at_end_of_line;
22074 it->current_x = x_before;
22075 it->hpos = hpos_before;
22078 row->truncated_on_right_p = true;
22079 it->continuation_lines_width = 0;
22080 reseat_at_next_visible_line_start (it, false);
22081 /* We insist below that IT's position be at ZV because in
22082 bidi-reordered lines the character at visible line start
22083 might not be the character that follows the newline in
22084 the logical order. */
22085 if (IT_BYTEPOS (*it) > BEG_BYTE)
22086 row->ends_at_zv_p =
22087 IT_BYTEPOS (*it) >= ZV_BYTE && FETCH_BYTE (ZV_BYTE - 1) != '\n';
22088 else
22089 row->ends_at_zv_p = false;
22090 break;
22094 if (wrap_data)
22095 bidi_unshelve_cache (wrap_data, true);
22097 /* If line is not empty and hscrolled, maybe insert truncation glyphs
22098 at the left window margin. */
22099 if (it->first_visible_x
22100 && IT_CHARPOS (*it) != CHARPOS (row->start.pos))
22102 if (!FRAME_WINDOW_P (it->f)
22103 || (((row->reversed_p
22104 ? WINDOW_RIGHT_FRINGE_WIDTH (it->w)
22105 : WINDOW_LEFT_FRINGE_WIDTH (it->w)) == 0)
22106 /* Don't let insert_left_trunc_glyphs overwrite the
22107 first glyph of the row if it is an image. */
22108 && row->glyphs[TEXT_AREA]->type != IMAGE_GLYPH))
22109 insert_left_trunc_glyphs (it);
22110 row->truncated_on_left_p = true;
22113 /* Remember the position at which this line ends.
22115 BIDI Note: any code that needs MATRIX_ROW_START/END_CHARPOS
22116 cannot be before the call to find_row_edges below, since that is
22117 where these positions are determined. */
22118 row->end = it->current;
22119 if (!it->bidi_p)
22121 row->minpos = row->start.pos;
22122 row->maxpos = row->end.pos;
22124 else
22126 /* ROW->minpos and ROW->maxpos must be the smallest and
22127 `1 + the largest' buffer positions in ROW. But if ROW was
22128 bidi-reordered, these two positions can be anywhere in the
22129 row, so we must determine them now. */
22130 find_row_edges (it, row, min_pos, min_bpos, max_pos, max_bpos);
22133 /* If the start of this line is the overlay arrow-position, then
22134 mark this glyph row as the one containing the overlay arrow.
22135 This is clearly a mess with variable size fonts. It would be
22136 better to let it be displayed like cursors under X. */
22137 if ((MATRIX_ROW_DISPLAYS_TEXT_P (row) || !overlay_arrow_seen)
22138 && (overlay_arrow_string = overlay_arrow_at_row (it, row),
22139 !NILP (overlay_arrow_string)))
22141 /* Overlay arrow in window redisplay is a fringe bitmap. */
22142 if (STRINGP (overlay_arrow_string))
22144 struct glyph_row *arrow_row
22145 = get_overlay_arrow_glyph_row (it->w, overlay_arrow_string);
22146 struct glyph *glyph = arrow_row->glyphs[TEXT_AREA];
22147 struct glyph *arrow_end = glyph + arrow_row->used[TEXT_AREA];
22148 struct glyph *p = row->glyphs[TEXT_AREA];
22149 struct glyph *p2, *end;
22151 /* Copy the arrow glyphs. */
22152 while (glyph < arrow_end)
22153 *p++ = *glyph++;
22155 /* Throw away padding glyphs. */
22156 p2 = p;
22157 end = row->glyphs[TEXT_AREA] + row->used[TEXT_AREA];
22158 while (p2 < end && CHAR_GLYPH_PADDING_P (*p2))
22159 ++p2;
22160 if (p2 > p)
22162 while (p2 < end)
22163 *p++ = *p2++;
22164 row->used[TEXT_AREA] = p2 - row->glyphs[TEXT_AREA];
22167 else
22169 eassert (INTEGERP (overlay_arrow_string));
22170 row->overlay_arrow_bitmap = XINT (overlay_arrow_string);
22172 overlay_arrow_seen = true;
22175 /* Highlight trailing whitespace. */
22176 if (!NILP (Vshow_trailing_whitespace))
22177 highlight_trailing_whitespace (it->f, it->glyph_row);
22179 /* Compute pixel dimensions of this line. */
22180 compute_line_metrics (it);
22182 /* Implementation note: No changes in the glyphs of ROW or in their
22183 faces can be done past this point, because compute_line_metrics
22184 computes ROW's hash value and stores it within the glyph_row
22185 structure. */
22187 /* Record whether this row ends inside an ellipsis. */
22188 row->ends_in_ellipsis_p
22189 = (it->method == GET_FROM_DISPLAY_VECTOR
22190 && it->ellipsis_p);
22192 /* Save fringe bitmaps in this row. */
22193 row->left_user_fringe_bitmap = it->left_user_fringe_bitmap;
22194 row->left_user_fringe_face_id = it->left_user_fringe_face_id;
22195 row->right_user_fringe_bitmap = it->right_user_fringe_bitmap;
22196 row->right_user_fringe_face_id = it->right_user_fringe_face_id;
22198 it->left_user_fringe_bitmap = 0;
22199 it->left_user_fringe_face_id = 0;
22200 it->right_user_fringe_bitmap = 0;
22201 it->right_user_fringe_face_id = 0;
22203 /* Maybe set the cursor. */
22204 cvpos = it->w->cursor.vpos;
22205 if ((cvpos < 0
22206 /* In bidi-reordered rows, keep checking for proper cursor
22207 position even if one has been found already, because buffer
22208 positions in such rows change non-linearly with ROW->VPOS,
22209 when a line is continued. One exception: when we are at ZV,
22210 display cursor on the first suitable glyph row, since all
22211 the empty rows after that also have their position set to ZV. */
22212 /* FIXME: Revisit this when glyph ``spilling'' in continuation
22213 lines' rows is implemented for bidi-reordered rows. */
22214 || (it->bidi_p
22215 && !MATRIX_ROW (it->w->desired_matrix, cvpos)->ends_at_zv_p))
22216 && PT >= MATRIX_ROW_START_CHARPOS (row)
22217 && PT <= MATRIX_ROW_END_CHARPOS (row)
22218 && cursor_row_p (row))
22219 set_cursor_from_row (it->w, row, it->w->desired_matrix, 0, 0, 0, 0);
22221 /* Prepare for the next line. This line starts horizontally at (X
22222 HPOS) = (0 0). Vertical positions are incremented. As a
22223 convenience for the caller, IT->glyph_row is set to the next
22224 row to be used. */
22225 it->current_x = it->hpos = 0;
22226 it->current_y += row->height;
22227 /* Restore the first and last visible X if we adjusted them for
22228 current-line hscrolling. */
22229 if (hscroll_this_line)
22231 it->first_visible_x = first_visible_x;
22232 it->last_visible_x = last_visible_x;
22234 SET_TEXT_POS (it->eol_pos, 0, 0);
22235 ++it->vpos;
22236 ++it->glyph_row;
22237 /* The next row should by default use the same value of the
22238 reversed_p flag as this one. set_iterator_to_next decides when
22239 it's a new paragraph, and PRODUCE_GLYPHS recomputes the value of
22240 the flag accordingly. */
22241 if (it->glyph_row < MATRIX_BOTTOM_TEXT_ROW (it->w->desired_matrix, it->w))
22242 it->glyph_row->reversed_p = row->reversed_p;
22243 it->start = row->end;
22244 return MATRIX_ROW_DISPLAYS_TEXT_P (row);
22246 #undef RECORD_MAX_MIN_POS
22249 DEFUN ("current-bidi-paragraph-direction", Fcurrent_bidi_paragraph_direction,
22250 Scurrent_bidi_paragraph_direction, 0, 1, 0,
22251 doc: /* Return paragraph direction at point in BUFFER.
22252 Value is either `left-to-right' or `right-to-left'.
22253 If BUFFER is omitted or nil, it defaults to the current buffer.
22255 Paragraph direction determines how the text in the paragraph is displayed.
22256 In left-to-right paragraphs, text begins at the left margin of the window
22257 and the reading direction is generally left to right. In right-to-left
22258 paragraphs, text begins at the right margin and is read from right to left.
22260 See also `bidi-paragraph-direction'. */)
22261 (Lisp_Object buffer)
22263 struct buffer *buf = current_buffer;
22264 struct buffer *old = buf;
22266 if (! NILP (buffer))
22268 CHECK_BUFFER (buffer);
22269 buf = XBUFFER (buffer);
22272 if (NILP (BVAR (buf, bidi_display_reordering))
22273 || NILP (BVAR (buf, enable_multibyte_characters))
22274 /* When we are loading loadup.el, the character property tables
22275 needed for bidi iteration are not yet available. */
22276 || redisplay__inhibit_bidi)
22277 return Qleft_to_right;
22278 else if (!NILP (BVAR (buf, bidi_paragraph_direction)))
22279 return BVAR (buf, bidi_paragraph_direction);
22280 else
22282 /* Determine the direction from buffer text. We could try to
22283 use current_matrix if it is up to date, but this seems fast
22284 enough as it is. */
22285 struct bidi_it itb;
22286 ptrdiff_t pos = BUF_PT (buf);
22287 ptrdiff_t bytepos = BUF_PT_BYTE (buf);
22288 int c;
22289 void *itb_data = bidi_shelve_cache ();
22291 set_buffer_temp (buf);
22292 /* bidi_paragraph_init finds the base direction of the paragraph
22293 by searching forward from paragraph start. We need the base
22294 direction of the current or _previous_ paragraph, so we need
22295 to make sure we are within that paragraph. To that end, find
22296 the previous non-empty line. */
22297 if (pos >= ZV && pos > BEGV)
22298 DEC_BOTH (pos, bytepos);
22299 AUTO_STRING (trailing_white_space, "[\f\t ]*\n");
22300 if (fast_looking_at (trailing_white_space,
22301 pos, bytepos, ZV, ZV_BYTE, Qnil) > 0)
22303 while ((c = FETCH_BYTE (bytepos)) == '\n'
22304 || c == ' ' || c == '\t' || c == '\f')
22306 if (bytepos <= BEGV_BYTE)
22307 break;
22308 bytepos--;
22309 pos--;
22311 while (!CHAR_HEAD_P (FETCH_BYTE (bytepos)))
22312 bytepos--;
22314 bidi_init_it (pos, bytepos, FRAME_WINDOW_P (SELECTED_FRAME ()), &itb);
22315 itb.paragraph_dir = NEUTRAL_DIR;
22316 itb.string.s = NULL;
22317 itb.string.lstring = Qnil;
22318 itb.string.bufpos = 0;
22319 itb.string.from_disp_str = false;
22320 itb.string.unibyte = false;
22321 /* We have no window to use here for ignoring window-specific
22322 overlays. Using NULL for window pointer will cause
22323 compute_display_string_pos to use the current buffer. */
22324 itb.w = NULL;
22325 bidi_paragraph_init (NEUTRAL_DIR, &itb, true);
22326 bidi_unshelve_cache (itb_data, false);
22327 set_buffer_temp (old);
22328 switch (itb.paragraph_dir)
22330 case L2R:
22331 return Qleft_to_right;
22332 break;
22333 case R2L:
22334 return Qright_to_left;
22335 break;
22336 default:
22337 emacs_abort ();
22342 DEFUN ("bidi-find-overridden-directionality",
22343 Fbidi_find_overridden_directionality,
22344 Sbidi_find_overridden_directionality, 2, 3, 0,
22345 doc: /* Return position between FROM and TO where directionality was overridden.
22347 This function returns the first character position in the specified
22348 region of OBJECT where there is a character whose `bidi-class' property
22349 is `L', but which was forced to display as `R' by a directional
22350 override, and likewise with characters whose `bidi-class' is `R'
22351 or `AL' that were forced to display as `L'.
22353 If no such character is found, the function returns nil.
22355 OBJECT is a Lisp string or buffer to search for overridden
22356 directionality, and defaults to the current buffer if nil or omitted.
22357 OBJECT can also be a window, in which case the function will search
22358 the buffer displayed in that window. Passing the window instead of
22359 a buffer is preferable when the buffer is displayed in some window,
22360 because this function will then be able to correctly account for
22361 window-specific overlays, which can affect the results.
22363 Strong directional characters `L', `R', and `AL' can have their
22364 intrinsic directionality overridden by directional override
22365 control characters RLO (u+202e) and LRO (u+202d). See the
22366 function `get-char-code-property' for a way to inquire about
22367 the `bidi-class' property of a character. */)
22368 (Lisp_Object from, Lisp_Object to, Lisp_Object object)
22370 struct buffer *buf = current_buffer;
22371 struct buffer *old = buf;
22372 struct window *w = NULL;
22373 bool frame_window_p = FRAME_WINDOW_P (SELECTED_FRAME ());
22374 struct bidi_it itb;
22375 ptrdiff_t from_pos, to_pos, from_bpos;
22376 void *itb_data;
22378 if (!NILP (object))
22380 if (BUFFERP (object))
22381 buf = XBUFFER (object);
22382 else if (WINDOWP (object))
22384 w = decode_live_window (object);
22385 buf = XBUFFER (w->contents);
22386 frame_window_p = FRAME_WINDOW_P (XFRAME (w->frame));
22388 else
22389 CHECK_STRING (object);
22392 if (STRINGP (object))
22394 /* Characters in unibyte strings are always treated by bidi.c as
22395 strong LTR. */
22396 if (!STRING_MULTIBYTE (object)
22397 /* When we are loading loadup.el, the character property
22398 tables needed for bidi iteration are not yet
22399 available. */
22400 || redisplay__inhibit_bidi)
22401 return Qnil;
22403 validate_subarray (object, from, to, SCHARS (object), &from_pos, &to_pos);
22404 if (from_pos >= SCHARS (object))
22405 return Qnil;
22407 /* Set up the bidi iterator. */
22408 itb_data = bidi_shelve_cache ();
22409 itb.paragraph_dir = NEUTRAL_DIR;
22410 itb.string.lstring = object;
22411 itb.string.s = NULL;
22412 itb.string.schars = SCHARS (object);
22413 itb.string.bufpos = 0;
22414 itb.string.from_disp_str = false;
22415 itb.string.unibyte = false;
22416 itb.w = w;
22417 bidi_init_it (0, 0, frame_window_p, &itb);
22419 else
22421 /* Nothing this fancy can happen in unibyte buffers, or in a
22422 buffer that disabled reordering, or if FROM is at EOB. */
22423 if (NILP (BVAR (buf, bidi_display_reordering))
22424 || NILP (BVAR (buf, enable_multibyte_characters))
22425 /* When we are loading loadup.el, the character property
22426 tables needed for bidi iteration are not yet
22427 available. */
22428 || redisplay__inhibit_bidi)
22429 return Qnil;
22431 set_buffer_temp (buf);
22432 validate_region (&from, &to);
22433 from_pos = XINT (from);
22434 to_pos = XINT (to);
22435 if (from_pos >= ZV)
22436 return Qnil;
22438 /* Set up the bidi iterator. */
22439 itb_data = bidi_shelve_cache ();
22440 from_bpos = CHAR_TO_BYTE (from_pos);
22441 if (from_pos == BEGV)
22443 itb.charpos = BEGV;
22444 itb.bytepos = BEGV_BYTE;
22446 else if (FETCH_CHAR (from_bpos - 1) == '\n')
22448 itb.charpos = from_pos;
22449 itb.bytepos = from_bpos;
22451 else
22452 itb.charpos = find_newline_no_quit (from_pos, CHAR_TO_BYTE (from_pos),
22453 -1, &itb.bytepos);
22454 itb.paragraph_dir = NEUTRAL_DIR;
22455 itb.string.s = NULL;
22456 itb.string.lstring = Qnil;
22457 itb.string.bufpos = 0;
22458 itb.string.from_disp_str = false;
22459 itb.string.unibyte = false;
22460 itb.w = w;
22461 bidi_init_it (itb.charpos, itb.bytepos, frame_window_p, &itb);
22464 ptrdiff_t found;
22465 do {
22466 /* For the purposes of this function, the actual base direction of
22467 the paragraph doesn't matter, so just set it to L2R. */
22468 bidi_paragraph_init (L2R, &itb, false);
22469 while ((found = bidi_find_first_overridden (&itb)) < from_pos)
22471 } while (found == ZV && itb.ch == '\n' && itb.charpos < to_pos);
22473 bidi_unshelve_cache (itb_data, false);
22474 set_buffer_temp (old);
22476 return (from_pos <= found && found < to_pos) ? make_number (found) : Qnil;
22479 DEFUN ("move-point-visually", Fmove_point_visually,
22480 Smove_point_visually, 1, 1, 0,
22481 doc: /* Move point in the visual order in the specified DIRECTION.
22482 DIRECTION can be 1, meaning move to the right, or -1, which moves to the
22483 left.
22485 Value is the new character position of point. */)
22486 (Lisp_Object direction)
22488 struct window *w = XWINDOW (selected_window);
22489 struct buffer *b = XBUFFER (w->contents);
22490 struct glyph_row *row;
22491 int dir;
22492 Lisp_Object paragraph_dir;
22494 #define ROW_GLYPH_NEWLINE_P(ROW,GLYPH) \
22495 (!(ROW)->continued_p \
22496 && NILP ((GLYPH)->object) \
22497 && (GLYPH)->type == CHAR_GLYPH \
22498 && (GLYPH)->u.ch == ' ' \
22499 && (GLYPH)->charpos >= 0 \
22500 && !(GLYPH)->avoid_cursor_p)
22502 CHECK_NUMBER (direction);
22503 dir = XINT (direction);
22504 if (dir > 0)
22505 dir = 1;
22506 else
22507 dir = -1;
22509 /* If current matrix is up-to-date, we can use the information
22510 recorded in the glyphs, at least as long as the goal is on the
22511 screen. */
22512 if (w->window_end_valid
22513 && !windows_or_buffers_changed
22514 && b
22515 && !b->clip_changed
22516 && !b->prevent_redisplay_optimizations_p
22517 && !window_outdated (w)
22518 /* We rely below on the cursor coordinates to be up to date, but
22519 we cannot trust them if some command moved point since the
22520 last complete redisplay. */
22521 && w->last_point == BUF_PT (b)
22522 && w->cursor.vpos >= 0
22523 && w->cursor.vpos < w->current_matrix->nrows
22524 && (row = MATRIX_ROW (w->current_matrix, w->cursor.vpos))->enabled_p)
22526 struct glyph *g = row->glyphs[TEXT_AREA];
22527 struct glyph *e = dir > 0 ? g + row->used[TEXT_AREA] : g - 1;
22528 struct glyph *gpt = g + w->cursor.hpos;
22530 for (g = gpt + dir; (dir > 0 ? g < e : g > e); g += dir)
22532 if (BUFFERP (g->object) && g->charpos != PT)
22534 SET_PT (g->charpos);
22535 w->cursor.vpos = -1;
22536 return make_number (PT);
22538 else if (!NILP (g->object) && !EQ (g->object, gpt->object))
22540 ptrdiff_t new_pos;
22542 if (BUFFERP (gpt->object))
22544 new_pos = PT;
22545 if ((gpt->resolved_level - row->reversed_p) % 2 == 0)
22546 new_pos += (row->reversed_p ? -dir : dir);
22547 else
22548 new_pos -= (row->reversed_p ? -dir : dir);
22549 new_pos = clip_to_bounds (BEGV, new_pos, ZV);
22550 /* If we didn't move, we've hit BEGV or ZV, so we
22551 need to signal a suitable error. */
22552 if (new_pos == PT)
22553 break;
22555 else if (BUFFERP (g->object))
22556 new_pos = g->charpos;
22557 else
22558 break;
22559 SET_PT (new_pos);
22560 w->cursor.vpos = -1;
22561 return make_number (PT);
22563 else if (ROW_GLYPH_NEWLINE_P (row, g))
22565 /* Glyphs inserted at the end of a non-empty line for
22566 positioning the cursor have zero charpos, so we must
22567 deduce the value of point by other means. */
22568 if (g->charpos > 0)
22569 SET_PT (g->charpos);
22570 else if (row->ends_at_zv_p && PT != ZV)
22571 SET_PT (ZV);
22572 else if (PT != MATRIX_ROW_END_CHARPOS (row) - 1)
22573 SET_PT (MATRIX_ROW_END_CHARPOS (row) - 1);
22574 else
22575 break;
22576 w->cursor.vpos = -1;
22577 return make_number (PT);
22580 if (g == e || NILP (g->object))
22582 if (row->truncated_on_left_p || row->truncated_on_right_p)
22583 goto simulate_display;
22584 if (!row->reversed_p)
22585 row += dir;
22586 else
22587 row -= dir;
22588 if (!(MATRIX_FIRST_TEXT_ROW (w->current_matrix) <= row
22589 && row < MATRIX_BOTTOM_TEXT_ROW (w->current_matrix, w)))
22590 goto simulate_display;
22592 if (dir > 0)
22594 if (row->reversed_p && !row->continued_p)
22596 SET_PT (MATRIX_ROW_END_CHARPOS (row) - 1);
22597 w->cursor.vpos = -1;
22598 return make_number (PT);
22600 g = row->glyphs[TEXT_AREA];
22601 e = g + row->used[TEXT_AREA];
22602 for ( ; g < e; g++)
22604 if (BUFFERP (g->object)
22605 /* Empty lines have only one glyph, which stands
22606 for the newline, and whose charpos is the
22607 buffer position of the newline. */
22608 || ROW_GLYPH_NEWLINE_P (row, g)
22609 /* When the buffer ends in a newline, the line at
22610 EOB also has one glyph, but its charpos is -1. */
22611 || (row->ends_at_zv_p
22612 && !row->reversed_p
22613 && NILP (g->object)
22614 && g->type == CHAR_GLYPH
22615 && g->u.ch == ' '))
22617 if (g->charpos > 0)
22618 SET_PT (g->charpos);
22619 else if (!row->reversed_p
22620 && row->ends_at_zv_p
22621 && PT != ZV)
22622 SET_PT (ZV);
22623 else
22624 continue;
22625 w->cursor.vpos = -1;
22626 return make_number (PT);
22630 else
22632 if (!row->reversed_p && !row->continued_p)
22634 SET_PT (MATRIX_ROW_END_CHARPOS (row) - 1);
22635 w->cursor.vpos = -1;
22636 return make_number (PT);
22638 e = row->glyphs[TEXT_AREA];
22639 g = e + row->used[TEXT_AREA] - 1;
22640 for ( ; g >= e; g--)
22642 if (BUFFERP (g->object)
22643 || (ROW_GLYPH_NEWLINE_P (row, g)
22644 && g->charpos > 0)
22645 /* Empty R2L lines on GUI frames have the buffer
22646 position of the newline stored in the stretch
22647 glyph. */
22648 || g->type == STRETCH_GLYPH
22649 || (row->ends_at_zv_p
22650 && row->reversed_p
22651 && NILP (g->object)
22652 && g->type == CHAR_GLYPH
22653 && g->u.ch == ' '))
22655 if (g->charpos > 0)
22656 SET_PT (g->charpos);
22657 else if (row->reversed_p
22658 && row->ends_at_zv_p
22659 && PT != ZV)
22660 SET_PT (ZV);
22661 else
22662 continue;
22663 w->cursor.vpos = -1;
22664 return make_number (PT);
22671 simulate_display:
22673 /* If we wind up here, we failed to move by using the glyphs, so we
22674 need to simulate display instead. */
22676 if (b)
22677 paragraph_dir = Fcurrent_bidi_paragraph_direction (w->contents);
22678 else
22679 paragraph_dir = Qleft_to_right;
22680 if (EQ (paragraph_dir, Qright_to_left))
22681 dir = -dir;
22682 if (PT <= BEGV && dir < 0)
22683 xsignal0 (Qbeginning_of_buffer);
22684 else if (PT >= ZV && dir > 0)
22685 xsignal0 (Qend_of_buffer);
22686 else
22688 struct text_pos pt;
22689 struct it it;
22690 int pt_x, target_x, pixel_width, pt_vpos;
22691 bool at_eol_p;
22692 bool overshoot_expected = false;
22693 bool target_is_eol_p = false;
22695 /* Setup the arena. */
22696 SET_TEXT_POS (pt, PT, PT_BYTE);
22697 start_display (&it, w, pt);
22698 /* When lines are truncated, we could be called with point
22699 outside of the windows edges, in which case move_it_*
22700 functions either prematurely stop at window's edge or jump to
22701 the next screen line, whereas we rely below on our ability to
22702 reach point, in order to start from its X coordinate. So we
22703 need to disregard the window's horizontal extent in that case. */
22704 if (it.line_wrap == TRUNCATE)
22705 it.last_visible_x = DISP_INFINITY;
22707 if (it.cmp_it.id < 0
22708 && it.method == GET_FROM_STRING
22709 && it.area == TEXT_AREA
22710 && it.string_from_display_prop_p
22711 && (it.sp > 0 && it.stack[it.sp - 1].method == GET_FROM_BUFFER))
22712 overshoot_expected = true;
22714 /* Find the X coordinate of point. We start from the beginning
22715 of this or previous line to make sure we are before point in
22716 the logical order (since the move_it_* functions can only
22717 move forward). */
22718 reseat:
22719 reseat_at_previous_visible_line_start (&it);
22720 it.current_x = it.hpos = it.current_y = it.vpos = 0;
22721 if (IT_CHARPOS (it) != PT)
22723 move_it_to (&it, overshoot_expected ? PT - 1 : PT,
22724 -1, -1, -1, MOVE_TO_POS);
22725 /* If we missed point because the character there is
22726 displayed out of a display vector that has more than one
22727 glyph, retry expecting overshoot. */
22728 if (it.method == GET_FROM_DISPLAY_VECTOR
22729 && it.current.dpvec_index > 0
22730 && !overshoot_expected)
22732 overshoot_expected = true;
22733 goto reseat;
22735 else if (IT_CHARPOS (it) != PT && !overshoot_expected)
22736 move_it_in_display_line (&it, PT, -1, MOVE_TO_POS);
22738 pt_x = it.current_x;
22739 pt_vpos = it.vpos;
22740 if (dir > 0 || overshoot_expected)
22742 struct glyph_row *row = it.glyph_row;
22744 /* When point is at beginning of line, we don't have
22745 information about the glyph there loaded into struct
22746 it. Calling get_next_display_element fixes that. */
22747 if (pt_x == 0)
22748 get_next_display_element (&it);
22749 at_eol_p = ITERATOR_AT_END_OF_LINE_P (&it);
22750 it.glyph_row = NULL;
22751 PRODUCE_GLYPHS (&it); /* compute it.pixel_width */
22752 it.glyph_row = row;
22753 /* PRODUCE_GLYPHS advances it.current_x, so we must restore
22754 it, lest it will become out of sync with it's buffer
22755 position. */
22756 it.current_x = pt_x;
22758 else
22759 at_eol_p = ITERATOR_AT_END_OF_LINE_P (&it);
22760 pixel_width = it.pixel_width;
22761 if (overshoot_expected && at_eol_p)
22762 pixel_width = 0;
22763 else if (pixel_width <= 0)
22764 pixel_width = 1;
22766 /* If there's a display string (or something similar) at point,
22767 we are actually at the glyph to the left of point, so we need
22768 to correct the X coordinate. */
22769 if (overshoot_expected)
22771 if (it.bidi_p)
22772 pt_x += pixel_width * it.bidi_it.scan_dir;
22773 else
22774 pt_x += pixel_width;
22777 /* Compute target X coordinate, either to the left or to the
22778 right of point. On TTY frames, all characters have the same
22779 pixel width of 1, so we can use that. On GUI frames we don't
22780 have an easy way of getting at the pixel width of the
22781 character to the left of point, so we use a different method
22782 of getting to that place. */
22783 if (dir > 0)
22784 target_x = pt_x + pixel_width;
22785 else
22786 target_x = pt_x - (!FRAME_WINDOW_P (it.f)) * pixel_width;
22788 /* Target X coordinate could be one line above or below the line
22789 of point, in which case we need to adjust the target X
22790 coordinate. Also, if moving to the left, we need to begin at
22791 the left edge of the point's screen line. */
22792 if (dir < 0)
22794 if (pt_x > 0)
22796 start_display (&it, w, pt);
22797 if (it.line_wrap == TRUNCATE)
22798 it.last_visible_x = DISP_INFINITY;
22799 reseat_at_previous_visible_line_start (&it);
22800 it.current_x = it.current_y = it.hpos = 0;
22801 if (pt_vpos != 0)
22802 move_it_by_lines (&it, pt_vpos);
22804 else
22806 move_it_by_lines (&it, -1);
22807 target_x = it.last_visible_x - !FRAME_WINDOW_P (it.f);
22808 target_is_eol_p = true;
22809 /* Under word-wrap, we don't know the x coordinate of
22810 the last character displayed on the previous line,
22811 which immediately precedes the wrap point. To find
22812 out its x coordinate, we try moving to the right
22813 margin of the window, which will stop at the wrap
22814 point, and then reset target_x to point at the
22815 character that precedes the wrap point. This is not
22816 needed on GUI frames, because (see below) there we
22817 move from the left margin one grapheme cluster at a
22818 time, and stop when we hit the wrap point. */
22819 if (!FRAME_WINDOW_P (it.f) && it.line_wrap == WORD_WRAP)
22821 void *it_data = NULL;
22822 struct it it2;
22824 SAVE_IT (it2, it, it_data);
22825 move_it_in_display_line_to (&it, ZV, target_x,
22826 MOVE_TO_POS | MOVE_TO_X);
22827 /* If we arrived at target_x, that _is_ the last
22828 character on the previous line. */
22829 if (it.current_x != target_x)
22830 target_x = it.current_x - 1;
22831 RESTORE_IT (&it, &it2, it_data);
22835 else
22837 if (at_eol_p
22838 || (target_x >= it.last_visible_x
22839 && it.line_wrap != TRUNCATE))
22841 if (pt_x > 0)
22842 move_it_by_lines (&it, 0);
22843 move_it_by_lines (&it, 1);
22844 target_x = 0;
22848 /* Move to the target X coordinate. */
22849 /* On GUI frames, as we don't know the X coordinate of the
22850 character to the left of point, moving point to the left
22851 requires walking, one grapheme cluster at a time, until we
22852 find ourself at a place immediately to the left of the
22853 character at point. */
22854 if (FRAME_WINDOW_P (it.f) && dir < 0)
22856 struct text_pos new_pos;
22857 enum move_it_result rc = MOVE_X_REACHED;
22859 if (it.current_x == 0)
22860 get_next_display_element (&it);
22861 if (it.what == IT_COMPOSITION)
22863 new_pos.charpos = it.cmp_it.charpos;
22864 new_pos.bytepos = -1;
22866 else
22867 new_pos = it.current.pos;
22869 while (it.current_x + it.pixel_width <= target_x
22870 && (rc == MOVE_X_REACHED
22871 /* Under word-wrap, move_it_in_display_line_to
22872 stops at correct coordinates, but sometimes
22873 returns MOVE_POS_MATCH_OR_ZV. */
22874 || (it.line_wrap == WORD_WRAP
22875 && rc == MOVE_POS_MATCH_OR_ZV)))
22877 int new_x = it.current_x + it.pixel_width;
22879 /* For composed characters, we want the position of the
22880 first character in the grapheme cluster (usually, the
22881 composition's base character), whereas it.current
22882 might give us the position of the _last_ one, e.g. if
22883 the composition is rendered in reverse due to bidi
22884 reordering. */
22885 if (it.what == IT_COMPOSITION)
22887 new_pos.charpos = it.cmp_it.charpos;
22888 new_pos.bytepos = -1;
22890 else
22891 new_pos = it.current.pos;
22892 if (new_x == it.current_x)
22893 new_x++;
22894 rc = move_it_in_display_line_to (&it, ZV, new_x,
22895 MOVE_TO_POS | MOVE_TO_X);
22896 if (ITERATOR_AT_END_OF_LINE_P (&it) && !target_is_eol_p)
22897 break;
22899 /* The previous position we saw in the loop is the one we
22900 want. */
22901 if (new_pos.bytepos == -1)
22902 new_pos.bytepos = CHAR_TO_BYTE (new_pos.charpos);
22903 it.current.pos = new_pos;
22905 else if (it.current_x != target_x)
22906 move_it_in_display_line_to (&it, ZV, target_x, MOVE_TO_POS | MOVE_TO_X);
22908 /* If we ended up in a display string that covers point, move to
22909 buffer position to the right in the visual order. */
22910 if (dir > 0)
22912 while (IT_CHARPOS (it) == PT)
22914 set_iterator_to_next (&it, false);
22915 if (!get_next_display_element (&it))
22916 break;
22920 /* Move point to that position. */
22921 SET_PT_BOTH (IT_CHARPOS (it), IT_BYTEPOS (it));
22924 return make_number (PT);
22926 #undef ROW_GLYPH_NEWLINE_P
22929 DEFUN ("bidi-resolved-levels", Fbidi_resolved_levels,
22930 Sbidi_resolved_levels, 0, 1, 0,
22931 doc: /* Return the resolved bidirectional levels of characters at VPOS.
22933 The resolved levels are produced by the Emacs bidi reordering engine
22934 that implements the UBA, the Unicode Bidirectional Algorithm. Please
22935 read the Unicode Standard Annex 9 (UAX#9) for background information
22936 about these levels.
22938 VPOS is the zero-based number of the current window's screen line
22939 for which to produce the resolved levels. If VPOS is nil or omitted,
22940 it defaults to the screen line of point. If the window displays a
22941 header line, VPOS of zero will report on the header line, and first
22942 line of text in the window will have VPOS of 1.
22944 Value is an array of resolved levels, indexed by glyph number.
22945 Glyphs are numbered from zero starting from the beginning of the
22946 screen line, i.e. the left edge of the window for left-to-right lines
22947 and from the right edge for right-to-left lines. The resolved levels
22948 are produced only for the window's text area; text in display margins
22949 is not included.
22951 If the selected window's display is not up-to-date, or if the specified
22952 screen line does not display text, this function returns nil. It is
22953 highly recommended to bind this function to some simple key, like F8,
22954 in order to avoid these problems.
22956 This function exists mainly for testing the correctness of the
22957 Emacs UBA implementation, in particular with the test suite. */)
22958 (Lisp_Object vpos)
22960 struct window *w = XWINDOW (selected_window);
22961 struct buffer *b = XBUFFER (w->contents);
22962 int nrow;
22963 struct glyph_row *row;
22965 if (NILP (vpos))
22967 int d1, d2, d3, d4, d5;
22969 pos_visible_p (w, PT, &d1, &d2, &d3, &d4, &d5, &nrow);
22971 else
22973 CHECK_NUMBER_COERCE_MARKER (vpos);
22974 nrow = XINT (vpos);
22977 /* We require up-to-date glyph matrix for this window. */
22978 if (w->window_end_valid
22979 && !windows_or_buffers_changed
22980 && b
22981 && !b->clip_changed
22982 && !b->prevent_redisplay_optimizations_p
22983 && !window_outdated (w)
22984 && nrow >= 0
22985 && nrow < w->current_matrix->nrows
22986 && (row = MATRIX_ROW (w->current_matrix, nrow))->enabled_p
22987 && MATRIX_ROW_DISPLAYS_TEXT_P (row))
22989 struct glyph *g, *e, *g1;
22990 int nglyphs, i;
22991 Lisp_Object levels;
22993 if (!row->reversed_p) /* Left-to-right glyph row. */
22995 g = g1 = row->glyphs[TEXT_AREA];
22996 e = g + row->used[TEXT_AREA];
22998 /* Skip over glyphs at the start of the row that was
22999 generated by redisplay for its own needs. */
23000 while (g < e
23001 && NILP (g->object)
23002 && g->charpos < 0)
23003 g++;
23004 g1 = g;
23006 /* Count the "interesting" glyphs in this row. */
23007 for (nglyphs = 0; g < e && !NILP (g->object); g++)
23008 nglyphs++;
23010 /* Create and fill the array. */
23011 levels = make_uninit_vector (nglyphs);
23012 for (i = 0; g1 < g; i++, g1++)
23013 ASET (levels, i, make_number (g1->resolved_level));
23015 else /* Right-to-left glyph row. */
23017 g = row->glyphs[TEXT_AREA] + row->used[TEXT_AREA] - 1;
23018 e = row->glyphs[TEXT_AREA] - 1;
23019 while (g > e
23020 && NILP (g->object)
23021 && g->charpos < 0)
23022 g--;
23023 g1 = g;
23024 for (nglyphs = 0; g > e && !NILP (g->object); g--)
23025 nglyphs++;
23026 levels = make_uninit_vector (nglyphs);
23027 for (i = 0; g1 > g; i++, g1--)
23028 ASET (levels, i, make_number (g1->resolved_level));
23030 return levels;
23032 else
23033 return Qnil;
23038 /***********************************************************************
23039 Menu Bar
23040 ***********************************************************************/
23042 /* Redisplay the menu bar in the frame for window W.
23044 The menu bar of X frames that don't have X toolkit support is
23045 displayed in a special window W->frame->menu_bar_window.
23047 The menu bar of terminal frames is treated specially as far as
23048 glyph matrices are concerned. Menu bar lines are not part of
23049 windows, so the update is done directly on the frame matrix rows
23050 for the menu bar. */
23052 static void
23053 display_menu_bar (struct window *w)
23055 struct frame *f = XFRAME (WINDOW_FRAME (w));
23056 struct it it;
23057 Lisp_Object items;
23058 int i;
23060 /* Don't do all this for graphical frames. */
23061 #ifdef HAVE_NTGUI
23062 if (FRAME_W32_P (f))
23063 return;
23064 #endif
23065 #if defined (USE_X_TOOLKIT) || defined (USE_GTK)
23066 if (FRAME_X_P (f))
23067 return;
23068 #endif
23070 #ifdef HAVE_NS
23071 if (FRAME_NS_P (f))
23072 return;
23073 #endif /* HAVE_NS */
23075 #if defined (USE_X_TOOLKIT) || defined (USE_GTK)
23076 eassert (!FRAME_WINDOW_P (f));
23077 init_iterator (&it, w, -1, -1, f->desired_matrix->rows, MENU_FACE_ID);
23078 it.first_visible_x = 0;
23079 it.last_visible_x = FRAME_PIXEL_WIDTH (f);
23080 #elif defined (HAVE_X_WINDOWS) /* X without toolkit. */
23081 if (FRAME_WINDOW_P (f))
23083 /* Menu bar lines are displayed in the desired matrix of the
23084 dummy window menu_bar_window. */
23085 struct window *menu_w;
23086 menu_w = XWINDOW (f->menu_bar_window);
23087 init_iterator (&it, menu_w, -1, -1, menu_w->desired_matrix->rows,
23088 MENU_FACE_ID);
23089 it.first_visible_x = 0;
23090 it.last_visible_x = FRAME_PIXEL_WIDTH (f);
23092 else
23093 #endif /* not USE_X_TOOLKIT and not USE_GTK */
23095 /* This is a TTY frame, i.e. character hpos/vpos are used as
23096 pixel x/y. */
23097 init_iterator (&it, w, -1, -1, f->desired_matrix->rows,
23098 MENU_FACE_ID);
23099 it.first_visible_x = 0;
23100 it.last_visible_x = FRAME_COLS (f);
23103 /* FIXME: This should be controlled by a user option. See the
23104 comments in redisplay_tool_bar and display_mode_line about
23105 this. */
23106 it.paragraph_embedding = L2R;
23108 /* Clear all rows of the menu bar. */
23109 for (i = 0; i < FRAME_MENU_BAR_LINES (f); ++i)
23111 struct glyph_row *row = it.glyph_row + i;
23112 clear_glyph_row (row);
23113 row->enabled_p = true;
23114 row->full_width_p = true;
23115 row->reversed_p = false;
23118 /* Display all items of the menu bar. */
23119 items = FRAME_MENU_BAR_ITEMS (it.f);
23120 for (i = 0; i < ASIZE (items); i += 4)
23122 Lisp_Object string;
23124 /* Stop at nil string. */
23125 string = AREF (items, i + 1);
23126 if (NILP (string))
23127 break;
23129 /* Remember where item was displayed. */
23130 ASET (items, i + 3, make_number (it.hpos));
23132 /* Display the item, pad with one space. */
23133 if (it.current_x < it.last_visible_x)
23134 display_string (NULL, string, Qnil, 0, 0, &it,
23135 SCHARS (string) + 1, 0, 0, -1);
23138 /* Fill out the line with spaces. */
23139 if (it.current_x < it.last_visible_x)
23140 display_string ("", Qnil, Qnil, 0, 0, &it, -1, 0, 0, -1);
23142 /* Compute the total height of the lines. */
23143 compute_line_metrics (&it);
23146 /* Deep copy of a glyph row, including the glyphs. */
23147 static void
23148 deep_copy_glyph_row (struct glyph_row *to, struct glyph_row *from)
23150 struct glyph *pointers[1 + LAST_AREA];
23151 int to_used = to->used[TEXT_AREA];
23153 /* Save glyph pointers of TO. */
23154 memcpy (pointers, to->glyphs, sizeof to->glyphs);
23156 /* Do a structure assignment. */
23157 *to = *from;
23159 /* Restore original glyph pointers of TO. */
23160 memcpy (to->glyphs, pointers, sizeof to->glyphs);
23162 /* Copy the glyphs. */
23163 memcpy (to->glyphs[TEXT_AREA], from->glyphs[TEXT_AREA],
23164 min (from->used[TEXT_AREA], to_used) * sizeof (struct glyph));
23166 /* If we filled only part of the TO row, fill the rest with
23167 space_glyph (which will display as empty space). */
23168 if (to_used > from->used[TEXT_AREA])
23169 fill_up_frame_row_with_spaces (to, to_used);
23172 /* Display one menu item on a TTY, by overwriting the glyphs in the
23173 frame F's desired glyph matrix with glyphs produced from the menu
23174 item text. Called from term.c to display TTY drop-down menus one
23175 item at a time.
23177 ITEM_TEXT is the menu item text as a C string.
23179 FACE_ID is the face ID to be used for this menu item. FACE_ID
23180 could specify one of 3 faces: a face for an enabled item, a face
23181 for a disabled item, or a face for a selected item.
23183 X and Y are coordinates of the first glyph in the frame's desired
23184 matrix to be overwritten by the menu item. Since this is a TTY, Y
23185 is the zero-based number of the glyph row and X is the zero-based
23186 glyph number in the row, starting from left, where to start
23187 displaying the item.
23189 SUBMENU means this menu item drops down a submenu, which
23190 should be indicated by displaying a proper visual cue after the
23191 item text. */
23193 void
23194 display_tty_menu_item (const char *item_text, int width, int face_id,
23195 int x, int y, bool submenu)
23197 struct it it;
23198 struct frame *f = SELECTED_FRAME ();
23199 struct window *w = XWINDOW (f->selected_window);
23200 struct glyph_row *row;
23201 size_t item_len = strlen (item_text);
23203 eassert (FRAME_TERMCAP_P (f));
23205 /* Don't write beyond the matrix's last row. This can happen for
23206 TTY screens that are not high enough to show the entire menu.
23207 (This is actually a bit of defensive programming, as
23208 tty_menu_display already limits the number of menu items to one
23209 less than the number of screen lines.) */
23210 if (y >= f->desired_matrix->nrows)
23211 return;
23213 init_iterator (&it, w, -1, -1, f->desired_matrix->rows + y, MENU_FACE_ID);
23214 it.first_visible_x = 0;
23215 it.last_visible_x = FRAME_COLS (f) - 1;
23216 row = it.glyph_row;
23217 /* Start with the row contents from the current matrix. */
23218 deep_copy_glyph_row (row, f->current_matrix->rows + y);
23219 bool saved_width = row->full_width_p;
23220 row->full_width_p = true;
23221 bool saved_reversed = row->reversed_p;
23222 row->reversed_p = false;
23223 row->enabled_p = true;
23225 /* Arrange for the menu item glyphs to start at (X,Y) and have the
23226 desired face. */
23227 eassert (x < f->desired_matrix->matrix_w);
23228 it.current_x = it.hpos = x;
23229 it.current_y = it.vpos = y;
23230 int saved_used = row->used[TEXT_AREA];
23231 bool saved_truncated = row->truncated_on_right_p;
23232 row->used[TEXT_AREA] = x;
23233 it.face_id = face_id;
23234 it.line_wrap = TRUNCATE;
23236 /* FIXME: This should be controlled by a user option. See the
23237 comments in redisplay_tool_bar and display_mode_line about this.
23238 Also, if paragraph_embedding could ever be R2L, changes will be
23239 needed to avoid shifting to the right the row characters in
23240 term.c:append_glyph. */
23241 it.paragraph_embedding = L2R;
23243 /* Pad with a space on the left. */
23244 display_string (" ", Qnil, Qnil, 0, 0, &it, 1, 0, FRAME_COLS (f) - 1, -1);
23245 width--;
23246 /* Display the menu item, pad with spaces to WIDTH. */
23247 if (submenu)
23249 display_string (item_text, Qnil, Qnil, 0, 0, &it,
23250 item_len, 0, FRAME_COLS (f) - 1, -1);
23251 width -= item_len;
23252 /* Indicate with " >" that there's a submenu. */
23253 display_string (" >", Qnil, Qnil, 0, 0, &it, width, 0,
23254 FRAME_COLS (f) - 1, -1);
23256 else
23257 display_string (item_text, Qnil, Qnil, 0, 0, &it,
23258 width, 0, FRAME_COLS (f) - 1, -1);
23260 row->used[TEXT_AREA] = max (saved_used, row->used[TEXT_AREA]);
23261 row->truncated_on_right_p = saved_truncated;
23262 row->hash = row_hash (row);
23263 row->full_width_p = saved_width;
23264 row->reversed_p = saved_reversed;
23267 /***********************************************************************
23268 Mode Line
23269 ***********************************************************************/
23271 /* Redisplay mode lines in the window tree whose root is WINDOW.
23272 If FORCE, redisplay mode lines unconditionally.
23273 Otherwise, redisplay only mode lines that are garbaged. Value is
23274 the number of windows whose mode lines were redisplayed. */
23276 static int
23277 redisplay_mode_lines (Lisp_Object window, bool force)
23279 int nwindows = 0;
23281 while (!NILP (window))
23283 struct window *w = XWINDOW (window);
23285 if (WINDOWP (w->contents))
23286 nwindows += redisplay_mode_lines (w->contents, force);
23287 else if (force
23288 || FRAME_GARBAGED_P (XFRAME (w->frame))
23289 || !MATRIX_MODE_LINE_ROW (w->current_matrix)->enabled_p)
23291 struct text_pos lpoint;
23292 struct buffer *old = current_buffer;
23294 /* Set the window's buffer for the mode line display. */
23295 SET_TEXT_POS (lpoint, PT, PT_BYTE);
23296 set_buffer_internal_1 (XBUFFER (w->contents));
23298 /* Point refers normally to the selected window. For any
23299 other window, set up appropriate value. */
23300 if (!EQ (window, selected_window))
23302 struct text_pos pt;
23304 CLIP_TEXT_POS_FROM_MARKER (pt, w->pointm);
23305 TEMP_SET_PT_BOTH (CHARPOS (pt), BYTEPOS (pt));
23308 /* Display mode lines. */
23309 clear_glyph_matrix (w->desired_matrix);
23310 if (display_mode_lines (w))
23311 ++nwindows;
23313 /* Restore old settings. */
23314 set_buffer_internal_1 (old);
23315 TEMP_SET_PT_BOTH (CHARPOS (lpoint), BYTEPOS (lpoint));
23318 window = w->next;
23321 return nwindows;
23325 /* Display the mode and/or header line of window W. Value is the
23326 sum number of mode lines and header lines displayed. */
23328 static int
23329 display_mode_lines (struct window *w)
23331 Lisp_Object old_selected_window = selected_window;
23332 Lisp_Object old_selected_frame = selected_frame;
23333 Lisp_Object new_frame = w->frame;
23334 Lisp_Object old_frame_selected_window = XFRAME (new_frame)->selected_window;
23335 int n = 0;
23337 if (window_wants_mode_line (w))
23339 Lisp_Object window;
23340 Lisp_Object default_help
23341 = buffer_local_value (Qmode_line_default_help_echo, w->contents);
23343 /* Set up mode line help echo. Do this before selecting w so it
23344 can reasonably tell whether a mouse click will select w. */
23345 XSETWINDOW (window, w);
23346 if (FUNCTIONP (default_help))
23347 wset_mode_line_help_echo (w, safe_call1 (default_help, window));
23348 else if (STRINGP (default_help))
23349 wset_mode_line_help_echo (w, default_help);
23350 else
23351 wset_mode_line_help_echo (w, Qnil);
23354 selected_frame = new_frame;
23355 /* FIXME: If we were to allow the mode-line's computation changing the buffer
23356 or window's point, then we'd need select_window_1 here as well. */
23357 XSETWINDOW (selected_window, w);
23358 XFRAME (new_frame)->selected_window = selected_window;
23360 /* These will be set while the mode line specs are processed. */
23361 line_number_displayed = false;
23362 w->column_number_displayed = -1;
23364 if (window_wants_mode_line (w))
23366 Lisp_Object window_mode_line_format
23367 = window_parameter (w, Qmode_line_format);
23368 struct window *sel_w = XWINDOW (old_selected_window);
23370 /* Select mode line face based on the real selected window. */
23371 display_mode_line (w, CURRENT_MODE_LINE_FACE_ID_3 (sel_w, sel_w, w),
23372 NILP (window_mode_line_format)
23373 ? BVAR (current_buffer, mode_line_format)
23374 : window_mode_line_format);
23375 ++n;
23378 if (window_wants_header_line (w))
23380 Lisp_Object window_header_line_format
23381 = window_parameter (w, Qheader_line_format);
23383 display_mode_line (w, HEADER_LINE_FACE_ID,
23384 NILP (window_header_line_format)
23385 ? BVAR (current_buffer, header_line_format)
23386 : window_header_line_format);
23387 ++n;
23390 XFRAME (new_frame)->selected_window = old_frame_selected_window;
23391 selected_frame = old_selected_frame;
23392 selected_window = old_selected_window;
23393 if (n > 0)
23394 w->must_be_updated_p = true;
23395 return n;
23399 /* Display mode or header line of window W. FACE_ID specifies which
23400 line to display; it is either MODE_LINE_FACE_ID or
23401 HEADER_LINE_FACE_ID. FORMAT is the mode/header line format to
23402 display. Value is the pixel height of the mode/header line
23403 displayed. */
23405 static int
23406 display_mode_line (struct window *w, enum face_id face_id, Lisp_Object format)
23408 struct it it;
23409 struct face *face;
23410 ptrdiff_t count = SPECPDL_INDEX ();
23412 init_iterator (&it, w, -1, -1, NULL, face_id);
23413 /* Don't extend on a previously drawn mode-line.
23414 This may happen if called from pos_visible_p. */
23415 it.glyph_row->enabled_p = false;
23416 prepare_desired_row (w, it.glyph_row, true);
23418 it.glyph_row->mode_line_p = true;
23420 /* FIXME: This should be controlled by a user option. But
23421 supporting such an option is not trivial, since the mode line is
23422 made up of many separate strings. */
23423 it.paragraph_embedding = L2R;
23425 record_unwind_protect (unwind_format_mode_line,
23426 format_mode_line_unwind_data (NULL, NULL,
23427 Qnil, false));
23429 mode_line_target = MODE_LINE_DISPLAY;
23431 /* Temporarily make frame's keyboard the current kboard so that
23432 kboard-local variables in the mode_line_format will get the right
23433 values. */
23434 push_kboard (FRAME_KBOARD (it.f));
23435 record_unwind_save_match_data ();
23436 display_mode_element (&it, 0, 0, 0, format, Qnil, false);
23437 pop_kboard ();
23439 unbind_to (count, Qnil);
23441 /* Fill up with spaces. */
23442 display_string (" ", Qnil, Qnil, 0, 0, &it, 10000, -1, -1, 0);
23444 compute_line_metrics (&it);
23445 it.glyph_row->full_width_p = true;
23446 it.glyph_row->continued_p = false;
23447 it.glyph_row->truncated_on_left_p = false;
23448 it.glyph_row->truncated_on_right_p = false;
23450 /* Make a 3D mode-line have a shadow at its right end. */
23451 face = FACE_FROM_ID (it.f, face_id);
23452 extend_face_to_end_of_line (&it);
23453 if (face->box != FACE_NO_BOX)
23455 struct glyph *last = (it.glyph_row->glyphs[TEXT_AREA]
23456 + it.glyph_row->used[TEXT_AREA] - 1);
23457 last->right_box_line_p = true;
23460 return it.glyph_row->height;
23463 /* Move element ELT in LIST to the front of LIST.
23464 Return the updated list. */
23466 static Lisp_Object
23467 move_elt_to_front (Lisp_Object elt, Lisp_Object list)
23469 register Lisp_Object tail, prev;
23470 register Lisp_Object tem;
23472 tail = list;
23473 prev = Qnil;
23474 while (CONSP (tail))
23476 tem = XCAR (tail);
23478 if (EQ (elt, tem))
23480 /* Splice out the link TAIL. */
23481 if (NILP (prev))
23482 list = XCDR (tail);
23483 else
23484 Fsetcdr (prev, XCDR (tail));
23486 /* Now make it the first. */
23487 Fsetcdr (tail, list);
23488 return tail;
23490 else
23491 prev = tail;
23492 tail = XCDR (tail);
23493 maybe_quit ();
23496 /* Not found--return unchanged LIST. */
23497 return list;
23500 /* Contribute ELT to the mode line for window IT->w. How it
23501 translates into text depends on its data type.
23503 IT describes the display environment in which we display, as usual.
23505 DEPTH is the depth in recursion. It is used to prevent
23506 infinite recursion here.
23508 FIELD_WIDTH is the number of characters the display of ELT should
23509 occupy in the mode line, and PRECISION is the maximum number of
23510 characters to display from ELT's representation. See
23511 display_string for details.
23513 Returns the hpos of the end of the text generated by ELT.
23515 PROPS is a property list to add to any string we encounter.
23517 If RISKY, remove (disregard) any properties in any string
23518 we encounter, and ignore :eval and :propertize.
23520 The global variable `mode_line_target' determines whether the
23521 output is passed to `store_mode_line_noprop',
23522 `store_mode_line_string', or `display_string'. */
23524 static int
23525 display_mode_element (struct it *it, int depth, int field_width, int precision,
23526 Lisp_Object elt, Lisp_Object props, bool risky)
23528 int n = 0, field, prec;
23529 bool literal = false;
23531 tail_recurse:
23532 if (depth > 100)
23533 elt = build_string ("*too-deep*");
23535 depth++;
23537 switch (XTYPE (elt))
23539 case Lisp_String:
23541 /* A string: output it and check for %-constructs within it. */
23542 unsigned char c;
23543 ptrdiff_t offset = 0;
23545 if (SCHARS (elt) > 0
23546 && (!NILP (props) || risky))
23548 Lisp_Object oprops, aelt;
23549 oprops = Ftext_properties_at (make_number (0), elt);
23551 /* If the starting string's properties are not what
23552 we want, translate the string. Also, if the string
23553 is risky, do that anyway. */
23555 if (NILP (Fequal (props, oprops)) || risky)
23557 /* If the starting string has properties,
23558 merge the specified ones onto the existing ones. */
23559 if (! NILP (oprops) && !risky)
23561 Lisp_Object tem;
23563 oprops = Fcopy_sequence (oprops);
23564 tem = props;
23565 while (CONSP (tem))
23567 oprops = Fplist_put (oprops, XCAR (tem),
23568 XCAR (XCDR (tem)));
23569 tem = XCDR (XCDR (tem));
23571 props = oprops;
23574 aelt = Fassoc (elt, mode_line_proptrans_alist, Qnil);
23575 if (! NILP (aelt) && !NILP (Fequal (props, XCDR (aelt))))
23577 /* AELT is what we want. Move it to the front
23578 without consing. */
23579 elt = XCAR (aelt);
23580 mode_line_proptrans_alist
23581 = move_elt_to_front (aelt, mode_line_proptrans_alist);
23583 else
23585 Lisp_Object tem;
23587 /* If AELT has the wrong props, it is useless.
23588 so get rid of it. */
23589 if (! NILP (aelt))
23590 mode_line_proptrans_alist
23591 = Fdelq (aelt, mode_line_proptrans_alist);
23593 elt = Fcopy_sequence (elt);
23594 Fset_text_properties (make_number (0), Flength (elt),
23595 props, elt);
23596 /* Add this item to mode_line_proptrans_alist. */
23597 mode_line_proptrans_alist
23598 = Fcons (Fcons (elt, props),
23599 mode_line_proptrans_alist);
23600 /* Truncate mode_line_proptrans_alist
23601 to at most 50 elements. */
23602 tem = Fnthcdr (make_number (50),
23603 mode_line_proptrans_alist);
23604 if (! NILP (tem))
23605 XSETCDR (tem, Qnil);
23610 offset = 0;
23612 if (literal)
23614 prec = precision - n;
23615 switch (mode_line_target)
23617 case MODE_LINE_NOPROP:
23618 case MODE_LINE_TITLE:
23619 n += store_mode_line_noprop (SSDATA (elt), -1, prec);
23620 break;
23621 case MODE_LINE_STRING:
23622 n += store_mode_line_string (NULL, elt, true, 0, prec, Qnil);
23623 break;
23624 case MODE_LINE_DISPLAY:
23625 n += display_string (NULL, elt, Qnil, 0, 0, it,
23626 0, prec, 0, STRING_MULTIBYTE (elt));
23627 break;
23630 break;
23633 /* Handle the non-literal case. */
23635 while ((precision <= 0 || n < precision)
23636 && SREF (elt, offset) != 0
23637 && (mode_line_target != MODE_LINE_DISPLAY
23638 || it->current_x < it->last_visible_x))
23640 ptrdiff_t last_offset = offset;
23642 /* Advance to end of string or next format specifier. */
23643 while ((c = SREF (elt, offset++)) != '\0' && c != '%')
23646 if (offset - 1 != last_offset)
23648 ptrdiff_t nchars, nbytes;
23650 /* Output to end of string or up to '%'. Field width
23651 is length of string. Don't output more than
23652 PRECISION allows us. */
23653 offset--;
23655 prec = c_string_width (SDATA (elt) + last_offset,
23656 offset - last_offset, precision - n,
23657 &nchars, &nbytes);
23659 switch (mode_line_target)
23661 case MODE_LINE_NOPROP:
23662 case MODE_LINE_TITLE:
23663 n += store_mode_line_noprop (SSDATA (elt) + last_offset, 0, prec);
23664 break;
23665 case MODE_LINE_STRING:
23667 ptrdiff_t bytepos = last_offset;
23668 ptrdiff_t charpos = string_byte_to_char (elt, bytepos);
23669 ptrdiff_t endpos = (precision <= 0
23670 ? string_byte_to_char (elt, offset)
23671 : charpos + nchars);
23672 Lisp_Object mode_string
23673 = Fsubstring (elt, make_number (charpos),
23674 make_number (endpos));
23675 n += store_mode_line_string (NULL, mode_string, false,
23676 0, 0, Qnil);
23678 break;
23679 case MODE_LINE_DISPLAY:
23681 ptrdiff_t bytepos = last_offset;
23682 ptrdiff_t charpos = string_byte_to_char (elt, bytepos);
23684 if (precision <= 0)
23685 nchars = string_byte_to_char (elt, offset) - charpos;
23686 n += display_string (NULL, elt, Qnil, 0, charpos,
23687 it, 0, nchars, 0,
23688 STRING_MULTIBYTE (elt));
23690 break;
23693 else /* c == '%' */
23695 ptrdiff_t percent_position = offset;
23697 /* Get the specified minimum width. Zero means
23698 don't pad. */
23699 field = 0;
23700 while ((c = SREF (elt, offset++)) >= '0' && c <= '9')
23701 field = field * 10 + c - '0';
23703 /* Don't pad beyond the total padding allowed. */
23704 if (field_width - n > 0 && field > field_width - n)
23705 field = field_width - n;
23707 /* Note that either PRECISION <= 0 or N < PRECISION. */
23708 prec = precision - n;
23710 if (c == 'M')
23711 n += display_mode_element (it, depth, field, prec,
23712 Vglobal_mode_string, props,
23713 risky);
23714 else if (c != 0)
23716 bool multibyte;
23717 ptrdiff_t bytepos, charpos;
23718 const char *spec;
23719 Lisp_Object string;
23721 bytepos = percent_position;
23722 charpos = (STRING_MULTIBYTE (elt)
23723 ? string_byte_to_char (elt, bytepos)
23724 : bytepos);
23725 spec = decode_mode_spec (it->w, c, field, &string);
23726 multibyte = STRINGP (string) && STRING_MULTIBYTE (string);
23728 switch (mode_line_target)
23730 case MODE_LINE_NOPROP:
23731 case MODE_LINE_TITLE:
23732 n += store_mode_line_noprop (spec, field, prec);
23733 break;
23734 case MODE_LINE_STRING:
23736 Lisp_Object tem = build_string (spec);
23737 props = Ftext_properties_at (make_number (charpos), elt);
23738 /* Should only keep face property in props */
23739 n += store_mode_line_string (NULL, tem, false,
23740 field, prec, props);
23742 break;
23743 case MODE_LINE_DISPLAY:
23745 int nglyphs_before, nwritten;
23747 nglyphs_before = it->glyph_row->used[TEXT_AREA];
23748 nwritten = display_string (spec, string, elt,
23749 charpos, 0, it,
23750 field, prec, 0,
23751 multibyte);
23753 /* Assign to the glyphs written above the
23754 string where the `%x' came from, position
23755 of the `%'. */
23756 if (nwritten > 0)
23758 struct glyph *glyph
23759 = (it->glyph_row->glyphs[TEXT_AREA]
23760 + nglyphs_before);
23761 int i;
23763 for (i = 0; i < nwritten; ++i)
23765 glyph[i].object = elt;
23766 glyph[i].charpos = charpos;
23769 n += nwritten;
23772 break;
23775 else /* c == 0 */
23776 break;
23780 break;
23782 case Lisp_Symbol:
23783 /* A symbol: process the value of the symbol recursively
23784 as if it appeared here directly. Avoid error if symbol void.
23785 Special case: if value of symbol is a string, output the string
23786 literally. */
23788 register Lisp_Object tem;
23790 /* If the variable is not marked as risky to set
23791 then its contents are risky to use. */
23792 if (NILP (Fget (elt, Qrisky_local_variable)))
23793 risky = true;
23795 tem = Fboundp (elt);
23796 if (!NILP (tem))
23798 tem = Fsymbol_value (elt);
23799 /* If value is a string, output that string literally:
23800 don't check for % within it. */
23801 if (STRINGP (tem))
23802 literal = true;
23804 if (!EQ (tem, elt))
23806 /* Give up right away for nil or t. */
23807 elt = tem;
23808 goto tail_recurse;
23812 break;
23814 case Lisp_Cons:
23816 register Lisp_Object car, tem;
23818 /* A cons cell: five distinct cases.
23819 If first element is :eval or :propertize, do something special.
23820 If first element is a string or a cons, process all the elements
23821 and effectively concatenate them.
23822 If first element is a negative number, truncate displaying cdr to
23823 at most that many characters. If positive, pad (with spaces)
23824 to at least that many characters.
23825 If first element is a symbol, process the cadr or caddr recursively
23826 according to whether the symbol's value is non-nil or nil. */
23827 car = XCAR (elt);
23828 if (EQ (car, QCeval))
23830 /* An element of the form (:eval FORM) means evaluate FORM
23831 and use the result as mode line elements. */
23833 if (risky)
23834 break;
23836 if (CONSP (XCDR (elt)))
23838 Lisp_Object spec;
23839 spec = safe__eval (true, XCAR (XCDR (elt)));
23840 /* The :eval form could delete the frame stored in the
23841 iterator, which will cause a crash if we try to
23842 access faces and other fields (e.g., FRAME_KBOARD)
23843 on that frame. This is a nonsensical thing to do,
23844 and signaling an error from redisplay might be
23845 dangerous, but we cannot continue with an invalid frame. */
23846 if (!FRAME_LIVE_P (it->f))
23847 signal_error (":eval deleted the frame being displayed", elt);
23848 n += display_mode_element (it, depth, field_width - n,
23849 precision - n, spec, props,
23850 risky);
23853 else if (EQ (car, QCpropertize))
23855 /* An element of the form (:propertize ELT PROPS...)
23856 means display ELT but applying properties PROPS. */
23858 if (risky)
23859 break;
23861 if (CONSP (XCDR (elt)))
23862 n += display_mode_element (it, depth, field_width - n,
23863 precision - n, XCAR (XCDR (elt)),
23864 XCDR (XCDR (elt)), risky);
23866 else if (SYMBOLP (car))
23868 tem = Fboundp (car);
23869 elt = XCDR (elt);
23870 if (!CONSP (elt))
23871 goto invalid;
23872 /* elt is now the cdr, and we know it is a cons cell.
23873 Use its car if CAR has a non-nil value. */
23874 if (!NILP (tem))
23876 tem = Fsymbol_value (car);
23877 if (!NILP (tem))
23879 elt = XCAR (elt);
23880 goto tail_recurse;
23883 /* Symbol's value is nil (or symbol is unbound)
23884 Get the cddr of the original list
23885 and if possible find the caddr and use that. */
23886 elt = XCDR (elt);
23887 if (NILP (elt))
23888 break;
23889 else if (!CONSP (elt))
23890 goto invalid;
23891 elt = XCAR (elt);
23892 goto tail_recurse;
23894 else if (INTEGERP (car))
23896 register int lim = XINT (car);
23897 elt = XCDR (elt);
23898 if (lim < 0)
23900 /* Negative int means reduce maximum width. */
23901 if (precision <= 0)
23902 precision = -lim;
23903 else
23904 precision = min (precision, -lim);
23906 else if (lim > 0)
23908 /* Padding specified. Don't let it be more than
23909 current maximum. */
23910 if (precision > 0)
23911 lim = min (precision, lim);
23913 /* If that's more padding than already wanted, queue it.
23914 But don't reduce padding already specified even if
23915 that is beyond the current truncation point. */
23916 field_width = max (lim, field_width);
23918 goto tail_recurse;
23920 else if (STRINGP (car) || CONSP (car))
23921 FOR_EACH_TAIL_SAFE (elt)
23923 if (0 < precision && precision <= n)
23924 break;
23925 n += display_mode_element (it, depth,
23926 /* Pad after only the last
23927 list element. */
23928 (! CONSP (XCDR (elt))
23929 ? field_width - n
23930 : 0),
23931 precision - n, XCAR (elt),
23932 props, risky);
23935 break;
23937 default:
23938 invalid:
23939 elt = build_string ("*invalid*");
23940 goto tail_recurse;
23943 /* Pad to FIELD_WIDTH. */
23944 if (field_width > 0 && n < field_width)
23946 switch (mode_line_target)
23948 case MODE_LINE_NOPROP:
23949 case MODE_LINE_TITLE:
23950 n += store_mode_line_noprop ("", field_width - n, 0);
23951 break;
23952 case MODE_LINE_STRING:
23953 n += store_mode_line_string ("", Qnil, false, field_width - n, 0,
23954 Qnil);
23955 break;
23956 case MODE_LINE_DISPLAY:
23957 n += display_string ("", Qnil, Qnil, 0, 0, it, field_width - n,
23958 0, 0, 0);
23959 break;
23963 return n;
23966 /* Store a mode-line string element in mode_line_string_list.
23968 If STRING is non-null, display that C string. Otherwise, the Lisp
23969 string LISP_STRING is displayed.
23971 FIELD_WIDTH is the minimum number of output glyphs to produce.
23972 If STRING has fewer characters than FIELD_WIDTH, pad to the right
23973 with spaces. FIELD_WIDTH <= 0 means don't pad.
23975 PRECISION is the maximum number of characters to output from
23976 STRING. PRECISION <= 0 means don't truncate the string.
23978 If COPY_STRING, make a copy of LISP_STRING before adding
23979 properties to the string.
23981 PROPS are the properties to add to the string.
23982 The mode_line_string_face face property is always added to the string.
23985 static int
23986 store_mode_line_string (const char *string, Lisp_Object lisp_string,
23987 bool copy_string,
23988 int field_width, int precision, Lisp_Object props)
23990 ptrdiff_t len;
23991 int n = 0;
23993 if (string != NULL)
23995 len = strlen (string);
23996 if (precision > 0 && len > precision)
23997 len = precision;
23998 lisp_string = make_string (string, len);
23999 if (NILP (props))
24000 props = mode_line_string_face_prop;
24001 else if (!NILP (mode_line_string_face))
24003 Lisp_Object face = Fplist_get (props, Qface);
24004 props = Fcopy_sequence (props);
24005 if (NILP (face))
24006 face = mode_line_string_face;
24007 else
24008 face = list2 (face, mode_line_string_face);
24009 props = Fplist_put (props, Qface, face);
24011 Fadd_text_properties (make_number (0), make_number (len),
24012 props, lisp_string);
24014 else
24016 len = XFASTINT (Flength (lisp_string));
24017 if (precision > 0 && len > precision)
24019 len = precision;
24020 lisp_string = Fsubstring (lisp_string, make_number (0), make_number (len));
24021 precision = -1;
24023 if (!NILP (mode_line_string_face))
24025 Lisp_Object face;
24026 if (NILP (props))
24027 props = Ftext_properties_at (make_number (0), lisp_string);
24028 face = Fplist_get (props, Qface);
24029 if (NILP (face))
24030 face = mode_line_string_face;
24031 else
24032 face = list2 (face, mode_line_string_face);
24033 props = list2 (Qface, face);
24034 if (copy_string)
24035 lisp_string = Fcopy_sequence (lisp_string);
24037 if (!NILP (props))
24038 Fadd_text_properties (make_number (0), make_number (len),
24039 props, lisp_string);
24042 if (len > 0)
24044 mode_line_string_list = Fcons (lisp_string, mode_line_string_list);
24045 n += len;
24048 if (field_width > len)
24050 field_width -= len;
24051 lisp_string = Fmake_string (make_number (field_width), make_number (' '),
24052 Qnil);
24053 if (!NILP (props))
24054 Fadd_text_properties (make_number (0), make_number (field_width),
24055 props, lisp_string);
24056 mode_line_string_list = Fcons (lisp_string, mode_line_string_list);
24057 n += field_width;
24060 return n;
24064 DEFUN ("format-mode-line", Fformat_mode_line, Sformat_mode_line,
24065 1, 4, 0,
24066 doc: /* Format a string out of a mode line format specification.
24067 First arg FORMAT specifies the mode line format (see `mode-line-format'
24068 for details) to use.
24070 By default, the format is evaluated for the currently selected window.
24072 Optional second arg FACE specifies the face property to put on all
24073 characters for which no face is specified. The value nil means the
24074 default face. The value t means whatever face the window's mode line
24075 currently uses (either `mode-line' or `mode-line-inactive',
24076 depending on whether the window is the selected window or not).
24077 An integer value means the value string has no text
24078 properties.
24080 Optional third and fourth args WINDOW and BUFFER specify the window
24081 and buffer to use as the context for the formatting (defaults
24082 are the selected window and the WINDOW's buffer). */)
24083 (Lisp_Object format, Lisp_Object face,
24084 Lisp_Object window, Lisp_Object buffer)
24086 struct it it;
24087 int len;
24088 struct window *w;
24089 struct buffer *old_buffer = NULL;
24090 int face_id;
24091 bool no_props = INTEGERP (face);
24092 ptrdiff_t count = SPECPDL_INDEX ();
24093 Lisp_Object str;
24094 int string_start = 0;
24096 w = decode_any_window (window);
24097 XSETWINDOW (window, w);
24099 if (NILP (buffer))
24100 buffer = w->contents;
24101 CHECK_BUFFER (buffer);
24103 /* Make formatting the modeline a non-op when noninteractive, otherwise
24104 there will be problems later caused by a partially initialized frame. */
24105 if (NILP (format) || noninteractive)
24106 return empty_unibyte_string;
24108 if (no_props)
24109 face = Qnil;
24111 face_id = (NILP (face) || EQ (face, Qdefault)) ? DEFAULT_FACE_ID
24112 : EQ (face, Qt) ? (EQ (window, selected_window)
24113 ? MODE_LINE_FACE_ID : MODE_LINE_INACTIVE_FACE_ID)
24114 : EQ (face, Qmode_line) ? MODE_LINE_FACE_ID
24115 : EQ (face, Qmode_line_inactive) ? MODE_LINE_INACTIVE_FACE_ID
24116 : EQ (face, Qheader_line) ? HEADER_LINE_FACE_ID
24117 : EQ (face, Qtool_bar) ? TOOL_BAR_FACE_ID
24118 : DEFAULT_FACE_ID;
24120 old_buffer = current_buffer;
24122 /* Save things including mode_line_proptrans_alist,
24123 and set that to nil so that we don't alter the outer value. */
24124 record_unwind_protect (unwind_format_mode_line,
24125 format_mode_line_unwind_data
24126 (XFRAME (WINDOW_FRAME (w)),
24127 old_buffer, selected_window, true));
24128 mode_line_proptrans_alist = Qnil;
24130 Fselect_window (window, Qt);
24131 set_buffer_internal_1 (XBUFFER (buffer));
24133 init_iterator (&it, w, -1, -1, NULL, face_id);
24135 if (no_props)
24137 mode_line_target = MODE_LINE_NOPROP;
24138 mode_line_string_face_prop = Qnil;
24139 mode_line_string_list = Qnil;
24140 string_start = MODE_LINE_NOPROP_LEN (0);
24142 else
24144 mode_line_target = MODE_LINE_STRING;
24145 mode_line_string_list = Qnil;
24146 mode_line_string_face = face;
24147 mode_line_string_face_prop
24148 = NILP (face) ? Qnil : list2 (Qface, face);
24151 push_kboard (FRAME_KBOARD (it.f));
24152 display_mode_element (&it, 0, 0, 0, format, Qnil, false);
24153 pop_kboard ();
24155 if (no_props)
24157 len = MODE_LINE_NOPROP_LEN (string_start);
24158 str = make_string (mode_line_noprop_buf + string_start, len);
24160 else
24162 mode_line_string_list = Fnreverse (mode_line_string_list);
24163 str = Fmapconcat (Qidentity, mode_line_string_list,
24164 empty_unibyte_string);
24167 unbind_to (count, Qnil);
24168 return str;
24171 /* Write a null-terminated, right justified decimal representation of
24172 the positive integer D to BUF using a minimal field width WIDTH. */
24174 static void
24175 pint2str (register char *buf, register int width, register ptrdiff_t d)
24177 register char *p = buf;
24179 if (d <= 0)
24180 *p++ = '0';
24181 else
24183 while (d > 0)
24185 *p++ = d % 10 + '0';
24186 d /= 10;
24190 for (width -= (int) (p - buf); width > 0; --width)
24191 *p++ = ' ';
24192 *p-- = '\0';
24193 while (p > buf)
24195 d = *buf;
24196 *buf++ = *p;
24197 *p-- = d;
24201 /* Write a null-terminated, right justified decimal and "human
24202 readable" representation of the nonnegative integer D to BUF using
24203 a minimal field width WIDTH. D should be smaller than 999.5e24. */
24205 static const char power_letter[] =
24207 0, /* no letter */
24208 'k', /* kilo */
24209 'M', /* mega */
24210 'G', /* giga */
24211 'T', /* tera */
24212 'P', /* peta */
24213 'E', /* exa */
24214 'Z', /* zetta */
24215 'Y' /* yotta */
24218 static void
24219 pint2hrstr (char *buf, int width, ptrdiff_t d)
24221 /* We aim to represent the nonnegative integer D as
24222 QUOTIENT.TENTHS * 10 ^ (3 * EXPONENT). */
24223 ptrdiff_t quotient = d;
24224 int remainder = 0;
24225 /* -1 means: do not use TENTHS. */
24226 int tenths = -1;
24227 int exponent = 0;
24229 /* Length of QUOTIENT.TENTHS as a string. */
24230 int length;
24232 char * psuffix;
24233 char * p;
24235 if (quotient >= 1000)
24237 /* Scale to the appropriate EXPONENT. */
24240 remainder = quotient % 1000;
24241 quotient /= 1000;
24242 exponent++;
24244 while (quotient >= 1000);
24246 /* Round to nearest and decide whether to use TENTHS or not. */
24247 if (quotient <= 9)
24249 tenths = remainder / 100;
24250 if (remainder % 100 >= 50)
24252 if (tenths < 9)
24253 tenths++;
24254 else
24256 quotient++;
24257 if (quotient == 10)
24258 tenths = -1;
24259 else
24260 tenths = 0;
24264 else
24265 if (remainder >= 500)
24267 if (quotient < 999)
24268 quotient++;
24269 else
24271 quotient = 1;
24272 exponent++;
24273 tenths = 0;
24278 /* Calculate the LENGTH of QUOTIENT.TENTHS as a string. */
24279 if (tenths == -1 && quotient <= 99)
24280 if (quotient <= 9)
24281 length = 1;
24282 else
24283 length = 2;
24284 else
24285 length = 3;
24286 p = psuffix = buf + max (width, length);
24288 /* Print EXPONENT. */
24289 *psuffix++ = power_letter[exponent];
24290 *psuffix = '\0';
24292 /* Print TENTHS. */
24293 if (tenths >= 0)
24295 *--p = '0' + tenths;
24296 *--p = '.';
24299 /* Print QUOTIENT. */
24302 int digit = quotient % 10;
24303 *--p = '0' + digit;
24305 while ((quotient /= 10) != 0);
24307 /* Print leading spaces. */
24308 while (buf < p)
24309 *--p = ' ';
24312 /* Set a mnemonic character for coding_system (Lisp symbol) in BUF.
24313 If EOL_FLAG, set also a mnemonic character for end-of-line
24314 type of CODING_SYSTEM. Return updated pointer into BUF. */
24316 static unsigned char invalid_eol_type[] = "(*invalid*)";
24318 static char *
24319 decode_mode_spec_coding (Lisp_Object coding_system, char *buf, bool eol_flag)
24321 Lisp_Object val;
24322 bool multibyte = !NILP (BVAR (current_buffer, enable_multibyte_characters));
24323 const unsigned char *eol_str;
24324 int eol_str_len;
24325 /* The EOL conversion we are using. */
24326 Lisp_Object eoltype;
24328 val = CODING_SYSTEM_SPEC (coding_system);
24329 eoltype = Qnil;
24331 if (!VECTORP (val)) /* Not yet decided. */
24333 *buf++ = multibyte ? '-' : ' ';
24334 if (eol_flag)
24335 eoltype = eol_mnemonic_undecided;
24336 /* Don't mention EOL conversion if it isn't decided. */
24338 else
24340 Lisp_Object attrs;
24341 Lisp_Object eolvalue;
24343 attrs = AREF (val, 0);
24344 eolvalue = AREF (val, 2);
24346 *buf++ = multibyte
24347 ? XFASTINT (CODING_ATTR_MNEMONIC (attrs))
24348 : ' ';
24350 if (eol_flag)
24352 /* The EOL conversion that is normal on this system. */
24354 if (NILP (eolvalue)) /* Not yet decided. */
24355 eoltype = eol_mnemonic_undecided;
24356 else if (VECTORP (eolvalue)) /* Not yet decided. */
24357 eoltype = eol_mnemonic_undecided;
24358 else /* eolvalue is Qunix, Qdos, or Qmac. */
24359 eoltype = (EQ (eolvalue, Qunix)
24360 ? eol_mnemonic_unix
24361 : EQ (eolvalue, Qdos)
24362 ? eol_mnemonic_dos : eol_mnemonic_mac);
24366 if (eol_flag)
24368 /* Mention the EOL conversion if it is not the usual one. */
24369 if (STRINGP (eoltype))
24371 eol_str = SDATA (eoltype);
24372 eol_str_len = SBYTES (eoltype);
24374 else if (CHARACTERP (eoltype))
24376 int c = XFASTINT (eoltype);
24377 return buf + CHAR_STRING (c, (unsigned char *) buf);
24379 else
24381 eol_str = invalid_eol_type;
24382 eol_str_len = sizeof (invalid_eol_type) - 1;
24384 memcpy (buf, eol_str, eol_str_len);
24385 buf += eol_str_len;
24388 return buf;
24391 /* Return the approximate percentage N is of D (rounding upward), or 99,
24392 whichever is less. Assume 0 < D and 0 <= N <= D * INT_MAX / 100. */
24394 static int
24395 percent99 (ptrdiff_t n, ptrdiff_t d)
24397 int percent = (d - 1 + 100.0 * n) / d;
24398 return min (percent, 99);
24401 /* Return a string for the output of a mode line %-spec for window W,
24402 generated by character C. FIELD_WIDTH > 0 means pad the string
24403 returned with spaces to that value. Return a Lisp string in
24404 *STRING if the resulting string is taken from that Lisp string.
24406 Note we operate on the current buffer for most purposes. */
24408 static char lots_of_dashes[] = "--------------------------------------------------------------------------------------------------------------------------------------------";
24410 static const char *
24411 decode_mode_spec (struct window *w, register int c, int field_width,
24412 Lisp_Object *string)
24414 Lisp_Object obj;
24415 struct frame *f = XFRAME (WINDOW_FRAME (w));
24416 char *decode_mode_spec_buf = f->decode_mode_spec_buffer;
24417 /* We are going to use f->decode_mode_spec_buffer as the buffer to
24418 produce strings from numerical values, so limit preposterously
24419 large values of FIELD_WIDTH to avoid overrunning the buffer's
24420 end. The size of the buffer is enough for FRAME_MESSAGE_BUF_SIZE
24421 bytes plus the terminating null. */
24422 int width = min (field_width, FRAME_MESSAGE_BUF_SIZE (f));
24423 struct buffer *b = current_buffer;
24425 obj = Qnil;
24426 *string = Qnil;
24428 switch (c)
24430 case '*':
24431 if (!NILP (BVAR (b, read_only)))
24432 return "%";
24433 if (BUF_MODIFF (b) > BUF_SAVE_MODIFF (b))
24434 return "*";
24435 return "-";
24437 case '+':
24438 /* This differs from %* only for a modified read-only buffer. */
24439 if (BUF_MODIFF (b) > BUF_SAVE_MODIFF (b))
24440 return "*";
24441 if (!NILP (BVAR (b, read_only)))
24442 return "%";
24443 return "-";
24445 case '&':
24446 /* This differs from %* in ignoring read-only-ness. */
24447 if (BUF_MODIFF (b) > BUF_SAVE_MODIFF (b))
24448 return "*";
24449 return "-";
24451 case '%':
24452 return "%";
24454 case '[':
24456 int i;
24457 char *p;
24459 if (command_loop_level > 5)
24460 return "[[[... ";
24461 p = decode_mode_spec_buf;
24462 for (i = 0; i < command_loop_level; i++)
24463 *p++ = '[';
24464 *p = 0;
24465 return decode_mode_spec_buf;
24468 case ']':
24470 int i;
24471 char *p;
24473 if (command_loop_level > 5)
24474 return " ...]]]";
24475 p = decode_mode_spec_buf;
24476 for (i = 0; i < command_loop_level; i++)
24477 *p++ = ']';
24478 *p = 0;
24479 return decode_mode_spec_buf;
24482 case '-':
24484 register int i;
24486 /* Let lots_of_dashes be a string of infinite length. */
24487 if (mode_line_target == MODE_LINE_NOPROP
24488 || mode_line_target == MODE_LINE_STRING)
24489 return "--";
24490 if (field_width <= 0
24491 || field_width > sizeof (lots_of_dashes))
24493 for (i = 0; i < FRAME_MESSAGE_BUF_SIZE (f) - 1; ++i)
24494 decode_mode_spec_buf[i] = '-';
24495 decode_mode_spec_buf[i] = '\0';
24496 return decode_mode_spec_buf;
24498 else
24499 return lots_of_dashes;
24502 case 'b':
24503 obj = BVAR (b, name);
24504 break;
24506 case 'c':
24507 case 'C':
24508 /* %c, %C, and %l are ignored in `frame-title-format'.
24509 (In redisplay_internal, the frame title is drawn _before_ the
24510 windows are updated, so the stuff which depends on actual
24511 window contents (such as %l) may fail to render properly, or
24512 even crash emacs.) */
24513 if (mode_line_target == MODE_LINE_TITLE)
24514 return "";
24515 else
24517 ptrdiff_t col = current_column ();
24518 int disp_col = (c == 'C') ? col + 1 : col;
24519 w->column_number_displayed = col;
24520 pint2str (decode_mode_spec_buf, width, disp_col);
24521 return decode_mode_spec_buf;
24524 case 'e':
24525 #if !defined SYSTEM_MALLOC && !defined HYBRID_MALLOC
24527 if (NILP (Vmemory_full))
24528 return "";
24529 else
24530 return "!MEM FULL! ";
24532 #else
24533 return "";
24534 #endif
24536 case 'F':
24537 /* %F displays the frame name. */
24538 if (!NILP (f->title))
24539 return SSDATA (f->title);
24540 if (f->explicit_name || ! FRAME_WINDOW_P (f))
24541 return SSDATA (f->name);
24542 return "Emacs";
24544 case 'f':
24545 obj = BVAR (b, filename);
24546 break;
24548 case 'i':
24550 ptrdiff_t size = ZV - BEGV;
24551 pint2str (decode_mode_spec_buf, width, size);
24552 return decode_mode_spec_buf;
24555 case 'I':
24557 ptrdiff_t size = ZV - BEGV;
24558 pint2hrstr (decode_mode_spec_buf, width, size);
24559 return decode_mode_spec_buf;
24562 case 'l':
24564 ptrdiff_t startpos, startpos_byte, line, linepos, linepos_byte;
24565 ptrdiff_t topline, nlines, height;
24566 ptrdiff_t junk;
24568 /* %c, %C, and %l are ignored in `frame-title-format'. */
24569 if (mode_line_target == MODE_LINE_TITLE)
24570 return "";
24572 startpos = marker_position (w->start);
24573 startpos_byte = marker_byte_position (w->start);
24574 height = WINDOW_TOTAL_LINES (w);
24576 /* If we decided that this buffer isn't suitable for line numbers,
24577 don't forget that too fast. */
24578 if (w->base_line_pos == -1)
24579 goto no_value;
24581 /* If the buffer is very big, don't waste time. */
24582 if (INTEGERP (Vline_number_display_limit)
24583 && BUF_ZV (b) - BUF_BEGV (b) > XINT (Vline_number_display_limit))
24585 w->base_line_pos = 0;
24586 w->base_line_number = 0;
24587 goto no_value;
24590 if (w->base_line_number > 0
24591 && w->base_line_pos > 0
24592 && w->base_line_pos <= startpos)
24594 line = w->base_line_number;
24595 linepos = w->base_line_pos;
24596 linepos_byte = buf_charpos_to_bytepos (b, linepos);
24598 else
24600 line = 1;
24601 linepos = BUF_BEGV (b);
24602 linepos_byte = BUF_BEGV_BYTE (b);
24605 /* Count lines from base line to window start position. */
24606 nlines = display_count_lines (linepos_byte,
24607 startpos_byte,
24608 startpos, &junk);
24610 topline = nlines + line;
24612 /* Determine a new base line, if the old one is too close
24613 or too far away, or if we did not have one.
24614 "Too close" means it's plausible a scroll-down would
24615 go back past it. */
24616 if (startpos == BUF_BEGV (b))
24618 w->base_line_number = topline;
24619 w->base_line_pos = BUF_BEGV (b);
24621 else if (nlines < height + 25 || nlines > height * 3 + 50
24622 || linepos == BUF_BEGV (b))
24624 ptrdiff_t limit = BUF_BEGV (b);
24625 ptrdiff_t limit_byte = BUF_BEGV_BYTE (b);
24626 ptrdiff_t position;
24627 ptrdiff_t distance =
24628 (height * 2 + 30) * line_number_display_limit_width;
24630 if (startpos - distance > limit)
24632 limit = startpos - distance;
24633 limit_byte = CHAR_TO_BYTE (limit);
24636 nlines = display_count_lines (startpos_byte,
24637 limit_byte,
24638 - (height * 2 + 30),
24639 &position);
24640 /* If we couldn't find the lines we wanted within
24641 line_number_display_limit_width chars per line,
24642 give up on line numbers for this window. */
24643 if (position == limit_byte && limit == startpos - distance)
24645 w->base_line_pos = -1;
24646 w->base_line_number = 0;
24647 goto no_value;
24650 w->base_line_number = topline - nlines;
24651 w->base_line_pos = BYTE_TO_CHAR (position);
24654 /* Now count lines from the start pos to point. */
24655 nlines = display_count_lines (startpos_byte,
24656 PT_BYTE, PT, &junk);
24658 /* Record that we did display the line number. */
24659 line_number_displayed = true;
24661 /* Make the string to show. */
24662 pint2str (decode_mode_spec_buf, width, topline + nlines);
24663 return decode_mode_spec_buf;
24664 no_value:
24666 char *p = decode_mode_spec_buf;
24667 int pad = width - 2;
24668 while (pad-- > 0)
24669 *p++ = ' ';
24670 *p++ = '?';
24671 *p++ = '?';
24672 *p = '\0';
24673 return decode_mode_spec_buf;
24676 break;
24678 case 'm':
24679 obj = BVAR (b, mode_name);
24680 break;
24682 case 'n':
24683 if (BUF_BEGV (b) > BUF_BEG (b) || BUF_ZV (b) < BUF_Z (b))
24684 return " Narrow";
24685 break;
24687 /* Display the "degree of travel" of the window through the buffer. */
24688 case 'o':
24690 ptrdiff_t toppos = marker_position (w->start);
24691 ptrdiff_t botpos = BUF_Z (b) - w->window_end_pos;
24692 ptrdiff_t begv = BUF_BEGV (b);
24693 ptrdiff_t zv = BUF_ZV (b);
24695 if (zv <= botpos)
24696 return toppos <= begv ? "All" : "Bottom";
24697 else if (toppos <= begv)
24698 return "Top";
24699 else
24701 sprintf (decode_mode_spec_buf, "%2d%%",
24702 percent99 (toppos - begv, (toppos - begv) + (zv - botpos)));
24703 return decode_mode_spec_buf;
24707 /* Display percentage of buffer above the top of the screen. */
24708 case 'p':
24710 ptrdiff_t pos = marker_position (w->start);
24711 ptrdiff_t begv = BUF_BEGV (b);
24712 ptrdiff_t zv = BUF_ZV (b);
24714 if (w->window_end_pos <= BUF_Z (b) - zv)
24715 return pos <= begv ? "All" : "Bottom";
24716 else if (pos <= begv)
24717 return "Top";
24718 else
24720 sprintf (decode_mode_spec_buf, "%2d%%",
24721 percent99 (pos - begv, zv - begv));
24722 return decode_mode_spec_buf;
24726 /* Display percentage of size above the bottom of the screen. */
24727 case 'P':
24729 ptrdiff_t toppos = marker_position (w->start);
24730 ptrdiff_t botpos = BUF_Z (b) - w->window_end_pos;
24731 ptrdiff_t begv = BUF_BEGV (b);
24732 ptrdiff_t zv = BUF_ZV (b);
24734 if (zv <= botpos)
24735 return toppos <= begv ? "All" : "Bottom";
24736 else
24738 sprintf (decode_mode_spec_buf,
24739 &"Top%2d%%"[begv < toppos ? sizeof "Top" - 1 : 0],
24740 percent99 (botpos - begv, zv - begv));
24741 return decode_mode_spec_buf;
24745 /* Display percentage offsets of top and bottom of the window,
24746 using "All" (but not "Top" or "Bottom") where appropriate. */
24747 case 'q':
24749 ptrdiff_t toppos = marker_position (w->start);
24750 ptrdiff_t botpos = BUF_Z (b) - w->window_end_pos;
24751 ptrdiff_t begv = BUF_BEGV (b);
24752 ptrdiff_t zv = BUF_ZV (b);
24753 int top_perc, bot_perc;
24755 if ((toppos <= begv) && (zv <= botpos))
24756 return "All ";
24758 top_perc = toppos <= begv ? 0 : percent99 (toppos - begv, zv - begv);
24759 bot_perc = zv <= botpos ? 100 : percent99 (botpos - begv, zv - begv);
24761 if (top_perc == bot_perc)
24762 sprintf (decode_mode_spec_buf, "%d%%", top_perc);
24763 else
24764 sprintf (decode_mode_spec_buf, "%d-%d%%", top_perc, bot_perc);
24766 return decode_mode_spec_buf;
24769 case 's':
24770 /* status of process */
24771 obj = Fget_buffer_process (Fcurrent_buffer ());
24772 if (NILP (obj))
24773 return "no process";
24774 #ifndef MSDOS
24775 obj = Fsymbol_name (Fprocess_status (obj));
24776 #endif
24777 break;
24779 case '@':
24781 ptrdiff_t count = inhibit_garbage_collection ();
24782 Lisp_Object curdir = BVAR (current_buffer, directory);
24783 Lisp_Object val = Qnil;
24785 if (STRINGP (curdir))
24786 val = call1 (intern ("file-remote-p"), curdir);
24788 unbind_to (count, Qnil);
24790 if (NILP (val))
24791 return "-";
24792 else
24793 return "@";
24796 case 'z':
24797 /* coding-system (not including end-of-line format) */
24798 case 'Z':
24799 /* coding-system (including end-of-line type) */
24801 bool eol_flag = (c == 'Z');
24802 char *p = decode_mode_spec_buf;
24804 if (! FRAME_WINDOW_P (f))
24806 /* No need to mention EOL here--the terminal never needs
24807 to do EOL conversion. */
24808 p = decode_mode_spec_coding (CODING_ID_NAME
24809 (FRAME_KEYBOARD_CODING (f)->id),
24810 p, false);
24811 p = decode_mode_spec_coding (CODING_ID_NAME
24812 (FRAME_TERMINAL_CODING (f)->id),
24813 p, false);
24815 p = decode_mode_spec_coding (BVAR (b, buffer_file_coding_system),
24816 p, eol_flag);
24818 #if false /* This proves to be annoying; I think we can do without. -- rms. */
24819 #ifdef subprocesses
24820 obj = Fget_buffer_process (Fcurrent_buffer ());
24821 if (PROCESSP (obj))
24823 p = decode_mode_spec_coding
24824 (XPROCESS (obj)->decode_coding_system, p, eol_flag);
24825 p = decode_mode_spec_coding
24826 (XPROCESS (obj)->encode_coding_system, p, eol_flag);
24828 #endif /* subprocesses */
24829 #endif /* false */
24830 *p = 0;
24831 return decode_mode_spec_buf;
24835 if (STRINGP (obj))
24837 *string = obj;
24838 return SSDATA (obj);
24840 else
24841 return "";
24845 /* Count up to COUNT lines starting from START_BYTE. COUNT negative
24846 means count lines back from START_BYTE. But don't go beyond
24847 LIMIT_BYTE. Return the number of lines thus found (always
24848 nonnegative).
24850 Set *BYTE_POS_PTR to the byte position where we stopped. This is
24851 either the position COUNT lines after/before START_BYTE, if we
24852 found COUNT lines, or LIMIT_BYTE if we hit the limit before finding
24853 COUNT lines. */
24855 static ptrdiff_t
24856 display_count_lines (ptrdiff_t start_byte,
24857 ptrdiff_t limit_byte, ptrdiff_t count,
24858 ptrdiff_t *byte_pos_ptr)
24860 register unsigned char *cursor;
24861 unsigned char *base;
24863 register ptrdiff_t ceiling;
24864 register unsigned char *ceiling_addr;
24865 ptrdiff_t orig_count = count;
24867 /* If we are not in selective display mode,
24868 check only for newlines. */
24869 bool selective_display
24870 = (!NILP (BVAR (current_buffer, selective_display))
24871 && !INTEGERP (BVAR (current_buffer, selective_display)));
24873 if (count > 0)
24875 while (start_byte < limit_byte)
24877 ceiling = BUFFER_CEILING_OF (start_byte);
24878 ceiling = min (limit_byte - 1, ceiling);
24879 ceiling_addr = BYTE_POS_ADDR (ceiling) + 1;
24880 base = (cursor = BYTE_POS_ADDR (start_byte));
24884 if (selective_display)
24886 while (*cursor != '\n' && *cursor != 015
24887 && ++cursor != ceiling_addr)
24888 continue;
24889 if (cursor == ceiling_addr)
24890 break;
24892 else
24894 cursor = memchr (cursor, '\n', ceiling_addr - cursor);
24895 if (! cursor)
24896 break;
24899 cursor++;
24901 if (--count == 0)
24903 start_byte += cursor - base;
24904 *byte_pos_ptr = start_byte;
24905 return orig_count;
24908 while (cursor < ceiling_addr);
24910 start_byte += ceiling_addr - base;
24913 else
24915 while (start_byte > limit_byte)
24917 ceiling = BUFFER_FLOOR_OF (start_byte - 1);
24918 ceiling = max (limit_byte, ceiling);
24919 ceiling_addr = BYTE_POS_ADDR (ceiling);
24920 base = (cursor = BYTE_POS_ADDR (start_byte - 1) + 1);
24921 while (true)
24923 if (selective_display)
24925 while (--cursor >= ceiling_addr
24926 && *cursor != '\n' && *cursor != 015)
24927 continue;
24928 if (cursor < ceiling_addr)
24929 break;
24931 else
24933 cursor = memrchr (ceiling_addr, '\n', cursor - ceiling_addr);
24934 if (! cursor)
24935 break;
24938 if (++count == 0)
24940 start_byte += cursor - base + 1;
24941 *byte_pos_ptr = start_byte;
24942 /* When scanning backwards, we should
24943 not count the newline posterior to which we stop. */
24944 return - orig_count - 1;
24947 start_byte += ceiling_addr - base;
24951 *byte_pos_ptr = limit_byte;
24953 if (count < 0)
24954 return - orig_count + count;
24955 return orig_count - count;
24961 /***********************************************************************
24962 Displaying strings
24963 ***********************************************************************/
24965 /* Display a NUL-terminated string, starting with index START.
24967 If STRING is non-null, display that C string. Otherwise, the Lisp
24968 string LISP_STRING is displayed. There's a case that STRING is
24969 non-null and LISP_STRING is not nil. It means STRING is a string
24970 data of LISP_STRING. In that case, we display LISP_STRING while
24971 ignoring its text properties.
24973 If FACE_STRING is not nil, FACE_STRING_POS is a position in
24974 FACE_STRING. Display STRING or LISP_STRING with the face at
24975 FACE_STRING_POS in FACE_STRING:
24977 Display the string in the environment given by IT, but use the
24978 standard display table, temporarily.
24980 FIELD_WIDTH is the minimum number of output glyphs to produce.
24981 If STRING has fewer characters than FIELD_WIDTH, pad to the right
24982 with spaces. If STRING has more characters, more than FIELD_WIDTH
24983 glyphs will be produced. FIELD_WIDTH <= 0 means don't pad.
24985 PRECISION is the maximum number of characters to output from
24986 STRING. PRECISION < 0 means don't truncate the string.
24988 This is roughly equivalent to printf format specifiers:
24990 FIELD_WIDTH PRECISION PRINTF
24991 ----------------------------------------
24992 -1 -1 %s
24993 -1 10 %.10s
24994 10 -1 %10s
24995 20 10 %20.10s
24997 MULTIBYTE zero means do not display multibyte chars, > 0 means do
24998 display them, and < 0 means obey the current buffer's value of
24999 enable_multibyte_characters.
25001 Value is the number of columns displayed. */
25003 static int
25004 display_string (const char *string, Lisp_Object lisp_string, Lisp_Object face_string,
25005 ptrdiff_t face_string_pos, ptrdiff_t start, struct it *it,
25006 int field_width, int precision, int max_x, int multibyte)
25008 int hpos_at_start = it->hpos;
25009 int saved_face_id = it->face_id;
25010 struct glyph_row *row = it->glyph_row;
25011 ptrdiff_t it_charpos;
25013 /* Initialize the iterator IT for iteration over STRING beginning
25014 with index START. */
25015 reseat_to_string (it, NILP (lisp_string) ? string : NULL, lisp_string, start,
25016 precision, field_width, multibyte);
25017 if (string && STRINGP (lisp_string))
25018 /* LISP_STRING is the one returned by decode_mode_spec. We should
25019 ignore its text properties. */
25020 it->stop_charpos = it->end_charpos;
25022 /* If displaying STRING, set up the face of the iterator from
25023 FACE_STRING, if that's given. */
25024 if (STRINGP (face_string))
25026 ptrdiff_t endptr;
25027 struct face *face;
25029 it->face_id
25030 = face_at_string_position (it->w, face_string, face_string_pos,
25031 0, &endptr, it->base_face_id, false);
25032 face = FACE_FROM_ID (it->f, it->face_id);
25033 it->face_box_p = face->box != FACE_NO_BOX;
25036 /* Set max_x to the maximum allowed X position. Don't let it go
25037 beyond the right edge of the window. */
25038 if (max_x <= 0)
25039 max_x = it->last_visible_x;
25040 else
25041 max_x = min (max_x, it->last_visible_x);
25043 /* Skip over display elements that are not visible. because IT->w is
25044 hscrolled. */
25045 if (it->current_x < it->first_visible_x)
25046 move_it_in_display_line_to (it, 100000, it->first_visible_x,
25047 MOVE_TO_POS | MOVE_TO_X);
25049 row->ascent = it->max_ascent;
25050 row->height = it->max_ascent + it->max_descent;
25051 row->phys_ascent = it->max_phys_ascent;
25052 row->phys_height = it->max_phys_ascent + it->max_phys_descent;
25053 row->extra_line_spacing = it->max_extra_line_spacing;
25055 if (STRINGP (it->string))
25056 it_charpos = IT_STRING_CHARPOS (*it);
25057 else
25058 it_charpos = IT_CHARPOS (*it);
25060 /* This condition is for the case that we are called with current_x
25061 past last_visible_x. */
25062 while (it->current_x < max_x)
25064 int x_before, x, n_glyphs_before, i, nglyphs;
25066 /* Get the next display element. */
25067 if (!get_next_display_element (it))
25068 break;
25070 /* Produce glyphs. */
25071 x_before = it->current_x;
25072 n_glyphs_before = row->used[TEXT_AREA];
25073 PRODUCE_GLYPHS (it);
25075 nglyphs = row->used[TEXT_AREA] - n_glyphs_before;
25076 i = 0;
25077 x = x_before;
25078 while (i < nglyphs)
25080 struct glyph *glyph = row->glyphs[TEXT_AREA] + n_glyphs_before + i;
25082 if (it->line_wrap != TRUNCATE
25083 && x + glyph->pixel_width > max_x)
25085 /* End of continued line or max_x reached. */
25086 if (CHAR_GLYPH_PADDING_P (*glyph))
25088 /* A wide character is unbreakable. */
25089 if (row->reversed_p)
25090 unproduce_glyphs (it, row->used[TEXT_AREA]
25091 - n_glyphs_before);
25092 row->used[TEXT_AREA] = n_glyphs_before;
25093 it->current_x = x_before;
25095 else
25097 if (row->reversed_p)
25098 unproduce_glyphs (it, row->used[TEXT_AREA]
25099 - (n_glyphs_before + i));
25100 row->used[TEXT_AREA] = n_glyphs_before + i;
25101 it->current_x = x;
25103 break;
25105 else if (x + glyph->pixel_width >= it->first_visible_x)
25107 /* Glyph is at least partially visible. */
25108 ++it->hpos;
25109 if (x < it->first_visible_x)
25110 row->x = x - it->first_visible_x;
25112 else
25114 /* Glyph is off the left margin of the display area.
25115 Should not happen. */
25116 emacs_abort ();
25119 row->ascent = max (row->ascent, it->max_ascent);
25120 row->height = max (row->height, it->max_ascent + it->max_descent);
25121 row->phys_ascent = max (row->phys_ascent, it->max_phys_ascent);
25122 row->phys_height = max (row->phys_height,
25123 it->max_phys_ascent + it->max_phys_descent);
25124 row->extra_line_spacing = max (row->extra_line_spacing,
25125 it->max_extra_line_spacing);
25126 x += glyph->pixel_width;
25127 ++i;
25130 /* Stop if max_x reached. */
25131 if (i < nglyphs)
25132 break;
25134 /* Stop at line ends. */
25135 if (ITERATOR_AT_END_OF_LINE_P (it))
25137 it->continuation_lines_width = 0;
25138 break;
25141 set_iterator_to_next (it, true);
25142 if (STRINGP (it->string))
25143 it_charpos = IT_STRING_CHARPOS (*it);
25144 else
25145 it_charpos = IT_CHARPOS (*it);
25147 /* Stop if truncating at the right edge. */
25148 if (it->line_wrap == TRUNCATE
25149 && it->current_x >= it->last_visible_x)
25151 /* Add truncation mark, but don't do it if the line is
25152 truncated at a padding space. */
25153 if (it_charpos < it->string_nchars)
25155 if (!FRAME_WINDOW_P (it->f))
25157 int ii, n;
25159 if (it->current_x > it->last_visible_x)
25161 if (!row->reversed_p)
25163 for (ii = row->used[TEXT_AREA] - 1; ii > 0; --ii)
25164 if (!CHAR_GLYPH_PADDING_P (row->glyphs[TEXT_AREA][ii]))
25165 break;
25167 else
25169 for (ii = 0; ii < row->used[TEXT_AREA]; ii++)
25170 if (!CHAR_GLYPH_PADDING_P (row->glyphs[TEXT_AREA][ii]))
25171 break;
25172 unproduce_glyphs (it, ii + 1);
25173 ii = row->used[TEXT_AREA] - (ii + 1);
25175 for (n = row->used[TEXT_AREA]; ii < n; ++ii)
25177 row->used[TEXT_AREA] = ii;
25178 produce_special_glyphs (it, IT_TRUNCATION);
25181 produce_special_glyphs (it, IT_TRUNCATION);
25183 row->truncated_on_right_p = true;
25185 break;
25189 /* Maybe insert a truncation at the left. */
25190 if (it->first_visible_x
25191 && it_charpos > 0)
25193 if (!FRAME_WINDOW_P (it->f)
25194 || (row->reversed_p
25195 ? WINDOW_RIGHT_FRINGE_WIDTH (it->w)
25196 : WINDOW_LEFT_FRINGE_WIDTH (it->w)) == 0)
25197 insert_left_trunc_glyphs (it);
25198 row->truncated_on_left_p = true;
25201 it->face_id = saved_face_id;
25203 /* Value is number of columns displayed. */
25204 return it->hpos - hpos_at_start;
25209 /* This is like a combination of memq and assq. Return 1/2 if PROPVAL
25210 appears as an element of LIST or as the car of an element of LIST.
25211 If PROPVAL is a list, compare each element against LIST in that
25212 way, and return 1/2 if any element of PROPVAL is found in LIST.
25213 Otherwise return 0. This function cannot quit.
25214 The return value is 2 if the text is invisible but with an ellipsis
25215 and 1 if it's invisible and without an ellipsis. */
25218 invisible_prop (Lisp_Object propval, Lisp_Object list)
25220 Lisp_Object tail, proptail;
25222 for (tail = list; CONSP (tail); tail = XCDR (tail))
25224 register Lisp_Object tem;
25225 tem = XCAR (tail);
25226 if (EQ (propval, tem))
25227 return 1;
25228 if (CONSP (tem) && EQ (propval, XCAR (tem)))
25229 return NILP (XCDR (tem)) ? 1 : 2;
25232 if (CONSP (propval))
25234 for (proptail = propval; CONSP (proptail); proptail = XCDR (proptail))
25236 Lisp_Object propelt;
25237 propelt = XCAR (proptail);
25238 for (tail = list; CONSP (tail); tail = XCDR (tail))
25240 register Lisp_Object tem;
25241 tem = XCAR (tail);
25242 if (EQ (propelt, tem))
25243 return 1;
25244 if (CONSP (tem) && EQ (propelt, XCAR (tem)))
25245 return NILP (XCDR (tem)) ? 1 : 2;
25250 return 0;
25253 DEFUN ("invisible-p", Finvisible_p, Sinvisible_p, 1, 1, 0,
25254 doc: /* Non-nil if text properties at POS cause text there to be currently invisible.
25255 POS should be a marker or a buffer position; the value of the `invisible'
25256 property at that position in the current buffer is examined.
25257 POS can also be the actual value of the `invisible' text or overlay
25258 property of the text of interest, in which case the value itself is
25259 examined.
25261 The non-nil value returned can be t for currently invisible text that is
25262 entirely hidden on display, or some other non-nil, non-t value if the
25263 text is replaced by an ellipsis.
25265 Note that whether text with `invisible' property is actually hidden on
25266 display may depend on `buffer-invisibility-spec', which see. */)
25267 (Lisp_Object pos)
25269 Lisp_Object prop
25270 = (NATNUMP (pos) || MARKERP (pos)
25271 ? Fget_char_property (pos, Qinvisible, Qnil)
25272 : pos);
25273 int invis = TEXT_PROP_MEANS_INVISIBLE (prop);
25274 return (invis == 0 ? Qnil
25275 : invis == 1 ? Qt
25276 : make_number (invis));
25279 /* Calculate a width or height in pixels from a specification using
25280 the following elements:
25282 SPEC ::=
25283 NUM - a (fractional) multiple of the default font width/height
25284 (NUM) - specifies exactly NUM pixels
25285 UNIT - a fixed number of pixels, see below.
25286 ELEMENT - size of a display element in pixels, see below.
25287 (NUM . SPEC) - equals NUM * SPEC
25288 (+ SPEC SPEC ...) - add pixel values
25289 (- SPEC SPEC ...) - subtract pixel values
25290 (- SPEC) - negate pixel value
25292 NUM ::=
25293 INT or FLOAT - a number constant
25294 SYMBOL - use symbol's (buffer local) variable binding.
25296 UNIT ::=
25297 in - pixels per inch *)
25298 mm - pixels per 1/1000 meter *)
25299 cm - pixels per 1/100 meter *)
25300 width - width of current font in pixels.
25301 height - height of current font in pixels.
25303 *) using the ratio(s) defined in display-pixels-per-inch.
25305 ELEMENT ::=
25307 left-fringe - left fringe width in pixels
25308 right-fringe - right fringe width in pixels
25310 left-margin - left margin width in pixels
25311 right-margin - right margin width in pixels
25313 scroll-bar - scroll-bar area width in pixels
25315 Examples:
25317 Pixels corresponding to 5 inches:
25318 (5 . in)
25320 Total width of non-text areas on left side of window (if scroll-bar is on left):
25321 '(space :width (+ left-fringe left-margin scroll-bar))
25323 Align to first text column (in header line):
25324 '(space :align-to 0)
25326 Align to middle of text area minus half the width of variable `my-image'
25327 containing a loaded image:
25328 '(space :align-to (0.5 . (- text my-image)))
25330 Width of left margin minus width of 1 character in the default font:
25331 '(space :width (- left-margin 1))
25333 Width of left margin minus width of 2 characters in the current font:
25334 '(space :width (- left-margin (2 . width)))
25336 Center 1 character over left-margin (in header line):
25337 '(space :align-to (+ left-margin (0.5 . left-margin) -0.5))
25339 Different ways to express width of left fringe plus left margin minus one pixel:
25340 '(space :width (- (+ left-fringe left-margin) (1)))
25341 '(space :width (+ left-fringe left-margin (- (1))))
25342 '(space :width (+ left-fringe left-margin (-1)))
25344 If ALIGN_TO is NULL, returns the result in *RES. If ALIGN_TO is
25345 non-NULL, the value of *ALIGN_TO is a window-relative pixel
25346 coordinate, and *RES is the additional pixel width from that point
25347 till the end of the stretch glyph.
25349 WIDTH_P non-zero means take the width dimension or X coordinate of
25350 the object specified by PROP, WIDTH_P zero means take the height
25351 dimension or the Y coordinate. (Therefore, if ALIGN_TO is
25352 non-NULL, WIDTH_P should be non-zero.)
25354 FONT is the font of the face of the surrounding text.
25356 The return value is non-zero if width or height were successfully
25357 calculated, i.e. if PROP is a valid spec. */
25359 static bool
25360 calc_pixel_width_or_height (double *res, struct it *it, Lisp_Object prop,
25361 struct font *font, bool width_p, int *align_to)
25363 double pixels;
25365 # define OK_PIXELS(val) (*res = (val), true)
25366 # define OK_ALIGN_TO(val) (*align_to = (val), true)
25368 if (NILP (prop))
25369 return OK_PIXELS (0);
25371 eassert (FRAME_LIVE_P (it->f));
25373 if (SYMBOLP (prop))
25375 if (SCHARS (SYMBOL_NAME (prop)) == 2)
25377 char *unit = SSDATA (SYMBOL_NAME (prop));
25379 /* The UNIT expression, e.g. as part of (NUM . UNIT). */
25380 if (unit[0] == 'i' && unit[1] == 'n')
25381 pixels = 1.0;
25382 else if (unit[0] == 'm' && unit[1] == 'm')
25383 pixels = 25.4;
25384 else if (unit[0] == 'c' && unit[1] == 'm')
25385 pixels = 2.54;
25386 else
25387 pixels = 0;
25388 if (pixels > 0)
25390 double ppi = (width_p ? FRAME_RES_X (it->f)
25391 : FRAME_RES_Y (it->f));
25393 if (ppi > 0)
25394 return OK_PIXELS (ppi / pixels);
25395 return false;
25399 #ifdef HAVE_WINDOW_SYSTEM
25400 /* 'height': the height of FONT. */
25401 if (EQ (prop, Qheight))
25402 return OK_PIXELS (font
25403 ? normal_char_height (font, -1)
25404 : FRAME_LINE_HEIGHT (it->f));
25405 /* 'width': the width of FONT. */
25406 if (EQ (prop, Qwidth))
25407 return OK_PIXELS (font
25408 ? FONT_WIDTH (font)
25409 : FRAME_COLUMN_WIDTH (it->f));
25410 #else
25411 if (EQ (prop, Qheight) || EQ (prop, Qwidth))
25412 return OK_PIXELS (1);
25413 #endif
25415 /* 'text': the width or height of the text area. */
25416 if (EQ (prop, Qtext))
25417 return OK_PIXELS (width_p
25418 ? (window_box_width (it->w, TEXT_AREA)
25419 - it->lnum_pixel_width)
25420 : WINDOW_BOX_HEIGHT_NO_MODE_LINE (it->w));
25422 /* ':align_to'. First time we compute the value, window
25423 elements are interpreted as the position of the element's
25424 left edge. */
25425 if (align_to && *align_to < 0)
25427 *res = 0;
25428 /* 'left': left edge of the text area. */
25429 if (EQ (prop, Qleft))
25430 return OK_ALIGN_TO (window_box_left_offset (it->w, TEXT_AREA)
25431 + it->lnum_pixel_width);
25432 /* 'right': right edge of the text area. */
25433 if (EQ (prop, Qright))
25434 return OK_ALIGN_TO (window_box_right_offset (it->w, TEXT_AREA));
25435 /* 'center': the center of the text area. */
25436 if (EQ (prop, Qcenter))
25437 return OK_ALIGN_TO (window_box_left_offset (it->w, TEXT_AREA)
25438 + it->lnum_pixel_width
25439 + window_box_width (it->w, TEXT_AREA) / 2);
25440 /* 'left-fringe': left edge of the left fringe. */
25441 if (EQ (prop, Qleft_fringe))
25442 return OK_ALIGN_TO (WINDOW_HAS_FRINGES_OUTSIDE_MARGINS (it->w)
25443 ? WINDOW_LEFT_SCROLL_BAR_AREA_WIDTH (it->w)
25444 : window_box_right_offset (it->w, LEFT_MARGIN_AREA));
25445 /* 'right-fringe': left edge of the right fringe. */
25446 if (EQ (prop, Qright_fringe))
25447 return OK_ALIGN_TO (WINDOW_HAS_FRINGES_OUTSIDE_MARGINS (it->w)
25448 ? window_box_right_offset (it->w, RIGHT_MARGIN_AREA)
25449 : window_box_right_offset (it->w, TEXT_AREA));
25450 /* 'left-margin': left edge of the left display margin. */
25451 if (EQ (prop, Qleft_margin))
25452 return OK_ALIGN_TO (window_box_left_offset (it->w, LEFT_MARGIN_AREA));
25453 /* 'right-margin': left edge of the right display margin. */
25454 if (EQ (prop, Qright_margin))
25455 return OK_ALIGN_TO (window_box_left_offset (it->w, RIGHT_MARGIN_AREA));
25456 /* 'scroll-bar': left edge of the vertical scroll bar. */
25457 if (EQ (prop, Qscroll_bar))
25458 return OK_ALIGN_TO (WINDOW_HAS_VERTICAL_SCROLL_BAR_ON_LEFT (it->w)
25460 : (window_box_right_offset (it->w, RIGHT_MARGIN_AREA)
25461 + (WINDOW_HAS_FRINGES_OUTSIDE_MARGINS (it->w)
25462 ? WINDOW_RIGHT_FRINGE_WIDTH (it->w)
25463 : 0)));
25465 else
25467 /* Otherwise, the elements stand for their width. */
25468 if (EQ (prop, Qleft_fringe))
25469 return OK_PIXELS (WINDOW_LEFT_FRINGE_WIDTH (it->w));
25470 if (EQ (prop, Qright_fringe))
25471 return OK_PIXELS (WINDOW_RIGHT_FRINGE_WIDTH (it->w));
25472 if (EQ (prop, Qleft_margin))
25473 return OK_PIXELS (WINDOW_LEFT_MARGIN_WIDTH (it->w));
25474 if (EQ (prop, Qright_margin))
25475 return OK_PIXELS (WINDOW_RIGHT_MARGIN_WIDTH (it->w));
25476 if (EQ (prop, Qscroll_bar))
25477 return OK_PIXELS (WINDOW_SCROLL_BAR_AREA_WIDTH (it->w));
25480 prop = buffer_local_value (prop, it->w->contents);
25481 if (EQ (prop, Qunbound))
25482 prop = Qnil;
25485 if (NUMBERP (prop))
25487 int base_unit = (width_p
25488 ? FRAME_COLUMN_WIDTH (it->f)
25489 : FRAME_LINE_HEIGHT (it->f));
25490 if (width_p && align_to && *align_to < 0)
25491 return OK_PIXELS (XFLOATINT (prop) * base_unit + it->lnum_pixel_width);
25492 return OK_PIXELS (XFLOATINT (prop) * base_unit);
25495 if (CONSP (prop))
25497 Lisp_Object car = XCAR (prop);
25498 Lisp_Object cdr = XCDR (prop);
25500 if (SYMBOLP (car))
25502 #ifdef HAVE_WINDOW_SYSTEM
25503 /* '(image PROPS...)': width or height of the specified image. */
25504 if (FRAME_WINDOW_P (it->f)
25505 && valid_image_p (prop))
25507 ptrdiff_t id = lookup_image (it->f, prop);
25508 struct image *img = IMAGE_FROM_ID (it->f, id);
25510 return OK_PIXELS (width_p ? img->width : img->height);
25512 /* '(xwidget PROPS...)': dimensions of the specified xwidget. */
25513 if (FRAME_WINDOW_P (it->f) && valid_xwidget_spec_p (prop))
25515 /* TODO: Don't return dummy size. */
25516 return OK_PIXELS (100);
25518 #endif
25519 /* '(+ EXPR...)' or '(- EXPR...)' add or subtract
25520 recursively calculated values. */
25521 if (EQ (car, Qplus) || EQ (car, Qminus))
25523 bool first = true;
25524 double px;
25526 pixels = 0;
25527 while (CONSP (cdr))
25529 if (!calc_pixel_width_or_height (&px, it, XCAR (cdr),
25530 font, width_p, align_to))
25531 return false;
25532 if (first)
25533 pixels = (EQ (car, Qplus) ? px : -px), first = false;
25534 else
25535 pixels += px;
25536 cdr = XCDR (cdr);
25538 if (EQ (car, Qminus))
25539 pixels = -pixels;
25540 return OK_PIXELS (pixels);
25543 car = buffer_local_value (car, it->w->contents);
25544 if (EQ (car, Qunbound))
25545 car = Qnil;
25548 /* '(NUM)': absolute number of pixels. */
25549 if (NUMBERP (car))
25551 double fact;
25552 int offset =
25553 width_p && align_to && *align_to < 0 ? it->lnum_pixel_width : 0;
25554 pixels = XFLOATINT (car);
25555 if (NILP (cdr))
25556 return OK_PIXELS (pixels + offset);
25557 if (calc_pixel_width_or_height (&fact, it, cdr,
25558 font, width_p, align_to))
25559 return OK_PIXELS (pixels * fact + offset);
25560 return false;
25563 return false;
25566 return false;
25569 void
25570 get_font_ascent_descent (struct font *font, int *ascent, int *descent)
25572 #ifdef HAVE_WINDOW_SYSTEM
25573 normal_char_ascent_descent (font, -1, ascent, descent);
25574 #else
25575 *ascent = 1;
25576 *descent = 0;
25577 #endif
25581 /***********************************************************************
25582 Glyph Display
25583 ***********************************************************************/
25585 #ifdef HAVE_WINDOW_SYSTEM
25587 #ifdef GLYPH_DEBUG
25589 void
25590 dump_glyph_string (struct glyph_string *s)
25592 fprintf (stderr, "glyph string\n");
25593 fprintf (stderr, " x, y, w, h = %d, %d, %d, %d\n",
25594 s->x, s->y, s->width, s->height);
25595 fprintf (stderr, " ybase = %d\n", s->ybase);
25596 fprintf (stderr, " hl = %u\n", s->hl);
25597 fprintf (stderr, " left overhang = %d, right = %d\n",
25598 s->left_overhang, s->right_overhang);
25599 fprintf (stderr, " nchars = %d\n", s->nchars);
25600 fprintf (stderr, " extends to end of line = %d\n",
25601 s->extends_to_end_of_line_p);
25602 fprintf (stderr, " font height = %d\n", FONT_HEIGHT (s->font));
25603 fprintf (stderr, " bg width = %d\n", s->background_width);
25606 #endif /* GLYPH_DEBUG */
25608 /* Initialize glyph string S. CHAR2B is a suitably allocated vector
25609 of XChar2b structures for S; it can't be allocated in
25610 init_glyph_string because it must be allocated via `alloca'. W
25611 is the window on which S is drawn. ROW and AREA are the glyph row
25612 and area within the row from which S is constructed. START is the
25613 index of the first glyph structure covered by S. HL is a
25614 face-override for drawing S. */
25616 #ifdef HAVE_NTGUI
25617 #define OPTIONAL_HDC(hdc) HDC hdc,
25618 #define DECLARE_HDC(hdc) HDC hdc;
25619 #define ALLOCATE_HDC(hdc, f) hdc = get_frame_dc ((f))
25620 #define RELEASE_HDC(hdc, f) release_frame_dc ((f), (hdc))
25621 #endif
25623 #ifndef OPTIONAL_HDC
25624 #define OPTIONAL_HDC(hdc)
25625 #define DECLARE_HDC(hdc)
25626 #define ALLOCATE_HDC(hdc, f)
25627 #define RELEASE_HDC(hdc, f)
25628 #endif
25630 static void
25631 init_glyph_string (struct glyph_string *s,
25632 OPTIONAL_HDC (hdc)
25633 XChar2b *char2b, struct window *w, struct glyph_row *row,
25634 enum glyph_row_area area, int start, enum draw_glyphs_face hl)
25636 memset (s, 0, sizeof *s);
25637 s->w = w;
25638 s->f = XFRAME (w->frame);
25639 #ifdef HAVE_NTGUI
25640 s->hdc = hdc;
25641 #endif
25642 s->display = FRAME_X_DISPLAY (s->f);
25643 s->char2b = char2b;
25644 s->hl = hl;
25645 s->row = row;
25646 s->area = area;
25647 s->first_glyph = row->glyphs[area] + start;
25648 s->height = row->height;
25649 s->y = WINDOW_TO_FRAME_PIXEL_Y (w, row->y);
25650 s->ybase = s->y + row->ascent;
25654 /* Append the list of glyph strings with head H and tail T to the list
25655 with head *HEAD and tail *TAIL. Set *HEAD and *TAIL to the result. */
25657 static void
25658 append_glyph_string_lists (struct glyph_string **head, struct glyph_string **tail,
25659 struct glyph_string *h, struct glyph_string *t)
25661 if (h)
25663 if (*head)
25664 (*tail)->next = h;
25665 else
25666 *head = h;
25667 h->prev = *tail;
25668 *tail = t;
25673 /* Prepend the list of glyph strings with head H and tail T to the
25674 list with head *HEAD and tail *TAIL. Set *HEAD and *TAIL to the
25675 result. */
25677 static void
25678 prepend_glyph_string_lists (struct glyph_string **head, struct glyph_string **tail,
25679 struct glyph_string *h, struct glyph_string *t)
25681 if (h)
25683 if (*head)
25684 (*head)->prev = t;
25685 else
25686 *tail = t;
25687 t->next = *head;
25688 *head = h;
25693 /* Append glyph string S to the list with head *HEAD and tail *TAIL.
25694 Set *HEAD and *TAIL to the resulting list. */
25696 static void
25697 append_glyph_string (struct glyph_string **head, struct glyph_string **tail,
25698 struct glyph_string *s)
25700 s->next = s->prev = NULL;
25701 append_glyph_string_lists (head, tail, s, s);
25705 /* Get face and two-byte form of character C in face FACE_ID on frame F.
25706 The encoding of C is returned in *CHAR2B. DISPLAY_P means
25707 make sure that X resources for the face returned are allocated.
25708 Value is a pointer to a realized face that is ready for display if
25709 DISPLAY_P. */
25711 static struct face *
25712 get_char_face_and_encoding (struct frame *f, int c, int face_id,
25713 XChar2b *char2b, bool display_p)
25715 struct face *face = FACE_FROM_ID (f, face_id);
25716 unsigned code = 0;
25718 if (face->font)
25720 code = face->font->driver->encode_char (face->font, c);
25722 if (code == FONT_INVALID_CODE)
25723 code = 0;
25725 STORE_XCHAR2B (char2b, (code >> 8), (code & 0xFF));
25727 /* Make sure X resources of the face are allocated. */
25728 #ifdef HAVE_X_WINDOWS
25729 if (display_p)
25730 #endif
25732 eassert (face != NULL);
25733 prepare_face_for_display (f, face);
25736 return face;
25740 /* Get face and two-byte form of character glyph GLYPH on frame F.
25741 The encoding of GLYPH->u.ch is returned in *CHAR2B. Value is
25742 a pointer to a realized face that is ready for display. */
25744 static struct face *
25745 get_glyph_face_and_encoding (struct frame *f, struct glyph *glyph,
25746 XChar2b *char2b)
25748 struct face *face;
25749 unsigned code = 0;
25751 eassert (glyph->type == CHAR_GLYPH);
25752 face = FACE_FROM_ID (f, glyph->face_id);
25754 /* Make sure X resources of the face are allocated. */
25755 prepare_face_for_display (f, face);
25757 if (face->font)
25759 if (CHAR_BYTE8_P (glyph->u.ch))
25760 code = CHAR_TO_BYTE8 (glyph->u.ch);
25761 else
25762 code = face->font->driver->encode_char (face->font, glyph->u.ch);
25764 if (code == FONT_INVALID_CODE)
25765 code = 0;
25768 STORE_XCHAR2B (char2b, (code >> 8), (code & 0xFF));
25769 return face;
25773 /* Get glyph code of character C in FONT in the two-byte form CHAR2B.
25774 Return true iff FONT has a glyph for C. */
25776 static bool
25777 get_char_glyph_code (int c, struct font *font, XChar2b *char2b)
25779 unsigned code;
25781 if (CHAR_BYTE8_P (c))
25782 code = CHAR_TO_BYTE8 (c);
25783 else
25784 code = font->driver->encode_char (font, c);
25786 if (code == FONT_INVALID_CODE)
25787 return false;
25788 STORE_XCHAR2B (char2b, (code >> 8), (code & 0xFF));
25789 return true;
25793 /* Fill glyph string S with composition components specified by S->cmp.
25795 BASE_FACE is the base face of the composition.
25796 S->cmp_from is the index of the first component for S.
25798 OVERLAPS non-zero means S should draw the foreground only, and use
25799 its physical height for clipping. See also draw_glyphs.
25801 Value is the index of a component not in S. */
25803 static int
25804 fill_composite_glyph_string (struct glyph_string *s, struct face *base_face,
25805 int overlaps)
25807 int i;
25808 /* For all glyphs of this composition, starting at the offset
25809 S->cmp_from, until we reach the end of the definition or encounter a
25810 glyph that requires the different face, add it to S. */
25811 struct face *face;
25813 eassert (s);
25815 s->for_overlaps = overlaps;
25816 s->face = NULL;
25817 s->font = NULL;
25818 for (i = s->cmp_from; i < s->cmp->glyph_len; i++)
25820 int c = COMPOSITION_GLYPH (s->cmp, i);
25822 /* TAB in a composition means display glyphs with padding space
25823 on the left or right. */
25824 if (c != '\t')
25826 int face_id = FACE_FOR_CHAR (s->f, base_face->ascii_face, c,
25827 -1, Qnil);
25829 face = get_char_face_and_encoding (s->f, c, face_id,
25830 s->char2b + i, true);
25831 if (face)
25833 if (! s->face)
25835 s->face = face;
25836 s->font = s->face->font;
25838 else if (s->face != face)
25839 break;
25842 ++s->nchars;
25844 s->cmp_to = i;
25846 if (s->face == NULL)
25848 s->face = base_face->ascii_face;
25849 s->font = s->face->font;
25852 /* All glyph strings for the same composition has the same width,
25853 i.e. the width set for the first component of the composition. */
25854 s->width = s->first_glyph->pixel_width;
25856 /* If the specified font could not be loaded, use the frame's
25857 default font, but record the fact that we couldn't load it in
25858 the glyph string so that we can draw rectangles for the
25859 characters of the glyph string. */
25860 if (s->font == NULL)
25862 s->font_not_found_p = true;
25863 s->font = FRAME_FONT (s->f);
25866 /* Adjust base line for subscript/superscript text. */
25867 s->ybase += s->first_glyph->voffset;
25869 return s->cmp_to;
25872 static int
25873 fill_gstring_glyph_string (struct glyph_string *s, int face_id,
25874 int start, int end, int overlaps)
25876 struct glyph *glyph, *last;
25877 Lisp_Object lgstring;
25878 int i;
25880 s->for_overlaps = overlaps;
25881 glyph = s->row->glyphs[s->area] + start;
25882 last = s->row->glyphs[s->area] + end;
25883 s->cmp_id = glyph->u.cmp.id;
25884 s->cmp_from = glyph->slice.cmp.from;
25885 s->cmp_to = glyph->slice.cmp.to + 1;
25886 s->face = FACE_FROM_ID (s->f, face_id);
25887 lgstring = composition_gstring_from_id (s->cmp_id);
25888 s->font = XFONT_OBJECT (LGSTRING_FONT (lgstring));
25889 glyph++;
25890 while (glyph < last
25891 && glyph->u.cmp.automatic
25892 && glyph->u.cmp.id == s->cmp_id
25893 && s->cmp_to == glyph->slice.cmp.from)
25894 s->cmp_to = (glyph++)->slice.cmp.to + 1;
25896 for (i = s->cmp_from; i < s->cmp_to; i++)
25898 Lisp_Object lglyph = LGSTRING_GLYPH (lgstring, i);
25899 unsigned code = LGLYPH_CODE (lglyph);
25901 STORE_XCHAR2B ((s->char2b + i), code >> 8, code & 0xFF);
25903 s->width = composition_gstring_width (lgstring, s->cmp_from, s->cmp_to, NULL);
25904 return glyph - s->row->glyphs[s->area];
25908 /* Fill glyph string S from a sequence glyphs for glyphless characters.
25909 See the comment of fill_glyph_string for arguments.
25910 Value is the index of the first glyph not in S. */
25913 static int
25914 fill_glyphless_glyph_string (struct glyph_string *s, int face_id,
25915 int start, int end, int overlaps)
25917 struct glyph *glyph, *last;
25918 int voffset;
25920 eassert (s->first_glyph->type == GLYPHLESS_GLYPH);
25921 s->for_overlaps = overlaps;
25922 glyph = s->row->glyphs[s->area] + start;
25923 last = s->row->glyphs[s->area] + end;
25924 voffset = glyph->voffset;
25925 s->face = FACE_FROM_ID (s->f, face_id);
25926 s->font = s->face->font ? s->face->font : FRAME_FONT (s->f);
25927 s->nchars = 1;
25928 s->width = glyph->pixel_width;
25929 glyph++;
25930 while (glyph < last
25931 && glyph->type == GLYPHLESS_GLYPH
25932 && glyph->voffset == voffset
25933 && glyph->face_id == face_id)
25935 s->nchars++;
25936 s->width += glyph->pixel_width;
25937 glyph++;
25939 s->ybase += voffset;
25940 return glyph - s->row->glyphs[s->area];
25944 /* Fill glyph string S from a sequence of character glyphs.
25946 FACE_ID is the face id of the string. START is the index of the
25947 first glyph to consider, END is the index of the last + 1.
25948 OVERLAPS non-zero means S should draw the foreground only, and use
25949 its physical height for clipping. See also draw_glyphs.
25951 Value is the index of the first glyph not in S. */
25953 static int
25954 fill_glyph_string (struct glyph_string *s, int face_id,
25955 int start, int end, int overlaps)
25957 struct glyph *glyph, *last;
25958 int voffset;
25959 bool glyph_not_available_p;
25961 eassert (s->f == XFRAME (s->w->frame));
25962 eassert (s->nchars == 0);
25963 eassert (start >= 0 && end > start);
25965 s->for_overlaps = overlaps;
25966 glyph = s->row->glyphs[s->area] + start;
25967 last = s->row->glyphs[s->area] + end;
25968 voffset = glyph->voffset;
25969 s->padding_p = glyph->padding_p;
25970 glyph_not_available_p = glyph->glyph_not_available_p;
25972 while (glyph < last
25973 && glyph->type == CHAR_GLYPH
25974 && glyph->voffset == voffset
25975 /* Same face id implies same font, nowadays. */
25976 && glyph->face_id == face_id
25977 && glyph->glyph_not_available_p == glyph_not_available_p)
25979 s->face = get_glyph_face_and_encoding (s->f, glyph,
25980 s->char2b + s->nchars);
25981 ++s->nchars;
25982 eassert (s->nchars <= end - start);
25983 s->width += glyph->pixel_width;
25984 if (glyph++->padding_p != s->padding_p)
25985 break;
25988 s->font = s->face->font;
25990 /* If the specified font could not be loaded, use the frame's font,
25991 but record the fact that we couldn't load it in
25992 S->font_not_found_p so that we can draw rectangles for the
25993 characters of the glyph string. */
25994 if (s->font == NULL || glyph_not_available_p)
25996 s->font_not_found_p = true;
25997 s->font = FRAME_FONT (s->f);
26000 /* Adjust base line for subscript/superscript text. */
26001 s->ybase += voffset;
26003 eassert (s->face && s->face->gc);
26004 return glyph - s->row->glyphs[s->area];
26008 /* Fill glyph string S from image glyph S->first_glyph. */
26010 static void
26011 fill_image_glyph_string (struct glyph_string *s)
26013 eassert (s->first_glyph->type == IMAGE_GLYPH);
26014 s->img = IMAGE_FROM_ID (s->f, s->first_glyph->u.img_id);
26015 eassert (s->img);
26016 s->slice = s->first_glyph->slice.img;
26017 s->face = FACE_FROM_ID (s->f, s->first_glyph->face_id);
26018 s->font = s->face->font;
26019 s->width = s->first_glyph->pixel_width;
26021 /* Adjust base line for subscript/superscript text. */
26022 s->ybase += s->first_glyph->voffset;
26026 #ifdef HAVE_XWIDGETS
26027 static void
26028 fill_xwidget_glyph_string (struct glyph_string *s)
26030 eassert (s->first_glyph->type == XWIDGET_GLYPH);
26031 s->face = FACE_FROM_ID (s->f, s->first_glyph->face_id);
26032 s->font = s->face->font;
26033 s->width = s->first_glyph->pixel_width;
26034 s->ybase += s->first_glyph->voffset;
26035 s->xwidget = s->first_glyph->u.xwidget;
26037 #endif
26038 /* Fill glyph string S from a sequence of stretch glyphs.
26040 START is the index of the first glyph to consider,
26041 END is the index of the last + 1.
26043 Value is the index of the first glyph not in S. */
26045 static int
26046 fill_stretch_glyph_string (struct glyph_string *s, int start, int end)
26048 struct glyph *glyph, *last;
26049 int voffset, face_id;
26051 eassert (s->first_glyph->type == STRETCH_GLYPH);
26053 glyph = s->row->glyphs[s->area] + start;
26054 last = s->row->glyphs[s->area] + end;
26055 face_id = glyph->face_id;
26056 s->face = FACE_FROM_ID (s->f, face_id);
26057 s->font = s->face->font;
26058 s->width = glyph->pixel_width;
26059 s->nchars = 1;
26060 voffset = glyph->voffset;
26062 for (++glyph;
26063 (glyph < last
26064 && glyph->type == STRETCH_GLYPH
26065 && glyph->voffset == voffset
26066 && glyph->face_id == face_id);
26067 ++glyph)
26068 s->width += glyph->pixel_width;
26070 /* Adjust base line for subscript/superscript text. */
26071 s->ybase += voffset;
26073 /* The case that face->gc == 0 is handled when drawing the glyph
26074 string by calling prepare_face_for_display. */
26075 eassert (s->face);
26076 return glyph - s->row->glyphs[s->area];
26079 static struct font_metrics *
26080 get_per_char_metric (struct font *font, XChar2b *char2b)
26082 static struct font_metrics metrics;
26083 unsigned code;
26085 if (! font)
26086 return NULL;
26087 code = (XCHAR2B_BYTE1 (char2b) << 8) | XCHAR2B_BYTE2 (char2b);
26088 if (code == FONT_INVALID_CODE)
26089 return NULL;
26090 font->driver->text_extents (font, &code, 1, &metrics);
26091 return &metrics;
26094 /* A subroutine that computes "normal" values of ASCENT and DESCENT
26095 for FONT. Values are taken from font-global ones, except for fonts
26096 that claim preposterously large values, but whose glyphs actually
26097 have reasonable dimensions. C is the character to use for metrics
26098 if the font-global values are too large; if C is negative, the
26099 function selects a default character. */
26100 static void
26101 normal_char_ascent_descent (struct font *font, int c, int *ascent, int *descent)
26103 *ascent = FONT_BASE (font);
26104 *descent = FONT_DESCENT (font);
26106 if (FONT_TOO_HIGH (font))
26108 XChar2b char2b;
26110 /* Get metrics of C, defaulting to a reasonably sized ASCII
26111 character. */
26112 if (get_char_glyph_code (c >= 0 ? c : '{', font, &char2b))
26114 struct font_metrics *pcm = get_per_char_metric (font, &char2b);
26116 if (!(pcm->width == 0 && pcm->rbearing == 0 && pcm->lbearing == 0))
26118 /* We add 1 pixel to character dimensions as heuristics
26119 that produces nicer display, e.g. when the face has
26120 the box attribute. */
26121 *ascent = pcm->ascent + 1;
26122 *descent = pcm->descent + 1;
26128 /* A subroutine that computes a reasonable "normal character height"
26129 for fonts that claim preposterously large vertical dimensions, but
26130 whose glyphs are actually reasonably sized. C is the character
26131 whose metrics to use for those fonts, or -1 for default
26132 character. */
26133 static int
26134 normal_char_height (struct font *font, int c)
26136 int ascent, descent;
26138 normal_char_ascent_descent (font, c, &ascent, &descent);
26140 return ascent + descent;
26143 /* EXPORT for RIF:
26144 Set *LEFT and *RIGHT to the left and right overhang of GLYPH on
26145 frame F. Overhangs of glyphs other than type CHAR_GLYPH are
26146 assumed to be zero. */
26148 void
26149 x_get_glyph_overhangs (struct glyph *glyph, struct frame *f, int *left, int *right)
26151 *left = *right = 0;
26153 if (glyph->type == CHAR_GLYPH)
26155 XChar2b char2b;
26156 struct face *face = get_glyph_face_and_encoding (f, glyph, &char2b);
26157 if (face->font)
26159 struct font_metrics *pcm = get_per_char_metric (face->font, &char2b);
26160 if (pcm)
26162 if (pcm->rbearing > pcm->width)
26163 *right = pcm->rbearing - pcm->width;
26164 if (pcm->lbearing < 0)
26165 *left = -pcm->lbearing;
26169 else if (glyph->type == COMPOSITE_GLYPH)
26171 if (! glyph->u.cmp.automatic)
26173 struct composition *cmp = composition_table[glyph->u.cmp.id];
26175 if (cmp->rbearing > cmp->pixel_width)
26176 *right = cmp->rbearing - cmp->pixel_width;
26177 if (cmp->lbearing < 0)
26178 *left = - cmp->lbearing;
26180 else
26182 Lisp_Object gstring = composition_gstring_from_id (glyph->u.cmp.id);
26183 struct font_metrics metrics;
26185 composition_gstring_width (gstring, glyph->slice.cmp.from,
26186 glyph->slice.cmp.to + 1, &metrics);
26187 if (metrics.rbearing > metrics.width)
26188 *right = metrics.rbearing - metrics.width;
26189 if (metrics.lbearing < 0)
26190 *left = - metrics.lbearing;
26196 /* Return the index of the first glyph preceding glyph string S that
26197 is overwritten by S because of S's left overhang. Value is -1
26198 if no glyphs are overwritten. */
26200 static int
26201 left_overwritten (struct glyph_string *s)
26203 int k;
26205 if (s->left_overhang)
26207 int x = 0, i;
26208 struct glyph *glyphs = s->row->glyphs[s->area];
26209 int first = s->first_glyph - glyphs;
26211 for (i = first - 1; i >= 0 && x > -s->left_overhang; --i)
26212 x -= glyphs[i].pixel_width;
26214 k = i + 1;
26216 else
26217 k = -1;
26219 return k;
26223 /* Return the index of the first glyph preceding glyph string S that
26224 is overwriting S because of its right overhang. Value is -1 if no
26225 glyph in front of S overwrites S. */
26227 static int
26228 left_overwriting (struct glyph_string *s)
26230 int i, k, x;
26231 struct glyph *glyphs = s->row->glyphs[s->area];
26232 int first = s->first_glyph - glyphs;
26234 k = -1;
26235 x = 0;
26236 for (i = first - 1; i >= 0; --i)
26238 int left, right;
26239 x_get_glyph_overhangs (glyphs + i, s->f, &left, &right);
26240 if (x + right > 0)
26241 k = i;
26242 x -= glyphs[i].pixel_width;
26245 return k;
26249 /* Return the index of the last glyph following glyph string S that is
26250 overwritten by S because of S's right overhang. Value is -1 if
26251 no such glyph is found. */
26253 static int
26254 right_overwritten (struct glyph_string *s)
26256 int k = -1;
26258 if (s->right_overhang)
26260 int x = 0, i;
26261 struct glyph *glyphs = s->row->glyphs[s->area];
26262 int first = (s->first_glyph - glyphs
26263 + (s->first_glyph->type == COMPOSITE_GLYPH ? 1 : s->nchars));
26264 int end = s->row->used[s->area];
26266 for (i = first; i < end && s->right_overhang > x; ++i)
26267 x += glyphs[i].pixel_width;
26269 k = i;
26272 return k;
26276 /* Return the index of the last glyph following glyph string S that
26277 overwrites S because of its left overhang. Value is negative
26278 if no such glyph is found. */
26280 static int
26281 right_overwriting (struct glyph_string *s)
26283 int i, k, x;
26284 int end = s->row->used[s->area];
26285 struct glyph *glyphs = s->row->glyphs[s->area];
26286 int first = (s->first_glyph - glyphs
26287 + (s->first_glyph->type == COMPOSITE_GLYPH ? 1 : s->nchars));
26289 k = -1;
26290 x = 0;
26291 for (i = first; i < end; ++i)
26293 int left, right;
26294 x_get_glyph_overhangs (glyphs + i, s->f, &left, &right);
26295 if (x - left < 0)
26296 k = i;
26297 x += glyphs[i].pixel_width;
26300 return k;
26304 /* Set background width of glyph string S. START is the index of the
26305 first glyph following S. LAST_X is the right-most x-position + 1
26306 in the drawing area. */
26308 static void
26309 set_glyph_string_background_width (struct glyph_string *s, int start, int last_x)
26311 /* If the face of this glyph string has to be drawn to the end of
26312 the drawing area, set S->extends_to_end_of_line_p. */
26314 if (start == s->row->used[s->area]
26315 && ((s->row->fill_line_p
26316 && (s->hl == DRAW_NORMAL_TEXT
26317 || s->hl == DRAW_IMAGE_RAISED
26318 || s->hl == DRAW_IMAGE_SUNKEN))
26319 || s->hl == DRAW_MOUSE_FACE))
26320 s->extends_to_end_of_line_p = true;
26322 /* If S extends its face to the end of the line, set its
26323 background_width to the distance to the right edge of the drawing
26324 area. */
26325 if (s->extends_to_end_of_line_p)
26326 s->background_width = last_x - s->x + 1;
26327 else
26328 s->background_width = s->width;
26332 /* Return glyph string that shares background with glyph string S and
26333 whose `background_width' member has been set. */
26335 static struct glyph_string *
26336 glyph_string_containing_background_width (struct glyph_string *s)
26338 if (s->cmp)
26339 while (s->cmp_from)
26340 s = s->prev;
26342 return s;
26346 /* Compute overhangs and x-positions for glyph string S and its
26347 predecessors, or successors. X is the starting x-position for S.
26348 BACKWARD_P means process predecessors. */
26350 static void
26351 compute_overhangs_and_x (struct glyph_string *s, int x, bool backward_p)
26353 if (backward_p)
26355 while (s)
26357 if (FRAME_RIF (s->f)->compute_glyph_string_overhangs)
26358 FRAME_RIF (s->f)->compute_glyph_string_overhangs (s);
26359 if (!s->cmp || s->cmp_to == s->cmp->glyph_len)
26360 x -= s->width;
26361 s->x = x;
26362 s = s->prev;
26365 else
26367 while (s)
26369 if (FRAME_RIF (s->f)->compute_glyph_string_overhangs)
26370 FRAME_RIF (s->f)->compute_glyph_string_overhangs (s);
26371 s->x = x;
26372 if (!s->cmp || s->cmp_to == s->cmp->glyph_len)
26373 x += s->width;
26374 s = s->next;
26381 /* The following macros are only called from draw_glyphs below.
26382 They reference the following parameters of that function directly:
26383 `w', `row', `area', and `overlap_p'
26384 as well as the following local variables:
26385 `s', `f', and `hdc' (in W32) */
26387 #ifdef HAVE_NTGUI
26388 /* On W32, silently add local `hdc' variable to argument list of
26389 init_glyph_string. */
26390 #define INIT_GLYPH_STRING(s, char2b, w, row, area, start, hl) \
26391 init_glyph_string (s, hdc, char2b, w, row, area, start, hl)
26392 #else
26393 #define INIT_GLYPH_STRING(s, char2b, w, row, area, start, hl) \
26394 init_glyph_string (s, char2b, w, row, area, start, hl)
26395 #endif
26397 /* Add a glyph string for a stretch glyph to the list of strings
26398 between HEAD and TAIL. START is the index of the stretch glyph in
26399 row area AREA of glyph row ROW. END is the index of the last glyph
26400 in that glyph row area. X is the current output position assigned
26401 to the new glyph string constructed. HL overrides that face of the
26402 glyph; e.g. it is DRAW_CURSOR if a cursor has to be drawn. LAST_X
26403 is the right-most x-position of the drawing area. */
26405 /* SunOS 4 bundled cc, barfed on continuations in the arg lists here
26406 and below -- keep them on one line. */
26407 #define BUILD_STRETCH_GLYPH_STRING(START, END, HEAD, TAIL, HL, X, LAST_X) \
26408 do \
26410 s = alloca (sizeof *s); \
26411 INIT_GLYPH_STRING (s, NULL, w, row, area, START, HL); \
26412 START = fill_stretch_glyph_string (s, START, END); \
26413 append_glyph_string (&HEAD, &TAIL, s); \
26414 s->x = (X); \
26416 while (false)
26419 /* Add a glyph string for an image glyph to the list of strings
26420 between HEAD and TAIL. START is the index of the image glyph in
26421 row area AREA of glyph row ROW. END is the index of the last glyph
26422 in that glyph row area. X is the current output position assigned
26423 to the new glyph string constructed. HL overrides that face of the
26424 glyph; e.g. it is DRAW_CURSOR if a cursor has to be drawn. LAST_X
26425 is the right-most x-position of the drawing area. */
26427 #define BUILD_IMAGE_GLYPH_STRING(START, END, HEAD, TAIL, HL, X, LAST_X) \
26428 do \
26430 s = alloca (sizeof *s); \
26431 INIT_GLYPH_STRING (s, NULL, w, row, area, START, HL); \
26432 fill_image_glyph_string (s); \
26433 append_glyph_string (&HEAD, &TAIL, s); \
26434 ++START; \
26435 s->x = (X); \
26437 while (false)
26439 #ifndef HAVE_XWIDGETS
26440 # define BUILD_XWIDGET_GLYPH_STRING(START, END, HEAD, TAIL, HL, X, LAST_X) \
26441 eassume (false)
26442 #else
26443 # define BUILD_XWIDGET_GLYPH_STRING(START, END, HEAD, TAIL, HL, X, LAST_X) \
26444 do \
26446 s = alloca (sizeof *s); \
26447 INIT_GLYPH_STRING (s, NULL, w, row, area, START, HL); \
26448 fill_xwidget_glyph_string (s); \
26449 append_glyph_string (&(HEAD), &(TAIL), s); \
26450 ++(START); \
26451 s->x = (X); \
26453 while (false)
26454 #endif
26456 /* Add a glyph string for a sequence of character glyphs to the list
26457 of strings between HEAD and TAIL. START is the index of the first
26458 glyph in row area AREA of glyph row ROW that is part of the new
26459 glyph string. END is the index of the last glyph in that glyph row
26460 area. X is the current output position assigned to the new glyph
26461 string constructed. HL overrides that face of the glyph; e.g. it
26462 is DRAW_CURSOR if a cursor has to be drawn. LAST_X is the
26463 right-most x-position of the drawing area. */
26465 #define BUILD_CHAR_GLYPH_STRINGS(START, END, HEAD, TAIL, HL, X, LAST_X) \
26466 do \
26468 int face_id; \
26469 XChar2b *char2b; \
26471 face_id = (row)->glyphs[area][START].face_id; \
26473 s = alloca (sizeof *s); \
26474 SAFE_NALLOCA (char2b, 1, (END) - (START)); \
26475 INIT_GLYPH_STRING (s, char2b, w, row, area, START, HL); \
26476 append_glyph_string (&HEAD, &TAIL, s); \
26477 s->x = (X); \
26478 START = fill_glyph_string (s, face_id, START, END, overlaps); \
26480 while (false)
26483 /* Add a glyph string for a composite sequence to the list of strings
26484 between HEAD and TAIL. START is the index of the first glyph in
26485 row area AREA of glyph row ROW that is part of the new glyph
26486 string. END is the index of the last glyph in that glyph row area.
26487 X is the current output position assigned to the new glyph string
26488 constructed. HL overrides that face of the glyph; e.g. it is
26489 DRAW_CURSOR if a cursor has to be drawn. LAST_X is the right-most
26490 x-position of the drawing area. */
26492 #define BUILD_COMPOSITE_GLYPH_STRING(START, END, HEAD, TAIL, HL, X, LAST_X) \
26493 do { \
26494 int face_id = (row)->glyphs[area][START].face_id; \
26495 struct face *base_face = FACE_FROM_ID (f, face_id); \
26496 ptrdiff_t cmp_id = (row)->glyphs[area][START].u.cmp.id; \
26497 struct composition *cmp = composition_table[cmp_id]; \
26498 XChar2b *char2b; \
26499 struct glyph_string *first_s = NULL; \
26500 int n; \
26502 SAFE_NALLOCA (char2b, 1, cmp->glyph_len); \
26504 /* Make glyph_strings for each glyph sequence that is drawable by \
26505 the same face, and append them to HEAD/TAIL. */ \
26506 for (n = 0; n < cmp->glyph_len;) \
26508 s = alloca (sizeof *s); \
26509 INIT_GLYPH_STRING (s, char2b, w, row, area, START, HL); \
26510 append_glyph_string (&(HEAD), &(TAIL), s); \
26511 s->cmp = cmp; \
26512 s->cmp_from = n; \
26513 s->x = (X); \
26514 if (n == 0) \
26515 first_s = s; \
26516 n = fill_composite_glyph_string (s, base_face, overlaps); \
26519 ++START; \
26520 s = first_s; \
26521 } while (false)
26524 /* Add a glyph string for a glyph-string sequence to the list of strings
26525 between HEAD and TAIL. */
26527 #define BUILD_GSTRING_GLYPH_STRING(START, END, HEAD, TAIL, HL, X, LAST_X) \
26528 do { \
26529 int face_id; \
26530 XChar2b *char2b; \
26531 Lisp_Object gstring; \
26533 face_id = (row)->glyphs[area][START].face_id; \
26534 gstring = (composition_gstring_from_id \
26535 ((row)->glyphs[area][START].u.cmp.id)); \
26536 s = alloca (sizeof *s); \
26537 SAFE_NALLOCA (char2b, 1, LGSTRING_GLYPH_LEN (gstring)); \
26538 INIT_GLYPH_STRING (s, char2b, w, row, area, START, HL); \
26539 append_glyph_string (&(HEAD), &(TAIL), s); \
26540 s->x = (X); \
26541 START = fill_gstring_glyph_string (s, face_id, START, END, overlaps); \
26542 } while (false)
26545 /* Add a glyph string for a sequence of glyphless character's glyphs
26546 to the list of strings between HEAD and TAIL. The meanings of
26547 arguments are the same as those of BUILD_CHAR_GLYPH_STRINGS. */
26549 #define BUILD_GLYPHLESS_GLYPH_STRING(START, END, HEAD, TAIL, HL, X, LAST_X) \
26550 do \
26552 int face_id; \
26554 face_id = (row)->glyphs[area][START].face_id; \
26556 s = alloca (sizeof *s); \
26557 INIT_GLYPH_STRING (s, NULL, w, row, area, START, HL); \
26558 append_glyph_string (&HEAD, &TAIL, s); \
26559 s->x = (X); \
26560 START = fill_glyphless_glyph_string (s, face_id, START, END, \
26561 overlaps); \
26563 while (false)
26566 /* Build a list of glyph strings between HEAD and TAIL for the glyphs
26567 of AREA of glyph row ROW on window W between indices START and END.
26568 HL overrides the face for drawing glyph strings, e.g. it is
26569 DRAW_CURSOR to draw a cursor. X and LAST_X are start and end
26570 x-positions of the drawing area.
26572 This is an ugly monster macro construct because we must use alloca
26573 to allocate glyph strings (because draw_glyphs can be called
26574 asynchronously). */
26576 #define BUILD_GLYPH_STRINGS_1(START, END, HEAD, TAIL, HL, X, LAST_X) \
26577 do \
26579 HEAD = TAIL = NULL; \
26580 while (START < END) \
26582 struct glyph *first_glyph = (row)->glyphs[area] + START; \
26583 switch (first_glyph->type) \
26585 case CHAR_GLYPH: \
26586 BUILD_CHAR_GLYPH_STRINGS (START, END, HEAD, TAIL, \
26587 HL, X, LAST_X); \
26588 break; \
26590 case COMPOSITE_GLYPH: \
26591 if (first_glyph->u.cmp.automatic) \
26592 BUILD_GSTRING_GLYPH_STRING (START, END, HEAD, TAIL, \
26593 HL, X, LAST_X); \
26594 else \
26595 BUILD_COMPOSITE_GLYPH_STRING (START, END, HEAD, TAIL, \
26596 HL, X, LAST_X); \
26597 break; \
26599 case STRETCH_GLYPH: \
26600 BUILD_STRETCH_GLYPH_STRING (START, END, HEAD, TAIL, \
26601 HL, X, LAST_X); \
26602 break; \
26604 case IMAGE_GLYPH: \
26605 BUILD_IMAGE_GLYPH_STRING (START, END, HEAD, TAIL, \
26606 HL, X, LAST_X); \
26607 break;
26609 #define BUILD_GLYPH_STRINGS_XW(START, END, HEAD, TAIL, HL, X, LAST_X) \
26610 case XWIDGET_GLYPH: \
26611 BUILD_XWIDGET_GLYPH_STRING (START, END, HEAD, TAIL, \
26612 HL, X, LAST_X); \
26613 break;
26615 #define BUILD_GLYPH_STRINGS_2(START, END, HEAD, TAIL, HL, X, LAST_X) \
26616 case GLYPHLESS_GLYPH: \
26617 BUILD_GLYPHLESS_GLYPH_STRING (START, END, HEAD, TAIL, \
26618 HL, X, LAST_X); \
26619 break; \
26621 default: \
26622 emacs_abort (); \
26625 if (s) \
26627 set_glyph_string_background_width (s, START, LAST_X); \
26628 (X) += s->width; \
26631 } while (false)
26634 #define BUILD_GLYPH_STRINGS(START, END, HEAD, TAIL, HL, X, LAST_X) \
26635 BUILD_GLYPH_STRINGS_1(START, END, HEAD, TAIL, HL, X, LAST_X) \
26636 BUILD_GLYPH_STRINGS_XW(START, END, HEAD, TAIL, HL, X, LAST_X) \
26637 BUILD_GLYPH_STRINGS_2(START, END, HEAD, TAIL, HL, X, LAST_X)
26640 /* Draw glyphs between START and END in AREA of ROW on window W,
26641 starting at x-position X. X is relative to AREA in W. HL is a
26642 face-override with the following meaning:
26644 DRAW_NORMAL_TEXT draw normally
26645 DRAW_CURSOR draw in cursor face
26646 DRAW_MOUSE_FACE draw in mouse face.
26647 DRAW_INVERSE_VIDEO draw in mode line face
26648 DRAW_IMAGE_SUNKEN draw an image with a sunken relief around it
26649 DRAW_IMAGE_RAISED draw an image with a raised relief around it
26651 If OVERLAPS is non-zero, draw only the foreground of characters and
26652 clip to the physical height of ROW. Non-zero value also defines
26653 the overlapping part to be drawn:
26655 OVERLAPS_PRED overlap with preceding rows
26656 OVERLAPS_SUCC overlap with succeeding rows
26657 OVERLAPS_BOTH overlap with both preceding/succeeding rows
26658 OVERLAPS_ERASED_CURSOR overlap with erased cursor area
26660 Value is the x-position reached, relative to AREA of W. */
26662 static int
26663 draw_glyphs (struct window *w, int x, struct glyph_row *row,
26664 enum glyph_row_area area, ptrdiff_t start, ptrdiff_t end,
26665 enum draw_glyphs_face hl, int overlaps)
26667 struct glyph_string *head, *tail;
26668 struct glyph_string *s;
26669 struct glyph_string *clip_head = NULL, *clip_tail = NULL;
26670 int i, j, x_reached, last_x, area_left = 0;
26671 struct frame *f = XFRAME (WINDOW_FRAME (w));
26672 DECLARE_HDC (hdc);
26674 ALLOCATE_HDC (hdc, f);
26676 /* Let's rather be paranoid than getting a SEGV. */
26677 end = min (end, row->used[area]);
26678 start = clip_to_bounds (0, start, end);
26680 /* Translate X to frame coordinates. Set last_x to the right
26681 end of the drawing area. */
26682 if (row->full_width_p)
26684 /* X is relative to the left edge of W, without scroll bars
26685 or fringes. */
26686 area_left = WINDOW_LEFT_EDGE_X (w);
26687 last_x = (WINDOW_LEFT_EDGE_X (w) + WINDOW_PIXEL_WIDTH (w)
26688 - (row->mode_line_p ? WINDOW_RIGHT_DIVIDER_WIDTH (w) : 0));
26690 else
26692 area_left = window_box_left (w, area);
26693 last_x = area_left + window_box_width (w, area);
26695 x += area_left;
26697 /* Build a doubly-linked list of glyph_string structures between
26698 head and tail from what we have to draw. Note that the macro
26699 BUILD_GLYPH_STRINGS will modify its start parameter. That's
26700 the reason we use a separate variable `i'. */
26701 i = start;
26702 USE_SAFE_ALLOCA;
26703 BUILD_GLYPH_STRINGS (i, end, head, tail, hl, x, last_x);
26704 if (tail)
26706 s = glyph_string_containing_background_width (tail);
26707 x_reached = s->x + s->background_width;
26709 else
26710 x_reached = x;
26712 /* If there are any glyphs with lbearing < 0 or rbearing > width in
26713 the row, redraw some glyphs in front or following the glyph
26714 strings built above. */
26715 if (head && !overlaps && row->contains_overlapping_glyphs_p)
26717 struct glyph_string *h, *t;
26718 Mouse_HLInfo *hlinfo = MOUSE_HL_INFO (f);
26719 int mouse_beg_col UNINIT, mouse_end_col UNINIT;
26720 bool check_mouse_face = false;
26721 int dummy_x = 0;
26723 /* If mouse highlighting is on, we may need to draw adjacent
26724 glyphs using mouse-face highlighting. */
26725 if (area == TEXT_AREA && row->mouse_face_p
26726 && hlinfo->mouse_face_beg_row >= 0
26727 && hlinfo->mouse_face_end_row >= 0)
26729 ptrdiff_t row_vpos = MATRIX_ROW_VPOS (row, w->current_matrix);
26731 if (row_vpos >= hlinfo->mouse_face_beg_row
26732 && row_vpos <= hlinfo->mouse_face_end_row)
26734 check_mouse_face = true;
26735 mouse_beg_col = (row_vpos == hlinfo->mouse_face_beg_row)
26736 ? hlinfo->mouse_face_beg_col : 0;
26737 mouse_end_col = (row_vpos == hlinfo->mouse_face_end_row)
26738 ? hlinfo->mouse_face_end_col
26739 : row->used[TEXT_AREA];
26743 /* Compute overhangs for all glyph strings. */
26744 if (FRAME_RIF (f)->compute_glyph_string_overhangs)
26745 for (s = head; s; s = s->next)
26746 FRAME_RIF (f)->compute_glyph_string_overhangs (s);
26748 /* Prepend glyph strings for glyphs in front of the first glyph
26749 string that are overwritten because of the first glyph
26750 string's left overhang. The background of all strings
26751 prepended must be drawn because the first glyph string
26752 draws over it. */
26753 i = left_overwritten (head);
26754 if (i >= 0)
26756 enum draw_glyphs_face overlap_hl;
26758 /* If this row contains mouse highlighting, attempt to draw
26759 the overlapped glyphs with the correct highlight. This
26760 code fails if the overlap encompasses more than one glyph
26761 and mouse-highlight spans only some of these glyphs.
26762 However, making it work perfectly involves a lot more
26763 code, and I don't know if the pathological case occurs in
26764 practice, so we'll stick to this for now. --- cyd */
26765 if (check_mouse_face
26766 && mouse_beg_col < start && mouse_end_col > i)
26767 overlap_hl = DRAW_MOUSE_FACE;
26768 else
26769 overlap_hl = DRAW_NORMAL_TEXT;
26771 if (hl != overlap_hl)
26772 clip_head = head;
26773 j = i;
26774 BUILD_GLYPH_STRINGS (j, start, h, t,
26775 overlap_hl, dummy_x, last_x);
26776 start = i;
26777 compute_overhangs_and_x (t, head->x, true);
26778 prepend_glyph_string_lists (&head, &tail, h, t);
26779 if (clip_head == NULL)
26780 clip_head = head;
26783 /* Prepend glyph strings for glyphs in front of the first glyph
26784 string that overwrite that glyph string because of their
26785 right overhang. For these strings, only the foreground must
26786 be drawn, because it draws over the glyph string at `head'.
26787 The background must not be drawn because this would overwrite
26788 right overhangs of preceding glyphs for which no glyph
26789 strings exist. */
26790 i = left_overwriting (head);
26791 if (i >= 0)
26793 enum draw_glyphs_face overlap_hl;
26795 if (check_mouse_face
26796 && mouse_beg_col < start && mouse_end_col > i)
26797 overlap_hl = DRAW_MOUSE_FACE;
26798 else
26799 overlap_hl = DRAW_NORMAL_TEXT;
26801 if (hl == overlap_hl || clip_head == NULL)
26802 clip_head = head;
26803 BUILD_GLYPH_STRINGS (i, start, h, t,
26804 overlap_hl, dummy_x, last_x);
26805 for (s = h; s; s = s->next)
26806 s->background_filled_p = true;
26807 compute_overhangs_and_x (t, head->x, true);
26808 prepend_glyph_string_lists (&head, &tail, h, t);
26811 /* Append glyphs strings for glyphs following the last glyph
26812 string tail that are overwritten by tail. The background of
26813 these strings has to be drawn because tail's foreground draws
26814 over it. */
26815 i = right_overwritten (tail);
26816 if (i >= 0)
26818 enum draw_glyphs_face overlap_hl;
26820 if (check_mouse_face
26821 && mouse_beg_col < i && mouse_end_col > end)
26822 overlap_hl = DRAW_MOUSE_FACE;
26823 else
26824 overlap_hl = DRAW_NORMAL_TEXT;
26826 if (hl != overlap_hl)
26827 clip_tail = tail;
26828 BUILD_GLYPH_STRINGS (end, i, h, t,
26829 overlap_hl, x, last_x);
26830 /* Because BUILD_GLYPH_STRINGS updates the first argument,
26831 we don't have `end = i;' here. */
26832 compute_overhangs_and_x (h, tail->x + tail->width, false);
26833 append_glyph_string_lists (&head, &tail, h, t);
26834 if (clip_tail == NULL)
26835 clip_tail = tail;
26838 /* Append glyph strings for glyphs following the last glyph
26839 string tail that overwrite tail. The foreground of such
26840 glyphs has to be drawn because it writes into the background
26841 of tail. The background must not be drawn because it could
26842 paint over the foreground of following glyphs. */
26843 i = right_overwriting (tail);
26844 if (i >= 0)
26846 enum draw_glyphs_face overlap_hl;
26847 if (check_mouse_face
26848 && mouse_beg_col < i && mouse_end_col > end)
26849 overlap_hl = DRAW_MOUSE_FACE;
26850 else
26851 overlap_hl = DRAW_NORMAL_TEXT;
26853 if (hl == overlap_hl || clip_tail == NULL)
26854 clip_tail = tail;
26855 i++; /* We must include the Ith glyph. */
26856 BUILD_GLYPH_STRINGS (end, i, h, t,
26857 overlap_hl, x, last_x);
26858 for (s = h; s; s = s->next)
26859 s->background_filled_p = true;
26860 compute_overhangs_and_x (h, tail->x + tail->width, false);
26861 append_glyph_string_lists (&head, &tail, h, t);
26863 tail = glyph_string_containing_background_width (tail);
26864 if (clip_tail)
26865 clip_tail = glyph_string_containing_background_width (clip_tail);
26866 if (clip_head || clip_tail)
26867 for (s = head; s; s = s->next)
26869 s->clip_head = clip_head;
26870 s->clip_tail = clip_tail;
26874 /* Draw all strings. */
26875 for (s = head; s; s = s->next)
26876 FRAME_RIF (f)->draw_glyph_string (s);
26878 #ifndef HAVE_NS
26879 /* When focus a sole frame and move horizontally, this clears on_p
26880 causing a failure to erase prev cursor position. */
26881 if (area == TEXT_AREA
26882 && !row->full_width_p
26883 /* When drawing overlapping rows, only the glyph strings'
26884 foreground is drawn, which doesn't erase a cursor
26885 completely. */
26886 && !overlaps)
26888 int x0 = clip_head ? clip_head->x : (head ? head->x : x);
26889 int x1 = (clip_tail ? clip_tail->x + clip_tail->background_width
26890 : (tail ? tail->x + tail->background_width : x));
26891 x0 -= area_left;
26892 x1 -= area_left;
26894 notice_overwritten_cursor (w, TEXT_AREA, x0, x1,
26895 row->y, MATRIX_ROW_BOTTOM_Y (row));
26897 #endif
26899 /* Value is the x-position up to which drawn, relative to AREA of W.
26900 This doesn't include parts drawn because of overhangs. */
26901 if (row->full_width_p)
26902 x_reached = FRAME_TO_WINDOW_PIXEL_X (w, x_reached);
26903 else
26904 x_reached -= area_left;
26906 RELEASE_HDC (hdc, f);
26908 SAFE_FREE ();
26909 return x_reached;
26912 /* Find the first glyph in the run of underlined glyphs preceding the
26913 beginning of glyph string S, and return its font (which could be
26914 NULL). This is needed because that font determines the underline
26915 position and thickness for the entire run of the underlined glyphs.
26916 This function is called from the draw_glyph_string method of GUI
26917 frame's redisplay interface (RIF) when it needs to draw in an
26918 underlined face. */
26919 struct font *
26920 font_for_underline_metrics (struct glyph_string *s)
26922 struct glyph *g0 = s->row->glyphs[s->area], *g;
26924 for (g = s->first_glyph - 1; g >= g0; g--)
26926 struct face *prev_face = FACE_FROM_ID (s->f, g->face_id);
26927 if (!(prev_face && prev_face->underline_p))
26928 break;
26931 /* If preceding glyphs are not underlined, use the font of S. */
26932 if (g == s->first_glyph - 1)
26933 return s->font;
26934 else
26936 /* Otherwise use the font of the last glyph we saw in the above
26937 loop whose face had the underline_p flag set. */
26938 return FACE_FROM_ID (s->f, g[1].face_id)->font;
26942 /* Expand row matrix if too narrow. Don't expand if area
26943 is not present. */
26945 #define IT_EXPAND_MATRIX_WIDTH(it, area) \
26947 if (!it->f->fonts_changed \
26948 && (it->glyph_row->glyphs[area] \
26949 < it->glyph_row->glyphs[area + 1])) \
26951 it->w->ncols_scale_factor++; \
26952 it->f->fonts_changed = true; \
26956 /* Store one glyph for IT->char_to_display in IT->glyph_row.
26957 Called from x_produce_glyphs when IT->glyph_row is non-null. */
26959 static void
26960 append_glyph (struct it *it)
26962 struct glyph *glyph;
26963 enum glyph_row_area area = it->area;
26965 eassert (it->glyph_row);
26966 eassert (it->char_to_display != '\n' && it->char_to_display != '\t');
26968 glyph = it->glyph_row->glyphs[area] + it->glyph_row->used[area];
26969 if (glyph < it->glyph_row->glyphs[area + 1])
26971 /* If the glyph row is reversed, we need to prepend the glyph
26972 rather than append it. */
26973 if (it->glyph_row->reversed_p && area == TEXT_AREA)
26975 struct glyph *g;
26977 /* Make room for the additional glyph. */
26978 for (g = glyph - 1; g >= it->glyph_row->glyphs[area]; g--)
26979 g[1] = *g;
26980 glyph = it->glyph_row->glyphs[area];
26982 glyph->charpos = CHARPOS (it->position);
26983 glyph->object = it->object;
26984 if (it->pixel_width > 0)
26986 eassert (it->pixel_width <= SHRT_MAX);
26987 glyph->pixel_width = it->pixel_width;
26988 glyph->padding_p = false;
26990 else
26992 /* Assure at least 1-pixel width. Otherwise, cursor can't
26993 be displayed correctly. */
26994 glyph->pixel_width = 1;
26995 glyph->padding_p = true;
26997 glyph->ascent = it->ascent;
26998 glyph->descent = it->descent;
26999 glyph->voffset = it->voffset;
27000 glyph->type = CHAR_GLYPH;
27001 glyph->avoid_cursor_p = it->avoid_cursor_p;
27002 glyph->multibyte_p = it->multibyte_p;
27003 if (it->glyph_row->reversed_p && area == TEXT_AREA)
27005 /* In R2L rows, the left and the right box edges need to be
27006 drawn in reverse direction. */
27007 glyph->right_box_line_p = it->start_of_box_run_p;
27008 glyph->left_box_line_p = it->end_of_box_run_p;
27010 else
27012 glyph->left_box_line_p = it->start_of_box_run_p;
27013 glyph->right_box_line_p = it->end_of_box_run_p;
27015 glyph->overlaps_vertically_p = (it->phys_ascent > it->ascent
27016 || it->phys_descent > it->descent);
27017 glyph->glyph_not_available_p = it->glyph_not_available_p;
27018 glyph->face_id = it->face_id;
27019 glyph->u.ch = it->char_to_display;
27020 glyph->slice.img = null_glyph_slice;
27021 glyph->font_type = FONT_TYPE_UNKNOWN;
27022 if (it->bidi_p)
27024 glyph->resolved_level = it->bidi_it.resolved_level;
27025 eassert ((it->bidi_it.type & 7) == it->bidi_it.type);
27026 glyph->bidi_type = it->bidi_it.type;
27028 else
27030 glyph->resolved_level = 0;
27031 glyph->bidi_type = UNKNOWN_BT;
27033 ++it->glyph_row->used[area];
27035 else
27036 IT_EXPAND_MATRIX_WIDTH (it, area);
27039 /* Store one glyph for the composition IT->cmp_it.id in
27040 IT->glyph_row. Called from x_produce_glyphs when IT->glyph_row is
27041 non-null. */
27043 static void
27044 append_composite_glyph (struct it *it)
27046 struct glyph *glyph;
27047 enum glyph_row_area area = it->area;
27049 eassert (it->glyph_row);
27051 glyph = it->glyph_row->glyphs[area] + it->glyph_row->used[area];
27052 if (glyph < it->glyph_row->glyphs[area + 1])
27054 /* If the glyph row is reversed, we need to prepend the glyph
27055 rather than append it. */
27056 if (it->glyph_row->reversed_p && it->area == TEXT_AREA)
27058 struct glyph *g;
27060 /* Make room for the new glyph. */
27061 for (g = glyph - 1; g >= it->glyph_row->glyphs[it->area]; g--)
27062 g[1] = *g;
27063 glyph = it->glyph_row->glyphs[it->area];
27065 glyph->charpos = it->cmp_it.charpos;
27066 glyph->object = it->object;
27067 eassert (it->pixel_width <= SHRT_MAX);
27068 glyph->pixel_width = it->pixel_width;
27069 glyph->ascent = it->ascent;
27070 glyph->descent = it->descent;
27071 glyph->voffset = it->voffset;
27072 glyph->type = COMPOSITE_GLYPH;
27073 if (it->cmp_it.ch < 0)
27075 glyph->u.cmp.automatic = false;
27076 glyph->u.cmp.id = it->cmp_it.id;
27077 glyph->slice.cmp.from = glyph->slice.cmp.to = 0;
27079 else
27081 glyph->u.cmp.automatic = true;
27082 glyph->u.cmp.id = it->cmp_it.id;
27083 glyph->slice.cmp.from = it->cmp_it.from;
27084 glyph->slice.cmp.to = it->cmp_it.to - 1;
27086 glyph->avoid_cursor_p = it->avoid_cursor_p;
27087 glyph->multibyte_p = it->multibyte_p;
27088 if (it->glyph_row->reversed_p && area == TEXT_AREA)
27090 /* In R2L rows, the left and the right box edges need to be
27091 drawn in reverse direction. */
27092 glyph->right_box_line_p = it->start_of_box_run_p;
27093 glyph->left_box_line_p = it->end_of_box_run_p;
27095 else
27097 glyph->left_box_line_p = it->start_of_box_run_p;
27098 glyph->right_box_line_p = it->end_of_box_run_p;
27100 glyph->overlaps_vertically_p = (it->phys_ascent > it->ascent
27101 || it->phys_descent > it->descent);
27102 glyph->padding_p = false;
27103 glyph->glyph_not_available_p = false;
27104 glyph->face_id = it->face_id;
27105 glyph->font_type = FONT_TYPE_UNKNOWN;
27106 if (it->bidi_p)
27108 glyph->resolved_level = it->bidi_it.resolved_level;
27109 eassert ((it->bidi_it.type & 7) == it->bidi_it.type);
27110 glyph->bidi_type = it->bidi_it.type;
27112 ++it->glyph_row->used[area];
27114 else
27115 IT_EXPAND_MATRIX_WIDTH (it, area);
27119 /* Change IT->ascent and IT->height according to the setting of
27120 IT->voffset. */
27122 static void
27123 take_vertical_position_into_account (struct it *it)
27125 if (it->voffset)
27127 if (it->voffset < 0)
27128 /* Increase the ascent so that we can display the text higher
27129 in the line. */
27130 it->ascent -= it->voffset;
27131 else
27132 /* Increase the descent so that we can display the text lower
27133 in the line. */
27134 it->descent += it->voffset;
27139 /* Produce glyphs/get display metrics for the image IT is loaded with.
27140 See the description of struct display_iterator in dispextern.h for
27141 an overview of struct display_iterator. */
27143 static void
27144 produce_image_glyph (struct it *it)
27146 struct image *img;
27147 struct face *face;
27148 int glyph_ascent, crop;
27149 struct glyph_slice slice;
27151 eassert (it->what == IT_IMAGE);
27153 face = FACE_FROM_ID (it->f, it->face_id);
27154 /* Make sure X resources of the face is loaded. */
27155 prepare_face_for_display (it->f, face);
27157 if (it->image_id < 0)
27159 /* Fringe bitmap. */
27160 it->ascent = it->phys_ascent = 0;
27161 it->descent = it->phys_descent = 0;
27162 it->pixel_width = 0;
27163 it->nglyphs = 0;
27164 return;
27167 img = IMAGE_FROM_ID (it->f, it->image_id);
27168 /* Make sure X resources of the image is loaded. */
27169 prepare_image_for_display (it->f, img);
27171 slice.x = slice.y = 0;
27172 slice.width = img->width;
27173 slice.height = img->height;
27175 if (INTEGERP (it->slice.x))
27176 slice.x = XINT (it->slice.x);
27177 else if (FLOATP (it->slice.x))
27178 slice.x = XFLOAT_DATA (it->slice.x) * img->width;
27180 if (INTEGERP (it->slice.y))
27181 slice.y = XINT (it->slice.y);
27182 else if (FLOATP (it->slice.y))
27183 slice.y = XFLOAT_DATA (it->slice.y) * img->height;
27185 if (INTEGERP (it->slice.width))
27186 slice.width = XINT (it->slice.width);
27187 else if (FLOATP (it->slice.width))
27188 slice.width = XFLOAT_DATA (it->slice.width) * img->width;
27190 if (INTEGERP (it->slice.height))
27191 slice.height = XINT (it->slice.height);
27192 else if (FLOATP (it->slice.height))
27193 slice.height = XFLOAT_DATA (it->slice.height) * img->height;
27195 if (slice.x >= img->width)
27196 slice.x = img->width;
27197 if (slice.y >= img->height)
27198 slice.y = img->height;
27199 if (slice.x + slice.width >= img->width)
27200 slice.width = img->width - slice.x;
27201 if (slice.y + slice.height > img->height)
27202 slice.height = img->height - slice.y;
27204 if (slice.width == 0 || slice.height == 0)
27205 return;
27207 it->ascent = it->phys_ascent = glyph_ascent = image_ascent (img, face, &slice);
27209 it->descent = slice.height - glyph_ascent;
27210 if (slice.y == 0)
27211 it->descent += img->vmargin;
27212 if (slice.y + slice.height == img->height)
27213 it->descent += img->vmargin;
27214 it->phys_descent = it->descent;
27216 it->pixel_width = slice.width;
27217 if (slice.x == 0)
27218 it->pixel_width += img->hmargin;
27219 if (slice.x + slice.width == img->width)
27220 it->pixel_width += img->hmargin;
27222 /* It's quite possible for images to have an ascent greater than
27223 their height, so don't get confused in that case. */
27224 if (it->descent < 0)
27225 it->descent = 0;
27227 it->nglyphs = 1;
27229 if (face->box != FACE_NO_BOX)
27231 if (face->box_line_width > 0)
27233 if (slice.y == 0)
27234 it->ascent += face->box_line_width;
27235 if (slice.y + slice.height == img->height)
27236 it->descent += face->box_line_width;
27239 if (it->start_of_box_run_p && slice.x == 0)
27240 it->pixel_width += eabs (face->box_line_width);
27241 if (it->end_of_box_run_p && slice.x + slice.width == img->width)
27242 it->pixel_width += eabs (face->box_line_width);
27245 take_vertical_position_into_account (it);
27247 /* Automatically crop wide image glyphs at right edge so we can
27248 draw the cursor on same display row. */
27249 if ((crop = it->pixel_width - (it->last_visible_x - it->current_x), crop > 0)
27250 && (it->hpos == 0 || it->pixel_width > it->last_visible_x / 4))
27252 it->pixel_width -= crop;
27253 slice.width -= crop;
27256 if (it->glyph_row)
27258 struct glyph *glyph;
27259 enum glyph_row_area area = it->area;
27261 glyph = it->glyph_row->glyphs[area] + it->glyph_row->used[area];
27262 if (it->glyph_row->reversed_p)
27264 struct glyph *g;
27266 /* Make room for the new glyph. */
27267 for (g = glyph - 1; g >= it->glyph_row->glyphs[it->area]; g--)
27268 g[1] = *g;
27269 glyph = it->glyph_row->glyphs[it->area];
27271 if (glyph < it->glyph_row->glyphs[area + 1])
27273 glyph->charpos = CHARPOS (it->position);
27274 glyph->object = it->object;
27275 glyph->pixel_width = clip_to_bounds (-1, it->pixel_width, SHRT_MAX);
27276 glyph->ascent = glyph_ascent;
27277 glyph->descent = it->descent;
27278 glyph->voffset = it->voffset;
27279 glyph->type = IMAGE_GLYPH;
27280 glyph->avoid_cursor_p = it->avoid_cursor_p;
27281 glyph->multibyte_p = it->multibyte_p;
27282 if (it->glyph_row->reversed_p && area == TEXT_AREA)
27284 /* In R2L rows, the left and the right box edges need to be
27285 drawn in reverse direction. */
27286 glyph->right_box_line_p = it->start_of_box_run_p;
27287 glyph->left_box_line_p = it->end_of_box_run_p;
27289 else
27291 glyph->left_box_line_p = it->start_of_box_run_p;
27292 glyph->right_box_line_p = it->end_of_box_run_p;
27294 glyph->overlaps_vertically_p = false;
27295 glyph->padding_p = false;
27296 glyph->glyph_not_available_p = false;
27297 glyph->face_id = it->face_id;
27298 glyph->u.img_id = img->id;
27299 glyph->slice.img = slice;
27300 glyph->font_type = FONT_TYPE_UNKNOWN;
27301 if (it->bidi_p)
27303 glyph->resolved_level = it->bidi_it.resolved_level;
27304 eassert ((it->bidi_it.type & 7) == it->bidi_it.type);
27305 glyph->bidi_type = it->bidi_it.type;
27307 ++it->glyph_row->used[area];
27309 else
27310 IT_EXPAND_MATRIX_WIDTH (it, area);
27314 static void
27315 produce_xwidget_glyph (struct it *it)
27317 #ifdef HAVE_XWIDGETS
27318 struct xwidget *xw;
27319 int glyph_ascent, crop;
27320 eassert (it->what == IT_XWIDGET);
27322 struct face *face = FACE_FROM_ID (it->f, it->face_id);
27323 /* Make sure X resources of the face is loaded. */
27324 prepare_face_for_display (it->f, face);
27326 xw = it->xwidget;
27327 it->ascent = it->phys_ascent = glyph_ascent = xw->height/2;
27328 it->descent = xw->height/2;
27329 it->phys_descent = it->descent;
27330 it->pixel_width = xw->width;
27331 /* It's quite possible for images to have an ascent greater than
27332 their height, so don't get confused in that case. */
27333 if (it->descent < 0)
27334 it->descent = 0;
27336 it->nglyphs = 1;
27338 if (face->box != FACE_NO_BOX)
27340 if (face->box_line_width > 0)
27342 it->ascent += face->box_line_width;
27343 it->descent += face->box_line_width;
27346 if (it->start_of_box_run_p)
27347 it->pixel_width += eabs (face->box_line_width);
27348 it->pixel_width += eabs (face->box_line_width);
27351 take_vertical_position_into_account (it);
27353 /* Automatically crop wide image glyphs at right edge so we can
27354 draw the cursor on same display row. */
27355 crop = it->pixel_width - (it->last_visible_x - it->current_x);
27356 if (crop > 0 && (it->hpos == 0 || it->pixel_width > it->last_visible_x / 4))
27357 it->pixel_width -= crop;
27359 if (it->glyph_row)
27361 enum glyph_row_area area = it->area;
27362 struct glyph *glyph
27363 = it->glyph_row->glyphs[area] + it->glyph_row->used[area];
27365 if (it->glyph_row->reversed_p)
27367 struct glyph *g;
27369 /* Make room for the new glyph. */
27370 for (g = glyph - 1; g >= it->glyph_row->glyphs[it->area]; g--)
27371 g[1] = *g;
27372 glyph = it->glyph_row->glyphs[it->area];
27374 if (glyph < it->glyph_row->glyphs[area + 1])
27376 glyph->charpos = CHARPOS (it->position);
27377 glyph->object = it->object;
27378 glyph->pixel_width = clip_to_bounds (-1, it->pixel_width, SHRT_MAX);
27379 glyph->ascent = glyph_ascent;
27380 glyph->descent = it->descent;
27381 glyph->voffset = it->voffset;
27382 glyph->type = XWIDGET_GLYPH;
27383 glyph->avoid_cursor_p = it->avoid_cursor_p;
27384 glyph->multibyte_p = it->multibyte_p;
27385 if (it->glyph_row->reversed_p && area == TEXT_AREA)
27387 /* In R2L rows, the left and the right box edges need to be
27388 drawn in reverse direction. */
27389 glyph->right_box_line_p = it->start_of_box_run_p;
27390 glyph->left_box_line_p = it->end_of_box_run_p;
27392 else
27394 glyph->left_box_line_p = it->start_of_box_run_p;
27395 glyph->right_box_line_p = it->end_of_box_run_p;
27397 glyph->overlaps_vertically_p = 0;
27398 glyph->padding_p = 0;
27399 glyph->glyph_not_available_p = 0;
27400 glyph->face_id = it->face_id;
27401 glyph->u.xwidget = it->xwidget;
27402 glyph->font_type = FONT_TYPE_UNKNOWN;
27403 if (it->bidi_p)
27405 glyph->resolved_level = it->bidi_it.resolved_level;
27406 eassert ((it->bidi_it.type & 7) == it->bidi_it.type);
27407 glyph->bidi_type = it->bidi_it.type;
27409 ++it->glyph_row->used[area];
27411 else
27412 IT_EXPAND_MATRIX_WIDTH (it, area);
27414 #endif
27417 /* Append a stretch glyph to IT->glyph_row. OBJECT is the source
27418 of the glyph, WIDTH and HEIGHT are the width and height of the
27419 stretch. ASCENT is the ascent of the glyph (0 <= ASCENT <= HEIGHT). */
27421 static void
27422 append_stretch_glyph (struct it *it, Lisp_Object object,
27423 int width, int height, int ascent)
27425 struct glyph *glyph;
27426 enum glyph_row_area area = it->area;
27428 eassert (ascent >= 0 && ascent <= height);
27430 glyph = it->glyph_row->glyphs[area] + it->glyph_row->used[area];
27431 if (glyph < it->glyph_row->glyphs[area + 1])
27433 /* If the glyph row is reversed, we need to prepend the glyph
27434 rather than append it. */
27435 if (it->glyph_row->reversed_p && area == TEXT_AREA)
27437 struct glyph *g;
27439 /* Make room for the additional glyph. */
27440 for (g = glyph - 1; g >= it->glyph_row->glyphs[area]; g--)
27441 g[1] = *g;
27442 glyph = it->glyph_row->glyphs[area];
27444 /* Decrease the width of the first glyph of the row that
27445 begins before first_visible_x (e.g., due to hscroll).
27446 This is so the overall width of the row becomes smaller
27447 by the scroll amount, and the stretch glyph appended by
27448 extend_face_to_end_of_line will be wider, to shift the
27449 row glyphs to the right. (In L2R rows, the corresponding
27450 left-shift effect is accomplished by setting row->x to a
27451 negative value, which won't work with R2L rows.)
27453 This must leave us with a positive value of WIDTH, since
27454 otherwise the call to move_it_in_display_line_to at the
27455 beginning of display_line would have got past the entire
27456 first glyph, and then it->current_x would have been
27457 greater or equal to it->first_visible_x. */
27458 if (it->current_x < it->first_visible_x)
27459 width -= it->first_visible_x - it->current_x;
27460 eassert (width > 0);
27462 glyph->charpos = CHARPOS (it->position);
27463 glyph->object = object;
27464 /* FIXME: It would be better to use TYPE_MAX here, but
27465 __typeof__ is not portable enough... */
27466 glyph->pixel_width = clip_to_bounds (-1, width, SHRT_MAX);
27467 glyph->ascent = ascent;
27468 glyph->descent = height - ascent;
27469 glyph->voffset = it->voffset;
27470 glyph->type = STRETCH_GLYPH;
27471 glyph->avoid_cursor_p = it->avoid_cursor_p;
27472 glyph->multibyte_p = it->multibyte_p;
27473 if (it->glyph_row->reversed_p && area == TEXT_AREA)
27475 /* In R2L rows, the left and the right box edges need to be
27476 drawn in reverse direction. */
27477 glyph->right_box_line_p = it->start_of_box_run_p;
27478 glyph->left_box_line_p = it->end_of_box_run_p;
27480 else
27482 glyph->left_box_line_p = it->start_of_box_run_p;
27483 glyph->right_box_line_p = it->end_of_box_run_p;
27485 glyph->overlaps_vertically_p = false;
27486 glyph->padding_p = false;
27487 glyph->glyph_not_available_p = false;
27488 glyph->face_id = it->face_id;
27489 glyph->u.stretch.ascent = ascent;
27490 glyph->u.stretch.height = height;
27491 glyph->slice.img = null_glyph_slice;
27492 glyph->font_type = FONT_TYPE_UNKNOWN;
27493 if (it->bidi_p)
27495 glyph->resolved_level = it->bidi_it.resolved_level;
27496 eassert ((it->bidi_it.type & 7) == it->bidi_it.type);
27497 glyph->bidi_type = it->bidi_it.type;
27499 else
27501 glyph->resolved_level = 0;
27502 glyph->bidi_type = UNKNOWN_BT;
27504 ++it->glyph_row->used[area];
27506 else
27507 IT_EXPAND_MATRIX_WIDTH (it, area);
27510 #endif /* HAVE_WINDOW_SYSTEM */
27512 /* Produce a stretch glyph for iterator IT. IT->object is the value
27513 of the glyph property displayed. The value must be a list
27514 `(space KEYWORD VALUE ...)' with the following KEYWORD/VALUE pairs
27515 being recognized:
27517 1. `:width WIDTH' specifies that the space should be WIDTH *
27518 canonical char width wide. WIDTH may be an integer or floating
27519 point number.
27521 2. `:relative-width FACTOR' specifies that the width of the stretch
27522 should be computed from the width of the first character having the
27523 `glyph' property, and should be FACTOR times that width.
27525 3. `:align-to HPOS' specifies that the space should be wide enough
27526 to reach HPOS, a value in canonical character units.
27528 Exactly one of the above pairs must be present.
27530 4. `:height HEIGHT' specifies that the height of the stretch produced
27531 should be HEIGHT, measured in canonical character units.
27533 5. `:relative-height FACTOR' specifies that the height of the
27534 stretch should be FACTOR times the height of the characters having
27535 the glyph property.
27537 Either none or exactly one of 4 or 5 must be present.
27539 6. `:ascent ASCENT' specifies that ASCENT percent of the height
27540 of the stretch should be used for the ascent of the stretch.
27541 ASCENT must be in the range 0 <= ASCENT <= 100. */
27543 void
27544 produce_stretch_glyph (struct it *it)
27546 /* (space :width WIDTH :height HEIGHT ...) */
27547 Lisp_Object prop, plist;
27548 int width = 0, height = 0, align_to = -1;
27549 bool zero_width_ok_p = false;
27550 double tem;
27551 struct font *font = NULL;
27553 #ifdef HAVE_WINDOW_SYSTEM
27554 int ascent = 0;
27555 bool zero_height_ok_p = false;
27557 if (FRAME_WINDOW_P (it->f))
27559 struct face *face = FACE_FROM_ID (it->f, it->face_id);
27560 font = face->font ? face->font : FRAME_FONT (it->f);
27561 prepare_face_for_display (it->f, face);
27563 #endif
27565 /* List should start with `space'. */
27566 eassert (CONSP (it->object) && EQ (XCAR (it->object), Qspace));
27567 plist = XCDR (it->object);
27569 /* Compute the width of the stretch. */
27570 if ((prop = Fplist_get (plist, QCwidth), !NILP (prop))
27571 && calc_pixel_width_or_height (&tem, it, prop, font, true, 0))
27573 /* Absolute width `:width WIDTH' specified and valid. */
27574 zero_width_ok_p = true;
27575 width = (int)tem;
27577 else if (prop = Fplist_get (plist, QCrelative_width), NUMVAL (prop) > 0)
27579 /* Relative width `:relative-width FACTOR' specified and valid.
27580 Compute the width of the characters having the `glyph'
27581 property. */
27582 struct it it2;
27583 unsigned char *p = BYTE_POS_ADDR (IT_BYTEPOS (*it));
27585 it2 = *it;
27586 if (it->multibyte_p)
27587 it2.c = it2.char_to_display = STRING_CHAR_AND_LENGTH (p, it2.len);
27588 else
27590 it2.c = it2.char_to_display = *p, it2.len = 1;
27591 if (! ASCII_CHAR_P (it2.c))
27592 it2.char_to_display = BYTE8_TO_CHAR (it2.c);
27595 it2.glyph_row = NULL;
27596 it2.what = IT_CHARACTER;
27597 PRODUCE_GLYPHS (&it2);
27598 width = NUMVAL (prop) * it2.pixel_width;
27600 else if ((prop = Fplist_get (plist, QCalign_to), !NILP (prop))
27601 && calc_pixel_width_or_height (&tem, it, prop, font, true,
27602 &align_to))
27604 if (it->glyph_row == NULL || !it->glyph_row->mode_line_p)
27605 align_to = (align_to < 0
27607 : align_to - window_box_left_offset (it->w, TEXT_AREA));
27608 else if (align_to < 0)
27609 align_to = window_box_left_offset (it->w, TEXT_AREA);
27610 width = max (0, (int)tem + align_to - it->current_x);
27611 zero_width_ok_p = true;
27613 else
27614 /* Nothing specified -> width defaults to canonical char width. */
27615 width = FRAME_COLUMN_WIDTH (it->f);
27617 if (width <= 0 && (width < 0 || !zero_width_ok_p))
27618 width = 1;
27620 #ifdef HAVE_WINDOW_SYSTEM
27621 /* Compute height. */
27622 if (FRAME_WINDOW_P (it->f))
27624 int default_height = normal_char_height (font, ' ');
27626 if ((prop = Fplist_get (plist, QCheight), !NILP (prop))
27627 && calc_pixel_width_or_height (&tem, it, prop, font, false, 0))
27629 height = (int)tem;
27630 zero_height_ok_p = true;
27632 else if (prop = Fplist_get (plist, QCrelative_height),
27633 NUMVAL (prop) > 0)
27634 height = default_height * NUMVAL (prop);
27635 else
27636 height = default_height;
27638 if (height <= 0 && (height < 0 || !zero_height_ok_p))
27639 height = 1;
27641 /* Compute percentage of height used for ascent. If
27642 `:ascent ASCENT' is present and valid, use that. Otherwise,
27643 derive the ascent from the font in use. */
27644 if (prop = Fplist_get (plist, QCascent),
27645 NUMVAL (prop) > 0 && NUMVAL (prop) <= 100)
27646 ascent = height * NUMVAL (prop) / 100.0;
27647 else if (!NILP (prop)
27648 && calc_pixel_width_or_height (&tem, it, prop, font, false, 0))
27649 ascent = min (max (0, (int)tem), height);
27650 else
27651 ascent = (height * FONT_BASE (font)) / FONT_HEIGHT (font);
27653 else
27654 #endif /* HAVE_WINDOW_SYSTEM */
27655 height = 1;
27657 if (width > 0 && it->line_wrap != TRUNCATE
27658 && it->current_x + width > it->last_visible_x)
27660 width = it->last_visible_x - it->current_x;
27661 #ifdef HAVE_WINDOW_SYSTEM
27662 /* Subtract one more pixel from the stretch width, but only on
27663 GUI frames, since on a TTY each glyph is one "pixel" wide. */
27664 width -= FRAME_WINDOW_P (it->f);
27665 #endif
27668 if (width > 0 && height > 0 && it->glyph_row)
27670 Lisp_Object o_object = it->object;
27671 Lisp_Object object = it->stack[it->sp - 1].string;
27672 int n = width;
27674 if (!STRINGP (object))
27675 object = it->w->contents;
27676 #ifdef HAVE_WINDOW_SYSTEM
27677 if (FRAME_WINDOW_P (it->f))
27678 append_stretch_glyph (it, object, width, height, ascent);
27679 else
27680 #endif
27682 it->object = object;
27683 it->char_to_display = ' ';
27684 it->pixel_width = it->len = 1;
27685 while (n--)
27686 tty_append_glyph (it);
27687 it->object = o_object;
27691 it->pixel_width = width;
27692 #ifdef HAVE_WINDOW_SYSTEM
27693 if (FRAME_WINDOW_P (it->f))
27695 it->ascent = it->phys_ascent = ascent;
27696 it->descent = it->phys_descent = height - it->ascent;
27697 it->nglyphs = width > 0 && height > 0;
27698 take_vertical_position_into_account (it);
27700 else
27701 #endif
27702 it->nglyphs = width;
27705 /* Get information about special display element WHAT in an
27706 environment described by IT. WHAT is one of IT_TRUNCATION or
27707 IT_CONTINUATION. Maybe produce glyphs for WHAT if IT has a
27708 non-null glyph_row member. This function ensures that fields like
27709 face_id, c, len of IT are left untouched. */
27711 static void
27712 produce_special_glyphs (struct it *it, enum display_element_type what)
27714 struct it temp_it;
27715 Lisp_Object gc;
27716 GLYPH glyph;
27718 temp_it = *it;
27719 temp_it.object = Qnil;
27720 memset (&temp_it.current, 0, sizeof temp_it.current);
27722 if (what == IT_CONTINUATION)
27724 /* Continuation glyph. For R2L lines, we mirror it by hand. */
27725 if (it->bidi_it.paragraph_dir == R2L)
27726 SET_GLYPH_FROM_CHAR (glyph, '/');
27727 else
27728 SET_GLYPH_FROM_CHAR (glyph, '\\');
27729 if (it->dp
27730 && (gc = DISP_CONTINUE_GLYPH (it->dp), GLYPH_CODE_P (gc)))
27732 /* FIXME: Should we mirror GC for R2L lines? */
27733 SET_GLYPH_FROM_GLYPH_CODE (glyph, gc);
27734 spec_glyph_lookup_face (XWINDOW (it->window), &glyph);
27737 else if (what == IT_TRUNCATION)
27739 /* Truncation glyph. */
27740 SET_GLYPH_FROM_CHAR (glyph, '$');
27741 if (it->dp
27742 && (gc = DISP_TRUNC_GLYPH (it->dp), GLYPH_CODE_P (gc)))
27744 /* FIXME: Should we mirror GC for R2L lines? */
27745 SET_GLYPH_FROM_GLYPH_CODE (glyph, gc);
27746 spec_glyph_lookup_face (XWINDOW (it->window), &glyph);
27749 else
27750 emacs_abort ();
27752 #ifdef HAVE_WINDOW_SYSTEM
27753 /* On a GUI frame, when the right fringe (left fringe for R2L rows)
27754 is turned off, we precede the truncation/continuation glyphs by a
27755 stretch glyph whose width is computed such that these special
27756 glyphs are aligned at the window margin, even when very different
27757 fonts are used in different glyph rows. */
27758 if (FRAME_WINDOW_P (temp_it.f)
27759 /* init_iterator calls this with it->glyph_row == NULL, and it
27760 wants only the pixel width of the truncation/continuation
27761 glyphs. */
27762 && temp_it.glyph_row
27763 /* insert_left_trunc_glyphs calls us at the beginning of the
27764 row, and it has its own calculation of the stretch glyph
27765 width. */
27766 && temp_it.glyph_row->used[TEXT_AREA] > 0
27767 && (temp_it.glyph_row->reversed_p
27768 ? WINDOW_LEFT_FRINGE_WIDTH (temp_it.w)
27769 : WINDOW_RIGHT_FRINGE_WIDTH (temp_it.w)) == 0)
27771 int stretch_width = temp_it.last_visible_x - temp_it.current_x;
27773 if (stretch_width > 0)
27775 struct face *face = FACE_FROM_ID (temp_it.f, temp_it.face_id);
27776 struct font *font =
27777 face->font ? face->font : FRAME_FONT (temp_it.f);
27778 int stretch_ascent =
27779 (((temp_it.ascent + temp_it.descent)
27780 * FONT_BASE (font)) / FONT_HEIGHT (font));
27782 append_stretch_glyph (&temp_it, Qnil, stretch_width,
27783 temp_it.ascent + temp_it.descent,
27784 stretch_ascent);
27787 #endif
27789 temp_it.dp = NULL;
27790 temp_it.what = IT_CHARACTER;
27791 temp_it.c = temp_it.char_to_display = GLYPH_CHAR (glyph);
27792 temp_it.face_id = GLYPH_FACE (glyph);
27793 temp_it.len = CHAR_BYTES (temp_it.c);
27795 PRODUCE_GLYPHS (&temp_it);
27796 it->pixel_width = temp_it.pixel_width;
27797 it->nglyphs = temp_it.nglyphs;
27800 #ifdef HAVE_WINDOW_SYSTEM
27802 /* Calculate line-height and line-spacing properties.
27803 An integer value specifies explicit pixel value.
27804 A float value specifies relative value to current face height.
27805 A cons (float . face-name) specifies relative value to
27806 height of specified face font.
27808 Returns height in pixels, or nil. */
27810 static Lisp_Object
27811 calc_line_height_property (struct it *it, Lisp_Object val, struct font *font,
27812 int boff, bool override)
27814 Lisp_Object face_name = Qnil;
27815 int ascent, descent, height;
27817 if (NILP (val) || INTEGERP (val) || (override && EQ (val, Qt)))
27818 return val;
27820 if (CONSP (val))
27822 face_name = XCAR (val);
27823 val = XCDR (val);
27824 if (!NUMBERP (val))
27825 val = make_number (1);
27826 if (NILP (face_name))
27828 height = it->ascent + it->descent;
27829 goto scale;
27833 if (NILP (face_name))
27835 font = FRAME_FONT (it->f);
27836 boff = FRAME_BASELINE_OFFSET (it->f);
27838 else if (EQ (face_name, Qt))
27840 override = false;
27842 else
27844 int face_id;
27845 struct face *face;
27847 face_id = lookup_named_face (it->f, face_name, false);
27848 face = FACE_FROM_ID_OR_NULL (it->f, face_id);
27849 if (face == NULL || ((font = face->font) == NULL))
27850 return make_number (-1);
27851 boff = font->baseline_offset;
27852 if (font->vertical_centering)
27853 boff = VCENTER_BASELINE_OFFSET (font, it->f) - boff;
27856 normal_char_ascent_descent (font, -1, &ascent, &descent);
27858 if (override)
27860 it->override_ascent = ascent;
27861 it->override_descent = descent;
27862 it->override_boff = boff;
27865 height = ascent + descent;
27867 scale:
27868 if (FLOATP (val))
27869 height = (int)(XFLOAT_DATA (val) * height);
27870 else if (INTEGERP (val))
27871 height *= XINT (val);
27873 return make_number (height);
27877 /* Append a glyph for a glyphless character to IT->glyph_row. FACE_ID
27878 is a face ID to be used for the glyph. FOR_NO_FONT is true if
27879 and only if this is for a character for which no font was found.
27881 If the display method (it->glyphless_method) is
27882 GLYPHLESS_DISPLAY_ACRONYM or GLYPHLESS_DISPLAY_HEX_CODE, LEN is a
27883 length of the acronym or the hexadecimal string, UPPER_XOFF and
27884 UPPER_YOFF are pixel offsets for the upper part of the string,
27885 LOWER_XOFF and LOWER_YOFF are for the lower part.
27887 For the other display methods, LEN through LOWER_YOFF are zero. */
27889 static void
27890 append_glyphless_glyph (struct it *it, int face_id, bool for_no_font, int len,
27891 short upper_xoff, short upper_yoff,
27892 short lower_xoff, short lower_yoff)
27894 struct glyph *glyph;
27895 enum glyph_row_area area = it->area;
27897 glyph = it->glyph_row->glyphs[area] + it->glyph_row->used[area];
27898 if (glyph < it->glyph_row->glyphs[area + 1])
27900 /* If the glyph row is reversed, we need to prepend the glyph
27901 rather than append it. */
27902 if (it->glyph_row->reversed_p && area == TEXT_AREA)
27904 struct glyph *g;
27906 /* Make room for the additional glyph. */
27907 for (g = glyph - 1; g >= it->glyph_row->glyphs[area]; g--)
27908 g[1] = *g;
27909 glyph = it->glyph_row->glyphs[area];
27911 glyph->charpos = CHARPOS (it->position);
27912 glyph->object = it->object;
27913 eassert (it->pixel_width <= SHRT_MAX);
27914 glyph->pixel_width = it->pixel_width;
27915 glyph->ascent = it->ascent;
27916 glyph->descent = it->descent;
27917 glyph->voffset = it->voffset;
27918 glyph->type = GLYPHLESS_GLYPH;
27919 glyph->u.glyphless.method = it->glyphless_method;
27920 glyph->u.glyphless.for_no_font = for_no_font;
27921 glyph->u.glyphless.len = len;
27922 glyph->u.glyphless.ch = it->c;
27923 glyph->slice.glyphless.upper_xoff = upper_xoff;
27924 glyph->slice.glyphless.upper_yoff = upper_yoff;
27925 glyph->slice.glyphless.lower_xoff = lower_xoff;
27926 glyph->slice.glyphless.lower_yoff = lower_yoff;
27927 glyph->avoid_cursor_p = it->avoid_cursor_p;
27928 glyph->multibyte_p = it->multibyte_p;
27929 if (it->glyph_row->reversed_p && area == TEXT_AREA)
27931 /* In R2L rows, the left and the right box edges need to be
27932 drawn in reverse direction. */
27933 glyph->right_box_line_p = it->start_of_box_run_p;
27934 glyph->left_box_line_p = it->end_of_box_run_p;
27936 else
27938 glyph->left_box_line_p = it->start_of_box_run_p;
27939 glyph->right_box_line_p = it->end_of_box_run_p;
27941 glyph->overlaps_vertically_p = (it->phys_ascent > it->ascent
27942 || it->phys_descent > it->descent);
27943 glyph->padding_p = false;
27944 glyph->glyph_not_available_p = false;
27945 glyph->face_id = face_id;
27946 glyph->font_type = FONT_TYPE_UNKNOWN;
27947 if (it->bidi_p)
27949 glyph->resolved_level = it->bidi_it.resolved_level;
27950 eassert ((it->bidi_it.type & 7) == it->bidi_it.type);
27951 glyph->bidi_type = it->bidi_it.type;
27953 ++it->glyph_row->used[area];
27955 else
27956 IT_EXPAND_MATRIX_WIDTH (it, area);
27960 /* Produce a glyph for a glyphless character for iterator IT.
27961 IT->glyphless_method specifies which method to use for displaying
27962 the character. See the description of enum
27963 glyphless_display_method in dispextern.h for the detail.
27965 FOR_NO_FONT is true if and only if this is for a character for
27966 which no font was found. ACRONYM, if non-nil, is an acronym string
27967 for the character. */
27969 static void
27970 produce_glyphless_glyph (struct it *it, bool for_no_font, Lisp_Object acronym)
27972 int face_id;
27973 struct face *face;
27974 struct font *font;
27975 int base_width, base_height, width, height;
27976 short upper_xoff, upper_yoff, lower_xoff, lower_yoff;
27977 int len;
27979 /* Get the metrics of the base font. We always refer to the current
27980 ASCII face. */
27981 face = FACE_FROM_ID (it->f, it->face_id)->ascii_face;
27982 font = face->font ? face->font : FRAME_FONT (it->f);
27983 normal_char_ascent_descent (font, -1, &it->ascent, &it->descent);
27984 it->ascent += font->baseline_offset;
27985 it->descent -= font->baseline_offset;
27986 base_height = it->ascent + it->descent;
27987 base_width = font->average_width;
27989 face_id = merge_glyphless_glyph_face (it);
27991 if (it->glyphless_method == GLYPHLESS_DISPLAY_THIN_SPACE)
27993 it->pixel_width = THIN_SPACE_WIDTH;
27994 len = 0;
27995 upper_xoff = upper_yoff = lower_xoff = lower_yoff = 0;
27997 else if (it->glyphless_method == GLYPHLESS_DISPLAY_EMPTY_BOX)
27999 width = CHARACTER_WIDTH (it->c);
28000 if (width == 0)
28001 width = 1;
28002 else if (width > 4)
28003 width = 4;
28004 it->pixel_width = base_width * width;
28005 len = 0;
28006 upper_xoff = upper_yoff = lower_xoff = lower_yoff = 0;
28008 else
28010 char buf[7];
28011 const char *str;
28012 unsigned int code[6];
28013 int upper_len;
28014 int ascent, descent;
28015 struct font_metrics metrics_upper, metrics_lower;
28017 face = FACE_FROM_ID (it->f, face_id);
28018 font = face->font ? face->font : FRAME_FONT (it->f);
28019 prepare_face_for_display (it->f, face);
28021 if (it->glyphless_method == GLYPHLESS_DISPLAY_ACRONYM)
28023 if (! STRINGP (acronym) && CHAR_TABLE_P (Vglyphless_char_display))
28024 acronym = CHAR_TABLE_REF (Vglyphless_char_display, it->c);
28025 if (CONSP (acronym))
28026 acronym = XCAR (acronym);
28027 str = STRINGP (acronym) ? SSDATA (acronym) : "";
28029 else
28031 eassert (it->glyphless_method == GLYPHLESS_DISPLAY_HEX_CODE);
28032 sprintf (buf, "%0*X", it->c < 0x10000 ? 4 : 6, it->c + 0u);
28033 str = buf;
28035 for (len = 0; str[len] && ASCII_CHAR_P (str[len]) && len < 6; len++)
28036 code[len] = font->driver->encode_char (font, str[len]);
28037 upper_len = (len + 1) / 2;
28038 font->driver->text_extents (font, code, upper_len,
28039 &metrics_upper);
28040 font->driver->text_extents (font, code + upper_len, len - upper_len,
28041 &metrics_lower);
28045 /* +4 is for vertical bars of a box plus 1-pixel spaces at both side. */
28046 width = max (metrics_upper.width, metrics_lower.width) + 4;
28047 upper_xoff = upper_yoff = 2; /* the typical case */
28048 if (base_width >= width)
28050 /* Align the upper to the left, the lower to the right. */
28051 it->pixel_width = base_width;
28052 lower_xoff = base_width - 2 - metrics_lower.width;
28054 else
28056 /* Center the shorter one. */
28057 it->pixel_width = width;
28058 if (metrics_upper.width >= metrics_lower.width)
28059 lower_xoff = (width - metrics_lower.width) / 2;
28060 else
28062 /* FIXME: This code doesn't look right. It formerly was
28063 missing the "lower_xoff = 0;", which couldn't have
28064 been right since it left lower_xoff uninitialized. */
28065 lower_xoff = 0;
28066 upper_xoff = (width - metrics_upper.width) / 2;
28070 /* +5 is for horizontal bars of a box plus 1-pixel spaces at
28071 top, bottom, and between upper and lower strings. */
28072 height = (metrics_upper.ascent + metrics_upper.descent
28073 + metrics_lower.ascent + metrics_lower.descent) + 5;
28074 /* Center vertically.
28075 H:base_height, D:base_descent
28076 h:height, ld:lower_descent, la:lower_ascent, ud:upper_descent
28078 ascent = - (D - H/2 - h/2 + 1); "+ 1" for rounding up
28079 descent = D - H/2 + h/2;
28080 lower_yoff = descent - 2 - ld;
28081 upper_yoff = lower_yoff - la - 1 - ud; */
28082 ascent = - (it->descent - (base_height + height + 1) / 2);
28083 descent = it->descent - (base_height - height) / 2;
28084 lower_yoff = descent - 2 - metrics_lower.descent;
28085 upper_yoff = (lower_yoff - metrics_lower.ascent - 1
28086 - metrics_upper.descent);
28087 /* Don't make the height shorter than the base height. */
28088 if (height > base_height)
28090 it->ascent = ascent;
28091 it->descent = descent;
28095 it->phys_ascent = it->ascent;
28096 it->phys_descent = it->descent;
28097 if (it->glyph_row)
28098 append_glyphless_glyph (it, face_id, for_no_font, len,
28099 upper_xoff, upper_yoff,
28100 lower_xoff, lower_yoff);
28101 it->nglyphs = 1;
28102 take_vertical_position_into_account (it);
28106 /* RIF:
28107 Produce glyphs/get display metrics for the display element IT is
28108 loaded with. See the description of struct it in dispextern.h
28109 for an overview of struct it. */
28111 void
28112 x_produce_glyphs (struct it *it)
28114 int extra_line_spacing = it->extra_line_spacing;
28116 it->glyph_not_available_p = false;
28118 if (it->what == IT_CHARACTER)
28120 XChar2b char2b;
28121 struct face *face = FACE_FROM_ID (it->f, it->face_id);
28122 struct font *font = face->font;
28123 struct font_metrics *pcm = NULL;
28124 int boff; /* Baseline offset. */
28126 if (font == NULL)
28128 /* When no suitable font is found, display this character by
28129 the method specified in the first extra slot of
28130 Vglyphless_char_display. */
28131 Lisp_Object acronym = lookup_glyphless_char_display (-1, it);
28133 eassert (it->what == IT_GLYPHLESS);
28134 produce_glyphless_glyph (it, true,
28135 STRINGP (acronym) ? acronym : Qnil);
28136 goto done;
28139 boff = font->baseline_offset;
28140 if (font->vertical_centering)
28141 boff = VCENTER_BASELINE_OFFSET (font, it->f) - boff;
28143 if (it->char_to_display != '\n' && it->char_to_display != '\t')
28145 it->nglyphs = 1;
28147 if (it->override_ascent >= 0)
28149 it->ascent = it->override_ascent;
28150 it->descent = it->override_descent;
28151 boff = it->override_boff;
28153 else
28155 it->ascent = FONT_BASE (font) + boff;
28156 it->descent = FONT_DESCENT (font) - boff;
28159 if (get_char_glyph_code (it->char_to_display, font, &char2b))
28161 pcm = get_per_char_metric (font, &char2b);
28162 if (pcm->width == 0
28163 && pcm->rbearing == 0 && pcm->lbearing == 0)
28164 pcm = NULL;
28167 if (pcm)
28169 it->phys_ascent = pcm->ascent + boff;
28170 it->phys_descent = pcm->descent - boff;
28171 it->pixel_width = pcm->width;
28172 /* Don't use font-global values for ascent and descent
28173 if they result in an exceedingly large line height. */
28174 if (it->override_ascent < 0)
28176 if (FONT_TOO_HIGH (font))
28178 it->ascent = it->phys_ascent;
28179 it->descent = it->phys_descent;
28180 /* These limitations are enforced by an
28181 assertion near the end of this function. */
28182 if (it->ascent < 0)
28183 it->ascent = 0;
28184 if (it->descent < 0)
28185 it->descent = 0;
28189 else
28191 it->glyph_not_available_p = true;
28192 it->phys_ascent = it->ascent;
28193 it->phys_descent = it->descent;
28194 it->pixel_width = font->space_width;
28197 if (it->constrain_row_ascent_descent_p)
28199 if (it->descent > it->max_descent)
28201 it->ascent += it->descent - it->max_descent;
28202 it->descent = it->max_descent;
28204 if (it->ascent > it->max_ascent)
28206 it->descent = min (it->max_descent, it->descent + it->ascent - it->max_ascent);
28207 it->ascent = it->max_ascent;
28209 it->phys_ascent = min (it->phys_ascent, it->ascent);
28210 it->phys_descent = min (it->phys_descent, it->descent);
28211 extra_line_spacing = 0;
28214 /* If this is a space inside a region of text with
28215 `space-width' property, change its width. */
28216 bool stretched_p
28217 = it->char_to_display == ' ' && !NILP (it->space_width);
28218 if (stretched_p)
28219 it->pixel_width *= XFLOATINT (it->space_width);
28221 /* If face has a box, add the box thickness to the character
28222 height. If character has a box line to the left and/or
28223 right, add the box line width to the character's width. */
28224 if (face->box != FACE_NO_BOX)
28226 int thick = face->box_line_width;
28228 if (thick > 0)
28230 it->ascent += thick;
28231 it->descent += thick;
28233 else
28234 thick = -thick;
28236 if (it->start_of_box_run_p)
28237 it->pixel_width += thick;
28238 if (it->end_of_box_run_p)
28239 it->pixel_width += thick;
28242 /* If face has an overline, add the height of the overline
28243 (1 pixel) and a 1 pixel margin to the character height. */
28244 if (face->overline_p)
28245 it->ascent += overline_margin;
28247 if (it->constrain_row_ascent_descent_p)
28249 if (it->ascent > it->max_ascent)
28250 it->ascent = it->max_ascent;
28251 if (it->descent > it->max_descent)
28252 it->descent = it->max_descent;
28255 take_vertical_position_into_account (it);
28257 /* If we have to actually produce glyphs, do it. */
28258 if (it->glyph_row)
28260 if (stretched_p)
28262 /* Translate a space with a `space-width' property
28263 into a stretch glyph. */
28264 int ascent = (((it->ascent + it->descent) * FONT_BASE (font))
28265 / FONT_HEIGHT (font));
28266 append_stretch_glyph (it, it->object, it->pixel_width,
28267 it->ascent + it->descent, ascent);
28269 else
28270 append_glyph (it);
28272 /* If characters with lbearing or rbearing are displayed
28273 in this line, record that fact in a flag of the
28274 glyph row. This is used to optimize X output code. */
28275 if (pcm && (pcm->lbearing < 0 || pcm->rbearing > pcm->width))
28276 it->glyph_row->contains_overlapping_glyphs_p = true;
28278 if (! stretched_p && it->pixel_width == 0)
28279 /* We assure that all visible glyphs have at least 1-pixel
28280 width. */
28281 it->pixel_width = 1;
28283 else if (it->char_to_display == '\n')
28285 /* A newline has no width, but we need the height of the
28286 line. But if previous part of the line sets a height,
28287 don't increase that height. */
28289 Lisp_Object height;
28290 Lisp_Object total_height = Qnil;
28292 it->override_ascent = -1;
28293 it->pixel_width = 0;
28294 it->nglyphs = 0;
28296 height = get_it_property (it, Qline_height);
28297 /* Split (line-height total-height) list. */
28298 if (CONSP (height)
28299 && CONSP (XCDR (height))
28300 && NILP (XCDR (XCDR (height))))
28302 total_height = XCAR (XCDR (height));
28303 height = XCAR (height);
28305 height = calc_line_height_property (it, height, font, boff, true);
28307 if (it->override_ascent >= 0)
28309 it->ascent = it->override_ascent;
28310 it->descent = it->override_descent;
28311 boff = it->override_boff;
28313 else
28315 if (FONT_TOO_HIGH (font))
28317 it->ascent = font->pixel_size + boff - 1;
28318 it->descent = -boff + 1;
28319 if (it->descent < 0)
28320 it->descent = 0;
28322 else
28324 it->ascent = FONT_BASE (font) + boff;
28325 it->descent = FONT_DESCENT (font) - boff;
28329 if (EQ (height, Qt))
28331 if (it->descent > it->max_descent)
28333 it->ascent += it->descent - it->max_descent;
28334 it->descent = it->max_descent;
28336 if (it->ascent > it->max_ascent)
28338 it->descent = min (it->max_descent, it->descent + it->ascent - it->max_ascent);
28339 it->ascent = it->max_ascent;
28341 it->phys_ascent = min (it->phys_ascent, it->ascent);
28342 it->phys_descent = min (it->phys_descent, it->descent);
28343 it->constrain_row_ascent_descent_p = true;
28344 extra_line_spacing = 0;
28346 else
28348 Lisp_Object spacing;
28350 it->phys_ascent = it->ascent;
28351 it->phys_descent = it->descent;
28353 if ((it->max_ascent > 0 || it->max_descent > 0)
28354 && face->box != FACE_NO_BOX
28355 && face->box_line_width > 0)
28357 it->ascent += face->box_line_width;
28358 it->descent += face->box_line_width;
28360 if (!NILP (height)
28361 && XINT (height) > it->ascent + it->descent)
28362 it->ascent = XINT (height) - it->descent;
28364 if (!NILP (total_height))
28365 spacing = calc_line_height_property (it, total_height, font,
28366 boff, false);
28367 else
28369 spacing = get_it_property (it, Qline_spacing);
28370 spacing = calc_line_height_property (it, spacing, font,
28371 boff, false);
28373 if (INTEGERP (spacing))
28375 extra_line_spacing = XINT (spacing);
28376 if (!NILP (total_height))
28377 extra_line_spacing -= (it->phys_ascent + it->phys_descent);
28381 else /* i.e. (it->char_to_display == '\t') */
28383 if (font->space_width > 0)
28385 int tab_width = it->tab_width * font->space_width;
28386 int x = it->current_x + it->continuation_lines_width;
28387 int x0 = x;
28388 /* Adjust for line numbers, if needed. */
28389 if (!NILP (Vdisplay_line_numbers) && it->line_number_produced_p)
28391 x -= it->lnum_pixel_width;
28392 /* Restore the original TAB width, if required. */
28393 if (x + it->tab_offset >= it->first_visible_x)
28394 x += it->tab_offset;
28397 int next_tab_x = ((1 + x + tab_width - 1) / tab_width) * tab_width;
28399 /* If the distance from the current position to the next tab
28400 stop is less than a space character width, use the
28401 tab stop after that. */
28402 if (next_tab_x - x < font->space_width)
28403 next_tab_x += tab_width;
28404 if (!NILP (Vdisplay_line_numbers) && it->line_number_produced_p)
28406 next_tab_x += it->lnum_pixel_width;
28407 /* If the line is hscrolled, and the TAB starts before
28408 the first visible pixel, simulate negative row->x. */
28409 if (x < it->first_visible_x)
28411 next_tab_x -= it->first_visible_x - x;
28412 it->tab_offset = it->first_visible_x - x;
28414 else
28415 next_tab_x -= it->tab_offset;
28418 it->pixel_width = next_tab_x - x0;
28419 it->nglyphs = 1;
28420 if (FONT_TOO_HIGH (font))
28422 if (get_char_glyph_code (' ', font, &char2b))
28424 pcm = get_per_char_metric (font, &char2b);
28425 if (pcm->width == 0
28426 && pcm->rbearing == 0 && pcm->lbearing == 0)
28427 pcm = NULL;
28430 if (pcm)
28432 it->ascent = pcm->ascent + boff;
28433 it->descent = pcm->descent - boff;
28435 else
28437 it->ascent = font->pixel_size + boff - 1;
28438 it->descent = -boff + 1;
28440 if (it->ascent < 0)
28441 it->ascent = 0;
28442 if (it->descent < 0)
28443 it->descent = 0;
28445 else
28447 it->ascent = FONT_BASE (font) + boff;
28448 it->descent = FONT_DESCENT (font) - boff;
28450 it->phys_ascent = it->ascent;
28451 it->phys_descent = it->descent;
28453 if (it->glyph_row)
28455 append_stretch_glyph (it, it->object, it->pixel_width,
28456 it->ascent + it->descent, it->ascent);
28459 else
28461 it->pixel_width = 0;
28462 it->nglyphs = 1;
28466 if (FONT_TOO_HIGH (font))
28468 int font_ascent, font_descent;
28470 /* For very large fonts, where we ignore the declared font
28471 dimensions, and go by per-character metrics instead,
28472 don't let the row ascent and descent values (and the row
28473 height computed from them) be smaller than the "normal"
28474 character metrics. This avoids unpleasant effects
28475 whereby lines on display would change their height
28476 depending on which characters are shown. */
28477 normal_char_ascent_descent (font, -1, &font_ascent, &font_descent);
28478 it->max_ascent = max (it->max_ascent, font_ascent);
28479 it->max_descent = max (it->max_descent, font_descent);
28482 else if (it->what == IT_COMPOSITION && it->cmp_it.ch < 0)
28484 /* A static composition.
28486 Note: A composition is represented as one glyph in the
28487 glyph matrix. There are no padding glyphs.
28489 Important note: pixel_width, ascent, and descent are the
28490 values of what is drawn by draw_glyphs (i.e. the values of
28491 the overall glyphs composed). */
28492 struct face *face = FACE_FROM_ID (it->f, it->face_id);
28493 int boff; /* baseline offset */
28494 struct composition *cmp = composition_table[it->cmp_it.id];
28495 int glyph_len = cmp->glyph_len;
28496 struct font *font = face->font;
28498 it->nglyphs = 1;
28500 /* If we have not yet calculated pixel size data of glyphs of
28501 the composition for the current face font, calculate them
28502 now. Theoretically, we have to check all fonts for the
28503 glyphs, but that requires much time and memory space. So,
28504 here we check only the font of the first glyph. This may
28505 lead to incorrect display, but it's very rare, and C-l
28506 (recenter-top-bottom) can correct the display anyway. */
28507 if (! cmp->font || cmp->font != font)
28509 /* Ascent and descent of the font of the first character
28510 of this composition (adjusted by baseline offset).
28511 Ascent and descent of overall glyphs should not be less
28512 than these, respectively. */
28513 int font_ascent, font_descent, font_height;
28514 /* Bounding box of the overall glyphs. */
28515 int leftmost, rightmost, lowest, highest;
28516 int lbearing, rbearing;
28517 int i, width, ascent, descent;
28518 int c;
28519 XChar2b char2b;
28520 struct font_metrics *pcm;
28521 ptrdiff_t pos;
28523 eassume (0 < glyph_len); /* See Bug#8512. */
28525 c = COMPOSITION_GLYPH (cmp, glyph_len - 1);
28526 while (c == '\t' && 0 < --glyph_len);
28528 bool right_padded = glyph_len < cmp->glyph_len;
28529 for (i = 0; i < glyph_len; i++)
28531 c = COMPOSITION_GLYPH (cmp, i);
28532 if (c != '\t')
28533 break;
28534 cmp->offsets[i * 2] = cmp->offsets[i * 2 + 1] = 0;
28536 bool left_padded = i > 0;
28538 pos = (STRINGP (it->string) ? IT_STRING_CHARPOS (*it)
28539 : IT_CHARPOS (*it));
28540 /* If no suitable font is found, use the default font. */
28541 bool font_not_found_p = font == NULL;
28542 if (font_not_found_p)
28544 face = face->ascii_face;
28545 font = face->font;
28547 boff = font->baseline_offset;
28548 if (font->vertical_centering)
28549 boff = VCENTER_BASELINE_OFFSET (font, it->f) - boff;
28550 normal_char_ascent_descent (font, -1, &font_ascent, &font_descent);
28551 font_ascent += boff;
28552 font_descent -= boff;
28553 font_height = font_ascent + font_descent;
28555 cmp->font = font;
28557 pcm = NULL;
28558 if (! font_not_found_p)
28560 get_char_face_and_encoding (it->f, c, it->face_id,
28561 &char2b, false);
28562 pcm = get_per_char_metric (font, &char2b);
28565 /* Initialize the bounding box. */
28566 if (pcm)
28568 width = cmp->glyph_len > 0 ? pcm->width : 0;
28569 ascent = pcm->ascent;
28570 descent = pcm->descent;
28571 lbearing = pcm->lbearing;
28572 rbearing = pcm->rbearing;
28574 else
28576 width = cmp->glyph_len > 0 ? font->space_width : 0;
28577 ascent = FONT_BASE (font);
28578 descent = FONT_DESCENT (font);
28579 lbearing = 0;
28580 rbearing = width;
28583 rightmost = width;
28584 leftmost = 0;
28585 lowest = - descent + boff;
28586 highest = ascent + boff;
28588 if (! font_not_found_p
28589 && font->default_ascent
28590 && CHAR_TABLE_P (Vuse_default_ascent)
28591 && !NILP (Faref (Vuse_default_ascent,
28592 make_number (it->char_to_display))))
28593 highest = font->default_ascent + boff;
28595 /* Draw the first glyph at the normal position. It may be
28596 shifted to right later if some other glyphs are drawn
28597 at the left. */
28598 cmp->offsets[i * 2] = 0;
28599 cmp->offsets[i * 2 + 1] = boff;
28600 cmp->lbearing = lbearing;
28601 cmp->rbearing = rbearing;
28603 /* Set cmp->offsets for the remaining glyphs. */
28604 for (i++; i < glyph_len; i++)
28606 int left, right, btm, top;
28607 int ch = COMPOSITION_GLYPH (cmp, i);
28608 int face_id;
28609 struct face *this_face;
28611 if (ch == '\t')
28612 ch = ' ';
28613 face_id = FACE_FOR_CHAR (it->f, face, ch, pos, it->string);
28614 this_face = FACE_FROM_ID (it->f, face_id);
28615 font = this_face->font;
28617 if (font == NULL)
28618 pcm = NULL;
28619 else
28621 get_char_face_and_encoding (it->f, ch, face_id,
28622 &char2b, false);
28623 pcm = get_per_char_metric (font, &char2b);
28625 if (! pcm)
28626 cmp->offsets[i * 2] = cmp->offsets[i * 2 + 1] = 0;
28627 else
28629 width = pcm->width;
28630 ascent = pcm->ascent;
28631 descent = pcm->descent;
28632 lbearing = pcm->lbearing;
28633 rbearing = pcm->rbearing;
28634 if (cmp->method != COMPOSITION_WITH_RULE_ALTCHARS)
28636 /* Relative composition with or without
28637 alternate chars. */
28638 left = (leftmost + rightmost - width) / 2;
28639 btm = - descent + boff;
28640 if (font->relative_compose
28641 && (! CHAR_TABLE_P (Vignore_relative_composition)
28642 || NILP (Faref (Vignore_relative_composition,
28643 make_number (ch)))))
28646 if (- descent >= font->relative_compose)
28647 /* One extra pixel between two glyphs. */
28648 btm = highest + 1;
28649 else if (ascent <= 0)
28650 /* One extra pixel between two glyphs. */
28651 btm = lowest - 1 - ascent - descent;
28654 else
28656 /* A composition rule is specified by an integer
28657 value that encodes global and new reference
28658 points (GREF and NREF). GREF and NREF are
28659 specified by numbers as below:
28661 0---1---2 -- ascent
28665 9--10--11 -- center
28667 ---3---4---5--- baseline
28669 6---7---8 -- descent
28671 int rule = COMPOSITION_RULE (cmp, i);
28672 int gref, nref, grefx, grefy, nrefx, nrefy, xoff, yoff;
28674 COMPOSITION_DECODE_RULE (rule, gref, nref, xoff, yoff);
28675 grefx = gref % 3, nrefx = nref % 3;
28676 grefy = gref / 3, nrefy = nref / 3;
28677 if (xoff)
28678 xoff = font_height * (xoff - 128) / 256;
28679 if (yoff)
28680 yoff = font_height * (yoff - 128) / 256;
28682 left = (leftmost
28683 + grefx * (rightmost - leftmost) / 2
28684 - nrefx * width / 2
28685 + xoff);
28687 btm = ((grefy == 0 ? highest
28688 : grefy == 1 ? 0
28689 : grefy == 2 ? lowest
28690 : (highest + lowest) / 2)
28691 - (nrefy == 0 ? ascent + descent
28692 : nrefy == 1 ? descent - boff
28693 : nrefy == 2 ? 0
28694 : (ascent + descent) / 2)
28695 + yoff);
28698 cmp->offsets[i * 2] = left;
28699 cmp->offsets[i * 2 + 1] = btm + descent;
28701 /* Update the bounding box of the overall glyphs. */
28702 if (width > 0)
28704 right = left + width;
28705 if (left < leftmost)
28706 leftmost = left;
28707 if (right > rightmost)
28708 rightmost = right;
28710 top = btm + descent + ascent;
28711 if (top > highest)
28712 highest = top;
28713 if (btm < lowest)
28714 lowest = btm;
28716 if (cmp->lbearing > left + lbearing)
28717 cmp->lbearing = left + lbearing;
28718 if (cmp->rbearing < left + rbearing)
28719 cmp->rbearing = left + rbearing;
28723 /* If there are glyphs whose x-offsets are negative,
28724 shift all glyphs to the right and make all x-offsets
28725 non-negative. */
28726 if (leftmost < 0)
28728 for (i = 0; i < cmp->glyph_len; i++)
28729 cmp->offsets[i * 2] -= leftmost;
28730 rightmost -= leftmost;
28731 cmp->lbearing -= leftmost;
28732 cmp->rbearing -= leftmost;
28735 if (left_padded && cmp->lbearing < 0)
28737 for (i = 0; i < cmp->glyph_len; i++)
28738 cmp->offsets[i * 2] -= cmp->lbearing;
28739 rightmost -= cmp->lbearing;
28740 cmp->rbearing -= cmp->lbearing;
28741 cmp->lbearing = 0;
28743 if (right_padded && rightmost < cmp->rbearing)
28745 rightmost = cmp->rbearing;
28748 cmp->pixel_width = rightmost;
28749 cmp->ascent = highest;
28750 cmp->descent = - lowest;
28751 if (cmp->ascent < font_ascent)
28752 cmp->ascent = font_ascent;
28753 if (cmp->descent < font_descent)
28754 cmp->descent = font_descent;
28757 if (it->glyph_row
28758 && (cmp->lbearing < 0
28759 || cmp->rbearing > cmp->pixel_width))
28760 it->glyph_row->contains_overlapping_glyphs_p = true;
28762 it->pixel_width = cmp->pixel_width;
28763 it->ascent = it->phys_ascent = cmp->ascent;
28764 it->descent = it->phys_descent = cmp->descent;
28765 if (face->box != FACE_NO_BOX)
28767 int thick = face->box_line_width;
28769 if (thick > 0)
28771 it->ascent += thick;
28772 it->descent += thick;
28774 else
28775 thick = - thick;
28777 if (it->start_of_box_run_p)
28778 it->pixel_width += thick;
28779 if (it->end_of_box_run_p)
28780 it->pixel_width += thick;
28783 /* If face has an overline, add the height of the overline
28784 (1 pixel) and a 1 pixel margin to the character height. */
28785 if (face->overline_p)
28786 it->ascent += overline_margin;
28788 take_vertical_position_into_account (it);
28789 if (it->ascent < 0)
28790 it->ascent = 0;
28791 if (it->descent < 0)
28792 it->descent = 0;
28794 if (it->glyph_row && cmp->glyph_len > 0)
28795 append_composite_glyph (it);
28797 else if (it->what == IT_COMPOSITION)
28799 /* A dynamic (automatic) composition. */
28800 struct face *face = FACE_FROM_ID (it->f, it->face_id);
28801 Lisp_Object gstring;
28802 struct font_metrics metrics;
28804 it->nglyphs = 1;
28806 gstring = composition_gstring_from_id (it->cmp_it.id);
28807 it->pixel_width
28808 = composition_gstring_width (gstring, it->cmp_it.from, it->cmp_it.to,
28809 &metrics);
28810 if (it->glyph_row
28811 && (metrics.lbearing < 0 || metrics.rbearing > metrics.width))
28812 it->glyph_row->contains_overlapping_glyphs_p = true;
28813 it->ascent = it->phys_ascent = metrics.ascent;
28814 it->descent = it->phys_descent = metrics.descent;
28815 if (face->box != FACE_NO_BOX)
28817 int thick = face->box_line_width;
28819 if (thick > 0)
28821 it->ascent += thick;
28822 it->descent += thick;
28824 else
28825 thick = - thick;
28827 if (it->start_of_box_run_p)
28828 it->pixel_width += thick;
28829 if (it->end_of_box_run_p)
28830 it->pixel_width += thick;
28832 /* If face has an overline, add the height of the overline
28833 (1 pixel) and a 1 pixel margin to the character height. */
28834 if (face->overline_p)
28835 it->ascent += overline_margin;
28836 take_vertical_position_into_account (it);
28837 if (it->ascent < 0)
28838 it->ascent = 0;
28839 if (it->descent < 0)
28840 it->descent = 0;
28842 if (it->glyph_row)
28843 append_composite_glyph (it);
28845 else if (it->what == IT_GLYPHLESS)
28846 produce_glyphless_glyph (it, false, Qnil);
28847 else if (it->what == IT_IMAGE)
28848 produce_image_glyph (it);
28849 else if (it->what == IT_STRETCH)
28850 produce_stretch_glyph (it);
28851 else if (it->what == IT_XWIDGET)
28852 produce_xwidget_glyph (it);
28854 done:
28855 /* Accumulate dimensions. Note: can't assume that it->descent > 0
28856 because this isn't true for images with `:ascent 100'. */
28857 eassert (it->ascent >= 0 && it->descent >= 0);
28858 if (it->area == TEXT_AREA)
28859 it->current_x += it->pixel_width;
28861 if (extra_line_spacing > 0)
28863 it->descent += extra_line_spacing;
28864 if (extra_line_spacing > it->max_extra_line_spacing)
28865 it->max_extra_line_spacing = extra_line_spacing;
28868 it->max_ascent = max (it->max_ascent, it->ascent);
28869 it->max_descent = max (it->max_descent, it->descent);
28870 it->max_phys_ascent = max (it->max_phys_ascent, it->phys_ascent);
28871 it->max_phys_descent = max (it->max_phys_descent, it->phys_descent);
28874 /* EXPORT for RIF:
28875 Output LEN glyphs starting at START at the nominal cursor position.
28876 Advance the nominal cursor over the text. UPDATED_ROW is the glyph row
28877 being updated, and UPDATED_AREA is the area of that row being updated. */
28879 void
28880 x_write_glyphs (struct window *w, struct glyph_row *updated_row,
28881 struct glyph *start, enum glyph_row_area updated_area, int len)
28883 int x, hpos, chpos = w->phys_cursor.hpos;
28885 eassert (updated_row);
28886 /* When the window is hscrolled, cursor hpos can legitimately be out
28887 of bounds, but we draw the cursor at the corresponding window
28888 margin in that case. */
28889 if (!updated_row->reversed_p && chpos < 0)
28890 chpos = 0;
28891 if (updated_row->reversed_p && chpos >= updated_row->used[TEXT_AREA])
28892 chpos = updated_row->used[TEXT_AREA] - 1;
28894 block_input ();
28896 /* Write glyphs. */
28898 hpos = start - updated_row->glyphs[updated_area];
28899 x = draw_glyphs (w, w->output_cursor.x,
28900 updated_row, updated_area,
28901 hpos, hpos + len,
28902 DRAW_NORMAL_TEXT, 0);
28904 /* Invalidate old phys cursor if the glyph at its hpos is redrawn. */
28905 if (updated_area == TEXT_AREA
28906 && w->phys_cursor_on_p
28907 && w->phys_cursor.vpos == w->output_cursor.vpos
28908 && chpos >= hpos
28909 && chpos < hpos + len)
28910 w->phys_cursor_on_p = false;
28912 unblock_input ();
28914 /* Advance the output cursor. */
28915 w->output_cursor.hpos += len;
28916 w->output_cursor.x = x;
28920 /* EXPORT for RIF:
28921 Insert LEN glyphs from START at the nominal cursor position. */
28923 void
28924 x_insert_glyphs (struct window *w, struct glyph_row *updated_row,
28925 struct glyph *start, enum glyph_row_area updated_area, int len)
28927 struct frame *f;
28928 int line_height, shift_by_width, shifted_region_width;
28929 struct glyph_row *row;
28930 struct glyph *glyph;
28931 int frame_x, frame_y;
28932 ptrdiff_t hpos;
28934 eassert (updated_row);
28935 block_input ();
28936 f = XFRAME (WINDOW_FRAME (w));
28938 /* Get the height of the line we are in. */
28939 row = updated_row;
28940 line_height = row->height;
28942 /* Get the width of the glyphs to insert. */
28943 shift_by_width = 0;
28944 for (glyph = start; glyph < start + len; ++glyph)
28945 shift_by_width += glyph->pixel_width;
28947 /* Get the width of the region to shift right. */
28948 shifted_region_width = (window_box_width (w, updated_area)
28949 - w->output_cursor.x
28950 - shift_by_width);
28952 /* Shift right. */
28953 frame_x = window_box_left (w, updated_area) + w->output_cursor.x;
28954 frame_y = WINDOW_TO_FRAME_PIXEL_Y (w, w->output_cursor.y);
28956 FRAME_RIF (f)->shift_glyphs_for_insert (f, frame_x, frame_y, shifted_region_width,
28957 line_height, shift_by_width);
28959 /* Write the glyphs. */
28960 hpos = start - row->glyphs[updated_area];
28961 draw_glyphs (w, w->output_cursor.x, row, updated_area,
28962 hpos, hpos + len,
28963 DRAW_NORMAL_TEXT, 0);
28965 /* Advance the output cursor. */
28966 w->output_cursor.hpos += len;
28967 w->output_cursor.x += shift_by_width;
28968 unblock_input ();
28972 /* EXPORT for RIF:
28973 Erase the current text line from the nominal cursor position
28974 (inclusive) to pixel column TO_X (exclusive). The idea is that
28975 everything from TO_X onward is already erased.
28977 TO_X is a pixel position relative to UPDATED_AREA of currently
28978 updated window W. TO_X == -1 means clear to the end of this area. */
28980 void
28981 x_clear_end_of_line (struct window *w, struct glyph_row *updated_row,
28982 enum glyph_row_area updated_area, int to_x)
28984 struct frame *f;
28985 int max_x, min_y, max_y;
28986 int from_x, from_y, to_y;
28988 eassert (updated_row);
28989 f = XFRAME (w->frame);
28991 if (updated_row->full_width_p)
28992 max_x = (WINDOW_PIXEL_WIDTH (w)
28993 - (updated_row->mode_line_p ? WINDOW_RIGHT_DIVIDER_WIDTH (w) : 0));
28994 else
28995 max_x = window_box_width (w, updated_area);
28996 max_y = window_text_bottom_y (w);
28998 /* TO_X == 0 means don't do anything. TO_X < 0 means clear to end
28999 of window. For TO_X > 0, truncate to end of drawing area. */
29000 if (to_x == 0)
29001 return;
29002 else if (to_x < 0)
29003 to_x = max_x;
29004 else
29005 to_x = min (to_x, max_x);
29007 to_y = min (max_y, w->output_cursor.y + updated_row->height);
29009 /* Notice if the cursor will be cleared by this operation. */
29010 if (!updated_row->full_width_p)
29011 notice_overwritten_cursor (w, updated_area,
29012 w->output_cursor.x, -1,
29013 updated_row->y,
29014 MATRIX_ROW_BOTTOM_Y (updated_row));
29016 from_x = w->output_cursor.x;
29018 /* Translate to frame coordinates. */
29019 if (updated_row->full_width_p)
29021 from_x = WINDOW_TO_FRAME_PIXEL_X (w, from_x);
29022 to_x = WINDOW_TO_FRAME_PIXEL_X (w, to_x);
29024 else
29026 int area_left = window_box_left (w, updated_area);
29027 from_x += area_left;
29028 to_x += area_left;
29031 min_y = WINDOW_HEADER_LINE_HEIGHT (w);
29032 from_y = WINDOW_TO_FRAME_PIXEL_Y (w, max (min_y, w->output_cursor.y));
29033 to_y = WINDOW_TO_FRAME_PIXEL_Y (w, to_y);
29035 /* Prevent inadvertently clearing to end of the X window. */
29036 if (to_x > from_x && to_y > from_y)
29038 block_input ();
29039 FRAME_RIF (f)->clear_frame_area (f, from_x, from_y,
29040 to_x - from_x, to_y - from_y);
29041 unblock_input ();
29045 #endif /* HAVE_WINDOW_SYSTEM */
29049 /***********************************************************************
29050 Cursor types
29051 ***********************************************************************/
29053 /* Value is the internal representation of the specified cursor type
29054 ARG. If type is BAR_CURSOR, return in *WIDTH the specified width
29055 of the bar cursor. */
29057 static enum text_cursor_kinds
29058 get_specified_cursor_type (Lisp_Object arg, int *width)
29060 enum text_cursor_kinds type;
29062 if (NILP (arg))
29063 return NO_CURSOR;
29065 if (EQ (arg, Qbox))
29066 return FILLED_BOX_CURSOR;
29068 if (EQ (arg, Qhollow))
29069 return HOLLOW_BOX_CURSOR;
29071 if (EQ (arg, Qbar))
29073 *width = 2;
29074 return BAR_CURSOR;
29077 if (CONSP (arg)
29078 && EQ (XCAR (arg), Qbar)
29079 && RANGED_INTEGERP (0, XCDR (arg), INT_MAX))
29081 *width = XINT (XCDR (arg));
29082 return BAR_CURSOR;
29085 if (EQ (arg, Qhbar))
29087 *width = 2;
29088 return HBAR_CURSOR;
29091 if (CONSP (arg)
29092 && EQ (XCAR (arg), Qhbar)
29093 && RANGED_INTEGERP (0, XCDR (arg), INT_MAX))
29095 *width = XINT (XCDR (arg));
29096 return HBAR_CURSOR;
29099 /* Treat anything unknown as "hollow box cursor".
29100 It was bad to signal an error; people have trouble fixing
29101 .Xdefaults with Emacs, when it has something bad in it. */
29102 type = HOLLOW_BOX_CURSOR;
29104 return type;
29107 /* Set the default cursor types for specified frame. */
29108 void
29109 set_frame_cursor_types (struct frame *f, Lisp_Object arg)
29111 int width = 1;
29112 Lisp_Object tem;
29114 FRAME_DESIRED_CURSOR (f) = get_specified_cursor_type (arg, &width);
29115 FRAME_CURSOR_WIDTH (f) = width;
29117 /* By default, set up the blink-off state depending on the on-state. */
29119 tem = Fassoc (arg, Vblink_cursor_alist, Qnil);
29120 if (!NILP (tem))
29122 FRAME_BLINK_OFF_CURSOR (f)
29123 = get_specified_cursor_type (XCDR (tem), &width);
29124 FRAME_BLINK_OFF_CURSOR_WIDTH (f) = width;
29126 else
29127 FRAME_BLINK_OFF_CURSOR (f) = DEFAULT_CURSOR;
29129 /* Make sure the cursor gets redrawn. */
29130 f->cursor_type_changed = true;
29134 #ifdef HAVE_WINDOW_SYSTEM
29136 /* Return the cursor we want to be displayed in window W. Return
29137 width of bar/hbar cursor through WIDTH arg. Return with
29138 ACTIVE_CURSOR arg set to true if cursor in window W is `active'
29139 (i.e. if the `system caret' should track this cursor).
29141 In a mini-buffer window, we want the cursor only to appear if we
29142 are reading input from this window. For the selected window, we
29143 want the cursor type given by the frame parameter or buffer local
29144 setting of cursor-type. If explicitly marked off, draw no cursor.
29145 In all other cases, we want a hollow box cursor. */
29147 static enum text_cursor_kinds
29148 get_window_cursor_type (struct window *w, struct glyph *glyph, int *width,
29149 bool *active_cursor)
29151 struct frame *f = XFRAME (w->frame);
29152 struct buffer *b = XBUFFER (w->contents);
29153 int cursor_type = DEFAULT_CURSOR;
29154 Lisp_Object alt_cursor;
29155 bool non_selected = false;
29157 *active_cursor = true;
29159 /* Echo area */
29160 if (cursor_in_echo_area
29161 && FRAME_HAS_MINIBUF_P (f)
29162 && EQ (FRAME_MINIBUF_WINDOW (f), echo_area_window))
29164 if (w == XWINDOW (echo_area_window))
29166 if (EQ (BVAR (b, cursor_type), Qt) || NILP (BVAR (b, cursor_type)))
29168 *width = FRAME_CURSOR_WIDTH (f);
29169 return FRAME_DESIRED_CURSOR (f);
29171 else
29172 return get_specified_cursor_type (BVAR (b, cursor_type), width);
29175 *active_cursor = false;
29176 non_selected = true;
29179 /* Detect a nonselected window or nonselected frame. */
29180 else if (w != XWINDOW (f->selected_window)
29181 || f != FRAME_DISPLAY_INFO (f)->x_highlight_frame)
29183 *active_cursor = false;
29185 if (MINI_WINDOW_P (w) && minibuf_level == 0)
29186 return NO_CURSOR;
29188 non_selected = true;
29191 /* Never display a cursor in a window in which cursor-type is nil. */
29192 if (NILP (BVAR (b, cursor_type)))
29193 return NO_CURSOR;
29195 /* Get the normal cursor type for this window. */
29196 if (EQ (BVAR (b, cursor_type), Qt))
29198 cursor_type = FRAME_DESIRED_CURSOR (f);
29199 *width = FRAME_CURSOR_WIDTH (f);
29201 else
29202 cursor_type = get_specified_cursor_type (BVAR (b, cursor_type), width);
29204 /* Use cursor-in-non-selected-windows instead
29205 for non-selected window or frame. */
29206 if (non_selected)
29208 alt_cursor = BVAR (b, cursor_in_non_selected_windows);
29209 if (!EQ (Qt, alt_cursor))
29210 return get_specified_cursor_type (alt_cursor, width);
29211 /* t means modify the normal cursor type. */
29212 if (cursor_type == FILLED_BOX_CURSOR)
29213 cursor_type = HOLLOW_BOX_CURSOR;
29214 else if (cursor_type == BAR_CURSOR && *width > 1)
29215 --*width;
29216 return cursor_type;
29219 /* Use normal cursor if not blinked off. */
29220 if (!w->cursor_off_p)
29222 if (glyph != NULL && glyph->type == XWIDGET_GLYPH)
29223 return NO_CURSOR;
29224 if (glyph != NULL && glyph->type == IMAGE_GLYPH)
29226 if (cursor_type == FILLED_BOX_CURSOR)
29228 /* Using a block cursor on large images can be very annoying.
29229 So use a hollow cursor for "large" images.
29230 If image is not transparent (no mask), also use hollow cursor. */
29231 struct image *img = IMAGE_OPT_FROM_ID (f, glyph->u.img_id);
29232 if (img != NULL && IMAGEP (img->spec))
29234 /* Arbitrarily, interpret "Large" as >32x32 and >NxN
29235 where N = size of default frame font size.
29236 This should cover most of the "tiny" icons people may use. */
29237 if (!img->mask
29238 || img->width > max (32, WINDOW_FRAME_COLUMN_WIDTH (w))
29239 || img->height > max (32, WINDOW_FRAME_LINE_HEIGHT (w)))
29240 cursor_type = HOLLOW_BOX_CURSOR;
29243 else if (cursor_type != NO_CURSOR)
29245 /* Display current only supports BOX and HOLLOW cursors for images.
29246 So for now, unconditionally use a HOLLOW cursor when cursor is
29247 not a solid box cursor. */
29248 cursor_type = HOLLOW_BOX_CURSOR;
29251 return cursor_type;
29254 /* Cursor is blinked off, so determine how to "toggle" it. */
29256 /* First look for an entry matching the buffer's cursor-type in blink-cursor-alist. */
29257 if ((alt_cursor = Fassoc (BVAR (b, cursor_type), Vblink_cursor_alist, Qnil), !NILP (alt_cursor)))
29258 return get_specified_cursor_type (XCDR (alt_cursor), width);
29260 /* Then see if frame has specified a specific blink off cursor type. */
29261 if (FRAME_BLINK_OFF_CURSOR (f) != DEFAULT_CURSOR)
29263 *width = FRAME_BLINK_OFF_CURSOR_WIDTH (f);
29264 return FRAME_BLINK_OFF_CURSOR (f);
29267 #if false
29268 /* Some people liked having a permanently visible blinking cursor,
29269 while others had very strong opinions against it. So it was
29270 decided to remove it. KFS 2003-09-03 */
29272 /* Finally perform built-in cursor blinking:
29273 filled box <-> hollow box
29274 wide [h]bar <-> narrow [h]bar
29275 narrow [h]bar <-> no cursor
29276 other type <-> no cursor */
29278 if (cursor_type == FILLED_BOX_CURSOR)
29279 return HOLLOW_BOX_CURSOR;
29281 if ((cursor_type == BAR_CURSOR || cursor_type == HBAR_CURSOR) && *width > 1)
29283 *width = 1;
29284 return cursor_type;
29286 #endif
29288 return NO_CURSOR;
29292 /* Notice when the text cursor of window W has been completely
29293 overwritten by a drawing operation that outputs glyphs in AREA
29294 starting at X0 and ending at X1 in the line starting at Y0 and
29295 ending at Y1. X coordinates are area-relative. X1 < 0 means all
29296 the rest of the line after X0 has been written. Y coordinates
29297 are window-relative. */
29299 static void
29300 notice_overwritten_cursor (struct window *w, enum glyph_row_area area,
29301 int x0, int x1, int y0, int y1)
29303 int cx0, cx1, cy0, cy1;
29304 struct glyph_row *row;
29306 if (!w->phys_cursor_on_p)
29307 return;
29308 if (area != TEXT_AREA)
29309 return;
29311 if (w->phys_cursor.vpos < 0
29312 || w->phys_cursor.vpos >= w->current_matrix->nrows
29313 || (row = w->current_matrix->rows + w->phys_cursor.vpos,
29314 !(row->enabled_p && MATRIX_ROW_DISPLAYS_TEXT_P (row))))
29315 return;
29317 if (row->cursor_in_fringe_p)
29319 row->cursor_in_fringe_p = false;
29320 draw_fringe_bitmap (w, row, row->reversed_p);
29321 w->phys_cursor_on_p = false;
29322 return;
29325 cx0 = w->phys_cursor.x;
29326 cx1 = cx0 + w->phys_cursor_width;
29327 if (x0 > cx0 || (x1 >= 0 && x1 < cx1))
29328 return;
29330 /* The cursor image will be completely removed from the
29331 screen if the output area intersects the cursor area in
29332 y-direction. When we draw in [y0 y1[, and some part of
29333 the cursor is at y < y0, that part must have been drawn
29334 before. When scrolling, the cursor is erased before
29335 actually scrolling, so we don't come here. When not
29336 scrolling, the rows above the old cursor row must have
29337 changed, and in this case these rows must have written
29338 over the cursor image.
29340 Likewise if part of the cursor is below y1, with the
29341 exception of the cursor being in the first blank row at
29342 the buffer and window end because update_text_area
29343 doesn't draw that row. (Except when it does, but
29344 that's handled in update_text_area.) */
29346 cy0 = w->phys_cursor.y;
29347 cy1 = cy0 + w->phys_cursor_height;
29348 if ((y0 < cy0 || y0 >= cy1) && (y1 <= cy0 || y1 >= cy1))
29349 return;
29351 w->phys_cursor_on_p = false;
29354 #endif /* HAVE_WINDOW_SYSTEM */
29357 /************************************************************************
29358 Mouse Face
29359 ************************************************************************/
29361 #ifdef HAVE_WINDOW_SYSTEM
29363 /* EXPORT for RIF:
29364 Fix the display of area AREA of overlapping row ROW in window W
29365 with respect to the overlapping part OVERLAPS. */
29367 void
29368 x_fix_overlapping_area (struct window *w, struct glyph_row *row,
29369 enum glyph_row_area area, int overlaps)
29371 int i, x;
29373 block_input ();
29375 x = 0;
29376 for (i = 0; i < row->used[area];)
29378 if (row->glyphs[area][i].overlaps_vertically_p)
29380 int start = i, start_x = x;
29384 x += row->glyphs[area][i].pixel_width;
29385 ++i;
29387 while (i < row->used[area]
29388 && row->glyphs[area][i].overlaps_vertically_p);
29390 draw_glyphs (w, start_x, row, area,
29391 start, i,
29392 DRAW_NORMAL_TEXT, overlaps);
29394 else
29396 x += row->glyphs[area][i].pixel_width;
29397 ++i;
29401 unblock_input ();
29405 /* EXPORT:
29406 Draw the cursor glyph of window W in glyph row ROW. See the
29407 comment of draw_glyphs for the meaning of HL. */
29409 void
29410 draw_phys_cursor_glyph (struct window *w, struct glyph_row *row,
29411 enum draw_glyphs_face hl)
29413 /* If cursor hpos is out of bounds, don't draw garbage. This can
29414 happen in mini-buffer windows when switching between echo area
29415 glyphs and mini-buffer. */
29416 if ((row->reversed_p
29417 ? (w->phys_cursor.hpos >= 0)
29418 : (w->phys_cursor.hpos < row->used[TEXT_AREA])))
29420 bool on_p = w->phys_cursor_on_p;
29421 int x1;
29422 int hpos = w->phys_cursor.hpos;
29424 /* When the window is hscrolled, cursor hpos can legitimately be
29425 out of bounds, but we draw the cursor at the corresponding
29426 window margin in that case. */
29427 if (!row->reversed_p && hpos < 0)
29428 hpos = 0;
29429 if (row->reversed_p && hpos >= row->used[TEXT_AREA])
29430 hpos = row->used[TEXT_AREA] - 1;
29432 x1 = draw_glyphs (w, w->phys_cursor.x, row, TEXT_AREA, hpos, hpos + 1,
29433 hl, 0);
29434 w->phys_cursor_on_p = on_p;
29436 if (hl == DRAW_CURSOR)
29437 w->phys_cursor_width = x1 - w->phys_cursor.x;
29438 /* When we erase the cursor, and ROW is overlapped by other
29439 rows, make sure that these overlapping parts of other rows
29440 are redrawn. */
29441 else if (hl == DRAW_NORMAL_TEXT && row->overlapped_p)
29443 w->phys_cursor_width = x1 - w->phys_cursor.x;
29445 if (row > w->current_matrix->rows
29446 && MATRIX_ROW_OVERLAPS_SUCC_P (row - 1))
29447 x_fix_overlapping_area (w, row - 1, TEXT_AREA,
29448 OVERLAPS_ERASED_CURSOR);
29450 if (MATRIX_ROW_BOTTOM_Y (row) < window_text_bottom_y (w)
29451 && MATRIX_ROW_OVERLAPS_PRED_P (row + 1))
29452 x_fix_overlapping_area (w, row + 1, TEXT_AREA,
29453 OVERLAPS_ERASED_CURSOR);
29459 /* Erase the image of a cursor of window W from the screen. */
29461 void
29462 erase_phys_cursor (struct window *w)
29464 struct frame *f = XFRAME (w->frame);
29465 Mouse_HLInfo *hlinfo = MOUSE_HL_INFO (f);
29466 int hpos = w->phys_cursor.hpos;
29467 int vpos = w->phys_cursor.vpos;
29468 bool mouse_face_here_p = false;
29469 struct glyph_matrix *active_glyphs = w->current_matrix;
29470 struct glyph_row *cursor_row;
29471 struct glyph *cursor_glyph;
29472 enum draw_glyphs_face hl;
29474 /* No cursor displayed or row invalidated => nothing to do on the
29475 screen. */
29476 if (w->phys_cursor_type == NO_CURSOR)
29477 goto mark_cursor_off;
29479 /* VPOS >= active_glyphs->nrows means that window has been resized.
29480 Don't bother to erase the cursor. */
29481 if (vpos >= active_glyphs->nrows)
29482 goto mark_cursor_off;
29484 /* If row containing cursor is marked invalid, there is nothing we
29485 can do. */
29486 cursor_row = MATRIX_ROW (active_glyphs, vpos);
29487 if (!cursor_row->enabled_p)
29488 goto mark_cursor_off;
29490 /* If line spacing is > 0, old cursor may only be partially visible in
29491 window after split-window. So adjust visible height. */
29492 cursor_row->visible_height = min (cursor_row->visible_height,
29493 window_text_bottom_y (w) - cursor_row->y);
29495 /* If row is completely invisible, don't attempt to delete a cursor which
29496 isn't there. This can happen if cursor is at top of a window, and
29497 we switch to a buffer with a header line in that window. */
29498 if (cursor_row->visible_height <= 0)
29499 goto mark_cursor_off;
29501 /* If cursor is in the fringe, erase by drawing actual bitmap there. */
29502 if (cursor_row->cursor_in_fringe_p)
29504 cursor_row->cursor_in_fringe_p = false;
29505 draw_fringe_bitmap (w, cursor_row, cursor_row->reversed_p);
29506 goto mark_cursor_off;
29509 /* This can happen when the new row is shorter than the old one.
29510 In this case, either draw_glyphs or clear_end_of_line
29511 should have cleared the cursor. Note that we wouldn't be
29512 able to erase the cursor in this case because we don't have a
29513 cursor glyph at hand. */
29514 if ((cursor_row->reversed_p
29515 ? (w->phys_cursor.hpos < 0)
29516 : (w->phys_cursor.hpos >= cursor_row->used[TEXT_AREA])))
29517 goto mark_cursor_off;
29519 /* When the window is hscrolled, cursor hpos can legitimately be out
29520 of bounds, but we draw the cursor at the corresponding window
29521 margin in that case. */
29522 if (!cursor_row->reversed_p && hpos < 0)
29523 hpos = 0;
29524 if (cursor_row->reversed_p && hpos >= cursor_row->used[TEXT_AREA])
29525 hpos = cursor_row->used[TEXT_AREA] - 1;
29527 /* If the cursor is in the mouse face area, redisplay that when
29528 we clear the cursor. */
29529 if (! NILP (hlinfo->mouse_face_window)
29530 && coords_in_mouse_face_p (w, hpos, vpos)
29531 /* Don't redraw the cursor's spot in mouse face if it is at the
29532 end of a line (on a newline). The cursor appears there, but
29533 mouse highlighting does not. */
29534 && cursor_row->used[TEXT_AREA] > hpos && hpos >= 0)
29535 mouse_face_here_p = true;
29537 /* Maybe clear the display under the cursor. */
29538 if (w->phys_cursor_type == HOLLOW_BOX_CURSOR)
29540 int x, y;
29541 int header_line_height = WINDOW_HEADER_LINE_HEIGHT (w);
29542 int width;
29544 cursor_glyph = get_phys_cursor_glyph (w);
29545 if (cursor_glyph == NULL)
29546 goto mark_cursor_off;
29548 width = cursor_glyph->pixel_width;
29549 x = w->phys_cursor.x;
29550 if (x < 0)
29552 width += x;
29553 x = 0;
29555 width = min (width, window_box_width (w, TEXT_AREA) - x);
29556 y = WINDOW_TO_FRAME_PIXEL_Y (w, max (header_line_height, cursor_row->y));
29557 x = WINDOW_TEXT_TO_FRAME_PIXEL_X (w, x);
29559 if (width > 0)
29560 FRAME_RIF (f)->clear_frame_area (f, x, y, width, cursor_row->visible_height);
29563 /* Erase the cursor by redrawing the character underneath it. */
29564 if (mouse_face_here_p)
29565 hl = DRAW_MOUSE_FACE;
29566 else
29567 hl = DRAW_NORMAL_TEXT;
29568 draw_phys_cursor_glyph (w, cursor_row, hl);
29570 mark_cursor_off:
29571 w->phys_cursor_on_p = false;
29572 w->phys_cursor_type = NO_CURSOR;
29576 /* Display or clear cursor of window W. If !ON, clear the cursor.
29577 If ON, display the cursor; where to put the cursor is specified by
29578 HPOS, VPOS, X and Y. */
29580 void
29581 display_and_set_cursor (struct window *w, bool on,
29582 int hpos, int vpos, int x, int y)
29584 struct frame *f = XFRAME (w->frame);
29585 int new_cursor_type;
29586 int new_cursor_width;
29587 bool active_cursor;
29588 struct glyph_row *glyph_row;
29589 struct glyph *glyph;
29591 /* This is pointless on invisible frames, and dangerous on garbaged
29592 windows and frames; in the latter case, the frame or window may
29593 be in the midst of changing its size, and x and y may be off the
29594 window. */
29595 if (! FRAME_VISIBLE_P (f)
29596 || vpos >= w->current_matrix->nrows
29597 || hpos >= w->current_matrix->matrix_w)
29598 return;
29600 /* If cursor is off and we want it off, return quickly. */
29601 if (!on && !w->phys_cursor_on_p)
29602 return;
29604 glyph_row = MATRIX_ROW (w->current_matrix, vpos);
29605 /* If cursor row is not enabled, we don't really know where to
29606 display the cursor. */
29607 if (!glyph_row->enabled_p)
29609 w->phys_cursor_on_p = false;
29610 return;
29613 /* A frame might be marked garbaged even though its cursor position
29614 is correct, and will not change upon subsequent redisplay. This
29615 happens in some rare situations, like toggling the sort order in
29616 Dired windows. We've already established that VPOS is valid, so
29617 it shouldn't do any harm to record the cursor position, as we are
29618 going to return without acting on it anyway. Otherwise, expose
29619 events might come in and call update_window_cursor, which will
29620 blindly use outdated values in w->phys_cursor. */
29621 if (FRAME_GARBAGED_P (f))
29623 if (on)
29625 w->phys_cursor.x = x;
29626 w->phys_cursor.y = glyph_row->y;
29627 w->phys_cursor.hpos = hpos;
29628 w->phys_cursor.vpos = vpos;
29630 return;
29633 glyph = NULL;
29634 if (0 <= hpos && hpos < glyph_row->used[TEXT_AREA])
29635 glyph = glyph_row->glyphs[TEXT_AREA] + hpos;
29637 eassert (input_blocked_p ());
29639 /* Set new_cursor_type to the cursor we want to be displayed. */
29640 new_cursor_type = get_window_cursor_type (w, glyph,
29641 &new_cursor_width, &active_cursor);
29643 /* If cursor is currently being shown and we don't want it to be or
29644 it is in the wrong place, or the cursor type is not what we want,
29645 erase it. */
29646 if (w->phys_cursor_on_p
29647 && (!on
29648 || w->phys_cursor.x != x
29649 || w->phys_cursor.y != y
29650 /* HPOS can be negative in R2L rows whose
29651 exact_window_width_line_p flag is set (i.e. their newline
29652 would "overflow into the fringe"). */
29653 || hpos < 0
29654 || new_cursor_type != w->phys_cursor_type
29655 || ((new_cursor_type == BAR_CURSOR || new_cursor_type == HBAR_CURSOR)
29656 && new_cursor_width != w->phys_cursor_width)))
29657 erase_phys_cursor (w);
29659 /* Don't check phys_cursor_on_p here because that flag is only set
29660 to false in some cases where we know that the cursor has been
29661 completely erased, to avoid the extra work of erasing the cursor
29662 twice. In other words, phys_cursor_on_p can be true and the cursor
29663 still not be visible, or it has only been partly erased. */
29664 if (on)
29666 w->phys_cursor_ascent = glyph_row->ascent;
29667 w->phys_cursor_height = glyph_row->height;
29669 /* Set phys_cursor_.* before x_draw_.* is called because some
29670 of them may need the information. */
29671 w->phys_cursor.x = x;
29672 w->phys_cursor.y = glyph_row->y;
29673 w->phys_cursor.hpos = hpos;
29674 w->phys_cursor.vpos = vpos;
29677 FRAME_RIF (f)->draw_window_cursor (w, glyph_row, x, y,
29678 new_cursor_type, new_cursor_width,
29679 on, active_cursor);
29683 /* Switch the display of W's cursor on or off, according to the value
29684 of ON. */
29686 static void
29687 update_window_cursor (struct window *w, bool on)
29689 /* Don't update cursor in windows whose frame is in the process
29690 of being deleted. */
29691 if (w->current_matrix)
29693 int hpos = w->phys_cursor.hpos;
29694 int vpos = w->phys_cursor.vpos;
29695 struct glyph_row *row;
29697 if (vpos >= w->current_matrix->nrows
29698 || hpos >= w->current_matrix->matrix_w)
29699 return;
29701 row = MATRIX_ROW (w->current_matrix, vpos);
29703 /* When the window is hscrolled, cursor hpos can legitimately be
29704 out of bounds, but we draw the cursor at the corresponding
29705 window margin in that case. */
29706 if (!row->reversed_p && hpos < 0)
29707 hpos = 0;
29708 if (row->reversed_p && hpos >= row->used[TEXT_AREA])
29709 hpos = row->used[TEXT_AREA] - 1;
29711 block_input ();
29712 display_and_set_cursor (w, on, hpos, vpos,
29713 w->phys_cursor.x, w->phys_cursor.y);
29714 unblock_input ();
29719 /* Call update_window_cursor with parameter ON_P on all leaf windows
29720 in the window tree rooted at W. */
29722 static void
29723 update_cursor_in_window_tree (struct window *w, bool on_p)
29725 while (w)
29727 if (WINDOWP (w->contents))
29728 update_cursor_in_window_tree (XWINDOW (w->contents), on_p);
29729 else
29730 update_window_cursor (w, on_p);
29732 w = NILP (w->next) ? 0 : XWINDOW (w->next);
29737 /* EXPORT:
29738 Display the cursor on window W, or clear it, according to ON_P.
29739 Don't change the cursor's position. */
29741 void
29742 x_update_cursor (struct frame *f, bool on_p)
29744 update_cursor_in_window_tree (XWINDOW (f->root_window), on_p);
29748 /* EXPORT:
29749 Clear the cursor of window W to background color, and mark the
29750 cursor as not shown. This is used when the text where the cursor
29751 is about to be rewritten. */
29753 void
29754 x_clear_cursor (struct window *w)
29756 if (FRAME_VISIBLE_P (XFRAME (w->frame)) && w->phys_cursor_on_p)
29757 update_window_cursor (w, false);
29760 #endif /* HAVE_WINDOW_SYSTEM */
29762 /* Implementation of draw_row_with_mouse_face for GUI sessions, GPM,
29763 and MSDOS. */
29764 static void
29765 draw_row_with_mouse_face (struct window *w, int start_x, struct glyph_row *row,
29766 int start_hpos, int end_hpos,
29767 enum draw_glyphs_face draw)
29769 #ifdef HAVE_WINDOW_SYSTEM
29770 if (FRAME_WINDOW_P (XFRAME (w->frame)))
29772 draw_glyphs (w, start_x, row, TEXT_AREA, start_hpos, end_hpos, draw, 0);
29773 return;
29775 #endif
29776 #if defined (HAVE_GPM) || defined (MSDOS) || defined (WINDOWSNT)
29777 tty_draw_row_with_mouse_face (w, row, start_hpos, end_hpos, draw);
29778 #endif
29781 /* Display the active region described by mouse_face_* according to DRAW. */
29783 static void
29784 show_mouse_face (Mouse_HLInfo *hlinfo, enum draw_glyphs_face draw)
29786 struct window *w = XWINDOW (hlinfo->mouse_face_window);
29787 struct frame *f = XFRAME (WINDOW_FRAME (w));
29789 if (/* If window is in the process of being destroyed, don't bother
29790 to do anything. */
29791 w->current_matrix != NULL
29792 /* Don't update mouse highlight if hidden. */
29793 && (draw != DRAW_MOUSE_FACE || !hlinfo->mouse_face_hidden)
29794 /* Recognize when we are called to operate on rows that don't exist
29795 anymore. This can happen when a window is split. */
29796 && hlinfo->mouse_face_end_row < w->current_matrix->nrows)
29798 bool phys_cursor_on_p = w->phys_cursor_on_p;
29799 struct glyph_row *row, *first, *last;
29801 first = MATRIX_ROW (w->current_matrix, hlinfo->mouse_face_beg_row);
29802 last = MATRIX_ROW (w->current_matrix, hlinfo->mouse_face_end_row);
29804 for (row = first; row <= last && row->enabled_p; ++row)
29806 int start_hpos, end_hpos, start_x;
29808 /* For all but the first row, the highlight starts at column 0. */
29809 if (row == first)
29811 /* R2L rows have BEG and END in reversed order, but the
29812 screen drawing geometry is always left to right. So
29813 we need to mirror the beginning and end of the
29814 highlighted area in R2L rows. */
29815 if (!row->reversed_p)
29817 start_hpos = hlinfo->mouse_face_beg_col;
29818 start_x = hlinfo->mouse_face_beg_x;
29820 else if (row == last)
29822 start_hpos = hlinfo->mouse_face_end_col;
29823 start_x = hlinfo->mouse_face_end_x;
29825 else
29827 start_hpos = 0;
29828 start_x = 0;
29831 else if (row->reversed_p && row == last)
29833 start_hpos = hlinfo->mouse_face_end_col;
29834 start_x = hlinfo->mouse_face_end_x;
29836 else
29838 start_hpos = 0;
29839 start_x = 0;
29842 if (row == last)
29844 if (!row->reversed_p)
29845 end_hpos = hlinfo->mouse_face_end_col;
29846 else if (row == first)
29847 end_hpos = hlinfo->mouse_face_beg_col;
29848 else
29850 end_hpos = row->used[TEXT_AREA];
29851 if (draw == DRAW_NORMAL_TEXT)
29852 row->fill_line_p = true; /* Clear to end of line. */
29855 else if (row->reversed_p && row == first)
29856 end_hpos = hlinfo->mouse_face_beg_col;
29857 else
29859 end_hpos = row->used[TEXT_AREA];
29860 if (draw == DRAW_NORMAL_TEXT)
29861 row->fill_line_p = true; /* Clear to end of line. */
29864 if (end_hpos > start_hpos)
29866 draw_row_with_mouse_face (w, start_x, row,
29867 start_hpos, end_hpos, draw);
29869 row->mouse_face_p
29870 = draw == DRAW_MOUSE_FACE || draw == DRAW_IMAGE_RAISED;
29874 /* When we've written over the cursor, arrange for it to
29875 be displayed again. */
29876 if (FRAME_WINDOW_P (f)
29877 && phys_cursor_on_p && !w->phys_cursor_on_p)
29879 #ifdef HAVE_WINDOW_SYSTEM
29880 int hpos = w->phys_cursor.hpos;
29882 /* When the window is hscrolled, cursor hpos can legitimately be
29883 out of bounds, but we draw the cursor at the corresponding
29884 window margin in that case. */
29885 if (!row->reversed_p && hpos < 0)
29886 hpos = 0;
29887 if (row->reversed_p && hpos >= row->used[TEXT_AREA])
29888 hpos = row->used[TEXT_AREA] - 1;
29890 block_input ();
29891 display_and_set_cursor (w, true, hpos, w->phys_cursor.vpos,
29892 w->phys_cursor.x, w->phys_cursor.y);
29893 unblock_input ();
29894 #endif /* HAVE_WINDOW_SYSTEM */
29898 #ifdef HAVE_WINDOW_SYSTEM
29899 /* Change the mouse cursor. */
29900 if (FRAME_WINDOW_P (f) && NILP (do_mouse_tracking))
29902 #if ! defined (USE_GTK) && ! defined (HAVE_NS)
29903 if (draw == DRAW_NORMAL_TEXT
29904 && !EQ (hlinfo->mouse_face_window, f->tool_bar_window))
29905 FRAME_RIF (f)->define_frame_cursor (f, FRAME_X_OUTPUT (f)->text_cursor);
29906 else
29907 #endif
29908 if (draw == DRAW_MOUSE_FACE)
29909 FRAME_RIF (f)->define_frame_cursor (f, FRAME_X_OUTPUT (f)->hand_cursor);
29910 else
29911 FRAME_RIF (f)->define_frame_cursor (f, FRAME_X_OUTPUT (f)->nontext_cursor);
29913 #endif /* HAVE_WINDOW_SYSTEM */
29916 /* EXPORT:
29917 Clear out the mouse-highlighted active region.
29918 Redraw it un-highlighted first. Value is true if mouse
29919 face was actually drawn unhighlighted. */
29921 bool
29922 clear_mouse_face (Mouse_HLInfo *hlinfo)
29924 bool cleared
29925 = !hlinfo->mouse_face_hidden && !NILP (hlinfo->mouse_face_window);
29926 if (cleared)
29927 show_mouse_face (hlinfo, DRAW_NORMAL_TEXT);
29928 hlinfo->mouse_face_beg_row = hlinfo->mouse_face_beg_col = -1;
29929 hlinfo->mouse_face_end_row = hlinfo->mouse_face_end_col = -1;
29930 hlinfo->mouse_face_window = Qnil;
29931 hlinfo->mouse_face_overlay = Qnil;
29932 return cleared;
29935 /* Return true if the coordinates HPOS and VPOS on windows W are
29936 within the mouse face on that window. */
29937 static bool
29938 coords_in_mouse_face_p (struct window *w, int hpos, int vpos)
29940 Mouse_HLInfo *hlinfo = MOUSE_HL_INFO (XFRAME (w->frame));
29942 /* Quickly resolve the easy cases. */
29943 if (!(WINDOWP (hlinfo->mouse_face_window)
29944 && XWINDOW (hlinfo->mouse_face_window) == w))
29945 return false;
29946 if (vpos < hlinfo->mouse_face_beg_row
29947 || vpos > hlinfo->mouse_face_end_row)
29948 return false;
29949 if (vpos > hlinfo->mouse_face_beg_row
29950 && vpos < hlinfo->mouse_face_end_row)
29951 return true;
29953 if (!MATRIX_ROW (w->current_matrix, vpos)->reversed_p)
29955 if (hlinfo->mouse_face_beg_row == hlinfo->mouse_face_end_row)
29957 if (hlinfo->mouse_face_beg_col <= hpos && hpos < hlinfo->mouse_face_end_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 else
29968 if (hlinfo->mouse_face_beg_row == hlinfo->mouse_face_end_row)
29970 if (hlinfo->mouse_face_end_col < hpos && hpos <= hlinfo->mouse_face_beg_col)
29971 return true;
29973 else if ((vpos == hlinfo->mouse_face_beg_row
29974 && hpos <= hlinfo->mouse_face_beg_col)
29975 || (vpos == hlinfo->mouse_face_end_row
29976 && hpos > hlinfo->mouse_face_end_col))
29977 return true;
29979 return false;
29983 /* EXPORT:
29984 True if physical cursor of window W is within mouse face. */
29986 bool
29987 cursor_in_mouse_face_p (struct window *w)
29989 int hpos = w->phys_cursor.hpos;
29990 int vpos = w->phys_cursor.vpos;
29991 struct glyph_row *row = MATRIX_ROW (w->current_matrix, vpos);
29993 /* When the window is hscrolled, cursor hpos can legitimately be out
29994 of bounds, but we draw the cursor at the corresponding window
29995 margin in that case. */
29996 if (!row->reversed_p && hpos < 0)
29997 hpos = 0;
29998 if (row->reversed_p && hpos >= row->used[TEXT_AREA])
29999 hpos = row->used[TEXT_AREA] - 1;
30001 return coords_in_mouse_face_p (w, hpos, vpos);
30006 /* Find the glyph rows START_ROW and END_ROW of window W that display
30007 characters between buffer positions START_CHARPOS and END_CHARPOS
30008 (excluding END_CHARPOS). DISP_STRING is a display string that
30009 covers these buffer positions. This is similar to
30010 row_containing_pos, but is more accurate when bidi reordering makes
30011 buffer positions change non-linearly with glyph rows. */
30012 static void
30013 rows_from_pos_range (struct window *w,
30014 ptrdiff_t start_charpos, ptrdiff_t end_charpos,
30015 Lisp_Object disp_string,
30016 struct glyph_row **start, struct glyph_row **end)
30018 struct glyph_row *first = MATRIX_FIRST_TEXT_ROW (w->current_matrix);
30019 int last_y = window_text_bottom_y (w);
30020 struct glyph_row *row;
30022 *start = NULL;
30023 *end = NULL;
30025 while (!first->enabled_p
30026 && first < MATRIX_BOTTOM_TEXT_ROW (w->current_matrix, w))
30027 first++;
30029 /* Find the START row. */
30030 for (row = first;
30031 row->enabled_p && MATRIX_ROW_BOTTOM_Y (row) <= last_y;
30032 row++)
30034 /* A row can potentially be the START row if the range of the
30035 characters it displays intersects the range
30036 [START_CHARPOS..END_CHARPOS). */
30037 if (! ((start_charpos < MATRIX_ROW_START_CHARPOS (row)
30038 && end_charpos < MATRIX_ROW_START_CHARPOS (row))
30039 /* See the commentary in row_containing_pos, for the
30040 explanation of the complicated way to check whether
30041 some position is beyond the end of the characters
30042 displayed by a row. */
30043 || ((start_charpos > MATRIX_ROW_END_CHARPOS (row)
30044 || (start_charpos == MATRIX_ROW_END_CHARPOS (row)
30045 && !row->ends_at_zv_p
30046 && !MATRIX_ROW_ENDS_IN_MIDDLE_OF_CHAR_P (row)))
30047 && (end_charpos > MATRIX_ROW_END_CHARPOS (row)
30048 || (end_charpos == MATRIX_ROW_END_CHARPOS (row)
30049 && !row->ends_at_zv_p
30050 && !MATRIX_ROW_ENDS_IN_MIDDLE_OF_CHAR_P (row))))))
30052 /* Found a candidate row. Now make sure at least one of the
30053 glyphs it displays has a charpos from the range
30054 [START_CHARPOS..END_CHARPOS).
30056 This is not obvious because bidi reordering could make
30057 buffer positions of a row be 1,2,3,102,101,100, and if we
30058 want to highlight characters in [50..60), we don't want
30059 this row, even though [50..60) does intersect [1..103),
30060 the range of character positions given by the row's start
30061 and end positions. */
30062 struct glyph *g = row->glyphs[TEXT_AREA];
30063 struct glyph *e = g + row->used[TEXT_AREA];
30065 while (g < e)
30067 if (((BUFFERP (g->object) || NILP (g->object))
30068 && start_charpos <= g->charpos && g->charpos < end_charpos)
30069 /* A glyph that comes from DISP_STRING is by
30070 definition to be highlighted. */
30071 || EQ (g->object, disp_string))
30072 *start = row;
30073 g++;
30075 if (*start)
30076 break;
30080 /* Find the END row. */
30081 if (!*start
30082 /* If the last row is partially visible, start looking for END
30083 from that row, instead of starting from FIRST. */
30084 && !(row->enabled_p
30085 && row->y < last_y && MATRIX_ROW_BOTTOM_Y (row) > last_y))
30086 row = first;
30087 for ( ; row->enabled_p && MATRIX_ROW_BOTTOM_Y (row) <= last_y; row++)
30089 struct glyph_row *next = row + 1;
30090 ptrdiff_t next_start = MATRIX_ROW_START_CHARPOS (next);
30092 if (!next->enabled_p
30093 || next >= MATRIX_BOTTOM_TEXT_ROW (w->current_matrix, w)
30094 /* The first row >= START whose range of displayed characters
30095 does NOT intersect the range [START_CHARPOS..END_CHARPOS]
30096 is the row END + 1. */
30097 || (start_charpos < next_start
30098 && end_charpos < next_start)
30099 || ((start_charpos > MATRIX_ROW_END_CHARPOS (next)
30100 || (start_charpos == MATRIX_ROW_END_CHARPOS (next)
30101 && !next->ends_at_zv_p
30102 && !MATRIX_ROW_ENDS_IN_MIDDLE_OF_CHAR_P (next)))
30103 && (end_charpos > MATRIX_ROW_END_CHARPOS (next)
30104 || (end_charpos == MATRIX_ROW_END_CHARPOS (next)
30105 && !next->ends_at_zv_p
30106 && !MATRIX_ROW_ENDS_IN_MIDDLE_OF_CHAR_P (next)))))
30108 *end = row;
30109 break;
30111 else
30113 /* If the next row's edges intersect [START_CHARPOS..END_CHARPOS],
30114 but none of the characters it displays are in the range, it is
30115 also END + 1. */
30116 struct glyph *g = next->glyphs[TEXT_AREA];
30117 struct glyph *s = g;
30118 struct glyph *e = g + next->used[TEXT_AREA];
30120 while (g < e)
30122 if (((BUFFERP (g->object) || NILP (g->object))
30123 && ((start_charpos <= g->charpos && g->charpos < end_charpos)
30124 /* If the buffer position of the first glyph in
30125 the row is equal to END_CHARPOS, it means
30126 the last character to be highlighted is the
30127 newline of ROW, and we must consider NEXT as
30128 END, not END+1. */
30129 || (((!next->reversed_p && g == s)
30130 || (next->reversed_p && g == e - 1))
30131 && (g->charpos == end_charpos
30132 /* Special case for when NEXT is an
30133 empty line at ZV. */
30134 || (g->charpos == -1
30135 && !row->ends_at_zv_p
30136 && next_start == end_charpos)))))
30137 /* A glyph that comes from DISP_STRING is by
30138 definition to be highlighted. */
30139 || EQ (g->object, disp_string))
30140 break;
30141 g++;
30143 if (g == e)
30145 *end = row;
30146 break;
30148 /* The first row that ends at ZV must be the last to be
30149 highlighted. */
30150 else if (next->ends_at_zv_p)
30152 *end = next;
30153 break;
30159 /* This function sets the mouse_face_* elements of HLINFO, assuming
30160 the mouse cursor is on a glyph with buffer charpos MOUSE_CHARPOS in
30161 window WINDOW. START_CHARPOS and END_CHARPOS are buffer positions
30162 for the overlay or run of text properties specifying the mouse
30163 face. BEFORE_STRING and AFTER_STRING, if non-nil, are a
30164 before-string and after-string that must also be highlighted.
30165 DISP_STRING, if non-nil, is a display string that may cover some
30166 or all of the highlighted text. */
30168 static void
30169 mouse_face_from_buffer_pos (Lisp_Object window,
30170 Mouse_HLInfo *hlinfo,
30171 ptrdiff_t mouse_charpos,
30172 ptrdiff_t start_charpos,
30173 ptrdiff_t end_charpos,
30174 Lisp_Object before_string,
30175 Lisp_Object after_string,
30176 Lisp_Object disp_string)
30178 struct window *w = XWINDOW (window);
30179 struct glyph_row *first = MATRIX_FIRST_TEXT_ROW (w->current_matrix);
30180 struct glyph_row *r1, *r2;
30181 struct glyph *glyph, *end;
30182 ptrdiff_t ignore, pos;
30183 int x;
30185 eassert (NILP (disp_string) || STRINGP (disp_string));
30186 eassert (NILP (before_string) || STRINGP (before_string));
30187 eassert (NILP (after_string) || STRINGP (after_string));
30189 /* Find the rows corresponding to START_CHARPOS and END_CHARPOS. */
30190 rows_from_pos_range (w, start_charpos, end_charpos, disp_string, &r1, &r2);
30191 if (r1 == NULL)
30192 r1 = MATRIX_ROW (w->current_matrix, w->window_end_vpos);
30193 /* If the before-string or display-string contains newlines,
30194 rows_from_pos_range skips to its last row. Move back. */
30195 if (!NILP (before_string) || !NILP (disp_string))
30197 struct glyph_row *prev;
30198 while ((prev = r1 - 1, prev >= first)
30199 && MATRIX_ROW_END_CHARPOS (prev) == start_charpos
30200 && prev->used[TEXT_AREA] > 0)
30202 struct glyph *beg = prev->glyphs[TEXT_AREA];
30203 glyph = beg + prev->used[TEXT_AREA];
30204 while (--glyph >= beg && NILP (glyph->object));
30205 if (glyph < beg
30206 || !(EQ (glyph->object, before_string)
30207 || EQ (glyph->object, disp_string)))
30208 break;
30209 r1 = prev;
30212 if (r2 == NULL)
30214 r2 = MATRIX_ROW (w->current_matrix, w->window_end_vpos);
30215 hlinfo->mouse_face_past_end = true;
30217 else if (!NILP (after_string))
30219 /* If the after-string has newlines, advance to its last row. */
30220 struct glyph_row *next;
30221 struct glyph_row *last
30222 = MATRIX_ROW (w->current_matrix, w->window_end_vpos);
30224 for (next = r2 + 1;
30225 next <= last
30226 && next->used[TEXT_AREA] > 0
30227 && EQ (next->glyphs[TEXT_AREA]->object, after_string);
30228 ++next)
30229 r2 = next;
30231 /* The rest of the display engine assumes that mouse_face_beg_row is
30232 either above mouse_face_end_row or identical to it. But with
30233 bidi-reordered continued lines, the row for START_CHARPOS could
30234 be below the row for END_CHARPOS. If so, swap the rows and store
30235 them in correct order. */
30236 if (r1->y > r2->y)
30238 struct glyph_row *tem = r2;
30240 r2 = r1;
30241 r1 = tem;
30244 hlinfo->mouse_face_beg_row = MATRIX_ROW_VPOS (r1, w->current_matrix);
30245 hlinfo->mouse_face_end_row = MATRIX_ROW_VPOS (r2, w->current_matrix);
30247 /* For a bidi-reordered row, the positions of BEFORE_STRING,
30248 AFTER_STRING, DISP_STRING, START_CHARPOS, and END_CHARPOS
30249 could be anywhere in the row and in any order. The strategy
30250 below is to find the leftmost and the rightmost glyph that
30251 belongs to either of these 3 strings, or whose position is
30252 between START_CHARPOS and END_CHARPOS, and highlight all the
30253 glyphs between those two. This may cover more than just the text
30254 between START_CHARPOS and END_CHARPOS if the range of characters
30255 strides the bidi level boundary, e.g. if the beginning is in R2L
30256 text while the end is in L2R text or vice versa. */
30257 if (!r1->reversed_p)
30259 /* This row is in a left to right paragraph. Scan it left to
30260 right. */
30261 glyph = r1->glyphs[TEXT_AREA];
30262 end = glyph + r1->used[TEXT_AREA];
30263 x = r1->x;
30265 /* Skip truncation glyphs at the start of the glyph row. */
30266 if (MATRIX_ROW_DISPLAYS_TEXT_P (r1))
30267 for (; glyph < end
30268 && NILP (glyph->object)
30269 && glyph->charpos < 0;
30270 ++glyph)
30271 x += glyph->pixel_width;
30273 /* Scan the glyph row, looking for BEFORE_STRING, AFTER_STRING,
30274 or DISP_STRING, and the first glyph from buffer whose
30275 position is between START_CHARPOS and END_CHARPOS. */
30276 for (; glyph < end
30277 && !NILP (glyph->object)
30278 && !EQ (glyph->object, disp_string)
30279 && !(BUFFERP (glyph->object)
30280 && (glyph->charpos >= start_charpos
30281 && glyph->charpos < end_charpos));
30282 ++glyph)
30284 /* BEFORE_STRING or AFTER_STRING are only relevant if they
30285 are present at buffer positions between START_CHARPOS and
30286 END_CHARPOS, or if they come from an overlay. */
30287 if (EQ (glyph->object, before_string))
30289 pos = string_buffer_position (before_string,
30290 start_charpos);
30291 /* If pos == 0, it means before_string came from an
30292 overlay, not from a buffer position. */
30293 if (!pos || (pos >= start_charpos && pos < end_charpos))
30294 break;
30296 else if (EQ (glyph->object, after_string))
30298 pos = string_buffer_position (after_string, end_charpos);
30299 if (!pos || (pos >= start_charpos && pos < end_charpos))
30300 break;
30302 x += glyph->pixel_width;
30304 hlinfo->mouse_face_beg_x = x;
30305 hlinfo->mouse_face_beg_col = glyph - r1->glyphs[TEXT_AREA];
30307 else
30309 /* This row is in a right to left paragraph. Scan it right to
30310 left. */
30311 struct glyph *g;
30313 end = r1->glyphs[TEXT_AREA] - 1;
30314 glyph = end + r1->used[TEXT_AREA];
30316 /* Skip truncation glyphs at the start of the glyph row. */
30317 if (MATRIX_ROW_DISPLAYS_TEXT_P (r1))
30318 for (; glyph > end
30319 && NILP (glyph->object)
30320 && glyph->charpos < 0;
30321 --glyph)
30324 /* Scan the glyph row, looking for BEFORE_STRING, AFTER_STRING,
30325 or DISP_STRING, and the first glyph from buffer whose
30326 position is between START_CHARPOS and END_CHARPOS. */
30327 for (; glyph > end
30328 && !NILP (glyph->object)
30329 && !EQ (glyph->object, disp_string)
30330 && !(BUFFERP (glyph->object)
30331 && (glyph->charpos >= start_charpos
30332 && glyph->charpos < end_charpos));
30333 --glyph)
30335 /* BEFORE_STRING or AFTER_STRING are only relevant if they
30336 are present at buffer positions between START_CHARPOS and
30337 END_CHARPOS, or if they come from an overlay. */
30338 if (EQ (glyph->object, before_string))
30340 pos = string_buffer_position (before_string, start_charpos);
30341 /* If pos == 0, it means before_string came from an
30342 overlay, not from a buffer position. */
30343 if (!pos || (pos >= start_charpos && pos < end_charpos))
30344 break;
30346 else if (EQ (glyph->object, after_string))
30348 pos = string_buffer_position (after_string, end_charpos);
30349 if (!pos || (pos >= start_charpos && pos < end_charpos))
30350 break;
30354 glyph++; /* first glyph to the right of the highlighted area */
30355 for (g = r1->glyphs[TEXT_AREA], x = r1->x; g < glyph; g++)
30356 x += g->pixel_width;
30357 hlinfo->mouse_face_beg_x = x;
30358 hlinfo->mouse_face_beg_col = glyph - r1->glyphs[TEXT_AREA];
30361 /* If the highlight ends in a different row, compute GLYPH and END
30362 for the end row. Otherwise, reuse the values computed above for
30363 the row where the highlight begins. */
30364 if (r2 != r1)
30366 if (!r2->reversed_p)
30368 glyph = r2->glyphs[TEXT_AREA];
30369 end = glyph + r2->used[TEXT_AREA];
30370 x = r2->x;
30372 else
30374 end = r2->glyphs[TEXT_AREA] - 1;
30375 glyph = end + r2->used[TEXT_AREA];
30379 if (!r2->reversed_p)
30381 /* Skip truncation and continuation glyphs near the end of the
30382 row, and also blanks and stretch glyphs inserted by
30383 extend_face_to_end_of_line. */
30384 while (end > glyph
30385 && NILP ((end - 1)->object))
30386 --end;
30387 /* Scan the rest of the glyph row from the end, looking for the
30388 first glyph that comes from BEFORE_STRING, AFTER_STRING, or
30389 DISP_STRING, or whose position is between START_CHARPOS
30390 and END_CHARPOS */
30391 for (--end;
30392 end > glyph
30393 && !NILP (end->object)
30394 && !EQ (end->object, disp_string)
30395 && !(BUFFERP (end->object)
30396 && (end->charpos >= start_charpos
30397 && end->charpos < end_charpos));
30398 --end)
30400 /* BEFORE_STRING or AFTER_STRING are only relevant if they
30401 are present at buffer positions between START_CHARPOS and
30402 END_CHARPOS, or if they come from an overlay. */
30403 if (EQ (end->object, before_string))
30405 pos = string_buffer_position (before_string, start_charpos);
30406 if (!pos || (pos >= start_charpos && pos < end_charpos))
30407 break;
30409 else if (EQ (end->object, after_string))
30411 pos = string_buffer_position (after_string, end_charpos);
30412 if (!pos || (pos >= start_charpos && pos < end_charpos))
30413 break;
30416 /* Find the X coordinate of the last glyph to be highlighted. */
30417 for (; glyph <= end; ++glyph)
30418 x += glyph->pixel_width;
30420 hlinfo->mouse_face_end_x = x;
30421 hlinfo->mouse_face_end_col = glyph - r2->glyphs[TEXT_AREA];
30423 else
30425 /* Skip truncation and continuation glyphs near the end of the
30426 row, and also blanks and stretch glyphs inserted by
30427 extend_face_to_end_of_line. */
30428 x = r2->x;
30429 end++;
30430 while (end < glyph
30431 && NILP (end->object))
30433 x += end->pixel_width;
30434 ++end;
30436 /* Scan the rest of the glyph row from the end, looking for the
30437 first glyph that comes from BEFORE_STRING, AFTER_STRING, or
30438 DISP_STRING, or whose position is between START_CHARPOS
30439 and END_CHARPOS */
30440 for ( ;
30441 end < glyph
30442 && !NILP (end->object)
30443 && !EQ (end->object, disp_string)
30444 && !(BUFFERP (end->object)
30445 && (end->charpos >= start_charpos
30446 && end->charpos < end_charpos));
30447 ++end)
30449 /* BEFORE_STRING or AFTER_STRING are only relevant if they
30450 are present at buffer positions between START_CHARPOS and
30451 END_CHARPOS, or if they come from an overlay. */
30452 if (EQ (end->object, before_string))
30454 pos = string_buffer_position (before_string, start_charpos);
30455 if (!pos || (pos >= start_charpos && pos < end_charpos))
30456 break;
30458 else if (EQ (end->object, after_string))
30460 pos = string_buffer_position (after_string, end_charpos);
30461 if (!pos || (pos >= start_charpos && pos < end_charpos))
30462 break;
30464 x += end->pixel_width;
30466 /* If we exited the above loop because we arrived at the last
30467 glyph of the row, and its buffer position is still not in
30468 range, it means the last character in range is the preceding
30469 newline. Bump the end column and x values to get past the
30470 last glyph. */
30471 if (end == glyph
30472 && BUFFERP (end->object)
30473 && (end->charpos < start_charpos
30474 || end->charpos >= end_charpos))
30476 x += end->pixel_width;
30477 ++end;
30479 hlinfo->mouse_face_end_x = x;
30480 hlinfo->mouse_face_end_col = end - r2->glyphs[TEXT_AREA];
30483 hlinfo->mouse_face_window = window;
30484 hlinfo->mouse_face_face_id
30485 = face_at_buffer_position (w, mouse_charpos, &ignore,
30486 mouse_charpos + 1,
30487 !hlinfo->mouse_face_hidden, -1);
30488 show_mouse_face (hlinfo, DRAW_MOUSE_FACE);
30491 /* The following function is not used anymore (replaced with
30492 mouse_face_from_string_pos), but I leave it here for the time
30493 being, in case someone would. */
30495 #if false /* not used */
30497 /* Find the position of the glyph for position POS in OBJECT in
30498 window W's current matrix, and return in *X, *Y the pixel
30499 coordinates, and return in *HPOS, *VPOS the column/row of the glyph.
30501 RIGHT_P means return the position of the right edge of the glyph.
30502 !RIGHT_P means return the left edge position.
30504 If no glyph for POS exists in the matrix, return the position of
30505 the glyph with the next smaller position that is in the matrix, if
30506 RIGHT_P is false. If RIGHT_P, and no glyph for POS
30507 exists in the matrix, return the position of the glyph with the
30508 next larger position in OBJECT.
30510 Value is true if a glyph was found. */
30512 static bool
30513 fast_find_string_pos (struct window *w, ptrdiff_t pos, Lisp_Object object,
30514 int *hpos, int *vpos, int *x, int *y, bool right_p)
30516 int yb = window_text_bottom_y (w);
30517 struct glyph_row *r;
30518 struct glyph *best_glyph = NULL;
30519 struct glyph_row *best_row = NULL;
30520 int best_x = 0;
30522 for (r = MATRIX_FIRST_TEXT_ROW (w->current_matrix);
30523 r->enabled_p && r->y < yb;
30524 ++r)
30526 struct glyph *g = r->glyphs[TEXT_AREA];
30527 struct glyph *e = g + r->used[TEXT_AREA];
30528 int gx;
30530 for (gx = r->x; g < e; gx += g->pixel_width, ++g)
30531 if (EQ (g->object, object))
30533 if (g->charpos == pos)
30535 best_glyph = g;
30536 best_x = gx;
30537 best_row = r;
30538 goto found;
30540 else if (best_glyph == NULL
30541 || ((eabs (g->charpos - pos)
30542 < eabs (best_glyph->charpos - pos))
30543 && (right_p
30544 ? g->charpos < pos
30545 : g->charpos > pos)))
30547 best_glyph = g;
30548 best_x = gx;
30549 best_row = r;
30554 found:
30556 if (best_glyph)
30558 *x = best_x;
30559 *hpos = best_glyph - best_row->glyphs[TEXT_AREA];
30561 if (right_p)
30563 *x += best_glyph->pixel_width;
30564 ++*hpos;
30567 *y = best_row->y;
30568 *vpos = MATRIX_ROW_VPOS (best_row, w->current_matrix);
30571 return best_glyph != NULL;
30573 #endif /* not used */
30575 /* Find the positions of the first and the last glyphs in window W's
30576 current matrix that occlude positions [STARTPOS..ENDPOS) in OBJECT
30577 (assumed to be a string), and return in HLINFO's mouse_face_*
30578 members the pixel and column/row coordinates of those glyphs. */
30580 static void
30581 mouse_face_from_string_pos (struct window *w, Mouse_HLInfo *hlinfo,
30582 Lisp_Object object,
30583 ptrdiff_t startpos, ptrdiff_t endpos)
30585 int yb = window_text_bottom_y (w);
30586 struct glyph_row *r;
30587 struct glyph *g, *e;
30588 int gx;
30589 bool found = false;
30591 /* Find the glyph row with at least one position in the range
30592 [STARTPOS..ENDPOS), and the first glyph in that row whose
30593 position belongs to that range. */
30594 for (r = MATRIX_FIRST_TEXT_ROW (w->current_matrix);
30595 r->enabled_p && r->y < yb;
30596 ++r)
30598 if (!r->reversed_p)
30600 g = r->glyphs[TEXT_AREA];
30601 e = g + r->used[TEXT_AREA];
30602 for (gx = r->x; g < e; gx += g->pixel_width, ++g)
30603 if (EQ (g->object, object)
30604 && startpos <= g->charpos && g->charpos < endpos)
30606 hlinfo->mouse_face_beg_row
30607 = MATRIX_ROW_VPOS (r, w->current_matrix);
30608 hlinfo->mouse_face_beg_col = g - r->glyphs[TEXT_AREA];
30609 hlinfo->mouse_face_beg_x = gx;
30610 found = true;
30611 break;
30614 else
30616 struct glyph *g1;
30618 e = r->glyphs[TEXT_AREA];
30619 g = e + r->used[TEXT_AREA];
30620 for ( ; g > e; --g)
30621 if (EQ ((g-1)->object, object)
30622 && startpos <= (g-1)->charpos && (g-1)->charpos < endpos)
30624 hlinfo->mouse_face_beg_row
30625 = MATRIX_ROW_VPOS (r, w->current_matrix);
30626 hlinfo->mouse_face_beg_col = g - r->glyphs[TEXT_AREA];
30627 for (gx = r->x, g1 = r->glyphs[TEXT_AREA]; g1 < g; ++g1)
30628 gx += g1->pixel_width;
30629 hlinfo->mouse_face_beg_x = gx;
30630 found = true;
30631 break;
30634 if (found)
30635 break;
30638 if (!found)
30639 return;
30641 /* Starting with the next row, look for the first row which does NOT
30642 include any glyphs whose positions are in the range. */
30643 for (++r; r->enabled_p && r->y < yb; ++r)
30645 g = r->glyphs[TEXT_AREA];
30646 e = g + r->used[TEXT_AREA];
30647 found = false;
30648 for ( ; g < e; ++g)
30649 if (EQ (g->object, object)
30650 && startpos <= g->charpos && g->charpos < endpos)
30652 found = true;
30653 break;
30655 if (!found)
30656 break;
30659 /* The highlighted region ends on the previous row. */
30660 r--;
30662 /* Set the end row. */
30663 hlinfo->mouse_face_end_row = MATRIX_ROW_VPOS (r, w->current_matrix);
30665 /* Compute and set the end column and the end column's horizontal
30666 pixel coordinate. */
30667 if (!r->reversed_p)
30669 g = r->glyphs[TEXT_AREA];
30670 e = g + r->used[TEXT_AREA];
30671 for ( ; e > g; --e)
30672 if (EQ ((e-1)->object, object)
30673 && startpos <= (e-1)->charpos && (e-1)->charpos < endpos)
30674 break;
30675 hlinfo->mouse_face_end_col = e - g;
30677 for (gx = r->x; g < e; ++g)
30678 gx += g->pixel_width;
30679 hlinfo->mouse_face_end_x = gx;
30681 else
30683 e = r->glyphs[TEXT_AREA];
30684 g = e + r->used[TEXT_AREA];
30685 for (gx = r->x ; e < g; ++e)
30687 if (EQ (e->object, object)
30688 && startpos <= e->charpos && e->charpos < endpos)
30689 break;
30690 gx += e->pixel_width;
30692 hlinfo->mouse_face_end_col = e - r->glyphs[TEXT_AREA];
30693 hlinfo->mouse_face_end_x = gx;
30697 #ifdef HAVE_WINDOW_SYSTEM
30699 /* See if position X, Y is within a hot-spot of an image. */
30701 static bool
30702 on_hot_spot_p (Lisp_Object hot_spot, int x, int y)
30704 if (!CONSP (hot_spot))
30705 return false;
30707 if (EQ (XCAR (hot_spot), Qrect))
30709 /* CDR is (Top-Left . Bottom-Right) = ((x0 . y0) . (x1 . y1)) */
30710 Lisp_Object rect = XCDR (hot_spot);
30711 Lisp_Object tem;
30712 if (!CONSP (rect))
30713 return false;
30714 if (!CONSP (XCAR (rect)))
30715 return false;
30716 if (!CONSP (XCDR (rect)))
30717 return false;
30718 if (!(tem = XCAR (XCAR (rect)), INTEGERP (tem) && x >= XINT (tem)))
30719 return false;
30720 if (!(tem = XCDR (XCAR (rect)), INTEGERP (tem) && y >= XINT (tem)))
30721 return false;
30722 if (!(tem = XCAR (XCDR (rect)), INTEGERP (tem) && x <= XINT (tem)))
30723 return false;
30724 if (!(tem = XCDR (XCDR (rect)), INTEGERP (tem) && y <= XINT (tem)))
30725 return false;
30726 return true;
30728 else if (EQ (XCAR (hot_spot), Qcircle))
30730 /* CDR is (Center . Radius) = ((x0 . y0) . r) */
30731 Lisp_Object circ = XCDR (hot_spot);
30732 Lisp_Object lr, lx0, ly0;
30733 if (CONSP (circ)
30734 && CONSP (XCAR (circ))
30735 && (lr = XCDR (circ), NUMBERP (lr))
30736 && (lx0 = XCAR (XCAR (circ)), INTEGERP (lx0))
30737 && (ly0 = XCDR (XCAR (circ)), INTEGERP (ly0)))
30739 double r = XFLOATINT (lr);
30740 double dx = XINT (lx0) - x;
30741 double dy = XINT (ly0) - y;
30742 return (dx * dx + dy * dy <= r * r);
30745 else if (EQ (XCAR (hot_spot), Qpoly))
30747 /* CDR is [x0 y0 x1 y1 x2 y2 ...x(n-1) y(n-1)] */
30748 if (VECTORP (XCDR (hot_spot)))
30750 struct Lisp_Vector *v = XVECTOR (XCDR (hot_spot));
30751 Lisp_Object *poly = v->contents;
30752 ptrdiff_t n = v->header.size;
30753 ptrdiff_t i;
30754 bool inside = false;
30755 Lisp_Object lx, ly;
30756 int x0, y0;
30758 /* Need an even number of coordinates, and at least 3 edges. */
30759 if (n < 6 || n & 1)
30760 return false;
30762 /* Count edge segments intersecting line from (X,Y) to (X,infinity).
30763 If count is odd, we are inside polygon. Pixels on edges
30764 may or may not be included depending on actual geometry of the
30765 polygon. */
30766 if ((lx = poly[n-2], !INTEGERP (lx))
30767 || (ly = poly[n-1], !INTEGERP (lx)))
30768 return false;
30769 x0 = XINT (lx), y0 = XINT (ly);
30770 for (i = 0; i < n; i += 2)
30772 int x1 = x0, y1 = y0;
30773 if ((lx = poly[i], !INTEGERP (lx))
30774 || (ly = poly[i+1], !INTEGERP (ly)))
30775 return false;
30776 x0 = XINT (lx), y0 = XINT (ly);
30778 /* Does this segment cross the X line? */
30779 if (x0 >= x)
30781 if (x1 >= x)
30782 continue;
30784 else if (x1 < x)
30785 continue;
30786 if (y > y0 && y > y1)
30787 continue;
30788 if (y < y0 + ((y1 - y0) * (x - x0)) / (x1 - x0))
30789 inside = !inside;
30791 return inside;
30794 return false;
30797 Lisp_Object
30798 find_hot_spot (Lisp_Object map, int x, int y)
30800 while (CONSP (map))
30802 if (CONSP (XCAR (map))
30803 && on_hot_spot_p (XCAR (XCAR (map)), x, y))
30804 return XCAR (map);
30805 map = XCDR (map);
30808 return Qnil;
30811 DEFUN ("lookup-image-map", Flookup_image_map, Slookup_image_map,
30812 3, 3, 0,
30813 doc: /* Lookup in image map MAP coordinates X and Y.
30814 An image map is an alist where each element has the format (AREA ID PLIST).
30815 An AREA is specified as either a rectangle, a circle, or a polygon:
30816 A rectangle is a cons (rect . ((x0 . y0) . (x1 . y1))) specifying the
30817 pixel coordinates of the upper left and bottom right corners.
30818 A circle is a cons (circle . ((x0 . y0) . r)) specifying the center
30819 and the radius of the circle; r may be a float or integer.
30820 A polygon is a cons (poly . [x0 y0 x1 y1 ...]) where each pair in the
30821 vector describes one corner in the polygon.
30822 Returns the alist element for the first matching AREA in MAP. */)
30823 (Lisp_Object map, Lisp_Object x, Lisp_Object y)
30825 if (NILP (map))
30826 return Qnil;
30828 CHECK_NUMBER (x);
30829 CHECK_NUMBER (y);
30831 return find_hot_spot (map,
30832 clip_to_bounds (INT_MIN, XINT (x), INT_MAX),
30833 clip_to_bounds (INT_MIN, XINT (y), INT_MAX));
30835 #endif /* HAVE_WINDOW_SYSTEM */
30838 /* Display frame CURSOR, optionally using shape defined by POINTER. */
30839 static void
30840 define_frame_cursor1 (struct frame *f, Cursor cursor, Lisp_Object pointer)
30842 #ifdef HAVE_WINDOW_SYSTEM
30843 if (!FRAME_WINDOW_P (f))
30844 return;
30846 /* Do not change cursor shape while dragging mouse. */
30847 if (EQ (do_mouse_tracking, Qdragging))
30848 return;
30850 if (!NILP (pointer))
30852 if (EQ (pointer, Qarrow))
30853 cursor = FRAME_X_OUTPUT (f)->nontext_cursor;
30854 else if (EQ (pointer, Qhand))
30855 cursor = FRAME_X_OUTPUT (f)->hand_cursor;
30856 else if (EQ (pointer, Qtext))
30857 cursor = FRAME_X_OUTPUT (f)->text_cursor;
30858 else if (EQ (pointer, intern ("hdrag")))
30859 cursor = FRAME_X_OUTPUT (f)->horizontal_drag_cursor;
30860 else if (EQ (pointer, intern ("nhdrag")))
30861 cursor = FRAME_X_OUTPUT (f)->vertical_drag_cursor;
30862 # ifdef HAVE_X_WINDOWS
30863 else if (EQ (pointer, intern ("vdrag")))
30864 cursor = FRAME_DISPLAY_INFO (f)->vertical_scroll_bar_cursor;
30865 # endif
30866 else if (EQ (pointer, intern ("hourglass")))
30867 cursor = FRAME_X_OUTPUT (f)->hourglass_cursor;
30868 else if (EQ (pointer, Qmodeline))
30869 cursor = FRAME_X_OUTPUT (f)->modeline_cursor;
30870 else
30871 cursor = FRAME_X_OUTPUT (f)->nontext_cursor;
30874 if (cursor != No_Cursor)
30875 FRAME_RIF (f)->define_frame_cursor (f, cursor);
30876 #endif
30879 /* Take proper action when mouse has moved to the mode or header line
30880 or marginal area AREA of window W, x-position X and y-position Y.
30881 X is relative to the start of the text display area of W, so the
30882 width of bitmap areas and scroll bars must be subtracted to get a
30883 position relative to the start of the mode line. */
30885 static void
30886 note_mode_line_or_margin_highlight (Lisp_Object window, int x, int y,
30887 enum window_part area)
30889 struct window *w = XWINDOW (window);
30890 struct frame *f = XFRAME (w->frame);
30891 Mouse_HLInfo *hlinfo = MOUSE_HL_INFO (f);
30892 Cursor cursor = No_Cursor;
30893 Lisp_Object pointer = Qnil;
30894 int dx, dy, width, height;
30895 ptrdiff_t charpos;
30896 Lisp_Object string, object = Qnil;
30897 Lisp_Object pos UNINIT;
30898 Lisp_Object mouse_face;
30899 int original_x_pixel = x;
30900 struct glyph * glyph = NULL, * row_start_glyph = NULL;
30901 struct glyph_row *row UNINIT;
30903 if (area == ON_MODE_LINE || area == ON_HEADER_LINE)
30905 int x0;
30906 struct glyph *end;
30908 /* Kludge alert: mode_line_string takes X/Y in pixels, but
30909 returns them in row/column units! */
30910 string = mode_line_string (w, area, &x, &y, &charpos,
30911 &object, &dx, &dy, &width, &height);
30913 row = (area == ON_MODE_LINE
30914 ? MATRIX_MODE_LINE_ROW (w->current_matrix)
30915 : MATRIX_HEADER_LINE_ROW (w->current_matrix));
30917 /* Find the glyph under the mouse pointer. */
30918 if (row->mode_line_p && row->enabled_p)
30920 glyph = row_start_glyph = row->glyphs[TEXT_AREA];
30921 end = glyph + row->used[TEXT_AREA];
30923 for (x0 = original_x_pixel;
30924 glyph < end && x0 >= glyph->pixel_width;
30925 ++glyph)
30926 x0 -= glyph->pixel_width;
30928 if (glyph >= end)
30929 glyph = NULL;
30932 else
30934 x -= WINDOW_LEFT_SCROLL_BAR_AREA_WIDTH (w);
30935 /* Kludge alert: marginal_area_string takes X/Y in pixels, but
30936 returns them in row/column units! */
30937 string = marginal_area_string (w, area, &x, &y, &charpos,
30938 &object, &dx, &dy, &width, &height);
30941 Lisp_Object help = Qnil;
30943 #ifdef HAVE_WINDOW_SYSTEM
30944 if (IMAGEP (object))
30946 Lisp_Object image_map, hotspot;
30947 if ((image_map = Fplist_get (XCDR (object), QCmap),
30948 !NILP (image_map))
30949 && (hotspot = find_hot_spot (image_map, dx, dy),
30950 CONSP (hotspot))
30951 && (hotspot = XCDR (hotspot), CONSP (hotspot)))
30953 Lisp_Object plist;
30955 /* Could check XCAR (hotspot) to see if we enter/leave this hot-spot.
30956 If so, we could look for mouse-enter, mouse-leave
30957 properties in PLIST (and do something...). */
30958 hotspot = XCDR (hotspot);
30959 if (CONSP (hotspot)
30960 && (plist = XCAR (hotspot), CONSP (plist)))
30962 pointer = Fplist_get (plist, Qpointer);
30963 if (NILP (pointer))
30964 pointer = Qhand;
30965 help = Fplist_get (plist, Qhelp_echo);
30966 if (!NILP (help))
30968 help_echo_string = help;
30969 XSETWINDOW (help_echo_window, w);
30970 help_echo_object = w->contents;
30971 help_echo_pos = charpos;
30975 if (NILP (pointer))
30976 pointer = Fplist_get (XCDR (object), QCpointer);
30978 #endif /* HAVE_WINDOW_SYSTEM */
30980 if (STRINGP (string))
30981 pos = make_number (charpos);
30983 /* Set the help text and mouse pointer. If the mouse is on a part
30984 of the mode line without any text (e.g. past the right edge of
30985 the mode line text), use that windows's mode line help echo if it
30986 has been set. */
30987 if (STRINGP (string) || area == ON_MODE_LINE)
30989 /* Arrange to display the help by setting the global variables
30990 help_echo_string, help_echo_object, and help_echo_pos. */
30991 if (NILP (help))
30993 if (STRINGP (string))
30994 help = Fget_text_property (pos, Qhelp_echo, string);
30996 if (!NILP (help))
30998 help_echo_string = help;
30999 XSETWINDOW (help_echo_window, w);
31000 help_echo_object = string;
31001 help_echo_pos = charpos;
31003 else if (area == ON_MODE_LINE
31004 && !NILP (w->mode_line_help_echo))
31006 help_echo_string = w->mode_line_help_echo;
31007 XSETWINDOW (help_echo_window, w);
31008 help_echo_object = Qnil;
31009 help_echo_pos = -1;
31013 #ifdef HAVE_WINDOW_SYSTEM
31014 /* Change the mouse pointer according to what is under it. */
31015 if (FRAME_WINDOW_P (f))
31017 bool draggable = (! WINDOW_BOTTOMMOST_P (w)
31018 || minibuf_level
31019 || NILP (Vresize_mini_windows));
31021 if (STRINGP (string))
31023 cursor = FRAME_X_OUTPUT (f)->nontext_cursor;
31025 if (NILP (pointer))
31026 pointer = Fget_text_property (pos, Qpointer, string);
31028 /* Change the mouse pointer according to what is under X/Y. */
31029 if (NILP (pointer)
31030 && (area == ON_MODE_LINE || area == ON_HEADER_LINE))
31032 Lisp_Object map;
31034 map = Fget_text_property (pos, Qlocal_map, string);
31035 if (!KEYMAPP (map))
31036 map = Fget_text_property (pos, Qkeymap, string);
31037 if (!KEYMAPP (map) && draggable && area == ON_MODE_LINE)
31038 cursor = FRAME_X_OUTPUT (f)->vertical_drag_cursor;
31041 else if (draggable && area == ON_MODE_LINE)
31042 cursor = FRAME_X_OUTPUT (f)->vertical_drag_cursor;
31043 else
31044 cursor = FRAME_X_OUTPUT (f)->nontext_cursor;
31046 #endif
31049 /* Change the mouse face according to what is under X/Y. */
31050 bool mouse_face_shown = false;
31052 if (STRINGP (string))
31054 mouse_face = Fget_text_property (pos, Qmouse_face, string);
31055 if (!NILP (Vmouse_highlight) && !NILP (mouse_face)
31056 && ((area == ON_MODE_LINE) || (area == ON_HEADER_LINE))
31057 && glyph)
31059 Lisp_Object b, e;
31061 struct glyph * tmp_glyph;
31063 int gpos;
31064 int gseq_length;
31065 int total_pixel_width;
31066 ptrdiff_t begpos, endpos, ignore;
31068 int vpos, hpos;
31070 b = Fprevious_single_property_change (make_number (charpos + 1),
31071 Qmouse_face, string, Qnil);
31072 if (NILP (b))
31073 begpos = 0;
31074 else
31075 begpos = XINT (b);
31077 e = Fnext_single_property_change (pos, Qmouse_face, string, Qnil);
31078 if (NILP (e))
31079 endpos = SCHARS (string);
31080 else
31081 endpos = XINT (e);
31083 /* Calculate the glyph position GPOS of GLYPH in the
31084 displayed string, relative to the beginning of the
31085 highlighted part of the string.
31087 Note: GPOS is different from CHARPOS. CHARPOS is the
31088 position of GLYPH in the internal string object. A mode
31089 line string format has structures which are converted to
31090 a flattened string by the Emacs Lisp interpreter. The
31091 internal string is an element of those structures. The
31092 displayed string is the flattened string. */
31093 tmp_glyph = row_start_glyph;
31094 while (tmp_glyph < glyph
31095 && (!(EQ (tmp_glyph->object, glyph->object)
31096 && begpos <= tmp_glyph->charpos
31097 && tmp_glyph->charpos < endpos)))
31098 tmp_glyph++;
31099 gpos = glyph - tmp_glyph;
31101 /* Calculate the length GSEQ_LENGTH of the glyph sequence of
31102 the highlighted part of the displayed string to which
31103 GLYPH belongs. Note: GSEQ_LENGTH is different from
31104 SCHARS (STRING), because the latter returns the length of
31105 the internal string. */
31106 for (tmp_glyph = row->glyphs[TEXT_AREA] + row->used[TEXT_AREA] - 1;
31107 tmp_glyph > glyph
31108 && (!(EQ (tmp_glyph->object, glyph->object)
31109 && begpos <= tmp_glyph->charpos
31110 && tmp_glyph->charpos < endpos));
31111 tmp_glyph--)
31113 gseq_length = gpos + (tmp_glyph - glyph) + 1;
31115 /* Calculate the total pixel width of all the glyphs between
31116 the beginning of the highlighted area and GLYPH. */
31117 total_pixel_width = 0;
31118 for (tmp_glyph = glyph - gpos; tmp_glyph != glyph; tmp_glyph++)
31119 total_pixel_width += tmp_glyph->pixel_width;
31121 /* Pre calculation of re-rendering position. Note: X is in
31122 column units here, after the call to mode_line_string or
31123 marginal_area_string. */
31124 hpos = x - gpos;
31125 vpos = (area == ON_MODE_LINE
31126 ? (w->current_matrix)->nrows - 1
31127 : 0);
31129 /* If GLYPH's position is included in the region that is
31130 already drawn in mouse face, we have nothing to do. */
31131 if ( EQ (window, hlinfo->mouse_face_window)
31132 && (!row->reversed_p
31133 ? (hlinfo->mouse_face_beg_col <= hpos
31134 && hpos < hlinfo->mouse_face_end_col)
31135 /* In R2L rows we swap BEG and END, see below. */
31136 : (hlinfo->mouse_face_end_col <= hpos
31137 && hpos < hlinfo->mouse_face_beg_col))
31138 && hlinfo->mouse_face_beg_row == vpos )
31139 return;
31141 if (clear_mouse_face (hlinfo))
31142 cursor = No_Cursor;
31144 if (!row->reversed_p)
31146 hlinfo->mouse_face_beg_col = hpos;
31147 hlinfo->mouse_face_beg_x = original_x_pixel
31148 - (total_pixel_width + dx);
31149 hlinfo->mouse_face_end_col = hpos + gseq_length;
31150 hlinfo->mouse_face_end_x = 0;
31152 else
31154 /* In R2L rows, show_mouse_face expects BEG and END
31155 coordinates to be swapped. */
31156 hlinfo->mouse_face_end_col = hpos;
31157 hlinfo->mouse_face_end_x = original_x_pixel
31158 - (total_pixel_width + dx);
31159 hlinfo->mouse_face_beg_col = hpos + gseq_length;
31160 hlinfo->mouse_face_beg_x = 0;
31163 hlinfo->mouse_face_beg_row = vpos;
31164 hlinfo->mouse_face_end_row = hlinfo->mouse_face_beg_row;
31165 hlinfo->mouse_face_past_end = false;
31166 hlinfo->mouse_face_window = window;
31168 hlinfo->mouse_face_face_id = face_at_string_position (w, string,
31169 charpos,
31170 0, &ignore,
31171 glyph->face_id,
31172 true);
31173 show_mouse_face (hlinfo, DRAW_MOUSE_FACE);
31174 mouse_face_shown = true;
31176 if (NILP (pointer))
31177 pointer = Qhand;
31181 /* If mouse-face doesn't need to be shown, clear any existing
31182 mouse-face. */
31183 if ((area == ON_MODE_LINE || area == ON_HEADER_LINE) && !mouse_face_shown)
31184 clear_mouse_face (hlinfo);
31186 define_frame_cursor1 (f, cursor, pointer);
31190 /* EXPORT:
31191 Take proper action when the mouse has moved to position X, Y on
31192 frame F with regards to highlighting portions of display that have
31193 mouse-face properties. Also de-highlight portions of display where
31194 the mouse was before, set the mouse pointer shape as appropriate
31195 for the mouse coordinates, and activate help echo (tooltips).
31196 X and Y can be negative or out of range. */
31198 void
31199 note_mouse_highlight (struct frame *f, int x, int y)
31201 Mouse_HLInfo *hlinfo = MOUSE_HL_INFO (f);
31202 enum window_part part = ON_NOTHING;
31203 Lisp_Object window;
31204 struct window *w;
31205 Cursor cursor = No_Cursor;
31206 Lisp_Object pointer = Qnil; /* Takes precedence over cursor! */
31207 struct buffer *b;
31209 /* When a menu is active, don't highlight because this looks odd. */
31210 #if defined (USE_X_TOOLKIT) || defined (USE_GTK) || defined (HAVE_NS) || defined (MSDOS)
31211 if (popup_activated ())
31212 return;
31213 #endif
31215 if (!f->glyphs_initialized_p
31216 || f->pointer_invisible)
31217 return;
31219 hlinfo->mouse_face_mouse_x = x;
31220 hlinfo->mouse_face_mouse_y = y;
31221 hlinfo->mouse_face_mouse_frame = f;
31223 if (hlinfo->mouse_face_defer)
31224 return;
31226 /* Which window is that in? */
31227 window = window_from_coordinates (f, x, y, &part, true);
31229 /* If displaying active text in another window, clear that. */
31230 if (! EQ (window, hlinfo->mouse_face_window)
31231 /* Also clear if we move out of text area in same window. */
31232 || (!NILP (hlinfo->mouse_face_window)
31233 && !NILP (window)
31234 && part != ON_TEXT
31235 && part != ON_MODE_LINE
31236 && part != ON_HEADER_LINE))
31237 clear_mouse_face (hlinfo);
31239 /* Reset help_echo_string. It will get recomputed below. */
31240 help_echo_string = Qnil;
31242 #ifdef HAVE_WINDOW_SYSTEM
31243 /* If the cursor is on the internal border of FRAME and FRAME's
31244 internal border is draggable, provide some visual feedback. */
31245 if (FRAME_INTERNAL_BORDER_WIDTH (f) > 0
31246 && !NILP (get_frame_param (f, Qdrag_internal_border)))
31248 enum internal_border_part part = frame_internal_border_part (f, x, y);
31250 switch (part)
31252 case INTERNAL_BORDER_NONE:
31253 if (cursor != FRAME_X_OUTPUT (f)->nontext_cursor)
31254 /* Reset cursor. */
31255 cursor = FRAME_X_OUTPUT (f)->nontext_cursor;
31256 break;
31257 case INTERNAL_BORDER_LEFT_EDGE:
31258 cursor = FRAME_X_OUTPUT (f)->left_edge_cursor;
31259 break;
31260 case INTERNAL_BORDER_TOP_LEFT_CORNER:
31261 cursor = FRAME_X_OUTPUT (f)->top_left_corner_cursor;
31262 break;
31263 case INTERNAL_BORDER_TOP_EDGE:
31264 cursor = FRAME_X_OUTPUT (f)->top_edge_cursor;
31265 break;
31266 case INTERNAL_BORDER_TOP_RIGHT_CORNER:
31267 cursor = FRAME_X_OUTPUT (f)->top_right_corner_cursor;
31268 break;
31269 case INTERNAL_BORDER_RIGHT_EDGE:
31270 cursor = FRAME_X_OUTPUT (f)->right_edge_cursor;
31271 break;
31272 case INTERNAL_BORDER_BOTTOM_RIGHT_CORNER:
31273 cursor = FRAME_X_OUTPUT (f)->bottom_right_corner_cursor;
31274 break;
31275 case INTERNAL_BORDER_BOTTOM_EDGE:
31276 cursor = FRAME_X_OUTPUT (f)->bottom_edge_cursor;
31277 break;
31278 case INTERNAL_BORDER_BOTTOM_LEFT_CORNER:
31279 cursor = FRAME_X_OUTPUT (f)->bottom_left_corner_cursor;
31280 break;
31281 default:
31282 /* This should not happen. */
31283 if (cursor != FRAME_X_OUTPUT (f)->nontext_cursor)
31284 cursor = FRAME_X_OUTPUT (f)->nontext_cursor;
31287 if (cursor != FRAME_X_OUTPUT (f)->nontext_cursor)
31289 /* Do we really want a help echo here? */
31290 help_echo_string = build_string ("drag-mouse-1: resize frame");
31291 goto set_cursor;
31294 #endif /* HAVE_WINDOW_SYSTEM */
31296 /* Not on a window -> return. */
31297 if (!WINDOWP (window))
31298 return;
31300 /* Convert to window-relative pixel coordinates. */
31301 w = XWINDOW (window);
31302 frame_to_window_pixel_xy (w, &x, &y);
31304 #if defined (HAVE_WINDOW_SYSTEM) && ! defined (USE_GTK) && ! defined (HAVE_NS)
31305 /* Handle tool-bar window differently since it doesn't display a
31306 buffer. */
31307 if (EQ (window, f->tool_bar_window))
31309 note_tool_bar_highlight (f, x, y);
31310 return;
31312 #endif
31314 /* Mouse is on the mode, header line or margin? */
31315 if (part == ON_MODE_LINE || part == ON_HEADER_LINE
31316 || part == ON_LEFT_MARGIN || part == ON_RIGHT_MARGIN)
31318 note_mode_line_or_margin_highlight (window, x, y, part);
31320 #ifdef HAVE_WINDOW_SYSTEM
31321 if (part == ON_LEFT_MARGIN || part == ON_RIGHT_MARGIN)
31323 cursor = FRAME_X_OUTPUT (f)->nontext_cursor;
31324 /* Show non-text cursor (Bug#16647). */
31325 goto set_cursor;
31327 else
31328 #endif
31329 return;
31332 #ifdef HAVE_WINDOW_SYSTEM
31333 if (part == ON_VERTICAL_BORDER)
31335 cursor = FRAME_X_OUTPUT (f)->horizontal_drag_cursor;
31336 help_echo_string = build_string ("drag-mouse-1: resize");
31337 goto set_cursor;
31339 else if (part == ON_RIGHT_DIVIDER)
31341 cursor = FRAME_X_OUTPUT (f)->horizontal_drag_cursor;
31342 help_echo_string = build_string ("drag-mouse-1: resize");
31343 goto set_cursor;
31345 else if (part == ON_BOTTOM_DIVIDER)
31346 if (! WINDOW_BOTTOMMOST_P (w)
31347 || minibuf_level
31348 || NILP (Vresize_mini_windows))
31350 cursor = FRAME_X_OUTPUT (f)->vertical_drag_cursor;
31351 help_echo_string = build_string ("drag-mouse-1: resize");
31352 goto set_cursor;
31354 else
31355 cursor = FRAME_X_OUTPUT (f)->nontext_cursor;
31356 else if (part == ON_LEFT_FRINGE || part == ON_RIGHT_FRINGE
31357 || part == ON_VERTICAL_SCROLL_BAR
31358 || part == ON_HORIZONTAL_SCROLL_BAR)
31359 cursor = FRAME_X_OUTPUT (f)->nontext_cursor;
31360 else
31361 cursor = FRAME_X_OUTPUT (f)->text_cursor;
31362 #endif
31364 /* Are we in a window whose display is up to date?
31365 And verify the buffer's text has not changed. */
31366 b = XBUFFER (w->contents);
31367 if (part == ON_TEXT && w->window_end_valid && !window_outdated (w))
31369 int hpos, vpos, dx, dy, area = LAST_AREA;
31370 ptrdiff_t pos;
31371 struct glyph *glyph;
31372 Lisp_Object object;
31373 Lisp_Object mouse_face = Qnil, position;
31374 Lisp_Object *overlay_vec = NULL;
31375 ptrdiff_t i, noverlays;
31376 struct buffer *obuf;
31377 ptrdiff_t obegv, ozv;
31378 bool same_region;
31380 /* Find the glyph under X/Y. */
31381 glyph = x_y_to_hpos_vpos (w, x, y, &hpos, &vpos, &dx, &dy, &area);
31383 #ifdef HAVE_WINDOW_SYSTEM
31384 /* Look for :pointer property on image. */
31385 if (glyph != NULL && glyph->type == IMAGE_GLYPH)
31387 struct image *img = IMAGE_OPT_FROM_ID (f, glyph->u.img_id);
31388 if (img != NULL && IMAGEP (img->spec))
31390 Lisp_Object image_map, hotspot;
31391 if ((image_map = Fplist_get (XCDR (img->spec), QCmap),
31392 !NILP (image_map))
31393 && (hotspot = find_hot_spot (image_map,
31394 glyph->slice.img.x + dx,
31395 glyph->slice.img.y + dy),
31396 CONSP (hotspot))
31397 && (hotspot = XCDR (hotspot), CONSP (hotspot)))
31399 Lisp_Object plist;
31401 /* Could check XCAR (hotspot) to see if we enter/leave
31402 this hot-spot.
31403 If so, we could look for mouse-enter, mouse-leave
31404 properties in PLIST (and do something...). */
31405 hotspot = XCDR (hotspot);
31406 if (CONSP (hotspot)
31407 && (plist = XCAR (hotspot), CONSP (plist)))
31409 pointer = Fplist_get (plist, Qpointer);
31410 if (NILP (pointer))
31411 pointer = Qhand;
31412 help_echo_string = Fplist_get (plist, Qhelp_echo);
31413 if (!NILP (help_echo_string))
31415 help_echo_window = window;
31416 help_echo_object = glyph->object;
31417 help_echo_pos = glyph->charpos;
31421 if (NILP (pointer))
31422 pointer = Fplist_get (XCDR (img->spec), QCpointer);
31425 #endif /* HAVE_WINDOW_SYSTEM */
31427 /* Clear mouse face if X/Y not over text. */
31428 if (glyph == NULL
31429 || area != TEXT_AREA
31430 || !MATRIX_ROW_DISPLAYS_TEXT_P (MATRIX_ROW (w->current_matrix, vpos))
31431 /* Glyph's OBJECT is nil for glyphs inserted by the
31432 display engine for its internal purposes, like truncation
31433 and continuation glyphs and blanks beyond the end of
31434 line's text on text terminals. If we are over such a
31435 glyph, we are not over any text. */
31436 || NILP (glyph->object)
31437 /* R2L rows have a stretch glyph at their front, which
31438 stands for no text, whereas L2R rows have no glyphs at
31439 all beyond the end of text. Treat such stretch glyphs
31440 like we do with NULL glyphs in L2R rows. */
31441 || (MATRIX_ROW (w->current_matrix, vpos)->reversed_p
31442 && glyph == MATRIX_ROW_GLYPH_START (w->current_matrix, vpos)
31443 && glyph->type == STRETCH_GLYPH
31444 && glyph->avoid_cursor_p))
31446 if (clear_mouse_face (hlinfo))
31447 cursor = No_Cursor;
31448 if (FRAME_WINDOW_P (f) && NILP (pointer))
31450 #ifdef HAVE_WINDOW_SYSTEM
31451 if (area != TEXT_AREA)
31452 cursor = FRAME_X_OUTPUT (f)->nontext_cursor;
31453 else
31454 pointer = Vvoid_text_area_pointer;
31455 #endif
31457 goto set_cursor;
31460 pos = glyph->charpos;
31461 object = glyph->object;
31462 if (!STRINGP (object) && !BUFFERP (object))
31463 goto set_cursor;
31465 /* If we get an out-of-range value, return now; avoid an error. */
31466 if (BUFFERP (object) && pos > BUF_Z (b))
31467 goto set_cursor;
31469 /* Make the window's buffer temporarily current for
31470 overlays_at and compute_char_face. */
31471 obuf = current_buffer;
31472 current_buffer = b;
31473 obegv = BEGV;
31474 ozv = ZV;
31475 BEGV = BEG;
31476 ZV = Z;
31478 /* Is this char mouse-active or does it have help-echo? */
31479 position = make_number (pos);
31481 USE_SAFE_ALLOCA;
31483 if (BUFFERP (object))
31485 /* Put all the overlays we want in a vector in overlay_vec. */
31486 GET_OVERLAYS_AT (pos, overlay_vec, noverlays, NULL, false);
31487 /* Sort overlays into increasing priority order. */
31488 noverlays = sort_overlays (overlay_vec, noverlays, w);
31490 else
31491 noverlays = 0;
31493 if (NILP (Vmouse_highlight))
31495 clear_mouse_face (hlinfo);
31496 goto check_help_echo;
31499 same_region = coords_in_mouse_face_p (w, hpos, vpos);
31501 if (same_region)
31502 cursor = No_Cursor;
31504 /* Check mouse-face highlighting. */
31505 if (! same_region
31506 /* If there exists an overlay with mouse-face overlapping
31507 the one we are currently highlighting, we have to check
31508 if we enter the overlapping overlay, and then highlight
31509 only that. Skip the check when mouse-face highlighting
31510 is currently hidden to avoid Bug#30519. */
31511 || (!hlinfo->mouse_face_hidden
31512 && OVERLAYP (hlinfo->mouse_face_overlay)
31513 && mouse_face_overlay_overlaps (hlinfo->mouse_face_overlay)))
31515 /* Find the highest priority overlay with a mouse-face. */
31516 Lisp_Object overlay = Qnil;
31517 for (i = noverlays - 1; i >= 0 && NILP (overlay); --i)
31519 mouse_face = Foverlay_get (overlay_vec[i], Qmouse_face);
31520 if (!NILP (mouse_face))
31521 overlay = overlay_vec[i];
31524 /* If we're highlighting the same overlay as before, there's
31525 no need to do that again. */
31526 if (!NILP (overlay) && EQ (overlay, hlinfo->mouse_face_overlay))
31527 goto check_help_echo;
31529 /* Clear the display of the old active region, if any. */
31530 if (clear_mouse_face (hlinfo))
31531 cursor = No_Cursor;
31533 /* Record the overlay, if any, to be highlighted. */
31534 hlinfo->mouse_face_overlay = overlay;
31536 /* If no overlay applies, get a text property. */
31537 if (NILP (overlay))
31538 mouse_face = Fget_text_property (position, Qmouse_face, object);
31540 /* Next, compute the bounds of the mouse highlighting and
31541 display it. */
31542 if (!NILP (mouse_face) && STRINGP (object))
31544 /* The mouse-highlighting comes from a display string
31545 with a mouse-face. */
31546 Lisp_Object s, e;
31547 ptrdiff_t ignore;
31549 s = Fprevious_single_property_change
31550 (make_number (pos + 1), Qmouse_face, object, Qnil);
31551 e = Fnext_single_property_change
31552 (position, Qmouse_face, object, Qnil);
31553 if (NILP (s))
31554 s = make_number (0);
31555 if (NILP (e))
31556 e = make_number (SCHARS (object));
31557 mouse_face_from_string_pos (w, hlinfo, object,
31558 XINT (s), XINT (e));
31559 hlinfo->mouse_face_past_end = false;
31560 hlinfo->mouse_face_window = window;
31561 hlinfo->mouse_face_face_id
31562 = face_at_string_position (w, object, pos, 0, &ignore,
31563 glyph->face_id, true);
31564 show_mouse_face (hlinfo, DRAW_MOUSE_FACE);
31565 cursor = No_Cursor;
31567 else
31569 /* The mouse-highlighting, if any, comes from an overlay
31570 or text property in the buffer. */
31571 Lisp_Object buffer UNINIT;
31572 Lisp_Object disp_string UNINIT;
31574 if (STRINGP (object))
31576 /* If we are on a display string with no mouse-face,
31577 check if the text under it has one. */
31578 struct glyph_row *r = MATRIX_ROW (w->current_matrix, vpos);
31579 ptrdiff_t start = MATRIX_ROW_START_CHARPOS (r);
31580 pos = string_buffer_position (object, start);
31581 if (pos > 0)
31583 mouse_face = get_char_property_and_overlay
31584 (make_number (pos), Qmouse_face, w->contents, &overlay);
31585 buffer = w->contents;
31586 disp_string = object;
31589 else
31591 buffer = object;
31592 disp_string = Qnil;
31595 if (!NILP (mouse_face))
31597 Lisp_Object before, after;
31598 Lisp_Object before_string, after_string;
31599 /* To correctly find the limits of mouse highlight
31600 in a bidi-reordered buffer, we must not use the
31601 optimization of limiting the search in
31602 previous-single-property-change and
31603 next-single-property-change, because
31604 rows_from_pos_range needs the real start and end
31605 positions to DTRT in this case. That's because
31606 the first row visible in a window does not
31607 necessarily display the character whose position
31608 is the smallest. */
31609 Lisp_Object lim1
31610 = NILP (BVAR (XBUFFER (buffer), bidi_display_reordering))
31611 ? Fmarker_position (w->start)
31612 : Qnil;
31613 Lisp_Object lim2
31614 = NILP (BVAR (XBUFFER (buffer), bidi_display_reordering))
31615 ? make_number (BUF_Z (XBUFFER (buffer))
31616 - w->window_end_pos)
31617 : Qnil;
31619 if (NILP (overlay))
31621 /* Handle the text property case. */
31622 before = Fprevious_single_property_change
31623 (make_number (pos + 1), Qmouse_face, buffer, lim1);
31624 after = Fnext_single_property_change
31625 (make_number (pos), Qmouse_face, buffer, lim2);
31626 before_string = after_string = Qnil;
31628 else
31630 /* Handle the overlay case. */
31631 before = Foverlay_start (overlay);
31632 after = Foverlay_end (overlay);
31633 before_string = Foverlay_get (overlay, Qbefore_string);
31634 after_string = Foverlay_get (overlay, Qafter_string);
31636 if (!STRINGP (before_string)) before_string = Qnil;
31637 if (!STRINGP (after_string)) after_string = Qnil;
31640 mouse_face_from_buffer_pos (window, hlinfo, pos,
31641 NILP (before)
31643 : XFASTINT (before),
31644 NILP (after)
31645 ? BUF_Z (XBUFFER (buffer))
31646 : XFASTINT (after),
31647 before_string, after_string,
31648 disp_string);
31649 cursor = No_Cursor;
31654 check_help_echo:
31656 /* Look for a `help-echo' property. */
31657 if (NILP (help_echo_string)) {
31658 Lisp_Object help, overlay;
31660 /* Check overlays first. */
31661 help = overlay = Qnil;
31662 for (i = noverlays - 1; i >= 0 && NILP (help); --i)
31664 overlay = overlay_vec[i];
31665 help = Foverlay_get (overlay, Qhelp_echo);
31668 if (!NILP (help))
31670 help_echo_string = help;
31671 help_echo_window = window;
31672 help_echo_object = overlay;
31673 help_echo_pos = pos;
31675 else
31677 Lisp_Object obj = glyph->object;
31678 ptrdiff_t charpos = glyph->charpos;
31680 /* Try text properties. */
31681 if (STRINGP (obj)
31682 && charpos >= 0
31683 && charpos < SCHARS (obj))
31685 help = Fget_text_property (make_number (charpos),
31686 Qhelp_echo, obj);
31687 if (NILP (help))
31689 /* If the string itself doesn't specify a help-echo,
31690 see if the buffer text ``under'' it does. */
31691 struct glyph_row *r
31692 = MATRIX_ROW (w->current_matrix, vpos);
31693 ptrdiff_t start = MATRIX_ROW_START_CHARPOS (r);
31694 ptrdiff_t p = string_buffer_position (obj, start);
31695 if (p > 0)
31697 help = Fget_char_property (make_number (p),
31698 Qhelp_echo, w->contents);
31699 if (!NILP (help))
31701 charpos = p;
31702 obj = w->contents;
31707 else if (BUFFERP (obj)
31708 && charpos >= BEGV
31709 && charpos < ZV)
31710 help = Fget_text_property (make_number (charpos), Qhelp_echo,
31711 obj);
31713 if (!NILP (help))
31715 help_echo_string = help;
31716 help_echo_window = window;
31717 help_echo_object = obj;
31718 help_echo_pos = charpos;
31723 #ifdef HAVE_WINDOW_SYSTEM
31724 /* Look for a `pointer' property. */
31725 if (FRAME_WINDOW_P (f) && NILP (pointer))
31727 /* Check overlays first. */
31728 for (i = noverlays - 1; i >= 0 && NILP (pointer); --i)
31729 pointer = Foverlay_get (overlay_vec[i], Qpointer);
31731 if (NILP (pointer))
31733 Lisp_Object obj = glyph->object;
31734 ptrdiff_t charpos = glyph->charpos;
31736 /* Try text properties. */
31737 if (STRINGP (obj)
31738 && charpos >= 0
31739 && charpos < SCHARS (obj))
31741 pointer = Fget_text_property (make_number (charpos),
31742 Qpointer, obj);
31743 if (NILP (pointer))
31745 /* If the string itself doesn't specify a pointer,
31746 see if the buffer text ``under'' it does. */
31747 struct glyph_row *r
31748 = MATRIX_ROW (w->current_matrix, vpos);
31749 ptrdiff_t start = MATRIX_ROW_START_CHARPOS (r);
31750 ptrdiff_t p = string_buffer_position (obj, start);
31751 if (p > 0)
31752 pointer = Fget_char_property (make_number (p),
31753 Qpointer, w->contents);
31756 else if (BUFFERP (obj)
31757 && charpos >= BEGV
31758 && charpos < ZV)
31759 pointer = Fget_text_property (make_number (charpos),
31760 Qpointer, obj);
31763 #endif /* HAVE_WINDOW_SYSTEM */
31765 BEGV = obegv;
31766 ZV = ozv;
31767 current_buffer = obuf;
31768 SAFE_FREE ();
31771 set_cursor:
31772 define_frame_cursor1 (f, cursor, pointer);
31776 /* EXPORT for RIF:
31777 Clear any mouse-face on window W. This function is part of the
31778 redisplay interface, and is called from try_window_id and similar
31779 functions to ensure the mouse-highlight is off. */
31781 void
31782 x_clear_window_mouse_face (struct window *w)
31784 Mouse_HLInfo *hlinfo = MOUSE_HL_INFO (XFRAME (w->frame));
31785 Lisp_Object window;
31787 block_input ();
31788 XSETWINDOW (window, w);
31789 if (EQ (window, hlinfo->mouse_face_window))
31790 clear_mouse_face (hlinfo);
31791 unblock_input ();
31795 /* EXPORT:
31796 Just discard the mouse face information for frame F, if any.
31797 This is used when the size of F is changed. */
31799 void
31800 cancel_mouse_face (struct frame *f)
31802 Lisp_Object window;
31803 Mouse_HLInfo *hlinfo = MOUSE_HL_INFO (f);
31805 window = hlinfo->mouse_face_window;
31806 if (! NILP (window) && XFRAME (XWINDOW (window)->frame) == f)
31807 reset_mouse_highlight (hlinfo);
31812 /***********************************************************************
31813 Exposure Events
31814 ***********************************************************************/
31816 #ifdef HAVE_WINDOW_SYSTEM
31818 /* Redraw the part of glyph row area AREA of glyph row ROW on window W
31819 which intersects rectangle R. R is in window-relative coordinates. */
31821 static void
31822 expose_area (struct window *w, struct glyph_row *row, XRectangle *r,
31823 enum glyph_row_area area)
31825 struct glyph *first = row->glyphs[area];
31826 struct glyph *end = row->glyphs[area] + row->used[area];
31827 struct glyph *last;
31828 int first_x, start_x, x;
31830 if (area == TEXT_AREA && row->fill_line_p)
31831 /* If row extends face to end of line write the whole line. */
31832 draw_glyphs (w, 0, row, area,
31833 0, row->used[area],
31834 DRAW_NORMAL_TEXT, 0);
31835 else
31837 /* Set START_X to the window-relative start position for drawing glyphs of
31838 AREA. The first glyph of the text area can be partially visible.
31839 The first glyphs of other areas cannot. */
31840 start_x = window_box_left_offset (w, area);
31841 x = start_x;
31842 if (area == TEXT_AREA)
31843 x += row->x;
31845 /* Find the first glyph that must be redrawn. */
31846 while (first < end
31847 && x + first->pixel_width < r->x)
31849 x += first->pixel_width;
31850 ++first;
31853 /* Find the last one. */
31854 last = first;
31855 first_x = x;
31856 /* Use a signed int intermediate value to avoid catastrophic
31857 failures due to comparison between signed and unsigned, when
31858 x is negative (can happen for wide images that are hscrolled). */
31859 int r_end = r->x + r->width;
31860 while (last < end && x < r_end)
31862 x += last->pixel_width;
31863 ++last;
31866 /* Repaint. */
31867 if (last > first)
31868 draw_glyphs (w, first_x - start_x, row, area,
31869 first - row->glyphs[area], last - row->glyphs[area],
31870 DRAW_NORMAL_TEXT, 0);
31875 /* Redraw the parts of the glyph row ROW on window W intersecting
31876 rectangle R. R is in window-relative coordinates. Value is
31877 true if mouse-face was overwritten. */
31879 static bool
31880 expose_line (struct window *w, struct glyph_row *row, XRectangle *r)
31882 eassert (row->enabled_p);
31884 if (row->mode_line_p || w->pseudo_window_p)
31885 draw_glyphs (w, 0, row, TEXT_AREA,
31886 0, row->used[TEXT_AREA],
31887 DRAW_NORMAL_TEXT, 0);
31888 else
31890 if (row->used[LEFT_MARGIN_AREA])
31891 expose_area (w, row, r, LEFT_MARGIN_AREA);
31892 if (row->used[TEXT_AREA])
31893 expose_area (w, row, r, TEXT_AREA);
31894 if (row->used[RIGHT_MARGIN_AREA])
31895 expose_area (w, row, r, RIGHT_MARGIN_AREA);
31896 draw_row_fringe_bitmaps (w, row);
31899 return row->mouse_face_p;
31903 /* Redraw those parts of glyphs rows during expose event handling that
31904 overlap other rows. Redrawing of an exposed line writes over parts
31905 of lines overlapping that exposed line; this function fixes that.
31907 W is the window being exposed. FIRST_OVERLAPPING_ROW is the first
31908 row in W's current matrix that is exposed and overlaps other rows.
31909 LAST_OVERLAPPING_ROW is the last such row. */
31911 static void
31912 expose_overlaps (struct window *w,
31913 struct glyph_row *first_overlapping_row,
31914 struct glyph_row *last_overlapping_row,
31915 XRectangle *r)
31917 struct glyph_row *row;
31919 for (row = first_overlapping_row; row <= last_overlapping_row; ++row)
31920 if (row->overlapping_p)
31922 eassert (row->enabled_p && !row->mode_line_p);
31924 row->clip = r;
31925 if (row->used[LEFT_MARGIN_AREA])
31926 x_fix_overlapping_area (w, row, LEFT_MARGIN_AREA, OVERLAPS_BOTH);
31928 if (row->used[TEXT_AREA])
31929 x_fix_overlapping_area (w, row, TEXT_AREA, OVERLAPS_BOTH);
31931 if (row->used[RIGHT_MARGIN_AREA])
31932 x_fix_overlapping_area (w, row, RIGHT_MARGIN_AREA, OVERLAPS_BOTH);
31933 row->clip = NULL;
31938 /* Return true if W's cursor intersects rectangle R. */
31940 static bool
31941 phys_cursor_in_rect_p (struct window *w, XRectangle *r)
31943 XRectangle cr, result;
31944 struct glyph *cursor_glyph;
31945 struct glyph_row *row;
31947 if (w->phys_cursor.vpos >= 0
31948 && w->phys_cursor.vpos < w->current_matrix->nrows
31949 && (row = MATRIX_ROW (w->current_matrix, w->phys_cursor.vpos),
31950 row->enabled_p)
31951 && row->cursor_in_fringe_p)
31953 /* Cursor is in the fringe. */
31954 cr.x = window_box_right_offset (w,
31955 (WINDOW_HAS_FRINGES_OUTSIDE_MARGINS (w)
31956 ? RIGHT_MARGIN_AREA
31957 : TEXT_AREA));
31958 cr.y = row->y;
31959 cr.width = WINDOW_RIGHT_FRINGE_WIDTH (w);
31960 cr.height = row->height;
31961 return x_intersect_rectangles (&cr, r, &result);
31964 cursor_glyph = get_phys_cursor_glyph (w);
31965 if (cursor_glyph)
31967 /* r is relative to W's box, but w->phys_cursor.x is relative
31968 to left edge of W's TEXT area. Adjust it. */
31969 cr.x = window_box_left_offset (w, TEXT_AREA) + w->phys_cursor.x;
31970 cr.y = w->phys_cursor.y;
31971 cr.width = cursor_glyph->pixel_width;
31972 cr.height = w->phys_cursor_height;
31973 /* ++KFS: W32 version used W32-specific IntersectRect here, but
31974 I assume the effect is the same -- and this is portable. */
31975 return x_intersect_rectangles (&cr, r, &result);
31977 /* If we don't understand the format, pretend we're not in the hot-spot. */
31978 return false;
31982 /* EXPORT:
31983 Draw a vertical window border to the right of window W if W doesn't
31984 have vertical scroll bars. */
31986 void
31987 x_draw_vertical_border (struct window *w)
31989 struct frame *f = XFRAME (WINDOW_FRAME (w));
31991 /* We could do better, if we knew what type of scroll-bar the adjacent
31992 windows (on either side) have... But we don't :-(
31993 However, I think this works ok. ++KFS 2003-04-25 */
31995 /* Redraw borders between horizontally adjacent windows. Don't
31996 do it for frames with vertical scroll bars because either the
31997 right scroll bar of a window, or the left scroll bar of its
31998 neighbor will suffice as a border. */
31999 if (FRAME_HAS_VERTICAL_SCROLL_BARS (f) || FRAME_RIGHT_DIVIDER_WIDTH (f))
32000 return;
32002 /* Note: It is necessary to redraw both the left and the right
32003 borders, for when only this single window W is being
32004 redisplayed. */
32005 if (!WINDOW_RIGHTMOST_P (w)
32006 && !WINDOW_HAS_VERTICAL_SCROLL_BAR_ON_RIGHT (w))
32008 int x0, x1, y0, y1;
32010 window_box_edges (w, &x0, &y0, &x1, &y1);
32011 y1 -= 1;
32013 if (WINDOW_LEFT_FRINGE_WIDTH (w) == 0)
32014 x1 -= 1;
32016 FRAME_RIF (f)->draw_vertical_window_border (w, x1, y0, y1);
32019 if (!WINDOW_LEFTMOST_P (w)
32020 && !WINDOW_HAS_VERTICAL_SCROLL_BAR_ON_LEFT (w))
32022 int x0, x1, y0, y1;
32024 window_box_edges (w, &x0, &y0, &x1, &y1);
32025 y1 -= 1;
32027 if (WINDOW_LEFT_FRINGE_WIDTH (w) == 0)
32028 x0 -= 1;
32030 FRAME_RIF (f)->draw_vertical_window_border (w, x0, y0, y1);
32035 /* Draw window dividers for window W. */
32037 void
32038 x_draw_right_divider (struct window *w)
32040 struct frame *f = WINDOW_XFRAME (w);
32042 if (w->mini || w->pseudo_window_p)
32043 return;
32044 else if (WINDOW_RIGHT_DIVIDER_WIDTH (w))
32046 int x0 = WINDOW_RIGHT_EDGE_X (w) - WINDOW_RIGHT_DIVIDER_WIDTH (w);
32047 int x1 = WINDOW_RIGHT_EDGE_X (w);
32048 int y0 = WINDOW_TOP_EDGE_Y (w);
32049 int y1 = WINDOW_BOTTOM_EDGE_Y (w);
32051 /* If W is horizontally combined and has a right sibling, don't
32052 draw over any bottom divider. */
32053 if (WINDOW_BOTTOM_DIVIDER_WIDTH (w)
32054 && !NILP (w->parent)
32055 && WINDOW_HORIZONTAL_COMBINATION_P (XWINDOW (w->parent))
32056 && !NILP (w->next))
32057 y1 -= WINDOW_BOTTOM_DIVIDER_WIDTH (w);
32059 FRAME_RIF (f)->draw_window_divider (w, x0, x1, y0, y1);
32063 static void
32064 x_draw_bottom_divider (struct window *w)
32066 struct frame *f = XFRAME (WINDOW_FRAME (w));
32068 if (w->mini || w->pseudo_window_p)
32069 return;
32070 else if (WINDOW_BOTTOM_DIVIDER_WIDTH (w))
32072 int x0 = WINDOW_LEFT_EDGE_X (w);
32073 int x1 = WINDOW_RIGHT_EDGE_X (w);
32074 int y0 = WINDOW_BOTTOM_EDGE_Y (w) - WINDOW_BOTTOM_DIVIDER_WIDTH (w);
32075 int y1 = WINDOW_BOTTOM_EDGE_Y (w);
32076 struct window *p = !NILP (w->parent) ? XWINDOW (w->parent) : NULL;
32078 /* If W is vertically combined and has a sibling below, don't draw
32079 over any right divider. */
32080 if (WINDOW_RIGHT_DIVIDER_WIDTH (w)
32081 && p
32082 && ((WINDOW_VERTICAL_COMBINATION_P (p)
32083 && !NILP (w->next))
32084 || (WINDOW_HORIZONTAL_COMBINATION_P (p)
32085 && NILP (w->next)
32086 && !NILP (p->parent)
32087 && WINDOW_VERTICAL_COMBINATION_P (XWINDOW (p->parent))
32088 && !NILP (XWINDOW (p->parent)->next))))
32089 x1 -= WINDOW_RIGHT_DIVIDER_WIDTH (w);
32091 FRAME_RIF (f)->draw_window_divider (w, x0, x1, y0, y1);
32095 /* Redraw the part of window W intersection rectangle FR. Pixel
32096 coordinates in FR are frame-relative. Call this function with
32097 input blocked. Value is true if the exposure overwrites
32098 mouse-face. */
32100 static bool
32101 expose_window (struct window *w, XRectangle *fr)
32103 struct frame *f = XFRAME (w->frame);
32104 XRectangle wr, r;
32105 bool mouse_face_overwritten_p = false;
32107 /* If window is not yet fully initialized, do nothing. This can
32108 happen when toolkit scroll bars are used and a window is split.
32109 Reconfiguring the scroll bar will generate an expose for a newly
32110 created window. */
32111 if (w->current_matrix == NULL)
32112 return false;
32114 /* When we're currently updating the window, display and current
32115 matrix usually don't agree. Arrange for a thorough display
32116 later. */
32117 if (w->must_be_updated_p)
32119 SET_FRAME_GARBAGED (f);
32120 return false;
32123 /* Frame-relative pixel rectangle of W. */
32124 wr.x = WINDOW_LEFT_EDGE_X (w);
32125 wr.y = WINDOW_TOP_EDGE_Y (w);
32126 wr.width = WINDOW_PIXEL_WIDTH (w);
32127 wr.height = WINDOW_PIXEL_HEIGHT (w);
32129 if (x_intersect_rectangles (fr, &wr, &r))
32131 int yb = window_text_bottom_y (w);
32132 struct glyph_row *row;
32133 struct glyph_row *first_overlapping_row, *last_overlapping_row;
32135 TRACE ((stderr, "expose_window (%d, %d, %d, %d)\n",
32136 r.x, r.y, r.width, r.height));
32138 /* Convert to window coordinates. */
32139 r.x -= WINDOW_LEFT_EDGE_X (w);
32140 r.y -= WINDOW_TOP_EDGE_Y (w);
32142 /* Turn off the cursor. */
32143 bool cursor_cleared_p = (!w->pseudo_window_p
32144 && phys_cursor_in_rect_p (w, &r));
32145 if (cursor_cleared_p)
32146 x_clear_cursor (w);
32148 /* If the row containing the cursor extends face to end of line,
32149 then expose_area might overwrite the cursor outside the
32150 rectangle and thus notice_overwritten_cursor might clear
32151 w->phys_cursor_on_p. We remember the original value and
32152 check later if it is changed. */
32153 bool phys_cursor_on_p = w->phys_cursor_on_p;
32155 /* Use a signed int intermediate value to avoid catastrophic
32156 failures due to comparison between signed and unsigned, when
32157 y0 or y1 is negative (can happen for tall images). */
32158 int r_bottom = r.y + r.height;
32160 /* Update lines intersecting rectangle R. */
32161 first_overlapping_row = last_overlapping_row = NULL;
32162 for (row = w->current_matrix->rows;
32163 row->enabled_p;
32164 ++row)
32166 int y0 = row->y;
32167 int y1 = MATRIX_ROW_BOTTOM_Y (row);
32169 if ((y0 >= r.y && y0 < r_bottom)
32170 || (y1 > r.y && y1 < r_bottom)
32171 || (r.y >= y0 && r.y < y1)
32172 || (r_bottom > y0 && r_bottom < y1))
32174 /* A header line may be overlapping, but there is no need
32175 to fix overlapping areas for them. KFS 2005-02-12 */
32176 if (row->overlapping_p && !row->mode_line_p)
32178 if (first_overlapping_row == NULL)
32179 first_overlapping_row = row;
32180 last_overlapping_row = row;
32183 row->clip = fr;
32184 if (expose_line (w, row, &r))
32185 mouse_face_overwritten_p = true;
32186 row->clip = NULL;
32188 else if (row->overlapping_p)
32190 /* We must redraw a row overlapping the exposed area. */
32191 if (y0 < r.y
32192 ? y0 + row->phys_height > r.y
32193 : y0 + row->ascent - row->phys_ascent < r.y +r.height)
32195 if (first_overlapping_row == NULL)
32196 first_overlapping_row = row;
32197 last_overlapping_row = row;
32201 if (y1 >= yb)
32202 break;
32205 /* Display the mode line if there is one. */
32206 if (window_wants_mode_line (w)
32207 && (row = MATRIX_MODE_LINE_ROW (w->current_matrix),
32208 row->enabled_p)
32209 && row->y < r_bottom)
32211 if (expose_line (w, row, &r))
32212 mouse_face_overwritten_p = true;
32215 if (!w->pseudo_window_p)
32217 /* Fix the display of overlapping rows. */
32218 if (first_overlapping_row)
32219 expose_overlaps (w, first_overlapping_row, last_overlapping_row,
32220 fr);
32222 /* Draw border between windows. */
32223 if (WINDOW_RIGHT_DIVIDER_WIDTH (w))
32224 x_draw_right_divider (w);
32225 else
32226 x_draw_vertical_border (w);
32228 if (WINDOW_BOTTOM_DIVIDER_WIDTH (w))
32229 x_draw_bottom_divider (w);
32231 /* Turn the cursor on again. */
32232 if (cursor_cleared_p
32233 || (phys_cursor_on_p && !w->phys_cursor_on_p))
32234 update_window_cursor (w, true);
32238 return mouse_face_overwritten_p;
32243 /* Redraw (parts) of all windows in the window tree rooted at W that
32244 intersect R. R contains frame pixel coordinates. Value is
32245 true if the exposure overwrites mouse-face. */
32247 static bool
32248 expose_window_tree (struct window *w, XRectangle *r)
32250 struct frame *f = XFRAME (w->frame);
32251 bool mouse_face_overwritten_p = false;
32253 while (w && !FRAME_GARBAGED_P (f))
32255 mouse_face_overwritten_p
32256 |= (WINDOWP (w->contents)
32257 ? expose_window_tree (XWINDOW (w->contents), r)
32258 : expose_window (w, r));
32260 w = NILP (w->next) ? NULL : XWINDOW (w->next);
32263 return mouse_face_overwritten_p;
32267 /* EXPORT:
32268 Redisplay an exposed area of frame F. X and Y are the upper-left
32269 corner of the exposed rectangle. W and H are width and height of
32270 the exposed area. All are pixel values. W or H zero means redraw
32271 the entire frame. */
32273 void
32274 expose_frame (struct frame *f, int x, int y, int w, int h)
32276 XRectangle r;
32277 bool mouse_face_overwritten_p = false;
32279 TRACE ((stderr, "expose_frame "));
32281 /* No need to redraw if frame will be redrawn soon. */
32282 if (FRAME_GARBAGED_P (f))
32284 TRACE ((stderr, " garbaged\n"));
32285 return;
32288 /* If basic faces haven't been realized yet, there is no point in
32289 trying to redraw anything. This can happen when we get an expose
32290 event while Emacs is starting, e.g. by moving another window. */
32291 if (FRAME_FACE_CACHE (f) == NULL
32292 || FRAME_FACE_CACHE (f)->used < BASIC_FACE_ID_SENTINEL)
32294 TRACE ((stderr, " no faces\n"));
32295 return;
32298 if (w == 0 || h == 0)
32300 r.x = r.y = 0;
32301 r.width = FRAME_TEXT_WIDTH (f);
32302 r.height = FRAME_TEXT_HEIGHT (f);
32304 else
32306 r.x = x;
32307 r.y = y;
32308 r.width = w;
32309 r.height = h;
32312 TRACE ((stderr, "(%d, %d, %d, %d)\n", r.x, r.y, r.width, r.height));
32313 mouse_face_overwritten_p = expose_window_tree (XWINDOW (f->root_window), &r);
32315 #if ! defined (USE_GTK) && ! defined (HAVE_NS)
32316 if (WINDOWP (f->tool_bar_window))
32317 mouse_face_overwritten_p
32318 |= expose_window (XWINDOW (f->tool_bar_window), &r);
32319 #endif
32321 #ifdef HAVE_X_WINDOWS
32322 #ifndef MSDOS
32323 #if ! defined (USE_X_TOOLKIT) && ! defined (USE_GTK)
32324 if (WINDOWP (f->menu_bar_window))
32325 mouse_face_overwritten_p
32326 |= expose_window (XWINDOW (f->menu_bar_window), &r);
32327 #endif /* not USE_X_TOOLKIT and not USE_GTK */
32328 #endif
32329 #endif
32331 /* Some window managers support a focus-follows-mouse style with
32332 delayed raising of frames. Imagine a partially obscured frame,
32333 and moving the mouse into partially obscured mouse-face on that
32334 frame. The visible part of the mouse-face will be highlighted,
32335 then the WM raises the obscured frame. With at least one WM, KDE
32336 2.1, Emacs is not getting any event for the raising of the frame
32337 (even tried with SubstructureRedirectMask), only Expose events.
32338 These expose events will draw text normally, i.e. not
32339 highlighted. Which means we must redo the highlight here.
32340 Subsume it under ``we love X''. --gerd 2001-08-15 */
32341 /* Included in Windows version because Windows most likely does not
32342 do the right thing if any third party tool offers
32343 focus-follows-mouse with delayed raise. --jason 2001-10-12 */
32344 if (mouse_face_overwritten_p && !FRAME_GARBAGED_P (f))
32346 Mouse_HLInfo *hlinfo = MOUSE_HL_INFO (f);
32347 if (f == hlinfo->mouse_face_mouse_frame)
32349 int mouse_x = hlinfo->mouse_face_mouse_x;
32350 int mouse_y = hlinfo->mouse_face_mouse_y;
32351 clear_mouse_face (hlinfo);
32352 note_mouse_highlight (f, mouse_x, mouse_y);
32358 /* EXPORT:
32359 Determine the intersection of two rectangles R1 and R2. Return
32360 the intersection in *RESULT. Value is true if RESULT is not
32361 empty. */
32363 bool
32364 x_intersect_rectangles (XRectangle *r1, XRectangle *r2, XRectangle *result)
32366 XRectangle *left, *right;
32367 XRectangle *upper, *lower;
32368 bool intersection_p = false;
32370 /* Rearrange so that R1 is the left-most rectangle. */
32371 if (r1->x < r2->x)
32372 left = r1, right = r2;
32373 else
32374 left = r2, right = r1;
32376 /* X0 of the intersection is right.x0, if this is inside R1,
32377 otherwise there is no intersection. */
32378 if (right->x <= left->x + left->width)
32380 result->x = right->x;
32382 /* The right end of the intersection is the minimum of
32383 the right ends of left and right. */
32384 result->width = (min (left->x + left->width, right->x + right->width)
32385 - result->x);
32387 /* Same game for Y. */
32388 if (r1->y < r2->y)
32389 upper = r1, lower = r2;
32390 else
32391 upper = r2, lower = r1;
32393 /* The upper end of the intersection is lower.y0, if this is inside
32394 of upper. Otherwise, there is no intersection. */
32395 if (lower->y <= upper->y + upper->height)
32397 result->y = lower->y;
32399 /* The lower end of the intersection is the minimum of the lower
32400 ends of upper and lower. */
32401 result->height = (min (lower->y + lower->height,
32402 upper->y + upper->height)
32403 - result->y);
32404 intersection_p = true;
32408 return intersection_p;
32411 #endif /* HAVE_WINDOW_SYSTEM */
32414 /***********************************************************************
32415 Initialization
32416 ***********************************************************************/
32418 void
32419 syms_of_xdisp (void)
32421 Vwith_echo_area_save_vector = Qnil;
32422 staticpro (&Vwith_echo_area_save_vector);
32424 Vmessage_stack = Qnil;
32425 staticpro (&Vmessage_stack);
32427 /* Non-nil means don't actually do any redisplay. */
32428 DEFSYM (Qinhibit_redisplay, "inhibit-redisplay");
32430 DEFSYM (Qredisplay_internal_xC_functionx, "redisplay_internal (C function)");
32432 DEFVAR_BOOL("inhibit-message", inhibit_message,
32433 doc: /* Non-nil means calls to `message' are not displayed.
32434 They are still logged to the *Messages* buffer. */);
32435 inhibit_message = 0;
32437 message_dolog_marker1 = Fmake_marker ();
32438 staticpro (&message_dolog_marker1);
32439 message_dolog_marker2 = Fmake_marker ();
32440 staticpro (&message_dolog_marker2);
32441 message_dolog_marker3 = Fmake_marker ();
32442 staticpro (&message_dolog_marker3);
32444 defsubr (&Sset_buffer_redisplay);
32445 #ifdef GLYPH_DEBUG
32446 defsubr (&Sdump_frame_glyph_matrix);
32447 defsubr (&Sdump_glyph_matrix);
32448 defsubr (&Sdump_glyph_row);
32449 defsubr (&Sdump_tool_bar_row);
32450 defsubr (&Strace_redisplay);
32451 defsubr (&Strace_to_stderr);
32452 #endif
32453 #ifdef HAVE_WINDOW_SYSTEM
32454 defsubr (&Stool_bar_height);
32455 defsubr (&Slookup_image_map);
32456 #endif
32457 defsubr (&Sline_pixel_height);
32458 defsubr (&Sformat_mode_line);
32459 defsubr (&Sinvisible_p);
32460 defsubr (&Scurrent_bidi_paragraph_direction);
32461 defsubr (&Swindow_text_pixel_size);
32462 defsubr (&Smove_point_visually);
32463 defsubr (&Sbidi_find_overridden_directionality);
32465 DEFSYM (Qmenu_bar_update_hook, "menu-bar-update-hook");
32466 DEFSYM (Qoverriding_terminal_local_map, "overriding-terminal-local-map");
32467 DEFSYM (Qoverriding_local_map, "overriding-local-map");
32468 DEFSYM (Qwindow_scroll_functions, "window-scroll-functions");
32469 DEFSYM (Qredisplay_end_trigger_functions, "redisplay-end-trigger-functions");
32470 DEFSYM (Qinhibit_point_motion_hooks, "inhibit-point-motion-hooks");
32471 DEFSYM (Qeval, "eval");
32472 DEFSYM (QCdata, ":data");
32474 /* Names of text properties relevant for redisplay. */
32475 DEFSYM (Qdisplay, "display");
32476 DEFSYM (Qspace_width, "space-width");
32477 DEFSYM (Qraise, "raise");
32478 DEFSYM (Qslice, "slice");
32479 DEFSYM (Qspace, "space");
32480 DEFSYM (Qmargin, "margin");
32481 DEFSYM (Qpointer, "pointer");
32482 DEFSYM (Qleft_margin, "left-margin");
32483 DEFSYM (Qright_margin, "right-margin");
32484 DEFSYM (Qcenter, "center");
32485 DEFSYM (Qline_height, "line-height");
32486 DEFSYM (QCalign_to, ":align-to");
32487 DEFSYM (QCrelative_width, ":relative-width");
32488 DEFSYM (QCrelative_height, ":relative-height");
32489 DEFSYM (QCeval, ":eval");
32490 DEFSYM (QCpropertize, ":propertize");
32491 DEFSYM (QCfile, ":file");
32492 DEFSYM (Qfontified, "fontified");
32493 DEFSYM (Qfontification_functions, "fontification-functions");
32495 /* Name of the symbol which disables Lisp evaluation in 'display'
32496 properties. This is used by enriched.el. */
32497 DEFSYM (Qdisable_eval, "disable-eval");
32499 /* Name of the face used to highlight trailing whitespace. */
32500 DEFSYM (Qtrailing_whitespace, "trailing-whitespace");
32502 /* Names of the faces used to display line numbers. */
32503 DEFSYM (Qline_number, "line-number");
32504 DEFSYM (Qline_number_current_line, "line-number-current-line");
32505 /* Name of a text property which disables line-number display. */
32506 DEFSYM (Qdisplay_line_numbers_disable, "display-line-numbers-disable");
32508 /* Name and number of the face used to highlight escape glyphs. */
32509 DEFSYM (Qescape_glyph, "escape-glyph");
32511 /* Name and number of the face used to highlight non-breaking
32512 spaces/hyphens. */
32513 DEFSYM (Qnobreak_space, "nobreak-space");
32514 DEFSYM (Qnobreak_hyphen, "nobreak-hyphen");
32516 /* The symbol 'image' which is the car of the lists used to represent
32517 images in Lisp. Also a tool bar style. */
32518 DEFSYM (Qimage, "image");
32520 /* Tool bar styles. */
32521 DEFSYM (Qtext, "text");
32522 DEFSYM (Qboth, "both");
32523 DEFSYM (Qboth_horiz, "both-horiz");
32524 DEFSYM (Qtext_image_horiz, "text-image-horiz");
32526 /* The image map types. */
32527 DEFSYM (QCmap, ":map");
32528 DEFSYM (QCpointer, ":pointer");
32529 DEFSYM (Qrect, "rect");
32530 DEFSYM (Qcircle, "circle");
32531 DEFSYM (Qpoly, "poly");
32533 DEFSYM (Qinhibit_menubar_update, "inhibit-menubar-update");
32535 DEFSYM (Qgrow_only, "grow-only");
32536 DEFSYM (Qinhibit_eval_during_redisplay, "inhibit-eval-during-redisplay");
32537 DEFSYM (Qposition, "position");
32538 DEFSYM (Qbuffer_position, "buffer-position");
32539 DEFSYM (Qobject, "object");
32541 /* Cursor shapes. */
32542 DEFSYM (Qbar, "bar");
32543 DEFSYM (Qhbar, "hbar");
32544 DEFSYM (Qbox, "box");
32545 DEFSYM (Qhollow, "hollow");
32547 /* Pointer shapes. */
32548 DEFSYM (Qhand, "hand");
32549 DEFSYM (Qarrow, "arrow");
32550 /* also Qtext */
32552 DEFSYM (Qdragging, "dragging");
32554 DEFSYM (Qinhibit_free_realized_faces, "inhibit-free-realized-faces");
32556 list_of_error = list1 (list2 (Qerror, Qvoid_variable));
32557 staticpro (&list_of_error);
32559 /* Values of those variables at last redisplay are stored as
32560 properties on 'overlay-arrow-position' symbol. However, if
32561 Voverlay_arrow_position is a marker, last-arrow-position is its
32562 numerical position. */
32563 DEFSYM (Qlast_arrow_position, "last-arrow-position");
32564 DEFSYM (Qlast_arrow_string, "last-arrow-string");
32566 /* Alternative overlay-arrow-string and overlay-arrow-bitmap
32567 properties on a symbol in overlay-arrow-variable-list. */
32568 DEFSYM (Qoverlay_arrow_string, "overlay-arrow-string");
32569 DEFSYM (Qoverlay_arrow_bitmap, "overlay-arrow-bitmap");
32571 echo_buffer[0] = echo_buffer[1] = Qnil;
32572 staticpro (&echo_buffer[0]);
32573 staticpro (&echo_buffer[1]);
32575 echo_area_buffer[0] = echo_area_buffer[1] = Qnil;
32576 staticpro (&echo_area_buffer[0]);
32577 staticpro (&echo_area_buffer[1]);
32579 Vmessages_buffer_name = build_pure_c_string ("*Messages*");
32580 staticpro (&Vmessages_buffer_name);
32582 mode_line_proptrans_alist = Qnil;
32583 staticpro (&mode_line_proptrans_alist);
32584 mode_line_string_list = Qnil;
32585 staticpro (&mode_line_string_list);
32586 mode_line_string_face = Qnil;
32587 staticpro (&mode_line_string_face);
32588 mode_line_string_face_prop = Qnil;
32589 staticpro (&mode_line_string_face_prop);
32590 Vmode_line_unwind_vector = Qnil;
32591 staticpro (&Vmode_line_unwind_vector);
32593 DEFSYM (Qmode_line_default_help_echo, "mode-line-default-help-echo");
32595 help_echo_string = Qnil;
32596 staticpro (&help_echo_string);
32597 help_echo_object = Qnil;
32598 staticpro (&help_echo_object);
32599 help_echo_window = Qnil;
32600 staticpro (&help_echo_window);
32601 previous_help_echo_string = Qnil;
32602 staticpro (&previous_help_echo_string);
32603 help_echo_pos = -1;
32605 DEFSYM (Qright_to_left, "right-to-left");
32606 DEFSYM (Qleft_to_right, "left-to-right");
32607 defsubr (&Sbidi_resolved_levels);
32609 #ifdef HAVE_WINDOW_SYSTEM
32610 DEFVAR_BOOL ("x-stretch-cursor", x_stretch_cursor_p,
32611 doc: /* Non-nil means draw block cursor as wide as the glyph under it.
32612 For example, if a block cursor is over a tab, it will be drawn as
32613 wide as that tab on the display. */);
32614 x_stretch_cursor_p = 0;
32615 #endif
32617 DEFVAR_LISP ("show-trailing-whitespace", Vshow_trailing_whitespace,
32618 doc: /* Non-nil means highlight trailing whitespace.
32619 The face used for trailing whitespace is `trailing-whitespace'. */);
32620 Vshow_trailing_whitespace = Qnil;
32622 DEFVAR_LISP ("nobreak-char-display", Vnobreak_char_display,
32623 doc: /* Control highlighting of non-ASCII space and hyphen chars.
32624 If the value is t, Emacs highlights non-ASCII chars which have the
32625 same appearance as an ASCII space or hyphen, using the `nobreak-space'
32626 or `nobreak-hyphen' face respectively.
32628 U+00A0 (no-break space), U+00AD (soft hyphen), U+2010 (hyphen), and
32629 U+2011 (non-breaking hyphen) are affected.
32631 Any other non-nil value means to display these characters as an escape
32632 glyph followed by an ordinary space or hyphen.
32634 A value of nil means no special handling of these characters. */);
32635 Vnobreak_char_display = Qt;
32637 DEFVAR_LISP ("void-text-area-pointer", Vvoid_text_area_pointer,
32638 doc: /* The pointer shape to show in void text areas.
32639 A value of nil means to show the text pointer. Other options are
32640 `arrow', `text', `hand', `vdrag', `hdrag', `nhdrag', `modeline', and
32641 `hourglass'. */);
32642 Vvoid_text_area_pointer = Qarrow;
32644 DEFVAR_LISP ("inhibit-redisplay", Vinhibit_redisplay,
32645 doc: /* Non-nil means don't actually do any redisplay.
32646 This is used for internal purposes. */);
32647 Vinhibit_redisplay = Qnil;
32649 DEFVAR_LISP ("global-mode-string", Vglobal_mode_string,
32650 doc: /* String (or mode line construct) included (normally) in `mode-line-format'. */);
32651 Vglobal_mode_string = Qnil;
32653 DEFVAR_LISP ("overlay-arrow-position", Voverlay_arrow_position,
32654 doc: /* Marker for where to display an arrow on top of the buffer text.
32655 This must be the beginning of a line in order to work.
32656 See also `overlay-arrow-string'. */);
32657 Voverlay_arrow_position = Qnil;
32659 DEFVAR_LISP ("overlay-arrow-string", Voverlay_arrow_string,
32660 doc: /* String to display as an arrow in non-window frames.
32661 See also `overlay-arrow-position'. */);
32662 Voverlay_arrow_string = build_pure_c_string ("=>");
32664 DEFVAR_LISP ("overlay-arrow-variable-list", Voverlay_arrow_variable_list,
32665 doc: /* List of variables (symbols) which hold markers for overlay arrows.
32666 The symbols on this list are examined during redisplay to determine
32667 where to display overlay arrows. */);
32668 Voverlay_arrow_variable_list
32669 = list1 (intern_c_string ("overlay-arrow-position"));
32671 DEFVAR_INT ("scroll-step", emacs_scroll_step,
32672 doc: /* The number of lines to try scrolling a window by when point moves out.
32673 If that fails to bring point back on frame, point is centered instead.
32674 If this is zero, point is always centered after it moves off frame.
32675 If you want scrolling to always be a line at a time, you should set
32676 `scroll-conservatively' to a large value rather than set this to 1. */);
32678 DEFVAR_INT ("scroll-conservatively", scroll_conservatively,
32679 doc: /* Scroll up to this many lines, to bring point back on screen.
32680 If point moves off-screen, redisplay will scroll by up to
32681 `scroll-conservatively' lines in order to bring point just barely
32682 onto the screen again. If that cannot be done, then redisplay
32683 recenters point as usual.
32685 If the value is greater than 100, redisplay will never recenter point,
32686 but will always scroll just enough text to bring point into view, even
32687 if you move far away.
32689 A value of zero means always recenter point if it moves off screen. */);
32690 scroll_conservatively = 0;
32692 DEFVAR_INT ("scroll-margin", scroll_margin,
32693 doc: /* Number of lines of margin at the top and bottom of a window.
32694 Trigger automatic scrolling whenever point gets within this many lines
32695 of the top or bottom of the window (see info node `Auto Scrolling'). */);
32696 scroll_margin = 0;
32698 DEFVAR_LISP ("maximum-scroll-margin", Vmaximum_scroll_margin,
32699 doc: /* Maximum effective value of `scroll-margin'.
32700 Given as a fraction of the current window's lines. The value should
32701 be a floating point number between 0.0 and 0.5. The effective maximum
32702 is limited to (/ (1- window-lines) 2). Non-float values for this
32703 variable are ignored and the default 0.25 is used instead. */);
32704 Vmaximum_scroll_margin = make_float (0.25);
32706 DEFVAR_LISP ("display-pixels-per-inch", Vdisplay_pixels_per_inch,
32707 doc: /* Pixels per inch value for non-window system displays.
32708 Value is a number or a cons (WIDTH-DPI . HEIGHT-DPI). */);
32709 Vdisplay_pixels_per_inch = make_float (72.0);
32711 #ifdef GLYPH_DEBUG
32712 DEFVAR_INT ("debug-end-pos", debug_end_pos, doc: /* Don't ask. */);
32713 #endif
32715 DEFVAR_LISP ("truncate-partial-width-windows",
32716 Vtruncate_partial_width_windows,
32717 doc: /* Non-nil means truncate lines in windows narrower than the frame.
32718 For an integer value, truncate lines in each window narrower than the
32719 full frame width, provided the total window width in column units is less
32720 than that integer; otherwise, respect the value of `truncate-lines'.
32721 The total width of the window is as returned by `window-total-width', it
32722 includes the fringes, the continuation and truncation glyphs, the
32723 display margins (if any), and the scroll bar
32725 For any other non-nil value, truncate lines in all windows that do
32726 not span the full frame width.
32728 A value of nil means to respect the value of `truncate-lines'.
32730 If `word-wrap' is enabled, you might want to reduce this. */);
32731 Vtruncate_partial_width_windows = make_number (50);
32733 DEFVAR_LISP ("line-number-display-limit", Vline_number_display_limit,
32734 doc: /* Maximum buffer size for which line number should be displayed.
32735 If the buffer is bigger than this, the line number does not appear
32736 in the mode line. A value of nil means no limit. */);
32737 Vline_number_display_limit = Qnil;
32739 DEFVAR_INT ("line-number-display-limit-width",
32740 line_number_display_limit_width,
32741 doc: /* Maximum line width (in characters) for line number display.
32742 If the average length of the lines near point is bigger than this, then the
32743 line number may be omitted from the mode line. */);
32744 line_number_display_limit_width = 200;
32746 DEFVAR_BOOL ("highlight-nonselected-windows", highlight_nonselected_windows,
32747 doc: /* Non-nil means highlight region even in nonselected windows. */);
32748 highlight_nonselected_windows = false;
32750 DEFVAR_BOOL ("multiple-frames", multiple_frames,
32751 doc: /* Non-nil if more than one frame is visible on this display.
32752 Minibuffer-only frames don't count, but iconified frames do.
32753 This variable is not guaranteed to be accurate except while processing
32754 `frame-title-format' and `icon-title-format'. */);
32756 DEFVAR_LISP ("frame-title-format", Vframe_title_format,
32757 doc: /* Template for displaying the title bar of visible frames.
32758 \(Assuming the window manager supports this feature.)
32760 This variable has the same structure as `mode-line-format', except that
32761 the %c, %C, and %l constructs are ignored. It is used only on frames for
32762 which no explicit name has been set (see `modify-frame-parameters'). */);
32764 DEFVAR_LISP ("icon-title-format", Vicon_title_format,
32765 doc: /* Template for displaying the title bar of an iconified frame.
32766 \(Assuming the window manager supports this feature.)
32767 This variable has the same structure as `mode-line-format' (which see),
32768 and is used only on frames for which no explicit name has been set
32769 \(see `modify-frame-parameters'). */);
32770 Vicon_title_format
32771 = Vframe_title_format
32772 = listn (CONSTYPE_PURE, 3,
32773 intern_c_string ("multiple-frames"),
32774 build_pure_c_string ("%b"),
32775 listn (CONSTYPE_PURE, 4,
32776 empty_unibyte_string,
32777 intern_c_string ("invocation-name"),
32778 build_pure_c_string ("@"),
32779 intern_c_string ("system-name")));
32781 DEFVAR_LISP ("message-log-max", Vmessage_log_max,
32782 doc: /* Maximum number of lines to keep in the message log buffer.
32783 If nil, disable message logging. If t, log messages but don't truncate
32784 the buffer when it becomes large. */);
32785 Vmessage_log_max = make_number (1000);
32787 DEFVAR_LISP ("window-scroll-functions", Vwindow_scroll_functions,
32788 doc: /* List of functions to call before redisplaying a window with scrolling.
32789 Each function is called with two arguments, the window and its new
32790 display-start position.
32791 These functions are called whenever the `window-start' marker is modified,
32792 either to point into another buffer (e.g. via `set-window-buffer') or another
32793 place in the same buffer.
32794 When each function is called, the `window-start' marker of its window
32795 argument has been already set to the new value, and the buffer which that
32796 window will display is set to be the current buffer.
32797 Note that the value of `window-end' is not valid when these functions are
32798 called.
32800 Warning: Do not use this feature to alter the way the window
32801 is scrolled. It is not designed for that, and such use probably won't
32802 work. */);
32803 Vwindow_scroll_functions = Qnil;
32805 DEFVAR_LISP ("redisplay-end-trigger-functions", Vredisplay_end_trigger_functions,
32806 doc: /* Functions called when redisplay of a window reaches the end trigger.
32807 Each function is called with two arguments, the window and the end trigger value.
32808 See `set-window-redisplay-end-trigger'. */);
32809 Vredisplay_end_trigger_functions = Qnil;
32811 DEFVAR_LISP ("mouse-autoselect-window", Vmouse_autoselect_window,
32812 doc: /* Non-nil means autoselect window with mouse pointer.
32813 If nil, do not autoselect windows.
32814 A positive number means delay autoselection by that many seconds: a
32815 window is autoselected only after the mouse has remained in that
32816 window for the duration of the delay.
32817 A negative number has a similar effect, but causes windows to be
32818 autoselected only after the mouse has stopped moving. (Because of
32819 the way Emacs compares mouse events, you will occasionally wait twice
32820 that time before the window gets selected.)
32821 Any other value means to autoselect window instantaneously when the
32822 mouse pointer enters it.
32824 Autoselection selects the minibuffer only if it is active, and never
32825 unselects the minibuffer if it is active.
32827 When customizing this variable make sure that the actual value of
32828 `focus-follows-mouse' matches the behavior of your window manager. */);
32829 Vmouse_autoselect_window = Qnil;
32831 DEFVAR_LISP ("auto-resize-tool-bars", Vauto_resize_tool_bars,
32832 doc: /* Non-nil means automatically resize tool-bars.
32833 This dynamically changes the tool-bar's height to the minimum height
32834 that is needed to make all tool-bar items visible.
32835 If value is `grow-only', the tool-bar's height is only increased
32836 automatically; to decrease the tool-bar height, use \\[recenter]. */);
32837 Vauto_resize_tool_bars = Qt;
32839 DEFVAR_BOOL ("auto-raise-tool-bar-buttons", auto_raise_tool_bar_buttons_p,
32840 doc: /* Non-nil means raise tool-bar buttons when the mouse moves over them. */);
32841 auto_raise_tool_bar_buttons_p = true;
32843 DEFVAR_BOOL ("make-cursor-line-fully-visible", make_cursor_line_fully_visible_p,
32844 doc: /* Non-nil means to scroll (recenter) cursor line if it is not fully visible. */);
32845 make_cursor_line_fully_visible_p = true;
32847 DEFVAR_LISP ("tool-bar-border", Vtool_bar_border,
32848 doc: /* Border below tool-bar in pixels.
32849 If an integer, use it as the height of the border.
32850 If it is one of `internal-border-width' or `border-width', use the
32851 value of the corresponding frame parameter.
32852 Otherwise, no border is added below the tool-bar. */);
32853 Vtool_bar_border = Qinternal_border_width;
32855 DEFVAR_LISP ("tool-bar-button-margin", Vtool_bar_button_margin,
32856 doc: /* Margin around tool-bar buttons in pixels.
32857 If an integer, use that for both horizontal and vertical margins.
32858 Otherwise, value should be a pair of integers `(HORZ . VERT)' with
32859 HORZ specifying the horizontal margin, and VERT specifying the
32860 vertical margin. */);
32861 Vtool_bar_button_margin = make_number (DEFAULT_TOOL_BAR_BUTTON_MARGIN);
32863 DEFVAR_INT ("tool-bar-button-relief", tool_bar_button_relief,
32864 doc: /* Relief thickness of tool-bar buttons. */);
32865 tool_bar_button_relief = DEFAULT_TOOL_BAR_BUTTON_RELIEF;
32867 DEFVAR_LISP ("tool-bar-style", Vtool_bar_style,
32868 doc: /* Tool bar style to use.
32869 It can be one of
32870 image - show images only
32871 text - show text only
32872 both - show both, text below image
32873 both-horiz - show text to the right of the image
32874 text-image-horiz - show text to the left of the image
32875 any other - use system default or image if no system default.
32877 This variable only affects the GTK+ toolkit version of Emacs. */);
32878 Vtool_bar_style = Qnil;
32880 DEFVAR_INT ("tool-bar-max-label-size", tool_bar_max_label_size,
32881 doc: /* Maximum number of characters a label can have to be shown.
32882 The tool bar style must also show labels for this to have any effect, see
32883 `tool-bar-style'. */);
32884 tool_bar_max_label_size = DEFAULT_TOOL_BAR_LABEL_SIZE;
32886 DEFVAR_LISP ("fontification-functions", Vfontification_functions,
32887 doc: /* List of functions to call to fontify regions of text.
32888 Each function is called with one argument POS. Functions must
32889 fontify a region starting at POS in the current buffer, and give
32890 fontified regions the property `fontified'. */);
32891 Vfontification_functions = Qnil;
32892 Fmake_variable_buffer_local (Qfontification_functions);
32894 DEFVAR_BOOL ("unibyte-display-via-language-environment",
32895 unibyte_display_via_language_environment,
32896 doc: /* Non-nil means display unibyte text according to language environment.
32897 Specifically, this means that raw bytes in the range 160-255 decimal
32898 are displayed by converting them to the equivalent multibyte characters
32899 according to the current language environment. As a result, they are
32900 displayed according to the current fontset.
32902 Note that this variable affects only how these bytes are displayed,
32903 but does not change the fact they are interpreted as raw bytes. */);
32904 unibyte_display_via_language_environment = false;
32906 DEFVAR_LISP ("max-mini-window-height", Vmax_mini_window_height,
32907 doc: /* Maximum height for resizing mini-windows (the minibuffer and the echo area).
32908 If a float, it specifies a fraction of the mini-window frame's height.
32909 If an integer, it specifies a number of lines. */);
32910 Vmax_mini_window_height = make_float (0.25);
32912 DEFVAR_LISP ("resize-mini-windows", Vresize_mini_windows,
32913 doc: /* How to resize mini-windows (the minibuffer and the echo area).
32914 A value of nil means don't automatically resize mini-windows.
32915 A value of t means resize them to fit the text displayed in them.
32916 A value of `grow-only', the default, means let mini-windows grow only;
32917 they return to their normal size when the minibuffer is closed, or the
32918 echo area becomes empty. */);
32919 /* Contrary to the doc string, we initialize this to nil, so that
32920 loading loadup.el won't try to resize windows before loading
32921 window.el, where some functions we need to call for this live.
32922 We assign the 'grow-only' value right after loading window.el
32923 during loadup. */
32924 Vresize_mini_windows = Qnil;
32926 DEFVAR_LISP ("blink-cursor-alist", Vblink_cursor_alist,
32927 doc: /* Alist specifying how to blink the cursor off.
32928 Each element has the form (ON-STATE . OFF-STATE). Whenever the
32929 `cursor-type' frame-parameter or variable equals ON-STATE,
32930 comparing using `equal', Emacs uses OFF-STATE to specify
32931 how to blink it off. ON-STATE and OFF-STATE are values for
32932 the `cursor-type' frame parameter.
32934 If a frame's ON-STATE has no entry in this list,
32935 the frame's other specifications determine how to blink the cursor off. */);
32936 Vblink_cursor_alist = Qnil;
32938 DEFVAR_LISP ("auto-hscroll-mode", automatic_hscrolling,
32939 doc: /* Allow or disallow automatic horizontal scrolling of windows.
32940 The value `current-line' means the line displaying point in each window
32941 is automatically scrolled horizontally to make point visible.
32942 Any other non-nil value means all the lines in a window are automatically
32943 scrolled horizontally to make point visible. */);
32944 automatic_hscrolling = Qt;
32945 DEFSYM (Qauto_hscroll_mode, "auto-hscroll-mode");
32946 DEFSYM (Qcurrent_line, "current-line");
32948 DEFVAR_INT ("hscroll-margin", hscroll_margin,
32949 doc: /* How many columns away from the window edge point is allowed to get
32950 before automatic hscrolling will horizontally scroll the window. */);
32951 hscroll_margin = 5;
32953 DEFVAR_LISP ("hscroll-step", Vhscroll_step,
32954 doc: /* How many columns to scroll the window when point gets too close to the edge.
32955 When point is less than `hscroll-margin' columns from the window
32956 edge, automatic hscrolling will scroll the window by the amount of columns
32957 determined by this variable. If its value is a positive integer, scroll that
32958 many columns. If it's a positive floating-point number, it specifies the
32959 fraction of the window's width to scroll. If it's nil or zero, point will be
32960 centered horizontally after the scroll. Any other value, including negative
32961 numbers, are treated as if the value were zero.
32963 Automatic hscrolling always moves point outside the scroll margin, so if
32964 point was more than scroll step columns inside the margin, the window will
32965 scroll more than the value given by the scroll step.
32967 Note that the lower bound for automatic hscrolling specified by `scroll-left'
32968 and `scroll-right' overrides this variable's effect. */);
32969 Vhscroll_step = make_number (0);
32971 DEFVAR_BOOL ("message-truncate-lines", message_truncate_lines,
32972 doc: /* If non-nil, messages are truncated instead of resizing the echo area.
32973 Bind this around calls to `message' to let it take effect. */);
32974 message_truncate_lines = false;
32976 DEFVAR_LISP ("menu-bar-update-hook", Vmenu_bar_update_hook,
32977 doc: /* Normal hook run to update the menu bar definitions.
32978 Redisplay runs this hook before it redisplays the menu bar.
32979 This is used to update menus such as Buffers, whose contents depend on
32980 various data. */);
32981 Vmenu_bar_update_hook = Qnil;
32983 DEFVAR_LISP ("menu-updating-frame", Vmenu_updating_frame,
32984 doc: /* Frame for which we are updating a menu.
32985 The enable predicate for a menu binding should check this variable. */);
32986 Vmenu_updating_frame = Qnil;
32988 DEFVAR_BOOL ("inhibit-menubar-update", inhibit_menubar_update,
32989 doc: /* Non-nil means don't update menu bars. Internal use only. */);
32990 inhibit_menubar_update = false;
32992 DEFVAR_LISP ("wrap-prefix", Vwrap_prefix,
32993 doc: /* Prefix prepended to all continuation lines at display time.
32994 The value may be a string, an image, or a stretch-glyph; it is
32995 interpreted in the same way as the value of a `display' text property.
32997 This variable is overridden by any `wrap-prefix' text or overlay
32998 property.
33000 To add a prefix to non-continuation lines, use `line-prefix'. */);
33001 Vwrap_prefix = Qnil;
33002 DEFSYM (Qwrap_prefix, "wrap-prefix");
33003 Fmake_variable_buffer_local (Qwrap_prefix);
33005 DEFVAR_LISP ("line-prefix", Vline_prefix,
33006 doc: /* Prefix prepended to all non-continuation lines at display time.
33007 The value may be a string, an image, or a stretch-glyph; it is
33008 interpreted in the same way as the value of a `display' text property.
33010 This variable is overridden by any `line-prefix' text or overlay
33011 property.
33013 To add a prefix to continuation lines, use `wrap-prefix'. */);
33014 Vline_prefix = Qnil;
33015 DEFSYM (Qline_prefix, "line-prefix");
33016 Fmake_variable_buffer_local (Qline_prefix);
33018 DEFVAR_LISP ("display-line-numbers", Vdisplay_line_numbers,
33019 doc: /* Non-nil means display line numbers.
33020 If the value is t, display the absolute number of each line of a buffer
33021 shown in a window. Absolute line numbers count from the beginning of
33022 the current narrowing, or from buffer beginning. If the value is
33023 `relative', display for each line not containing the window's point its
33024 relative number instead, i.e. the number of the line relative to the
33025 line showing the window's point.
33027 In either case, line numbers are displayed at the beginning of each
33028 non-continuation line that displays buffer text, i.e. after each newline
33029 character that comes from the buffer. The value `visual' is like
33030 `relative' but counts screen lines instead of buffer lines. In practice
33031 this means that continuation lines count as well when calculating the
33032 relative number of a line.
33034 Lisp programs can disable display of a line number of a particular
33035 buffer line by putting the `display-line-numbers-disable' text property
33036 or overlay property on the first visible character of that line. */);
33037 Vdisplay_line_numbers = Qnil;
33038 DEFSYM (Qdisplay_line_numbers, "display-line-numbers");
33039 Fmake_variable_buffer_local (Qdisplay_line_numbers);
33040 DEFSYM (Qrelative, "relative");
33041 DEFSYM (Qvisual, "visual");
33043 DEFVAR_LISP ("display-line-numbers-width", Vdisplay_line_numbers_width,
33044 doc: /* Minimum width of space reserved for line number display.
33045 A positive number means reserve that many columns for line numbers,
33046 even if the actual number needs less space.
33047 The default value of nil means compute the space dynamically.
33048 Any other value is treated as nil. */);
33049 Vdisplay_line_numbers_width = Qnil;
33050 DEFSYM (Qdisplay_line_numbers_width, "display-line-numbers-width");
33051 Fmake_variable_buffer_local (Qdisplay_line_numbers_width);
33053 DEFVAR_LISP ("display-line-numbers-current-absolute",
33054 Vdisplay_line_numbers_current_absolute,
33055 doc: /* Non-nil means display absolute number of current line.
33056 This variable has effect only when `display-line-numbers' is
33057 either `relative' or `visual'. */);
33058 Vdisplay_line_numbers_current_absolute = Qt;
33060 DEFVAR_BOOL ("display-line-numbers-widen", display_line_numbers_widen,
33061 doc: /* Non-nil means display line numbers disregarding any narrowing. */);
33062 display_line_numbers_widen = false;
33063 DEFSYM (Qdisplay_line_numbers_widen, "display-line-numbers-widen");
33064 Fmake_variable_buffer_local (Qdisplay_line_numbers_widen);
33066 DEFVAR_BOOL ("inhibit-eval-during-redisplay", inhibit_eval_during_redisplay,
33067 doc: /* Non-nil means don't eval Lisp during redisplay. */);
33068 inhibit_eval_during_redisplay = false;
33070 DEFVAR_BOOL ("inhibit-free-realized-faces", inhibit_free_realized_faces,
33071 doc: /* Non-nil means don't free realized faces. Internal use only. */);
33072 inhibit_free_realized_faces = false;
33074 DEFVAR_BOOL ("inhibit-bidi-mirroring", inhibit_bidi_mirroring,
33075 doc: /* Non-nil means don't mirror characters even when bidi context requires that.
33076 Intended for use during debugging and for testing bidi display;
33077 see biditest.el in the test suite. */);
33078 inhibit_bidi_mirroring = false;
33080 #ifdef GLYPH_DEBUG
33081 DEFVAR_BOOL ("inhibit-try-window-id", inhibit_try_window_id,
33082 doc: /* Inhibit try_window_id display optimization. */);
33083 inhibit_try_window_id = false;
33085 DEFVAR_BOOL ("inhibit-try-window-reusing", inhibit_try_window_reusing,
33086 doc: /* Inhibit try_window_reusing display optimization. */);
33087 inhibit_try_window_reusing = false;
33089 DEFVAR_BOOL ("inhibit-try-cursor-movement", inhibit_try_cursor_movement,
33090 doc: /* Inhibit try_cursor_movement display optimization. */);
33091 inhibit_try_cursor_movement = false;
33092 #endif /* GLYPH_DEBUG */
33094 DEFVAR_INT ("overline-margin", overline_margin,
33095 doc: /* Space between overline and text, in pixels.
33096 The default value is 2: the height of the overline (1 pixel) plus 1 pixel
33097 margin to the character height. */);
33098 overline_margin = 2;
33100 DEFVAR_INT ("underline-minimum-offset",
33101 underline_minimum_offset,
33102 doc: /* Minimum distance between baseline and underline.
33103 This can improve legibility of underlined text at small font sizes,
33104 particularly when using variable `x-use-underline-position-properties'
33105 with fonts that specify an UNDERLINE_POSITION relatively close to the
33106 baseline. The default value is 1. */);
33107 underline_minimum_offset = 1;
33108 DEFSYM (Qunderline_minimum_offset, "underline-minimum-offset");
33110 DEFVAR_BOOL ("display-hourglass", display_hourglass_p,
33111 doc: /* Non-nil means show an hourglass pointer, when Emacs is busy.
33112 This feature only works when on a window system that can change
33113 cursor shapes. */);
33114 display_hourglass_p = true;
33116 DEFVAR_LISP ("hourglass-delay", Vhourglass_delay,
33117 doc: /* Seconds to wait before displaying an hourglass pointer when Emacs is busy. */);
33118 Vhourglass_delay = make_number (DEFAULT_HOURGLASS_DELAY);
33120 #ifdef HAVE_WINDOW_SYSTEM
33121 hourglass_atimer = NULL;
33122 hourglass_shown_p = false;
33123 #endif /* HAVE_WINDOW_SYSTEM */
33125 /* Name of the face used to display glyphless characters. */
33126 DEFSYM (Qglyphless_char, "glyphless-char");
33128 /* Method symbols for Vglyphless_char_display. */
33129 DEFSYM (Qhex_code, "hex-code");
33130 DEFSYM (Qempty_box, "empty-box");
33131 DEFSYM (Qthin_space, "thin-space");
33132 DEFSYM (Qzero_width, "zero-width");
33134 DEFVAR_LISP ("pre-redisplay-function", Vpre_redisplay_function,
33135 doc: /* Function run just before redisplay.
33136 It is called with one argument, which is the set of windows that are to
33137 be redisplayed. This set can be nil (meaning, only the selected window),
33138 or t (meaning all windows). */);
33139 Vpre_redisplay_function = intern ("ignore");
33141 /* Symbol for the purpose of Vglyphless_char_display. */
33142 DEFSYM (Qglyphless_char_display, "glyphless-char-display");
33143 Fput (Qglyphless_char_display, Qchar_table_extra_slots, make_number (1));
33145 DEFVAR_LISP ("glyphless-char-display", Vglyphless_char_display,
33146 doc: /* Char-table defining glyphless characters.
33147 Each element, if non-nil, should be one of the following:
33148 an ASCII acronym string: display this string in a box
33149 `hex-code': display the hexadecimal code of a character in a box
33150 `empty-box': display as an empty box
33151 `thin-space': display as 1-pixel width space
33152 `zero-width': don't display
33153 An element may also be a cons cell (GRAPHICAL . TEXT), which specifies the
33154 display method for graphical terminals and text terminals respectively.
33155 GRAPHICAL and TEXT should each have one of the values listed above.
33157 The char-table has one extra slot to control the display of a character for
33158 which no font is found. This slot only takes effect on graphical terminals.
33159 Its value should be an ASCII acronym string, `hex-code', `empty-box', or
33160 `thin-space'. The default is `empty-box'.
33162 If a character has a non-nil entry in an active display table, the
33163 display table takes effect; in this case, Emacs does not consult
33164 `glyphless-char-display' at all. */);
33165 Vglyphless_char_display = Fmake_char_table (Qglyphless_char_display, Qnil);
33166 Fset_char_table_extra_slot (Vglyphless_char_display, make_number (0),
33167 Qempty_box);
33169 DEFVAR_LISP ("debug-on-message", Vdebug_on_message,
33170 doc: /* If non-nil, debug if a message matching this regexp is displayed. */);
33171 Vdebug_on_message = Qnil;
33173 DEFVAR_LISP ("redisplay--all-windows-cause", Vredisplay__all_windows_cause,
33174 doc: /* */);
33175 Vredisplay__all_windows_cause = Fmake_hash_table (0, NULL);
33177 DEFVAR_LISP ("redisplay--mode-lines-cause", Vredisplay__mode_lines_cause,
33178 doc: /* */);
33179 Vredisplay__mode_lines_cause = Fmake_hash_table (0, NULL);
33181 DEFVAR_BOOL ("redisplay--inhibit-bidi", redisplay__inhibit_bidi,
33182 doc: /* Non-nil means it is not safe to attempt bidi reordering for display. */);
33183 /* Initialize to t, since we need to disable reordering until
33184 loadup.el successfully loads charprop.el. */
33185 redisplay__inhibit_bidi = true;
33187 DEFVAR_BOOL ("display-raw-bytes-as-hex", display_raw_bytes_as_hex,
33188 doc: /* Non-nil means display raw bytes in hexadecimal format.
33189 The default is to use octal format (\200) whereas hexadecimal (\x80)
33190 may be more familiar to users. */);
33191 display_raw_bytes_as_hex = false;
33196 /* Initialize this module when Emacs starts. */
33198 void
33199 init_xdisp (void)
33201 CHARPOS (this_line_start_pos) = 0;
33203 if (!noninteractive)
33205 struct window *m = XWINDOW (minibuf_window);
33206 Lisp_Object frame = m->frame;
33207 struct frame *f = XFRAME (frame);
33208 Lisp_Object root = FRAME_ROOT_WINDOW (f);
33209 struct window *r = XWINDOW (root);
33210 int i;
33212 echo_area_window = minibuf_window;
33214 r->top_line = FRAME_TOP_MARGIN (f);
33215 r->pixel_top = r->top_line * FRAME_LINE_HEIGHT (f);
33216 r->total_cols = FRAME_COLS (f);
33217 r->pixel_width = r->total_cols * FRAME_COLUMN_WIDTH (f);
33218 r->total_lines = FRAME_TOTAL_LINES (f) - 1 - FRAME_TOP_MARGIN (f);
33219 r->pixel_height = r->total_lines * FRAME_LINE_HEIGHT (f);
33221 m->top_line = FRAME_TOTAL_LINES (f) - 1;
33222 m->pixel_top = m->top_line * FRAME_LINE_HEIGHT (f);
33223 m->total_cols = FRAME_COLS (f);
33224 m->pixel_width = m->total_cols * FRAME_COLUMN_WIDTH (f);
33225 m->total_lines = 1;
33226 m->pixel_height = m->total_lines * FRAME_LINE_HEIGHT (f);
33228 scratch_glyph_row.glyphs[TEXT_AREA] = scratch_glyphs;
33229 scratch_glyph_row.glyphs[TEXT_AREA + 1]
33230 = scratch_glyphs + MAX_SCRATCH_GLYPHS;
33232 /* The default ellipsis glyphs `...'. */
33233 for (i = 0; i < 3; ++i)
33234 default_invis_vector[i] = make_number ('.');
33238 /* Allocate the buffer for frame titles.
33239 Also used for `format-mode-line'. */
33240 int size = 100;
33241 mode_line_noprop_buf = xmalloc (size);
33242 mode_line_noprop_buf_end = mode_line_noprop_buf + size;
33243 mode_line_noprop_ptr = mode_line_noprop_buf;
33244 mode_line_target = MODE_LINE_DISPLAY;
33247 help_echo_showing_p = false;
33250 #ifdef HAVE_WINDOW_SYSTEM
33252 /* Platform-independent portion of hourglass implementation. */
33254 /* Timer function of hourglass_atimer. */
33256 static void
33257 show_hourglass (struct atimer *timer)
33259 /* The timer implementation will cancel this timer automatically
33260 after this function has run. Set hourglass_atimer to null
33261 so that we know the timer doesn't have to be canceled. */
33262 hourglass_atimer = NULL;
33264 if (!hourglass_shown_p)
33266 Lisp_Object tail, frame;
33268 block_input ();
33270 FOR_EACH_FRAME (tail, frame)
33272 struct frame *f = XFRAME (frame);
33274 if (FRAME_LIVE_P (f) && FRAME_WINDOW_P (f)
33275 && FRAME_RIF (f)->show_hourglass)
33276 FRAME_RIF (f)->show_hourglass (f);
33279 hourglass_shown_p = true;
33280 unblock_input ();
33284 /* Cancel a currently active hourglass timer, and start a new one. */
33286 void
33287 start_hourglass (void)
33289 struct timespec delay;
33291 cancel_hourglass ();
33293 if (INTEGERP (Vhourglass_delay)
33294 && XINT (Vhourglass_delay) > 0)
33295 delay = make_timespec (min (XINT (Vhourglass_delay),
33296 TYPE_MAXIMUM (time_t)),
33298 else if (FLOATP (Vhourglass_delay)
33299 && XFLOAT_DATA (Vhourglass_delay) > 0)
33300 delay = dtotimespec (XFLOAT_DATA (Vhourglass_delay));
33301 else
33302 delay = make_timespec (DEFAULT_HOURGLASS_DELAY, 0);
33304 hourglass_atimer = start_atimer (ATIMER_RELATIVE, delay,
33305 show_hourglass, NULL);
33308 /* Cancel the hourglass cursor timer if active, hide a busy cursor if
33309 shown. */
33311 void
33312 cancel_hourglass (void)
33314 if (hourglass_atimer)
33316 cancel_atimer (hourglass_atimer);
33317 hourglass_atimer = NULL;
33320 if (hourglass_shown_p)
33322 Lisp_Object tail, frame;
33324 block_input ();
33326 FOR_EACH_FRAME (tail, frame)
33328 struct frame *f = XFRAME (frame);
33330 if (FRAME_LIVE_P (f) && FRAME_WINDOW_P (f)
33331 && FRAME_RIF (f)->hide_hourglass)
33332 FRAME_RIF (f)->hide_hourglass (f);
33333 #ifdef HAVE_NTGUI
33334 /* No cursors on non GUI frames - restore to stock arrow cursor. */
33335 else if (!FRAME_W32_P (f))
33336 w32_arrow_cursor ();
33337 #endif
33340 hourglass_shown_p = false;
33341 unblock_input ();
33345 #endif /* HAVE_WINDOW_SYSTEM */