Allow 'browse-url-emacs' to fetch URL in the selected window
[emacs.git] / src / xdisp.c
bloba97d4db60705d9a51a9fbfa4c62a74c5b7e12964
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 ())
13921 return;
13922 #endif
13924 /* I don't think this happens but let's be paranoid. */
13925 if (redisplaying_p)
13926 return;
13928 /* Record a function that clears redisplaying_p
13929 when we leave this function. */
13930 count = SPECPDL_INDEX ();
13931 record_unwind_protect_void (unwind_redisplay);
13932 redisplaying_p = true;
13933 block_buffer_flips ();
13934 specbind (Qinhibit_free_realized_faces, Qnil);
13936 /* Record this function, so it appears on the profiler's backtraces. */
13937 record_in_backtrace (Qredisplay_internal_xC_functionx, 0, 0);
13939 FOR_EACH_FRAME (tail, frame)
13940 XFRAME (frame)->already_hscrolled_p = false;
13942 retry:
13943 /* Remember the currently selected window. */
13944 sw = w;
13946 pending = false;
13947 forget_escape_and_glyphless_faces ();
13949 inhibit_free_realized_faces = false;
13951 /* If face_change, init_iterator will free all realized faces, which
13952 includes the faces referenced from current matrices. So, we
13953 can't reuse current matrices in this case. */
13954 if (face_change)
13955 windows_or_buffers_changed = 47;
13957 if ((FRAME_TERMCAP_P (sf) || FRAME_MSDOS_P (sf))
13958 && FRAME_TTY (sf)->previous_frame != sf)
13960 /* Since frames on a single ASCII terminal share the same
13961 display area, displaying a different frame means redisplay
13962 the whole thing. */
13963 SET_FRAME_GARBAGED (sf);
13964 #ifndef DOS_NT
13965 set_tty_color_mode (FRAME_TTY (sf), sf);
13966 #endif
13967 FRAME_TTY (sf)->previous_frame = sf;
13970 /* Set the visible flags for all frames. Do this before checking for
13971 resized or garbaged frames; they want to know if their frames are
13972 visible. See the comment in frame.h for FRAME_SAMPLE_VISIBILITY. */
13973 number_of_visible_frames = 0;
13975 FOR_EACH_FRAME (tail, frame)
13977 struct frame *f = XFRAME (frame);
13979 if (FRAME_VISIBLE_P (f))
13981 ++number_of_visible_frames;
13982 /* Adjust matrices for visible frames only. */
13983 if (f->fonts_changed)
13985 adjust_frame_glyphs (f);
13986 /* Disable all redisplay optimizations for this frame.
13987 This is because adjust_frame_glyphs resets the
13988 enabled_p flag for all glyph rows of all windows, so
13989 many optimizations will fail anyway, and some might
13990 fail to test that flag and do bogus things as
13991 result. */
13992 SET_FRAME_GARBAGED (f);
13993 f->fonts_changed = false;
13995 /* If cursor type has been changed on the frame
13996 other than selected, consider all frames. */
13997 if (f != sf && f->cursor_type_changed)
13998 fset_redisplay (f);
14000 clear_desired_matrices (f);
14003 /* Notice any pending interrupt request to change frame size. */
14004 do_pending_window_change (true);
14006 /* do_pending_window_change could change the selected_window due to
14007 frame resizing which makes the selected window too small. */
14008 if (WINDOWP (selected_window) && (w = XWINDOW (selected_window)) != sw)
14009 sw = w;
14011 /* Clear frames marked as garbaged. */
14012 clear_garbaged_frames ();
14014 /* Build menubar and tool-bar items. */
14015 if (NILP (Vmemory_full))
14016 prepare_menu_bars ();
14018 reconsider_clip_changes (w);
14020 /* In most cases selected window displays current buffer. */
14021 match_p = XBUFFER (w->contents) == current_buffer;
14022 if (match_p)
14024 /* Detect case that we need to write or remove a star in the mode line. */
14025 if ((SAVE_MODIFF < MODIFF) != w->last_had_star)
14026 w->update_mode_line = true;
14028 if (mode_line_update_needed (w))
14029 w->update_mode_line = true;
14031 /* If reconsider_clip_changes above decided that the narrowing
14032 in the current buffer changed, make sure all other windows
14033 showing that buffer will be redisplayed. */
14034 if (current_buffer->clip_changed)
14035 bset_update_mode_line (current_buffer);
14038 /* Normally the message* functions will have already displayed and
14039 updated the echo area, but the frame may have been trashed, or
14040 the update may have been preempted, so display the echo area
14041 again here. Checking message_cleared_p captures the case that
14042 the echo area should be cleared. */
14043 if ((!NILP (echo_area_buffer[0]) && !display_last_displayed_message_p)
14044 || (!NILP (echo_area_buffer[1]) && display_last_displayed_message_p)
14045 || (message_cleared_p
14046 && minibuf_level == 0
14047 /* If the mini-window is currently selected, this means the
14048 echo-area doesn't show through. */
14049 && !MINI_WINDOW_P (XWINDOW (selected_window))))
14051 echo_area_display (false);
14053 /* If echo_area_display resizes the mini-window, the redisplay and
14054 window_sizes_changed flags of the selected frame are set, but
14055 it's too late for the hooks in window-size-change-functions,
14056 which have been examined already in prepare_menu_bars. So in
14057 that case we call the hooks here only for the selected frame. */
14058 if (sf->redisplay)
14060 ptrdiff_t count1 = SPECPDL_INDEX ();
14062 record_unwind_save_match_data ();
14063 run_window_size_change_functions (selected_frame);
14064 unbind_to (count1, Qnil);
14067 if (message_cleared_p)
14068 update_miniwindow_p = true;
14070 must_finish = true;
14072 /* If we don't display the current message, don't clear the
14073 message_cleared_p flag, because, if we did, we wouldn't clear
14074 the echo area in the next redisplay which doesn't preserve
14075 the echo area. */
14076 if (!display_last_displayed_message_p)
14077 message_cleared_p = false;
14079 else if (EQ (selected_window, minibuf_window)
14080 && (current_buffer->clip_changed || window_outdated (w))
14081 && resize_mini_window (w, false))
14083 if (sf->redisplay)
14085 ptrdiff_t count1 = SPECPDL_INDEX ();
14087 record_unwind_save_match_data ();
14088 run_window_size_change_functions (selected_frame);
14089 unbind_to (count1, Qnil);
14092 /* Resized active mini-window to fit the size of what it is
14093 showing if its contents might have changed. */
14094 must_finish = true;
14096 /* If window configuration was changed, frames may have been
14097 marked garbaged. Clear them or we will experience
14098 surprises wrt scrolling. */
14099 clear_garbaged_frames ();
14102 if (windows_or_buffers_changed && !update_mode_lines)
14103 /* Code that sets windows_or_buffers_changed doesn't distinguish whether
14104 only the windows's contents needs to be refreshed, or whether the
14105 mode-lines also need a refresh. */
14106 update_mode_lines = (windows_or_buffers_changed == REDISPLAY_SOME
14107 ? REDISPLAY_SOME : 32);
14109 /* If specs for an arrow have changed, do thorough redisplay
14110 to ensure we remove any arrow that should no longer exist. */
14111 /* Apparently, this is the only case where we update other windows,
14112 without updating other mode-lines. */
14113 overlay_arrows_changed_p (true);
14115 consider_all_windows_p = (update_mode_lines
14116 || windows_or_buffers_changed);
14118 #define AINC(a,i) \
14120 Lisp_Object entry = Fgethash (make_number (i), a, make_number (0)); \
14121 if (INTEGERP (entry)) \
14122 Fputhash (make_number (i), make_number (1 + XINT (entry)), a); \
14125 AINC (Vredisplay__all_windows_cause, windows_or_buffers_changed);
14126 AINC (Vredisplay__mode_lines_cause, update_mode_lines);
14128 /* Optimize the case that only the line containing the cursor in the
14129 selected window has changed. Variables starting with this_ are
14130 set in display_line and record information about the line
14131 containing the cursor. */
14132 tlbufpos = this_line_start_pos;
14133 tlendpos = this_line_end_pos;
14134 if (!consider_all_windows_p
14135 && CHARPOS (tlbufpos) > 0
14136 && !w->update_mode_line
14137 && !current_buffer->clip_changed
14138 && !current_buffer->prevent_redisplay_optimizations_p
14139 && FRAME_VISIBLE_P (XFRAME (w->frame))
14140 && !FRAME_OBSCURED_P (XFRAME (w->frame))
14141 && !XFRAME (w->frame)->cursor_type_changed
14142 && !XFRAME (w->frame)->face_change
14143 /* Make sure recorded data applies to current buffer, etc. */
14144 && this_line_buffer == current_buffer
14145 && match_p
14146 && !w->force_start
14147 && !w->optional_new_start
14148 /* Point must be on the line that we have info recorded about. */
14149 && PT >= CHARPOS (tlbufpos)
14150 && PT <= Z - CHARPOS (tlendpos)
14151 /* All text outside that line, including its final newline,
14152 must be unchanged. */
14153 && text_outside_line_unchanged_p (w, CHARPOS (tlbufpos),
14154 CHARPOS (tlendpos)))
14156 if (CHARPOS (tlbufpos) > BEGV
14157 && FETCH_BYTE (BYTEPOS (tlbufpos) - 1) != '\n'
14158 && (CHARPOS (tlbufpos) == ZV
14159 || FETCH_BYTE (BYTEPOS (tlbufpos)) == '\n'))
14160 /* Former continuation line has disappeared by becoming empty. */
14161 goto cancel;
14162 else if (window_outdated (w) || MINI_WINDOW_P (w))
14164 /* We have to handle the case of continuation around a
14165 wide-column character (see the comment in indent.c around
14166 line 1340).
14168 For instance, in the following case:
14170 -------- Insert --------
14171 K_A_N_\\ `a' K_A_N_a\ `X_' are wide-column chars.
14172 J_I_ ==> J_I_ `^^' are cursors.
14173 ^^ ^^
14174 -------- --------
14176 As we have to redraw the line above, we cannot use this
14177 optimization. */
14179 struct it it;
14180 int line_height_before = this_line_pixel_height;
14182 /* Note that start_display will handle the case that the
14183 line starting at tlbufpos is a continuation line. */
14184 start_display (&it, w, tlbufpos);
14186 /* Implementation note: It this still necessary? */
14187 if (it.current_x != this_line_start_x)
14188 goto cancel;
14190 TRACE ((stderr, "trying display optimization 1\n"));
14191 w->cursor.vpos = -1;
14192 overlay_arrow_seen = false;
14193 it.vpos = this_line_vpos;
14194 it.current_y = this_line_y;
14195 it.glyph_row = MATRIX_ROW (w->desired_matrix, this_line_vpos);
14196 display_line (&it, -1);
14198 /* If line contains point, is not continued,
14199 and ends at same distance from eob as before, we win. */
14200 if (w->cursor.vpos >= 0
14201 /* Line is not continued, otherwise this_line_start_pos
14202 would have been set to 0 in display_line. */
14203 && CHARPOS (this_line_start_pos)
14204 /* Line ends as before. */
14205 && CHARPOS (this_line_end_pos) == CHARPOS (tlendpos)
14206 /* Line has same height as before. Otherwise other lines
14207 would have to be shifted up or down. */
14208 && this_line_pixel_height == line_height_before)
14210 /* If this is not the window's last line, we must adjust
14211 the charstarts of the lines below. */
14212 if (it.current_y < it.last_visible_y)
14214 struct glyph_row *row
14215 = MATRIX_ROW (w->current_matrix, this_line_vpos + 1);
14216 ptrdiff_t delta, delta_bytes;
14218 /* We used to distinguish between two cases here,
14219 conditioned by Z - CHARPOS (tlendpos) == ZV, for
14220 when the line ends in a newline or the end of the
14221 buffer's accessible portion. But both cases did
14222 the same, so they were collapsed. */
14223 delta = (Z
14224 - CHARPOS (tlendpos)
14225 - MATRIX_ROW_START_CHARPOS (row));
14226 delta_bytes = (Z_BYTE
14227 - BYTEPOS (tlendpos)
14228 - MATRIX_ROW_START_BYTEPOS (row));
14230 increment_matrix_positions (w->current_matrix,
14231 this_line_vpos + 1,
14232 w->current_matrix->nrows,
14233 delta, delta_bytes);
14236 /* If this row displays text now but previously didn't,
14237 or vice versa, w->window_end_vpos may have to be
14238 adjusted. */
14239 if (MATRIX_ROW_DISPLAYS_TEXT_P (it.glyph_row - 1))
14241 if (w->window_end_vpos < this_line_vpos)
14242 w->window_end_vpos = this_line_vpos;
14244 else if (w->window_end_vpos == this_line_vpos
14245 && this_line_vpos > 0)
14246 w->window_end_vpos = this_line_vpos - 1;
14247 w->window_end_valid = false;
14249 /* Update hint: No need to try to scroll in update_window. */
14250 w->desired_matrix->no_scrolling_p = true;
14252 #ifdef GLYPH_DEBUG
14253 *w->desired_matrix->method = 0;
14254 debug_method_add (w, "optimization 1");
14255 #endif
14256 #ifdef HAVE_WINDOW_SYSTEM
14257 update_window_fringes (w, false);
14258 #endif
14259 goto update;
14261 else
14262 goto cancel;
14264 else if (/* Cursor position hasn't changed. */
14265 PT == w->last_point
14266 /* Make sure the cursor was last displayed
14267 in this window. Otherwise we have to reposition it. */
14269 /* PXW: Must be converted to pixels, probably. */
14270 && 0 <= w->cursor.vpos
14271 && w->cursor.vpos < WINDOW_TOTAL_LINES (w))
14273 if (!must_finish)
14275 do_pending_window_change (true);
14276 /* If selected_window changed, redisplay again. */
14277 if (WINDOWP (selected_window)
14278 && (w = XWINDOW (selected_window)) != sw)
14279 goto retry;
14281 /* We used to always goto end_of_redisplay here, but this
14282 isn't enough if we have a blinking cursor. */
14283 if (w->cursor_off_p == w->last_cursor_off_p)
14284 goto end_of_redisplay;
14286 goto update;
14288 /* If highlighting the region, or if the cursor is in the echo area,
14289 then we can't just move the cursor. */
14290 else if (NILP (Vshow_trailing_whitespace)
14291 && !cursor_in_echo_area)
14293 struct it it;
14294 struct glyph_row *row;
14296 /* Skip from tlbufpos to PT and see where it is. Note that
14297 PT may be in invisible text. If so, we will end at the
14298 next visible position. */
14299 init_iterator (&it, w, CHARPOS (tlbufpos), BYTEPOS (tlbufpos),
14300 NULL, DEFAULT_FACE_ID);
14301 it.current_x = this_line_start_x;
14302 it.current_y = this_line_y;
14303 it.vpos = this_line_vpos;
14305 /* The call to move_it_to stops in front of PT, but
14306 moves over before-strings. */
14307 move_it_to (&it, PT, -1, -1, -1, MOVE_TO_POS);
14309 if (it.vpos == this_line_vpos
14310 && (row = MATRIX_ROW (w->current_matrix, this_line_vpos),
14311 row->enabled_p))
14313 eassert (this_line_vpos == it.vpos);
14314 eassert (this_line_y == it.current_y);
14315 set_cursor_from_row (w, row, w->current_matrix, 0, 0, 0, 0);
14316 if (cursor_row_fully_visible_p (w, false, true))
14318 #ifdef GLYPH_DEBUG
14319 *w->desired_matrix->method = 0;
14320 debug_method_add (w, "optimization 3");
14321 #endif
14322 goto update;
14324 else
14325 goto cancel;
14327 else
14328 goto cancel;
14331 cancel:
14332 /* Text changed drastically or point moved off of line. */
14333 SET_MATRIX_ROW_ENABLED_P (w->desired_matrix, this_line_vpos, false);
14336 CHARPOS (this_line_start_pos) = 0;
14337 ++clear_face_cache_count;
14338 #ifdef HAVE_WINDOW_SYSTEM
14339 ++clear_image_cache_count;
14340 #endif
14342 /* Build desired matrices, and update the display. If
14343 consider_all_windows_p, do it for all windows on all frames that
14344 require redisplay, as specified by their 'redisplay' flag.
14345 Otherwise do it for selected_window, only. */
14347 if (consider_all_windows_p)
14349 FOR_EACH_FRAME (tail, frame)
14350 XFRAME (frame)->updated_p = false;
14352 propagate_buffer_redisplay ();
14354 FOR_EACH_FRAME (tail, frame)
14356 struct frame *f = XFRAME (frame);
14358 /* We don't have to do anything for unselected terminal
14359 frames. */
14360 if ((FRAME_TERMCAP_P (f) || FRAME_MSDOS_P (f))
14361 && !EQ (FRAME_TTY (f)->top_frame, frame))
14362 continue;
14364 retry_frame:
14365 if (FRAME_WINDOW_P (f) || FRAME_TERMCAP_P (f) || f == sf)
14367 bool gcscrollbars
14368 /* Only GC scrollbars when we redisplay the whole frame. */
14369 = f->redisplay || !REDISPLAY_SOME_P ();
14370 bool f_redisplay_flag = f->redisplay;
14371 /* Mark all the scroll bars to be removed; we'll redeem
14372 the ones we want when we redisplay their windows. */
14373 if (gcscrollbars && FRAME_TERMINAL (f)->condemn_scroll_bars_hook)
14374 FRAME_TERMINAL (f)->condemn_scroll_bars_hook (f);
14376 if (FRAME_VISIBLE_P (f) && !FRAME_OBSCURED_P (f))
14377 redisplay_windows (FRAME_ROOT_WINDOW (f));
14378 /* Remember that the invisible frames need to be redisplayed next
14379 time they're visible. */
14380 else if (!REDISPLAY_SOME_P ())
14381 f->redisplay = true;
14383 /* The X error handler may have deleted that frame. */
14384 if (!FRAME_LIVE_P (f))
14385 continue;
14387 /* Any scroll bars which redisplay_windows should have
14388 nuked should now go away. */
14389 if (gcscrollbars && FRAME_TERMINAL (f)->judge_scroll_bars_hook)
14390 FRAME_TERMINAL (f)->judge_scroll_bars_hook (f);
14392 if (FRAME_VISIBLE_P (f) && !FRAME_OBSCURED_P (f))
14394 /* If fonts changed on visible frame, display again. */
14395 if (f->fonts_changed)
14397 adjust_frame_glyphs (f);
14398 /* Disable all redisplay optimizations for this
14399 frame. For the reasons, see the comment near
14400 the previous call to adjust_frame_glyphs above. */
14401 SET_FRAME_GARBAGED (f);
14402 f->fonts_changed = false;
14403 goto retry_frame;
14406 /* See if we have to hscroll. */
14407 if (!f->already_hscrolled_p)
14409 f->already_hscrolled_p = true;
14410 if (hscroll_retries <= MAX_HSCROLL_RETRIES
14411 && hscroll_windows (f->root_window))
14413 hscroll_retries++;
14414 goto retry_frame;
14418 /* If the frame's redisplay flag was not set before
14419 we went about redisplaying its windows, but it is
14420 set now, that means we employed some redisplay
14421 optimizations inside redisplay_windows, and
14422 bypassed producing some screen lines. But if
14423 f->redisplay is now set, it might mean the old
14424 faces are no longer valid (e.g., if redisplaying
14425 some window called some Lisp which defined a new
14426 face or redefined an existing face), so trying to
14427 use them in update_frame will segfault.
14428 Therefore, we must redisplay this frame. */
14429 if (!f_redisplay_flag && f->redisplay)
14430 goto retry_frame;
14431 /* In some case (e.g., window resize), we notice
14432 only during window updating that the window
14433 content changed unpredictably (e.g., a GTK
14434 scrollbar moved, or some Lisp hook that winds up
14435 calling adjust_frame_glyphs) and that our
14436 previous estimation of the frame content was
14437 garbage. We have to start over. These cases
14438 should be rare, so going all the way back to the
14439 top of redisplay should be good enough. */
14440 if (FRAME_GARBAGED_P (f)
14441 && garbaged_frame_retries++ < MAX_GARBAGED_FRAME_RETRIES)
14442 goto retry;
14444 #if defined (HAVE_WINDOW_SYSTEM) && !defined (HAVE_NS)
14445 x_clear_under_internal_border (f);
14446 #endif /* HAVE_WINDOW_SYSTEM && !HAVE_NS */
14448 /* Prevent various kinds of signals during display
14449 update. stdio is not robust about handling
14450 signals, which can cause an apparent I/O error. */
14451 if (interrupt_input)
14452 unrequest_sigio ();
14453 STOP_POLLING;
14455 pending |= update_frame (f, false, false);
14456 f->cursor_type_changed = false;
14457 f->updated_p = true;
14462 eassert (EQ (XFRAME (selected_frame)->selected_window, selected_window));
14464 if (!pending)
14466 /* Do the mark_window_display_accurate after all windows have
14467 been redisplayed because this call resets flags in buffers
14468 which are needed for proper redisplay. */
14469 FOR_EACH_FRAME (tail, frame)
14471 struct frame *f = XFRAME (frame);
14472 if (f->updated_p)
14474 f->redisplay = false;
14475 f->garbaged = false;
14476 mark_window_display_accurate (f->root_window, true);
14477 if (FRAME_TERMINAL (f)->frame_up_to_date_hook)
14478 FRAME_TERMINAL (f)->frame_up_to_date_hook (f);
14483 else if (FRAME_VISIBLE_P (sf) && !FRAME_OBSCURED_P (sf))
14485 displayed_buffer = XBUFFER (XWINDOW (selected_window)->contents);
14486 /* Use list_of_error, not Qerror, so that
14487 we catch only errors and don't run the debugger. */
14488 internal_condition_case_1 (redisplay_window_1, selected_window,
14489 list_of_error,
14490 redisplay_window_error);
14491 if (update_miniwindow_p)
14492 internal_condition_case_1 (redisplay_window_1,
14493 FRAME_MINIBUF_WINDOW (sf), list_of_error,
14494 redisplay_window_error);
14496 /* Compare desired and current matrices, perform output. */
14498 update:
14499 /* If fonts changed, display again. Likewise if redisplay_window_1
14500 above caused some change (e.g., a change in faces) that requires
14501 considering the entire frame again. */
14502 if (sf->fonts_changed || sf->redisplay)
14504 if (sf->redisplay)
14506 /* Set this to force a more thorough redisplay.
14507 Otherwise, we might immediately loop back to the
14508 above "else-if" clause (since all the conditions that
14509 led here might still be true), and we will then
14510 infloop, because the selected-frame's redisplay flag
14511 is not (and cannot be) reset. */
14512 windows_or_buffers_changed = 50;
14514 goto retry;
14517 /* Prevent freeing of realized faces, since desired matrices are
14518 pending that reference the faces we computed and cached. */
14519 inhibit_free_realized_faces = true;
14521 /* Prevent various kinds of signals during display update.
14522 stdio is not robust about handling signals,
14523 which can cause an apparent I/O error. */
14524 if (interrupt_input)
14525 unrequest_sigio ();
14526 STOP_POLLING;
14528 if (FRAME_VISIBLE_P (sf) && !FRAME_OBSCURED_P (sf))
14530 if (hscroll_retries <= MAX_HSCROLL_RETRIES
14531 && hscroll_windows (selected_window))
14533 hscroll_retries++;
14534 goto retry;
14537 XWINDOW (selected_window)->must_be_updated_p = true;
14538 pending = update_frame (sf, false, false);
14539 sf->cursor_type_changed = false;
14542 /* We may have called echo_area_display at the top of this
14543 function. If the echo area is on another frame, that may
14544 have put text on a frame other than the selected one, so the
14545 above call to update_frame would not have caught it. Catch
14546 it here. */
14547 Lisp_Object mini_window = FRAME_MINIBUF_WINDOW (sf);
14548 struct frame *mini_frame = XFRAME (WINDOW_FRAME (XWINDOW (mini_window)));
14550 if (mini_frame != sf && FRAME_WINDOW_P (mini_frame))
14552 XWINDOW (mini_window)->must_be_updated_p = true;
14553 pending |= update_frame (mini_frame, false, false);
14554 mini_frame->cursor_type_changed = false;
14555 if (!pending && hscroll_retries <= MAX_HSCROLL_RETRIES
14556 && hscroll_windows (mini_window))
14558 hscroll_retries++;
14559 goto retry;
14564 /* If display was paused because of pending input, make sure we do a
14565 thorough update the next time. */
14566 if (pending)
14568 /* Prevent the optimization at the beginning of
14569 redisplay_internal that tries a single-line update of the
14570 line containing the cursor in the selected window. */
14571 CHARPOS (this_line_start_pos) = 0;
14573 /* Let the overlay arrow be updated the next time. */
14574 update_overlay_arrows (0);
14576 /* If we pause after scrolling, some rows in the current
14577 matrices of some windows are not valid. */
14578 if (!WINDOW_FULL_WIDTH_P (w)
14579 && !FRAME_WINDOW_P (XFRAME (w->frame)))
14580 update_mode_lines = 36;
14582 else
14584 if (!consider_all_windows_p)
14586 /* This has already been done above if
14587 consider_all_windows_p is set. */
14588 if (XBUFFER (w->contents)->text->redisplay
14589 && buffer_window_count (XBUFFER (w->contents)) > 1)
14590 /* This can happen if b->text->redisplay was set during
14591 jit-lock. */
14592 propagate_buffer_redisplay ();
14593 mark_window_display_accurate_1 (w, true);
14595 /* Say overlay arrows are up to date. */
14596 update_overlay_arrows (1);
14598 if (FRAME_TERMINAL (sf)->frame_up_to_date_hook != 0)
14599 FRAME_TERMINAL (sf)->frame_up_to_date_hook (sf);
14602 update_mode_lines = 0;
14603 windows_or_buffers_changed = 0;
14606 /* Start SIGIO interrupts coming again. Having them off during the
14607 code above makes it less likely one will discard output, but not
14608 impossible, since there might be stuff in the system buffer here.
14609 But it is much hairier to try to do anything about that. */
14610 if (interrupt_input)
14611 request_sigio ();
14612 RESUME_POLLING;
14614 /* If a frame has become visible which was not before, redisplay
14615 again, so that we display it. Expose events for such a frame
14616 (which it gets when becoming visible) don't call the parts of
14617 redisplay constructing glyphs, so simply exposing a frame won't
14618 display anything in this case. So, we have to display these
14619 frames here explicitly. */
14620 if (!pending)
14622 int new_count = 0;
14624 FOR_EACH_FRAME (tail, frame)
14626 if (XFRAME (frame)->visible)
14627 new_count++;
14630 if (new_count != number_of_visible_frames)
14631 windows_or_buffers_changed = 52;
14634 /* Change frame size now if a change is pending. */
14635 do_pending_window_change (true);
14637 /* If we just did a pending size change, or have additional
14638 visible frames, or selected_window changed, redisplay again. */
14639 if ((windows_or_buffers_changed && !pending)
14640 || (WINDOWP (selected_window) && (w = XWINDOW (selected_window)) != sw))
14641 goto retry;
14643 /* Clear the face and image caches.
14645 We used to do this only if consider_all_windows_p. But the cache
14646 needs to be cleared if a timer creates images in the current
14647 buffer (e.g. the test case in Bug#6230). */
14649 if (clear_face_cache_count > CLEAR_FACE_CACHE_COUNT)
14651 clear_face_cache (false);
14652 clear_face_cache_count = 0;
14655 #ifdef HAVE_WINDOW_SYSTEM
14656 if (clear_image_cache_count > CLEAR_IMAGE_CACHE_COUNT)
14658 clear_image_caches (Qnil);
14659 clear_image_cache_count = 0;
14661 #endif /* HAVE_WINDOW_SYSTEM */
14663 end_of_redisplay:
14664 #ifdef HAVE_NS
14665 ns_set_doc_edited ();
14666 #endif
14667 if (interrupt_input && interrupts_deferred)
14668 request_sigio ();
14670 unbind_to (count, Qnil);
14671 RESUME_POLLING;
14674 static void
14675 unwind_redisplay_preserve_echo_area (void)
14677 unblock_buffer_flips ();
14680 /* Redisplay, but leave alone any recent echo area message unless
14681 another message has been requested in its place.
14683 This is useful in situations where you need to redisplay but no
14684 user action has occurred, making it inappropriate for the message
14685 area to be cleared. See tracking_off and
14686 wait_reading_process_output for examples of these situations.
14688 FROM_WHERE is an integer saying from where this function was
14689 called. This is useful for debugging. */
14691 void
14692 redisplay_preserve_echo_area (int from_where)
14694 TRACE ((stderr, "redisplay_preserve_echo_area (%d)\n", from_where));
14696 block_input ();
14697 ptrdiff_t count = SPECPDL_INDEX ();
14698 record_unwind_protect_void (unwind_redisplay_preserve_echo_area);
14699 block_buffer_flips ();
14700 unblock_input ();
14702 if (!NILP (echo_area_buffer[1]))
14704 /* We have a previously displayed message, but no current
14705 message. Redisplay the previous message. */
14706 display_last_displayed_message_p = true;
14707 redisplay_internal ();
14708 display_last_displayed_message_p = false;
14710 else
14711 redisplay_internal ();
14713 flush_frame (SELECTED_FRAME ());
14714 unbind_to (count, Qnil);
14718 /* Function registered with record_unwind_protect in redisplay_internal. */
14720 static void
14721 unwind_redisplay (void)
14723 redisplaying_p = false;
14724 unblock_buffer_flips ();
14728 /* Mark the display of leaf window W as accurate or inaccurate.
14729 If ACCURATE_P, mark display of W as accurate.
14730 If !ACCURATE_P, arrange for W to be redisplayed the next
14731 time redisplay_internal is called. */
14733 static void
14734 mark_window_display_accurate_1 (struct window *w, bool accurate_p)
14736 struct buffer *b = XBUFFER (w->contents);
14738 w->last_modified = accurate_p ? BUF_MODIFF (b) : 0;
14739 w->last_overlay_modified = accurate_p ? BUF_OVERLAY_MODIFF (b) : 0;
14740 w->last_had_star = BUF_MODIFF (b) > BUF_SAVE_MODIFF (b);
14742 if (accurate_p)
14744 b->clip_changed = false;
14745 b->prevent_redisplay_optimizations_p = false;
14746 eassert (buffer_window_count (b) > 0);
14747 /* Resetting b->text->redisplay is problematic!
14748 In order to make it safer to do it here, redisplay_internal must
14749 have copied all b->text->redisplay to their respective windows. */
14750 b->text->redisplay = false;
14752 BUF_UNCHANGED_MODIFIED (b) = BUF_MODIFF (b);
14753 BUF_OVERLAY_UNCHANGED_MODIFIED (b) = BUF_OVERLAY_MODIFF (b);
14754 BUF_BEG_UNCHANGED (b) = BUF_GPT (b) - BUF_BEG (b);
14755 BUF_END_UNCHANGED (b) = BUF_Z (b) - BUF_GPT (b);
14757 w->current_matrix->buffer = b;
14758 w->current_matrix->begv = BUF_BEGV (b);
14759 w->current_matrix->zv = BUF_ZV (b);
14761 w->last_cursor_vpos = w->cursor.vpos;
14762 w->last_cursor_off_p = w->cursor_off_p;
14764 if (w == XWINDOW (selected_window))
14765 w->last_point = BUF_PT (b);
14766 else
14767 w->last_point = marker_position (w->pointm);
14769 w->window_end_valid = true;
14770 w->update_mode_line = false;
14773 w->redisplay = !accurate_p;
14777 /* Mark the display of windows in the window tree rooted at WINDOW as
14778 accurate or inaccurate. If ACCURATE_P, mark display of
14779 windows as accurate. If !ACCURATE_P, arrange for windows to
14780 be redisplayed the next time redisplay_internal is called. */
14782 void
14783 mark_window_display_accurate (Lisp_Object window, bool accurate_p)
14785 struct window *w;
14787 for (; !NILP (window); window = w->next)
14789 w = XWINDOW (window);
14790 if (WINDOWP (w->contents))
14791 mark_window_display_accurate (w->contents, accurate_p);
14792 else
14793 mark_window_display_accurate_1 (w, accurate_p);
14796 if (accurate_p)
14797 update_overlay_arrows (1);
14798 else
14799 /* Force a thorough redisplay the next time by setting
14800 last_arrow_position and last_arrow_string to t, which is
14801 unequal to any useful value of Voverlay_arrow_... */
14802 update_overlay_arrows (-1);
14806 /* Return value in display table DP (Lisp_Char_Table *) for character
14807 C. Since a display table doesn't have any parent, we don't have to
14808 follow parent. Do not call this function directly but use the
14809 macro DISP_CHAR_VECTOR. */
14811 Lisp_Object
14812 disp_char_vector (struct Lisp_Char_Table *dp, int c)
14814 Lisp_Object val;
14816 if (ASCII_CHAR_P (c))
14818 val = dp->ascii;
14819 if (SUB_CHAR_TABLE_P (val))
14820 val = XSUB_CHAR_TABLE (val)->contents[c];
14822 else
14824 Lisp_Object table;
14826 XSETCHAR_TABLE (table, dp);
14827 val = char_table_ref (table, c);
14829 if (NILP (val))
14830 val = dp->defalt;
14831 return val;
14834 static int buffer_flip_blocked_depth;
14836 static void
14837 block_buffer_flips (void)
14839 eassert (buffer_flip_blocked_depth >= 0);
14840 buffer_flip_blocked_depth++;
14843 static void
14844 unblock_buffer_flips (void)
14846 eassert (buffer_flip_blocked_depth > 0);
14847 if (--buffer_flip_blocked_depth == 0)
14849 Lisp_Object tail, frame;
14850 block_input ();
14851 FOR_EACH_FRAME (tail, frame)
14853 struct frame *f = XFRAME (frame);
14854 if (FRAME_TERMINAL (f)->buffer_flipping_unblocked_hook)
14855 (*FRAME_TERMINAL (f)->buffer_flipping_unblocked_hook) (f);
14857 unblock_input ();
14861 bool
14862 buffer_flipping_blocked_p (void)
14864 return buffer_flip_blocked_depth > 0;
14868 /***********************************************************************
14869 Window Redisplay
14870 ***********************************************************************/
14872 /* Redisplay all leaf windows in the window tree rooted at WINDOW. */
14874 static void
14875 redisplay_windows (Lisp_Object window)
14877 while (!NILP (window))
14879 struct window *w = XWINDOW (window);
14881 if (WINDOWP (w->contents))
14882 redisplay_windows (w->contents);
14883 else if (BUFFERP (w->contents))
14885 displayed_buffer = XBUFFER (w->contents);
14886 /* Use list_of_error, not Qerror, so that
14887 we catch only errors and don't run the debugger. */
14888 internal_condition_case_1 (redisplay_window_0, window,
14889 list_of_error,
14890 redisplay_window_error);
14893 window = w->next;
14897 static Lisp_Object
14898 redisplay_window_error (Lisp_Object ignore)
14900 displayed_buffer->display_error_modiff = BUF_MODIFF (displayed_buffer);
14901 return Qnil;
14904 static Lisp_Object
14905 redisplay_window_0 (Lisp_Object window)
14907 if (displayed_buffer->display_error_modiff < BUF_MODIFF (displayed_buffer))
14908 redisplay_window (window, false);
14909 return Qnil;
14912 static Lisp_Object
14913 redisplay_window_1 (Lisp_Object window)
14915 if (displayed_buffer->display_error_modiff < BUF_MODIFF (displayed_buffer))
14916 redisplay_window (window, true);
14917 return Qnil;
14921 /* Set cursor position of W. PT is assumed to be displayed in ROW.
14922 DELTA and DELTA_BYTES are the numbers of characters and bytes by
14923 which positions recorded in ROW differ from current buffer
14924 positions.
14926 Return true iff cursor is on this row. */
14928 static bool
14929 set_cursor_from_row (struct window *w, struct glyph_row *row,
14930 struct glyph_matrix *matrix,
14931 ptrdiff_t delta, ptrdiff_t delta_bytes,
14932 int dy, int dvpos)
14934 struct glyph *glyph = row->glyphs[TEXT_AREA];
14935 struct glyph *end = glyph + row->used[TEXT_AREA];
14936 struct glyph *cursor = NULL;
14937 /* The last known character position in row. */
14938 ptrdiff_t last_pos = MATRIX_ROW_START_CHARPOS (row) + delta;
14939 int x = row->x;
14940 ptrdiff_t pt_old = PT - delta;
14941 ptrdiff_t pos_before = MATRIX_ROW_START_CHARPOS (row) + delta;
14942 ptrdiff_t pos_after = MATRIX_ROW_END_CHARPOS (row) + delta;
14943 struct glyph *glyph_before = glyph - 1, *glyph_after = end;
14944 /* A glyph beyond the edge of TEXT_AREA which we should never
14945 touch. */
14946 struct glyph *glyphs_end = end;
14947 /* True means we've found a match for cursor position, but that
14948 glyph has the avoid_cursor_p flag set. */
14949 bool match_with_avoid_cursor = false;
14950 /* True means we've seen at least one glyph that came from a
14951 display string. */
14952 bool string_seen = false;
14953 /* Largest and smallest buffer positions seen so far during scan of
14954 glyph row. */
14955 ptrdiff_t bpos_max = pos_before;
14956 ptrdiff_t bpos_min = pos_after;
14957 /* Last buffer position covered by an overlay string with an integer
14958 `cursor' property. */
14959 ptrdiff_t bpos_covered = 0;
14960 /* True means the display string on which to display the cursor
14961 comes from a text property, not from an overlay. */
14962 bool string_from_text_prop = false;
14964 /* Don't even try doing anything if called for a mode-line or
14965 header-line row, since the rest of the code isn't prepared to
14966 deal with such calamities. */
14967 eassert (!row->mode_line_p);
14968 if (row->mode_line_p)
14969 return false;
14971 /* Skip over glyphs not having an object at the start and the end of
14972 the row. These are special glyphs like truncation marks on
14973 terminal frames. */
14974 if (MATRIX_ROW_DISPLAYS_TEXT_P (row))
14976 if (!row->reversed_p)
14978 while (glyph < end
14979 && NILP (glyph->object)
14980 && glyph->charpos < 0)
14982 x += glyph->pixel_width;
14983 ++glyph;
14985 while (end > glyph
14986 && NILP ((end - 1)->object)
14987 /* CHARPOS is zero for blanks and stretch glyphs
14988 inserted by extend_face_to_end_of_line. */
14989 && (end - 1)->charpos <= 0)
14990 --end;
14991 glyph_before = glyph - 1;
14992 glyph_after = end;
14994 else
14996 struct glyph *g;
14998 /* If the glyph row is reversed, we need to process it from back
14999 to front, so swap the edge pointers. */
15000 glyphs_end = end = glyph - 1;
15001 glyph += row->used[TEXT_AREA] - 1;
15003 while (glyph > end + 1
15004 && NILP (glyph->object)
15005 && glyph->charpos < 0)
15006 --glyph;
15007 if (NILP (glyph->object) && glyph->charpos < 0)
15008 --glyph;
15009 /* By default, in reversed rows we put the cursor on the
15010 rightmost (first in the reading order) glyph. */
15011 for (x = 0, g = end + 1; g < glyph; g++)
15012 x += g->pixel_width;
15013 while (end < glyph
15014 && NILP ((end + 1)->object)
15015 && (end + 1)->charpos <= 0)
15016 ++end;
15017 glyph_before = glyph + 1;
15018 glyph_after = end;
15021 else if (row->reversed_p)
15023 /* In R2L rows that don't display text, put the cursor on the
15024 rightmost glyph. Case in point: an empty last line that is
15025 part of an R2L paragraph. */
15026 cursor = end - 1;
15027 /* Avoid placing the cursor on the last glyph of the row, where
15028 on terminal frames we hold the vertical border between
15029 adjacent windows. */
15030 if (!FRAME_WINDOW_P (WINDOW_XFRAME (w))
15031 && !WINDOW_RIGHTMOST_P (w)
15032 && cursor == row->glyphs[LAST_AREA] - 1)
15033 cursor--;
15034 x = -1; /* will be computed below, at label compute_x */
15037 /* Step 1: Try to find the glyph whose character position
15038 corresponds to point. If that's not possible, find 2 glyphs
15039 whose character positions are the closest to point, one before
15040 point, the other after it. */
15041 if (!row->reversed_p)
15042 while (/* not marched to end of glyph row */
15043 glyph < end
15044 /* glyph was not inserted by redisplay for internal purposes */
15045 && !NILP (glyph->object))
15047 if (BUFFERP (glyph->object))
15049 ptrdiff_t dpos = glyph->charpos - pt_old;
15051 if (glyph->charpos > bpos_max)
15052 bpos_max = glyph->charpos;
15053 if (glyph->charpos < bpos_min)
15054 bpos_min = glyph->charpos;
15055 if (!glyph->avoid_cursor_p)
15057 /* If we hit point, we've found the glyph on which to
15058 display the cursor. */
15059 if (dpos == 0)
15061 match_with_avoid_cursor = false;
15062 break;
15064 /* See if we've found a better approximation to
15065 POS_BEFORE or to POS_AFTER. */
15066 if (0 > dpos && dpos > pos_before - pt_old)
15068 pos_before = glyph->charpos;
15069 glyph_before = glyph;
15071 else if (0 < dpos && dpos < pos_after - pt_old)
15073 pos_after = glyph->charpos;
15074 glyph_after = glyph;
15077 else if (dpos == 0)
15078 match_with_avoid_cursor = true;
15080 else if (STRINGP (glyph->object))
15082 Lisp_Object chprop;
15083 ptrdiff_t glyph_pos = glyph->charpos;
15085 chprop = Fget_char_property (make_number (glyph_pos), Qcursor,
15086 glyph->object);
15087 if (!NILP (chprop))
15089 /* If the string came from a `display' text property,
15090 look up the buffer position of that property and
15091 use that position to update bpos_max, as if we
15092 actually saw such a position in one of the row's
15093 glyphs. This helps with supporting integer values
15094 of `cursor' property on the display string in
15095 situations where most or all of the row's buffer
15096 text is completely covered by display properties,
15097 so that no glyph with valid buffer positions is
15098 ever seen in the row. */
15099 ptrdiff_t prop_pos =
15100 string_buffer_position_lim (glyph->object, pos_before,
15101 pos_after, false);
15103 if (prop_pos >= pos_before)
15104 bpos_max = prop_pos;
15106 if (INTEGERP (chprop))
15108 bpos_covered = bpos_max + XINT (chprop);
15109 /* If the `cursor' property covers buffer positions up
15110 to and including point, we should display cursor on
15111 this glyph. Note that, if a `cursor' property on one
15112 of the string's characters has an integer value, we
15113 will break out of the loop below _before_ we get to
15114 the position match above. IOW, integer values of
15115 the `cursor' property override the "exact match for
15116 point" strategy of positioning the cursor. */
15117 /* Implementation note: bpos_max == pt_old when, e.g.,
15118 we are in an empty line, where bpos_max is set to
15119 MATRIX_ROW_START_CHARPOS, see above. */
15120 if (bpos_max <= pt_old && bpos_covered >= pt_old)
15122 cursor = glyph;
15123 break;
15127 string_seen = true;
15129 x += glyph->pixel_width;
15130 ++glyph;
15132 else if (glyph > end) /* row is reversed */
15133 while (!NILP (glyph->object))
15135 if (BUFFERP (glyph->object))
15137 ptrdiff_t dpos = glyph->charpos - pt_old;
15139 if (glyph->charpos > bpos_max)
15140 bpos_max = glyph->charpos;
15141 if (glyph->charpos < bpos_min)
15142 bpos_min = glyph->charpos;
15143 if (!glyph->avoid_cursor_p)
15145 if (dpos == 0)
15147 match_with_avoid_cursor = false;
15148 break;
15150 if (0 > dpos && dpos > pos_before - pt_old)
15152 pos_before = glyph->charpos;
15153 glyph_before = glyph;
15155 else if (0 < dpos && dpos < pos_after - pt_old)
15157 pos_after = glyph->charpos;
15158 glyph_after = glyph;
15161 else if (dpos == 0)
15162 match_with_avoid_cursor = true;
15164 else if (STRINGP (glyph->object))
15166 Lisp_Object chprop;
15167 ptrdiff_t glyph_pos = glyph->charpos;
15169 chprop = Fget_char_property (make_number (glyph_pos), Qcursor,
15170 glyph->object);
15171 if (!NILP (chprop))
15173 ptrdiff_t prop_pos =
15174 string_buffer_position_lim (glyph->object, pos_before,
15175 pos_after, false);
15177 if (prop_pos >= pos_before)
15178 bpos_max = prop_pos;
15180 if (INTEGERP (chprop))
15182 bpos_covered = bpos_max + XINT (chprop);
15183 /* If the `cursor' property covers buffer positions up
15184 to and including point, we should display cursor on
15185 this glyph. */
15186 if (bpos_max <= pt_old && bpos_covered >= pt_old)
15188 cursor = glyph;
15189 break;
15192 string_seen = true;
15194 --glyph;
15195 if (glyph == glyphs_end) /* don't dereference outside TEXT_AREA */
15197 x--; /* can't use any pixel_width */
15198 break;
15200 x -= glyph->pixel_width;
15203 /* Step 2: If we didn't find an exact match for point, we need to
15204 look for a proper place to put the cursor among glyphs between
15205 GLYPH_BEFORE and GLYPH_AFTER. */
15206 if (!((row->reversed_p ? glyph > glyphs_end : glyph < glyphs_end)
15207 && BUFFERP (glyph->object) && glyph->charpos == pt_old)
15208 && !(bpos_max <= pt_old && pt_old <= bpos_covered))
15210 /* An empty line has a single glyph whose OBJECT is nil and
15211 whose CHARPOS is the position of a newline on that line.
15212 Note that on a TTY, there are more glyphs after that, which
15213 were produced by extend_face_to_end_of_line, but their
15214 CHARPOS is zero or negative. */
15215 bool empty_line_p =
15216 ((row->reversed_p ? glyph > glyphs_end : glyph < glyphs_end)
15217 && NILP (glyph->object) && glyph->charpos > 0
15218 /* On a TTY, continued and truncated rows also have a glyph at
15219 their end whose OBJECT is nil and whose CHARPOS is
15220 positive (the continuation and truncation glyphs), but such
15221 rows are obviously not "empty". */
15222 && !(row->continued_p || row->truncated_on_right_p));
15224 if (row->ends_in_ellipsis_p && pos_after == last_pos)
15226 ptrdiff_t ellipsis_pos;
15228 /* Scan back over the ellipsis glyphs. */
15229 if (!row->reversed_p)
15231 ellipsis_pos = (glyph - 1)->charpos;
15232 while (glyph > row->glyphs[TEXT_AREA]
15233 && (glyph - 1)->charpos == ellipsis_pos)
15234 glyph--, x -= glyph->pixel_width;
15235 /* That loop always goes one position too far, including
15236 the glyph before the ellipsis. So scan forward over
15237 that one. */
15238 x += glyph->pixel_width;
15239 glyph++;
15241 else /* row is reversed */
15243 ellipsis_pos = (glyph + 1)->charpos;
15244 while (glyph < row->glyphs[TEXT_AREA] + row->used[TEXT_AREA] - 1
15245 && (glyph + 1)->charpos == ellipsis_pos)
15246 glyph++, x += glyph->pixel_width;
15247 x -= glyph->pixel_width;
15248 glyph--;
15251 else if (match_with_avoid_cursor)
15253 cursor = glyph_after;
15254 x = -1;
15256 else if (string_seen)
15258 int incr = row->reversed_p ? -1 : +1;
15260 /* Need to find the glyph that came out of a string which is
15261 present at point. That glyph is somewhere between
15262 GLYPH_BEFORE and GLYPH_AFTER, and it came from a string
15263 positioned between POS_BEFORE and POS_AFTER in the
15264 buffer. */
15265 struct glyph *start, *stop;
15266 ptrdiff_t pos = pos_before;
15268 x = -1;
15270 /* If the row ends in a newline from a display string,
15271 reordering could have moved the glyphs belonging to the
15272 string out of the [GLYPH_BEFORE..GLYPH_AFTER] range. So
15273 in this case we extend the search to the last glyph in
15274 the row that was not inserted by redisplay. */
15275 if (row->ends_in_newline_from_string_p)
15277 glyph_after = end;
15278 pos_after = MATRIX_ROW_END_CHARPOS (row) + delta;
15281 /* GLYPH_BEFORE and GLYPH_AFTER are the glyphs that
15282 correspond to POS_BEFORE and POS_AFTER, respectively. We
15283 need START and STOP in the order that corresponds to the
15284 row's direction as given by its reversed_p flag. If the
15285 directionality of characters between POS_BEFORE and
15286 POS_AFTER is the opposite of the row's base direction,
15287 these characters will have been reordered for display,
15288 and we need to reverse START and STOP. */
15289 if (!row->reversed_p)
15291 start = min (glyph_before, glyph_after);
15292 stop = max (glyph_before, glyph_after);
15294 else
15296 start = max (glyph_before, glyph_after);
15297 stop = min (glyph_before, glyph_after);
15299 for (glyph = start + incr;
15300 row->reversed_p ? glyph > stop : glyph < stop; )
15303 /* Any glyphs that come from the buffer are here because
15304 of bidi reordering. Skip them, and only pay
15305 attention to glyphs that came from some string. */
15306 if (STRINGP (glyph->object))
15308 Lisp_Object str;
15309 ptrdiff_t tem;
15310 /* If the display property covers the newline, we
15311 need to search for it one position farther. */
15312 ptrdiff_t lim = pos_after
15313 + (pos_after == MATRIX_ROW_END_CHARPOS (row) + delta);
15315 string_from_text_prop = false;
15316 str = glyph->object;
15317 tem = string_buffer_position_lim (str, pos, lim, false);
15318 if (tem == 0 /* from overlay */
15319 || pos <= tem)
15321 /* If the string from which this glyph came is
15322 found in the buffer at point, or at position
15323 that is closer to point than pos_after, then
15324 we've found the glyph we've been looking for.
15325 If it comes from an overlay (tem == 0), and
15326 it has the `cursor' property on one of its
15327 glyphs, record that glyph as a candidate for
15328 displaying the cursor. (As in the
15329 unidirectional version, we will display the
15330 cursor on the last candidate we find.) */
15331 if (tem == 0
15332 || tem == pt_old
15333 || (tem - pt_old > 0 && tem < pos_after))
15335 /* The glyphs from this string could have
15336 been reordered. Find the one with the
15337 smallest string position. Or there could
15338 be a character in the string with the
15339 `cursor' property, which means display
15340 cursor on that character's glyph. */
15341 ptrdiff_t strpos = glyph->charpos;
15343 if (tem)
15345 cursor = glyph;
15346 string_from_text_prop = true;
15348 for ( ;
15349 (row->reversed_p ? glyph > stop : glyph < stop)
15350 && EQ (glyph->object, str);
15351 glyph += incr)
15353 Lisp_Object cprop;
15354 ptrdiff_t gpos = glyph->charpos;
15356 cprop = Fget_char_property (make_number (gpos),
15357 Qcursor,
15358 glyph->object);
15359 if (!NILP (cprop))
15361 cursor = glyph;
15362 break;
15364 if (tem && glyph->charpos < strpos)
15366 strpos = glyph->charpos;
15367 cursor = glyph;
15371 if (tem == pt_old
15372 || (tem - pt_old > 0 && tem < pos_after))
15373 goto compute_x;
15375 if (tem)
15376 pos = tem + 1; /* don't find previous instances */
15378 /* This string is not what we want; skip all of the
15379 glyphs that came from it. */
15380 while ((row->reversed_p ? glyph > stop : glyph < stop)
15381 && EQ (glyph->object, str))
15382 glyph += incr;
15384 else
15385 glyph += incr;
15388 /* If we reached the end of the line, and END was from a string,
15389 the cursor is not on this line. */
15390 if (cursor == NULL
15391 && (row->reversed_p ? glyph <= end : glyph >= end)
15392 && (row->reversed_p ? end > glyphs_end : end < glyphs_end)
15393 && STRINGP (end->object)
15394 && row->continued_p)
15395 return false;
15397 /* A truncated row may not include PT among its character positions.
15398 Setting the cursor inside the scroll margin will trigger
15399 recalculation of hscroll in hscroll_window_tree. But if a
15400 display string covers point, defer to the string-handling
15401 code below to figure this out. */
15402 else if (row->truncated_on_left_p && pt_old < bpos_min)
15404 cursor = glyph_before;
15405 x = -1;
15407 else if ((row->truncated_on_right_p && pt_old > bpos_max)
15408 /* Zero-width characters produce no glyphs. */
15409 || (!empty_line_p
15410 && (row->reversed_p
15411 ? glyph_after > glyphs_end
15412 : glyph_after < glyphs_end)))
15414 cursor = glyph_after;
15415 x = -1;
15419 compute_x:
15420 if (cursor != NULL)
15421 glyph = cursor;
15422 else if (glyph == glyphs_end
15423 && pos_before == pos_after
15424 && STRINGP ((row->reversed_p
15425 ? row->glyphs[TEXT_AREA] + row->used[TEXT_AREA] - 1
15426 : row->glyphs[TEXT_AREA])->object))
15428 /* If all the glyphs of this row came from strings, put the
15429 cursor on the first glyph of the row. This avoids having the
15430 cursor outside of the text area in this very rare and hard
15431 use case. */
15432 glyph =
15433 row->reversed_p
15434 ? row->glyphs[TEXT_AREA] + row->used[TEXT_AREA] - 1
15435 : row->glyphs[TEXT_AREA];
15437 if (x < 0)
15439 struct glyph *g;
15441 /* Need to compute x that corresponds to GLYPH. */
15442 for (g = row->glyphs[TEXT_AREA], x = row->x; g < glyph; g++)
15444 if (g >= row->glyphs[TEXT_AREA] + row->used[TEXT_AREA])
15445 emacs_abort ();
15446 x += g->pixel_width;
15450 /* ROW could be part of a continued line, which, under bidi
15451 reordering, might have other rows whose start and end charpos
15452 occlude point. Only set w->cursor if we found a better
15453 approximation to the cursor position than we have from previously
15454 examined candidate rows belonging to the same continued line. */
15455 if (/* We already have a candidate row. */
15456 w->cursor.vpos >= 0
15457 /* That candidate is not the row we are processing. */
15458 && MATRIX_ROW (matrix, w->cursor.vpos) != row
15459 /* Make sure cursor.vpos specifies a row whose start and end
15460 charpos occlude point, and it is valid candidate for being a
15461 cursor-row. This is because some callers of this function
15462 leave cursor.vpos at the row where the cursor was displayed
15463 during the last redisplay cycle. */
15464 && MATRIX_ROW_START_CHARPOS (MATRIX_ROW (matrix, w->cursor.vpos)) <= pt_old
15465 && pt_old <= MATRIX_ROW_END_CHARPOS (MATRIX_ROW (matrix, w->cursor.vpos))
15466 && cursor_row_p (MATRIX_ROW (matrix, w->cursor.vpos)))
15468 struct glyph *g1
15469 = MATRIX_ROW_GLYPH_START (matrix, w->cursor.vpos) + w->cursor.hpos;
15471 /* Don't consider glyphs that are outside TEXT_AREA. */
15472 if (!(row->reversed_p ? glyph > glyphs_end : glyph < glyphs_end))
15473 return false;
15474 /* Keep the candidate whose buffer position is the closest to
15475 point or has the `cursor' property. */
15476 if (/* Previous candidate is a glyph in TEXT_AREA of that row. */
15477 w->cursor.hpos >= 0
15478 && w->cursor.hpos < MATRIX_ROW_USED (matrix, w->cursor.vpos)
15479 && ((BUFFERP (g1->object)
15480 && (g1->charpos == pt_old /* An exact match always wins. */
15481 || (BUFFERP (glyph->object)
15482 && eabs (g1->charpos - pt_old)
15483 < eabs (glyph->charpos - pt_old))))
15484 /* Previous candidate is a glyph from a string that has
15485 a non-nil `cursor' property. */
15486 || (STRINGP (g1->object)
15487 && (!NILP (Fget_char_property (make_number (g1->charpos),
15488 Qcursor, g1->object))
15489 /* Previous candidate is from the same display
15490 string as this one, and the display string
15491 came from a text property. */
15492 || (EQ (g1->object, glyph->object)
15493 && string_from_text_prop)
15494 /* this candidate is from newline and its
15495 position is not an exact match */
15496 || (NILP (glyph->object)
15497 && glyph->charpos != pt_old)))))
15498 return false;
15499 /* If this candidate gives an exact match, use that. */
15500 if (!((BUFFERP (glyph->object) && glyph->charpos == pt_old)
15501 /* If this candidate is a glyph created for the
15502 terminating newline of a line, and point is on that
15503 newline, it wins because it's an exact match. */
15504 || (!row->continued_p
15505 && NILP (glyph->object)
15506 && glyph->charpos == 0
15507 && pt_old == MATRIX_ROW_END_CHARPOS (row) - 1))
15508 /* Otherwise, keep the candidate that comes from a row
15509 spanning less buffer positions. This may win when one or
15510 both candidate positions are on glyphs that came from
15511 display strings, for which we cannot compare buffer
15512 positions. */
15513 && MATRIX_ROW_END_CHARPOS (MATRIX_ROW (matrix, w->cursor.vpos))
15514 - MATRIX_ROW_START_CHARPOS (MATRIX_ROW (matrix, w->cursor.vpos))
15515 < MATRIX_ROW_END_CHARPOS (row) - MATRIX_ROW_START_CHARPOS (row))
15516 return false;
15518 w->cursor.hpos = glyph - row->glyphs[TEXT_AREA];
15519 w->cursor.x = x;
15520 w->cursor.vpos = MATRIX_ROW_VPOS (row, matrix) + dvpos;
15521 w->cursor.y = row->y + dy;
15523 if (w == XWINDOW (selected_window))
15525 if (!row->continued_p
15526 && !MATRIX_ROW_CONTINUATION_LINE_P (row)
15527 && row->x == 0)
15529 this_line_buffer = XBUFFER (w->contents);
15531 CHARPOS (this_line_start_pos)
15532 = MATRIX_ROW_START_CHARPOS (row) + delta;
15533 BYTEPOS (this_line_start_pos)
15534 = MATRIX_ROW_START_BYTEPOS (row) + delta_bytes;
15536 CHARPOS (this_line_end_pos)
15537 = Z - (MATRIX_ROW_END_CHARPOS (row) + delta);
15538 BYTEPOS (this_line_end_pos)
15539 = Z_BYTE - (MATRIX_ROW_END_BYTEPOS (row) + delta_bytes);
15541 this_line_y = w->cursor.y;
15542 this_line_pixel_height = row->height;
15543 this_line_vpos = w->cursor.vpos;
15544 this_line_start_x = row->x;
15546 else
15547 CHARPOS (this_line_start_pos) = 0;
15550 return true;
15554 /* Run window scroll functions, if any, for WINDOW with new window
15555 start STARTP. Sets the window start of WINDOW to that position.
15557 We assume that the window's buffer is really current. */
15559 static struct text_pos
15560 run_window_scroll_functions (Lisp_Object window, struct text_pos startp)
15562 struct window *w = XWINDOW (window);
15563 SET_MARKER_FROM_TEXT_POS (w->start, startp);
15565 eassert (current_buffer == XBUFFER (w->contents));
15567 if (!NILP (Vwindow_scroll_functions))
15569 run_hook_with_args_2 (Qwindow_scroll_functions, window,
15570 make_number (CHARPOS (startp)));
15571 SET_TEXT_POS_FROM_MARKER (startp, w->start);
15572 /* In case the hook functions switch buffers. */
15573 set_buffer_internal (XBUFFER (w->contents));
15576 return startp;
15580 /* Make sure the line containing the cursor is fully visible.
15581 A value of true means there is nothing to be done.
15582 (Either the line is fully visible, or it cannot be made so,
15583 or we cannot tell.)
15585 If FORCE_P, return false even if partial visible cursor row
15586 is higher than window.
15588 If CURRENT_MATRIX_P, use the information from the
15589 window's current glyph matrix; otherwise use the desired glyph
15590 matrix.
15592 A value of false means the caller should do scrolling
15593 as if point had gone off the screen. */
15595 static bool
15596 cursor_row_fully_visible_p (struct window *w, bool force_p,
15597 bool current_matrix_p)
15599 struct glyph_matrix *matrix;
15600 struct glyph_row *row;
15601 int window_height;
15603 if (!make_cursor_line_fully_visible_p)
15604 return true;
15606 /* It's not always possible to find the cursor, e.g, when a window
15607 is full of overlay strings. Don't do anything in that case. */
15608 if (w->cursor.vpos < 0)
15609 return true;
15611 matrix = current_matrix_p ? w->current_matrix : w->desired_matrix;
15612 row = MATRIX_ROW (matrix, w->cursor.vpos);
15614 /* If the cursor row is not partially visible, there's nothing to do. */
15615 if (!MATRIX_ROW_PARTIALLY_VISIBLE_P (w, row))
15616 return true;
15618 /* If the row the cursor is in is taller than the window's height,
15619 it's not clear what to do, so do nothing. */
15620 window_height = window_box_height (w);
15621 if (row->height >= window_height)
15623 if (!force_p || MINI_WINDOW_P (w)
15624 || w->vscroll || w->cursor.vpos == 0)
15625 return true;
15627 return false;
15631 /* Try scrolling PT into view in window WINDOW. JUST_THIS_ONE_P
15632 means only WINDOW is redisplayed in redisplay_internal.
15633 TEMP_SCROLL_STEP has the same meaning as emacs_scroll_step, and is used
15634 in redisplay_window to bring a partially visible line into view in
15635 the case that only the cursor has moved.
15637 LAST_LINE_MISFIT should be true if we're scrolling because the
15638 last screen line's vertical height extends past the end of the screen.
15640 Value is
15642 1 if scrolling succeeded
15644 0 if scrolling didn't find point.
15646 -1 if new fonts have been loaded so that we must interrupt
15647 redisplay, adjust glyph matrices, and try again. */
15649 enum
15651 SCROLLING_SUCCESS,
15652 SCROLLING_FAILED,
15653 SCROLLING_NEED_LARGER_MATRICES
15656 /* If scroll-conservatively is more than this, never recenter.
15658 If you change this, don't forget to update the doc string of
15659 `scroll-conservatively' and the Emacs manual. */
15660 #define SCROLL_LIMIT 100
15662 static int
15663 try_scrolling (Lisp_Object window, bool just_this_one_p,
15664 ptrdiff_t arg_scroll_conservatively, ptrdiff_t scroll_step,
15665 bool temp_scroll_step, bool last_line_misfit)
15667 struct window *w = XWINDOW (window);
15668 struct text_pos pos, startp;
15669 struct it it;
15670 int this_scroll_margin, scroll_max, rc, height;
15671 int dy = 0, amount_to_scroll = 0;
15672 bool scroll_down_p = false;
15673 int extra_scroll_margin_lines = last_line_misfit;
15674 Lisp_Object aggressive;
15675 /* We will never try scrolling more than this number of lines. */
15676 int scroll_limit = SCROLL_LIMIT;
15677 int frame_line_height = default_line_pixel_height (w);
15679 #ifdef GLYPH_DEBUG
15680 debug_method_add (w, "try_scrolling");
15681 #endif
15683 SET_TEXT_POS_FROM_MARKER (startp, w->start);
15685 this_scroll_margin = window_scroll_margin (w, MARGIN_IN_PIXELS);
15687 /* Force arg_scroll_conservatively to have a reasonable value, to
15688 avoid scrolling too far away with slow move_it_* functions. Note
15689 that the user can supply scroll-conservatively equal to
15690 `most-positive-fixnum', which can be larger than INT_MAX. */
15691 if (arg_scroll_conservatively > scroll_limit)
15693 arg_scroll_conservatively = scroll_limit + 1;
15694 scroll_max = scroll_limit * frame_line_height;
15696 else if (scroll_step || arg_scroll_conservatively || temp_scroll_step)
15697 /* Compute how much we should try to scroll maximally to bring
15698 point into view. */
15699 scroll_max = (max (scroll_step,
15700 max (arg_scroll_conservatively, temp_scroll_step))
15701 * frame_line_height);
15702 else if (NUMBERP (BVAR (current_buffer, scroll_down_aggressively))
15703 || NUMBERP (BVAR (current_buffer, scroll_up_aggressively)))
15704 /* We're trying to scroll because of aggressive scrolling but no
15705 scroll_step is set. Choose an arbitrary one. */
15706 scroll_max = 10 * frame_line_height;
15707 else
15708 scroll_max = 0;
15710 too_near_end:
15712 /* Decide whether to scroll down. */
15713 if (PT > CHARPOS (startp))
15715 int scroll_margin_y;
15717 /* Compute the pixel ypos of the scroll margin, then move IT to
15718 either that ypos or PT, whichever comes first. */
15719 start_display (&it, w, startp);
15720 scroll_margin_y = it.last_visible_y - partial_line_height (&it)
15721 - this_scroll_margin
15722 - frame_line_height * extra_scroll_margin_lines;
15723 move_it_to (&it, PT, -1, scroll_margin_y - 1, -1,
15724 (MOVE_TO_POS | MOVE_TO_Y));
15726 if (PT > CHARPOS (it.current.pos))
15728 int y0 = line_bottom_y (&it);
15729 /* Compute how many pixels below window bottom to stop searching
15730 for PT. This avoids costly search for PT that is far away if
15731 the user limited scrolling by a small number of lines, but
15732 always finds PT if scroll_conservatively is set to a large
15733 number, such as most-positive-fixnum. */
15734 int slack = max (scroll_max, 10 * frame_line_height);
15735 int y_to_move = it.last_visible_y + slack;
15737 /* Compute the distance from the scroll margin to PT or to
15738 the scroll limit, whichever comes first. This should
15739 include the height of the cursor line, to make that line
15740 fully visible. */
15741 move_it_to (&it, PT, -1, y_to_move,
15742 -1, MOVE_TO_POS | MOVE_TO_Y);
15743 dy = line_bottom_y (&it) - y0;
15745 if (dy > scroll_max)
15746 return SCROLLING_FAILED;
15748 if (dy > 0)
15749 scroll_down_p = true;
15751 else if (PT == IT_CHARPOS (it)
15752 && IT_CHARPOS (it) < ZV
15753 && it.method == GET_FROM_STRING
15754 && arg_scroll_conservatively > scroll_limit
15755 && it.current_x == 0)
15757 enum move_it_result skip;
15758 int y1 = it.current_y;
15759 int vpos;
15761 /* A before-string that includes newlines and is displayed
15762 on the last visible screen line could fail us under
15763 scroll-conservatively > 100, because we will be unable to
15764 position the cursor on that last visible line. Try to
15765 recover by finding the first screen line that has some
15766 glyphs coming from the buffer text. */
15767 do {
15768 skip = move_it_in_display_line_to (&it, ZV, -1, MOVE_TO_POS);
15769 if (skip != MOVE_NEWLINE_OR_CR
15770 || IT_CHARPOS (it) != PT
15771 || it.method == GET_FROM_BUFFER)
15772 break;
15773 vpos = it.vpos;
15774 move_it_to (&it, -1, -1, -1, vpos + 1, MOVE_TO_VPOS);
15775 } while (it.vpos > vpos);
15777 dy = it.current_y - y1;
15779 if (dy > scroll_max)
15780 return SCROLLING_FAILED;
15782 if (dy > 0)
15783 scroll_down_p = true;
15787 if (scroll_down_p)
15789 /* Point is in or below the bottom scroll margin, so move the
15790 window start down. If scrolling conservatively, move it just
15791 enough down to make point visible. If scroll_step is set,
15792 move it down by scroll_step. */
15793 if (arg_scroll_conservatively)
15794 amount_to_scroll
15795 = min (max (dy, frame_line_height),
15796 frame_line_height * arg_scroll_conservatively);
15797 else if (scroll_step || temp_scroll_step)
15798 amount_to_scroll = scroll_max;
15799 else
15801 aggressive = BVAR (current_buffer, scroll_up_aggressively);
15802 height = WINDOW_BOX_TEXT_HEIGHT (w);
15803 if (NUMBERP (aggressive))
15805 double float_amount = XFLOATINT (aggressive) * height;
15806 int aggressive_scroll = float_amount;
15807 if (aggressive_scroll == 0 && float_amount > 0)
15808 aggressive_scroll = 1;
15809 /* Don't let point enter the scroll margin near top of
15810 the window. This could happen if the value of
15811 scroll_up_aggressively is too large and there are
15812 non-zero margins, because scroll_up_aggressively
15813 means put point that fraction of window height
15814 _from_the_bottom_margin_. */
15815 if (aggressive_scroll + 2 * this_scroll_margin > height)
15816 aggressive_scroll = height - 2 * this_scroll_margin;
15817 amount_to_scroll = dy + aggressive_scroll;
15821 if (amount_to_scroll <= 0)
15822 return SCROLLING_FAILED;
15824 start_display (&it, w, startp);
15825 if (arg_scroll_conservatively <= scroll_limit)
15826 move_it_vertically (&it, amount_to_scroll);
15827 else
15829 /* Extra precision for users who set scroll-conservatively
15830 to a large number: make sure the amount we scroll
15831 the window start is never less than amount_to_scroll,
15832 which was computed as distance from window bottom to
15833 point. This matters when lines at window top and lines
15834 below window bottom have different height. */
15835 struct it it1;
15836 void *it1data = NULL;
15837 /* We use a temporary it1 because line_bottom_y can modify
15838 its argument, if it moves one line down; see there. */
15839 int start_y;
15841 SAVE_IT (it1, it, it1data);
15842 start_y = line_bottom_y (&it1);
15843 do {
15844 RESTORE_IT (&it, &it, it1data);
15845 move_it_by_lines (&it, 1);
15846 SAVE_IT (it1, it, it1data);
15847 } while (IT_CHARPOS (it) < ZV
15848 && line_bottom_y (&it1) - start_y < amount_to_scroll);
15849 bidi_unshelve_cache (it1data, true);
15852 /* If STARTP is unchanged, move it down another screen line. */
15853 if (IT_CHARPOS (it) == CHARPOS (startp))
15854 move_it_by_lines (&it, 1);
15855 startp = it.current.pos;
15857 else
15859 struct text_pos scroll_margin_pos = startp;
15860 int y_offset = 0;
15862 /* See if point is inside the scroll margin at the top of the
15863 window. */
15864 if (this_scroll_margin)
15866 int y_start;
15868 start_display (&it, w, startp);
15869 y_start = it.current_y;
15870 move_it_vertically (&it, this_scroll_margin);
15871 scroll_margin_pos = it.current.pos;
15872 /* If we didn't move enough before hitting ZV, request
15873 additional amount of scroll, to move point out of the
15874 scroll margin. */
15875 if (IT_CHARPOS (it) == ZV
15876 && it.current_y - y_start < this_scroll_margin)
15877 y_offset = this_scroll_margin - (it.current_y - y_start);
15880 if (PT < CHARPOS (scroll_margin_pos))
15882 /* Point is in the scroll margin at the top of the window or
15883 above what is displayed in the window. */
15884 int y0, y_to_move;
15886 /* Compute the vertical distance from PT to the scroll
15887 margin position. Move as far as scroll_max allows, or
15888 one screenful, or 10 screen lines, whichever is largest.
15889 Give up if distance is greater than scroll_max or if we
15890 didn't reach the scroll margin position. */
15891 SET_TEXT_POS (pos, PT, PT_BYTE);
15892 start_display (&it, w, pos);
15893 y0 = it.current_y;
15894 y_to_move = max (it.last_visible_y,
15895 max (scroll_max, 10 * frame_line_height));
15896 move_it_to (&it, CHARPOS (scroll_margin_pos), 0,
15897 y_to_move, -1,
15898 MOVE_TO_POS | MOVE_TO_X | MOVE_TO_Y);
15899 dy = it.current_y - y0;
15900 if (dy > scroll_max
15901 || IT_CHARPOS (it) < CHARPOS (scroll_margin_pos))
15902 return SCROLLING_FAILED;
15904 /* Additional scroll for when ZV was too close to point. */
15905 dy += y_offset;
15907 /* Compute new window start. */
15908 start_display (&it, w, startp);
15910 if (arg_scroll_conservatively)
15911 amount_to_scroll = max (dy, frame_line_height
15912 * max (scroll_step, temp_scroll_step));
15913 else if (scroll_step || temp_scroll_step)
15914 amount_to_scroll = scroll_max;
15915 else
15917 aggressive = BVAR (current_buffer, scroll_down_aggressively);
15918 height = WINDOW_BOX_TEXT_HEIGHT (w);
15919 if (NUMBERP (aggressive))
15921 double float_amount = XFLOATINT (aggressive) * height;
15922 int aggressive_scroll = float_amount;
15923 if (aggressive_scroll == 0 && float_amount > 0)
15924 aggressive_scroll = 1;
15925 /* Don't let point enter the scroll margin near
15926 bottom of the window, if the value of
15927 scroll_down_aggressively happens to be too
15928 large. */
15929 if (aggressive_scroll + 2 * this_scroll_margin > height)
15930 aggressive_scroll = height - 2 * this_scroll_margin;
15931 amount_to_scroll = dy + aggressive_scroll;
15935 if (amount_to_scroll <= 0)
15936 return SCROLLING_FAILED;
15938 move_it_vertically_backward (&it, amount_to_scroll);
15939 startp = it.current.pos;
15943 /* Run window scroll functions. */
15944 startp = run_window_scroll_functions (window, startp);
15946 /* Display the window. Give up if new fonts are loaded, or if point
15947 doesn't appear. */
15948 if (!try_window (window, startp, 0))
15949 rc = SCROLLING_NEED_LARGER_MATRICES;
15950 else if (w->cursor.vpos < 0)
15952 clear_glyph_matrix (w->desired_matrix);
15953 rc = SCROLLING_FAILED;
15955 else
15957 /* Maybe forget recorded base line for line number display. */
15958 if (!just_this_one_p
15959 || current_buffer->clip_changed
15960 || BEG_UNCHANGED < CHARPOS (startp))
15961 w->base_line_number = 0;
15963 /* If cursor ends up on a partially visible line,
15964 treat that as being off the bottom of the screen. */
15965 if (! cursor_row_fully_visible_p (w, extra_scroll_margin_lines <= 1,
15966 false)
15967 /* It's possible that the cursor is on the first line of the
15968 buffer, which is partially obscured due to a vscroll
15969 (Bug#7537). In that case, avoid looping forever. */
15970 && extra_scroll_margin_lines < w->desired_matrix->nrows - 1)
15972 clear_glyph_matrix (w->desired_matrix);
15973 ++extra_scroll_margin_lines;
15974 goto too_near_end;
15976 rc = SCROLLING_SUCCESS;
15979 return rc;
15983 /* Compute a suitable window start for window W if display of W starts
15984 on a continuation line. Value is true if a new window start
15985 was computed.
15987 The new window start will be computed, based on W's width, starting
15988 from the start of the continued line. It is the start of the
15989 screen line with the minimum distance from the old start W->start,
15990 which is still before point (otherwise point will definitely not
15991 be visible in the window). */
15993 static bool
15994 compute_window_start_on_continuation_line (struct window *w)
15996 struct text_pos pos, start_pos, pos_before_pt;
15997 bool window_start_changed_p = false;
15999 SET_TEXT_POS_FROM_MARKER (start_pos, w->start);
16001 /* If window start is on a continuation line... Window start may be
16002 < BEGV in case there's invisible text at the start of the
16003 buffer (M-x rmail, for example). */
16004 if (CHARPOS (start_pos) > BEGV
16005 && FETCH_BYTE (BYTEPOS (start_pos) - 1) != '\n')
16007 struct it it;
16008 struct glyph_row *row;
16010 /* Handle the case that the window start is out of range. */
16011 if (CHARPOS (start_pos) < BEGV)
16012 SET_TEXT_POS (start_pos, BEGV, BEGV_BYTE);
16013 else if (CHARPOS (start_pos) > ZV)
16014 SET_TEXT_POS (start_pos, ZV, ZV_BYTE);
16016 /* Find the start of the continued line. This should be fast
16017 because find_newline is fast (newline cache). */
16018 row = w->desired_matrix->rows + window_wants_header_line (w);
16019 init_iterator (&it, w, CHARPOS (start_pos), BYTEPOS (start_pos),
16020 row, DEFAULT_FACE_ID);
16021 reseat_at_previous_visible_line_start (&it);
16023 /* If the line start is "too far" away from the window start,
16024 say it takes too much time to compute a new window start.
16025 Also, give up if the line start is after point, as in that
16026 case point will not be visible with any window start we
16027 compute. */
16028 if (IT_CHARPOS (it) <= PT
16029 || (CHARPOS (start_pos) - IT_CHARPOS (it)
16030 /* PXW: Do we need upper bounds here? */
16031 < WINDOW_TOTAL_LINES (w) * WINDOW_TOTAL_COLS (w)))
16033 int min_distance, distance;
16035 /* Move forward by display lines to find the new window
16036 start. If window width was enlarged, the new start can
16037 be expected to be > the old start. If window width was
16038 decreased, the new window start will be < the old start.
16039 So, we're looking for the display line start with the
16040 minimum distance from the old window start. */
16041 pos_before_pt = pos = it.current.pos;
16042 min_distance = DISP_INFINITY;
16043 while ((distance = eabs (CHARPOS (start_pos) - IT_CHARPOS (it))),
16044 distance < min_distance)
16046 min_distance = distance;
16047 if (CHARPOS (pos) <= PT)
16048 pos_before_pt = pos;
16049 pos = it.current.pos;
16050 if (it.line_wrap == WORD_WRAP)
16052 /* Under WORD_WRAP, move_it_by_lines is likely to
16053 overshoot and stop not at the first, but the
16054 second character from the left margin. So in
16055 that case, we need a more tight control on the X
16056 coordinate of the iterator than move_it_by_lines
16057 promises in its contract. The method is to first
16058 go to the last (rightmost) visible character of a
16059 line, then move to the leftmost character on the
16060 next line in a separate call. */
16061 move_it_to (&it, ZV, it.last_visible_x, it.current_y, -1,
16062 MOVE_TO_POS | MOVE_TO_X | MOVE_TO_Y);
16063 move_it_to (&it, ZV, 0,
16064 it.current_y + it.max_ascent + it.max_descent, -1,
16065 MOVE_TO_POS | MOVE_TO_X | MOVE_TO_Y);
16067 else
16068 move_it_by_lines (&it, 1);
16071 /* It makes very little sense to make the new window start
16072 after point, as point won't be visible. If that's what
16073 the loop above finds, fall back on the candidate before
16074 or at point that is closest to the old window start. */
16075 if (CHARPOS (pos) > PT)
16076 pos = pos_before_pt;
16078 /* Set the window start there. */
16079 SET_MARKER_FROM_TEXT_POS (w->start, pos);
16080 window_start_changed_p = true;
16084 return window_start_changed_p;
16088 /* Try cursor movement in case text has not changed in window WINDOW,
16089 with window start STARTP. Value is
16091 CURSOR_MOVEMENT_SUCCESS if successful
16093 CURSOR_MOVEMENT_CANNOT_BE_USED if this method cannot be used
16095 CURSOR_MOVEMENT_MUST_SCROLL if we know we have to scroll the
16096 display. *SCROLL_STEP is set to true, under certain circumstances, if
16097 we want to scroll as if scroll-step were set to 1. See the code.
16099 CURSOR_MOVEMENT_NEED_LARGER_MATRICES if we need larger matrices, in
16100 which case we have to abort this redisplay, and adjust matrices
16101 first. */
16103 enum
16105 CURSOR_MOVEMENT_SUCCESS,
16106 CURSOR_MOVEMENT_CANNOT_BE_USED,
16107 CURSOR_MOVEMENT_MUST_SCROLL,
16108 CURSOR_MOVEMENT_NEED_LARGER_MATRICES
16111 static int
16112 try_cursor_movement (Lisp_Object window, struct text_pos startp,
16113 bool *scroll_step)
16115 struct window *w = XWINDOW (window);
16116 struct frame *f = XFRAME (w->frame);
16117 int rc = CURSOR_MOVEMENT_CANNOT_BE_USED;
16119 #ifdef GLYPH_DEBUG
16120 if (inhibit_try_cursor_movement)
16121 return rc;
16122 #endif
16124 /* Previously, there was a check for Lisp integer in the
16125 if-statement below. Now, this field is converted to
16126 ptrdiff_t, thus zero means invalid position in a buffer. */
16127 eassert (w->last_point > 0);
16128 /* Likewise there was a check whether window_end_vpos is nil or larger
16129 than the window. Now window_end_vpos is int and so never nil, but
16130 let's leave eassert to check whether it fits in the window. */
16131 eassert (!w->window_end_valid
16132 || w->window_end_vpos < w->current_matrix->nrows);
16134 /* Handle case where text has not changed, only point, and it has
16135 not moved off the frame. */
16136 if (/* Point may be in this window. */
16137 PT >= CHARPOS (startp)
16138 /* Selective display hasn't changed. */
16139 && !current_buffer->clip_changed
16140 /* Function force-mode-line-update is used to force a thorough
16141 redisplay. It sets either windows_or_buffers_changed or
16142 update_mode_lines. So don't take a shortcut here for these
16143 cases. */
16144 && !update_mode_lines
16145 && !windows_or_buffers_changed
16146 && !f->cursor_type_changed
16147 && NILP (Vshow_trailing_whitespace)
16148 /* When display-line-numbers is in relative mode, moving point
16149 requires to redraw the entire window. */
16150 && !EQ (Vdisplay_line_numbers, Qrelative)
16151 && !EQ (Vdisplay_line_numbers, Qvisual)
16152 /* When the current line number should be displayed in a
16153 distinct face, moving point cannot be handled in optimized
16154 way as below. */
16155 && !(!NILP (Vdisplay_line_numbers)
16156 && NILP (Finternal_lisp_face_equal_p (Qline_number,
16157 Qline_number_current_line,
16158 w->frame)))
16159 /* This code is not used for mini-buffer for the sake of the case
16160 of redisplaying to replace an echo area message; since in
16161 that case the mini-buffer contents per se are usually
16162 unchanged. This code is of no real use in the mini-buffer
16163 since the handling of this_line_start_pos, etc., in redisplay
16164 handles the same cases. */
16165 && !EQ (window, minibuf_window)
16166 /* When overlay arrow is shown in current buffer, point movement
16167 is no longer "simple", as it typically causes the overlay
16168 arrow to move as well. */
16169 && !overlay_arrow_in_current_buffer_p ())
16171 int this_scroll_margin, top_scroll_margin;
16172 struct glyph_row *row = NULL;
16174 #ifdef GLYPH_DEBUG
16175 debug_method_add (w, "cursor movement");
16176 #endif
16178 this_scroll_margin = window_scroll_margin (w, MARGIN_IN_PIXELS);
16180 top_scroll_margin = this_scroll_margin;
16181 if (window_wants_header_line (w))
16182 top_scroll_margin += CURRENT_HEADER_LINE_HEIGHT (w);
16184 /* Start with the row the cursor was displayed during the last
16185 not paused redisplay. Give up if that row is not valid. */
16186 if (w->last_cursor_vpos < 0
16187 || w->last_cursor_vpos >= w->current_matrix->nrows)
16188 rc = CURSOR_MOVEMENT_MUST_SCROLL;
16189 else
16191 row = MATRIX_ROW (w->current_matrix, w->last_cursor_vpos);
16192 if (row->mode_line_p)
16193 ++row;
16194 if (!row->enabled_p)
16195 rc = CURSOR_MOVEMENT_MUST_SCROLL;
16198 if (rc == CURSOR_MOVEMENT_CANNOT_BE_USED)
16200 bool scroll_p = false, must_scroll = false;
16201 int last_y = window_text_bottom_y (w) - this_scroll_margin;
16203 if (PT > w->last_point)
16205 /* Point has moved forward. */
16206 while (MATRIX_ROW_END_CHARPOS (row) < PT
16207 && MATRIX_ROW_BOTTOM_Y (row) < last_y)
16209 eassert (row->enabled_p);
16210 ++row;
16213 /* If the end position of a row equals the start
16214 position of the next row, and PT is at that position,
16215 we would rather display cursor in the next line. */
16216 while (MATRIX_ROW_BOTTOM_Y (row) < last_y
16217 && MATRIX_ROW_END_CHARPOS (row) == PT
16218 && row < MATRIX_MODE_LINE_ROW (w->current_matrix)
16219 && MATRIX_ROW_START_CHARPOS (row+1) == PT
16220 && !cursor_row_p (row))
16221 ++row;
16223 /* If within the scroll margin, scroll. Note that
16224 MATRIX_ROW_BOTTOM_Y gives the pixel position at which
16225 the next line would be drawn, and that
16226 this_scroll_margin can be zero. */
16227 if (MATRIX_ROW_BOTTOM_Y (row) > last_y
16228 || PT > MATRIX_ROW_END_CHARPOS (row)
16229 /* Line is completely visible last line in window
16230 and PT is to be set in the next line. */
16231 || (MATRIX_ROW_BOTTOM_Y (row) == last_y
16232 && PT == MATRIX_ROW_END_CHARPOS (row)
16233 && !row->ends_at_zv_p
16234 && !MATRIX_ROW_ENDS_IN_MIDDLE_OF_CHAR_P (row)))
16235 scroll_p = true;
16237 else if (PT < w->last_point)
16239 /* Cursor has to be moved backward. Note that PT >=
16240 CHARPOS (startp) because of the outer if-statement. */
16241 while (!row->mode_line_p
16242 && (MATRIX_ROW_START_CHARPOS (row) > PT
16243 || (MATRIX_ROW_START_CHARPOS (row) == PT
16244 && (MATRIX_ROW_STARTS_IN_MIDDLE_OF_CHAR_P (row)
16245 || (/* STARTS_IN_MIDDLE_OF_STRING_P (row) */
16246 row > w->current_matrix->rows
16247 && (row-1)->ends_in_newline_from_string_p))))
16248 && (row->y > top_scroll_margin
16249 || CHARPOS (startp) == BEGV))
16251 eassert (row->enabled_p);
16252 --row;
16255 /* Consider the following case: Window starts at BEGV,
16256 there is invisible, intangible text at BEGV, so that
16257 display starts at some point START > BEGV. It can
16258 happen that we are called with PT somewhere between
16259 BEGV and START. Try to handle that case. */
16260 if (row < w->current_matrix->rows
16261 || row->mode_line_p)
16263 row = w->current_matrix->rows;
16264 if (row->mode_line_p)
16265 ++row;
16268 /* Due to newlines in overlay strings, we may have to
16269 skip forward over overlay strings. */
16270 while (MATRIX_ROW_BOTTOM_Y (row) < last_y
16271 && MATRIX_ROW_END_CHARPOS (row) == PT
16272 && !cursor_row_p (row))
16273 ++row;
16275 /* If within the scroll margin, scroll. */
16276 if (row->y < top_scroll_margin
16277 && CHARPOS (startp) != BEGV)
16278 scroll_p = true;
16280 else
16282 /* Cursor did not move. So don't scroll even if cursor line
16283 is partially visible, as it was so before. */
16284 rc = CURSOR_MOVEMENT_SUCCESS;
16287 if (PT < MATRIX_ROW_START_CHARPOS (row)
16288 || PT > MATRIX_ROW_END_CHARPOS (row))
16290 /* if PT is not in the glyph row, give up. */
16291 rc = CURSOR_MOVEMENT_MUST_SCROLL;
16292 must_scroll = true;
16294 else if (rc != CURSOR_MOVEMENT_SUCCESS
16295 && !NILP (BVAR (XBUFFER (w->contents), bidi_display_reordering)))
16297 struct glyph_row *row1;
16299 /* If rows are bidi-reordered and point moved, back up
16300 until we find a row that does not belong to a
16301 continuation line. This is because we must consider
16302 all rows of a continued line as candidates for the
16303 new cursor positioning, since row start and end
16304 positions change non-linearly with vertical position
16305 in such rows. */
16306 /* FIXME: Revisit this when glyph ``spilling'' in
16307 continuation lines' rows is implemented for
16308 bidi-reordered rows. */
16309 for (row1 = MATRIX_FIRST_TEXT_ROW (w->current_matrix);
16310 MATRIX_ROW_CONTINUATION_LINE_P (row);
16311 --row)
16313 /* If we hit the beginning of the displayed portion
16314 without finding the first row of a continued
16315 line, give up. */
16316 if (row <= row1)
16318 rc = CURSOR_MOVEMENT_MUST_SCROLL;
16319 break;
16321 eassert (row->enabled_p);
16324 if (must_scroll)
16326 else if (rc != CURSOR_MOVEMENT_SUCCESS
16327 && MATRIX_ROW_PARTIALLY_VISIBLE_P (w, row)
16328 /* Make sure this isn't a header line by any chance, since
16329 then MATRIX_ROW_PARTIALLY_VISIBLE_P might yield true. */
16330 && !row->mode_line_p
16331 && make_cursor_line_fully_visible_p)
16333 if (PT == MATRIX_ROW_END_CHARPOS (row)
16334 && !row->ends_at_zv_p
16335 && !MATRIX_ROW_ENDS_IN_MIDDLE_OF_CHAR_P (row))
16336 rc = CURSOR_MOVEMENT_MUST_SCROLL;
16337 else if (row->height > window_box_height (w))
16339 /* If we end up in a partially visible line, let's
16340 make it fully visible, except when it's taller
16341 than the window, in which case we can't do much
16342 about it. */
16343 *scroll_step = true;
16344 rc = CURSOR_MOVEMENT_MUST_SCROLL;
16346 else
16348 set_cursor_from_row (w, row, w->current_matrix, 0, 0, 0, 0);
16349 if (!cursor_row_fully_visible_p (w, false, true))
16350 rc = CURSOR_MOVEMENT_MUST_SCROLL;
16351 else
16352 rc = CURSOR_MOVEMENT_SUCCESS;
16355 else if (scroll_p)
16356 rc = CURSOR_MOVEMENT_MUST_SCROLL;
16357 else if (rc != CURSOR_MOVEMENT_SUCCESS
16358 && !NILP (BVAR (XBUFFER (w->contents), bidi_display_reordering)))
16360 /* With bidi-reordered rows, there could be more than
16361 one candidate row whose start and end positions
16362 occlude point. We need to let set_cursor_from_row
16363 find the best candidate. */
16364 /* FIXME: Revisit this when glyph ``spilling'' in
16365 continuation lines' rows is implemented for
16366 bidi-reordered rows. */
16367 bool rv = false;
16371 bool at_zv_p = false, exact_match_p = false;
16373 if (MATRIX_ROW_START_CHARPOS (row) <= PT
16374 && PT <= MATRIX_ROW_END_CHARPOS (row)
16375 && cursor_row_p (row))
16376 rv |= set_cursor_from_row (w, row, w->current_matrix,
16377 0, 0, 0, 0);
16378 /* As soon as we've found the exact match for point,
16379 or the first suitable row whose ends_at_zv_p flag
16380 is set, we are done. */
16381 if (rv)
16383 at_zv_p = MATRIX_ROW (w->current_matrix,
16384 w->cursor.vpos)->ends_at_zv_p;
16385 if (!at_zv_p
16386 && w->cursor.hpos >= 0
16387 && w->cursor.hpos < MATRIX_ROW_USED (w->current_matrix,
16388 w->cursor.vpos))
16390 struct glyph_row *candidate =
16391 MATRIX_ROW (w->current_matrix, w->cursor.vpos);
16392 struct glyph *g =
16393 candidate->glyphs[TEXT_AREA] + w->cursor.hpos;
16394 ptrdiff_t endpos = MATRIX_ROW_END_CHARPOS (candidate);
16396 exact_match_p =
16397 (BUFFERP (g->object) && g->charpos == PT)
16398 || (NILP (g->object)
16399 && (g->charpos == PT
16400 || (g->charpos == 0 && endpos - 1 == PT)));
16402 if (at_zv_p || exact_match_p)
16404 rc = CURSOR_MOVEMENT_SUCCESS;
16405 break;
16408 if (MATRIX_ROW_BOTTOM_Y (row) == last_y)
16409 break;
16410 ++row;
16412 while (((MATRIX_ROW_CONTINUATION_LINE_P (row)
16413 || row->continued_p)
16414 && MATRIX_ROW_BOTTOM_Y (row) <= last_y)
16415 || (MATRIX_ROW_START_CHARPOS (row) == PT
16416 && MATRIX_ROW_BOTTOM_Y (row) < last_y));
16417 /* If we didn't find any candidate rows, or exited the
16418 loop before all the candidates were examined, signal
16419 to the caller that this method failed. */
16420 if (rc != CURSOR_MOVEMENT_SUCCESS
16421 && !(rv
16422 && !MATRIX_ROW_CONTINUATION_LINE_P (row)
16423 && !row->continued_p))
16424 rc = CURSOR_MOVEMENT_MUST_SCROLL;
16425 else if (rv)
16426 rc = CURSOR_MOVEMENT_SUCCESS;
16428 else
16432 if (set_cursor_from_row (w, row, w->current_matrix, 0, 0, 0, 0))
16434 rc = CURSOR_MOVEMENT_SUCCESS;
16435 break;
16437 ++row;
16439 while (MATRIX_ROW_BOTTOM_Y (row) < last_y
16440 && MATRIX_ROW_START_CHARPOS (row) == PT
16441 && cursor_row_p (row));
16446 return rc;
16450 void
16451 set_vertical_scroll_bar (struct window *w)
16453 ptrdiff_t start, end, whole;
16455 /* Calculate the start and end positions for the current window.
16456 At some point, it would be nice to choose between scrollbars
16457 which reflect the whole buffer size, with special markers
16458 indicating narrowing, and scrollbars which reflect only the
16459 visible region.
16461 Note that mini-buffers sometimes aren't displaying any text. */
16462 if (!MINI_WINDOW_P (w)
16463 || (w == XWINDOW (minibuf_window)
16464 && NILP (echo_area_buffer[0])))
16466 struct buffer *buf = XBUFFER (w->contents);
16467 whole = BUF_ZV (buf) - BUF_BEGV (buf);
16468 start = marker_position (w->start) - BUF_BEGV (buf);
16469 /* I don't think this is guaranteed to be right. For the
16470 moment, we'll pretend it is. */
16471 end = BUF_Z (buf) - w->window_end_pos - BUF_BEGV (buf);
16473 if (end < start)
16474 end = start;
16475 if (whole < (end - start))
16476 whole = end - start;
16478 else
16479 start = end = whole = 0;
16481 /* Indicate what this scroll bar ought to be displaying now. */
16482 if (FRAME_TERMINAL (XFRAME (w->frame))->set_vertical_scroll_bar_hook)
16483 (*FRAME_TERMINAL (XFRAME (w->frame))->set_vertical_scroll_bar_hook)
16484 (w, end - start, whole, start);
16488 void
16489 set_horizontal_scroll_bar (struct window *w)
16491 int start, end, whole, portion;
16493 if (!MINI_WINDOW_P (w)
16494 || (w == XWINDOW (minibuf_window)
16495 && NILP (echo_area_buffer[0])))
16497 struct buffer *b = XBUFFER (w->contents);
16498 struct buffer *old_buffer = NULL;
16499 struct it it;
16500 struct text_pos startp;
16502 if (b != current_buffer)
16504 old_buffer = current_buffer;
16505 set_buffer_internal (b);
16508 SET_TEXT_POS_FROM_MARKER (startp, w->start);
16509 start_display (&it, w, startp);
16510 it.last_visible_x = INT_MAX;
16511 whole = move_it_to (&it, -1, INT_MAX, window_box_height (w), -1,
16512 MOVE_TO_X | MOVE_TO_Y);
16513 /* whole = move_it_to (&it, w->window_end_pos, INT_MAX,
16514 window_box_height (w), -1,
16515 MOVE_TO_POS | MOVE_TO_X | MOVE_TO_Y); */
16517 start = w->hscroll * FRAME_COLUMN_WIDTH (WINDOW_XFRAME (w));
16518 end = start + window_box_width (w, TEXT_AREA);
16519 portion = end - start;
16520 /* After enlarging a horizontally scrolled window such that it
16521 gets at least as wide as the text it contains, make sure that
16522 the thumb doesn't fill the entire scroll bar so we can still
16523 drag it back to see the entire text. */
16524 whole = max (whole, end);
16526 if (it.bidi_p)
16528 Lisp_Object pdir;
16530 pdir = Fcurrent_bidi_paragraph_direction (Qnil);
16531 if (EQ (pdir, Qright_to_left))
16533 start = whole - end;
16534 end = start + portion;
16538 if (old_buffer)
16539 set_buffer_internal (old_buffer);
16541 else
16542 start = end = whole = portion = 0;
16544 w->hscroll_whole = whole;
16546 /* Indicate what this scroll bar ought to be displaying now. */
16547 if (FRAME_TERMINAL (XFRAME (w->frame))->set_horizontal_scroll_bar_hook)
16548 (*FRAME_TERMINAL (XFRAME (w->frame))->set_horizontal_scroll_bar_hook)
16549 (w, portion, whole, start);
16553 /* Redisplay leaf window WINDOW. JUST_THIS_ONE_P means only
16554 selected_window is redisplayed.
16556 We can return without actually redisplaying the window if fonts has been
16557 changed on window's frame. In that case, redisplay_internal will retry.
16559 As one of the important parts of redisplaying a window, we need to
16560 decide whether the previous window-start position (stored in the
16561 window's w->start marker position) is still valid, and if it isn't,
16562 recompute it. Some details about that:
16564 . The previous window-start could be in a continuation line, in
16565 which case we need to recompute it when the window width
16566 changes. See compute_window_start_on_continuation_line and its
16567 call below.
16569 . The text that changed since last redisplay could include the
16570 previous window-start position. In that case, we try to salvage
16571 what we can from the current glyph matrix by calling
16572 try_scrolling, which see.
16574 . Some Emacs command could force us to use a specific window-start
16575 position by setting the window's force_start flag, or gently
16576 propose doing that by setting the window's optional_new_start
16577 flag. In these cases, we try using the specified start point if
16578 that succeeds (i.e. the window desired matrix is successfully
16579 recomputed, and point location is within the window). In case
16580 of optional_new_start, we first check if the specified start
16581 position is feasible, i.e. if it will allow point to be
16582 displayed in the window. If using the specified start point
16583 fails, e.g., if new fonts are needed to be loaded, we abort the
16584 redisplay cycle and leave it up to the next cycle to figure out
16585 things.
16587 . Note that the window's force_start flag is sometimes set by
16588 redisplay itself, when it decides that the previous window start
16589 point is fine and should be kept. Search for "goto force_start"
16590 below to see the details. Like the values of window-start
16591 specified outside of redisplay, these internally-deduced values
16592 are tested for feasibility, and ignored if found to be
16593 unfeasible.
16595 . Note that the function try_window, used to completely redisplay
16596 a window, accepts the window's start point as its argument.
16597 This is used several times in the redisplay code to control
16598 where the window start will be, according to user options such
16599 as scroll-conservatively, and also to ensure the screen line
16600 showing point will be fully (as opposed to partially) visible on
16601 display. */
16603 static void
16604 redisplay_window (Lisp_Object window, bool just_this_one_p)
16606 struct window *w = XWINDOW (window);
16607 struct frame *f = XFRAME (w->frame);
16608 struct buffer *buffer = XBUFFER (w->contents);
16609 struct buffer *old = current_buffer;
16610 struct text_pos lpoint, opoint, startp;
16611 bool update_mode_line;
16612 int tem;
16613 struct it it;
16614 /* Record it now because it's overwritten. */
16615 bool current_matrix_up_to_date_p = false;
16616 bool used_current_matrix_p = false;
16617 /* This is less strict than current_matrix_up_to_date_p.
16618 It indicates that the buffer contents and narrowing are unchanged. */
16619 bool buffer_unchanged_p = false;
16620 bool temp_scroll_step = false;
16621 ptrdiff_t count = SPECPDL_INDEX ();
16622 int rc;
16623 int centering_position = -1;
16624 bool last_line_misfit = false;
16625 ptrdiff_t beg_unchanged, end_unchanged;
16626 int frame_line_height, margin;
16627 bool use_desired_matrix;
16628 void *itdata = NULL;
16630 SET_TEXT_POS (lpoint, PT, PT_BYTE);
16631 opoint = lpoint;
16633 #ifdef GLYPH_DEBUG
16634 *w->desired_matrix->method = 0;
16635 #endif
16637 if (!just_this_one_p
16638 && REDISPLAY_SOME_P ()
16639 && !w->redisplay
16640 && !w->update_mode_line
16641 && !f->face_change
16642 && !f->redisplay
16643 && !buffer->text->redisplay
16644 && BUF_PT (buffer) == w->last_point)
16645 return;
16647 /* Make sure that both W's markers are valid. */
16648 eassert (XMARKER (w->start)->buffer == buffer);
16649 eassert (XMARKER (w->pointm)->buffer == buffer);
16651 reconsider_clip_changes (w);
16652 frame_line_height = default_line_pixel_height (w);
16653 margin = window_scroll_margin (w, MARGIN_IN_LINES);
16656 /* Has the mode line to be updated? */
16657 update_mode_line = (w->update_mode_line
16658 || update_mode_lines
16659 || buffer->clip_changed
16660 || buffer->prevent_redisplay_optimizations_p);
16662 if (!just_this_one_p)
16663 /* If `just_this_one_p' is set, we apparently set must_be_updated_p more
16664 cleverly elsewhere. */
16665 w->must_be_updated_p = true;
16667 if (MINI_WINDOW_P (w))
16669 if (w == XWINDOW (echo_area_window)
16670 && !NILP (echo_area_buffer[0]))
16672 if (update_mode_line)
16673 /* We may have to update a tty frame's menu bar or a
16674 tool-bar. Example `M-x C-h C-h C-g'. */
16675 goto finish_menu_bars;
16676 else
16677 /* We've already displayed the echo area glyphs in this window. */
16678 goto finish_scroll_bars;
16680 else if ((w != XWINDOW (minibuf_window)
16681 || minibuf_level == 0)
16682 /* When buffer is nonempty, redisplay window normally. */
16683 && BUF_Z (XBUFFER (w->contents)) == BUF_BEG (XBUFFER (w->contents))
16684 /* Quail displays non-mini buffers in minibuffer window.
16685 In that case, redisplay the window normally. */
16686 && !NILP (Fmemq (w->contents, Vminibuffer_list)))
16688 /* W is a mini-buffer window, but it's not active, so clear
16689 it. */
16690 int yb = window_text_bottom_y (w);
16691 struct glyph_row *row;
16692 int y;
16694 for (y = 0, row = w->desired_matrix->rows;
16695 y < yb;
16696 y += row->height, ++row)
16697 blank_row (w, row, y);
16698 goto finish_scroll_bars;
16701 clear_glyph_matrix (w->desired_matrix);
16704 /* Otherwise set up data on this window; select its buffer and point
16705 value. */
16706 /* Really select the buffer, for the sake of buffer-local
16707 variables. */
16708 set_buffer_internal_1 (XBUFFER (w->contents));
16710 current_matrix_up_to_date_p
16711 = (w->window_end_valid
16712 && !current_buffer->clip_changed
16713 && !current_buffer->prevent_redisplay_optimizations_p
16714 && !window_outdated (w)
16715 && !hscrolling_current_line_p (w));
16717 beg_unchanged = BEG_UNCHANGED;
16718 end_unchanged = END_UNCHANGED;
16720 SET_TEXT_POS (opoint, PT, PT_BYTE);
16722 specbind (Qinhibit_point_motion_hooks, Qt);
16724 buffer_unchanged_p
16725 = (w->window_end_valid
16726 && !current_buffer->clip_changed
16727 && !window_outdated (w));
16729 /* When windows_or_buffers_changed is non-zero, we can't rely
16730 on the window end being valid, so set it to zero there. */
16731 if (windows_or_buffers_changed)
16733 /* If window starts on a continuation line, maybe adjust the
16734 window start in case the window's width changed. */
16735 if (XMARKER (w->start)->buffer == current_buffer)
16736 compute_window_start_on_continuation_line (w);
16738 w->window_end_valid = false;
16739 /* If so, we also can't rely on current matrix
16740 and should not fool try_cursor_movement below. */
16741 current_matrix_up_to_date_p = false;
16744 /* Some sanity checks. */
16745 CHECK_WINDOW_END (w);
16746 if (Z == Z_BYTE && CHARPOS (opoint) != BYTEPOS (opoint))
16747 emacs_abort ();
16748 if (BYTEPOS (opoint) < CHARPOS (opoint))
16749 emacs_abort ();
16751 if (mode_line_update_needed (w))
16752 update_mode_line = true;
16754 /* Point refers normally to the selected window. For any other
16755 window, set up appropriate value. */
16756 if (!EQ (window, selected_window))
16758 ptrdiff_t new_pt = marker_position (w->pointm);
16759 ptrdiff_t new_pt_byte = marker_byte_position (w->pointm);
16761 if (new_pt < BEGV)
16763 new_pt = BEGV;
16764 new_pt_byte = BEGV_BYTE;
16765 set_marker_both (w->pointm, Qnil, BEGV, BEGV_BYTE);
16767 else if (new_pt > (ZV - 1))
16769 new_pt = ZV;
16770 new_pt_byte = ZV_BYTE;
16771 set_marker_both (w->pointm, Qnil, ZV, ZV_BYTE);
16774 /* We don't use SET_PT so that the point-motion hooks don't run. */
16775 TEMP_SET_PT_BOTH (new_pt, new_pt_byte);
16778 /* If any of the character widths specified in the display table
16779 have changed, invalidate the width run cache. It's true that
16780 this may be a bit late to catch such changes, but the rest of
16781 redisplay goes (non-fatally) haywire when the display table is
16782 changed, so why should we worry about doing any better? */
16783 if (current_buffer->width_run_cache
16784 || (current_buffer->base_buffer
16785 && current_buffer->base_buffer->width_run_cache))
16787 struct Lisp_Char_Table *disptab = buffer_display_table ();
16789 if (! disptab_matches_widthtab
16790 (disptab, XVECTOR (BVAR (current_buffer, width_table))))
16792 struct buffer *buf = current_buffer;
16794 if (buf->base_buffer)
16795 buf = buf->base_buffer;
16796 invalidate_region_cache (buf, buf->width_run_cache, BEG, Z);
16797 recompute_width_table (current_buffer, disptab);
16801 /* If window-start is screwed up, choose a new one. */
16802 if (XMARKER (w->start)->buffer != current_buffer)
16803 goto recenter;
16805 SET_TEXT_POS_FROM_MARKER (startp, w->start);
16807 /* If someone specified a new starting point but did not insist,
16808 check whether it can be used. */
16809 if ((w->optional_new_start || window_frozen_p (w))
16810 && CHARPOS (startp) >= BEGV
16811 && CHARPOS (startp) <= ZV)
16813 ptrdiff_t it_charpos;
16815 w->optional_new_start = false;
16816 start_display (&it, w, startp);
16817 move_it_to (&it, PT, 0, it.last_visible_y, -1,
16818 MOVE_TO_POS | MOVE_TO_X | MOVE_TO_Y);
16819 /* Record IT's position now, since line_bottom_y might change
16820 that. */
16821 it_charpos = IT_CHARPOS (it);
16822 /* Make sure we set the force_start flag only if the cursor row
16823 will be fully visible. Otherwise, the code under force_start
16824 label below will try to move point back into view, which is
16825 not what the code which sets optional_new_start wants. */
16826 if ((it.current_y == 0 || line_bottom_y (&it) < it.last_visible_y)
16827 && !w->force_start)
16829 if (it_charpos == PT)
16830 w->force_start = true;
16831 /* IT may overshoot PT if text at PT is invisible. */
16832 else if (it_charpos > PT && CHARPOS (startp) <= PT)
16833 w->force_start = true;
16834 #ifdef GLYPH_DEBUG
16835 if (w->force_start)
16837 if (window_frozen_p (w))
16838 debug_method_add (w, "set force_start from frozen window start");
16839 else
16840 debug_method_add (w, "set force_start from optional_new_start");
16842 #endif
16846 force_start:
16848 /* Handle case where place to start displaying has been specified,
16849 unless the specified location is outside the accessible range. */
16850 if (w->force_start)
16852 /* We set this later on if we have to adjust point. */
16853 int new_vpos = -1;
16855 w->force_start = false;
16856 w->vscroll = 0;
16857 w->window_end_valid = false;
16859 /* Forget any recorded base line for line number display. */
16860 if (!buffer_unchanged_p)
16861 w->base_line_number = 0;
16863 /* Redisplay the mode line. Select the buffer properly for that.
16864 Also, run the hook window-scroll-functions
16865 because we have scrolled. */
16866 /* Note, we do this after clearing force_start because
16867 if there's an error, it is better to forget about force_start
16868 than to get into an infinite loop calling the hook functions
16869 and having them get more errors. */
16870 if (!update_mode_line
16871 || ! NILP (Vwindow_scroll_functions))
16873 update_mode_line = true;
16874 w->update_mode_line = true;
16875 startp = run_window_scroll_functions (window, startp);
16878 if (CHARPOS (startp) < BEGV)
16879 SET_TEXT_POS (startp, BEGV, BEGV_BYTE);
16880 else if (CHARPOS (startp) > ZV)
16881 SET_TEXT_POS (startp, ZV, ZV_BYTE);
16883 /* Redisplay, then check if cursor has been set during the
16884 redisplay. Give up if new fonts were loaded. */
16885 /* We used to issue a CHECK_MARGINS argument to try_window here,
16886 but this causes scrolling to fail when point begins inside
16887 the scroll margin (bug#148) -- cyd */
16888 if (!try_window (window, startp, 0))
16890 w->force_start = true;
16891 clear_glyph_matrix (w->desired_matrix);
16892 goto need_larger_matrices;
16895 if (w->cursor.vpos < 0)
16897 /* If point does not appear, try to move point so it does
16898 appear. The desired matrix has been built above, so we
16899 can use it here. First see if point is in invisible
16900 text, and if so, move it to the first visible buffer
16901 position past that. */
16902 struct glyph_row *r = NULL;
16903 Lisp_Object invprop =
16904 get_char_property_and_overlay (make_number (PT), Qinvisible,
16905 Qnil, NULL);
16907 if (TEXT_PROP_MEANS_INVISIBLE (invprop) != 0)
16909 ptrdiff_t alt_pt;
16910 Lisp_Object invprop_end =
16911 Fnext_single_char_property_change (make_number (PT), Qinvisible,
16912 Qnil, Qnil);
16914 if (NATNUMP (invprop_end))
16915 alt_pt = XFASTINT (invprop_end);
16916 else
16917 alt_pt = ZV;
16918 r = row_containing_pos (w, alt_pt, w->desired_matrix->rows,
16919 NULL, 0);
16921 if (r)
16922 new_vpos = MATRIX_ROW_BOTTOM_Y (r);
16923 else /* Give up and just move to the middle of the window. */
16924 new_vpos = window_box_height (w) / 2;
16927 if (!cursor_row_fully_visible_p (w, false, false))
16929 /* Point does appear, but on a line partly visible at end of window.
16930 Move it back to a fully-visible line. */
16931 new_vpos = window_box_height (w);
16932 /* But if window_box_height suggests a Y coordinate that is
16933 not less than we already have, that line will clearly not
16934 be fully visible, so give up and scroll the display.
16935 This can happen when the default face uses a font whose
16936 dimensions are different from the frame's default
16937 font. */
16938 if (new_vpos >= w->cursor.y)
16940 w->cursor.vpos = -1;
16941 clear_glyph_matrix (w->desired_matrix);
16942 goto try_to_scroll;
16945 else if (w->cursor.vpos >= 0)
16947 /* Some people insist on not letting point enter the scroll
16948 margin, even though this part handles windows that didn't
16949 scroll at all. */
16950 int pixel_margin = margin * frame_line_height;
16951 bool header_line = window_wants_header_line (w);
16953 /* Note: We add an extra FRAME_LINE_HEIGHT, because the loop
16954 below, which finds the row to move point to, advances by
16955 the Y coordinate of the _next_ row, see the definition of
16956 MATRIX_ROW_BOTTOM_Y. */
16957 if (w->cursor.vpos < margin + header_line)
16959 w->cursor.vpos = -1;
16960 clear_glyph_matrix (w->desired_matrix);
16961 goto try_to_scroll;
16963 else
16965 int window_height = window_box_height (w);
16967 if (header_line)
16968 window_height += CURRENT_HEADER_LINE_HEIGHT (w);
16969 if (w->cursor.y >= window_height - pixel_margin)
16971 w->cursor.vpos = -1;
16972 clear_glyph_matrix (w->desired_matrix);
16973 goto try_to_scroll;
16978 /* If we need to move point for either of the above reasons,
16979 now actually do it. */
16980 if (new_vpos >= 0)
16982 struct glyph_row *row;
16984 row = MATRIX_FIRST_TEXT_ROW (w->desired_matrix);
16985 while (MATRIX_ROW_BOTTOM_Y (row) < new_vpos)
16986 ++row;
16988 TEMP_SET_PT_BOTH (MATRIX_ROW_START_CHARPOS (row),
16989 MATRIX_ROW_START_BYTEPOS (row));
16991 if (w != XWINDOW (selected_window))
16992 set_marker_both (w->pointm, Qnil, PT, PT_BYTE);
16993 else if (current_buffer == old)
16994 SET_TEXT_POS (lpoint, PT, PT_BYTE);
16996 set_cursor_from_row (w, row, w->desired_matrix, 0, 0, 0, 0);
16998 /* Re-run pre-redisplay-function so it can update the region
16999 according to the new position of point. */
17000 /* Other than the cursor, w's redisplay is done so we can set its
17001 redisplay to false. Also the buffer's redisplay can be set to
17002 false, since propagate_buffer_redisplay should have already
17003 propagated its info to `w' anyway. */
17004 w->redisplay = false;
17005 XBUFFER (w->contents)->text->redisplay = false;
17006 safe__call1 (true, Vpre_redisplay_function, Fcons (window, Qnil));
17008 if (w->redisplay || XBUFFER (w->contents)->text->redisplay
17009 || ((EQ (Vdisplay_line_numbers, Qrelative)
17010 || EQ (Vdisplay_line_numbers, Qvisual))
17011 && row != MATRIX_FIRST_TEXT_ROW (w->desired_matrix)))
17013 /* Either pre-redisplay-function made changes (e.g. move
17014 the region), or we moved point in a window that is
17015 under display-line-numbers = relative mode. We need
17016 another round of redisplay. */
17017 clear_glyph_matrix (w->desired_matrix);
17018 if (!try_window (window, startp, 0))
17019 goto need_larger_matrices;
17022 if (w->cursor.vpos < 0 || !cursor_row_fully_visible_p (w, false, false))
17024 clear_glyph_matrix (w->desired_matrix);
17025 goto try_to_scroll;
17028 #ifdef GLYPH_DEBUG
17029 debug_method_add (w, "forced window start");
17030 #endif
17031 goto done;
17034 /* Handle case where text has not changed, only point, and it has
17035 not moved off the frame, and we are not retrying after hscroll.
17036 (current_matrix_up_to_date_p is true when retrying.) */
17037 if (current_matrix_up_to_date_p
17038 && (rc = try_cursor_movement (window, startp, &temp_scroll_step),
17039 rc != CURSOR_MOVEMENT_CANNOT_BE_USED))
17041 switch (rc)
17043 case CURSOR_MOVEMENT_SUCCESS:
17044 used_current_matrix_p = true;
17045 goto done;
17047 case CURSOR_MOVEMENT_MUST_SCROLL:
17048 goto try_to_scroll;
17050 default:
17051 emacs_abort ();
17054 /* If current starting point was originally the beginning of a line
17055 but no longer is, find a new starting point. */
17056 else if (w->start_at_line_beg
17057 && !(CHARPOS (startp) <= BEGV
17058 || FETCH_BYTE (BYTEPOS (startp) - 1) == '\n'))
17060 #ifdef GLYPH_DEBUG
17061 debug_method_add (w, "recenter 1");
17062 #endif
17063 goto recenter;
17066 /* Try scrolling with try_window_id. Value is > 0 if update has
17067 been done, it is -1 if we know that the same window start will
17068 not work. It is 0 if unsuccessful for some other reason. */
17069 else if ((tem = try_window_id (w)) != 0)
17071 #ifdef GLYPH_DEBUG
17072 debug_method_add (w, "try_window_id %d", tem);
17073 #endif
17075 if (f->fonts_changed)
17076 goto need_larger_matrices;
17077 if (tem > 0)
17078 goto done;
17080 /* Otherwise try_window_id has returned -1 which means that we
17081 don't want the alternative below this comment to execute. */
17083 else if (CHARPOS (startp) >= BEGV
17084 && CHARPOS (startp) <= ZV
17085 && PT >= CHARPOS (startp)
17086 && (CHARPOS (startp) < ZV
17087 /* Avoid starting at end of buffer. */
17088 || CHARPOS (startp) == BEGV
17089 || !window_outdated (w)))
17091 int d1, d2, d5, d6;
17092 int rtop, rbot;
17094 /* If first window line is a continuation line, and window start
17095 is inside the modified region, but the first change is before
17096 current window start, we must select a new window start.
17098 However, if this is the result of a down-mouse event (e.g. by
17099 extending the mouse-drag-overlay), we don't want to select a
17100 new window start, since that would change the position under
17101 the mouse, resulting in an unwanted mouse-movement rather
17102 than a simple mouse-click. */
17103 if (!w->start_at_line_beg
17104 && NILP (do_mouse_tracking)
17105 && CHARPOS (startp) > BEGV
17106 && CHARPOS (startp) > BEG + beg_unchanged
17107 && CHARPOS (startp) <= Z - end_unchanged
17108 /* Even if w->start_at_line_beg is nil, a new window may
17109 start at a line_beg, since that's how set_buffer_window
17110 sets it. So, we need to check the return value of
17111 compute_window_start_on_continuation_line. (See also
17112 bug#197). */
17113 && XMARKER (w->start)->buffer == current_buffer
17114 && compute_window_start_on_continuation_line (w)
17115 /* It doesn't make sense to force the window start like we
17116 do at label force_start if it is already known that point
17117 will not be fully visible in the resulting window, because
17118 doing so will move point from its correct position
17119 instead of scrolling the window to bring point into view.
17120 See bug#9324. */
17121 && pos_visible_p (w, PT, &d1, &d2, &rtop, &rbot, &d5, &d6)
17122 /* A very tall row could need more than the window height,
17123 in which case we accept that it is partially visible. */
17124 && (rtop != 0) == (rbot != 0))
17126 w->force_start = true;
17127 SET_TEXT_POS_FROM_MARKER (startp, w->start);
17128 #ifdef GLYPH_DEBUG
17129 debug_method_add (w, "recomputed window start in continuation line");
17130 #endif
17131 goto force_start;
17134 #ifdef GLYPH_DEBUG
17135 debug_method_add (w, "same window start");
17136 #endif
17138 /* Try to redisplay starting at same place as before.
17139 If point has not moved off frame, accept the results. */
17140 if (!current_matrix_up_to_date_p
17141 /* Don't use try_window_reusing_current_matrix in this case
17142 because a window scroll function can have changed the
17143 buffer. */
17144 || !NILP (Vwindow_scroll_functions)
17145 || MINI_WINDOW_P (w)
17146 || !(used_current_matrix_p
17147 = try_window_reusing_current_matrix (w)))
17149 IF_DEBUG (debug_method_add (w, "1"));
17150 clear_glyph_matrix (w->desired_matrix);
17151 if (try_window (window, startp, TRY_WINDOW_CHECK_MARGINS) < 0)
17152 /* -1 means we need to scroll.
17153 0 means we need new matrices, but fonts_changed
17154 is set in that case, so we will detect it below. */
17155 goto try_to_scroll;
17158 if (f->fonts_changed)
17159 goto need_larger_matrices;
17161 if (w->cursor.vpos >= 0)
17163 if (!just_this_one_p
17164 || current_buffer->clip_changed
17165 || BEG_UNCHANGED < CHARPOS (startp))
17166 /* Forget any recorded base line for line number display. */
17167 w->base_line_number = 0;
17169 if (!cursor_row_fully_visible_p (w, true, false))
17171 clear_glyph_matrix (w->desired_matrix);
17172 last_line_misfit = true;
17174 /* Drop through and scroll. */
17175 else
17176 goto done;
17178 else
17179 clear_glyph_matrix (w->desired_matrix);
17182 try_to_scroll:
17184 /* Redisplay the mode line. Select the buffer properly for that. */
17185 if (!update_mode_line)
17187 update_mode_line = true;
17188 w->update_mode_line = true;
17191 /* Try to scroll by specified few lines. */
17192 if ((scroll_conservatively
17193 || emacs_scroll_step
17194 || temp_scroll_step
17195 || NUMBERP (BVAR (current_buffer, scroll_up_aggressively))
17196 || NUMBERP (BVAR (current_buffer, scroll_down_aggressively)))
17197 && CHARPOS (startp) >= BEGV
17198 && CHARPOS (startp) <= ZV)
17200 /* The function returns -1 if new fonts were loaded, 1 if
17201 successful, 0 if not successful. */
17202 int ss = try_scrolling (window, just_this_one_p,
17203 scroll_conservatively,
17204 emacs_scroll_step,
17205 temp_scroll_step, last_line_misfit);
17206 switch (ss)
17208 case SCROLLING_SUCCESS:
17209 goto done;
17211 case SCROLLING_NEED_LARGER_MATRICES:
17212 goto need_larger_matrices;
17214 case SCROLLING_FAILED:
17215 break;
17217 default:
17218 emacs_abort ();
17222 /* Finally, just choose a place to start which positions point
17223 according to user preferences. */
17225 recenter:
17227 #ifdef GLYPH_DEBUG
17228 debug_method_add (w, "recenter");
17229 #endif
17231 /* Forget any previously recorded base line for line number display. */
17232 if (!buffer_unchanged_p)
17233 w->base_line_number = 0;
17235 /* Determine the window start relative to point. */
17236 init_iterator (&it, w, PT, PT_BYTE, NULL, DEFAULT_FACE_ID);
17237 it.current_y = it.last_visible_y;
17238 if (centering_position < 0)
17240 ptrdiff_t margin_pos = CHARPOS (startp);
17241 Lisp_Object aggressive;
17242 bool scrolling_up;
17244 /* If there is a scroll margin at the top of the window, find
17245 its character position. */
17246 if (margin
17247 /* Cannot call start_display if startp is not in the
17248 accessible region of the buffer. This can happen when we
17249 have just switched to a different buffer and/or changed
17250 its restriction. In that case, startp is initialized to
17251 the character position 1 (BEGV) because we did not yet
17252 have chance to display the buffer even once. */
17253 && BEGV <= CHARPOS (startp) && CHARPOS (startp) <= ZV)
17255 struct it it1;
17256 void *it1data = NULL;
17258 SAVE_IT (it1, it, it1data);
17259 start_display (&it1, w, startp);
17260 move_it_vertically (&it1, margin * frame_line_height);
17261 margin_pos = IT_CHARPOS (it1);
17262 RESTORE_IT (&it, &it, it1data);
17264 scrolling_up = PT > margin_pos;
17265 aggressive =
17266 scrolling_up
17267 ? BVAR (current_buffer, scroll_up_aggressively)
17268 : BVAR (current_buffer, scroll_down_aggressively);
17270 if (!MINI_WINDOW_P (w)
17271 && (scroll_conservatively > SCROLL_LIMIT || NUMBERP (aggressive)))
17273 int pt_offset = 0;
17275 /* Setting scroll-conservatively overrides
17276 scroll-*-aggressively. */
17277 if (!scroll_conservatively && NUMBERP (aggressive))
17279 double float_amount = XFLOATINT (aggressive);
17281 pt_offset = float_amount * WINDOW_BOX_TEXT_HEIGHT (w);
17282 if (pt_offset == 0 && float_amount > 0)
17283 pt_offset = 1;
17284 if (pt_offset && margin > 0)
17285 margin -= 1;
17287 /* Compute how much to move the window start backward from
17288 point so that point will be displayed where the user
17289 wants it. */
17290 if (scrolling_up)
17292 centering_position = it.last_visible_y;
17293 if (pt_offset)
17294 centering_position -= pt_offset;
17295 centering_position -=
17296 (frame_line_height * (1 + margin + last_line_misfit)
17297 + WINDOW_HEADER_LINE_HEIGHT (w));
17298 /* Don't let point enter the scroll margin near top of
17299 the window. */
17300 if (centering_position < margin * frame_line_height)
17301 centering_position = margin * frame_line_height;
17303 else
17304 centering_position = margin * frame_line_height + pt_offset;
17306 else
17307 /* Set the window start half the height of the window backward
17308 from point. */
17309 centering_position = window_box_height (w) / 2;
17311 move_it_vertically_backward (&it, centering_position);
17313 eassert (IT_CHARPOS (it) >= BEGV);
17315 /* The function move_it_vertically_backward may move over more
17316 than the specified y-distance. If it->w is small, e.g. a
17317 mini-buffer window, we may end up in front of the window's
17318 display area. Start displaying at the start of the line
17319 containing PT in this case. */
17320 if (it.current_y <= 0)
17322 init_iterator (&it, w, PT, PT_BYTE, NULL, DEFAULT_FACE_ID);
17323 move_it_vertically_backward (&it, 0);
17324 it.current_y = 0;
17327 it.current_x = it.hpos = 0;
17329 /* Set the window start position here explicitly, to avoid an
17330 infinite loop in case the functions in window-scroll-functions
17331 get errors. */
17332 set_marker_both (w->start, Qnil, IT_CHARPOS (it), IT_BYTEPOS (it));
17334 /* Run scroll hooks. */
17335 startp = run_window_scroll_functions (window, it.current.pos);
17337 /* We invoke try_window and try_window_reusing_current_matrix below,
17338 and they manipulate the bidi cache. Save and restore the cache
17339 state of our iterator, so we could continue using it after that. */
17340 itdata = bidi_shelve_cache ();
17342 /* Redisplay the window. */
17343 use_desired_matrix = false;
17344 if (!current_matrix_up_to_date_p
17345 || windows_or_buffers_changed
17346 || f->cursor_type_changed
17347 /* Don't use try_window_reusing_current_matrix in this case
17348 because it can have changed the buffer. */
17349 || !NILP (Vwindow_scroll_functions)
17350 || !just_this_one_p
17351 || MINI_WINDOW_P (w)
17352 || !(used_current_matrix_p
17353 = try_window_reusing_current_matrix (w)))
17354 use_desired_matrix = (try_window (window, startp, 0) == 1);
17356 bidi_unshelve_cache (itdata, false);
17358 /* If new fonts have been loaded (due to fontsets), give up. We
17359 have to start a new redisplay since we need to re-adjust glyph
17360 matrices. */
17361 if (f->fonts_changed)
17362 goto need_larger_matrices;
17364 /* If cursor did not appear assume that the middle of the window is
17365 in the first line of the window. Do it again with the next line.
17366 (Imagine a window of height 100, displaying two lines of height
17367 60. Moving back 50 from it->last_visible_y will end in the first
17368 line.) */
17369 if (w->cursor.vpos < 0)
17371 if (w->window_end_valid && PT >= Z - w->window_end_pos)
17373 clear_glyph_matrix (w->desired_matrix);
17374 move_it_by_lines (&it, 1);
17375 try_window (window, it.current.pos, 0);
17377 else if (PT < IT_CHARPOS (it))
17379 clear_glyph_matrix (w->desired_matrix);
17380 move_it_by_lines (&it, -1);
17381 try_window (window, it.current.pos, 0);
17383 else if (scroll_conservatively > SCROLL_LIMIT
17384 && (it.method == GET_FROM_STRING
17385 || overlay_touches_p (IT_CHARPOS (it)))
17386 && IT_CHARPOS (it) < ZV)
17388 /* If the window starts with a before-string that spans more
17389 than one screen line, using that position to display the
17390 window might fail to bring point into the view, because
17391 start_display will always start by displaying the string,
17392 whereas the code above determines where to set w->start
17393 by the buffer position of the place where it takes screen
17394 coordinates. Try to recover by finding the next screen
17395 line that displays buffer text. */
17396 ptrdiff_t pos0 = IT_CHARPOS (it);
17398 clear_glyph_matrix (w->desired_matrix);
17399 do {
17400 move_it_by_lines (&it, 1);
17401 } while (IT_CHARPOS (it) == pos0);
17402 try_window (window, it.current.pos, 0);
17404 else
17406 /* Not much we can do about it. */
17410 /* Consider the following case: Window starts at BEGV, there is
17411 invisible, intangible text at BEGV, so that display starts at
17412 some point START > BEGV. It can happen that we are called with
17413 PT somewhere between BEGV and START. Try to handle that case,
17414 and similar ones. */
17415 if (w->cursor.vpos < 0)
17417 /* Prefer the desired matrix to the current matrix, if possible,
17418 in the fallback calculations below. This is because using
17419 the current matrix might completely goof, e.g. if its first
17420 row is after point. */
17421 struct glyph_matrix *matrix =
17422 use_desired_matrix ? w->desired_matrix : w->current_matrix;
17423 /* First, try locating the proper glyph row for PT. */
17424 struct glyph_row *row =
17425 row_containing_pos (w, PT, matrix->rows, NULL, 0);
17427 /* Sometimes point is at the beginning of invisible text that is
17428 before the 1st character displayed in the row. In that case,
17429 row_containing_pos fails to find the row, because no glyphs
17430 with appropriate buffer positions are present in the row.
17431 Therefore, we next try to find the row which shows the 1st
17432 position after the invisible text. */
17433 if (!row)
17435 Lisp_Object val =
17436 get_char_property_and_overlay (make_number (PT), Qinvisible,
17437 Qnil, NULL);
17439 if (TEXT_PROP_MEANS_INVISIBLE (val) != 0)
17441 ptrdiff_t alt_pos;
17442 Lisp_Object invis_end =
17443 Fnext_single_char_property_change (make_number (PT), Qinvisible,
17444 Qnil, Qnil);
17446 if (NATNUMP (invis_end))
17447 alt_pos = XFASTINT (invis_end);
17448 else
17449 alt_pos = ZV;
17450 row = row_containing_pos (w, alt_pos, matrix->rows, NULL, 0);
17453 /* Finally, fall back on the first row of the window after the
17454 header line (if any). This is slightly better than not
17455 displaying the cursor at all. */
17456 if (!row)
17458 row = matrix->rows;
17459 if (row->mode_line_p)
17460 ++row;
17462 set_cursor_from_row (w, row, matrix, 0, 0, 0, 0);
17465 if (!cursor_row_fully_visible_p (w, false, false))
17467 /* If vscroll is enabled, disable it and try again. */
17468 if (w->vscroll)
17470 w->vscroll = 0;
17471 clear_glyph_matrix (w->desired_matrix);
17472 goto recenter;
17475 /* Users who set scroll-conservatively to a large number want
17476 point just above/below the scroll margin. If we ended up
17477 with point's row partially visible, move the window start to
17478 make that row fully visible and out of the margin. */
17479 if (scroll_conservatively > SCROLL_LIMIT)
17481 int window_total_lines
17482 = WINDOW_TOTAL_LINES (w) * FRAME_LINE_HEIGHT (f) / frame_line_height;
17483 bool move_down = w->cursor.vpos >= window_total_lines / 2;
17485 move_it_by_lines (&it, move_down ? margin + 1 : -(margin + 1));
17486 clear_glyph_matrix (w->desired_matrix);
17487 if (1 == try_window (window, it.current.pos,
17488 TRY_WINDOW_CHECK_MARGINS))
17489 goto done;
17492 /* If centering point failed to make the whole line visible,
17493 put point at the top instead. That has to make the whole line
17494 visible, if it can be done. */
17495 if (centering_position == 0)
17496 goto done;
17498 clear_glyph_matrix (w->desired_matrix);
17499 centering_position = 0;
17500 goto recenter;
17503 done:
17505 SET_TEXT_POS_FROM_MARKER (startp, w->start);
17506 w->start_at_line_beg = (CHARPOS (startp) == BEGV
17507 || FETCH_BYTE (BYTEPOS (startp) - 1) == '\n');
17509 /* Display the mode line, if we must. */
17510 if ((update_mode_line
17511 /* If window not full width, must redo its mode line
17512 if (a) the window to its side is being redone and
17513 (b) we do a frame-based redisplay. This is a consequence
17514 of how inverted lines are drawn in frame-based redisplay. */
17515 || (!just_this_one_p
17516 && !FRAME_WINDOW_P (f)
17517 && !WINDOW_FULL_WIDTH_P (w))
17518 /* Line number to display. */
17519 || w->base_line_pos > 0
17520 /* Column number is displayed and different from the one displayed. */
17521 || (w->column_number_displayed != -1
17522 && (w->column_number_displayed != current_column ())))
17523 /* This means that the window has a mode line. */
17524 && (window_wants_mode_line (w)
17525 || window_wants_header_line (w)))
17528 display_mode_lines (w);
17530 /* If mode line height has changed, arrange for a thorough
17531 immediate redisplay using the correct mode line height. */
17532 if (window_wants_mode_line (w)
17533 && CURRENT_MODE_LINE_HEIGHT (w) != DESIRED_MODE_LINE_HEIGHT (w))
17535 f->fonts_changed = true;
17536 w->mode_line_height = -1;
17537 MATRIX_MODE_LINE_ROW (w->current_matrix)->height
17538 = DESIRED_MODE_LINE_HEIGHT (w);
17541 /* If header line height has changed, arrange for a thorough
17542 immediate redisplay using the correct header line height. */
17543 if (window_wants_header_line (w)
17544 && CURRENT_HEADER_LINE_HEIGHT (w) != DESIRED_HEADER_LINE_HEIGHT (w))
17546 f->fonts_changed = true;
17547 w->header_line_height = -1;
17548 MATRIX_HEADER_LINE_ROW (w->current_matrix)->height
17549 = DESIRED_HEADER_LINE_HEIGHT (w);
17552 if (f->fonts_changed)
17553 goto need_larger_matrices;
17556 if (!line_number_displayed && w->base_line_pos != -1)
17558 w->base_line_pos = 0;
17559 w->base_line_number = 0;
17562 finish_menu_bars:
17564 /* When we reach a frame's selected window, redo the frame's menu
17565 bar and the frame's title. */
17566 if (update_mode_line
17567 && EQ (FRAME_SELECTED_WINDOW (f), window))
17569 bool redisplay_menu_p;
17571 if (FRAME_WINDOW_P (f))
17573 #if defined (USE_X_TOOLKIT) || defined (HAVE_NTGUI) \
17574 || defined (HAVE_NS) || defined (USE_GTK)
17575 redisplay_menu_p = FRAME_EXTERNAL_MENU_BAR (f);
17576 #else
17577 redisplay_menu_p = FRAME_MENU_BAR_LINES (f) > 0;
17578 #endif
17580 else
17581 redisplay_menu_p = FRAME_MENU_BAR_LINES (f) > 0;
17583 if (redisplay_menu_p)
17584 display_menu_bar (w);
17586 #ifdef HAVE_WINDOW_SYSTEM
17587 if (FRAME_WINDOW_P (f))
17589 #if defined (USE_GTK) || defined (HAVE_NS)
17590 if (FRAME_EXTERNAL_TOOL_BAR (f))
17591 redisplay_tool_bar (f);
17592 #else
17593 if (WINDOWP (f->tool_bar_window)
17594 && (FRAME_TOOL_BAR_LINES (f) > 0
17595 || !NILP (Vauto_resize_tool_bars))
17596 && redisplay_tool_bar (f))
17597 ignore_mouse_drag_p = true;
17598 #endif
17600 x_consider_frame_title (w->frame);
17601 #endif
17604 #ifdef HAVE_WINDOW_SYSTEM
17605 if (FRAME_WINDOW_P (f)
17606 && update_window_fringes (w, (just_this_one_p
17607 || (!used_current_matrix_p && !overlay_arrow_seen)
17608 || w->pseudo_window_p)))
17610 update_begin (f);
17611 block_input ();
17612 if (draw_window_fringes (w, true))
17614 if (WINDOW_RIGHT_DIVIDER_WIDTH (w))
17615 x_draw_right_divider (w);
17616 else
17617 x_draw_vertical_border (w);
17619 unblock_input ();
17620 update_end (f);
17623 if (WINDOW_BOTTOM_DIVIDER_WIDTH (w))
17624 x_draw_bottom_divider (w);
17625 #endif /* HAVE_WINDOW_SYSTEM */
17627 /* We go to this label, with fonts_changed set, if it is
17628 necessary to try again using larger glyph matrices.
17629 We have to redeem the scroll bar even in this case,
17630 because the loop in redisplay_internal expects that. */
17631 need_larger_matrices:
17633 finish_scroll_bars:
17635 if (WINDOW_HAS_VERTICAL_SCROLL_BAR (w) || WINDOW_HAS_HORIZONTAL_SCROLL_BAR (w))
17637 if (WINDOW_HAS_VERTICAL_SCROLL_BAR (w))
17638 /* Set the thumb's position and size. */
17639 set_vertical_scroll_bar (w);
17641 if (WINDOW_HAS_HORIZONTAL_SCROLL_BAR (w))
17642 /* Set the thumb's position and size. */
17643 set_horizontal_scroll_bar (w);
17645 /* Note that we actually used the scroll bar attached to this
17646 window, so it shouldn't be deleted at the end of redisplay. */
17647 if (FRAME_TERMINAL (f)->redeem_scroll_bar_hook)
17648 (*FRAME_TERMINAL (f)->redeem_scroll_bar_hook) (w);
17651 /* Restore current_buffer and value of point in it. The window
17652 update may have changed the buffer, so first make sure `opoint'
17653 is still valid (Bug#6177). */
17654 if (CHARPOS (opoint) < BEGV)
17655 TEMP_SET_PT_BOTH (BEGV, BEGV_BYTE);
17656 else if (CHARPOS (opoint) > ZV)
17657 TEMP_SET_PT_BOTH (Z, Z_BYTE);
17658 else
17659 TEMP_SET_PT_BOTH (CHARPOS (opoint), BYTEPOS (opoint));
17661 set_buffer_internal_1 (old);
17662 /* Avoid an abort in TEMP_SET_PT_BOTH if the buffer has become
17663 shorter. This can be caused by log truncation in *Messages*. */
17664 if (CHARPOS (lpoint) <= ZV)
17665 TEMP_SET_PT_BOTH (CHARPOS (lpoint), BYTEPOS (lpoint));
17667 unbind_to (count, Qnil);
17671 /* Build the complete desired matrix of WINDOW with a window start
17672 buffer position POS.
17674 Value is 1 if successful. It is zero if fonts were loaded during
17675 redisplay which makes re-adjusting glyph matrices necessary, and -1
17676 if point would appear in the scroll margins.
17677 (We check the former only if TRY_WINDOW_IGNORE_FONTS_CHANGE is
17678 unset in FLAGS, and the latter only if TRY_WINDOW_CHECK_MARGINS is
17679 set in FLAGS.) */
17682 try_window (Lisp_Object window, struct text_pos pos, int flags)
17684 struct window *w = XWINDOW (window);
17685 struct it it;
17686 struct glyph_row *last_text_row = NULL;
17687 struct frame *f = XFRAME (w->frame);
17688 int cursor_vpos = w->cursor.vpos;
17690 /* Make POS the new window start. */
17691 set_marker_both (w->start, Qnil, CHARPOS (pos), BYTEPOS (pos));
17693 /* Mark cursor position as unknown. No overlay arrow seen. */
17694 w->cursor.vpos = -1;
17695 overlay_arrow_seen = false;
17697 /* Initialize iterator and info to start at POS. */
17698 start_display (&it, w, pos);
17699 it.glyph_row->reversed_p = false;
17701 /* Display all lines of W. */
17702 while (it.current_y < it.last_visible_y)
17704 if (display_line (&it, cursor_vpos))
17705 last_text_row = it.glyph_row - 1;
17706 if (f->fonts_changed && !(flags & TRY_WINDOW_IGNORE_FONTS_CHANGE))
17707 return 0;
17710 /* Save the character position of 'it' before we call
17711 'start_display' again. */
17712 ptrdiff_t it_charpos = IT_CHARPOS (it);
17714 /* Don't let the cursor end in the scroll margins. */
17715 if ((flags & TRY_WINDOW_CHECK_MARGINS)
17716 && !MINI_WINDOW_P (w))
17718 int this_scroll_margin = window_scroll_margin (w, MARGIN_IN_PIXELS);
17719 start_display (&it, w, pos);
17721 if ((w->cursor.y >= 0 /* not vscrolled */
17722 && w->cursor.y < this_scroll_margin
17723 && CHARPOS (pos) > BEGV
17724 && it_charpos < ZV)
17725 /* rms: considering make_cursor_line_fully_visible_p here
17726 seems to give wrong results. We don't want to recenter
17727 when the last line is partly visible, we want to allow
17728 that case to be handled in the usual way. */
17729 || w->cursor.y > (it.last_visible_y - partial_line_height (&it)
17730 - this_scroll_margin - 1))
17732 w->cursor.vpos = -1;
17733 clear_glyph_matrix (w->desired_matrix);
17734 return -1;
17738 /* If bottom moved off end of frame, change mode line percentage. */
17739 if (w->window_end_pos <= 0 && Z != it_charpos)
17740 w->update_mode_line = true;
17742 /* Set window_end_pos to the offset of the last character displayed
17743 on the window from the end of current_buffer. Set
17744 window_end_vpos to its row number. */
17745 if (last_text_row)
17747 eassert (MATRIX_ROW_DISPLAYS_TEXT_P (last_text_row));
17748 adjust_window_ends (w, last_text_row, false);
17749 eassert
17750 (MATRIX_ROW_DISPLAYS_TEXT_P (MATRIX_ROW (w->desired_matrix,
17751 w->window_end_vpos)));
17753 else
17755 w->window_end_bytepos = Z_BYTE - ZV_BYTE;
17756 w->window_end_pos = Z - ZV;
17757 w->window_end_vpos = 0;
17760 /* But that is not valid info until redisplay finishes. */
17761 w->window_end_valid = false;
17762 return 1;
17767 /************************************************************************
17768 Window redisplay reusing current matrix when buffer has not changed
17769 ************************************************************************/
17771 /* Try redisplay of window W showing an unchanged buffer with a
17772 different window start than the last time it was displayed by
17773 reusing its current matrix. Value is true if successful.
17774 W->start is the new window start. */
17776 static bool
17777 try_window_reusing_current_matrix (struct window *w)
17779 struct frame *f = XFRAME (w->frame);
17780 struct glyph_row *bottom_row;
17781 struct it it;
17782 struct run run;
17783 struct text_pos start, new_start;
17784 int nrows_scrolled, i;
17785 struct glyph_row *last_text_row;
17786 struct glyph_row *last_reused_text_row;
17787 struct glyph_row *start_row;
17788 int start_vpos, min_y, max_y;
17790 #ifdef GLYPH_DEBUG
17791 if (inhibit_try_window_reusing)
17792 return false;
17793 #endif
17795 if (/* This function doesn't handle terminal frames. */
17796 !FRAME_WINDOW_P (f)
17797 /* Don't try to reuse the display if windows have been split
17798 or such. */
17799 || windows_or_buffers_changed
17800 || f->cursor_type_changed
17801 /* This function cannot handle buffers where the overlay arrow
17802 is shown on the fringes, because if the arrow position
17803 changes, we cannot just reuse the current matrix. */
17804 || overlay_arrow_in_current_buffer_p ())
17805 return false;
17807 /* Can't do this if showing trailing whitespace. */
17808 if (!NILP (Vshow_trailing_whitespace))
17809 return false;
17811 /* If top-line visibility has changed, give up. */
17812 if (window_wants_header_line (w)
17813 != MATRIX_HEADER_LINE_ROW (w->current_matrix)->mode_line_p)
17814 return false;
17816 /* Give up if old or new display is scrolled vertically. We could
17817 make this function handle this, but right now it doesn't. */
17818 start_row = MATRIX_FIRST_TEXT_ROW (w->current_matrix);
17819 if (w->vscroll || MATRIX_ROW_PARTIALLY_VISIBLE_P (w, start_row))
17820 return false;
17822 /* Clear the desired matrix for the display below. */
17823 clear_glyph_matrix (w->desired_matrix);
17825 /* Give up if line numbers are being displayed, because reusing the
17826 current matrix might use the wrong width for line-number
17827 display. */
17828 if (!NILP (Vdisplay_line_numbers))
17829 return false;
17831 /* The variable new_start now holds the new window start. The old
17832 start `start' can be determined from the current matrix. */
17833 SET_TEXT_POS_FROM_MARKER (new_start, w->start);
17834 start = start_row->minpos;
17835 start_vpos = MATRIX_ROW_VPOS (start_row, w->current_matrix);
17837 if (CHARPOS (new_start) <= CHARPOS (start))
17839 /* Don't use this method if the display starts with an ellipsis
17840 displayed for invisible text. It's not easy to handle that case
17841 below, and it's certainly not worth the effort since this is
17842 not a frequent case. */
17843 if (in_ellipses_for_invisible_text_p (&start_row->start, w))
17844 return false;
17846 IF_DEBUG (debug_method_add (w, "twu1"));
17848 /* Display up to a row that can be reused. The variable
17849 last_text_row is set to the last row displayed that displays
17850 text. Note that it.vpos == 0 if or if not there is a
17851 header-line; it's not the same as the MATRIX_ROW_VPOS! */
17852 start_display (&it, w, new_start);
17853 w->cursor.vpos = -1;
17854 last_text_row = last_reused_text_row = NULL;
17856 while (it.current_y < it.last_visible_y && !f->fonts_changed)
17858 /* If we have reached into the characters in the START row,
17859 that means the line boundaries have changed. So we
17860 can't start copying with the row START. Maybe it will
17861 work to start copying with the following row. */
17862 while (IT_CHARPOS (it) > CHARPOS (start))
17864 /* Advance to the next row as the "start". */
17865 start_row++;
17866 start = start_row->minpos;
17867 /* If there are no more rows to try, or just one, give up. */
17868 if (start_row == MATRIX_MODE_LINE_ROW (w->current_matrix) - 1
17869 || w->vscroll || MATRIX_ROW_PARTIALLY_VISIBLE_P (w, start_row)
17870 || CHARPOS (start) == ZV)
17872 clear_glyph_matrix (w->desired_matrix);
17873 return false;
17876 start_vpos = MATRIX_ROW_VPOS (start_row, w->current_matrix);
17878 /* If we have reached alignment, we can copy the rest of the
17879 rows. */
17880 if (IT_CHARPOS (it) == CHARPOS (start)
17881 /* Don't accept "alignment" inside a display vector,
17882 since start_row could have started in the middle of
17883 that same display vector (thus their character
17884 positions match), and we have no way of telling if
17885 that is the case. */
17886 && it.current.dpvec_index < 0)
17887 break;
17889 it.glyph_row->reversed_p = false;
17890 if (display_line (&it, -1))
17891 last_text_row = it.glyph_row - 1;
17895 /* A value of current_y < last_visible_y means that we stopped
17896 at the previous window start, which in turn means that we
17897 have at least one reusable row. */
17898 if (it.current_y < it.last_visible_y)
17900 struct glyph_row *row;
17902 /* IT.vpos always starts from 0; it counts text lines. */
17903 nrows_scrolled = it.vpos - (start_row - MATRIX_FIRST_TEXT_ROW (w->current_matrix));
17905 /* Find PT if not already found in the lines displayed. */
17906 if (w->cursor.vpos < 0)
17908 int dy = it.current_y - start_row->y;
17910 row = MATRIX_FIRST_TEXT_ROW (w->current_matrix);
17911 row = row_containing_pos (w, PT, row, NULL, dy);
17912 if (row)
17913 set_cursor_from_row (w, row, w->current_matrix, 0, 0,
17914 dy, nrows_scrolled);
17915 else
17917 clear_glyph_matrix (w->desired_matrix);
17918 return false;
17922 /* Scroll the display. Do it before the current matrix is
17923 changed. The problem here is that update has not yet
17924 run, i.e. part of the current matrix is not up to date.
17925 scroll_run_hook will clear the cursor, and use the
17926 current matrix to get the height of the row the cursor is
17927 in. */
17928 run.current_y = start_row->y;
17929 run.desired_y = it.current_y;
17930 run.height = it.last_visible_y - it.current_y;
17932 if (run.height > 0 && run.current_y != run.desired_y)
17934 update_begin (f);
17935 FRAME_RIF (f)->update_window_begin_hook (w);
17936 FRAME_RIF (f)->clear_window_mouse_face (w);
17937 FRAME_RIF (f)->scroll_run_hook (w, &run);
17938 FRAME_RIF (f)->update_window_end_hook (w, false, false);
17939 update_end (f);
17942 /* Shift current matrix down by nrows_scrolled lines. */
17943 bottom_row = MATRIX_BOTTOM_TEXT_ROW (w->current_matrix, w);
17944 rotate_matrix (w->current_matrix,
17945 start_vpos,
17946 MATRIX_ROW_VPOS (bottom_row, w->current_matrix),
17947 nrows_scrolled);
17949 /* Disable lines that must be updated. */
17950 for (i = 0; i < nrows_scrolled; ++i)
17951 (start_row + i)->enabled_p = false;
17953 /* Re-compute Y positions. */
17954 min_y = WINDOW_HEADER_LINE_HEIGHT (w);
17955 max_y = it.last_visible_y;
17956 for (row = start_row + nrows_scrolled;
17957 row < bottom_row;
17958 ++row)
17960 row->y = it.current_y;
17961 row->visible_height = row->height;
17963 if (row->y < min_y)
17964 row->visible_height -= min_y - row->y;
17965 if (row->y + row->height > max_y)
17966 row->visible_height -= row->y + row->height - max_y;
17967 if (row->fringe_bitmap_periodic_p)
17968 row->redraw_fringe_bitmaps_p = true;
17970 it.current_y += row->height;
17972 if (MATRIX_ROW_DISPLAYS_TEXT_P (row))
17973 last_reused_text_row = row;
17974 if (MATRIX_ROW_BOTTOM_Y (row) >= it.last_visible_y)
17975 break;
17978 /* Disable lines in the current matrix which are now
17979 below the window. */
17980 for (++row; row < bottom_row; ++row)
17981 row->enabled_p = row->mode_line_p = false;
17984 /* Update window_end_pos etc.; last_reused_text_row is the last
17985 reused row from the current matrix containing text, if any.
17986 The value of last_text_row is the last displayed line
17987 containing text. */
17988 if (last_reused_text_row)
17989 adjust_window_ends (w, last_reused_text_row, true);
17990 else if (last_text_row)
17991 adjust_window_ends (w, last_text_row, false);
17992 else
17994 /* This window must be completely empty. */
17995 w->window_end_bytepos = Z_BYTE - ZV_BYTE;
17996 w->window_end_pos = Z - ZV;
17997 w->window_end_vpos = 0;
17999 w->window_end_valid = false;
18001 /* Update hint: don't try scrolling again in update_window. */
18002 w->desired_matrix->no_scrolling_p = true;
18004 #ifdef GLYPH_DEBUG
18005 debug_method_add (w, "try_window_reusing_current_matrix 1");
18006 #endif
18007 return true;
18009 else if (CHARPOS (new_start) > CHARPOS (start))
18011 struct glyph_row *pt_row, *row;
18012 struct glyph_row *first_reusable_row;
18013 struct glyph_row *first_row_to_display;
18014 int dy;
18015 int yb = window_text_bottom_y (w);
18017 /* Find the row starting at new_start, if there is one. Don't
18018 reuse a partially visible line at the end. */
18019 first_reusable_row = start_row;
18020 while (first_reusable_row->enabled_p
18021 && MATRIX_ROW_BOTTOM_Y (first_reusable_row) < yb
18022 && (MATRIX_ROW_START_CHARPOS (first_reusable_row)
18023 < CHARPOS (new_start)))
18024 ++first_reusable_row;
18026 /* Give up if there is no row to reuse. */
18027 if (MATRIX_ROW_BOTTOM_Y (first_reusable_row) >= yb
18028 || !first_reusable_row->enabled_p
18029 || (MATRIX_ROW_START_CHARPOS (first_reusable_row)
18030 != CHARPOS (new_start)))
18031 return false;
18033 /* We can reuse fully visible rows beginning with
18034 first_reusable_row to the end of the window. Set
18035 first_row_to_display to the first row that cannot be reused.
18036 Set pt_row to the row containing point, if there is any. */
18037 pt_row = NULL;
18038 for (first_row_to_display = first_reusable_row;
18039 MATRIX_ROW_BOTTOM_Y (first_row_to_display) < yb;
18040 ++first_row_to_display)
18042 if (PT >= MATRIX_ROW_START_CHARPOS (first_row_to_display)
18043 && (PT < MATRIX_ROW_END_CHARPOS (first_row_to_display)
18044 || (PT == MATRIX_ROW_END_CHARPOS (first_row_to_display)
18045 && first_row_to_display->ends_at_zv_p
18046 && pt_row == NULL)))
18047 pt_row = first_row_to_display;
18050 /* Start displaying at the start of first_row_to_display. */
18051 eassert (first_row_to_display->y < yb);
18052 init_to_row_start (&it, w, first_row_to_display);
18054 nrows_scrolled = (MATRIX_ROW_VPOS (first_reusable_row, w->current_matrix)
18055 - start_vpos);
18056 it.vpos = (MATRIX_ROW_VPOS (first_row_to_display, w->current_matrix)
18057 - nrows_scrolled);
18058 it.current_y = (first_row_to_display->y - first_reusable_row->y
18059 + WINDOW_HEADER_LINE_HEIGHT (w));
18061 /* Display lines beginning with first_row_to_display in the
18062 desired matrix. Set last_text_row to the last row displayed
18063 that displays text. */
18064 it.glyph_row = MATRIX_ROW (w->desired_matrix, it.vpos);
18065 if (pt_row == NULL)
18066 w->cursor.vpos = -1;
18067 last_text_row = NULL;
18068 while (it.current_y < it.last_visible_y && !f->fonts_changed)
18069 if (display_line (&it, w->cursor.vpos))
18070 last_text_row = it.glyph_row - 1;
18072 /* If point is in a reused row, adjust y and vpos of the cursor
18073 position. */
18074 if (pt_row)
18076 w->cursor.vpos -= nrows_scrolled;
18077 w->cursor.y -= first_reusable_row->y - start_row->y;
18080 /* Give up if point isn't in a row displayed or reused. (This
18081 also handles the case where w->cursor.vpos < nrows_scrolled
18082 after the calls to display_line, which can happen with scroll
18083 margins. See bug#1295.) */
18084 if (w->cursor.vpos < 0)
18086 clear_glyph_matrix (w->desired_matrix);
18087 return false;
18090 /* Scroll the display. */
18091 run.current_y = first_reusable_row->y;
18092 run.desired_y = WINDOW_HEADER_LINE_HEIGHT (w);
18093 run.height = it.last_visible_y - run.current_y;
18094 dy = run.current_y - run.desired_y;
18096 if (run.height)
18098 update_begin (f);
18099 FRAME_RIF (f)->update_window_begin_hook (w);
18100 FRAME_RIF (f)->clear_window_mouse_face (w);
18101 FRAME_RIF (f)->scroll_run_hook (w, &run);
18102 FRAME_RIF (f)->update_window_end_hook (w, false, false);
18103 update_end (f);
18106 /* Adjust Y positions of reused rows. */
18107 bottom_row = MATRIX_BOTTOM_TEXT_ROW (w->current_matrix, w);
18108 min_y = WINDOW_HEADER_LINE_HEIGHT (w);
18109 max_y = it.last_visible_y;
18110 for (row = first_reusable_row; row < first_row_to_display; ++row)
18112 row->y -= dy;
18113 row->visible_height = row->height;
18114 if (row->y < min_y)
18115 row->visible_height -= min_y - row->y;
18116 if (row->y + row->height > max_y)
18117 row->visible_height -= row->y + row->height - max_y;
18118 if (row->fringe_bitmap_periodic_p)
18119 row->redraw_fringe_bitmaps_p = true;
18122 /* Scroll the current matrix. */
18123 eassert (nrows_scrolled > 0);
18124 rotate_matrix (w->current_matrix,
18125 start_vpos,
18126 MATRIX_ROW_VPOS (bottom_row, w->current_matrix),
18127 -nrows_scrolled);
18129 /* Disable rows not reused. */
18130 for (row -= nrows_scrolled; row < bottom_row; ++row)
18131 row->enabled_p = false;
18133 /* Point may have moved to a different line, so we cannot assume that
18134 the previous cursor position is valid; locate the correct row. */
18135 if (pt_row)
18137 for (row = MATRIX_ROW (w->current_matrix, w->cursor.vpos);
18138 row < bottom_row
18139 && PT >= MATRIX_ROW_END_CHARPOS (row)
18140 && !row->ends_at_zv_p;
18141 row++)
18143 w->cursor.vpos++;
18144 w->cursor.y = row->y;
18146 if (row < bottom_row)
18148 /* Can't simply scan the row for point with
18149 bidi-reordered glyph rows. Let set_cursor_from_row
18150 figure out where to put the cursor, and if it fails,
18151 give up. */
18152 if (!NILP (BVAR (XBUFFER (w->contents), bidi_display_reordering)))
18154 if (!set_cursor_from_row (w, row, w->current_matrix,
18155 0, 0, 0, 0))
18157 clear_glyph_matrix (w->desired_matrix);
18158 return false;
18161 else
18163 struct glyph *glyph = row->glyphs[TEXT_AREA] + w->cursor.hpos;
18164 struct glyph *end = row->glyphs[TEXT_AREA] + row->used[TEXT_AREA];
18166 for (; glyph < end
18167 && (!BUFFERP (glyph->object)
18168 || glyph->charpos < PT);
18169 glyph++)
18171 w->cursor.hpos++;
18172 w->cursor.x += glyph->pixel_width;
18178 /* Adjust window end. A null value of last_text_row means that
18179 the window end is in reused rows which in turn means that
18180 only its vpos can have changed. */
18181 if (last_text_row)
18182 adjust_window_ends (w, last_text_row, false);
18183 else
18184 w->window_end_vpos -= nrows_scrolled;
18186 w->window_end_valid = false;
18187 w->desired_matrix->no_scrolling_p = true;
18189 #ifdef GLYPH_DEBUG
18190 debug_method_add (w, "try_window_reusing_current_matrix 2");
18191 #endif
18192 return true;
18195 return false;
18200 /************************************************************************
18201 Window redisplay reusing current matrix when buffer has changed
18202 ************************************************************************/
18204 static struct glyph_row *find_last_unchanged_at_beg_row (struct window *);
18205 static struct glyph_row *find_first_unchanged_at_end_row (struct window *,
18206 ptrdiff_t *, ptrdiff_t *);
18207 static struct glyph_row *
18208 find_last_row_displaying_text (struct glyph_matrix *, struct it *,
18209 struct glyph_row *);
18212 /* Return the last row in MATRIX displaying text. If row START is
18213 non-null, start searching with that row. IT gives the dimensions
18214 of the display. Value is null if matrix is empty; otherwise it is
18215 a pointer to the row found. */
18217 static struct glyph_row *
18218 find_last_row_displaying_text (struct glyph_matrix *matrix, struct it *it,
18219 struct glyph_row *start)
18221 struct glyph_row *row, *row_found;
18223 /* Set row_found to the last row in IT->w's current matrix
18224 displaying text. The loop looks funny but think of partially
18225 visible lines. */
18226 row_found = NULL;
18227 row = start ? start : MATRIX_FIRST_TEXT_ROW (matrix);
18228 while (MATRIX_ROW_DISPLAYS_TEXT_P (row))
18230 eassert (row->enabled_p);
18231 row_found = row;
18232 if (MATRIX_ROW_BOTTOM_Y (row) >= it->last_visible_y)
18233 break;
18234 ++row;
18237 return row_found;
18241 /* Return the last row in the current matrix of W that is not affected
18242 by changes at the start of current_buffer that occurred since W's
18243 current matrix was built. Value is null if no such row exists.
18245 BEG_UNCHANGED us the number of characters unchanged at the start of
18246 current_buffer. BEG + BEG_UNCHANGED is the buffer position of the
18247 first changed character in current_buffer. Characters at positions <
18248 BEG + BEG_UNCHANGED are at the same buffer positions as they were
18249 when the current matrix was built. */
18251 static struct glyph_row *
18252 find_last_unchanged_at_beg_row (struct window *w)
18254 ptrdiff_t first_changed_pos = BEG + BEG_UNCHANGED;
18255 struct glyph_row *row;
18256 struct glyph_row *row_found = NULL;
18257 int yb = window_text_bottom_y (w);
18259 /* Find the last row displaying unchanged text. */
18260 for (row = MATRIX_FIRST_TEXT_ROW (w->current_matrix);
18261 MATRIX_ROW_DISPLAYS_TEXT_P (row)
18262 && MATRIX_ROW_START_CHARPOS (row) < first_changed_pos;
18263 ++row)
18265 if (/* If row ends before first_changed_pos, it is unchanged,
18266 except in some case. */
18267 MATRIX_ROW_END_CHARPOS (row) <= first_changed_pos
18268 /* When row ends in ZV and we write at ZV it is not
18269 unchanged. */
18270 && !row->ends_at_zv_p
18271 /* When first_changed_pos is the end of a continued line,
18272 row is not unchanged because it may be no longer
18273 continued. */
18274 && !(MATRIX_ROW_END_CHARPOS (row) == first_changed_pos
18275 && (row->continued_p
18276 || row->exact_window_width_line_p))
18277 /* If ROW->end is beyond ZV, then ROW->end is outdated and
18278 needs to be recomputed, so don't consider this row as
18279 unchanged. This happens when the last line was
18280 bidi-reordered and was killed immediately before this
18281 redisplay cycle. In that case, ROW->end stores the
18282 buffer position of the first visual-order character of
18283 the killed text, which is now beyond ZV. */
18284 && CHARPOS (row->end.pos) <= ZV)
18285 row_found = row;
18287 /* Stop if last visible row. */
18288 if (MATRIX_ROW_BOTTOM_Y (row) >= yb)
18289 break;
18292 return row_found;
18296 /* Find the first glyph row in the current matrix of W that is not
18297 affected by changes at the end of current_buffer since the
18298 time W's current matrix was built.
18300 Return in *DELTA the number of chars by which buffer positions in
18301 unchanged text at the end of current_buffer must be adjusted.
18303 Return in *DELTA_BYTES the corresponding number of bytes.
18305 Value is null if no such row exists, i.e. all rows are affected by
18306 changes. */
18308 static struct glyph_row *
18309 find_first_unchanged_at_end_row (struct window *w,
18310 ptrdiff_t *delta, ptrdiff_t *delta_bytes)
18312 struct glyph_row *row;
18313 struct glyph_row *row_found = NULL;
18315 *delta = *delta_bytes = 0;
18317 /* Display must not have been paused, otherwise the current matrix
18318 is not up to date. */
18319 eassert (w->window_end_valid);
18321 /* A value of window_end_pos >= END_UNCHANGED means that the window
18322 end is in the range of changed text. If so, there is no
18323 unchanged row at the end of W's current matrix. */
18324 if (w->window_end_pos >= END_UNCHANGED)
18325 return NULL;
18327 /* Set row to the last row in W's current matrix displaying text. */
18328 row = MATRIX_ROW (w->current_matrix, w->window_end_vpos);
18330 /* If matrix is entirely empty, no unchanged row exists. */
18331 if (MATRIX_ROW_DISPLAYS_TEXT_P (row))
18333 /* The value of row is the last glyph row in the matrix having a
18334 meaningful buffer position in it. The end position of row
18335 corresponds to window_end_pos. This allows us to translate
18336 buffer positions in the current matrix to current buffer
18337 positions for characters not in changed text. */
18338 ptrdiff_t Z_old =
18339 MATRIX_ROW_END_CHARPOS (row) + w->window_end_pos;
18340 ptrdiff_t Z_BYTE_old =
18341 MATRIX_ROW_END_BYTEPOS (row) + w->window_end_bytepos;
18342 ptrdiff_t last_unchanged_pos, last_unchanged_pos_old;
18343 struct glyph_row *first_text_row
18344 = MATRIX_FIRST_TEXT_ROW (w->current_matrix);
18346 *delta = Z - Z_old;
18347 *delta_bytes = Z_BYTE - Z_BYTE_old;
18349 /* Set last_unchanged_pos to the buffer position of the last
18350 character in the buffer that has not been changed. Z is the
18351 index + 1 of the last character in current_buffer, i.e. by
18352 subtracting END_UNCHANGED we get the index of the last
18353 unchanged character, and we have to add BEG to get its buffer
18354 position. */
18355 last_unchanged_pos = Z - END_UNCHANGED + BEG;
18356 last_unchanged_pos_old = last_unchanged_pos - *delta;
18358 /* Search backward from ROW for a row displaying a line that
18359 starts at a minimum position >= last_unchanged_pos_old. */
18360 for (; row > first_text_row; --row)
18362 /* This used to abort, but it can happen.
18363 It is ok to just stop the search instead here. KFS. */
18364 if (!row->enabled_p || !MATRIX_ROW_DISPLAYS_TEXT_P (row))
18365 break;
18367 if (MATRIX_ROW_START_CHARPOS (row) >= last_unchanged_pos_old)
18368 row_found = row;
18372 eassert (!row_found || MATRIX_ROW_DISPLAYS_TEXT_P (row_found));
18374 return row_found;
18378 /* Make sure that glyph rows in the current matrix of window W
18379 reference the same glyph memory as corresponding rows in the
18380 frame's frame matrix. This function is called after scrolling W's
18381 current matrix on a terminal frame in try_window_id and
18382 try_window_reusing_current_matrix. */
18384 static void
18385 sync_frame_with_window_matrix_rows (struct window *w)
18387 struct frame *f = XFRAME (w->frame);
18388 struct glyph_row *window_row, *window_row_end, *frame_row;
18390 /* Preconditions: W must be a leaf window and full-width. Its frame
18391 must have a frame matrix. */
18392 eassert (BUFFERP (w->contents));
18393 eassert (WINDOW_FULL_WIDTH_P (w));
18394 eassert (!FRAME_WINDOW_P (f));
18396 /* If W is a full-width window, glyph pointers in W's current matrix
18397 have, by definition, to be the same as glyph pointers in the
18398 corresponding frame matrix. Note that frame matrices have no
18399 marginal areas (see build_frame_matrix). */
18400 window_row = w->current_matrix->rows;
18401 window_row_end = window_row + w->current_matrix->nrows;
18402 frame_row = f->current_matrix->rows + WINDOW_TOP_EDGE_LINE (w);
18403 while (window_row < window_row_end)
18405 struct glyph *start = window_row->glyphs[LEFT_MARGIN_AREA];
18406 struct glyph *end = window_row->glyphs[LAST_AREA];
18408 frame_row->glyphs[LEFT_MARGIN_AREA] = start;
18409 frame_row->glyphs[TEXT_AREA] = start;
18410 frame_row->glyphs[RIGHT_MARGIN_AREA] = end;
18411 frame_row->glyphs[LAST_AREA] = end;
18413 /* Disable frame rows whose corresponding window rows have
18414 been disabled in try_window_id. */
18415 if (!window_row->enabled_p)
18416 frame_row->enabled_p = false;
18418 ++window_row, ++frame_row;
18423 /* Find the glyph row in window W containing CHARPOS. Consider all
18424 rows between START and END (not inclusive). END null means search
18425 all rows to the end of the display area of W. Value is the row
18426 containing CHARPOS or null. */
18428 struct glyph_row *
18429 row_containing_pos (struct window *w, ptrdiff_t charpos,
18430 struct glyph_row *start, struct glyph_row *end, int dy)
18432 struct glyph_row *row = start;
18433 struct glyph_row *best_row = NULL;
18434 ptrdiff_t mindif = BUF_ZV (XBUFFER (w->contents)) + 1;
18435 int last_y;
18437 /* If we happen to start on a header-line, skip that. */
18438 if (row->mode_line_p)
18439 ++row;
18441 if ((end && row >= end) || !row->enabled_p)
18442 return NULL;
18444 last_y = window_text_bottom_y (w) - dy;
18446 while (true)
18448 /* Give up if we have gone too far. */
18449 if ((end && row >= end) || !row->enabled_p)
18450 return NULL;
18451 /* This formerly returned if they were equal.
18452 I think that both quantities are of a "last plus one" type;
18453 if so, when they are equal, the row is within the screen. -- rms. */
18454 if (MATRIX_ROW_BOTTOM_Y (row) > last_y)
18455 return NULL;
18457 /* If it is in this row, return this row. */
18458 if (! (MATRIX_ROW_END_CHARPOS (row) < charpos
18459 || (MATRIX_ROW_END_CHARPOS (row) == charpos
18460 /* The end position of a row equals the start
18461 position of the next row. If CHARPOS is there, we
18462 would rather consider it displayed in the next
18463 line, except when this line ends in ZV. */
18464 && !row_for_charpos_p (row, charpos)))
18465 && charpos >= MATRIX_ROW_START_CHARPOS (row))
18467 struct glyph *g;
18469 if (NILP (BVAR (XBUFFER (w->contents), bidi_display_reordering))
18470 || (!best_row && !row->continued_p))
18471 return row;
18472 /* In bidi-reordered rows, there could be several rows whose
18473 edges surround CHARPOS, all of these rows belonging to
18474 the same continued line. We need to find the row which
18475 fits CHARPOS the best. */
18476 for (g = row->glyphs[TEXT_AREA];
18477 g < row->glyphs[TEXT_AREA] + row->used[TEXT_AREA];
18478 g++)
18480 if (!STRINGP (g->object))
18482 if (g->charpos > 0 && eabs (g->charpos - charpos) < mindif)
18484 mindif = eabs (g->charpos - charpos);
18485 best_row = row;
18486 /* Exact match always wins. */
18487 if (mindif == 0)
18488 return best_row;
18493 else if (best_row && !row->continued_p)
18494 return best_row;
18495 ++row;
18500 /* Try to redisplay window W by reusing its existing display. W's
18501 current matrix must be up to date when this function is called,
18502 i.e., window_end_valid must be true.
18504 Value is
18506 >= 1 if successful, i.e. display has been updated
18507 specifically:
18508 1 means the changes were in front of a newline that precedes
18509 the window start, and the whole current matrix was reused
18510 2 means the changes were after the last position displayed
18511 in the window, and the whole current matrix was reused
18512 3 means portions of the current matrix were reused, while
18513 some of the screen lines were redrawn
18514 -1 if redisplay with same window start is known not to succeed
18515 0 if otherwise unsuccessful
18517 The following steps are performed:
18519 1. Find the last row in the current matrix of W that is not
18520 affected by changes at the start of current_buffer. If no such row
18521 is found, give up.
18523 2. Find the first row in W's current matrix that is not affected by
18524 changes at the end of current_buffer. Maybe there is no such row.
18526 3. Display lines beginning with the row + 1 found in step 1 to the
18527 row found in step 2 or, if step 2 didn't find a row, to the end of
18528 the window.
18530 4. If cursor is not known to appear on the window, give up.
18532 5. If display stopped at the row found in step 2, scroll the
18533 display and current matrix as needed.
18535 6. Maybe display some lines at the end of W, if we must. This can
18536 happen under various circumstances, like a partially visible line
18537 becoming fully visible, or because newly displayed lines are displayed
18538 in smaller font sizes.
18540 7. Update W's window end information. */
18542 static int
18543 try_window_id (struct window *w)
18545 struct frame *f = XFRAME (w->frame);
18546 struct glyph_matrix *current_matrix = w->current_matrix;
18547 struct glyph_matrix *desired_matrix = w->desired_matrix;
18548 struct glyph_row *last_unchanged_at_beg_row;
18549 struct glyph_row *first_unchanged_at_end_row;
18550 struct glyph_row *row;
18551 struct glyph_row *bottom_row;
18552 int bottom_vpos;
18553 struct it it;
18554 ptrdiff_t delta = 0, delta_bytes = 0, stop_pos;
18555 int dvpos, dy;
18556 struct text_pos start_pos;
18557 struct run run;
18558 int first_unchanged_at_end_vpos = 0;
18559 struct glyph_row *last_text_row, *last_text_row_at_end;
18560 struct text_pos start;
18561 ptrdiff_t first_changed_charpos, last_changed_charpos;
18563 #ifdef GLYPH_DEBUG
18564 if (inhibit_try_window_id)
18565 return 0;
18566 #endif
18568 /* This is handy for debugging. */
18569 #if false
18570 #define GIVE_UP(X) \
18571 do { \
18572 TRACE ((stderr, "try_window_id give up %d\n", (X))); \
18573 return 0; \
18574 } while (false)
18575 #else
18576 #define GIVE_UP(X) return 0
18577 #endif
18579 SET_TEXT_POS_FROM_MARKER (start, w->start);
18581 /* Don't use this for mini-windows because these can show
18582 messages and mini-buffers, and we don't handle that here. */
18583 if (MINI_WINDOW_P (w))
18584 GIVE_UP (1);
18586 /* This flag is used to prevent redisplay optimizations. */
18587 if (windows_or_buffers_changed || f->cursor_type_changed)
18588 GIVE_UP (2);
18590 /* This function's optimizations cannot be used if overlays have
18591 changed in the buffer displayed by the window, so give up if they
18592 have. */
18593 if (w->last_overlay_modified != OVERLAY_MODIFF)
18594 GIVE_UP (200);
18596 /* Verify that narrowing has not changed.
18597 Also verify that we were not told to prevent redisplay optimizations.
18598 It would be nice to further
18599 reduce the number of cases where this prevents try_window_id. */
18600 if (current_buffer->clip_changed
18601 || current_buffer->prevent_redisplay_optimizations_p)
18602 GIVE_UP (3);
18604 /* Window must either use window-based redisplay or be full width. */
18605 if (!FRAME_WINDOW_P (f)
18606 && (!FRAME_LINE_INS_DEL_OK (f)
18607 || !WINDOW_FULL_WIDTH_P (w)))
18608 GIVE_UP (4);
18610 /* Give up if point is known NOT to appear in W. */
18611 if (PT < CHARPOS (start))
18612 GIVE_UP (5);
18614 /* Another way to prevent redisplay optimizations. */
18615 if (w->last_modified == 0)
18616 GIVE_UP (6);
18618 /* Verify that window is not hscrolled. */
18619 if (w->hscroll != 0)
18620 GIVE_UP (7);
18622 /* Verify that display wasn't paused. */
18623 if (!w->window_end_valid)
18624 GIVE_UP (8);
18626 /* Likewise if highlighting trailing whitespace. */
18627 if (!NILP (Vshow_trailing_whitespace))
18628 GIVE_UP (11);
18630 /* Can't use this if overlay arrow position and/or string have
18631 changed. */
18632 if (overlay_arrows_changed_p (false))
18633 GIVE_UP (12);
18635 /* When word-wrap is on, adding a space to the first word of a
18636 wrapped line can change the wrap position, altering the line
18637 above it. It might be worthwhile to handle this more
18638 intelligently, but for now just redisplay from scratch. */
18639 if (!NILP (BVAR (XBUFFER (w->contents), word_wrap)))
18640 GIVE_UP (21);
18642 /* Under bidi reordering, adding or deleting a character in the
18643 beginning of a paragraph, before the first strong directional
18644 character, can change the base direction of the paragraph (unless
18645 the buffer specifies a fixed paragraph direction), which will
18646 require redisplaying the whole paragraph. It might be worthwhile
18647 to find the paragraph limits and widen the range of redisplayed
18648 lines to that, but for now just give up this optimization and
18649 redisplay from scratch. */
18650 if (!NILP (BVAR (XBUFFER (w->contents), bidi_display_reordering))
18651 && NILP (BVAR (XBUFFER (w->contents), bidi_paragraph_direction)))
18652 GIVE_UP (22);
18654 /* Give up if the buffer has line-spacing set, as Lisp-level changes
18655 to that variable require thorough redisplay. */
18656 if (!NILP (BVAR (XBUFFER (w->contents), extra_line_spacing)))
18657 GIVE_UP (23);
18659 /* Give up if display-line-numbers is in relative mode, or when the
18660 current line's number needs to be displayed in a distinct face. */
18661 if (EQ (Vdisplay_line_numbers, Qrelative)
18662 || EQ (Vdisplay_line_numbers, Qvisual)
18663 || (!NILP (Vdisplay_line_numbers)
18664 && NILP (Finternal_lisp_face_equal_p (Qline_number,
18665 Qline_number_current_line,
18666 w->frame))))
18667 GIVE_UP (24);
18669 /* Make sure beg_unchanged and end_unchanged are up to date. Do it
18670 only if buffer has really changed. The reason is that the gap is
18671 initially at Z for freshly visited files. The code below would
18672 set end_unchanged to 0 in that case. */
18673 if (MODIFF > SAVE_MODIFF
18674 /* This seems to happen sometimes after saving a buffer. */
18675 || BEG_UNCHANGED + END_UNCHANGED > Z_BYTE)
18677 if (GPT - BEG < BEG_UNCHANGED)
18678 BEG_UNCHANGED = GPT - BEG;
18679 if (Z - GPT < END_UNCHANGED)
18680 END_UNCHANGED = Z - GPT;
18683 /* The position of the first and last character that has been changed. */
18684 first_changed_charpos = BEG + BEG_UNCHANGED;
18685 last_changed_charpos = Z - END_UNCHANGED;
18687 /* If window starts after a line end, and the last change is in
18688 front of that newline, then changes don't affect the display.
18689 This case happens with stealth-fontification. Note that although
18690 the display is unchanged, glyph positions in the matrix have to
18691 be adjusted, of course. */
18692 row = MATRIX_ROW (w->current_matrix, w->window_end_vpos);
18693 if (MATRIX_ROW_DISPLAYS_TEXT_P (row)
18694 && ((last_changed_charpos < CHARPOS (start)
18695 && CHARPOS (start) == BEGV)
18696 || (last_changed_charpos < CHARPOS (start) - 1
18697 && FETCH_BYTE (BYTEPOS (start) - 1) == '\n')))
18699 ptrdiff_t Z_old, Z_delta, Z_BYTE_old, Z_delta_bytes;
18700 struct glyph_row *r0;
18702 /* Compute how many chars/bytes have been added to or removed
18703 from the buffer. */
18704 Z_old = MATRIX_ROW_END_CHARPOS (row) + w->window_end_pos;
18705 Z_BYTE_old = MATRIX_ROW_END_BYTEPOS (row) + w->window_end_bytepos;
18706 Z_delta = Z - Z_old;
18707 Z_delta_bytes = Z_BYTE - Z_BYTE_old;
18709 /* Give up if PT is not in the window. Note that it already has
18710 been checked at the start of try_window_id that PT is not in
18711 front of the window start. */
18712 if (PT >= MATRIX_ROW_END_CHARPOS (row) + Z_delta)
18713 GIVE_UP (13);
18715 /* If window start is unchanged, we can reuse the whole matrix
18716 as is, after adjusting glyph positions. No need to compute
18717 the window end again, since its offset from Z hasn't changed. */
18718 r0 = MATRIX_FIRST_TEXT_ROW (current_matrix);
18719 if (CHARPOS (start) == MATRIX_ROW_START_CHARPOS (r0) + Z_delta
18720 && BYTEPOS (start) == MATRIX_ROW_START_BYTEPOS (r0) + Z_delta_bytes
18721 /* PT must not be in a partially visible line. */
18722 && !(PT >= MATRIX_ROW_START_CHARPOS (row) + Z_delta
18723 && MATRIX_ROW_BOTTOM_Y (row) > window_text_bottom_y (w)))
18725 /* Adjust positions in the glyph matrix. */
18726 if (Z_delta || Z_delta_bytes)
18728 struct glyph_row *r1
18729 = MATRIX_BOTTOM_TEXT_ROW (current_matrix, w);
18730 increment_matrix_positions (w->current_matrix,
18731 MATRIX_ROW_VPOS (r0, current_matrix),
18732 MATRIX_ROW_VPOS (r1, current_matrix),
18733 Z_delta, Z_delta_bytes);
18736 /* Set the cursor. */
18737 row = row_containing_pos (w, PT, r0, NULL, 0);
18738 if (row)
18739 set_cursor_from_row (w, row, current_matrix, 0, 0, 0, 0);
18740 return 1;
18744 /* Handle the case that changes are all below what is displayed in
18745 the window, and that PT is in the window. This shortcut cannot
18746 be taken if ZV is visible in the window, and text has been added
18747 there that is visible in the window. */
18748 if (first_changed_charpos >= MATRIX_ROW_END_CHARPOS (row)
18749 /* ZV is not visible in the window, or there are no
18750 changes at ZV, actually. */
18751 && (current_matrix->zv > MATRIX_ROW_END_CHARPOS (row)
18752 || first_changed_charpos == last_changed_charpos))
18754 struct glyph_row *r0;
18756 /* Give up if PT is not in the window. Note that it already has
18757 been checked at the start of try_window_id that PT is not in
18758 front of the window start. */
18759 if (PT >= MATRIX_ROW_END_CHARPOS (row))
18760 GIVE_UP (14);
18762 /* If window start is unchanged, we can reuse the whole matrix
18763 as is, without changing glyph positions since no text has
18764 been added/removed in front of the window end. */
18765 r0 = MATRIX_FIRST_TEXT_ROW (current_matrix);
18766 if (TEXT_POS_EQUAL_P (start, r0->minpos)
18767 /* PT must not be in a partially visible line. */
18768 && !(PT >= MATRIX_ROW_START_CHARPOS (row)
18769 && MATRIX_ROW_BOTTOM_Y (row) > window_text_bottom_y (w)))
18771 /* We have to compute the window end anew since text
18772 could have been added/removed after it. */
18773 w->window_end_pos = Z - MATRIX_ROW_END_CHARPOS (row);
18774 w->window_end_bytepos = Z_BYTE - MATRIX_ROW_END_BYTEPOS (row);
18776 /* Set the cursor. */
18777 row = row_containing_pos (w, PT, r0, NULL, 0);
18778 if (row)
18779 set_cursor_from_row (w, row, current_matrix, 0, 0, 0, 0);
18780 return 2;
18784 /* Give up if window start is in the changed area.
18786 The condition used to read
18788 (BEG_UNCHANGED + END_UNCHANGED != Z - BEG && ...)
18790 but why that was tested escapes me at the moment. */
18791 if (CHARPOS (start) >= first_changed_charpos
18792 && CHARPOS (start) <= last_changed_charpos)
18793 GIVE_UP (15);
18795 /* Check that window start agrees with the start of the first glyph
18796 row in its current matrix. Check this after we know the window
18797 start is not in changed text, otherwise positions would not be
18798 comparable. */
18799 row = MATRIX_FIRST_TEXT_ROW (current_matrix);
18800 if (!TEXT_POS_EQUAL_P (start, row->minpos))
18801 GIVE_UP (16);
18803 /* Give up if the window ends in strings. Overlay strings
18804 at the end are difficult to handle, so don't try. */
18805 row = MATRIX_ROW (current_matrix, w->window_end_vpos);
18806 if (MATRIX_ROW_START_CHARPOS (row) == MATRIX_ROW_END_CHARPOS (row))
18807 GIVE_UP (20);
18809 /* Compute the position at which we have to start displaying new
18810 lines. Some of the lines at the top of the window might be
18811 reusable because they are not displaying changed text. Find the
18812 last row in W's current matrix not affected by changes at the
18813 start of current_buffer. Value is null if changes start in the
18814 first line of window. */
18815 last_unchanged_at_beg_row = find_last_unchanged_at_beg_row (w);
18816 if (last_unchanged_at_beg_row)
18818 /* Avoid starting to display in the middle of a character, a TAB
18819 for instance. This is easier than to set up the iterator
18820 exactly, and it's not a frequent case, so the additional
18821 effort wouldn't really pay off. */
18822 while ((MATRIX_ROW_ENDS_IN_MIDDLE_OF_CHAR_P (last_unchanged_at_beg_row)
18823 || last_unchanged_at_beg_row->ends_in_newline_from_string_p)
18824 && last_unchanged_at_beg_row > w->current_matrix->rows)
18825 --last_unchanged_at_beg_row;
18827 if (MATRIX_ROW_ENDS_IN_MIDDLE_OF_CHAR_P (last_unchanged_at_beg_row))
18828 GIVE_UP (17);
18830 if (! init_to_row_end (&it, w, last_unchanged_at_beg_row))
18831 GIVE_UP (18);
18832 start_pos = it.current.pos;
18834 /* Start displaying new lines in the desired matrix at the same
18835 vpos we would use in the current matrix, i.e. below
18836 last_unchanged_at_beg_row. */
18837 it.vpos = 1 + MATRIX_ROW_VPOS (last_unchanged_at_beg_row,
18838 current_matrix);
18839 it.glyph_row = MATRIX_ROW (desired_matrix, it.vpos);
18840 it.current_y = MATRIX_ROW_BOTTOM_Y (last_unchanged_at_beg_row);
18842 eassert (it.hpos == 0 && it.current_x == 0);
18844 else
18846 /* There are no reusable lines at the start of the window.
18847 Start displaying in the first text line. */
18848 start_display (&it, w, start);
18849 it.vpos = it.first_vpos;
18850 start_pos = it.current.pos;
18853 /* Find the first row that is not affected by changes at the end of
18854 the buffer. Value will be null if there is no unchanged row, in
18855 which case we must redisplay to the end of the window. delta
18856 will be set to the value by which buffer positions beginning with
18857 first_unchanged_at_end_row have to be adjusted due to text
18858 changes. */
18859 first_unchanged_at_end_row
18860 = find_first_unchanged_at_end_row (w, &delta, &delta_bytes);
18861 IF_DEBUG (debug_delta = delta);
18862 IF_DEBUG (debug_delta_bytes = delta_bytes);
18864 /* Set stop_pos to the buffer position up to which we will have to
18865 display new lines. If first_unchanged_at_end_row != NULL, this
18866 is the buffer position of the start of the line displayed in that
18867 row. For first_unchanged_at_end_row == NULL, use 0 to indicate
18868 that we don't stop at a buffer position. */
18869 stop_pos = 0;
18870 if (first_unchanged_at_end_row)
18872 eassert (last_unchanged_at_beg_row == NULL
18873 || first_unchanged_at_end_row >= last_unchanged_at_beg_row);
18875 /* If this is a continuation line, move forward to the next one
18876 that isn't. Changes in lines above affect this line.
18877 Caution: this may move first_unchanged_at_end_row to a row
18878 not displaying text. */
18879 while (MATRIX_ROW_CONTINUATION_LINE_P (first_unchanged_at_end_row)
18880 && MATRIX_ROW_DISPLAYS_TEXT_P (first_unchanged_at_end_row)
18881 && (MATRIX_ROW_BOTTOM_Y (first_unchanged_at_end_row)
18882 < it.last_visible_y))
18883 ++first_unchanged_at_end_row;
18885 if (!MATRIX_ROW_DISPLAYS_TEXT_P (first_unchanged_at_end_row)
18886 || (MATRIX_ROW_BOTTOM_Y (first_unchanged_at_end_row)
18887 >= it.last_visible_y))
18888 first_unchanged_at_end_row = NULL;
18889 else
18891 stop_pos = (MATRIX_ROW_START_CHARPOS (first_unchanged_at_end_row)
18892 + delta);
18893 first_unchanged_at_end_vpos
18894 = MATRIX_ROW_VPOS (first_unchanged_at_end_row, current_matrix);
18895 eassert (stop_pos >= Z - END_UNCHANGED);
18898 else if (last_unchanged_at_beg_row == NULL)
18899 GIVE_UP (19);
18902 #ifdef GLYPH_DEBUG
18904 /* Either there is no unchanged row at the end, or the one we have
18905 now displays text. This is a necessary condition for the window
18906 end pos calculation at the end of this function. */
18907 eassert (first_unchanged_at_end_row == NULL
18908 || MATRIX_ROW_DISPLAYS_TEXT_P (first_unchanged_at_end_row));
18910 debug_last_unchanged_at_beg_vpos
18911 = (last_unchanged_at_beg_row
18912 ? MATRIX_ROW_VPOS (last_unchanged_at_beg_row, current_matrix)
18913 : -1);
18914 debug_first_unchanged_at_end_vpos = first_unchanged_at_end_vpos;
18916 #endif /* GLYPH_DEBUG */
18919 /* Display new lines. Set last_text_row to the last new line
18920 displayed which has text on it, i.e. might end up as being the
18921 line where the window_end_vpos is. */
18922 w->cursor.vpos = -1;
18923 last_text_row = NULL;
18924 overlay_arrow_seen = false;
18925 if (it.current_y < it.last_visible_y
18926 && !f->fonts_changed
18927 && (first_unchanged_at_end_row == NULL
18928 || IT_CHARPOS (it) < stop_pos))
18929 it.glyph_row->reversed_p = false;
18930 while (it.current_y < it.last_visible_y
18931 && !f->fonts_changed
18932 && (first_unchanged_at_end_row == NULL
18933 || IT_CHARPOS (it) < stop_pos))
18935 if (display_line (&it, -1))
18936 last_text_row = it.glyph_row - 1;
18939 if (f->fonts_changed)
18940 return -1;
18942 /* The redisplay iterations in display_line above could have
18943 triggered font-lock, which could have done something that
18944 invalidates IT->w window's end-point information, on which we
18945 rely below. E.g., one package, which will remain unnamed, used
18946 to install a font-lock-fontify-region-function that called
18947 bury-buffer, whose side effect is to switch the buffer displayed
18948 by IT->w, and that predictably resets IT->w's window_end_valid
18949 flag, which we already tested at the entry to this function.
18950 Amply punish such packages/modes by giving up on this
18951 optimization in those cases. */
18952 if (!w->window_end_valid)
18954 clear_glyph_matrix (w->desired_matrix);
18955 return -1;
18958 /* Compute differences in buffer positions, y-positions etc. for
18959 lines reused at the bottom of the window. Compute what we can
18960 scroll. */
18961 if (first_unchanged_at_end_row
18962 /* No lines reused because we displayed everything up to the
18963 bottom of the window. */
18964 && it.current_y < it.last_visible_y)
18966 dvpos = (it.vpos
18967 - MATRIX_ROW_VPOS (first_unchanged_at_end_row,
18968 current_matrix));
18969 dy = it.current_y - first_unchanged_at_end_row->y;
18970 run.current_y = first_unchanged_at_end_row->y;
18971 run.desired_y = run.current_y + dy;
18972 run.height = it.last_visible_y - max (run.current_y, run.desired_y);
18974 else
18976 delta = delta_bytes = dvpos = dy
18977 = run.current_y = run.desired_y = run.height = 0;
18978 first_unchanged_at_end_row = NULL;
18980 IF_DEBUG ((debug_dvpos = dvpos, debug_dy = dy));
18983 /* Find the cursor if not already found. We have to decide whether
18984 PT will appear on this window (it sometimes doesn't, but this is
18985 not a very frequent case.) This decision has to be made before
18986 the current matrix is altered. A value of cursor.vpos < 0 means
18987 that PT is either in one of the lines beginning at
18988 first_unchanged_at_end_row or below the window. Don't care for
18989 lines that might be displayed later at the window end; as
18990 mentioned, this is not a frequent case. */
18991 if (w->cursor.vpos < 0)
18993 /* Cursor in unchanged rows at the top? */
18994 if (PT < CHARPOS (start_pos)
18995 && last_unchanged_at_beg_row)
18997 row = row_containing_pos (w, PT,
18998 MATRIX_FIRST_TEXT_ROW (w->current_matrix),
18999 last_unchanged_at_beg_row + 1, 0);
19000 if (row)
19001 set_cursor_from_row (w, row, w->current_matrix, 0, 0, 0, 0);
19004 /* Start from first_unchanged_at_end_row looking for PT. */
19005 else if (first_unchanged_at_end_row)
19007 row = row_containing_pos (w, PT - delta,
19008 first_unchanged_at_end_row, NULL, 0);
19009 if (row)
19010 set_cursor_from_row (w, row, w->current_matrix, delta,
19011 delta_bytes, dy, dvpos);
19014 /* Give up if cursor was not found. */
19015 if (w->cursor.vpos < 0)
19017 clear_glyph_matrix (w->desired_matrix);
19018 return -1;
19022 /* Don't let the cursor end in the scroll margins. */
19024 int this_scroll_margin = window_scroll_margin (w, MARGIN_IN_PIXELS);
19025 int cursor_height = MATRIX_ROW (w->desired_matrix, w->cursor.vpos)->height;
19027 if ((w->cursor.y < this_scroll_margin
19028 && CHARPOS (start) > BEGV)
19029 /* Old redisplay didn't take scroll margin into account at the bottom,
19030 but then global-hl-line-mode doesn't scroll. KFS 2004-06-14 */
19031 || (w->cursor.y + (make_cursor_line_fully_visible_p
19032 ? cursor_height + this_scroll_margin
19033 : 1)) > it.last_visible_y)
19035 w->cursor.vpos = -1;
19036 clear_glyph_matrix (w->desired_matrix);
19037 return -1;
19041 /* Scroll the display. Do it before changing the current matrix so
19042 that xterm.c doesn't get confused about where the cursor glyph is
19043 found. */
19044 if (dy && run.height)
19046 update_begin (f);
19048 if (FRAME_WINDOW_P (f))
19050 FRAME_RIF (f)->update_window_begin_hook (w);
19051 FRAME_RIF (f)->clear_window_mouse_face (w);
19052 FRAME_RIF (f)->scroll_run_hook (w, &run);
19053 FRAME_RIF (f)->update_window_end_hook (w, false, false);
19055 else
19057 /* Terminal frame. In this case, dvpos gives the number of
19058 lines to scroll by; dvpos < 0 means scroll up. */
19059 int from_vpos
19060 = MATRIX_ROW_VPOS (first_unchanged_at_end_row, w->current_matrix);
19061 int from = WINDOW_TOP_EDGE_LINE (w) + from_vpos;
19062 int end = (WINDOW_TOP_EDGE_LINE (w)
19063 + window_wants_header_line (w)
19064 + window_internal_height (w));
19066 #if defined (HAVE_GPM) || defined (MSDOS)
19067 x_clear_window_mouse_face (w);
19068 #endif
19069 /* Perform the operation on the screen. */
19070 if (dvpos > 0)
19072 /* Scroll last_unchanged_at_beg_row to the end of the
19073 window down dvpos lines. */
19074 set_terminal_window (f, end);
19076 /* On dumb terminals delete dvpos lines at the end
19077 before inserting dvpos empty lines. */
19078 if (!FRAME_SCROLL_REGION_OK (f))
19079 ins_del_lines (f, end - dvpos, -dvpos);
19081 /* Insert dvpos empty lines in front of
19082 last_unchanged_at_beg_row. */
19083 ins_del_lines (f, from, dvpos);
19085 else if (dvpos < 0)
19087 /* Scroll up last_unchanged_at_beg_vpos to the end of
19088 the window to last_unchanged_at_beg_vpos - |dvpos|. */
19089 set_terminal_window (f, end);
19091 /* Delete dvpos lines in front of
19092 last_unchanged_at_beg_vpos. ins_del_lines will set
19093 the cursor to the given vpos and emit |dvpos| delete
19094 line sequences. */
19095 ins_del_lines (f, from + dvpos, dvpos);
19097 /* On a dumb terminal insert dvpos empty lines at the
19098 end. */
19099 if (!FRAME_SCROLL_REGION_OK (f))
19100 ins_del_lines (f, end + dvpos, -dvpos);
19103 set_terminal_window (f, 0);
19106 update_end (f);
19109 /* Shift reused rows of the current matrix to the right position.
19110 BOTTOM_ROW is the last + 1 row in the current matrix reserved for
19111 text. */
19112 bottom_row = MATRIX_BOTTOM_TEXT_ROW (current_matrix, w);
19113 bottom_vpos = MATRIX_ROW_VPOS (bottom_row, current_matrix);
19114 if (dvpos < 0)
19116 rotate_matrix (current_matrix, first_unchanged_at_end_vpos + dvpos,
19117 bottom_vpos, dvpos);
19118 clear_glyph_matrix_rows (current_matrix, bottom_vpos + dvpos,
19119 bottom_vpos);
19121 else if (dvpos > 0)
19123 rotate_matrix (current_matrix, first_unchanged_at_end_vpos,
19124 bottom_vpos, dvpos);
19125 clear_glyph_matrix_rows (current_matrix, first_unchanged_at_end_vpos,
19126 first_unchanged_at_end_vpos + dvpos);
19129 /* For frame-based redisplay, make sure that current frame and window
19130 matrix are in sync with respect to glyph memory. */
19131 if (!FRAME_WINDOW_P (f))
19132 sync_frame_with_window_matrix_rows (w);
19134 /* Adjust buffer positions in reused rows. */
19135 if (delta || delta_bytes)
19136 increment_matrix_positions (current_matrix,
19137 first_unchanged_at_end_vpos + dvpos,
19138 bottom_vpos, delta, delta_bytes);
19140 /* Adjust Y positions. */
19141 if (dy)
19142 shift_glyph_matrix (w, current_matrix,
19143 first_unchanged_at_end_vpos + dvpos,
19144 bottom_vpos, dy);
19146 if (first_unchanged_at_end_row)
19148 first_unchanged_at_end_row += dvpos;
19149 if (first_unchanged_at_end_row->y >= it.last_visible_y
19150 || !MATRIX_ROW_DISPLAYS_TEXT_P (first_unchanged_at_end_row))
19151 first_unchanged_at_end_row = NULL;
19154 /* If scrolling up, there may be some lines to display at the end of
19155 the window. */
19156 last_text_row_at_end = NULL;
19157 if (dy < 0)
19159 /* Scrolling up can leave for example a partially visible line
19160 at the end of the window to be redisplayed. */
19161 /* Set last_row to the glyph row in the current matrix where the
19162 window end line is found. It has been moved up or down in
19163 the matrix by dvpos. */
19164 int last_vpos = w->window_end_vpos + dvpos;
19165 struct glyph_row *last_row = MATRIX_ROW (current_matrix, last_vpos);
19167 /* If last_row is the window end line, it should display text. */
19168 eassert (MATRIX_ROW_DISPLAYS_TEXT_P (last_row));
19170 /* If window end line was partially visible before, begin
19171 displaying at that line. Otherwise begin displaying with the
19172 line following it. */
19173 if (MATRIX_ROW_BOTTOM_Y (last_row) - dy >= it.last_visible_y)
19175 init_to_row_start (&it, w, last_row);
19176 it.vpos = last_vpos;
19177 it.current_y = last_row->y;
19179 else
19181 init_to_row_end (&it, w, last_row);
19182 it.vpos = 1 + last_vpos;
19183 it.current_y = MATRIX_ROW_BOTTOM_Y (last_row);
19184 ++last_row;
19187 /* We may start in a continuation line. If so, we have to
19188 get the right continuation_lines_width and current_x. */
19189 it.continuation_lines_width = last_row->continuation_lines_width;
19190 it.hpos = it.current_x = 0;
19192 /* Display the rest of the lines at the window end. */
19193 it.glyph_row = MATRIX_ROW (desired_matrix, it.vpos);
19194 while (it.current_y < it.last_visible_y && !f->fonts_changed)
19196 /* Is it always sure that the display agrees with lines in
19197 the current matrix? I don't think so, so we mark rows
19198 displayed invalid in the current matrix by setting their
19199 enabled_p flag to false. */
19200 SET_MATRIX_ROW_ENABLED_P (w->current_matrix, it.vpos, false);
19201 if (display_line (&it, w->cursor.vpos))
19202 last_text_row_at_end = it.glyph_row - 1;
19206 /* Update window_end_pos and window_end_vpos. */
19207 if (first_unchanged_at_end_row && !last_text_row_at_end)
19209 /* Window end line if one of the preserved rows from the current
19210 matrix. Set row to the last row displaying text in current
19211 matrix starting at first_unchanged_at_end_row, after
19212 scrolling. */
19213 eassert (MATRIX_ROW_DISPLAYS_TEXT_P (first_unchanged_at_end_row));
19214 row = find_last_row_displaying_text (w->current_matrix, &it,
19215 first_unchanged_at_end_row);
19216 eassume (row && MATRIX_ROW_DISPLAYS_TEXT_P (row));
19217 adjust_window_ends (w, row, true);
19218 eassert (w->window_end_bytepos >= 0);
19219 IF_DEBUG (debug_method_add (w, "A"));
19221 else if (last_text_row_at_end)
19223 adjust_window_ends (w, last_text_row_at_end, false);
19224 eassert (w->window_end_bytepos >= 0);
19225 IF_DEBUG (debug_method_add (w, "B"));
19227 else if (last_text_row)
19229 /* We have displayed either to the end of the window or at the
19230 end of the window, i.e. the last row with text is to be found
19231 in the desired matrix. */
19232 adjust_window_ends (w, last_text_row, false);
19233 eassert (w->window_end_bytepos >= 0);
19235 else if (first_unchanged_at_end_row == NULL
19236 && last_text_row == NULL
19237 && last_text_row_at_end == NULL)
19239 /* Displayed to end of window, but no line containing text was
19240 displayed. Lines were deleted at the end of the window. */
19241 bool first_vpos = window_wants_header_line (w);
19242 int vpos = w->window_end_vpos;
19243 struct glyph_row *current_row = current_matrix->rows + vpos;
19244 struct glyph_row *desired_row = desired_matrix->rows + vpos;
19246 for (row = NULL; !row; --vpos, --current_row, --desired_row)
19248 eassert (first_vpos <= vpos);
19249 if (desired_row->enabled_p)
19251 if (MATRIX_ROW_DISPLAYS_TEXT_P (desired_row))
19252 row = desired_row;
19254 else if (MATRIX_ROW_DISPLAYS_TEXT_P (current_row))
19255 row = current_row;
19258 w->window_end_vpos = vpos + 1;
19259 w->window_end_pos = Z - MATRIX_ROW_END_CHARPOS (row);
19260 w->window_end_bytepos = Z_BYTE - MATRIX_ROW_END_BYTEPOS (row);
19261 eassert (w->window_end_bytepos >= 0);
19262 IF_DEBUG (debug_method_add (w, "C"));
19264 else
19265 emacs_abort ();
19267 IF_DEBUG ((debug_end_pos = w->window_end_pos,
19268 debug_end_vpos = w->window_end_vpos));
19270 /* Record that display has not been completed. */
19271 w->window_end_valid = false;
19272 w->desired_matrix->no_scrolling_p = true;
19273 return 3;
19275 #undef GIVE_UP
19280 /***********************************************************************
19281 More debugging support
19282 ***********************************************************************/
19284 #ifdef GLYPH_DEBUG
19286 void dump_glyph_row (struct glyph_row *, int, int) EXTERNALLY_VISIBLE;
19287 void dump_glyph_matrix (struct glyph_matrix *, int) EXTERNALLY_VISIBLE;
19288 void dump_glyph (struct glyph_row *, struct glyph *, int) EXTERNALLY_VISIBLE;
19291 /* Dump the contents of glyph matrix MATRIX on stderr.
19293 GLYPHS 0 means don't show glyph contents.
19294 GLYPHS 1 means show glyphs in short form
19295 GLYPHS > 1 means show glyphs in long form. */
19297 void
19298 dump_glyph_matrix (struct glyph_matrix *matrix, int glyphs)
19300 int i;
19301 for (i = 0; i < matrix->nrows; ++i)
19302 dump_glyph_row (MATRIX_ROW (matrix, i), i, glyphs);
19306 /* Dump contents of glyph GLYPH to stderr. ROW and AREA are
19307 the glyph row and area where the glyph comes from. */
19309 void
19310 dump_glyph (struct glyph_row *row, struct glyph *glyph, int area)
19312 if (glyph->type == CHAR_GLYPH
19313 || glyph->type == GLYPHLESS_GLYPH)
19315 fprintf (stderr,
19316 " %5"pD"d %c %9"pD"d %c %3d 0x%06x %c %4d %1.1d%1.1d\n",
19317 glyph - row->glyphs[TEXT_AREA],
19318 (glyph->type == CHAR_GLYPH
19319 ? 'C'
19320 : 'G'),
19321 glyph->charpos,
19322 (BUFFERP (glyph->object)
19323 ? 'B'
19324 : (STRINGP (glyph->object)
19325 ? 'S'
19326 : (NILP (glyph->object)
19327 ? '0'
19328 : '-'))),
19329 glyph->pixel_width,
19330 glyph->u.ch,
19331 (glyph->u.ch < 0x80 && glyph->u.ch >= ' '
19332 ? (int) glyph->u.ch
19333 : '.'),
19334 glyph->face_id,
19335 glyph->left_box_line_p,
19336 glyph->right_box_line_p);
19338 else if (glyph->type == STRETCH_GLYPH)
19340 fprintf (stderr,
19341 " %5"pD"d %c %9"pD"d %c %3d 0x%06x %c %4d %1.1d%1.1d\n",
19342 glyph - row->glyphs[TEXT_AREA],
19343 'S',
19344 glyph->charpos,
19345 (BUFFERP (glyph->object)
19346 ? 'B'
19347 : (STRINGP (glyph->object)
19348 ? 'S'
19349 : (NILP (glyph->object)
19350 ? '0'
19351 : '-'))),
19352 glyph->pixel_width,
19354 ' ',
19355 glyph->face_id,
19356 glyph->left_box_line_p,
19357 glyph->right_box_line_p);
19359 else if (glyph->type == IMAGE_GLYPH)
19361 fprintf (stderr,
19362 " %5"pD"d %c %9"pD"d %c %3d 0x%06x %c %4d %1.1d%1.1d\n",
19363 glyph - row->glyphs[TEXT_AREA],
19364 'I',
19365 glyph->charpos,
19366 (BUFFERP (glyph->object)
19367 ? 'B'
19368 : (STRINGP (glyph->object)
19369 ? 'S'
19370 : (NILP (glyph->object)
19371 ? '0'
19372 : '-'))),
19373 glyph->pixel_width,
19374 (unsigned int) glyph->u.img_id,
19375 '.',
19376 glyph->face_id,
19377 glyph->left_box_line_p,
19378 glyph->right_box_line_p);
19380 else if (glyph->type == COMPOSITE_GLYPH)
19382 fprintf (stderr,
19383 " %5"pD"d %c %9"pD"d %c %3d 0x%06x",
19384 glyph - row->glyphs[TEXT_AREA],
19385 '+',
19386 glyph->charpos,
19387 (BUFFERP (glyph->object)
19388 ? 'B'
19389 : (STRINGP (glyph->object)
19390 ? 'S'
19391 : (NILP (glyph->object)
19392 ? '0'
19393 : '-'))),
19394 glyph->pixel_width,
19395 (unsigned int) glyph->u.cmp.id);
19396 if (glyph->u.cmp.automatic)
19397 fprintf (stderr,
19398 "[%d-%d]",
19399 glyph->slice.cmp.from, glyph->slice.cmp.to);
19400 fprintf (stderr, " . %4d %1.1d%1.1d\n",
19401 glyph->face_id,
19402 glyph->left_box_line_p,
19403 glyph->right_box_line_p);
19405 else if (glyph->type == XWIDGET_GLYPH)
19407 #ifndef HAVE_XWIDGETS
19408 eassume (false);
19409 #else
19410 fprintf (stderr,
19411 " %5d %4c %6d %c %3d 0x%05x %c %4d %1.1d%1.1d\n",
19412 glyph - row->glyphs[TEXT_AREA],
19413 'X',
19414 glyph->charpos,
19415 (BUFFERP (glyph->object)
19416 ? 'B'
19417 : (STRINGP (glyph->object)
19418 ? 'S'
19419 : '-')),
19420 glyph->pixel_width,
19421 glyph->u.xwidget,
19422 '.',
19423 glyph->face_id,
19424 glyph->left_box_line_p,
19425 glyph->right_box_line_p);
19426 #endif
19431 /* Dump the contents of glyph row at VPOS in MATRIX to stderr.
19432 GLYPHS 0 means don't show glyph contents.
19433 GLYPHS 1 means show glyphs in short form
19434 GLYPHS > 1 means show glyphs in long form. */
19436 void
19437 dump_glyph_row (struct glyph_row *row, int vpos, int glyphs)
19439 if (glyphs != 1)
19441 fprintf (stderr, "Row Start End Used oE><\\CTZFesm X Y W H V A P\n");
19442 fprintf (stderr, "==============================================================================\n");
19444 fprintf (stderr, "%3d %9"pD"d %9"pD"d %4d %1.1d%1.1d%1.1d%1.1d\
19445 %1.1d%1.1d%1.1d%1.1d%1.1d%1.1d%1.1d%1.1d %4d %4d %4d %4d %4d %4d %4d\n",
19446 vpos,
19447 MATRIX_ROW_START_CHARPOS (row),
19448 MATRIX_ROW_END_CHARPOS (row),
19449 row->used[TEXT_AREA],
19450 row->contains_overlapping_glyphs_p,
19451 row->enabled_p,
19452 row->truncated_on_left_p,
19453 row->truncated_on_right_p,
19454 row->continued_p,
19455 MATRIX_ROW_CONTINUATION_LINE_P (row),
19456 MATRIX_ROW_DISPLAYS_TEXT_P (row),
19457 row->ends_at_zv_p,
19458 row->fill_line_p,
19459 row->ends_in_middle_of_char_p,
19460 row->starts_in_middle_of_char_p,
19461 row->mouse_face_p,
19462 row->x,
19463 row->y,
19464 row->pixel_width,
19465 row->height,
19466 row->visible_height,
19467 row->ascent,
19468 row->phys_ascent);
19469 /* The next 3 lines should align to "Start" in the header. */
19470 fprintf (stderr, " %9"pD"d %9"pD"d\t%5d\n", row->start.overlay_string_index,
19471 row->end.overlay_string_index,
19472 row->continuation_lines_width);
19473 fprintf (stderr, " %9"pD"d %9"pD"d\n",
19474 CHARPOS (row->start.string_pos),
19475 CHARPOS (row->end.string_pos));
19476 fprintf (stderr, " %9d %9d\n", row->start.dpvec_index,
19477 row->end.dpvec_index);
19480 if (glyphs > 1)
19482 int area;
19484 for (area = LEFT_MARGIN_AREA; area < LAST_AREA; ++area)
19486 struct glyph *glyph = row->glyphs[area];
19487 struct glyph *glyph_end = glyph + row->used[area];
19489 /* Glyph for a line end in text. */
19490 if (area == TEXT_AREA && glyph == glyph_end && glyph->charpos > 0)
19491 ++glyph_end;
19493 if (glyph < glyph_end)
19494 fprintf (stderr, " Glyph# Type Pos O W Code C Face LR\n");
19496 for (; glyph < glyph_end; ++glyph)
19497 dump_glyph (row, glyph, area);
19500 else if (glyphs == 1)
19502 int area;
19503 char s[SHRT_MAX + 4];
19505 for (area = LEFT_MARGIN_AREA; area < LAST_AREA; ++area)
19507 int i;
19509 for (i = 0; i < row->used[area]; ++i)
19511 struct glyph *glyph = row->glyphs[area] + i;
19512 if (i == row->used[area] - 1
19513 && area == TEXT_AREA
19514 && NILP (glyph->object)
19515 && glyph->type == CHAR_GLYPH
19516 && glyph->u.ch == ' ')
19518 strcpy (&s[i], "[\\n]");
19519 i += 4;
19521 else if (glyph->type == CHAR_GLYPH
19522 && glyph->u.ch < 0x80
19523 && glyph->u.ch >= ' ')
19524 s[i] = glyph->u.ch;
19525 else
19526 s[i] = '.';
19529 s[i] = '\0';
19530 fprintf (stderr, "%3d: (%d) '%s'\n", vpos, row->enabled_p, s);
19536 DEFUN ("dump-glyph-matrix", Fdump_glyph_matrix,
19537 Sdump_glyph_matrix, 0, 1, "p",
19538 doc: /* Dump the current matrix of the selected window to stderr.
19539 Shows contents of glyph row structures. With non-nil
19540 parameter GLYPHS, dump glyphs as well. If GLYPHS is 1 show
19541 glyphs in short form, otherwise show glyphs in long form.
19543 Interactively, no argument means show glyphs in short form;
19544 with numeric argument, its value is passed as the GLYPHS flag. */)
19545 (Lisp_Object glyphs)
19547 struct window *w = XWINDOW (selected_window);
19548 struct buffer *buffer = XBUFFER (w->contents);
19550 fprintf (stderr, "PT = %"pD"d, BEGV = %"pD"d. ZV = %"pD"d\n",
19551 BUF_PT (buffer), BUF_BEGV (buffer), BUF_ZV (buffer));
19552 fprintf (stderr, "Cursor x = %d, y = %d, hpos = %d, vpos = %d\n",
19553 w->cursor.x, w->cursor.y, w->cursor.hpos, w->cursor.vpos);
19554 fprintf (stderr, "=============================================\n");
19555 dump_glyph_matrix (w->current_matrix,
19556 TYPE_RANGED_INTEGERP (int, glyphs) ? XINT (glyphs) : 0);
19557 return Qnil;
19561 DEFUN ("dump-frame-glyph-matrix", Fdump_frame_glyph_matrix,
19562 Sdump_frame_glyph_matrix, 0, 0, "", doc: /* Dump the current glyph matrix of the selected frame to stderr.
19563 Only text-mode frames have frame glyph matrices. */)
19564 (void)
19566 struct frame *f = XFRAME (selected_frame);
19568 if (f->current_matrix)
19569 dump_glyph_matrix (f->current_matrix, 1);
19570 else
19571 fprintf (stderr, "*** This frame doesn't have a frame glyph matrix ***\n");
19572 return Qnil;
19576 DEFUN ("dump-glyph-row", Fdump_glyph_row, Sdump_glyph_row, 1, 2, "P",
19577 doc: /* Dump glyph row ROW to stderr.
19578 Interactively, ROW is the prefix numeric argument and defaults to
19579 the row which displays point.
19580 Optional argument GLYPHS 0 means don't dump glyphs.
19581 GLYPHS 1 means dump glyphs in short form.
19582 GLYPHS > 1 or omitted means dump glyphs in long form. */)
19583 (Lisp_Object row, Lisp_Object glyphs)
19585 struct glyph_matrix *matrix;
19586 EMACS_INT vpos;
19588 if (NILP (row))
19590 int d1, d2, d3, d4, d5, ypos;
19591 bool visible_p = pos_visible_p (XWINDOW (selected_window), PT,
19592 &d1, &d2, &d3, &d4, &d5, &ypos);
19593 if (visible_p)
19594 vpos = ypos;
19595 else
19596 vpos = 0;
19598 else
19600 CHECK_NUMBER (row);
19601 vpos = XINT (row);
19603 matrix = XWINDOW (selected_window)->current_matrix;
19604 if (vpos >= 0 && vpos < matrix->nrows)
19605 dump_glyph_row (MATRIX_ROW (matrix, vpos),
19606 vpos,
19607 TYPE_RANGED_INTEGERP (int, glyphs) ? XINT (glyphs) : 2);
19608 return Qnil;
19612 DEFUN ("dump-tool-bar-row", Fdump_tool_bar_row, Sdump_tool_bar_row, 1, 2, "P",
19613 doc: /* Dump glyph row ROW of the tool-bar of the current frame to stderr.
19614 Interactively, ROW is the prefix numeric argument and defaults to zero.
19615 GLYPHS 0 means don't dump glyphs.
19616 GLYPHS 1 means dump glyphs in short form.
19617 GLYPHS > 1 or omitted means dump glyphs in long form.
19619 If there's no tool-bar, or if the tool-bar is not drawn by Emacs,
19620 do nothing. */)
19621 (Lisp_Object row, Lisp_Object glyphs)
19623 #if defined (HAVE_WINDOW_SYSTEM) && ! defined (USE_GTK) && ! defined (HAVE_NS)
19624 struct frame *sf = SELECTED_FRAME ();
19625 struct glyph_matrix *m = XWINDOW (sf->tool_bar_window)->current_matrix;
19626 EMACS_INT vpos;
19628 if (NILP (row))
19629 vpos = 0;
19630 else
19632 CHECK_NUMBER (row);
19633 vpos = XINT (row);
19635 if (vpos >= 0 && vpos < m->nrows)
19636 dump_glyph_row (MATRIX_ROW (m, vpos), vpos,
19637 TYPE_RANGED_INTEGERP (int, glyphs) ? XINT (glyphs) : 2);
19638 #endif
19639 return Qnil;
19643 DEFUN ("trace-redisplay", Ftrace_redisplay, Strace_redisplay, 0, 1, "P",
19644 doc: /* Toggle tracing of redisplay.
19645 With ARG, turn tracing on if and only if ARG is positive. */)
19646 (Lisp_Object arg)
19648 if (NILP (arg))
19649 trace_redisplay_p = !trace_redisplay_p;
19650 else
19652 arg = Fprefix_numeric_value (arg);
19653 trace_redisplay_p = XINT (arg) > 0;
19656 return Qnil;
19660 DEFUN ("trace-to-stderr", Ftrace_to_stderr, Strace_to_stderr, 1, MANY, "",
19661 doc: /* Like `format', but print result to stderr.
19662 usage: (trace-to-stderr STRING &rest OBJECTS) */)
19663 (ptrdiff_t nargs, Lisp_Object *args)
19665 Lisp_Object s = Fformat (nargs, args);
19666 fwrite (SDATA (s), 1, SBYTES (s), stderr);
19667 return Qnil;
19670 #endif /* GLYPH_DEBUG */
19674 /***********************************************************************
19675 Building Desired Matrix Rows
19676 ***********************************************************************/
19678 /* Return a temporary glyph row holding the glyphs of an overlay arrow.
19679 Used for non-window-redisplay windows, and for windows w/o left fringe. */
19681 static struct glyph_row *
19682 get_overlay_arrow_glyph_row (struct window *w, Lisp_Object overlay_arrow_string)
19684 struct frame *f = XFRAME (WINDOW_FRAME (w));
19685 struct buffer *buffer = XBUFFER (w->contents);
19686 struct buffer *old = current_buffer;
19687 const unsigned char *arrow_string = SDATA (overlay_arrow_string);
19688 ptrdiff_t arrow_len = SCHARS (overlay_arrow_string);
19689 const unsigned char *arrow_end = arrow_string + arrow_len;
19690 const unsigned char *p;
19691 struct it it;
19692 bool multibyte_p;
19693 int n_glyphs_before;
19695 set_buffer_temp (buffer);
19696 init_iterator (&it, w, -1, -1, &scratch_glyph_row, DEFAULT_FACE_ID);
19697 scratch_glyph_row.reversed_p = false;
19698 it.glyph_row->used[TEXT_AREA] = 0;
19699 SET_TEXT_POS (it.position, 0, 0);
19701 multibyte_p = !NILP (BVAR (buffer, enable_multibyte_characters));
19702 p = arrow_string;
19703 while (p < arrow_end)
19705 Lisp_Object face, ilisp;
19707 /* Get the next character. */
19708 if (multibyte_p)
19709 it.c = it.char_to_display = string_char_and_length (p, &it.len);
19710 else
19712 it.c = it.char_to_display = *p, it.len = 1;
19713 if (! ASCII_CHAR_P (it.c))
19714 it.char_to_display = BYTE8_TO_CHAR (it.c);
19716 p += it.len;
19718 /* Get its face. */
19719 ilisp = make_number (p - arrow_string);
19720 face = Fget_text_property (ilisp, Qface, overlay_arrow_string);
19721 it.face_id = compute_char_face (f, it.char_to_display, face);
19723 /* Compute its width, get its glyphs. */
19724 n_glyphs_before = it.glyph_row->used[TEXT_AREA];
19725 SET_TEXT_POS (it.position, -1, -1);
19726 PRODUCE_GLYPHS (&it);
19728 /* If this character doesn't fit any more in the line, we have
19729 to remove some glyphs. */
19730 if (it.current_x > it.last_visible_x)
19732 it.glyph_row->used[TEXT_AREA] = n_glyphs_before;
19733 break;
19737 set_buffer_temp (old);
19738 return it.glyph_row;
19742 /* Insert truncation glyphs at the start of IT->glyph_row. Which
19743 glyphs to insert is determined by produce_special_glyphs. */
19745 static void
19746 insert_left_trunc_glyphs (struct it *it)
19748 struct it truncate_it;
19749 struct glyph *from, *end, *to, *toend;
19751 eassert (!FRAME_WINDOW_P (it->f)
19752 || (!it->glyph_row->reversed_p
19753 && WINDOW_LEFT_FRINGE_WIDTH (it->w) == 0)
19754 || (it->glyph_row->reversed_p
19755 && WINDOW_RIGHT_FRINGE_WIDTH (it->w) == 0));
19757 /* Get the truncation glyphs. */
19758 truncate_it = *it;
19759 truncate_it.current_x = 0;
19760 truncate_it.face_id = DEFAULT_FACE_ID;
19761 truncate_it.glyph_row = &scratch_glyph_row;
19762 truncate_it.area = TEXT_AREA;
19763 truncate_it.glyph_row->used[TEXT_AREA] = 0;
19764 CHARPOS (truncate_it.position) = BYTEPOS (truncate_it.position) = -1;
19765 truncate_it.object = Qnil;
19766 produce_special_glyphs (&truncate_it, IT_TRUNCATION);
19768 /* Overwrite glyphs from IT with truncation glyphs. */
19769 if (!it->glyph_row->reversed_p)
19771 short tused = truncate_it.glyph_row->used[TEXT_AREA];
19773 from = truncate_it.glyph_row->glyphs[TEXT_AREA];
19774 end = from + tused;
19775 to = it->glyph_row->glyphs[TEXT_AREA];
19776 toend = to + it->glyph_row->used[TEXT_AREA];
19777 if (FRAME_WINDOW_P (it->f))
19779 /* On GUI frames, when variable-size fonts are displayed,
19780 the truncation glyphs may need more pixels than the row's
19781 glyphs they overwrite. We overwrite more glyphs to free
19782 enough screen real estate, and enlarge the stretch glyph
19783 on the right (see display_line), if there is one, to
19784 preserve the screen position of the truncation glyphs on
19785 the right. */
19786 int w = 0;
19787 struct glyph *g = to;
19788 short used;
19790 /* The first glyph could be partially visible, in which case
19791 it->glyph_row->x will be negative. But we want the left
19792 truncation glyphs to be aligned at the left margin of the
19793 window, so we override the x coordinate at which the row
19794 will begin. */
19795 it->glyph_row->x = 0;
19796 while (g < toend && w < it->truncation_pixel_width)
19798 w += g->pixel_width;
19799 ++g;
19801 if (g - to - tused > 0)
19803 memmove (to + tused, g, (toend - g) * sizeof(*g));
19804 it->glyph_row->used[TEXT_AREA] -= g - to - tused;
19806 used = it->glyph_row->used[TEXT_AREA];
19807 if (it->glyph_row->truncated_on_right_p
19808 && WINDOW_RIGHT_FRINGE_WIDTH (it->w) == 0
19809 && it->glyph_row->glyphs[TEXT_AREA][used - 2].type
19810 == STRETCH_GLYPH)
19812 int extra = w - it->truncation_pixel_width;
19814 it->glyph_row->glyphs[TEXT_AREA][used - 2].pixel_width += extra;
19818 while (from < end)
19819 *to++ = *from++;
19821 /* There may be padding glyphs left over. Overwrite them too. */
19822 if (!FRAME_WINDOW_P (it->f))
19824 while (to < toend && CHAR_GLYPH_PADDING_P (*to))
19826 from = truncate_it.glyph_row->glyphs[TEXT_AREA];
19827 while (from < end)
19828 *to++ = *from++;
19832 if (to > toend)
19833 it->glyph_row->used[TEXT_AREA] = to - it->glyph_row->glyphs[TEXT_AREA];
19835 else
19837 short tused = truncate_it.glyph_row->used[TEXT_AREA];
19839 /* In R2L rows, overwrite the last (rightmost) glyphs, and do
19840 that back to front. */
19841 end = truncate_it.glyph_row->glyphs[TEXT_AREA];
19842 from = end + truncate_it.glyph_row->used[TEXT_AREA] - 1;
19843 toend = it->glyph_row->glyphs[TEXT_AREA];
19844 to = toend + it->glyph_row->used[TEXT_AREA] - 1;
19845 if (FRAME_WINDOW_P (it->f))
19847 int w = 0;
19848 struct glyph *g = to;
19850 while (g >= toend && w < it->truncation_pixel_width)
19852 w += g->pixel_width;
19853 --g;
19855 if (to - g - tused > 0)
19856 to = g + tused;
19857 if (it->glyph_row->truncated_on_right_p
19858 && WINDOW_LEFT_FRINGE_WIDTH (it->w) == 0
19859 && it->glyph_row->glyphs[TEXT_AREA][1].type == STRETCH_GLYPH)
19861 int extra = w - it->truncation_pixel_width;
19863 it->glyph_row->glyphs[TEXT_AREA][1].pixel_width += extra;
19867 while (from >= end && to >= toend)
19868 *to-- = *from--;
19869 if (!FRAME_WINDOW_P (it->f))
19871 while (to >= toend && CHAR_GLYPH_PADDING_P (*to))
19873 from =
19874 truncate_it.glyph_row->glyphs[TEXT_AREA]
19875 + truncate_it.glyph_row->used[TEXT_AREA] - 1;
19876 while (from >= end && to >= toend)
19877 *to-- = *from--;
19880 if (from >= end)
19882 /* Need to free some room before prepending additional
19883 glyphs. */
19884 int move_by = from - end + 1;
19885 struct glyph *g0 = it->glyph_row->glyphs[TEXT_AREA];
19886 struct glyph *g = g0 + it->glyph_row->used[TEXT_AREA] - 1;
19888 for ( ; g >= g0; g--)
19889 g[move_by] = *g;
19890 while (from >= end)
19891 *to-- = *from--;
19892 it->glyph_row->used[TEXT_AREA] += move_by;
19897 /* Compute the hash code for ROW. */
19898 unsigned
19899 row_hash (struct glyph_row *row)
19901 int area, k;
19902 unsigned hashval = 0;
19904 for (area = LEFT_MARGIN_AREA; area < LAST_AREA; ++area)
19905 for (k = 0; k < row->used[area]; ++k)
19906 hashval = ((((hashval << 4) + (hashval >> 24)) & 0x0fffffff)
19907 + row->glyphs[area][k].u.val
19908 + row->glyphs[area][k].face_id
19909 + row->glyphs[area][k].padding_p
19910 + (row->glyphs[area][k].type << 2));
19912 return hashval;
19915 /* Compute the pixel height and width of IT->glyph_row.
19917 Most of the time, ascent and height of a display line will be equal
19918 to the max_ascent and max_height values of the display iterator
19919 structure. This is not the case if
19921 1. We hit ZV without displaying anything. In this case, max_ascent
19922 and max_height will be zero.
19924 2. We have some glyphs that don't contribute to the line height.
19925 (The glyph row flag contributes_to_line_height_p is for future
19926 pixmap extensions).
19928 The first case is easily covered by using default values because in
19929 these cases, the line height does not really matter, except that it
19930 must not be zero. */
19932 static void
19933 compute_line_metrics (struct it *it)
19935 struct glyph_row *row = it->glyph_row;
19937 if (FRAME_WINDOW_P (it->f))
19939 int i, min_y, max_y;
19941 /* The line may consist of one space only, that was added to
19942 place the cursor on it. If so, the row's height hasn't been
19943 computed yet. */
19944 if (row->height == 0)
19946 if (it->max_ascent + it->max_descent == 0)
19947 it->max_descent = it->max_phys_descent = FRAME_LINE_HEIGHT (it->f);
19948 row->ascent = it->max_ascent;
19949 row->height = it->max_ascent + it->max_descent;
19950 row->phys_ascent = it->max_phys_ascent;
19951 row->phys_height = it->max_phys_ascent + it->max_phys_descent;
19952 row->extra_line_spacing = it->max_extra_line_spacing;
19955 /* Compute the width of this line. */
19956 row->pixel_width = row->x;
19957 for (i = 0; i < row->used[TEXT_AREA]; ++i)
19958 row->pixel_width += row->glyphs[TEXT_AREA][i].pixel_width;
19960 eassert (row->pixel_width >= 0);
19961 eassert (row->ascent >= 0 && row->height > 0);
19963 row->overlapping_p = (MATRIX_ROW_OVERLAPS_SUCC_P (row)
19964 || MATRIX_ROW_OVERLAPS_PRED_P (row));
19966 /* If first line's physical ascent is larger than its logical
19967 ascent, use the physical ascent, and make the row taller.
19968 This makes accented characters fully visible. */
19969 if (row == MATRIX_FIRST_TEXT_ROW (it->w->desired_matrix)
19970 && row->phys_ascent > row->ascent)
19972 row->height += row->phys_ascent - row->ascent;
19973 row->ascent = row->phys_ascent;
19976 /* Compute how much of the line is visible. */
19977 row->visible_height = row->height;
19979 min_y = WINDOW_HEADER_LINE_HEIGHT (it->w);
19980 max_y = WINDOW_BOX_HEIGHT_NO_MODE_LINE (it->w);
19982 if (row->y < min_y)
19983 row->visible_height -= min_y - row->y;
19984 if (row->y + row->height > max_y)
19985 row->visible_height -= row->y + row->height - max_y;
19987 else
19989 row->pixel_width = row->used[TEXT_AREA];
19990 if (row->continued_p)
19991 row->pixel_width -= it->continuation_pixel_width;
19992 else if (row->truncated_on_right_p)
19993 row->pixel_width -= it->truncation_pixel_width;
19994 row->ascent = row->phys_ascent = 0;
19995 row->height = row->phys_height = row->visible_height = 1;
19996 row->extra_line_spacing = 0;
19999 /* Compute a hash code for this row. */
20000 row->hash = row_hash (row);
20002 it->max_ascent = it->max_descent = 0;
20003 it->max_phys_ascent = it->max_phys_descent = 0;
20007 /* Append one space to the glyph row of iterator IT if doing a
20008 window-based redisplay. The space has the same face as
20009 IT->face_id. Value is true if a space was added.
20011 This function is called to make sure that there is always one glyph
20012 at the end of a glyph row that the cursor can be set on under
20013 window-systems. (If there weren't such a glyph we would not know
20014 how wide and tall a box cursor should be displayed).
20016 At the same time this space let's a nicely handle clearing to the
20017 end of the line if the row ends in italic text. */
20019 static bool
20020 append_space_for_newline (struct it *it, bool default_face_p)
20022 if (FRAME_WINDOW_P (it->f))
20024 int n = it->glyph_row->used[TEXT_AREA];
20026 if (it->glyph_row->glyphs[TEXT_AREA] + n
20027 < it->glyph_row->glyphs[1 + TEXT_AREA])
20029 /* Save some values that must not be changed.
20030 Must save IT->c and IT->len because otherwise
20031 ITERATOR_AT_END_P wouldn't work anymore after
20032 append_space_for_newline has been called. */
20033 enum display_element_type saved_what = it->what;
20034 int saved_c = it->c, saved_len = it->len;
20035 int saved_char_to_display = it->char_to_display;
20036 int saved_x = it->current_x;
20037 int saved_face_id = it->face_id;
20038 bool saved_box_end = it->end_of_box_run_p;
20039 struct text_pos saved_pos;
20040 Lisp_Object saved_object;
20041 struct face *face;
20043 saved_object = it->object;
20044 saved_pos = it->position;
20046 it->what = IT_CHARACTER;
20047 memset (&it->position, 0, sizeof it->position);
20048 it->object = Qnil;
20049 it->c = it->char_to_display = ' ';
20050 it->len = 1;
20052 /* If the default face was remapped, be sure to use the
20053 remapped face for the appended newline. */
20054 if (default_face_p)
20055 it->face_id = lookup_basic_face (it->f, DEFAULT_FACE_ID);
20056 else if (it->face_before_selective_p)
20057 it->face_id = it->saved_face_id;
20058 face = FACE_FROM_ID (it->f, it->face_id);
20059 it->face_id = FACE_FOR_CHAR (it->f, face, 0, -1, Qnil);
20060 /* In R2L rows, we will prepend a stretch glyph that will
20061 have the end_of_box_run_p flag set for it, so there's no
20062 need for the appended newline glyph to have that flag
20063 set. */
20064 if (it->glyph_row->reversed_p
20065 /* But if the appended newline glyph goes all the way to
20066 the end of the row, there will be no stretch glyph,
20067 so leave the box flag set. */
20068 && saved_x + FRAME_COLUMN_WIDTH (it->f) < it->last_visible_x)
20069 it->end_of_box_run_p = false;
20071 PRODUCE_GLYPHS (it);
20073 #ifdef HAVE_WINDOW_SYSTEM
20074 /* Make sure this space glyph has the right ascent and
20075 descent values, or else cursor at end of line will look
20076 funny, and height of empty lines will be incorrect. */
20077 struct glyph *g = it->glyph_row->glyphs[TEXT_AREA] + n;
20078 struct font *font = face->font ? face->font : FRAME_FONT (it->f);
20079 if (n == 0)
20081 Lisp_Object height, total_height;
20082 int extra_line_spacing = it->extra_line_spacing;
20083 int boff = font->baseline_offset;
20085 if (font->vertical_centering)
20086 boff = VCENTER_BASELINE_OFFSET (font, it->f) - boff;
20088 it->object = saved_object; /* get_it_property needs this */
20089 normal_char_ascent_descent (font, -1, &it->ascent, &it->descent);
20090 /* Must do a subset of line height processing from
20091 x_produce_glyph for newline characters. */
20092 height = get_it_property (it, Qline_height);
20093 if (CONSP (height)
20094 && CONSP (XCDR (height))
20095 && NILP (XCDR (XCDR (height))))
20097 total_height = XCAR (XCDR (height));
20098 height = XCAR (height);
20100 else
20101 total_height = Qnil;
20102 height = calc_line_height_property (it, height, font, boff, true);
20104 if (it->override_ascent >= 0)
20106 it->ascent = it->override_ascent;
20107 it->descent = it->override_descent;
20108 boff = it->override_boff;
20110 if (EQ (height, Qt))
20111 extra_line_spacing = 0;
20112 else
20114 Lisp_Object spacing;
20116 it->phys_ascent = it->ascent;
20117 it->phys_descent = it->descent;
20118 if (!NILP (height)
20119 && XINT (height) > it->ascent + it->descent)
20120 it->ascent = XINT (height) - it->descent;
20122 if (!NILP (total_height))
20123 spacing = calc_line_height_property (it, total_height, font,
20124 boff, false);
20125 else
20127 spacing = get_it_property (it, Qline_spacing);
20128 spacing = calc_line_height_property (it, spacing, font,
20129 boff, false);
20131 if (INTEGERP (spacing))
20133 extra_line_spacing = XINT (spacing);
20134 if (!NILP (total_height))
20135 extra_line_spacing -= (it->phys_ascent + it->phys_descent);
20138 if (extra_line_spacing > 0)
20140 it->descent += extra_line_spacing;
20141 if (extra_line_spacing > it->max_extra_line_spacing)
20142 it->max_extra_line_spacing = extra_line_spacing;
20144 it->max_ascent = it->ascent;
20145 it->max_descent = it->descent;
20146 /* Make sure compute_line_metrics recomputes the row height. */
20147 it->glyph_row->height = 0;
20150 g->ascent = it->max_ascent;
20151 g->descent = it->max_descent;
20152 #endif
20154 it->override_ascent = -1;
20155 it->constrain_row_ascent_descent_p = false;
20156 it->current_x = saved_x;
20157 it->object = saved_object;
20158 it->position = saved_pos;
20159 it->what = saved_what;
20160 it->face_id = saved_face_id;
20161 it->len = saved_len;
20162 it->c = saved_c;
20163 it->char_to_display = saved_char_to_display;
20164 it->end_of_box_run_p = saved_box_end;
20165 return true;
20169 return false;
20173 /* Extend the face of the last glyph in the text area of IT->glyph_row
20174 to the end of the display line. Called from display_line. If the
20175 glyph row is empty, add a space glyph to it so that we know the
20176 face to draw. Set the glyph row flag fill_line_p. If the glyph
20177 row is R2L, prepend a stretch glyph to cover the empty space to the
20178 left of the leftmost glyph. */
20180 static void
20181 extend_face_to_end_of_line (struct it *it)
20183 struct face *face, *default_face;
20184 struct frame *f = it->f;
20186 /* If line is already filled, do nothing. Non window-system frames
20187 get a grace of one more ``pixel'' because their characters are
20188 1-``pixel'' wide, so they hit the equality too early. This grace
20189 is needed only for R2L rows that are not continued, to produce
20190 one extra blank where we could display the cursor. */
20191 if ((it->current_x >= it->last_visible_x
20192 + (!FRAME_WINDOW_P (f)
20193 && it->glyph_row->reversed_p
20194 && !it->glyph_row->continued_p))
20195 /* If the window has display margins, we will need to extend
20196 their face even if the text area is filled. */
20197 && !(WINDOW_LEFT_MARGIN_WIDTH (it->w) > 0
20198 || WINDOW_RIGHT_MARGIN_WIDTH (it->w) > 0))
20199 return;
20201 /* The default face, possibly remapped. */
20202 default_face = FACE_FROM_ID_OR_NULL (f,
20203 lookup_basic_face (f, DEFAULT_FACE_ID));
20205 /* Face extension extends the background and box of IT->face_id
20206 to the end of the line. If the background equals the background
20207 of the frame, we don't have to do anything. */
20208 face = FACE_FROM_ID (f, (it->face_before_selective_p
20209 ? it->saved_face_id
20210 : it->face_id));
20212 if (FRAME_WINDOW_P (f)
20213 && MATRIX_ROW_DISPLAYS_TEXT_P (it->glyph_row)
20214 && face->box == FACE_NO_BOX
20215 && face->background == FRAME_BACKGROUND_PIXEL (f)
20216 #ifdef HAVE_WINDOW_SYSTEM
20217 && !face->stipple
20218 #endif
20219 && !it->glyph_row->reversed_p)
20220 return;
20222 /* Set the glyph row flag indicating that the face of the last glyph
20223 in the text area has to be drawn to the end of the text area. */
20224 it->glyph_row->fill_line_p = true;
20226 /* If current character of IT is not ASCII, make sure we have the
20227 ASCII face. This will be automatically undone the next time
20228 get_next_display_element returns a multibyte character. Note
20229 that the character will always be single byte in unibyte
20230 text. */
20231 if (!ASCII_CHAR_P (it->c))
20233 it->face_id = FACE_FOR_CHAR (f, face, 0, -1, Qnil);
20236 if (FRAME_WINDOW_P (f))
20238 /* If the row is empty, add a space with the current face of IT,
20239 so that we know which face to draw. */
20240 if (it->glyph_row->used[TEXT_AREA] == 0)
20242 it->glyph_row->glyphs[TEXT_AREA][0] = space_glyph;
20243 it->glyph_row->glyphs[TEXT_AREA][0].face_id = face->id;
20244 it->glyph_row->used[TEXT_AREA] = 1;
20246 /* Mode line and the header line don't have margins, and
20247 likewise the frame's tool-bar window, if there is any. */
20248 if (!(it->glyph_row->mode_line_p
20249 #if defined (HAVE_WINDOW_SYSTEM) && ! defined (USE_GTK) && ! defined (HAVE_NS)
20250 || (WINDOWP (f->tool_bar_window)
20251 && it->w == XWINDOW (f->tool_bar_window))
20252 #endif
20255 if (WINDOW_LEFT_MARGIN_WIDTH (it->w) > 0
20256 && it->glyph_row->used[LEFT_MARGIN_AREA] == 0)
20258 it->glyph_row->glyphs[LEFT_MARGIN_AREA][0] = space_glyph;
20259 it->glyph_row->glyphs[LEFT_MARGIN_AREA][0].face_id =
20260 default_face->id;
20261 it->glyph_row->used[LEFT_MARGIN_AREA] = 1;
20263 if (WINDOW_RIGHT_MARGIN_WIDTH (it->w) > 0
20264 && it->glyph_row->used[RIGHT_MARGIN_AREA] == 0)
20266 it->glyph_row->glyphs[RIGHT_MARGIN_AREA][0] = space_glyph;
20267 it->glyph_row->glyphs[RIGHT_MARGIN_AREA][0].face_id =
20268 default_face->id;
20269 it->glyph_row->used[RIGHT_MARGIN_AREA] = 1;
20272 #ifdef HAVE_WINDOW_SYSTEM
20273 if (it->glyph_row->reversed_p)
20275 /* Prepend a stretch glyph to the row, such that the
20276 rightmost glyph will be drawn flushed all the way to the
20277 right margin of the window. The stretch glyph that will
20278 occupy the empty space, if any, to the left of the
20279 glyphs. */
20280 struct font *font = face->font ? face->font : FRAME_FONT (f);
20281 struct glyph *row_start = it->glyph_row->glyphs[TEXT_AREA];
20282 struct glyph *row_end = row_start + it->glyph_row->used[TEXT_AREA];
20283 struct glyph *g;
20284 int row_width, stretch_ascent, stretch_width;
20285 struct text_pos saved_pos;
20286 int saved_face_id;
20287 bool saved_avoid_cursor, saved_box_start;
20289 for (row_width = 0, g = row_start; g < row_end; g++)
20290 row_width += g->pixel_width;
20292 /* FIXME: There are various minor display glitches in R2L
20293 rows when only one of the fringes is missing. The
20294 strange condition below produces the least bad effect. */
20295 if ((WINDOW_LEFT_FRINGE_WIDTH (it->w) == 0)
20296 == (WINDOW_RIGHT_FRINGE_WIDTH (it->w) == 0)
20297 || WINDOW_RIGHT_FRINGE_WIDTH (it->w) != 0)
20298 stretch_width = window_box_width (it->w, TEXT_AREA);
20299 else
20300 stretch_width = it->last_visible_x - it->first_visible_x;
20301 stretch_width -= row_width;
20303 if (stretch_width > 0)
20305 stretch_ascent =
20306 (((it->ascent + it->descent)
20307 * FONT_BASE (font)) / FONT_HEIGHT (font));
20308 saved_pos = it->position;
20309 memset (&it->position, 0, sizeof it->position);
20310 saved_avoid_cursor = it->avoid_cursor_p;
20311 it->avoid_cursor_p = true;
20312 saved_face_id = it->face_id;
20313 saved_box_start = it->start_of_box_run_p;
20314 /* The last row's stretch glyph should get the default
20315 face, to avoid painting the rest of the window with
20316 the region face, if the region ends at ZV. */
20317 if (it->glyph_row->ends_at_zv_p)
20318 it->face_id = default_face->id;
20319 else
20320 it->face_id = face->id;
20321 it->start_of_box_run_p = false;
20322 append_stretch_glyph (it, Qnil, stretch_width,
20323 it->ascent + it->descent, stretch_ascent);
20324 it->position = saved_pos;
20325 it->avoid_cursor_p = saved_avoid_cursor;
20326 it->face_id = saved_face_id;
20327 it->start_of_box_run_p = saved_box_start;
20329 /* If stretch_width comes out negative, it means that the
20330 last glyph is only partially visible. In R2L rows, we
20331 want the leftmost glyph to be partially visible, so we
20332 need to give the row the corresponding left offset. */
20333 if (stretch_width < 0)
20334 it->glyph_row->x = stretch_width;
20336 #endif /* HAVE_WINDOW_SYSTEM */
20338 else
20340 /* Save some values that must not be changed. */
20341 int saved_x = it->current_x;
20342 struct text_pos saved_pos;
20343 Lisp_Object saved_object;
20344 enum display_element_type saved_what = it->what;
20345 int saved_face_id = it->face_id;
20347 saved_object = it->object;
20348 saved_pos = it->position;
20350 it->what = IT_CHARACTER;
20351 memset (&it->position, 0, sizeof it->position);
20352 it->object = Qnil;
20353 it->c = it->char_to_display = ' ';
20354 it->len = 1;
20356 if (WINDOW_LEFT_MARGIN_WIDTH (it->w) > 0
20357 && (it->glyph_row->used[LEFT_MARGIN_AREA]
20358 < WINDOW_LEFT_MARGIN_WIDTH (it->w))
20359 && !it->glyph_row->mode_line_p
20360 && default_face->background != FRAME_BACKGROUND_PIXEL (f))
20362 struct glyph *g = it->glyph_row->glyphs[LEFT_MARGIN_AREA];
20363 struct glyph *e = g + it->glyph_row->used[LEFT_MARGIN_AREA];
20365 for (it->current_x = 0; g < e; g++)
20366 it->current_x += g->pixel_width;
20368 it->area = LEFT_MARGIN_AREA;
20369 it->face_id = default_face->id;
20370 while (it->glyph_row->used[LEFT_MARGIN_AREA]
20371 < WINDOW_LEFT_MARGIN_WIDTH (it->w)
20372 && g < it->glyph_row->glyphs[TEXT_AREA])
20374 PRODUCE_GLYPHS (it);
20375 /* term.c:produce_glyphs advances it->current_x only for
20376 TEXT_AREA. */
20377 it->current_x += it->pixel_width;
20378 g++;
20381 it->current_x = saved_x;
20382 it->area = TEXT_AREA;
20385 /* The last row's blank glyphs should get the default face, to
20386 avoid painting the rest of the window with the region face,
20387 if the region ends at ZV. */
20388 if (it->glyph_row->ends_at_zv_p)
20389 it->face_id = default_face->id;
20390 else
20391 it->face_id = face->id;
20392 PRODUCE_GLYPHS (it);
20394 while (it->current_x <= it->last_visible_x)
20395 PRODUCE_GLYPHS (it);
20397 if (WINDOW_RIGHT_MARGIN_WIDTH (it->w) > 0
20398 && (it->glyph_row->used[RIGHT_MARGIN_AREA]
20399 < WINDOW_RIGHT_MARGIN_WIDTH (it->w))
20400 && !it->glyph_row->mode_line_p
20401 && default_face->background != FRAME_BACKGROUND_PIXEL (f))
20403 struct glyph *g = it->glyph_row->glyphs[RIGHT_MARGIN_AREA];
20404 struct glyph *e = g + it->glyph_row->used[RIGHT_MARGIN_AREA];
20406 for ( ; g < e; g++)
20407 it->current_x += g->pixel_width;
20409 it->area = RIGHT_MARGIN_AREA;
20410 it->face_id = default_face->id;
20411 while (it->glyph_row->used[RIGHT_MARGIN_AREA]
20412 < WINDOW_RIGHT_MARGIN_WIDTH (it->w)
20413 && g < it->glyph_row->glyphs[LAST_AREA])
20415 PRODUCE_GLYPHS (it);
20416 it->current_x += it->pixel_width;
20417 g++;
20420 it->area = TEXT_AREA;
20423 /* Don't count these blanks really. It would let us insert a left
20424 truncation glyph below and make us set the cursor on them, maybe. */
20425 it->current_x = saved_x;
20426 it->object = saved_object;
20427 it->position = saved_pos;
20428 it->what = saved_what;
20429 it->face_id = saved_face_id;
20434 /* Value is true if text starting at CHARPOS in current_buffer is
20435 trailing whitespace. */
20437 static bool
20438 trailing_whitespace_p (ptrdiff_t charpos)
20440 ptrdiff_t bytepos = CHAR_TO_BYTE (charpos);
20441 int c = 0;
20443 while (bytepos < ZV_BYTE
20444 && (c = FETCH_CHAR (bytepos),
20445 c == ' ' || c == '\t'))
20446 ++bytepos;
20448 if (bytepos >= ZV_BYTE || c == '\n' || c == '\r')
20450 if (bytepos != PT_BYTE)
20451 return true;
20453 return false;
20457 /* Highlight trailing whitespace, if any, in ROW. */
20459 static void
20460 highlight_trailing_whitespace (struct frame *f, struct glyph_row *row)
20462 int used = row->used[TEXT_AREA];
20464 if (used)
20466 struct glyph *start = row->glyphs[TEXT_AREA];
20467 struct glyph *glyph = start + used - 1;
20469 if (row->reversed_p)
20471 /* Right-to-left rows need to be processed in the opposite
20472 direction, so swap the edge pointers. */
20473 glyph = start;
20474 start = row->glyphs[TEXT_AREA] + used - 1;
20477 /* Skip over glyphs inserted to display the cursor at the
20478 end of a line, for extending the face of the last glyph
20479 to the end of the line on terminals, and for truncation
20480 and continuation glyphs. */
20481 if (!row->reversed_p)
20483 while (glyph >= start
20484 && glyph->type == CHAR_GLYPH
20485 && NILP (glyph->object))
20486 --glyph;
20488 else
20490 while (glyph <= start
20491 && glyph->type == CHAR_GLYPH
20492 && NILP (glyph->object))
20493 ++glyph;
20496 /* If last glyph is a space or stretch, and it's trailing
20497 whitespace, set the face of all trailing whitespace glyphs in
20498 IT->glyph_row to `trailing-whitespace'. */
20499 if ((row->reversed_p ? glyph <= start : glyph >= start)
20500 && BUFFERP (glyph->object)
20501 && (glyph->type == STRETCH_GLYPH
20502 || (glyph->type == CHAR_GLYPH
20503 && glyph->u.ch == ' '))
20504 && trailing_whitespace_p (glyph->charpos))
20506 int face_id = lookup_named_face (f, Qtrailing_whitespace, false);
20507 if (face_id < 0)
20508 return;
20510 if (!row->reversed_p)
20512 while (glyph >= start
20513 && BUFFERP (glyph->object)
20514 && (glyph->type == STRETCH_GLYPH
20515 || (glyph->type == CHAR_GLYPH
20516 && glyph->u.ch == ' ')))
20517 (glyph--)->face_id = face_id;
20519 else
20521 while (glyph <= start
20522 && BUFFERP (glyph->object)
20523 && (glyph->type == STRETCH_GLYPH
20524 || (glyph->type == CHAR_GLYPH
20525 && glyph->u.ch == ' ')))
20526 (glyph++)->face_id = face_id;
20533 /* Value is true if glyph row ROW should be
20534 considered to hold the buffer position CHARPOS. */
20536 static bool
20537 row_for_charpos_p (struct glyph_row *row, ptrdiff_t charpos)
20539 bool result = true;
20541 if (charpos == CHARPOS (row->end.pos)
20542 || charpos == MATRIX_ROW_END_CHARPOS (row))
20544 /* Suppose the row ends on a string.
20545 Unless the row is continued, that means it ends on a newline
20546 in the string. If it's anything other than a display string
20547 (e.g., a before-string from an overlay), we don't want the
20548 cursor there. (This heuristic seems to give the optimal
20549 behavior for the various types of multi-line strings.)
20550 One exception: if the string has `cursor' property on one of
20551 its characters, we _do_ want the cursor there. */
20552 if (CHARPOS (row->end.string_pos) >= 0)
20554 if (row->continued_p)
20555 result = true;
20556 else
20558 /* Check for `display' property. */
20559 struct glyph *beg = row->glyphs[TEXT_AREA];
20560 struct glyph *end = beg + row->used[TEXT_AREA] - 1;
20561 struct glyph *glyph;
20563 result = false;
20564 for (glyph = end; glyph >= beg; --glyph)
20565 if (STRINGP (glyph->object))
20567 Lisp_Object prop
20568 = Fget_char_property (make_number (charpos),
20569 Qdisplay, Qnil);
20570 result =
20571 (!NILP (prop)
20572 && display_prop_string_p (prop, glyph->object));
20573 /* If there's a `cursor' property on one of the
20574 string's characters, this row is a cursor row,
20575 even though this is not a display string. */
20576 if (!result)
20578 Lisp_Object s = glyph->object;
20580 for ( ; glyph >= beg && EQ (glyph->object, s); --glyph)
20582 ptrdiff_t gpos = glyph->charpos;
20584 if (!NILP (Fget_char_property (make_number (gpos),
20585 Qcursor, s)))
20587 result = true;
20588 break;
20592 break;
20596 else if (MATRIX_ROW_ENDS_IN_MIDDLE_OF_CHAR_P (row))
20598 /* If the row ends in middle of a real character,
20599 and the line is continued, we want the cursor here.
20600 That's because CHARPOS (ROW->end.pos) would equal
20601 PT if PT is before the character. */
20602 if (!row->ends_in_ellipsis_p)
20603 result = row->continued_p;
20604 else
20605 /* If the row ends in an ellipsis, then
20606 CHARPOS (ROW->end.pos) will equal point after the
20607 invisible text. We want that position to be displayed
20608 after the ellipsis. */
20609 result = false;
20611 /* If the row ends at ZV, display the cursor at the end of that
20612 row instead of at the start of the row below. */
20613 else
20614 result = row->ends_at_zv_p;
20617 return result;
20620 /* Value is true if glyph row ROW should be
20621 used to hold the cursor. */
20623 static bool
20624 cursor_row_p (struct glyph_row *row)
20626 return row_for_charpos_p (row, PT);
20631 /* Push the property PROP so that it will be rendered at the current
20632 position in IT. Return true if PROP was successfully pushed, false
20633 otherwise. Called from handle_line_prefix to handle the
20634 `line-prefix' and `wrap-prefix' properties. */
20636 static bool
20637 push_prefix_prop (struct it *it, Lisp_Object prop)
20639 struct text_pos pos =
20640 STRINGP (it->string) ? it->current.string_pos : it->current.pos;
20642 eassert (it->method == GET_FROM_BUFFER
20643 || it->method == GET_FROM_DISPLAY_VECTOR
20644 || it->method == GET_FROM_STRING
20645 || it->method == GET_FROM_IMAGE);
20647 /* We need to save the current buffer/string position, so it will be
20648 restored by pop_it, because iterate_out_of_display_property
20649 depends on that being set correctly, but some situations leave
20650 it->position not yet set when this function is called. */
20651 push_it (it, &pos);
20653 if (STRINGP (prop))
20655 if (SCHARS (prop) == 0)
20657 pop_it (it);
20658 return false;
20661 it->string = prop;
20662 it->string_from_prefix_prop_p = true;
20663 it->multibyte_p = STRING_MULTIBYTE (it->string);
20664 it->current.overlay_string_index = -1;
20665 IT_STRING_CHARPOS (*it) = IT_STRING_BYTEPOS (*it) = 0;
20666 it->end_charpos = it->string_nchars = SCHARS (it->string);
20667 it->method = GET_FROM_STRING;
20668 it->stop_charpos = 0;
20669 it->prev_stop = 0;
20670 it->base_level_stop = 0;
20671 it->cmp_it.id = -1;
20673 /* Force paragraph direction to be that of the parent
20674 buffer/string. */
20675 if (it->bidi_p && it->bidi_it.paragraph_dir == R2L)
20676 it->paragraph_embedding = it->bidi_it.paragraph_dir;
20677 else
20678 it->paragraph_embedding = L2R;
20680 /* Set up the bidi iterator for this display string. */
20681 if (it->bidi_p)
20683 it->bidi_it.string.lstring = it->string;
20684 it->bidi_it.string.s = NULL;
20685 it->bidi_it.string.schars = it->end_charpos;
20686 it->bidi_it.string.bufpos = IT_CHARPOS (*it);
20687 it->bidi_it.string.from_disp_str = it->string_from_display_prop_p;
20688 it->bidi_it.string.unibyte = !it->multibyte_p;
20689 it->bidi_it.w = it->w;
20690 bidi_init_it (0, 0, FRAME_WINDOW_P (it->f), &it->bidi_it);
20693 else if (CONSP (prop) && EQ (XCAR (prop), Qspace))
20695 it->method = GET_FROM_STRETCH;
20696 it->object = prop;
20698 #ifdef HAVE_WINDOW_SYSTEM
20699 else if (IMAGEP (prop))
20701 it->what = IT_IMAGE;
20702 it->image_id = lookup_image (it->f, prop);
20703 it->method = GET_FROM_IMAGE;
20705 #endif /* HAVE_WINDOW_SYSTEM */
20706 else
20708 pop_it (it); /* bogus display property, give up */
20709 return false;
20712 return true;
20715 /* Return the character-property PROP at the current position in IT. */
20717 static Lisp_Object
20718 get_it_property (struct it *it, Lisp_Object prop)
20720 Lisp_Object position, object = it->object;
20722 if (STRINGP (object))
20723 position = make_number (IT_STRING_CHARPOS (*it));
20724 else if (BUFFERP (object))
20726 position = make_number (IT_CHARPOS (*it));
20727 object = it->window;
20729 else
20730 return Qnil;
20732 return Fget_char_property (position, prop, object);
20735 /* See if there's a line- or wrap-prefix, and if so, push it on IT. */
20737 static void
20738 handle_line_prefix (struct it *it)
20740 Lisp_Object prefix;
20742 if (it->continuation_lines_width > 0)
20744 prefix = get_it_property (it, Qwrap_prefix);
20745 if (NILP (prefix))
20746 prefix = Vwrap_prefix;
20748 else
20750 prefix = get_it_property (it, Qline_prefix);
20751 if (NILP (prefix))
20752 prefix = Vline_prefix;
20754 if (! NILP (prefix) && push_prefix_prop (it, prefix))
20756 /* If the prefix is wider than the window, and we try to wrap
20757 it, it would acquire its own wrap prefix, and so on till the
20758 iterator stack overflows. So, don't wrap the prefix. */
20759 it->line_wrap = TRUNCATE;
20760 it->avoid_cursor_p = true;
20766 /* Remove N glyphs at the start of a reversed IT->glyph_row. Called
20767 only for R2L lines from display_line and display_string, when they
20768 decide that too many glyphs were produced by PRODUCE_GLYPHS, and
20769 the line/string needs to be continued on the next glyph row. */
20770 static void
20771 unproduce_glyphs (struct it *it, int n)
20773 struct glyph *glyph, *end;
20775 eassert (it->glyph_row);
20776 eassert (it->glyph_row->reversed_p);
20777 eassert (it->area == TEXT_AREA);
20778 eassert (n <= it->glyph_row->used[TEXT_AREA]);
20780 if (n > it->glyph_row->used[TEXT_AREA])
20781 n = it->glyph_row->used[TEXT_AREA];
20782 glyph = it->glyph_row->glyphs[TEXT_AREA] + n;
20783 end = it->glyph_row->glyphs[TEXT_AREA] + it->glyph_row->used[TEXT_AREA];
20784 for ( ; glyph < end; glyph++)
20785 glyph[-n] = *glyph;
20788 /* Find the positions in a bidi-reordered ROW to serve as ROW->minpos
20789 and ROW->maxpos. */
20790 static void
20791 find_row_edges (struct it *it, struct glyph_row *row,
20792 ptrdiff_t min_pos, ptrdiff_t min_bpos,
20793 ptrdiff_t max_pos, ptrdiff_t max_bpos)
20795 /* FIXME: Revisit this when glyph ``spilling'' in continuation
20796 lines' rows is implemented for bidi-reordered rows. */
20798 /* ROW->minpos is the value of min_pos, the minimal buffer position
20799 we have in ROW, or ROW->start.pos if that is smaller. */
20800 if (min_pos <= ZV && min_pos < row->start.pos.charpos)
20801 SET_TEXT_POS (row->minpos, min_pos, min_bpos);
20802 else
20803 /* We didn't find buffer positions smaller than ROW->start, or
20804 didn't find _any_ valid buffer positions in any of the glyphs,
20805 so we must trust the iterator's computed positions. */
20806 row->minpos = row->start.pos;
20807 if (max_pos <= 0)
20809 max_pos = CHARPOS (it->current.pos);
20810 max_bpos = BYTEPOS (it->current.pos);
20813 /* Here are the various use-cases for ending the row, and the
20814 corresponding values for ROW->maxpos:
20816 Line ends in a newline from buffer eol_pos + 1
20817 Line is continued from buffer max_pos + 1
20818 Line is truncated on right it->current.pos
20819 Line ends in a newline from string max_pos + 1(*)
20820 (*) + 1 only when line ends in a forward scan
20821 Line is continued from string max_pos
20822 Line is continued from display vector max_pos
20823 Line is entirely from a string min_pos == max_pos
20824 Line is entirely from a display vector min_pos == max_pos
20825 Line that ends at ZV ZV
20827 If you discover other use-cases, please add them here as
20828 appropriate. */
20829 if (row->ends_at_zv_p)
20830 row->maxpos = it->current.pos;
20831 else if (row->used[TEXT_AREA])
20833 bool seen_this_string = false;
20834 struct glyph_row *r1 = row - 1;
20836 /* Did we see the same display string on the previous row? */
20837 if (STRINGP (it->object)
20838 /* this is not the first row */
20839 && row > it->w->desired_matrix->rows
20840 /* previous row is not the header line */
20841 && !r1->mode_line_p
20842 /* previous row also ends in a newline from a string */
20843 && r1->ends_in_newline_from_string_p)
20845 struct glyph *start, *end;
20847 /* Search for the last glyph of the previous row that came
20848 from buffer or string. Depending on whether the row is
20849 L2R or R2L, we need to process it front to back or the
20850 other way round. */
20851 if (!r1->reversed_p)
20853 start = r1->glyphs[TEXT_AREA];
20854 end = start + r1->used[TEXT_AREA];
20855 /* Glyphs inserted by redisplay have nil as their object. */
20856 while (end > start
20857 && NILP ((end - 1)->object)
20858 && (end - 1)->charpos <= 0)
20859 --end;
20860 if (end > start)
20862 if (EQ ((end - 1)->object, it->object))
20863 seen_this_string = true;
20865 else
20866 /* If all the glyphs of the previous row were inserted
20867 by redisplay, it means the previous row was
20868 produced from a single newline, which is only
20869 possible if that newline came from the same string
20870 as the one which produced this ROW. */
20871 seen_this_string = true;
20873 else
20875 end = r1->glyphs[TEXT_AREA] - 1;
20876 start = end + r1->used[TEXT_AREA];
20877 while (end < start
20878 && NILP ((end + 1)->object)
20879 && (end + 1)->charpos <= 0)
20880 ++end;
20881 if (end < start)
20883 if (EQ ((end + 1)->object, it->object))
20884 seen_this_string = true;
20886 else
20887 seen_this_string = true;
20890 /* Take note of each display string that covers a newline only
20891 once, the first time we see it. This is for when a display
20892 string includes more than one newline in it. */
20893 if (row->ends_in_newline_from_string_p && !seen_this_string)
20895 /* If we were scanning the buffer forward when we displayed
20896 the string, we want to account for at least one buffer
20897 position that belongs to this row (position covered by
20898 the display string), so that cursor positioning will
20899 consider this row as a candidate when point is at the end
20900 of the visual line represented by this row. This is not
20901 required when scanning back, because max_pos will already
20902 have a much larger value. */
20903 if (CHARPOS (row->end.pos) > max_pos)
20904 INC_BOTH (max_pos, max_bpos);
20905 SET_TEXT_POS (row->maxpos, max_pos, max_bpos);
20907 else if (CHARPOS (it->eol_pos) > 0)
20908 SET_TEXT_POS (row->maxpos,
20909 CHARPOS (it->eol_pos) + 1, BYTEPOS (it->eol_pos) + 1);
20910 else if (row->continued_p)
20912 /* If max_pos is different from IT's current position, it
20913 means IT->method does not belong to the display element
20914 at max_pos. However, it also means that the display
20915 element at max_pos was displayed in its entirety on this
20916 line, which is equivalent to saying that the next line
20917 starts at the next buffer position. */
20918 if (IT_CHARPOS (*it) == max_pos && it->method != GET_FROM_BUFFER)
20919 SET_TEXT_POS (row->maxpos, max_pos, max_bpos);
20920 else
20922 INC_BOTH (max_pos, max_bpos);
20923 SET_TEXT_POS (row->maxpos, max_pos, max_bpos);
20926 else if (row->truncated_on_right_p)
20927 /* display_line already called reseat_at_next_visible_line_start,
20928 which puts the iterator at the beginning of the next line, in
20929 the logical order. */
20930 row->maxpos = it->current.pos;
20931 else if (max_pos == min_pos && it->method != GET_FROM_BUFFER)
20932 /* A line that is entirely from a string/image/stretch... */
20933 row->maxpos = row->minpos;
20934 else
20935 emacs_abort ();
20937 else
20938 row->maxpos = it->current.pos;
20941 /* Like display_count_lines, but capable of counting outside of the
20942 current narrowed region. */
20943 static ptrdiff_t
20944 display_count_lines_logically (ptrdiff_t start_byte, ptrdiff_t limit_byte,
20945 ptrdiff_t count, ptrdiff_t *byte_pos_ptr)
20947 if (!display_line_numbers_widen || (BEGV == BEG && ZV == Z))
20948 return display_count_lines (start_byte, limit_byte, count, byte_pos_ptr);
20950 ptrdiff_t val;
20951 ptrdiff_t pdl_count = SPECPDL_INDEX ();
20952 record_unwind_protect (save_restriction_restore, save_restriction_save ());
20953 Fwiden ();
20954 val = display_count_lines (start_byte, limit_byte, count, byte_pos_ptr);
20955 unbind_to (pdl_count, Qnil);
20956 return val;
20959 /* Count the number of screen lines in window IT->w between character
20960 position IT_CHARPOS(*IT) and the line showing that window's point. */
20961 static ptrdiff_t
20962 display_count_lines_visually (struct it *it)
20964 struct it tem_it;
20965 ptrdiff_t to;
20966 struct text_pos from;
20968 /* If we already calculated a relative line number, use that. This
20969 trick relies on the fact that visual lines (a.k.a. "glyph rows")
20970 are laid out sequentially, one by one, for each sequence of calls
20971 to display_line or other similar function that follows a call to
20972 init_iterator. */
20973 if (it->lnum_bytepos > 0)
20974 return it->lnum + 1;
20975 else
20977 ptrdiff_t count = SPECPDL_INDEX ();
20979 if (IT_CHARPOS (*it) <= PT)
20981 from = it->current.pos;
20982 to = PT;
20984 else
20986 SET_TEXT_POS (from, PT, PT_BYTE);
20987 to = IT_CHARPOS (*it);
20989 start_display (&tem_it, it->w, from);
20990 /* Need to disable visual mode temporarily, since otherwise the
20991 call to move_it_to will cause infinite recursion. */
20992 specbind (Qdisplay_line_numbers, Qrelative);
20993 /* Some redisplay optimizations could invoke us very far from
20994 PT, which will make the caller painfully slow. There should
20995 be no need to go too far beyond the window's bottom, as any
20996 such optimization will fail to show point anyway. */
20997 move_it_to (&tem_it, to, -1,
20998 tem_it.last_visible_y
20999 + (SCROLL_LIMIT + 10) * FRAME_LINE_HEIGHT (tem_it.f),
21000 -1, MOVE_TO_POS | MOVE_TO_Y);
21001 unbind_to (count, Qnil);
21002 return IT_CHARPOS (*it) <= PT ? -tem_it.vpos : tem_it.vpos;
21006 /* Produce the line-number glyphs for the current glyph_row. If
21007 IT->glyph_row is non-NULL, populate the row with the produced
21008 glyphs. */
21009 static void
21010 maybe_produce_line_number (struct it *it)
21012 ptrdiff_t last_line = it->lnum;
21013 ptrdiff_t start_from, bytepos;
21014 ptrdiff_t this_line;
21015 bool first_time = false;
21016 ptrdiff_t beg_byte = display_line_numbers_widen ? BEG_BYTE : BEGV_BYTE;
21017 ptrdiff_t z_byte = display_line_numbers_widen ? Z_BYTE : ZV_BYTE;
21018 void *itdata = bidi_shelve_cache ();
21020 if (EQ (Vdisplay_line_numbers, Qvisual))
21021 this_line = display_count_lines_visually (it);
21022 else
21024 if (!last_line)
21026 /* If possible, reuse data cached by line-number-mode. */
21027 if (it->w->base_line_number > 0
21028 && it->w->base_line_pos > 0
21029 && it->w->base_line_pos <= IT_CHARPOS (*it)
21030 /* line-number-mode always displays narrowed line
21031 numbers, so we cannot use its data if the user wants
21032 line numbers that disregard narrowing, or if the
21033 buffer's narrowing has just changed. */
21034 && !(display_line_numbers_widen
21035 && (BEG_BYTE != BEGV_BYTE || Z_BYTE != ZV_BYTE))
21036 && !current_buffer->clip_changed)
21038 start_from = CHAR_TO_BYTE (it->w->base_line_pos);
21039 last_line = it->w->base_line_number - 1;
21041 else
21042 start_from = beg_byte;
21043 if (!it->lnum_bytepos)
21044 first_time = true;
21046 else
21047 start_from = it->lnum_bytepos;
21049 /* Paranoia: what if someone changes the narrowing since the
21050 last time display_line was called? Shouldn't really happen,
21051 but who knows what some crazy Lisp invoked by :eval could do? */
21052 if (!(beg_byte <= start_from && start_from <= z_byte))
21054 last_line = 0;
21055 start_from = beg_byte;
21058 this_line =
21059 last_line + display_count_lines_logically (start_from,
21060 IT_BYTEPOS (*it),
21061 IT_CHARPOS (*it), &bytepos);
21062 eassert (this_line > 0 || (this_line == 0 && start_from == beg_byte));
21063 eassert (bytepos == IT_BYTEPOS (*it));
21066 /* Record the line number information. */
21067 if (this_line != last_line || !it->lnum_bytepos)
21069 it->lnum = this_line;
21070 it->lnum_bytepos = IT_BYTEPOS (*it);
21073 /* Produce the glyphs for the line number. */
21074 struct it tem_it;
21075 char lnum_buf[INT_STRLEN_BOUND (ptrdiff_t) + 1];
21076 bool beyond_zv = IT_BYTEPOS (*it) >= ZV_BYTE ? true : false;
21077 ptrdiff_t lnum_offset = -1; /* to produce 1-based line numbers */
21078 int lnum_face_id = merge_faces (it->f, Qline_number, 0, DEFAULT_FACE_ID);
21079 int current_lnum_face_id
21080 = merge_faces (it->f, Qline_number_current_line, 0, DEFAULT_FACE_ID);
21081 /* Compute point's line number if needed. */
21082 if ((EQ (Vdisplay_line_numbers, Qrelative)
21083 || EQ (Vdisplay_line_numbers, Qvisual)
21084 || lnum_face_id != current_lnum_face_id)
21085 && !it->pt_lnum)
21087 ptrdiff_t ignored;
21088 if (PT_BYTE > it->lnum_bytepos && !EQ (Vdisplay_line_numbers, Qvisual))
21089 it->pt_lnum =
21090 this_line + display_count_lines_logically (it->lnum_bytepos, PT_BYTE,
21091 PT, &ignored);
21092 else
21093 it->pt_lnum = display_count_lines_logically (beg_byte, PT_BYTE, PT,
21094 &ignored);
21096 /* Compute the required width if needed. */
21097 if (!it->lnum_width)
21099 if (NATNUMP (Vdisplay_line_numbers_width))
21100 it->lnum_width = XFASTINT (Vdisplay_line_numbers_width);
21102 /* Max line number to be displayed cannot be more than the one
21103 corresponding to the last row of the desired matrix. */
21104 ptrdiff_t max_lnum;
21106 if (NILP (Vdisplay_line_numbers_current_absolute)
21107 && (EQ (Vdisplay_line_numbers, Qrelative)
21108 || EQ (Vdisplay_line_numbers, Qvisual)))
21109 /* We subtract one more because the current line is always
21110 zero in this mode. */
21111 max_lnum = it->w->desired_matrix->nrows - 2;
21112 else if (EQ (Vdisplay_line_numbers, Qvisual))
21113 max_lnum = it->pt_lnum + it->w->desired_matrix->nrows - 1;
21114 else
21115 max_lnum = this_line + it->w->desired_matrix->nrows - 1 - it->vpos;
21116 max_lnum = max (1, max_lnum);
21117 it->lnum_width = max (it->lnum_width, log10 (max_lnum) + 1);
21118 eassert (it->lnum_width > 0);
21120 if (EQ (Vdisplay_line_numbers, Qrelative))
21121 lnum_offset = it->pt_lnum;
21122 else if (EQ (Vdisplay_line_numbers, Qvisual))
21123 lnum_offset = 0;
21125 /* Under 'relative', display the absolute line number for the
21126 current line, unless the user requests otherwise. */
21127 ptrdiff_t lnum_to_display = eabs (this_line - lnum_offset);
21128 if ((EQ (Vdisplay_line_numbers, Qrelative)
21129 || EQ (Vdisplay_line_numbers, Qvisual))
21130 && lnum_to_display == 0
21131 && !NILP (Vdisplay_line_numbers_current_absolute))
21132 lnum_to_display = it->pt_lnum + 1;
21133 /* In L2R rows we need to append the blank separator, in R2L
21134 rows we need to prepend it. But this function is usually
21135 called when no display elements were produced from the
21136 following line, so the paragraph direction might be unknown.
21137 Therefore we cheat and add 2 blanks, one on either side. */
21138 pint2str (lnum_buf, it->lnum_width + 1, lnum_to_display);
21139 strcat (lnum_buf, " ");
21141 /* Setup for producing the glyphs. */
21142 init_iterator (&tem_it, it->w, -1, -1, &scratch_glyph_row,
21143 /* FIXME: Use specialized face. */
21144 DEFAULT_FACE_ID);
21145 scratch_glyph_row.reversed_p = false;
21146 scratch_glyph_row.used[TEXT_AREA] = 0;
21147 SET_TEXT_POS (tem_it.position, 0, 0);
21148 tem_it.avoid_cursor_p = true;
21149 tem_it.bidi_p = true;
21150 tem_it.bidi_it.type = WEAK_EN;
21151 /* According to UAX#9, EN goes up 2 levels in L2R paragraph and
21152 1 level in R2L paragraphs. Emulate that, assuming we are in
21153 an L2R paragraph. */
21154 tem_it.bidi_it.resolved_level = 2;
21156 /* Produce glyphs for the line number in a scratch glyph_row. */
21157 int n_glyphs_before;
21158 for (const char *p = lnum_buf; *p; p++)
21160 /* For continuation lines and lines after ZV, instead of a line
21161 number, produce a blank prefix of the same width. Use the
21162 default face for the blank field beyond ZV. */
21163 if (beyond_zv)
21164 tem_it.face_id = it->base_face_id;
21165 else if (lnum_face_id != current_lnum_face_id
21166 && (EQ (Vdisplay_line_numbers, Qvisual)
21167 ? this_line == 0
21168 : this_line == it->pt_lnum))
21169 tem_it.face_id = current_lnum_face_id;
21170 else
21171 tem_it.face_id = lnum_face_id;
21172 if (beyond_zv
21173 /* Don't display the same line number more than once. */
21174 || (!EQ (Vdisplay_line_numbers, Qvisual)
21175 && (it->continuation_lines_width > 0
21176 || (this_line == last_line && !first_time))))
21177 tem_it.c = tem_it.char_to_display = ' ';
21178 else
21179 tem_it.c = tem_it.char_to_display = *p;
21180 tem_it.len = 1;
21181 n_glyphs_before = scratch_glyph_row.used[TEXT_AREA];
21182 /* Make sure these glyphs will have a "position" of -1. */
21183 SET_TEXT_POS (tem_it.position, -1, -1);
21184 PRODUCE_GLYPHS (&tem_it);
21186 /* Stop producing glyphs if we don't have enough space on
21187 this line. FIXME: should we refrain from producing the
21188 line number at all in that case? */
21189 if (tem_it.current_x > tem_it.last_visible_x)
21191 scratch_glyph_row.used[TEXT_AREA] = n_glyphs_before;
21192 break;
21196 /* Record the width in pixels we need for the line number display. */
21197 it->lnum_pixel_width = tem_it.current_x;
21198 /* Copy the produced glyphs into IT's glyph_row. */
21199 struct glyph *g = scratch_glyph_row.glyphs[TEXT_AREA];
21200 struct glyph *e = g + scratch_glyph_row.used[TEXT_AREA];
21201 struct glyph *p = it->glyph_row ? it->glyph_row->glyphs[TEXT_AREA] : NULL;
21202 short *u = it->glyph_row ? &it->glyph_row->used[TEXT_AREA] : NULL;
21204 eassert (it->glyph_row == NULL || it->glyph_row->used[TEXT_AREA] == 0);
21206 for ( ; g < e; g++)
21208 it->current_x += g->pixel_width;
21209 /* The following is important when this function is called
21210 from move_it_in_display_line_to: HPOS is incremented only
21211 when we are in the visible portion of the glyph row. */
21212 if (it->current_x > it->first_visible_x)
21213 it->hpos++;
21214 if (p)
21216 *p++ = *g;
21217 (*u)++;
21221 /* Update IT's metrics due to glyphs produced for line numbers. */
21222 if (it->glyph_row)
21224 struct glyph_row *row = it->glyph_row;
21226 it->max_ascent = max (row->ascent, tem_it.max_ascent);
21227 it->max_descent = max (row->height - row->ascent, tem_it.max_descent);
21228 it->max_phys_ascent = max (row->phys_ascent, tem_it.max_phys_ascent);
21229 it->max_phys_descent = max (row->phys_height - row->phys_ascent,
21230 tem_it.max_phys_descent);
21232 else
21234 it->max_ascent = max (it->max_ascent, tem_it.max_ascent);
21235 it->max_descent = max (it->max_descent, tem_it.max_descent);
21236 it->max_phys_ascent = max (it->max_phys_ascent, tem_it.max_phys_ascent);
21237 it->max_phys_descent = max (it->max_phys_descent, tem_it.max_phys_descent);
21240 it->line_number_produced_p = true;
21242 bidi_unshelve_cache (itdata, false);
21245 /* Return true if this glyph row needs a line number to be produced
21246 for it. */
21247 static bool
21248 should_produce_line_number (struct it *it)
21250 if (NILP (Vdisplay_line_numbers))
21251 return false;
21253 /* Don't display line numbers in minibuffer windows. */
21254 if (MINI_WINDOW_P (it->w))
21255 return false;
21257 #ifdef HAVE_WINDOW_SYSTEM
21258 /* Don't display line number in tooltip frames. */
21259 if (FRAME_TOOLTIP_P (XFRAME (WINDOW_FRAME (it->w))))
21260 return false;
21261 #endif
21263 /* If the character at current position has a non-nil special
21264 property, disable line numbers for this row. This is for
21265 packages such as company-mode, which need this for their tricky
21266 layout, where line numbers get in the way. */
21267 Lisp_Object val = Fget_char_property (make_number (IT_CHARPOS (*it)),
21268 Qdisplay_line_numbers_disable,
21269 it->window);
21270 /* For ZV, we need to also look in empty overlays at that point,
21271 because get-char-property always returns nil for ZV, except if
21272 the property is in 'default-text-properties'. */
21273 if (NILP (val) && IT_CHARPOS (*it) >= ZV)
21274 val = disable_line_numbers_overlay_at_eob ();
21275 return NILP (val) ? true : false;
21278 /* Return true if ROW has no glyphs except those inserted by the
21279 display engine. This is needed for indicate-empty-lines and
21280 similar features when the glyph row starts with glyphs which didn't
21281 come from buffer or string. */
21282 static bool
21283 row_text_area_empty (struct glyph_row *row)
21285 if (!row->reversed_p)
21287 for (struct glyph *g = row->glyphs[TEXT_AREA];
21288 g < row->glyphs[TEXT_AREA] + row->used[TEXT_AREA];
21289 g++)
21290 if (!NILP (g->object) || g->charpos > 0)
21291 return false;
21293 else
21295 for (struct glyph *g = row->glyphs[TEXT_AREA] + row->used[TEXT_AREA] - 1;
21296 g > row->glyphs[TEXT_AREA];
21297 g--)
21298 if (!NILP ((g - 1)->object) || (g - 1)->charpos > 0)
21299 return false;
21302 return true;
21305 /* Construct the glyph row IT->glyph_row in the desired matrix of
21306 IT->w from text at the current position of IT. See dispextern.h
21307 for an overview of struct it. Value is true if
21308 IT->glyph_row displays text, as opposed to a line displaying ZV
21309 only. CURSOR_VPOS is the window-relative vertical position of
21310 the glyph row displaying the cursor, or -1 if unknown. */
21312 static bool
21313 display_line (struct it *it, int cursor_vpos)
21315 struct glyph_row *row = it->glyph_row;
21316 Lisp_Object overlay_arrow_string;
21317 struct it wrap_it;
21318 void *wrap_data = NULL;
21319 bool may_wrap = false;
21320 int wrap_x UNINIT;
21321 int wrap_row_used = -1;
21322 int wrap_row_ascent UNINIT, wrap_row_height UNINIT;
21323 int wrap_row_phys_ascent UNINIT, wrap_row_phys_height UNINIT;
21324 int wrap_row_extra_line_spacing UNINIT;
21325 ptrdiff_t wrap_row_min_pos UNINIT, wrap_row_min_bpos UNINIT;
21326 ptrdiff_t wrap_row_max_pos UNINIT, wrap_row_max_bpos UNINIT;
21327 int cvpos;
21328 ptrdiff_t min_pos = ZV + 1, max_pos = 0;
21329 ptrdiff_t min_bpos UNINIT, max_bpos UNINIT;
21330 bool pending_handle_line_prefix = false;
21331 int header_line = window_wants_header_line (it->w);
21332 bool hscroll_this_line = (cursor_vpos >= 0
21333 && it->vpos == cursor_vpos - header_line
21334 && hscrolling_current_line_p (it->w));
21335 int first_visible_x = it->first_visible_x;
21336 int last_visible_x = it->last_visible_x;
21337 int x_incr = 0;
21339 /* We always start displaying at hpos zero even if hscrolled. */
21340 eassert (it->hpos == 0 && it->current_x == 0);
21342 if (MATRIX_ROW_VPOS (row, it->w->desired_matrix)
21343 >= it->w->desired_matrix->nrows)
21345 it->w->nrows_scale_factor++;
21346 it->f->fonts_changed = true;
21347 return false;
21350 /* Clear the result glyph row and enable it. */
21351 prepare_desired_row (it->w, row, false);
21353 row->y = it->current_y;
21354 row->start = it->start;
21355 row->continuation_lines_width = it->continuation_lines_width;
21356 row->displays_text_p = true;
21357 row->starts_in_middle_of_char_p = it->starts_in_middle_of_char_p;
21358 it->starts_in_middle_of_char_p = false;
21359 it->tab_offset = 0;
21360 it->line_number_produced_p = false;
21362 /* Arrange the overlays nicely for our purposes. Usually, we call
21363 display_line on only one line at a time, in which case this
21364 can't really hurt too much, or we call it on lines which appear
21365 one after another in the buffer, in which case all calls to
21366 recenter_overlay_lists but the first will be pretty cheap. */
21367 recenter_overlay_lists (current_buffer, IT_CHARPOS (*it));
21369 /* If we are going to display the cursor's line, account for the
21370 hscroll of that line. We subtract the window's min_hscroll,
21371 because that was already accounted for in init_iterator. */
21372 if (hscroll_this_line)
21373 x_incr =
21374 (window_hscroll_limited (it->w, it->f) - it->w->min_hscroll)
21375 * FRAME_COLUMN_WIDTH (it->f);
21377 bool line_number_needed = should_produce_line_number (it);
21379 /* Move over display elements that are not visible because we are
21380 hscrolled. This may stop at an x-position < first_visible_x
21381 if the first glyph is partially visible or if we hit a line end. */
21382 if (it->current_x < it->first_visible_x + x_incr)
21384 enum move_it_result move_result;
21386 this_line_min_pos = row->start.pos;
21387 if (hscroll_this_line)
21389 it->first_visible_x += x_incr;
21390 it->last_visible_x += x_incr;
21392 move_result = move_it_in_display_line_to (it, ZV, it->first_visible_x,
21393 MOVE_TO_POS | MOVE_TO_X);
21394 /* If we are under a large hscroll, move_it_in_display_line_to
21395 could hit the end of the line without reaching
21396 first_visible_x. Pretend that we did reach it. This is
21397 especially important on a TTY, where we will call
21398 extend_face_to_end_of_line, which needs to know how many
21399 blank glyphs to produce. */
21400 if (it->current_x < it->first_visible_x
21401 && (move_result == MOVE_NEWLINE_OR_CR
21402 || move_result == MOVE_POS_MATCH_OR_ZV))
21403 it->current_x = it->first_visible_x;
21405 /* In case move_it_in_display_line_to above "produced" the line
21406 number. */
21407 it->line_number_produced_p = false;
21409 /* Record the smallest positions seen while we moved over
21410 display elements that are not visible. This is needed by
21411 redisplay_internal for optimizing the case where the cursor
21412 stays inside the same line. The rest of this function only
21413 considers positions that are actually displayed, so
21414 RECORD_MAX_MIN_POS will not otherwise record positions that
21415 are hscrolled to the left of the left edge of the window. */
21416 min_pos = CHARPOS (this_line_min_pos);
21417 min_bpos = BYTEPOS (this_line_min_pos);
21419 /* Produce line number, if needed. */
21420 if (line_number_needed)
21421 maybe_produce_line_number (it);
21423 else if (it->area == TEXT_AREA)
21425 /* Line numbers should precede the line-prefix or wrap-prefix. */
21426 if (line_number_needed)
21427 maybe_produce_line_number (it);
21429 /* We only do this when not calling move_it_in_display_line_to
21430 above, because that function calls itself handle_line_prefix. */
21431 handle_line_prefix (it);
21433 else
21435 /* Line-prefix and wrap-prefix are always displayed in the text
21436 area. But if this is the first call to display_line after
21437 init_iterator, the iterator might have been set up to write
21438 into a marginal area, e.g. if the line begins with some
21439 display property that writes to the margins. So we need to
21440 wait with the call to handle_line_prefix until whatever
21441 writes to the margin has done its job. */
21442 pending_handle_line_prefix = true;
21445 /* Get the initial row height. This is either the height of the
21446 text hscrolled, if there is any, or zero. */
21447 row->ascent = it->max_ascent;
21448 row->height = it->max_ascent + it->max_descent;
21449 row->phys_ascent = it->max_phys_ascent;
21450 row->phys_height = it->max_phys_ascent + it->max_phys_descent;
21451 row->extra_line_spacing = it->max_extra_line_spacing;
21453 /* Utility macro to record max and min buffer positions seen until now. */
21454 #define RECORD_MAX_MIN_POS(IT) \
21455 do \
21457 bool composition_p \
21458 = !STRINGP ((IT)->string) && ((IT)->what == IT_COMPOSITION); \
21459 ptrdiff_t current_pos = \
21460 composition_p ? (IT)->cmp_it.charpos \
21461 : IT_CHARPOS (*(IT)); \
21462 ptrdiff_t current_bpos = \
21463 composition_p ? CHAR_TO_BYTE (current_pos) \
21464 : IT_BYTEPOS (*(IT)); \
21465 if (current_pos < min_pos) \
21467 min_pos = current_pos; \
21468 min_bpos = current_bpos; \
21470 if (IT_CHARPOS (*it) > max_pos) \
21472 max_pos = IT_CHARPOS (*it); \
21473 max_bpos = IT_BYTEPOS (*it); \
21476 while (false)
21478 /* Loop generating characters. The loop is left with IT on the next
21479 character to display. */
21480 while (true)
21482 int n_glyphs_before, hpos_before, x_before;
21483 int x, nglyphs;
21484 int ascent = 0, descent = 0, phys_ascent = 0, phys_descent = 0;
21486 /* Retrieve the next thing to display. Value is false if end of
21487 buffer reached. */
21488 if (!get_next_display_element (it))
21490 bool row_has_glyphs = false;
21491 /* Maybe add a space at the end of this line that is used to
21492 display the cursor there under X. Set the charpos of the
21493 first glyph of blank lines not corresponding to any text
21494 to -1. */
21495 if (IT_OVERFLOW_NEWLINE_INTO_FRINGE (it))
21496 row->exact_window_width_line_p = true;
21497 else if ((append_space_for_newline (it, true)
21498 && row->used[TEXT_AREA] == 1)
21499 || row->used[TEXT_AREA] == 0
21500 || (row_has_glyphs = row_text_area_empty (row)))
21502 row->glyphs[TEXT_AREA]->charpos = -1;
21503 /* Don't reset the displays_text_p flag if we are
21504 displaying line numbers or line-prefix. */
21505 if (!row_has_glyphs)
21506 row->displays_text_p = false;
21508 if (!NILP (BVAR (XBUFFER (it->w->contents), indicate_empty_lines))
21509 && (!MINI_WINDOW_P (it->w)))
21510 row->indicate_empty_line_p = true;
21513 it->continuation_lines_width = 0;
21514 /* Reset those iterator values set from display property
21515 values. This is for the case when the display property
21516 ends at ZV, and is not a replacing property, so pop_it is
21517 not called. */
21518 it->font_height = Qnil;
21519 it->voffset = 0;
21520 row->ends_at_zv_p = true;
21521 /* A row that displays right-to-left text must always have
21522 its last face extended all the way to the end of line,
21523 even if this row ends in ZV, because we still write to
21524 the screen left to right. We also need to extend the
21525 last face if the default face is remapped to some
21526 different face, otherwise the functions that clear
21527 portions of the screen will clear with the default face's
21528 background color. */
21529 if (row->reversed_p
21530 || lookup_basic_face (it->f, DEFAULT_FACE_ID) != DEFAULT_FACE_ID)
21531 extend_face_to_end_of_line (it);
21532 break;
21535 /* Now, get the metrics of what we want to display. This also
21536 generates glyphs in `row' (which is IT->glyph_row). */
21537 n_glyphs_before = row->used[TEXT_AREA];
21538 x = it->current_x;
21540 /* Remember the line height so far in case the next element doesn't
21541 fit on the line. */
21542 if (it->line_wrap != TRUNCATE)
21544 ascent = it->max_ascent;
21545 descent = it->max_descent;
21546 phys_ascent = it->max_phys_ascent;
21547 phys_descent = it->max_phys_descent;
21549 if (it->line_wrap == WORD_WRAP && it->area == TEXT_AREA)
21551 if (IT_DISPLAYING_WHITESPACE (it))
21552 may_wrap = true;
21553 else if (may_wrap)
21555 SAVE_IT (wrap_it, *it, wrap_data);
21556 wrap_x = x;
21557 wrap_row_used = row->used[TEXT_AREA];
21558 wrap_row_ascent = row->ascent;
21559 wrap_row_height = row->height;
21560 wrap_row_phys_ascent = row->phys_ascent;
21561 wrap_row_phys_height = row->phys_height;
21562 wrap_row_extra_line_spacing = row->extra_line_spacing;
21563 wrap_row_min_pos = min_pos;
21564 wrap_row_min_bpos = min_bpos;
21565 wrap_row_max_pos = max_pos;
21566 wrap_row_max_bpos = max_bpos;
21567 may_wrap = false;
21572 PRODUCE_GLYPHS (it);
21574 /* If this display element was in marginal areas, continue with
21575 the next one. */
21576 if (it->area != TEXT_AREA)
21578 row->ascent = max (row->ascent, it->max_ascent);
21579 row->height = max (row->height, it->max_ascent + it->max_descent);
21580 row->phys_ascent = max (row->phys_ascent, it->max_phys_ascent);
21581 row->phys_height = max (row->phys_height,
21582 it->max_phys_ascent + it->max_phys_descent);
21583 row->extra_line_spacing = max (row->extra_line_spacing,
21584 it->max_extra_line_spacing);
21585 set_iterator_to_next (it, true);
21586 /* If we didn't handle the line/wrap prefix above, and the
21587 call to set_iterator_to_next just switched to TEXT_AREA,
21588 process the prefix now. */
21589 if (it->area == TEXT_AREA && pending_handle_line_prefix)
21591 /* Line numbers should precede the line-prefix or wrap-prefix. */
21592 if (line_number_needed)
21593 maybe_produce_line_number (it);
21595 pending_handle_line_prefix = false;
21596 handle_line_prefix (it);
21598 continue;
21601 /* Does the display element fit on the line? If we truncate
21602 lines, we should draw past the right edge of the window. If
21603 we don't truncate, we want to stop so that we can display the
21604 continuation glyph before the right margin. If lines are
21605 continued, there are two possible strategies for characters
21606 resulting in more than 1 glyph (e.g. tabs): Display as many
21607 glyphs as possible in this line and leave the rest for the
21608 continuation line, or display the whole element in the next
21609 line. Original redisplay did the former, so we do it also. */
21610 nglyphs = row->used[TEXT_AREA] - n_glyphs_before;
21611 hpos_before = it->hpos;
21612 x_before = x;
21614 if (/* Not a newline. */
21615 nglyphs > 0
21616 /* Glyphs produced fit entirely in the line. */
21617 && it->current_x < it->last_visible_x)
21619 it->hpos += nglyphs;
21620 row->ascent = max (row->ascent, it->max_ascent);
21621 row->height = max (row->height, it->max_ascent + it->max_descent);
21622 row->phys_ascent = max (row->phys_ascent, it->max_phys_ascent);
21623 row->phys_height = max (row->phys_height,
21624 it->max_phys_ascent + it->max_phys_descent);
21625 row->extra_line_spacing = max (row->extra_line_spacing,
21626 it->max_extra_line_spacing);
21627 if (it->current_x - it->pixel_width < it->first_visible_x
21628 /* When line numbers are displayed, row->x should not be
21629 offset, as the first glyph after the line number can
21630 never be partially visible. */
21631 && !line_number_needed
21632 /* In R2L rows, we arrange in extend_face_to_end_of_line
21633 to add a right offset to the line, by a suitable
21634 change to the stretch glyph that is the leftmost
21635 glyph of the line. */
21636 && !row->reversed_p)
21637 row->x = x - it->first_visible_x;
21638 /* Record the maximum and minimum buffer positions seen so
21639 far in glyphs that will be displayed by this row. */
21640 if (it->bidi_p)
21641 RECORD_MAX_MIN_POS (it);
21643 else
21645 int i, new_x;
21646 struct glyph *glyph;
21648 for (i = 0; i < nglyphs; ++i, x = new_x)
21650 /* Identify the glyphs added by the last call to
21651 PRODUCE_GLYPHS. In R2L rows, they are prepended to
21652 the previous glyphs. */
21653 if (!row->reversed_p)
21654 glyph = row->glyphs[TEXT_AREA] + n_glyphs_before + i;
21655 else
21656 glyph = row->glyphs[TEXT_AREA] + nglyphs - 1 - i;
21657 new_x = x + glyph->pixel_width;
21659 if (/* Lines are continued. */
21660 it->line_wrap != TRUNCATE
21661 && (/* Glyph doesn't fit on the line. */
21662 new_x > it->last_visible_x
21663 /* Or it fits exactly on a window system frame. */
21664 || (new_x == it->last_visible_x
21665 && FRAME_WINDOW_P (it->f)
21666 && (row->reversed_p
21667 ? WINDOW_LEFT_FRINGE_WIDTH (it->w)
21668 : WINDOW_RIGHT_FRINGE_WIDTH (it->w)))))
21670 /* End of a continued line. */
21672 if (it->hpos == 0
21673 || (new_x == it->last_visible_x
21674 && FRAME_WINDOW_P (it->f)
21675 && (row->reversed_p
21676 ? WINDOW_LEFT_FRINGE_WIDTH (it->w)
21677 : WINDOW_RIGHT_FRINGE_WIDTH (it->w))))
21679 /* Current glyph is the only one on the line or
21680 fits exactly on the line. We must continue
21681 the line because we can't draw the cursor
21682 after the glyph. */
21683 row->continued_p = true;
21684 it->current_x = new_x;
21685 it->continuation_lines_width += new_x;
21686 ++it->hpos;
21687 if (i == nglyphs - 1)
21689 /* If line-wrap is on, check if a previous
21690 wrap point was found. */
21691 if (!IT_OVERFLOW_NEWLINE_INTO_FRINGE (it)
21692 && wrap_row_used > 0
21693 /* Even if there is a previous wrap
21694 point, continue the line here as
21695 usual, if (i) the previous character
21696 was a space or tab AND (ii) the
21697 current character is not. */
21698 && (!may_wrap
21699 || IT_DISPLAYING_WHITESPACE (it)))
21700 goto back_to_wrap;
21702 /* Record the maximum and minimum buffer
21703 positions seen so far in glyphs that will be
21704 displayed by this row. */
21705 if (it->bidi_p)
21706 RECORD_MAX_MIN_POS (it);
21707 set_iterator_to_next (it, true);
21708 if (IT_OVERFLOW_NEWLINE_INTO_FRINGE (it))
21710 if (!get_next_display_element (it))
21712 row->exact_window_width_line_p = true;
21713 it->continuation_lines_width = 0;
21714 it->font_height = Qnil;
21715 it->voffset = 0;
21716 row->continued_p = false;
21717 row->ends_at_zv_p = true;
21719 else if (ITERATOR_AT_END_OF_LINE_P (it))
21721 row->continued_p = false;
21722 row->exact_window_width_line_p = true;
21724 /* If line-wrap is on, check if a
21725 previous wrap point was found. */
21726 else if (wrap_row_used > 0
21727 /* Even if there is a previous wrap
21728 point, continue the line here as
21729 usual, if (i) the previous character
21730 was a space or tab AND (ii) the
21731 current character is not. */
21732 && (!may_wrap
21733 || IT_DISPLAYING_WHITESPACE (it)))
21734 goto back_to_wrap;
21738 else if (it->bidi_p)
21739 RECORD_MAX_MIN_POS (it);
21740 if (WINDOW_LEFT_MARGIN_WIDTH (it->w) > 0
21741 || WINDOW_RIGHT_MARGIN_WIDTH (it->w) > 0)
21742 extend_face_to_end_of_line (it);
21744 else if (CHAR_GLYPH_PADDING_P (*glyph)
21745 && !FRAME_WINDOW_P (it->f))
21747 /* A padding glyph that doesn't fit on this line.
21748 This means the whole character doesn't fit
21749 on the line. */
21750 if (row->reversed_p)
21751 unproduce_glyphs (it, row->used[TEXT_AREA]
21752 - n_glyphs_before);
21753 row->used[TEXT_AREA] = n_glyphs_before;
21755 /* Fill the rest of the row with continuation
21756 glyphs like in 20.x. */
21757 while (row->glyphs[TEXT_AREA] + row->used[TEXT_AREA]
21758 < row->glyphs[1 + TEXT_AREA])
21759 produce_special_glyphs (it, IT_CONTINUATION);
21761 row->continued_p = true;
21762 it->current_x = x_before;
21763 it->continuation_lines_width += x_before;
21765 /* Restore the height to what it was before the
21766 element not fitting on the line. */
21767 it->max_ascent = ascent;
21768 it->max_descent = descent;
21769 it->max_phys_ascent = phys_ascent;
21770 it->max_phys_descent = phys_descent;
21771 if (WINDOW_LEFT_MARGIN_WIDTH (it->w) > 0
21772 || WINDOW_RIGHT_MARGIN_WIDTH (it->w) > 0)
21773 extend_face_to_end_of_line (it);
21775 else if (wrap_row_used > 0)
21777 back_to_wrap:
21778 if (row->reversed_p)
21779 unproduce_glyphs (it,
21780 row->used[TEXT_AREA] - wrap_row_used);
21781 RESTORE_IT (it, &wrap_it, wrap_data);
21782 it->continuation_lines_width += wrap_x;
21783 row->used[TEXT_AREA] = wrap_row_used;
21784 row->ascent = wrap_row_ascent;
21785 row->height = wrap_row_height;
21786 row->phys_ascent = wrap_row_phys_ascent;
21787 row->phys_height = wrap_row_phys_height;
21788 row->extra_line_spacing = wrap_row_extra_line_spacing;
21789 min_pos = wrap_row_min_pos;
21790 min_bpos = wrap_row_min_bpos;
21791 max_pos = wrap_row_max_pos;
21792 max_bpos = wrap_row_max_bpos;
21793 row->continued_p = true;
21794 row->ends_at_zv_p = false;
21795 row->exact_window_width_line_p = false;
21797 /* Make sure that a non-default face is extended
21798 up to the right margin of the window. */
21799 extend_face_to_end_of_line (it);
21801 else if ((it->what == IT_CHARACTER
21802 || it->what == IT_STRETCH
21803 || it->what == IT_COMPOSITION)
21804 && it->c == '\t' && FRAME_WINDOW_P (it->f))
21806 /* A TAB that extends past the right edge of the
21807 window. This produces a single glyph on
21808 window system frames. We leave the glyph in
21809 this row and let it fill the row, but don't
21810 consume the TAB. */
21811 if ((row->reversed_p
21812 ? WINDOW_LEFT_FRINGE_WIDTH (it->w)
21813 : WINDOW_RIGHT_FRINGE_WIDTH (it->w)) == 0)
21814 produce_special_glyphs (it, IT_CONTINUATION);
21815 it->continuation_lines_width += it->last_visible_x;
21816 row->ends_in_middle_of_char_p = true;
21817 row->continued_p = true;
21818 glyph->pixel_width = it->last_visible_x - x;
21819 it->starts_in_middle_of_char_p = true;
21820 if (WINDOW_LEFT_MARGIN_WIDTH (it->w) > 0
21821 || WINDOW_RIGHT_MARGIN_WIDTH (it->w) > 0)
21822 extend_face_to_end_of_line (it);
21824 else
21826 /* Something other than a TAB that draws past
21827 the right edge of the window. Restore
21828 positions to values before the element. */
21829 if (row->reversed_p)
21830 unproduce_glyphs (it, row->used[TEXT_AREA]
21831 - (n_glyphs_before + i));
21832 row->used[TEXT_AREA] = n_glyphs_before + i;
21834 /* Display continuation glyphs. */
21835 it->current_x = x_before;
21836 it->continuation_lines_width += x;
21837 if (!FRAME_WINDOW_P (it->f)
21838 || (row->reversed_p
21839 ? WINDOW_LEFT_FRINGE_WIDTH (it->w)
21840 : WINDOW_RIGHT_FRINGE_WIDTH (it->w)) == 0)
21841 produce_special_glyphs (it, IT_CONTINUATION);
21842 row->continued_p = true;
21844 extend_face_to_end_of_line (it);
21846 if (nglyphs > 1 && i > 0)
21848 row->ends_in_middle_of_char_p = true;
21849 it->starts_in_middle_of_char_p = true;
21852 /* Restore the height to what it was before the
21853 element not fitting on the line. */
21854 it->max_ascent = ascent;
21855 it->max_descent = descent;
21856 it->max_phys_ascent = phys_ascent;
21857 it->max_phys_descent = phys_descent;
21860 break;
21862 else if (new_x > it->first_visible_x)
21864 /* Increment number of glyphs actually displayed. */
21865 ++it->hpos;
21867 /* Record the maximum and minimum buffer positions
21868 seen so far in glyphs that will be displayed by
21869 this row. */
21870 if (it->bidi_p)
21871 RECORD_MAX_MIN_POS (it);
21873 if (x < it->first_visible_x && !row->reversed_p
21874 && !line_number_needed)
21875 /* Glyph is partially visible, i.e. row starts at
21876 negative X position. Don't do that in R2L
21877 rows, where we arrange to add a right offset to
21878 the line in extend_face_to_end_of_line, by a
21879 suitable change to the stretch glyph that is
21880 the leftmost glyph of the line. */
21881 row->x = x - it->first_visible_x;
21882 /* When the last glyph of an R2L row only fits
21883 partially on the line, we need to set row->x to a
21884 negative offset, so that the leftmost glyph is
21885 the one that is partially visible. But if we are
21886 going to produce the truncation glyph, this will
21887 be taken care of in produce_special_glyphs. */
21888 if (row->reversed_p
21889 && new_x > it->last_visible_x
21890 && !line_number_needed
21891 && !(it->line_wrap == TRUNCATE
21892 && WINDOW_LEFT_FRINGE_WIDTH (it->w) == 0))
21894 eassert (FRAME_WINDOW_P (it->f));
21895 row->x = it->last_visible_x - new_x;
21898 else
21900 /* Glyph is completely off the left margin of the
21901 window. This should not happen because of the
21902 move_it_in_display_line at the start of this
21903 function, unless the text display area of the
21904 window is empty. */
21905 eassert (it->first_visible_x <= it->last_visible_x);
21908 /* Even if this display element produced no glyphs at all,
21909 we want to record its position. */
21910 if (it->bidi_p && nglyphs == 0)
21911 RECORD_MAX_MIN_POS (it);
21913 row->ascent = max (row->ascent, it->max_ascent);
21914 row->height = max (row->height, it->max_ascent + it->max_descent);
21915 row->phys_ascent = max (row->phys_ascent, it->max_phys_ascent);
21916 row->phys_height = max (row->phys_height,
21917 it->max_phys_ascent + it->max_phys_descent);
21918 row->extra_line_spacing = max (row->extra_line_spacing,
21919 it->max_extra_line_spacing);
21921 /* End of this display line if row is continued. */
21922 if (row->continued_p || row->ends_at_zv_p)
21923 break;
21926 at_end_of_line:
21927 /* Is this a line end? If yes, we're also done, after making
21928 sure that a non-default face is extended up to the right
21929 margin of the window. */
21930 if (ITERATOR_AT_END_OF_LINE_P (it))
21932 int used_before = row->used[TEXT_AREA];
21934 row->ends_in_newline_from_string_p = STRINGP (it->object);
21936 /* Add a space at the end of the line that is used to
21937 display the cursor there. */
21938 if (!IT_OVERFLOW_NEWLINE_INTO_FRINGE (it))
21939 append_space_for_newline (it, false);
21941 /* Extend the face to the end of the line. */
21942 extend_face_to_end_of_line (it);
21944 /* Make sure we have the position. */
21945 if (used_before == 0)
21946 row->glyphs[TEXT_AREA]->charpos = CHARPOS (it->position);
21948 /* Record the position of the newline, for use in
21949 find_row_edges. */
21950 it->eol_pos = it->current.pos;
21952 /* Consume the line end. This skips over invisible lines. */
21953 set_iterator_to_next (it, true);
21954 it->continuation_lines_width = 0;
21955 break;
21958 /* Proceed with next display element. Note that this skips
21959 over lines invisible because of selective display. */
21960 set_iterator_to_next (it, true);
21962 /* If we truncate lines, we are done when the last displayed
21963 glyphs reach past the right margin of the window. */
21964 if (it->line_wrap == TRUNCATE
21965 && ((FRAME_WINDOW_P (it->f)
21966 /* Images are preprocessed in produce_image_glyph such
21967 that they are cropped at the right edge of the
21968 window, so an image glyph will always end exactly at
21969 last_visible_x, even if there's no right fringe. */
21970 && ((row->reversed_p
21971 ? WINDOW_LEFT_FRINGE_WIDTH (it->w)
21972 : WINDOW_RIGHT_FRINGE_WIDTH (it->w))
21973 || it->what == IT_IMAGE))
21974 ? (it->current_x >= it->last_visible_x)
21975 : (it->current_x > it->last_visible_x)))
21977 /* Maybe add truncation glyphs. */
21978 if (!FRAME_WINDOW_P (it->f)
21979 || (row->reversed_p
21980 ? WINDOW_LEFT_FRINGE_WIDTH (it->w)
21981 : WINDOW_RIGHT_FRINGE_WIDTH (it->w)) == 0)
21983 int i, n;
21985 if (!row->reversed_p)
21987 for (i = row->used[TEXT_AREA] - 1; i > 0; --i)
21988 if (!CHAR_GLYPH_PADDING_P (row->glyphs[TEXT_AREA][i]))
21989 break;
21991 else
21993 for (i = 0; i < row->used[TEXT_AREA]; i++)
21994 if (!CHAR_GLYPH_PADDING_P (row->glyphs[TEXT_AREA][i]))
21995 break;
21996 /* Remove any padding glyphs at the front of ROW, to
21997 make room for the truncation glyphs we will be
21998 adding below. The loop below always inserts at
21999 least one truncation glyph, so also remove the
22000 last glyph added to ROW. */
22001 unproduce_glyphs (it, i + 1);
22002 /* Adjust i for the loop below. */
22003 i = row->used[TEXT_AREA] - (i + 1);
22006 /* produce_special_glyphs overwrites the last glyph, so
22007 we don't want that if we want to keep that last
22008 glyph, which means it's an image. */
22009 if (it->current_x > it->last_visible_x)
22011 it->current_x = x_before;
22012 if (!FRAME_WINDOW_P (it->f))
22014 for (n = row->used[TEXT_AREA]; i < n; ++i)
22016 row->used[TEXT_AREA] = i;
22017 produce_special_glyphs (it, IT_TRUNCATION);
22020 else
22022 row->used[TEXT_AREA] = i;
22023 produce_special_glyphs (it, IT_TRUNCATION);
22025 it->hpos = hpos_before;
22028 else if (IT_OVERFLOW_NEWLINE_INTO_FRINGE (it))
22030 /* Don't truncate if we can overflow newline into fringe. */
22031 if (!get_next_display_element (it))
22033 it->continuation_lines_width = 0;
22034 it->font_height = Qnil;
22035 it->voffset = 0;
22036 row->ends_at_zv_p = true;
22037 row->exact_window_width_line_p = true;
22038 break;
22040 if (ITERATOR_AT_END_OF_LINE_P (it))
22042 row->exact_window_width_line_p = true;
22043 goto at_end_of_line;
22045 it->current_x = x_before;
22046 it->hpos = hpos_before;
22049 row->truncated_on_right_p = true;
22050 it->continuation_lines_width = 0;
22051 reseat_at_next_visible_line_start (it, false);
22052 /* We insist below that IT's position be at ZV because in
22053 bidi-reordered lines the character at visible line start
22054 might not be the character that follows the newline in
22055 the logical order. */
22056 if (IT_BYTEPOS (*it) > BEG_BYTE)
22057 row->ends_at_zv_p =
22058 IT_BYTEPOS (*it) >= ZV_BYTE && FETCH_BYTE (ZV_BYTE - 1) != '\n';
22059 else
22060 row->ends_at_zv_p = false;
22061 break;
22065 if (wrap_data)
22066 bidi_unshelve_cache (wrap_data, true);
22068 /* If line is not empty and hscrolled, maybe insert truncation glyphs
22069 at the left window margin. */
22070 if (it->first_visible_x
22071 && IT_CHARPOS (*it) != CHARPOS (row->start.pos))
22073 if (!FRAME_WINDOW_P (it->f)
22074 || (((row->reversed_p
22075 ? WINDOW_RIGHT_FRINGE_WIDTH (it->w)
22076 : WINDOW_LEFT_FRINGE_WIDTH (it->w)) == 0)
22077 /* Don't let insert_left_trunc_glyphs overwrite the
22078 first glyph of the row if it is an image. */
22079 && row->glyphs[TEXT_AREA]->type != IMAGE_GLYPH))
22080 insert_left_trunc_glyphs (it);
22081 row->truncated_on_left_p = true;
22084 /* Remember the position at which this line ends.
22086 BIDI Note: any code that needs MATRIX_ROW_START/END_CHARPOS
22087 cannot be before the call to find_row_edges below, since that is
22088 where these positions are determined. */
22089 row->end = it->current;
22090 if (!it->bidi_p)
22092 row->minpos = row->start.pos;
22093 row->maxpos = row->end.pos;
22095 else
22097 /* ROW->minpos and ROW->maxpos must be the smallest and
22098 `1 + the largest' buffer positions in ROW. But if ROW was
22099 bidi-reordered, these two positions can be anywhere in the
22100 row, so we must determine them now. */
22101 find_row_edges (it, row, min_pos, min_bpos, max_pos, max_bpos);
22104 /* If the start of this line is the overlay arrow-position, then
22105 mark this glyph row as the one containing the overlay arrow.
22106 This is clearly a mess with variable size fonts. It would be
22107 better to let it be displayed like cursors under X. */
22108 if ((MATRIX_ROW_DISPLAYS_TEXT_P (row) || !overlay_arrow_seen)
22109 && (overlay_arrow_string = overlay_arrow_at_row (it, row),
22110 !NILP (overlay_arrow_string)))
22112 /* Overlay arrow in window redisplay is a fringe bitmap. */
22113 if (STRINGP (overlay_arrow_string))
22115 struct glyph_row *arrow_row
22116 = get_overlay_arrow_glyph_row (it->w, overlay_arrow_string);
22117 struct glyph *glyph = arrow_row->glyphs[TEXT_AREA];
22118 struct glyph *arrow_end = glyph + arrow_row->used[TEXT_AREA];
22119 struct glyph *p = row->glyphs[TEXT_AREA];
22120 struct glyph *p2, *end;
22122 /* Copy the arrow glyphs. */
22123 while (glyph < arrow_end)
22124 *p++ = *glyph++;
22126 /* Throw away padding glyphs. */
22127 p2 = p;
22128 end = row->glyphs[TEXT_AREA] + row->used[TEXT_AREA];
22129 while (p2 < end && CHAR_GLYPH_PADDING_P (*p2))
22130 ++p2;
22131 if (p2 > p)
22133 while (p2 < end)
22134 *p++ = *p2++;
22135 row->used[TEXT_AREA] = p2 - row->glyphs[TEXT_AREA];
22138 else
22140 eassert (INTEGERP (overlay_arrow_string));
22141 row->overlay_arrow_bitmap = XINT (overlay_arrow_string);
22143 overlay_arrow_seen = true;
22146 /* Highlight trailing whitespace. */
22147 if (!NILP (Vshow_trailing_whitespace))
22148 highlight_trailing_whitespace (it->f, it->glyph_row);
22150 /* Compute pixel dimensions of this line. */
22151 compute_line_metrics (it);
22153 /* Implementation note: No changes in the glyphs of ROW or in their
22154 faces can be done past this point, because compute_line_metrics
22155 computes ROW's hash value and stores it within the glyph_row
22156 structure. */
22158 /* Record whether this row ends inside an ellipsis. */
22159 row->ends_in_ellipsis_p
22160 = (it->method == GET_FROM_DISPLAY_VECTOR
22161 && it->ellipsis_p);
22163 /* Save fringe bitmaps in this row. */
22164 row->left_user_fringe_bitmap = it->left_user_fringe_bitmap;
22165 row->left_user_fringe_face_id = it->left_user_fringe_face_id;
22166 row->right_user_fringe_bitmap = it->right_user_fringe_bitmap;
22167 row->right_user_fringe_face_id = it->right_user_fringe_face_id;
22169 it->left_user_fringe_bitmap = 0;
22170 it->left_user_fringe_face_id = 0;
22171 it->right_user_fringe_bitmap = 0;
22172 it->right_user_fringe_face_id = 0;
22174 /* Maybe set the cursor. */
22175 cvpos = it->w->cursor.vpos;
22176 if ((cvpos < 0
22177 /* In bidi-reordered rows, keep checking for proper cursor
22178 position even if one has been found already, because buffer
22179 positions in such rows change non-linearly with ROW->VPOS,
22180 when a line is continued. One exception: when we are at ZV,
22181 display cursor on the first suitable glyph row, since all
22182 the empty rows after that also have their position set to ZV. */
22183 /* FIXME: Revisit this when glyph ``spilling'' in continuation
22184 lines' rows is implemented for bidi-reordered rows. */
22185 || (it->bidi_p
22186 && !MATRIX_ROW (it->w->desired_matrix, cvpos)->ends_at_zv_p))
22187 && PT >= MATRIX_ROW_START_CHARPOS (row)
22188 && PT <= MATRIX_ROW_END_CHARPOS (row)
22189 && cursor_row_p (row))
22190 set_cursor_from_row (it->w, row, it->w->desired_matrix, 0, 0, 0, 0);
22192 /* Prepare for the next line. This line starts horizontally at (X
22193 HPOS) = (0 0). Vertical positions are incremented. As a
22194 convenience for the caller, IT->glyph_row is set to the next
22195 row to be used. */
22196 it->current_x = it->hpos = 0;
22197 it->current_y += row->height;
22198 /* Restore the first and last visible X if we adjusted them for
22199 current-line hscrolling. */
22200 if (hscroll_this_line)
22202 it->first_visible_x = first_visible_x;
22203 it->last_visible_x = last_visible_x;
22205 SET_TEXT_POS (it->eol_pos, 0, 0);
22206 ++it->vpos;
22207 ++it->glyph_row;
22208 /* The next row should by default use the same value of the
22209 reversed_p flag as this one. set_iterator_to_next decides when
22210 it's a new paragraph, and PRODUCE_GLYPHS recomputes the value of
22211 the flag accordingly. */
22212 if (it->glyph_row < MATRIX_BOTTOM_TEXT_ROW (it->w->desired_matrix, it->w))
22213 it->glyph_row->reversed_p = row->reversed_p;
22214 it->start = row->end;
22215 return MATRIX_ROW_DISPLAYS_TEXT_P (row);
22217 #undef RECORD_MAX_MIN_POS
22220 DEFUN ("current-bidi-paragraph-direction", Fcurrent_bidi_paragraph_direction,
22221 Scurrent_bidi_paragraph_direction, 0, 1, 0,
22222 doc: /* Return paragraph direction at point in BUFFER.
22223 Value is either `left-to-right' or `right-to-left'.
22224 If BUFFER is omitted or nil, it defaults to the current buffer.
22226 Paragraph direction determines how the text in the paragraph is displayed.
22227 In left-to-right paragraphs, text begins at the left margin of the window
22228 and the reading direction is generally left to right. In right-to-left
22229 paragraphs, text begins at the right margin and is read from right to left.
22231 See also `bidi-paragraph-direction'. */)
22232 (Lisp_Object buffer)
22234 struct buffer *buf = current_buffer;
22235 struct buffer *old = buf;
22237 if (! NILP (buffer))
22239 CHECK_BUFFER (buffer);
22240 buf = XBUFFER (buffer);
22243 if (NILP (BVAR (buf, bidi_display_reordering))
22244 || NILP (BVAR (buf, enable_multibyte_characters))
22245 /* When we are loading loadup.el, the character property tables
22246 needed for bidi iteration are not yet available. */
22247 || redisplay__inhibit_bidi)
22248 return Qleft_to_right;
22249 else if (!NILP (BVAR (buf, bidi_paragraph_direction)))
22250 return BVAR (buf, bidi_paragraph_direction);
22251 else
22253 /* Determine the direction from buffer text. We could try to
22254 use current_matrix if it is up to date, but this seems fast
22255 enough as it is. */
22256 struct bidi_it itb;
22257 ptrdiff_t pos = BUF_PT (buf);
22258 ptrdiff_t bytepos = BUF_PT_BYTE (buf);
22259 int c;
22260 void *itb_data = bidi_shelve_cache ();
22262 set_buffer_temp (buf);
22263 /* bidi_paragraph_init finds the base direction of the paragraph
22264 by searching forward from paragraph start. We need the base
22265 direction of the current or _previous_ paragraph, so we need
22266 to make sure we are within that paragraph. To that end, find
22267 the previous non-empty line. */
22268 if (pos >= ZV && pos > BEGV)
22269 DEC_BOTH (pos, bytepos);
22270 AUTO_STRING (trailing_white_space, "[\f\t ]*\n");
22271 if (fast_looking_at (trailing_white_space,
22272 pos, bytepos, ZV, ZV_BYTE, Qnil) > 0)
22274 while ((c = FETCH_BYTE (bytepos)) == '\n'
22275 || c == ' ' || c == '\t' || c == '\f')
22277 if (bytepos <= BEGV_BYTE)
22278 break;
22279 bytepos--;
22280 pos--;
22282 while (!CHAR_HEAD_P (FETCH_BYTE (bytepos)))
22283 bytepos--;
22285 bidi_init_it (pos, bytepos, FRAME_WINDOW_P (SELECTED_FRAME ()), &itb);
22286 itb.paragraph_dir = NEUTRAL_DIR;
22287 itb.string.s = NULL;
22288 itb.string.lstring = Qnil;
22289 itb.string.bufpos = 0;
22290 itb.string.from_disp_str = false;
22291 itb.string.unibyte = false;
22292 /* We have no window to use here for ignoring window-specific
22293 overlays. Using NULL for window pointer will cause
22294 compute_display_string_pos to use the current buffer. */
22295 itb.w = NULL;
22296 bidi_paragraph_init (NEUTRAL_DIR, &itb, true);
22297 bidi_unshelve_cache (itb_data, false);
22298 set_buffer_temp (old);
22299 switch (itb.paragraph_dir)
22301 case L2R:
22302 return Qleft_to_right;
22303 break;
22304 case R2L:
22305 return Qright_to_left;
22306 break;
22307 default:
22308 emacs_abort ();
22313 DEFUN ("bidi-find-overridden-directionality",
22314 Fbidi_find_overridden_directionality,
22315 Sbidi_find_overridden_directionality, 2, 3, 0,
22316 doc: /* Return position between FROM and TO where directionality was overridden.
22318 This function returns the first character position in the specified
22319 region of OBJECT where there is a character whose `bidi-class' property
22320 is `L', but which was forced to display as `R' by a directional
22321 override, and likewise with characters whose `bidi-class' is `R'
22322 or `AL' that were forced to display as `L'.
22324 If no such character is found, the function returns nil.
22326 OBJECT is a Lisp string or buffer to search for overridden
22327 directionality, and defaults to the current buffer if nil or omitted.
22328 OBJECT can also be a window, in which case the function will search
22329 the buffer displayed in that window. Passing the window instead of
22330 a buffer is preferable when the buffer is displayed in some window,
22331 because this function will then be able to correctly account for
22332 window-specific overlays, which can affect the results.
22334 Strong directional characters `L', `R', and `AL' can have their
22335 intrinsic directionality overridden by directional override
22336 control characters RLO (u+202e) and LRO (u+202d). See the
22337 function `get-char-code-property' for a way to inquire about
22338 the `bidi-class' property of a character. */)
22339 (Lisp_Object from, Lisp_Object to, Lisp_Object object)
22341 struct buffer *buf = current_buffer;
22342 struct buffer *old = buf;
22343 struct window *w = NULL;
22344 bool frame_window_p = FRAME_WINDOW_P (SELECTED_FRAME ());
22345 struct bidi_it itb;
22346 ptrdiff_t from_pos, to_pos, from_bpos;
22347 void *itb_data;
22349 if (!NILP (object))
22351 if (BUFFERP (object))
22352 buf = XBUFFER (object);
22353 else if (WINDOWP (object))
22355 w = decode_live_window (object);
22356 buf = XBUFFER (w->contents);
22357 frame_window_p = FRAME_WINDOW_P (XFRAME (w->frame));
22359 else
22360 CHECK_STRING (object);
22363 if (STRINGP (object))
22365 /* Characters in unibyte strings are always treated by bidi.c as
22366 strong LTR. */
22367 if (!STRING_MULTIBYTE (object)
22368 /* When we are loading loadup.el, the character property
22369 tables needed for bidi iteration are not yet
22370 available. */
22371 || redisplay__inhibit_bidi)
22372 return Qnil;
22374 validate_subarray (object, from, to, SCHARS (object), &from_pos, &to_pos);
22375 if (from_pos >= SCHARS (object))
22376 return Qnil;
22378 /* Set up the bidi iterator. */
22379 itb_data = bidi_shelve_cache ();
22380 itb.paragraph_dir = NEUTRAL_DIR;
22381 itb.string.lstring = object;
22382 itb.string.s = NULL;
22383 itb.string.schars = SCHARS (object);
22384 itb.string.bufpos = 0;
22385 itb.string.from_disp_str = false;
22386 itb.string.unibyte = false;
22387 itb.w = w;
22388 bidi_init_it (0, 0, frame_window_p, &itb);
22390 else
22392 /* Nothing this fancy can happen in unibyte buffers, or in a
22393 buffer that disabled reordering, or if FROM is at EOB. */
22394 if (NILP (BVAR (buf, bidi_display_reordering))
22395 || NILP (BVAR (buf, enable_multibyte_characters))
22396 /* When we are loading loadup.el, the character property
22397 tables needed for bidi iteration are not yet
22398 available. */
22399 || redisplay__inhibit_bidi)
22400 return Qnil;
22402 set_buffer_temp (buf);
22403 validate_region (&from, &to);
22404 from_pos = XINT (from);
22405 to_pos = XINT (to);
22406 if (from_pos >= ZV)
22407 return Qnil;
22409 /* Set up the bidi iterator. */
22410 itb_data = bidi_shelve_cache ();
22411 from_bpos = CHAR_TO_BYTE (from_pos);
22412 if (from_pos == BEGV)
22414 itb.charpos = BEGV;
22415 itb.bytepos = BEGV_BYTE;
22417 else if (FETCH_CHAR (from_bpos - 1) == '\n')
22419 itb.charpos = from_pos;
22420 itb.bytepos = from_bpos;
22422 else
22423 itb.charpos = find_newline_no_quit (from_pos, CHAR_TO_BYTE (from_pos),
22424 -1, &itb.bytepos);
22425 itb.paragraph_dir = NEUTRAL_DIR;
22426 itb.string.s = NULL;
22427 itb.string.lstring = Qnil;
22428 itb.string.bufpos = 0;
22429 itb.string.from_disp_str = false;
22430 itb.string.unibyte = false;
22431 itb.w = w;
22432 bidi_init_it (itb.charpos, itb.bytepos, frame_window_p, &itb);
22435 ptrdiff_t found;
22436 do {
22437 /* For the purposes of this function, the actual base direction of
22438 the paragraph doesn't matter, so just set it to L2R. */
22439 bidi_paragraph_init (L2R, &itb, false);
22440 while ((found = bidi_find_first_overridden (&itb)) < from_pos)
22442 } while (found == ZV && itb.ch == '\n' && itb.charpos < to_pos);
22444 bidi_unshelve_cache (itb_data, false);
22445 set_buffer_temp (old);
22447 return (from_pos <= found && found < to_pos) ? make_number (found) : Qnil;
22450 DEFUN ("move-point-visually", Fmove_point_visually,
22451 Smove_point_visually, 1, 1, 0,
22452 doc: /* Move point in the visual order in the specified DIRECTION.
22453 DIRECTION can be 1, meaning move to the right, or -1, which moves to the
22454 left.
22456 Value is the new character position of point. */)
22457 (Lisp_Object direction)
22459 struct window *w = XWINDOW (selected_window);
22460 struct buffer *b = XBUFFER (w->contents);
22461 struct glyph_row *row;
22462 int dir;
22463 Lisp_Object paragraph_dir;
22465 #define ROW_GLYPH_NEWLINE_P(ROW,GLYPH) \
22466 (!(ROW)->continued_p \
22467 && NILP ((GLYPH)->object) \
22468 && (GLYPH)->type == CHAR_GLYPH \
22469 && (GLYPH)->u.ch == ' ' \
22470 && (GLYPH)->charpos >= 0 \
22471 && !(GLYPH)->avoid_cursor_p)
22473 CHECK_NUMBER (direction);
22474 dir = XINT (direction);
22475 if (dir > 0)
22476 dir = 1;
22477 else
22478 dir = -1;
22480 /* If current matrix is up-to-date, we can use the information
22481 recorded in the glyphs, at least as long as the goal is on the
22482 screen. */
22483 if (w->window_end_valid
22484 && !windows_or_buffers_changed
22485 && b
22486 && !b->clip_changed
22487 && !b->prevent_redisplay_optimizations_p
22488 && !window_outdated (w)
22489 /* We rely below on the cursor coordinates to be up to date, but
22490 we cannot trust them if some command moved point since the
22491 last complete redisplay. */
22492 && w->last_point == BUF_PT (b)
22493 && w->cursor.vpos >= 0
22494 && w->cursor.vpos < w->current_matrix->nrows
22495 && (row = MATRIX_ROW (w->current_matrix, w->cursor.vpos))->enabled_p)
22497 struct glyph *g = row->glyphs[TEXT_AREA];
22498 struct glyph *e = dir > 0 ? g + row->used[TEXT_AREA] : g - 1;
22499 struct glyph *gpt = g + w->cursor.hpos;
22501 for (g = gpt + dir; (dir > 0 ? g < e : g > e); g += dir)
22503 if (BUFFERP (g->object) && g->charpos != PT)
22505 SET_PT (g->charpos);
22506 w->cursor.vpos = -1;
22507 return make_number (PT);
22509 else if (!NILP (g->object) && !EQ (g->object, gpt->object))
22511 ptrdiff_t new_pos;
22513 if (BUFFERP (gpt->object))
22515 new_pos = PT;
22516 if ((gpt->resolved_level - row->reversed_p) % 2 == 0)
22517 new_pos += (row->reversed_p ? -dir : dir);
22518 else
22519 new_pos -= (row->reversed_p ? -dir : dir);
22520 new_pos = clip_to_bounds (BEGV, new_pos, ZV);
22521 /* If we didn't move, we've hit BEGV or ZV, so we
22522 need to signal a suitable error. */
22523 if (new_pos == PT)
22524 break;
22526 else if (BUFFERP (g->object))
22527 new_pos = g->charpos;
22528 else
22529 break;
22530 SET_PT (new_pos);
22531 w->cursor.vpos = -1;
22532 return make_number (PT);
22534 else if (ROW_GLYPH_NEWLINE_P (row, g))
22536 /* Glyphs inserted at the end of a non-empty line for
22537 positioning the cursor have zero charpos, so we must
22538 deduce the value of point by other means. */
22539 if (g->charpos > 0)
22540 SET_PT (g->charpos);
22541 else if (row->ends_at_zv_p && PT != ZV)
22542 SET_PT (ZV);
22543 else if (PT != MATRIX_ROW_END_CHARPOS (row) - 1)
22544 SET_PT (MATRIX_ROW_END_CHARPOS (row) - 1);
22545 else
22546 break;
22547 w->cursor.vpos = -1;
22548 return make_number (PT);
22551 if (g == e || NILP (g->object))
22553 if (row->truncated_on_left_p || row->truncated_on_right_p)
22554 goto simulate_display;
22555 if (!row->reversed_p)
22556 row += dir;
22557 else
22558 row -= dir;
22559 if (!(MATRIX_FIRST_TEXT_ROW (w->current_matrix) <= row
22560 && row < MATRIX_BOTTOM_TEXT_ROW (w->current_matrix, w)))
22561 goto simulate_display;
22563 if (dir > 0)
22565 if (row->reversed_p && !row->continued_p)
22567 SET_PT (MATRIX_ROW_END_CHARPOS (row) - 1);
22568 w->cursor.vpos = -1;
22569 return make_number (PT);
22571 g = row->glyphs[TEXT_AREA];
22572 e = g + row->used[TEXT_AREA];
22573 for ( ; g < e; g++)
22575 if (BUFFERP (g->object)
22576 /* Empty lines have only one glyph, which stands
22577 for the newline, and whose charpos is the
22578 buffer position of the newline. */
22579 || ROW_GLYPH_NEWLINE_P (row, g)
22580 /* When the buffer ends in a newline, the line at
22581 EOB also has one glyph, but its charpos is -1. */
22582 || (row->ends_at_zv_p
22583 && !row->reversed_p
22584 && NILP (g->object)
22585 && g->type == CHAR_GLYPH
22586 && g->u.ch == ' '))
22588 if (g->charpos > 0)
22589 SET_PT (g->charpos);
22590 else if (!row->reversed_p
22591 && row->ends_at_zv_p
22592 && PT != ZV)
22593 SET_PT (ZV);
22594 else
22595 continue;
22596 w->cursor.vpos = -1;
22597 return make_number (PT);
22601 else
22603 if (!row->reversed_p && !row->continued_p)
22605 SET_PT (MATRIX_ROW_END_CHARPOS (row) - 1);
22606 w->cursor.vpos = -1;
22607 return make_number (PT);
22609 e = row->glyphs[TEXT_AREA];
22610 g = e + row->used[TEXT_AREA] - 1;
22611 for ( ; g >= e; g--)
22613 if (BUFFERP (g->object)
22614 || (ROW_GLYPH_NEWLINE_P (row, g)
22615 && g->charpos > 0)
22616 /* Empty R2L lines on GUI frames have the buffer
22617 position of the newline stored in the stretch
22618 glyph. */
22619 || g->type == STRETCH_GLYPH
22620 || (row->ends_at_zv_p
22621 && row->reversed_p
22622 && NILP (g->object)
22623 && g->type == CHAR_GLYPH
22624 && g->u.ch == ' '))
22626 if (g->charpos > 0)
22627 SET_PT (g->charpos);
22628 else if (row->reversed_p
22629 && row->ends_at_zv_p
22630 && PT != ZV)
22631 SET_PT (ZV);
22632 else
22633 continue;
22634 w->cursor.vpos = -1;
22635 return make_number (PT);
22642 simulate_display:
22644 /* If we wind up here, we failed to move by using the glyphs, so we
22645 need to simulate display instead. */
22647 if (b)
22648 paragraph_dir = Fcurrent_bidi_paragraph_direction (w->contents);
22649 else
22650 paragraph_dir = Qleft_to_right;
22651 if (EQ (paragraph_dir, Qright_to_left))
22652 dir = -dir;
22653 if (PT <= BEGV && dir < 0)
22654 xsignal0 (Qbeginning_of_buffer);
22655 else if (PT >= ZV && dir > 0)
22656 xsignal0 (Qend_of_buffer);
22657 else
22659 struct text_pos pt;
22660 struct it it;
22661 int pt_x, target_x, pixel_width, pt_vpos;
22662 bool at_eol_p;
22663 bool overshoot_expected = false;
22664 bool target_is_eol_p = false;
22666 /* Setup the arena. */
22667 SET_TEXT_POS (pt, PT, PT_BYTE);
22668 start_display (&it, w, pt);
22669 /* When lines are truncated, we could be called with point
22670 outside of the windows edges, in which case move_it_*
22671 functions either prematurely stop at window's edge or jump to
22672 the next screen line, whereas we rely below on our ability to
22673 reach point, in order to start from its X coordinate. So we
22674 need to disregard the window's horizontal extent in that case. */
22675 if (it.line_wrap == TRUNCATE)
22676 it.last_visible_x = DISP_INFINITY;
22678 if (it.cmp_it.id < 0
22679 && it.method == GET_FROM_STRING
22680 && it.area == TEXT_AREA
22681 && it.string_from_display_prop_p
22682 && (it.sp > 0 && it.stack[it.sp - 1].method == GET_FROM_BUFFER))
22683 overshoot_expected = true;
22685 /* Find the X coordinate of point. We start from the beginning
22686 of this or previous line to make sure we are before point in
22687 the logical order (since the move_it_* functions can only
22688 move forward). */
22689 reseat:
22690 reseat_at_previous_visible_line_start (&it);
22691 it.current_x = it.hpos = it.current_y = it.vpos = 0;
22692 if (IT_CHARPOS (it) != PT)
22694 move_it_to (&it, overshoot_expected ? PT - 1 : PT,
22695 -1, -1, -1, MOVE_TO_POS);
22696 /* If we missed point because the character there is
22697 displayed out of a display vector that has more than one
22698 glyph, retry expecting overshoot. */
22699 if (it.method == GET_FROM_DISPLAY_VECTOR
22700 && it.current.dpvec_index > 0
22701 && !overshoot_expected)
22703 overshoot_expected = true;
22704 goto reseat;
22706 else if (IT_CHARPOS (it) != PT && !overshoot_expected)
22707 move_it_in_display_line (&it, PT, -1, MOVE_TO_POS);
22709 pt_x = it.current_x;
22710 pt_vpos = it.vpos;
22711 if (dir > 0 || overshoot_expected)
22713 struct glyph_row *row = it.glyph_row;
22715 /* When point is at beginning of line, we don't have
22716 information about the glyph there loaded into struct
22717 it. Calling get_next_display_element fixes that. */
22718 if (pt_x == 0)
22719 get_next_display_element (&it);
22720 at_eol_p = ITERATOR_AT_END_OF_LINE_P (&it);
22721 it.glyph_row = NULL;
22722 PRODUCE_GLYPHS (&it); /* compute it.pixel_width */
22723 it.glyph_row = row;
22724 /* PRODUCE_GLYPHS advances it.current_x, so we must restore
22725 it, lest it will become out of sync with it's buffer
22726 position. */
22727 it.current_x = pt_x;
22729 else
22730 at_eol_p = ITERATOR_AT_END_OF_LINE_P (&it);
22731 pixel_width = it.pixel_width;
22732 if (overshoot_expected && at_eol_p)
22733 pixel_width = 0;
22734 else if (pixel_width <= 0)
22735 pixel_width = 1;
22737 /* If there's a display string (or something similar) at point,
22738 we are actually at the glyph to the left of point, so we need
22739 to correct the X coordinate. */
22740 if (overshoot_expected)
22742 if (it.bidi_p)
22743 pt_x += pixel_width * it.bidi_it.scan_dir;
22744 else
22745 pt_x += pixel_width;
22748 /* Compute target X coordinate, either to the left or to the
22749 right of point. On TTY frames, all characters have the same
22750 pixel width of 1, so we can use that. On GUI frames we don't
22751 have an easy way of getting at the pixel width of the
22752 character to the left of point, so we use a different method
22753 of getting to that place. */
22754 if (dir > 0)
22755 target_x = pt_x + pixel_width;
22756 else
22757 target_x = pt_x - (!FRAME_WINDOW_P (it.f)) * pixel_width;
22759 /* Target X coordinate could be one line above or below the line
22760 of point, in which case we need to adjust the target X
22761 coordinate. Also, if moving to the left, we need to begin at
22762 the left edge of the point's screen line. */
22763 if (dir < 0)
22765 if (pt_x > 0)
22767 start_display (&it, w, pt);
22768 if (it.line_wrap == TRUNCATE)
22769 it.last_visible_x = DISP_INFINITY;
22770 reseat_at_previous_visible_line_start (&it);
22771 it.current_x = it.current_y = it.hpos = 0;
22772 if (pt_vpos != 0)
22773 move_it_by_lines (&it, pt_vpos);
22775 else
22777 move_it_by_lines (&it, -1);
22778 target_x = it.last_visible_x - !FRAME_WINDOW_P (it.f);
22779 target_is_eol_p = true;
22780 /* Under word-wrap, we don't know the x coordinate of
22781 the last character displayed on the previous line,
22782 which immediately precedes the wrap point. To find
22783 out its x coordinate, we try moving to the right
22784 margin of the window, which will stop at the wrap
22785 point, and then reset target_x to point at the
22786 character that precedes the wrap point. This is not
22787 needed on GUI frames, because (see below) there we
22788 move from the left margin one grapheme cluster at a
22789 time, and stop when we hit the wrap point. */
22790 if (!FRAME_WINDOW_P (it.f) && it.line_wrap == WORD_WRAP)
22792 void *it_data = NULL;
22793 struct it it2;
22795 SAVE_IT (it2, it, it_data);
22796 move_it_in_display_line_to (&it, ZV, target_x,
22797 MOVE_TO_POS | MOVE_TO_X);
22798 /* If we arrived at target_x, that _is_ the last
22799 character on the previous line. */
22800 if (it.current_x != target_x)
22801 target_x = it.current_x - 1;
22802 RESTORE_IT (&it, &it2, it_data);
22806 else
22808 if (at_eol_p
22809 || (target_x >= it.last_visible_x
22810 && it.line_wrap != TRUNCATE))
22812 if (pt_x > 0)
22813 move_it_by_lines (&it, 0);
22814 move_it_by_lines (&it, 1);
22815 target_x = 0;
22819 /* Move to the target X coordinate. */
22820 /* On GUI frames, as we don't know the X coordinate of the
22821 character to the left of point, moving point to the left
22822 requires walking, one grapheme cluster at a time, until we
22823 find ourself at a place immediately to the left of the
22824 character at point. */
22825 if (FRAME_WINDOW_P (it.f) && dir < 0)
22827 struct text_pos new_pos;
22828 enum move_it_result rc = MOVE_X_REACHED;
22830 if (it.current_x == 0)
22831 get_next_display_element (&it);
22832 if (it.what == IT_COMPOSITION)
22834 new_pos.charpos = it.cmp_it.charpos;
22835 new_pos.bytepos = -1;
22837 else
22838 new_pos = it.current.pos;
22840 while (it.current_x + it.pixel_width <= target_x
22841 && (rc == MOVE_X_REACHED
22842 /* Under word-wrap, move_it_in_display_line_to
22843 stops at correct coordinates, but sometimes
22844 returns MOVE_POS_MATCH_OR_ZV. */
22845 || (it.line_wrap == WORD_WRAP
22846 && rc == MOVE_POS_MATCH_OR_ZV)))
22848 int new_x = it.current_x + it.pixel_width;
22850 /* For composed characters, we want the position of the
22851 first character in the grapheme cluster (usually, the
22852 composition's base character), whereas it.current
22853 might give us the position of the _last_ one, e.g. if
22854 the composition is rendered in reverse due to bidi
22855 reordering. */
22856 if (it.what == IT_COMPOSITION)
22858 new_pos.charpos = it.cmp_it.charpos;
22859 new_pos.bytepos = -1;
22861 else
22862 new_pos = it.current.pos;
22863 if (new_x == it.current_x)
22864 new_x++;
22865 rc = move_it_in_display_line_to (&it, ZV, new_x,
22866 MOVE_TO_POS | MOVE_TO_X);
22867 if (ITERATOR_AT_END_OF_LINE_P (&it) && !target_is_eol_p)
22868 break;
22870 /* The previous position we saw in the loop is the one we
22871 want. */
22872 if (new_pos.bytepos == -1)
22873 new_pos.bytepos = CHAR_TO_BYTE (new_pos.charpos);
22874 it.current.pos = new_pos;
22876 else if (it.current_x != target_x)
22877 move_it_in_display_line_to (&it, ZV, target_x, MOVE_TO_POS | MOVE_TO_X);
22879 /* If we ended up in a display string that covers point, move to
22880 buffer position to the right in the visual order. */
22881 if (dir > 0)
22883 while (IT_CHARPOS (it) == PT)
22885 set_iterator_to_next (&it, false);
22886 if (!get_next_display_element (&it))
22887 break;
22891 /* Move point to that position. */
22892 SET_PT_BOTH (IT_CHARPOS (it), IT_BYTEPOS (it));
22895 return make_number (PT);
22897 #undef ROW_GLYPH_NEWLINE_P
22900 DEFUN ("bidi-resolved-levels", Fbidi_resolved_levels,
22901 Sbidi_resolved_levels, 0, 1, 0,
22902 doc: /* Return the resolved bidirectional levels of characters at VPOS.
22904 The resolved levels are produced by the Emacs bidi reordering engine
22905 that implements the UBA, the Unicode Bidirectional Algorithm. Please
22906 read the Unicode Standard Annex 9 (UAX#9) for background information
22907 about these levels.
22909 VPOS is the zero-based number of the current window's screen line
22910 for which to produce the resolved levels. If VPOS is nil or omitted,
22911 it defaults to the screen line of point. If the window displays a
22912 header line, VPOS of zero will report on the header line, and first
22913 line of text in the window will have VPOS of 1.
22915 Value is an array of resolved levels, indexed by glyph number.
22916 Glyphs are numbered from zero starting from the beginning of the
22917 screen line, i.e. the left edge of the window for left-to-right lines
22918 and from the right edge for right-to-left lines. The resolved levels
22919 are produced only for the window's text area; text in display margins
22920 is not included.
22922 If the selected window's display is not up-to-date, or if the specified
22923 screen line does not display text, this function returns nil. It is
22924 highly recommended to bind this function to some simple key, like F8,
22925 in order to avoid these problems.
22927 This function exists mainly for testing the correctness of the
22928 Emacs UBA implementation, in particular with the test suite. */)
22929 (Lisp_Object vpos)
22931 struct window *w = XWINDOW (selected_window);
22932 struct buffer *b = XBUFFER (w->contents);
22933 int nrow;
22934 struct glyph_row *row;
22936 if (NILP (vpos))
22938 int d1, d2, d3, d4, d5;
22940 pos_visible_p (w, PT, &d1, &d2, &d3, &d4, &d5, &nrow);
22942 else
22944 CHECK_NUMBER_COERCE_MARKER (vpos);
22945 nrow = XINT (vpos);
22948 /* We require up-to-date glyph matrix for this window. */
22949 if (w->window_end_valid
22950 && !windows_or_buffers_changed
22951 && b
22952 && !b->clip_changed
22953 && !b->prevent_redisplay_optimizations_p
22954 && !window_outdated (w)
22955 && nrow >= 0
22956 && nrow < w->current_matrix->nrows
22957 && (row = MATRIX_ROW (w->current_matrix, nrow))->enabled_p
22958 && MATRIX_ROW_DISPLAYS_TEXT_P (row))
22960 struct glyph *g, *e, *g1;
22961 int nglyphs, i;
22962 Lisp_Object levels;
22964 if (!row->reversed_p) /* Left-to-right glyph row. */
22966 g = g1 = row->glyphs[TEXT_AREA];
22967 e = g + row->used[TEXT_AREA];
22969 /* Skip over glyphs at the start of the row that was
22970 generated by redisplay for its own needs. */
22971 while (g < e
22972 && NILP (g->object)
22973 && g->charpos < 0)
22974 g++;
22975 g1 = g;
22977 /* Count the "interesting" glyphs in this row. */
22978 for (nglyphs = 0; g < e && !NILP (g->object); g++)
22979 nglyphs++;
22981 /* Create and fill the array. */
22982 levels = make_uninit_vector (nglyphs);
22983 for (i = 0; g1 < g; i++, g1++)
22984 ASET (levels, i, make_number (g1->resolved_level));
22986 else /* Right-to-left glyph row. */
22988 g = row->glyphs[TEXT_AREA] + row->used[TEXT_AREA] - 1;
22989 e = row->glyphs[TEXT_AREA] - 1;
22990 while (g > e
22991 && NILP (g->object)
22992 && g->charpos < 0)
22993 g--;
22994 g1 = g;
22995 for (nglyphs = 0; g > e && !NILP (g->object); g--)
22996 nglyphs++;
22997 levels = make_uninit_vector (nglyphs);
22998 for (i = 0; g1 > g; i++, g1--)
22999 ASET (levels, i, make_number (g1->resolved_level));
23001 return levels;
23003 else
23004 return Qnil;
23009 /***********************************************************************
23010 Menu Bar
23011 ***********************************************************************/
23013 /* Redisplay the menu bar in the frame for window W.
23015 The menu bar of X frames that don't have X toolkit support is
23016 displayed in a special window W->frame->menu_bar_window.
23018 The menu bar of terminal frames is treated specially as far as
23019 glyph matrices are concerned. Menu bar lines are not part of
23020 windows, so the update is done directly on the frame matrix rows
23021 for the menu bar. */
23023 static void
23024 display_menu_bar (struct window *w)
23026 struct frame *f = XFRAME (WINDOW_FRAME (w));
23027 struct it it;
23028 Lisp_Object items;
23029 int i;
23031 /* Don't do all this for graphical frames. */
23032 #ifdef HAVE_NTGUI
23033 if (FRAME_W32_P (f))
23034 return;
23035 #endif
23036 #if defined (USE_X_TOOLKIT) || defined (USE_GTK)
23037 if (FRAME_X_P (f))
23038 return;
23039 #endif
23041 #ifdef HAVE_NS
23042 if (FRAME_NS_P (f))
23043 return;
23044 #endif /* HAVE_NS */
23046 #if defined (USE_X_TOOLKIT) || defined (USE_GTK)
23047 eassert (!FRAME_WINDOW_P (f));
23048 init_iterator (&it, w, -1, -1, f->desired_matrix->rows, MENU_FACE_ID);
23049 it.first_visible_x = 0;
23050 it.last_visible_x = FRAME_PIXEL_WIDTH (f);
23051 #elif defined (HAVE_X_WINDOWS) /* X without toolkit. */
23052 if (FRAME_WINDOW_P (f))
23054 /* Menu bar lines are displayed in the desired matrix of the
23055 dummy window menu_bar_window. */
23056 struct window *menu_w;
23057 menu_w = XWINDOW (f->menu_bar_window);
23058 init_iterator (&it, menu_w, -1, -1, menu_w->desired_matrix->rows,
23059 MENU_FACE_ID);
23060 it.first_visible_x = 0;
23061 it.last_visible_x = FRAME_PIXEL_WIDTH (f);
23063 else
23064 #endif /* not USE_X_TOOLKIT and not USE_GTK */
23066 /* This is a TTY frame, i.e. character hpos/vpos are used as
23067 pixel x/y. */
23068 init_iterator (&it, w, -1, -1, f->desired_matrix->rows,
23069 MENU_FACE_ID);
23070 it.first_visible_x = 0;
23071 it.last_visible_x = FRAME_COLS (f);
23074 /* FIXME: This should be controlled by a user option. See the
23075 comments in redisplay_tool_bar and display_mode_line about
23076 this. */
23077 it.paragraph_embedding = L2R;
23079 /* Clear all rows of the menu bar. */
23080 for (i = 0; i < FRAME_MENU_BAR_LINES (f); ++i)
23082 struct glyph_row *row = it.glyph_row + i;
23083 clear_glyph_row (row);
23084 row->enabled_p = true;
23085 row->full_width_p = true;
23086 row->reversed_p = false;
23089 /* Display all items of the menu bar. */
23090 items = FRAME_MENU_BAR_ITEMS (it.f);
23091 for (i = 0; i < ASIZE (items); i += 4)
23093 Lisp_Object string;
23095 /* Stop at nil string. */
23096 string = AREF (items, i + 1);
23097 if (NILP (string))
23098 break;
23100 /* Remember where item was displayed. */
23101 ASET (items, i + 3, make_number (it.hpos));
23103 /* Display the item, pad with one space. */
23104 if (it.current_x < it.last_visible_x)
23105 display_string (NULL, string, Qnil, 0, 0, &it,
23106 SCHARS (string) + 1, 0, 0, -1);
23109 /* Fill out the line with spaces. */
23110 if (it.current_x < it.last_visible_x)
23111 display_string ("", Qnil, Qnil, 0, 0, &it, -1, 0, 0, -1);
23113 /* Compute the total height of the lines. */
23114 compute_line_metrics (&it);
23117 /* Deep copy of a glyph row, including the glyphs. */
23118 static void
23119 deep_copy_glyph_row (struct glyph_row *to, struct glyph_row *from)
23121 struct glyph *pointers[1 + LAST_AREA];
23122 int to_used = to->used[TEXT_AREA];
23124 /* Save glyph pointers of TO. */
23125 memcpy (pointers, to->glyphs, sizeof to->glyphs);
23127 /* Do a structure assignment. */
23128 *to = *from;
23130 /* Restore original glyph pointers of TO. */
23131 memcpy (to->glyphs, pointers, sizeof to->glyphs);
23133 /* Copy the glyphs. */
23134 memcpy (to->glyphs[TEXT_AREA], from->glyphs[TEXT_AREA],
23135 min (from->used[TEXT_AREA], to_used) * sizeof (struct glyph));
23137 /* If we filled only part of the TO row, fill the rest with
23138 space_glyph (which will display as empty space). */
23139 if (to_used > from->used[TEXT_AREA])
23140 fill_up_frame_row_with_spaces (to, to_used);
23143 /* Display one menu item on a TTY, by overwriting the glyphs in the
23144 frame F's desired glyph matrix with glyphs produced from the menu
23145 item text. Called from term.c to display TTY drop-down menus one
23146 item at a time.
23148 ITEM_TEXT is the menu item text as a C string.
23150 FACE_ID is the face ID to be used for this menu item. FACE_ID
23151 could specify one of 3 faces: a face for an enabled item, a face
23152 for a disabled item, or a face for a selected item.
23154 X and Y are coordinates of the first glyph in the frame's desired
23155 matrix to be overwritten by the menu item. Since this is a TTY, Y
23156 is the zero-based number of the glyph row and X is the zero-based
23157 glyph number in the row, starting from left, where to start
23158 displaying the item.
23160 SUBMENU means this menu item drops down a submenu, which
23161 should be indicated by displaying a proper visual cue after the
23162 item text. */
23164 void
23165 display_tty_menu_item (const char *item_text, int width, int face_id,
23166 int x, int y, bool submenu)
23168 struct it it;
23169 struct frame *f = SELECTED_FRAME ();
23170 struct window *w = XWINDOW (f->selected_window);
23171 struct glyph_row *row;
23172 size_t item_len = strlen (item_text);
23174 eassert (FRAME_TERMCAP_P (f));
23176 /* Don't write beyond the matrix's last row. This can happen for
23177 TTY screens that are not high enough to show the entire menu.
23178 (This is actually a bit of defensive programming, as
23179 tty_menu_display already limits the number of menu items to one
23180 less than the number of screen lines.) */
23181 if (y >= f->desired_matrix->nrows)
23182 return;
23184 init_iterator (&it, w, -1, -1, f->desired_matrix->rows + y, MENU_FACE_ID);
23185 it.first_visible_x = 0;
23186 it.last_visible_x = FRAME_COLS (f) - 1;
23187 row = it.glyph_row;
23188 /* Start with the row contents from the current matrix. */
23189 deep_copy_glyph_row (row, f->current_matrix->rows + y);
23190 bool saved_width = row->full_width_p;
23191 row->full_width_p = true;
23192 bool saved_reversed = row->reversed_p;
23193 row->reversed_p = false;
23194 row->enabled_p = true;
23196 /* Arrange for the menu item glyphs to start at (X,Y) and have the
23197 desired face. */
23198 eassert (x < f->desired_matrix->matrix_w);
23199 it.current_x = it.hpos = x;
23200 it.current_y = it.vpos = y;
23201 int saved_used = row->used[TEXT_AREA];
23202 bool saved_truncated = row->truncated_on_right_p;
23203 row->used[TEXT_AREA] = x;
23204 it.face_id = face_id;
23205 it.line_wrap = TRUNCATE;
23207 /* FIXME: This should be controlled by a user option. See the
23208 comments in redisplay_tool_bar and display_mode_line about this.
23209 Also, if paragraph_embedding could ever be R2L, changes will be
23210 needed to avoid shifting to the right the row characters in
23211 term.c:append_glyph. */
23212 it.paragraph_embedding = L2R;
23214 /* Pad with a space on the left. */
23215 display_string (" ", Qnil, Qnil, 0, 0, &it, 1, 0, FRAME_COLS (f) - 1, -1);
23216 width--;
23217 /* Display the menu item, pad with spaces to WIDTH. */
23218 if (submenu)
23220 display_string (item_text, Qnil, Qnil, 0, 0, &it,
23221 item_len, 0, FRAME_COLS (f) - 1, -1);
23222 width -= item_len;
23223 /* Indicate with " >" that there's a submenu. */
23224 display_string (" >", Qnil, Qnil, 0, 0, &it, width, 0,
23225 FRAME_COLS (f) - 1, -1);
23227 else
23228 display_string (item_text, Qnil, Qnil, 0, 0, &it,
23229 width, 0, FRAME_COLS (f) - 1, -1);
23231 row->used[TEXT_AREA] = max (saved_used, row->used[TEXT_AREA]);
23232 row->truncated_on_right_p = saved_truncated;
23233 row->hash = row_hash (row);
23234 row->full_width_p = saved_width;
23235 row->reversed_p = saved_reversed;
23238 /***********************************************************************
23239 Mode Line
23240 ***********************************************************************/
23242 /* Redisplay mode lines in the window tree whose root is WINDOW.
23243 If FORCE, redisplay mode lines unconditionally.
23244 Otherwise, redisplay only mode lines that are garbaged. Value is
23245 the number of windows whose mode lines were redisplayed. */
23247 static int
23248 redisplay_mode_lines (Lisp_Object window, bool force)
23250 int nwindows = 0;
23252 while (!NILP (window))
23254 struct window *w = XWINDOW (window);
23256 if (WINDOWP (w->contents))
23257 nwindows += redisplay_mode_lines (w->contents, force);
23258 else if (force
23259 || FRAME_GARBAGED_P (XFRAME (w->frame))
23260 || !MATRIX_MODE_LINE_ROW (w->current_matrix)->enabled_p)
23262 struct text_pos lpoint;
23263 struct buffer *old = current_buffer;
23265 /* Set the window's buffer for the mode line display. */
23266 SET_TEXT_POS (lpoint, PT, PT_BYTE);
23267 set_buffer_internal_1 (XBUFFER (w->contents));
23269 /* Point refers normally to the selected window. For any
23270 other window, set up appropriate value. */
23271 if (!EQ (window, selected_window))
23273 struct text_pos pt;
23275 CLIP_TEXT_POS_FROM_MARKER (pt, w->pointm);
23276 TEMP_SET_PT_BOTH (CHARPOS (pt), BYTEPOS (pt));
23279 /* Display mode lines. */
23280 clear_glyph_matrix (w->desired_matrix);
23281 if (display_mode_lines (w))
23282 ++nwindows;
23284 /* Restore old settings. */
23285 set_buffer_internal_1 (old);
23286 TEMP_SET_PT_BOTH (CHARPOS (lpoint), BYTEPOS (lpoint));
23289 window = w->next;
23292 return nwindows;
23296 /* Display the mode and/or header line of window W. Value is the
23297 sum number of mode lines and header lines displayed. */
23299 static int
23300 display_mode_lines (struct window *w)
23302 Lisp_Object old_selected_window = selected_window;
23303 Lisp_Object old_selected_frame = selected_frame;
23304 Lisp_Object new_frame = w->frame;
23305 Lisp_Object old_frame_selected_window = XFRAME (new_frame)->selected_window;
23306 int n = 0;
23308 if (window_wants_mode_line (w))
23310 Lisp_Object window;
23311 Lisp_Object default_help
23312 = buffer_local_value (Qmode_line_default_help_echo, w->contents);
23314 /* Set up mode line help echo. Do this before selecting w so it
23315 can reasonably tell whether a mouse click will select w. */
23316 XSETWINDOW (window, w);
23317 if (FUNCTIONP (default_help))
23318 wset_mode_line_help_echo (w, safe_call1 (default_help, window));
23319 else if (STRINGP (default_help))
23320 wset_mode_line_help_echo (w, default_help);
23321 else
23322 wset_mode_line_help_echo (w, Qnil);
23325 selected_frame = new_frame;
23326 /* FIXME: If we were to allow the mode-line's computation changing the buffer
23327 or window's point, then we'd need select_window_1 here as well. */
23328 XSETWINDOW (selected_window, w);
23329 XFRAME (new_frame)->selected_window = selected_window;
23331 /* These will be set while the mode line specs are processed. */
23332 line_number_displayed = false;
23333 w->column_number_displayed = -1;
23335 if (window_wants_mode_line (w))
23337 Lisp_Object window_mode_line_format
23338 = window_parameter (w, Qmode_line_format);
23339 struct window *sel_w = XWINDOW (old_selected_window);
23341 /* Select mode line face based on the real selected window. */
23342 display_mode_line (w, CURRENT_MODE_LINE_FACE_ID_3 (sel_w, sel_w, w),
23343 NILP (window_mode_line_format)
23344 ? BVAR (current_buffer, mode_line_format)
23345 : window_mode_line_format);
23346 ++n;
23349 if (window_wants_header_line (w))
23351 Lisp_Object window_header_line_format
23352 = window_parameter (w, Qheader_line_format);
23354 display_mode_line (w, HEADER_LINE_FACE_ID,
23355 NILP (window_header_line_format)
23356 ? BVAR (current_buffer, header_line_format)
23357 : window_header_line_format);
23358 ++n;
23361 XFRAME (new_frame)->selected_window = old_frame_selected_window;
23362 selected_frame = old_selected_frame;
23363 selected_window = old_selected_window;
23364 if (n > 0)
23365 w->must_be_updated_p = true;
23366 return n;
23370 /* Display mode or header line of window W. FACE_ID specifies which
23371 line to display; it is either MODE_LINE_FACE_ID or
23372 HEADER_LINE_FACE_ID. FORMAT is the mode/header line format to
23373 display. Value is the pixel height of the mode/header line
23374 displayed. */
23376 static int
23377 display_mode_line (struct window *w, enum face_id face_id, Lisp_Object format)
23379 struct it it;
23380 struct face *face;
23381 ptrdiff_t count = SPECPDL_INDEX ();
23383 init_iterator (&it, w, -1, -1, NULL, face_id);
23384 /* Don't extend on a previously drawn mode-line.
23385 This may happen if called from pos_visible_p. */
23386 it.glyph_row->enabled_p = false;
23387 prepare_desired_row (w, it.glyph_row, true);
23389 it.glyph_row->mode_line_p = true;
23391 /* FIXME: This should be controlled by a user option. But
23392 supporting such an option is not trivial, since the mode line is
23393 made up of many separate strings. */
23394 it.paragraph_embedding = L2R;
23396 record_unwind_protect (unwind_format_mode_line,
23397 format_mode_line_unwind_data (NULL, NULL,
23398 Qnil, false));
23400 mode_line_target = MODE_LINE_DISPLAY;
23402 /* Temporarily make frame's keyboard the current kboard so that
23403 kboard-local variables in the mode_line_format will get the right
23404 values. */
23405 push_kboard (FRAME_KBOARD (it.f));
23406 record_unwind_save_match_data ();
23407 display_mode_element (&it, 0, 0, 0, format, Qnil, false);
23408 pop_kboard ();
23410 unbind_to (count, Qnil);
23412 /* Fill up with spaces. */
23413 display_string (" ", Qnil, Qnil, 0, 0, &it, 10000, -1, -1, 0);
23415 compute_line_metrics (&it);
23416 it.glyph_row->full_width_p = true;
23417 it.glyph_row->continued_p = false;
23418 it.glyph_row->truncated_on_left_p = false;
23419 it.glyph_row->truncated_on_right_p = false;
23421 /* Make a 3D mode-line have a shadow at its right end. */
23422 face = FACE_FROM_ID (it.f, face_id);
23423 extend_face_to_end_of_line (&it);
23424 if (face->box != FACE_NO_BOX)
23426 struct glyph *last = (it.glyph_row->glyphs[TEXT_AREA]
23427 + it.glyph_row->used[TEXT_AREA] - 1);
23428 last->right_box_line_p = true;
23431 return it.glyph_row->height;
23434 /* Move element ELT in LIST to the front of LIST.
23435 Return the updated list. */
23437 static Lisp_Object
23438 move_elt_to_front (Lisp_Object elt, Lisp_Object list)
23440 register Lisp_Object tail, prev;
23441 register Lisp_Object tem;
23443 tail = list;
23444 prev = Qnil;
23445 while (CONSP (tail))
23447 tem = XCAR (tail);
23449 if (EQ (elt, tem))
23451 /* Splice out the link TAIL. */
23452 if (NILP (prev))
23453 list = XCDR (tail);
23454 else
23455 Fsetcdr (prev, XCDR (tail));
23457 /* Now make it the first. */
23458 Fsetcdr (tail, list);
23459 return tail;
23461 else
23462 prev = tail;
23463 tail = XCDR (tail);
23464 maybe_quit ();
23467 /* Not found--return unchanged LIST. */
23468 return list;
23471 /* Contribute ELT to the mode line for window IT->w. How it
23472 translates into text depends on its data type.
23474 IT describes the display environment in which we display, as usual.
23476 DEPTH is the depth in recursion. It is used to prevent
23477 infinite recursion here.
23479 FIELD_WIDTH is the number of characters the display of ELT should
23480 occupy in the mode line, and PRECISION is the maximum number of
23481 characters to display from ELT's representation. See
23482 display_string for details.
23484 Returns the hpos of the end of the text generated by ELT.
23486 PROPS is a property list to add to any string we encounter.
23488 If RISKY, remove (disregard) any properties in any string
23489 we encounter, and ignore :eval and :propertize.
23491 The global variable `mode_line_target' determines whether the
23492 output is passed to `store_mode_line_noprop',
23493 `store_mode_line_string', or `display_string'. */
23495 static int
23496 display_mode_element (struct it *it, int depth, int field_width, int precision,
23497 Lisp_Object elt, Lisp_Object props, bool risky)
23499 int n = 0, field, prec;
23500 bool literal = false;
23502 tail_recurse:
23503 if (depth > 100)
23504 elt = build_string ("*too-deep*");
23506 depth++;
23508 switch (XTYPE (elt))
23510 case Lisp_String:
23512 /* A string: output it and check for %-constructs within it. */
23513 unsigned char c;
23514 ptrdiff_t offset = 0;
23516 if (SCHARS (elt) > 0
23517 && (!NILP (props) || risky))
23519 Lisp_Object oprops, aelt;
23520 oprops = Ftext_properties_at (make_number (0), elt);
23522 /* If the starting string's properties are not what
23523 we want, translate the string. Also, if the string
23524 is risky, do that anyway. */
23526 if (NILP (Fequal (props, oprops)) || risky)
23528 /* If the starting string has properties,
23529 merge the specified ones onto the existing ones. */
23530 if (! NILP (oprops) && !risky)
23532 Lisp_Object tem;
23534 oprops = Fcopy_sequence (oprops);
23535 tem = props;
23536 while (CONSP (tem))
23538 oprops = Fplist_put (oprops, XCAR (tem),
23539 XCAR (XCDR (tem)));
23540 tem = XCDR (XCDR (tem));
23542 props = oprops;
23545 aelt = Fassoc (elt, mode_line_proptrans_alist, Qnil);
23546 if (! NILP (aelt) && !NILP (Fequal (props, XCDR (aelt))))
23548 /* AELT is what we want. Move it to the front
23549 without consing. */
23550 elt = XCAR (aelt);
23551 mode_line_proptrans_alist
23552 = move_elt_to_front (aelt, mode_line_proptrans_alist);
23554 else
23556 Lisp_Object tem;
23558 /* If AELT has the wrong props, it is useless.
23559 so get rid of it. */
23560 if (! NILP (aelt))
23561 mode_line_proptrans_alist
23562 = Fdelq (aelt, mode_line_proptrans_alist);
23564 elt = Fcopy_sequence (elt);
23565 Fset_text_properties (make_number (0), Flength (elt),
23566 props, elt);
23567 /* Add this item to mode_line_proptrans_alist. */
23568 mode_line_proptrans_alist
23569 = Fcons (Fcons (elt, props),
23570 mode_line_proptrans_alist);
23571 /* Truncate mode_line_proptrans_alist
23572 to at most 50 elements. */
23573 tem = Fnthcdr (make_number (50),
23574 mode_line_proptrans_alist);
23575 if (! NILP (tem))
23576 XSETCDR (tem, Qnil);
23581 offset = 0;
23583 if (literal)
23585 prec = precision - n;
23586 switch (mode_line_target)
23588 case MODE_LINE_NOPROP:
23589 case MODE_LINE_TITLE:
23590 n += store_mode_line_noprop (SSDATA (elt), -1, prec);
23591 break;
23592 case MODE_LINE_STRING:
23593 n += store_mode_line_string (NULL, elt, true, 0, prec, Qnil);
23594 break;
23595 case MODE_LINE_DISPLAY:
23596 n += display_string (NULL, elt, Qnil, 0, 0, it,
23597 0, prec, 0, STRING_MULTIBYTE (elt));
23598 break;
23601 break;
23604 /* Handle the non-literal case. */
23606 while ((precision <= 0 || n < precision)
23607 && SREF (elt, offset) != 0
23608 && (mode_line_target != MODE_LINE_DISPLAY
23609 || it->current_x < it->last_visible_x))
23611 ptrdiff_t last_offset = offset;
23613 /* Advance to end of string or next format specifier. */
23614 while ((c = SREF (elt, offset++)) != '\0' && c != '%')
23617 if (offset - 1 != last_offset)
23619 ptrdiff_t nchars, nbytes;
23621 /* Output to end of string or up to '%'. Field width
23622 is length of string. Don't output more than
23623 PRECISION allows us. */
23624 offset--;
23626 prec = c_string_width (SDATA (elt) + last_offset,
23627 offset - last_offset, precision - n,
23628 &nchars, &nbytes);
23630 switch (mode_line_target)
23632 case MODE_LINE_NOPROP:
23633 case MODE_LINE_TITLE:
23634 n += store_mode_line_noprop (SSDATA (elt) + last_offset, 0, prec);
23635 break;
23636 case MODE_LINE_STRING:
23638 ptrdiff_t bytepos = last_offset;
23639 ptrdiff_t charpos = string_byte_to_char (elt, bytepos);
23640 ptrdiff_t endpos = (precision <= 0
23641 ? string_byte_to_char (elt, offset)
23642 : charpos + nchars);
23643 Lisp_Object mode_string
23644 = Fsubstring (elt, make_number (charpos),
23645 make_number (endpos));
23646 n += store_mode_line_string (NULL, mode_string, false,
23647 0, 0, Qnil);
23649 break;
23650 case MODE_LINE_DISPLAY:
23652 ptrdiff_t bytepos = last_offset;
23653 ptrdiff_t charpos = string_byte_to_char (elt, bytepos);
23655 if (precision <= 0)
23656 nchars = string_byte_to_char (elt, offset) - charpos;
23657 n += display_string (NULL, elt, Qnil, 0, charpos,
23658 it, 0, nchars, 0,
23659 STRING_MULTIBYTE (elt));
23661 break;
23664 else /* c == '%' */
23666 ptrdiff_t percent_position = offset;
23668 /* Get the specified minimum width. Zero means
23669 don't pad. */
23670 field = 0;
23671 while ((c = SREF (elt, offset++)) >= '0' && c <= '9')
23672 field = field * 10 + c - '0';
23674 /* Don't pad beyond the total padding allowed. */
23675 if (field_width - n > 0 && field > field_width - n)
23676 field = field_width - n;
23678 /* Note that either PRECISION <= 0 or N < PRECISION. */
23679 prec = precision - n;
23681 if (c == 'M')
23682 n += display_mode_element (it, depth, field, prec,
23683 Vglobal_mode_string, props,
23684 risky);
23685 else if (c != 0)
23687 bool multibyte;
23688 ptrdiff_t bytepos, charpos;
23689 const char *spec;
23690 Lisp_Object string;
23692 bytepos = percent_position;
23693 charpos = (STRING_MULTIBYTE (elt)
23694 ? string_byte_to_char (elt, bytepos)
23695 : bytepos);
23696 spec = decode_mode_spec (it->w, c, field, &string);
23697 multibyte = STRINGP (string) && STRING_MULTIBYTE (string);
23699 switch (mode_line_target)
23701 case MODE_LINE_NOPROP:
23702 case MODE_LINE_TITLE:
23703 n += store_mode_line_noprop (spec, field, prec);
23704 break;
23705 case MODE_LINE_STRING:
23707 Lisp_Object tem = build_string (spec);
23708 props = Ftext_properties_at (make_number (charpos), elt);
23709 /* Should only keep face property in props */
23710 n += store_mode_line_string (NULL, tem, false,
23711 field, prec, props);
23713 break;
23714 case MODE_LINE_DISPLAY:
23716 int nglyphs_before, nwritten;
23718 nglyphs_before = it->glyph_row->used[TEXT_AREA];
23719 nwritten = display_string (spec, string, elt,
23720 charpos, 0, it,
23721 field, prec, 0,
23722 multibyte);
23724 /* Assign to the glyphs written above the
23725 string where the `%x' came from, position
23726 of the `%'. */
23727 if (nwritten > 0)
23729 struct glyph *glyph
23730 = (it->glyph_row->glyphs[TEXT_AREA]
23731 + nglyphs_before);
23732 int i;
23734 for (i = 0; i < nwritten; ++i)
23736 glyph[i].object = elt;
23737 glyph[i].charpos = charpos;
23740 n += nwritten;
23743 break;
23746 else /* c == 0 */
23747 break;
23751 break;
23753 case Lisp_Symbol:
23754 /* A symbol: process the value of the symbol recursively
23755 as if it appeared here directly. Avoid error if symbol void.
23756 Special case: if value of symbol is a string, output the string
23757 literally. */
23759 register Lisp_Object tem;
23761 /* If the variable is not marked as risky to set
23762 then its contents are risky to use. */
23763 if (NILP (Fget (elt, Qrisky_local_variable)))
23764 risky = true;
23766 tem = Fboundp (elt);
23767 if (!NILP (tem))
23769 tem = Fsymbol_value (elt);
23770 /* If value is a string, output that string literally:
23771 don't check for % within it. */
23772 if (STRINGP (tem))
23773 literal = true;
23775 if (!EQ (tem, elt))
23777 /* Give up right away for nil or t. */
23778 elt = tem;
23779 goto tail_recurse;
23783 break;
23785 case Lisp_Cons:
23787 register Lisp_Object car, tem;
23789 /* A cons cell: five distinct cases.
23790 If first element is :eval or :propertize, do something special.
23791 If first element is a string or a cons, process all the elements
23792 and effectively concatenate them.
23793 If first element is a negative number, truncate displaying cdr to
23794 at most that many characters. If positive, pad (with spaces)
23795 to at least that many characters.
23796 If first element is a symbol, process the cadr or caddr recursively
23797 according to whether the symbol's value is non-nil or nil. */
23798 car = XCAR (elt);
23799 if (EQ (car, QCeval))
23801 /* An element of the form (:eval FORM) means evaluate FORM
23802 and use the result as mode line elements. */
23804 if (risky)
23805 break;
23807 if (CONSP (XCDR (elt)))
23809 Lisp_Object spec;
23810 spec = safe__eval (true, XCAR (XCDR (elt)));
23811 /* The :eval form could delete the frame stored in the
23812 iterator, which will cause a crash if we try to
23813 access faces and other fields (e.g., FRAME_KBOARD)
23814 on that frame. This is a nonsensical thing to do,
23815 and signaling an error from redisplay might be
23816 dangerous, but we cannot continue with an invalid frame. */
23817 if (!FRAME_LIVE_P (it->f))
23818 signal_error (":eval deleted the frame being displayed", elt);
23819 n += display_mode_element (it, depth, field_width - n,
23820 precision - n, spec, props,
23821 risky);
23824 else if (EQ (car, QCpropertize))
23826 /* An element of the form (:propertize ELT PROPS...)
23827 means display ELT but applying properties PROPS. */
23829 if (risky)
23830 break;
23832 if (CONSP (XCDR (elt)))
23833 n += display_mode_element (it, depth, field_width - n,
23834 precision - n, XCAR (XCDR (elt)),
23835 XCDR (XCDR (elt)), risky);
23837 else if (SYMBOLP (car))
23839 tem = Fboundp (car);
23840 elt = XCDR (elt);
23841 if (!CONSP (elt))
23842 goto invalid;
23843 /* elt is now the cdr, and we know it is a cons cell.
23844 Use its car if CAR has a non-nil value. */
23845 if (!NILP (tem))
23847 tem = Fsymbol_value (car);
23848 if (!NILP (tem))
23850 elt = XCAR (elt);
23851 goto tail_recurse;
23854 /* Symbol's value is nil (or symbol is unbound)
23855 Get the cddr of the original list
23856 and if possible find the caddr and use that. */
23857 elt = XCDR (elt);
23858 if (NILP (elt))
23859 break;
23860 else if (!CONSP (elt))
23861 goto invalid;
23862 elt = XCAR (elt);
23863 goto tail_recurse;
23865 else if (INTEGERP (car))
23867 register int lim = XINT (car);
23868 elt = XCDR (elt);
23869 if (lim < 0)
23871 /* Negative int means reduce maximum width. */
23872 if (precision <= 0)
23873 precision = -lim;
23874 else
23875 precision = min (precision, -lim);
23877 else if (lim > 0)
23879 /* Padding specified. Don't let it be more than
23880 current maximum. */
23881 if (precision > 0)
23882 lim = min (precision, lim);
23884 /* If that's more padding than already wanted, queue it.
23885 But don't reduce padding already specified even if
23886 that is beyond the current truncation point. */
23887 field_width = max (lim, field_width);
23889 goto tail_recurse;
23891 else if (STRINGP (car) || CONSP (car))
23892 FOR_EACH_TAIL_SAFE (elt)
23894 if (0 < precision && precision <= n)
23895 break;
23896 n += display_mode_element (it, depth,
23897 /* Pad after only the last
23898 list element. */
23899 (! CONSP (XCDR (elt))
23900 ? field_width - n
23901 : 0),
23902 precision - n, XCAR (elt),
23903 props, risky);
23906 break;
23908 default:
23909 invalid:
23910 elt = build_string ("*invalid*");
23911 goto tail_recurse;
23914 /* Pad to FIELD_WIDTH. */
23915 if (field_width > 0 && n < field_width)
23917 switch (mode_line_target)
23919 case MODE_LINE_NOPROP:
23920 case MODE_LINE_TITLE:
23921 n += store_mode_line_noprop ("", field_width - n, 0);
23922 break;
23923 case MODE_LINE_STRING:
23924 n += store_mode_line_string ("", Qnil, false, field_width - n, 0,
23925 Qnil);
23926 break;
23927 case MODE_LINE_DISPLAY:
23928 n += display_string ("", Qnil, Qnil, 0, 0, it, field_width - n,
23929 0, 0, 0);
23930 break;
23934 return n;
23937 /* Store a mode-line string element in mode_line_string_list.
23939 If STRING is non-null, display that C string. Otherwise, the Lisp
23940 string LISP_STRING is displayed.
23942 FIELD_WIDTH is the minimum number of output glyphs to produce.
23943 If STRING has fewer characters than FIELD_WIDTH, pad to the right
23944 with spaces. FIELD_WIDTH <= 0 means don't pad.
23946 PRECISION is the maximum number of characters to output from
23947 STRING. PRECISION <= 0 means don't truncate the string.
23949 If COPY_STRING, make a copy of LISP_STRING before adding
23950 properties to the string.
23952 PROPS are the properties to add to the string.
23953 The mode_line_string_face face property is always added to the string.
23956 static int
23957 store_mode_line_string (const char *string, Lisp_Object lisp_string,
23958 bool copy_string,
23959 int field_width, int precision, Lisp_Object props)
23961 ptrdiff_t len;
23962 int n = 0;
23964 if (string != NULL)
23966 len = strlen (string);
23967 if (precision > 0 && len > precision)
23968 len = precision;
23969 lisp_string = make_string (string, len);
23970 if (NILP (props))
23971 props = mode_line_string_face_prop;
23972 else if (!NILP (mode_line_string_face))
23974 Lisp_Object face = Fplist_get (props, Qface);
23975 props = Fcopy_sequence (props);
23976 if (NILP (face))
23977 face = mode_line_string_face;
23978 else
23979 face = list2 (face, mode_line_string_face);
23980 props = Fplist_put (props, Qface, face);
23982 Fadd_text_properties (make_number (0), make_number (len),
23983 props, lisp_string);
23985 else
23987 len = XFASTINT (Flength (lisp_string));
23988 if (precision > 0 && len > precision)
23990 len = precision;
23991 lisp_string = Fsubstring (lisp_string, make_number (0), make_number (len));
23992 precision = -1;
23994 if (!NILP (mode_line_string_face))
23996 Lisp_Object face;
23997 if (NILP (props))
23998 props = Ftext_properties_at (make_number (0), lisp_string);
23999 face = Fplist_get (props, Qface);
24000 if (NILP (face))
24001 face = mode_line_string_face;
24002 else
24003 face = list2 (face, mode_line_string_face);
24004 props = list2 (Qface, face);
24005 if (copy_string)
24006 lisp_string = Fcopy_sequence (lisp_string);
24008 if (!NILP (props))
24009 Fadd_text_properties (make_number (0), make_number (len),
24010 props, lisp_string);
24013 if (len > 0)
24015 mode_line_string_list = Fcons (lisp_string, mode_line_string_list);
24016 n += len;
24019 if (field_width > len)
24021 field_width -= len;
24022 lisp_string = Fmake_string (make_number (field_width), make_number (' '),
24023 Qnil);
24024 if (!NILP (props))
24025 Fadd_text_properties (make_number (0), make_number (field_width),
24026 props, lisp_string);
24027 mode_line_string_list = Fcons (lisp_string, mode_line_string_list);
24028 n += field_width;
24031 return n;
24035 DEFUN ("format-mode-line", Fformat_mode_line, Sformat_mode_line,
24036 1, 4, 0,
24037 doc: /* Format a string out of a mode line format specification.
24038 First arg FORMAT specifies the mode line format (see `mode-line-format'
24039 for details) to use.
24041 By default, the format is evaluated for the currently selected window.
24043 Optional second arg FACE specifies the face property to put on all
24044 characters for which no face is specified. The value nil means the
24045 default face. The value t means whatever face the window's mode line
24046 currently uses (either `mode-line' or `mode-line-inactive',
24047 depending on whether the window is the selected window or not).
24048 An integer value means the value string has no text
24049 properties.
24051 Optional third and fourth args WINDOW and BUFFER specify the window
24052 and buffer to use as the context for the formatting (defaults
24053 are the selected window and the WINDOW's buffer). */)
24054 (Lisp_Object format, Lisp_Object face,
24055 Lisp_Object window, Lisp_Object buffer)
24057 struct it it;
24058 int len;
24059 struct window *w;
24060 struct buffer *old_buffer = NULL;
24061 int face_id;
24062 bool no_props = INTEGERP (face);
24063 ptrdiff_t count = SPECPDL_INDEX ();
24064 Lisp_Object str;
24065 int string_start = 0;
24067 w = decode_any_window (window);
24068 XSETWINDOW (window, w);
24070 if (NILP (buffer))
24071 buffer = w->contents;
24072 CHECK_BUFFER (buffer);
24074 /* Make formatting the modeline a non-op when noninteractive, otherwise
24075 there will be problems later caused by a partially initialized frame. */
24076 if (NILP (format) || noninteractive)
24077 return empty_unibyte_string;
24079 if (no_props)
24080 face = Qnil;
24082 face_id = (NILP (face) || EQ (face, Qdefault)) ? DEFAULT_FACE_ID
24083 : EQ (face, Qt) ? (EQ (window, selected_window)
24084 ? MODE_LINE_FACE_ID : MODE_LINE_INACTIVE_FACE_ID)
24085 : EQ (face, Qmode_line) ? MODE_LINE_FACE_ID
24086 : EQ (face, Qmode_line_inactive) ? MODE_LINE_INACTIVE_FACE_ID
24087 : EQ (face, Qheader_line) ? HEADER_LINE_FACE_ID
24088 : EQ (face, Qtool_bar) ? TOOL_BAR_FACE_ID
24089 : DEFAULT_FACE_ID;
24091 old_buffer = current_buffer;
24093 /* Save things including mode_line_proptrans_alist,
24094 and set that to nil so that we don't alter the outer value. */
24095 record_unwind_protect (unwind_format_mode_line,
24096 format_mode_line_unwind_data
24097 (XFRAME (WINDOW_FRAME (w)),
24098 old_buffer, selected_window, true));
24099 mode_line_proptrans_alist = Qnil;
24101 Fselect_window (window, Qt);
24102 set_buffer_internal_1 (XBUFFER (buffer));
24104 init_iterator (&it, w, -1, -1, NULL, face_id);
24106 if (no_props)
24108 mode_line_target = MODE_LINE_NOPROP;
24109 mode_line_string_face_prop = Qnil;
24110 mode_line_string_list = Qnil;
24111 string_start = MODE_LINE_NOPROP_LEN (0);
24113 else
24115 mode_line_target = MODE_LINE_STRING;
24116 mode_line_string_list = Qnil;
24117 mode_line_string_face = face;
24118 mode_line_string_face_prop
24119 = NILP (face) ? Qnil : list2 (Qface, face);
24122 push_kboard (FRAME_KBOARD (it.f));
24123 display_mode_element (&it, 0, 0, 0, format, Qnil, false);
24124 pop_kboard ();
24126 if (no_props)
24128 len = MODE_LINE_NOPROP_LEN (string_start);
24129 str = make_string (mode_line_noprop_buf + string_start, len);
24131 else
24133 mode_line_string_list = Fnreverse (mode_line_string_list);
24134 str = Fmapconcat (Qidentity, mode_line_string_list,
24135 empty_unibyte_string);
24138 unbind_to (count, Qnil);
24139 return str;
24142 /* Write a null-terminated, right justified decimal representation of
24143 the positive integer D to BUF using a minimal field width WIDTH. */
24145 static void
24146 pint2str (register char *buf, register int width, register ptrdiff_t d)
24148 register char *p = buf;
24150 if (d <= 0)
24151 *p++ = '0';
24152 else
24154 while (d > 0)
24156 *p++ = d % 10 + '0';
24157 d /= 10;
24161 for (width -= (int) (p - buf); width > 0; --width)
24162 *p++ = ' ';
24163 *p-- = '\0';
24164 while (p > buf)
24166 d = *buf;
24167 *buf++ = *p;
24168 *p-- = d;
24172 /* Write a null-terminated, right justified decimal and "human
24173 readable" representation of the nonnegative integer D to BUF using
24174 a minimal field width WIDTH. D should be smaller than 999.5e24. */
24176 static const char power_letter[] =
24178 0, /* no letter */
24179 'k', /* kilo */
24180 'M', /* mega */
24181 'G', /* giga */
24182 'T', /* tera */
24183 'P', /* peta */
24184 'E', /* exa */
24185 'Z', /* zetta */
24186 'Y' /* yotta */
24189 static void
24190 pint2hrstr (char *buf, int width, ptrdiff_t d)
24192 /* We aim to represent the nonnegative integer D as
24193 QUOTIENT.TENTHS * 10 ^ (3 * EXPONENT). */
24194 ptrdiff_t quotient = d;
24195 int remainder = 0;
24196 /* -1 means: do not use TENTHS. */
24197 int tenths = -1;
24198 int exponent = 0;
24200 /* Length of QUOTIENT.TENTHS as a string. */
24201 int length;
24203 char * psuffix;
24204 char * p;
24206 if (quotient >= 1000)
24208 /* Scale to the appropriate EXPONENT. */
24211 remainder = quotient % 1000;
24212 quotient /= 1000;
24213 exponent++;
24215 while (quotient >= 1000);
24217 /* Round to nearest and decide whether to use TENTHS or not. */
24218 if (quotient <= 9)
24220 tenths = remainder / 100;
24221 if (remainder % 100 >= 50)
24223 if (tenths < 9)
24224 tenths++;
24225 else
24227 quotient++;
24228 if (quotient == 10)
24229 tenths = -1;
24230 else
24231 tenths = 0;
24235 else
24236 if (remainder >= 500)
24238 if (quotient < 999)
24239 quotient++;
24240 else
24242 quotient = 1;
24243 exponent++;
24244 tenths = 0;
24249 /* Calculate the LENGTH of QUOTIENT.TENTHS as a string. */
24250 if (tenths == -1 && quotient <= 99)
24251 if (quotient <= 9)
24252 length = 1;
24253 else
24254 length = 2;
24255 else
24256 length = 3;
24257 p = psuffix = buf + max (width, length);
24259 /* Print EXPONENT. */
24260 *psuffix++ = power_letter[exponent];
24261 *psuffix = '\0';
24263 /* Print TENTHS. */
24264 if (tenths >= 0)
24266 *--p = '0' + tenths;
24267 *--p = '.';
24270 /* Print QUOTIENT. */
24273 int digit = quotient % 10;
24274 *--p = '0' + digit;
24276 while ((quotient /= 10) != 0);
24278 /* Print leading spaces. */
24279 while (buf < p)
24280 *--p = ' ';
24283 /* Set a mnemonic character for coding_system (Lisp symbol) in BUF.
24284 If EOL_FLAG, set also a mnemonic character for end-of-line
24285 type of CODING_SYSTEM. Return updated pointer into BUF. */
24287 static unsigned char invalid_eol_type[] = "(*invalid*)";
24289 static char *
24290 decode_mode_spec_coding (Lisp_Object coding_system, char *buf, bool eol_flag)
24292 Lisp_Object val;
24293 bool multibyte = !NILP (BVAR (current_buffer, enable_multibyte_characters));
24294 const unsigned char *eol_str;
24295 int eol_str_len;
24296 /* The EOL conversion we are using. */
24297 Lisp_Object eoltype;
24299 val = CODING_SYSTEM_SPEC (coding_system);
24300 eoltype = Qnil;
24302 if (!VECTORP (val)) /* Not yet decided. */
24304 *buf++ = multibyte ? '-' : ' ';
24305 if (eol_flag)
24306 eoltype = eol_mnemonic_undecided;
24307 /* Don't mention EOL conversion if it isn't decided. */
24309 else
24311 Lisp_Object attrs;
24312 Lisp_Object eolvalue;
24314 attrs = AREF (val, 0);
24315 eolvalue = AREF (val, 2);
24317 *buf++ = multibyte
24318 ? XFASTINT (CODING_ATTR_MNEMONIC (attrs))
24319 : ' ';
24321 if (eol_flag)
24323 /* The EOL conversion that is normal on this system. */
24325 if (NILP (eolvalue)) /* Not yet decided. */
24326 eoltype = eol_mnemonic_undecided;
24327 else if (VECTORP (eolvalue)) /* Not yet decided. */
24328 eoltype = eol_mnemonic_undecided;
24329 else /* eolvalue is Qunix, Qdos, or Qmac. */
24330 eoltype = (EQ (eolvalue, Qunix)
24331 ? eol_mnemonic_unix
24332 : EQ (eolvalue, Qdos)
24333 ? eol_mnemonic_dos : eol_mnemonic_mac);
24337 if (eol_flag)
24339 /* Mention the EOL conversion if it is not the usual one. */
24340 if (STRINGP (eoltype))
24342 eol_str = SDATA (eoltype);
24343 eol_str_len = SBYTES (eoltype);
24345 else if (CHARACTERP (eoltype))
24347 int c = XFASTINT (eoltype);
24348 return buf + CHAR_STRING (c, (unsigned char *) buf);
24350 else
24352 eol_str = invalid_eol_type;
24353 eol_str_len = sizeof (invalid_eol_type) - 1;
24355 memcpy (buf, eol_str, eol_str_len);
24356 buf += eol_str_len;
24359 return buf;
24362 /* Return the approximate percentage N is of D (rounding upward), or 99,
24363 whichever is less. Assume 0 < D and 0 <= N <= D * INT_MAX / 100. */
24365 static int
24366 percent99 (ptrdiff_t n, ptrdiff_t d)
24368 int percent = (d - 1 + 100.0 * n) / d;
24369 return min (percent, 99);
24372 /* Return a string for the output of a mode line %-spec for window W,
24373 generated by character C. FIELD_WIDTH > 0 means pad the string
24374 returned with spaces to that value. Return a Lisp string in
24375 *STRING if the resulting string is taken from that Lisp string.
24377 Note we operate on the current buffer for most purposes. */
24379 static char lots_of_dashes[] = "--------------------------------------------------------------------------------------------------------------------------------------------";
24381 static const char *
24382 decode_mode_spec (struct window *w, register int c, int field_width,
24383 Lisp_Object *string)
24385 Lisp_Object obj;
24386 struct frame *f = XFRAME (WINDOW_FRAME (w));
24387 char *decode_mode_spec_buf = f->decode_mode_spec_buffer;
24388 /* We are going to use f->decode_mode_spec_buffer as the buffer to
24389 produce strings from numerical values, so limit preposterously
24390 large values of FIELD_WIDTH to avoid overrunning the buffer's
24391 end. The size of the buffer is enough for FRAME_MESSAGE_BUF_SIZE
24392 bytes plus the terminating null. */
24393 int width = min (field_width, FRAME_MESSAGE_BUF_SIZE (f));
24394 struct buffer *b = current_buffer;
24396 obj = Qnil;
24397 *string = Qnil;
24399 switch (c)
24401 case '*':
24402 if (!NILP (BVAR (b, read_only)))
24403 return "%";
24404 if (BUF_MODIFF (b) > BUF_SAVE_MODIFF (b))
24405 return "*";
24406 return "-";
24408 case '+':
24409 /* This differs from %* only for a modified read-only buffer. */
24410 if (BUF_MODIFF (b) > BUF_SAVE_MODIFF (b))
24411 return "*";
24412 if (!NILP (BVAR (b, read_only)))
24413 return "%";
24414 return "-";
24416 case '&':
24417 /* This differs from %* in ignoring read-only-ness. */
24418 if (BUF_MODIFF (b) > BUF_SAVE_MODIFF (b))
24419 return "*";
24420 return "-";
24422 case '%':
24423 return "%";
24425 case '[':
24427 int i;
24428 char *p;
24430 if (command_loop_level > 5)
24431 return "[[[... ";
24432 p = decode_mode_spec_buf;
24433 for (i = 0; i < command_loop_level; i++)
24434 *p++ = '[';
24435 *p = 0;
24436 return decode_mode_spec_buf;
24439 case ']':
24441 int i;
24442 char *p;
24444 if (command_loop_level > 5)
24445 return " ...]]]";
24446 p = decode_mode_spec_buf;
24447 for (i = 0; i < command_loop_level; i++)
24448 *p++ = ']';
24449 *p = 0;
24450 return decode_mode_spec_buf;
24453 case '-':
24455 register int i;
24457 /* Let lots_of_dashes be a string of infinite length. */
24458 if (mode_line_target == MODE_LINE_NOPROP
24459 || mode_line_target == MODE_LINE_STRING)
24460 return "--";
24461 if (field_width <= 0
24462 || field_width > sizeof (lots_of_dashes))
24464 for (i = 0; i < FRAME_MESSAGE_BUF_SIZE (f) - 1; ++i)
24465 decode_mode_spec_buf[i] = '-';
24466 decode_mode_spec_buf[i] = '\0';
24467 return decode_mode_spec_buf;
24469 else
24470 return lots_of_dashes;
24473 case 'b':
24474 obj = BVAR (b, name);
24475 break;
24477 case 'c':
24478 case 'C':
24479 /* %c, %C, and %l are ignored in `frame-title-format'.
24480 (In redisplay_internal, the frame title is drawn _before_ the
24481 windows are updated, so the stuff which depends on actual
24482 window contents (such as %l) may fail to render properly, or
24483 even crash emacs.) */
24484 if (mode_line_target == MODE_LINE_TITLE)
24485 return "";
24486 else
24488 ptrdiff_t col = current_column ();
24489 int disp_col = (c == 'C') ? col + 1 : col;
24490 w->column_number_displayed = col;
24491 pint2str (decode_mode_spec_buf, width, disp_col);
24492 return decode_mode_spec_buf;
24495 case 'e':
24496 #if !defined SYSTEM_MALLOC && !defined HYBRID_MALLOC
24498 if (NILP (Vmemory_full))
24499 return "";
24500 else
24501 return "!MEM FULL! ";
24503 #else
24504 return "";
24505 #endif
24507 case 'F':
24508 /* %F displays the frame name. */
24509 if (!NILP (f->title))
24510 return SSDATA (f->title);
24511 if (f->explicit_name || ! FRAME_WINDOW_P (f))
24512 return SSDATA (f->name);
24513 return "Emacs";
24515 case 'f':
24516 obj = BVAR (b, filename);
24517 break;
24519 case 'i':
24521 ptrdiff_t size = ZV - BEGV;
24522 pint2str (decode_mode_spec_buf, width, size);
24523 return decode_mode_spec_buf;
24526 case 'I':
24528 ptrdiff_t size = ZV - BEGV;
24529 pint2hrstr (decode_mode_spec_buf, width, size);
24530 return decode_mode_spec_buf;
24533 case 'l':
24535 ptrdiff_t startpos, startpos_byte, line, linepos, linepos_byte;
24536 ptrdiff_t topline, nlines, height;
24537 ptrdiff_t junk;
24539 /* %c, %C, and %l are ignored in `frame-title-format'. */
24540 if (mode_line_target == MODE_LINE_TITLE)
24541 return "";
24543 startpos = marker_position (w->start);
24544 startpos_byte = marker_byte_position (w->start);
24545 height = WINDOW_TOTAL_LINES (w);
24547 /* If we decided that this buffer isn't suitable for line numbers,
24548 don't forget that too fast. */
24549 if (w->base_line_pos == -1)
24550 goto no_value;
24552 /* If the buffer is very big, don't waste time. */
24553 if (INTEGERP (Vline_number_display_limit)
24554 && BUF_ZV (b) - BUF_BEGV (b) > XINT (Vline_number_display_limit))
24556 w->base_line_pos = 0;
24557 w->base_line_number = 0;
24558 goto no_value;
24561 if (w->base_line_number > 0
24562 && w->base_line_pos > 0
24563 && w->base_line_pos <= startpos)
24565 line = w->base_line_number;
24566 linepos = w->base_line_pos;
24567 linepos_byte = buf_charpos_to_bytepos (b, linepos);
24569 else
24571 line = 1;
24572 linepos = BUF_BEGV (b);
24573 linepos_byte = BUF_BEGV_BYTE (b);
24576 /* Count lines from base line to window start position. */
24577 nlines = display_count_lines (linepos_byte,
24578 startpos_byte,
24579 startpos, &junk);
24581 topline = nlines + line;
24583 /* Determine a new base line, if the old one is too close
24584 or too far away, or if we did not have one.
24585 "Too close" means it's plausible a scroll-down would
24586 go back past it. */
24587 if (startpos == BUF_BEGV (b))
24589 w->base_line_number = topline;
24590 w->base_line_pos = BUF_BEGV (b);
24592 else if (nlines < height + 25 || nlines > height * 3 + 50
24593 || linepos == BUF_BEGV (b))
24595 ptrdiff_t limit = BUF_BEGV (b);
24596 ptrdiff_t limit_byte = BUF_BEGV_BYTE (b);
24597 ptrdiff_t position;
24598 ptrdiff_t distance =
24599 (height * 2 + 30) * line_number_display_limit_width;
24601 if (startpos - distance > limit)
24603 limit = startpos - distance;
24604 limit_byte = CHAR_TO_BYTE (limit);
24607 nlines = display_count_lines (startpos_byte,
24608 limit_byte,
24609 - (height * 2 + 30),
24610 &position);
24611 /* If we couldn't find the lines we wanted within
24612 line_number_display_limit_width chars per line,
24613 give up on line numbers for this window. */
24614 if (position == limit_byte && limit == startpos - distance)
24616 w->base_line_pos = -1;
24617 w->base_line_number = 0;
24618 goto no_value;
24621 w->base_line_number = topline - nlines;
24622 w->base_line_pos = BYTE_TO_CHAR (position);
24625 /* Now count lines from the start pos to point. */
24626 nlines = display_count_lines (startpos_byte,
24627 PT_BYTE, PT, &junk);
24629 /* Record that we did display the line number. */
24630 line_number_displayed = true;
24632 /* Make the string to show. */
24633 pint2str (decode_mode_spec_buf, width, topline + nlines);
24634 return decode_mode_spec_buf;
24635 no_value:
24637 char *p = decode_mode_spec_buf;
24638 int pad = width - 2;
24639 while (pad-- > 0)
24640 *p++ = ' ';
24641 *p++ = '?';
24642 *p++ = '?';
24643 *p = '\0';
24644 return decode_mode_spec_buf;
24647 break;
24649 case 'm':
24650 obj = BVAR (b, mode_name);
24651 break;
24653 case 'n':
24654 if (BUF_BEGV (b) > BUF_BEG (b) || BUF_ZV (b) < BUF_Z (b))
24655 return " Narrow";
24656 break;
24658 /* Display the "degree of travel" of the window through the buffer. */
24659 case 'o':
24661 ptrdiff_t toppos = marker_position (w->start);
24662 ptrdiff_t botpos = BUF_Z (b) - w->window_end_pos;
24663 ptrdiff_t begv = BUF_BEGV (b);
24664 ptrdiff_t zv = BUF_ZV (b);
24666 if (zv <= botpos)
24667 return toppos <= begv ? "All" : "Bottom";
24668 else if (toppos <= begv)
24669 return "Top";
24670 else
24672 sprintf (decode_mode_spec_buf, "%2d%%",
24673 percent99 (toppos - begv, (toppos - begv) + (zv - botpos)));
24674 return decode_mode_spec_buf;
24678 /* Display percentage of buffer above the top of the screen. */
24679 case 'p':
24681 ptrdiff_t pos = marker_position (w->start);
24682 ptrdiff_t begv = BUF_BEGV (b);
24683 ptrdiff_t zv = BUF_ZV (b);
24685 if (w->window_end_pos <= BUF_Z (b) - zv)
24686 return pos <= begv ? "All" : "Bottom";
24687 else if (pos <= begv)
24688 return "Top";
24689 else
24691 sprintf (decode_mode_spec_buf, "%2d%%",
24692 percent99 (pos - begv, zv - begv));
24693 return decode_mode_spec_buf;
24697 /* Display percentage of size above the bottom of the screen. */
24698 case 'P':
24700 ptrdiff_t toppos = marker_position (w->start);
24701 ptrdiff_t botpos = BUF_Z (b) - w->window_end_pos;
24702 ptrdiff_t begv = BUF_BEGV (b);
24703 ptrdiff_t zv = BUF_ZV (b);
24705 if (zv <= botpos)
24706 return toppos <= begv ? "All" : "Bottom";
24707 else
24709 sprintf (decode_mode_spec_buf,
24710 &"Top%2d%%"[begv < toppos ? sizeof "Top" - 1 : 0],
24711 percent99 (botpos - begv, zv - begv));
24712 return decode_mode_spec_buf;
24716 /* Display percentage offsets of top and bottom of the window,
24717 using "All" (but not "Top" or "Bottom") where appropriate. */
24718 case 'q':
24720 ptrdiff_t toppos = marker_position (w->start);
24721 ptrdiff_t botpos = BUF_Z (b) - w->window_end_pos;
24722 ptrdiff_t begv = BUF_BEGV (b);
24723 ptrdiff_t zv = BUF_ZV (b);
24724 int top_perc, bot_perc;
24726 if ((toppos <= begv) && (zv <= botpos))
24727 return "All ";
24729 top_perc = toppos <= begv ? 0 : percent99 (toppos - begv, zv - begv);
24730 bot_perc = zv <= botpos ? 100 : percent99 (botpos - begv, zv - begv);
24732 if (top_perc == bot_perc)
24733 sprintf (decode_mode_spec_buf, "%d%%", top_perc);
24734 else
24735 sprintf (decode_mode_spec_buf, "%d-%d%%", top_perc, bot_perc);
24737 return decode_mode_spec_buf;
24740 case 's':
24741 /* status of process */
24742 obj = Fget_buffer_process (Fcurrent_buffer ());
24743 if (NILP (obj))
24744 return "no process";
24745 #ifndef MSDOS
24746 obj = Fsymbol_name (Fprocess_status (obj));
24747 #endif
24748 break;
24750 case '@':
24752 ptrdiff_t count = inhibit_garbage_collection ();
24753 Lisp_Object curdir = BVAR (current_buffer, directory);
24754 Lisp_Object val = Qnil;
24756 if (STRINGP (curdir))
24757 val = call1 (intern ("file-remote-p"), curdir);
24759 unbind_to (count, Qnil);
24761 if (NILP (val))
24762 return "-";
24763 else
24764 return "@";
24767 case 'z':
24768 /* coding-system (not including end-of-line format) */
24769 case 'Z':
24770 /* coding-system (including end-of-line type) */
24772 bool eol_flag = (c == 'Z');
24773 char *p = decode_mode_spec_buf;
24775 if (! FRAME_WINDOW_P (f))
24777 /* No need to mention EOL here--the terminal never needs
24778 to do EOL conversion. */
24779 p = decode_mode_spec_coding (CODING_ID_NAME
24780 (FRAME_KEYBOARD_CODING (f)->id),
24781 p, false);
24782 p = decode_mode_spec_coding (CODING_ID_NAME
24783 (FRAME_TERMINAL_CODING (f)->id),
24784 p, false);
24786 p = decode_mode_spec_coding (BVAR (b, buffer_file_coding_system),
24787 p, eol_flag);
24789 #if false /* This proves to be annoying; I think we can do without. -- rms. */
24790 #ifdef subprocesses
24791 obj = Fget_buffer_process (Fcurrent_buffer ());
24792 if (PROCESSP (obj))
24794 p = decode_mode_spec_coding
24795 (XPROCESS (obj)->decode_coding_system, p, eol_flag);
24796 p = decode_mode_spec_coding
24797 (XPROCESS (obj)->encode_coding_system, p, eol_flag);
24799 #endif /* subprocesses */
24800 #endif /* false */
24801 *p = 0;
24802 return decode_mode_spec_buf;
24806 if (STRINGP (obj))
24808 *string = obj;
24809 return SSDATA (obj);
24811 else
24812 return "";
24816 /* Count up to COUNT lines starting from START_BYTE. COUNT negative
24817 means count lines back from START_BYTE. But don't go beyond
24818 LIMIT_BYTE. Return the number of lines thus found (always
24819 nonnegative).
24821 Set *BYTE_POS_PTR to the byte position where we stopped. This is
24822 either the position COUNT lines after/before START_BYTE, if we
24823 found COUNT lines, or LIMIT_BYTE if we hit the limit before finding
24824 COUNT lines. */
24826 static ptrdiff_t
24827 display_count_lines (ptrdiff_t start_byte,
24828 ptrdiff_t limit_byte, ptrdiff_t count,
24829 ptrdiff_t *byte_pos_ptr)
24831 register unsigned char *cursor;
24832 unsigned char *base;
24834 register ptrdiff_t ceiling;
24835 register unsigned char *ceiling_addr;
24836 ptrdiff_t orig_count = count;
24838 /* If we are not in selective display mode,
24839 check only for newlines. */
24840 bool selective_display
24841 = (!NILP (BVAR (current_buffer, selective_display))
24842 && !INTEGERP (BVAR (current_buffer, selective_display)));
24844 if (count > 0)
24846 while (start_byte < limit_byte)
24848 ceiling = BUFFER_CEILING_OF (start_byte);
24849 ceiling = min (limit_byte - 1, ceiling);
24850 ceiling_addr = BYTE_POS_ADDR (ceiling) + 1;
24851 base = (cursor = BYTE_POS_ADDR (start_byte));
24855 if (selective_display)
24857 while (*cursor != '\n' && *cursor != 015
24858 && ++cursor != ceiling_addr)
24859 continue;
24860 if (cursor == ceiling_addr)
24861 break;
24863 else
24865 cursor = memchr (cursor, '\n', ceiling_addr - cursor);
24866 if (! cursor)
24867 break;
24870 cursor++;
24872 if (--count == 0)
24874 start_byte += cursor - base;
24875 *byte_pos_ptr = start_byte;
24876 return orig_count;
24879 while (cursor < ceiling_addr);
24881 start_byte += ceiling_addr - base;
24884 else
24886 while (start_byte > limit_byte)
24888 ceiling = BUFFER_FLOOR_OF (start_byte - 1);
24889 ceiling = max (limit_byte, ceiling);
24890 ceiling_addr = BYTE_POS_ADDR (ceiling);
24891 base = (cursor = BYTE_POS_ADDR (start_byte - 1) + 1);
24892 while (true)
24894 if (selective_display)
24896 while (--cursor >= ceiling_addr
24897 && *cursor != '\n' && *cursor != 015)
24898 continue;
24899 if (cursor < ceiling_addr)
24900 break;
24902 else
24904 cursor = memrchr (ceiling_addr, '\n', cursor - ceiling_addr);
24905 if (! cursor)
24906 break;
24909 if (++count == 0)
24911 start_byte += cursor - base + 1;
24912 *byte_pos_ptr = start_byte;
24913 /* When scanning backwards, we should
24914 not count the newline posterior to which we stop. */
24915 return - orig_count - 1;
24918 start_byte += ceiling_addr - base;
24922 *byte_pos_ptr = limit_byte;
24924 if (count < 0)
24925 return - orig_count + count;
24926 return orig_count - count;
24932 /***********************************************************************
24933 Displaying strings
24934 ***********************************************************************/
24936 /* Display a NUL-terminated string, starting with index START.
24938 If STRING is non-null, display that C string. Otherwise, the Lisp
24939 string LISP_STRING is displayed. There's a case that STRING is
24940 non-null and LISP_STRING is not nil. It means STRING is a string
24941 data of LISP_STRING. In that case, we display LISP_STRING while
24942 ignoring its text properties.
24944 If FACE_STRING is not nil, FACE_STRING_POS is a position in
24945 FACE_STRING. Display STRING or LISP_STRING with the face at
24946 FACE_STRING_POS in FACE_STRING:
24948 Display the string in the environment given by IT, but use the
24949 standard display table, temporarily.
24951 FIELD_WIDTH is the minimum number of output glyphs to produce.
24952 If STRING has fewer characters than FIELD_WIDTH, pad to the right
24953 with spaces. If STRING has more characters, more than FIELD_WIDTH
24954 glyphs will be produced. FIELD_WIDTH <= 0 means don't pad.
24956 PRECISION is the maximum number of characters to output from
24957 STRING. PRECISION < 0 means don't truncate the string.
24959 This is roughly equivalent to printf format specifiers:
24961 FIELD_WIDTH PRECISION PRINTF
24962 ----------------------------------------
24963 -1 -1 %s
24964 -1 10 %.10s
24965 10 -1 %10s
24966 20 10 %20.10s
24968 MULTIBYTE zero means do not display multibyte chars, > 0 means do
24969 display them, and < 0 means obey the current buffer's value of
24970 enable_multibyte_characters.
24972 Value is the number of columns displayed. */
24974 static int
24975 display_string (const char *string, Lisp_Object lisp_string, Lisp_Object face_string,
24976 ptrdiff_t face_string_pos, ptrdiff_t start, struct it *it,
24977 int field_width, int precision, int max_x, int multibyte)
24979 int hpos_at_start = it->hpos;
24980 int saved_face_id = it->face_id;
24981 struct glyph_row *row = it->glyph_row;
24982 ptrdiff_t it_charpos;
24984 /* Initialize the iterator IT for iteration over STRING beginning
24985 with index START. */
24986 reseat_to_string (it, NILP (lisp_string) ? string : NULL, lisp_string, start,
24987 precision, field_width, multibyte);
24988 if (string && STRINGP (lisp_string))
24989 /* LISP_STRING is the one returned by decode_mode_spec. We should
24990 ignore its text properties. */
24991 it->stop_charpos = it->end_charpos;
24993 /* If displaying STRING, set up the face of the iterator from
24994 FACE_STRING, if that's given. */
24995 if (STRINGP (face_string))
24997 ptrdiff_t endptr;
24998 struct face *face;
25000 it->face_id
25001 = face_at_string_position (it->w, face_string, face_string_pos,
25002 0, &endptr, it->base_face_id, false);
25003 face = FACE_FROM_ID (it->f, it->face_id);
25004 it->face_box_p = face->box != FACE_NO_BOX;
25007 /* Set max_x to the maximum allowed X position. Don't let it go
25008 beyond the right edge of the window. */
25009 if (max_x <= 0)
25010 max_x = it->last_visible_x;
25011 else
25012 max_x = min (max_x, it->last_visible_x);
25014 /* Skip over display elements that are not visible. because IT->w is
25015 hscrolled. */
25016 if (it->current_x < it->first_visible_x)
25017 move_it_in_display_line_to (it, 100000, it->first_visible_x,
25018 MOVE_TO_POS | MOVE_TO_X);
25020 row->ascent = it->max_ascent;
25021 row->height = it->max_ascent + it->max_descent;
25022 row->phys_ascent = it->max_phys_ascent;
25023 row->phys_height = it->max_phys_ascent + it->max_phys_descent;
25024 row->extra_line_spacing = it->max_extra_line_spacing;
25026 if (STRINGP (it->string))
25027 it_charpos = IT_STRING_CHARPOS (*it);
25028 else
25029 it_charpos = IT_CHARPOS (*it);
25031 /* This condition is for the case that we are called with current_x
25032 past last_visible_x. */
25033 while (it->current_x < max_x)
25035 int x_before, x, n_glyphs_before, i, nglyphs;
25037 /* Get the next display element. */
25038 if (!get_next_display_element (it))
25039 break;
25041 /* Produce glyphs. */
25042 x_before = it->current_x;
25043 n_glyphs_before = row->used[TEXT_AREA];
25044 PRODUCE_GLYPHS (it);
25046 nglyphs = row->used[TEXT_AREA] - n_glyphs_before;
25047 i = 0;
25048 x = x_before;
25049 while (i < nglyphs)
25051 struct glyph *glyph = row->glyphs[TEXT_AREA] + n_glyphs_before + i;
25053 if (it->line_wrap != TRUNCATE
25054 && x + glyph->pixel_width > max_x)
25056 /* End of continued line or max_x reached. */
25057 if (CHAR_GLYPH_PADDING_P (*glyph))
25059 /* A wide character is unbreakable. */
25060 if (row->reversed_p)
25061 unproduce_glyphs (it, row->used[TEXT_AREA]
25062 - n_glyphs_before);
25063 row->used[TEXT_AREA] = n_glyphs_before;
25064 it->current_x = x_before;
25066 else
25068 if (row->reversed_p)
25069 unproduce_glyphs (it, row->used[TEXT_AREA]
25070 - (n_glyphs_before + i));
25071 row->used[TEXT_AREA] = n_glyphs_before + i;
25072 it->current_x = x;
25074 break;
25076 else if (x + glyph->pixel_width >= it->first_visible_x)
25078 /* Glyph is at least partially visible. */
25079 ++it->hpos;
25080 if (x < it->first_visible_x)
25081 row->x = x - it->first_visible_x;
25083 else
25085 /* Glyph is off the left margin of the display area.
25086 Should not happen. */
25087 emacs_abort ();
25090 row->ascent = max (row->ascent, it->max_ascent);
25091 row->height = max (row->height, it->max_ascent + it->max_descent);
25092 row->phys_ascent = max (row->phys_ascent, it->max_phys_ascent);
25093 row->phys_height = max (row->phys_height,
25094 it->max_phys_ascent + it->max_phys_descent);
25095 row->extra_line_spacing = max (row->extra_line_spacing,
25096 it->max_extra_line_spacing);
25097 x += glyph->pixel_width;
25098 ++i;
25101 /* Stop if max_x reached. */
25102 if (i < nglyphs)
25103 break;
25105 /* Stop at line ends. */
25106 if (ITERATOR_AT_END_OF_LINE_P (it))
25108 it->continuation_lines_width = 0;
25109 break;
25112 set_iterator_to_next (it, true);
25113 if (STRINGP (it->string))
25114 it_charpos = IT_STRING_CHARPOS (*it);
25115 else
25116 it_charpos = IT_CHARPOS (*it);
25118 /* Stop if truncating at the right edge. */
25119 if (it->line_wrap == TRUNCATE
25120 && it->current_x >= it->last_visible_x)
25122 /* Add truncation mark, but don't do it if the line is
25123 truncated at a padding space. */
25124 if (it_charpos < it->string_nchars)
25126 if (!FRAME_WINDOW_P (it->f))
25128 int ii, n;
25130 if (it->current_x > it->last_visible_x)
25132 if (!row->reversed_p)
25134 for (ii = row->used[TEXT_AREA] - 1; ii > 0; --ii)
25135 if (!CHAR_GLYPH_PADDING_P (row->glyphs[TEXT_AREA][ii]))
25136 break;
25138 else
25140 for (ii = 0; ii < row->used[TEXT_AREA]; ii++)
25141 if (!CHAR_GLYPH_PADDING_P (row->glyphs[TEXT_AREA][ii]))
25142 break;
25143 unproduce_glyphs (it, ii + 1);
25144 ii = row->used[TEXT_AREA] - (ii + 1);
25146 for (n = row->used[TEXT_AREA]; ii < n; ++ii)
25148 row->used[TEXT_AREA] = ii;
25149 produce_special_glyphs (it, IT_TRUNCATION);
25152 produce_special_glyphs (it, IT_TRUNCATION);
25154 row->truncated_on_right_p = true;
25156 break;
25160 /* Maybe insert a truncation at the left. */
25161 if (it->first_visible_x
25162 && it_charpos > 0)
25164 if (!FRAME_WINDOW_P (it->f)
25165 || (row->reversed_p
25166 ? WINDOW_RIGHT_FRINGE_WIDTH (it->w)
25167 : WINDOW_LEFT_FRINGE_WIDTH (it->w)) == 0)
25168 insert_left_trunc_glyphs (it);
25169 row->truncated_on_left_p = true;
25172 it->face_id = saved_face_id;
25174 /* Value is number of columns displayed. */
25175 return it->hpos - hpos_at_start;
25180 /* This is like a combination of memq and assq. Return 1/2 if PROPVAL
25181 appears as an element of LIST or as the car of an element of LIST.
25182 If PROPVAL is a list, compare each element against LIST in that
25183 way, and return 1/2 if any element of PROPVAL is found in LIST.
25184 Otherwise return 0. This function cannot quit.
25185 The return value is 2 if the text is invisible but with an ellipsis
25186 and 1 if it's invisible and without an ellipsis. */
25189 invisible_prop (Lisp_Object propval, Lisp_Object list)
25191 Lisp_Object tail, proptail;
25193 for (tail = list; CONSP (tail); tail = XCDR (tail))
25195 register Lisp_Object tem;
25196 tem = XCAR (tail);
25197 if (EQ (propval, tem))
25198 return 1;
25199 if (CONSP (tem) && EQ (propval, XCAR (tem)))
25200 return NILP (XCDR (tem)) ? 1 : 2;
25203 if (CONSP (propval))
25205 for (proptail = propval; CONSP (proptail); proptail = XCDR (proptail))
25207 Lisp_Object propelt;
25208 propelt = XCAR (proptail);
25209 for (tail = list; CONSP (tail); tail = XCDR (tail))
25211 register Lisp_Object tem;
25212 tem = XCAR (tail);
25213 if (EQ (propelt, tem))
25214 return 1;
25215 if (CONSP (tem) && EQ (propelt, XCAR (tem)))
25216 return NILP (XCDR (tem)) ? 1 : 2;
25221 return 0;
25224 DEFUN ("invisible-p", Finvisible_p, Sinvisible_p, 1, 1, 0,
25225 doc: /* Non-nil if text properties at POS cause text there to be currently invisible.
25226 POS should be a marker or a buffer position; the value of the `invisible'
25227 property at that position in the current buffer is examined.
25228 POS can also be the actual value of the `invisible' text or overlay
25229 property of the text of interest, in which case the value itself is
25230 examined.
25232 The non-nil value returned can be t for currently invisible text that is
25233 entirely hidden on display, or some other non-nil, non-t value if the
25234 text is replaced by an ellipsis.
25236 Note that whether text with `invisible' property is actually hidden on
25237 display may depend on `buffer-invisibility-spec', which see. */)
25238 (Lisp_Object pos)
25240 Lisp_Object prop
25241 = (NATNUMP (pos) || MARKERP (pos)
25242 ? Fget_char_property (pos, Qinvisible, Qnil)
25243 : pos);
25244 int invis = TEXT_PROP_MEANS_INVISIBLE (prop);
25245 return (invis == 0 ? Qnil
25246 : invis == 1 ? Qt
25247 : make_number (invis));
25250 /* Calculate a width or height in pixels from a specification using
25251 the following elements:
25253 SPEC ::=
25254 NUM - a (fractional) multiple of the default font width/height
25255 (NUM) - specifies exactly NUM pixels
25256 UNIT - a fixed number of pixels, see below.
25257 ELEMENT - size of a display element in pixels, see below.
25258 (NUM . SPEC) - equals NUM * SPEC
25259 (+ SPEC SPEC ...) - add pixel values
25260 (- SPEC SPEC ...) - subtract pixel values
25261 (- SPEC) - negate pixel value
25263 NUM ::=
25264 INT or FLOAT - a number constant
25265 SYMBOL - use symbol's (buffer local) variable binding.
25267 UNIT ::=
25268 in - pixels per inch *)
25269 mm - pixels per 1/1000 meter *)
25270 cm - pixels per 1/100 meter *)
25271 width - width of current font in pixels.
25272 height - height of current font in pixels.
25274 *) using the ratio(s) defined in display-pixels-per-inch.
25276 ELEMENT ::=
25278 left-fringe - left fringe width in pixels
25279 right-fringe - right fringe width in pixels
25281 left-margin - left margin width in pixels
25282 right-margin - right margin width in pixels
25284 scroll-bar - scroll-bar area width in pixels
25286 Examples:
25288 Pixels corresponding to 5 inches:
25289 (5 . in)
25291 Total width of non-text areas on left side of window (if scroll-bar is on left):
25292 '(space :width (+ left-fringe left-margin scroll-bar))
25294 Align to first text column (in header line):
25295 '(space :align-to 0)
25297 Align to middle of text area minus half the width of variable `my-image'
25298 containing a loaded image:
25299 '(space :align-to (0.5 . (- text my-image)))
25301 Width of left margin minus width of 1 character in the default font:
25302 '(space :width (- left-margin 1))
25304 Width of left margin minus width of 2 characters in the current font:
25305 '(space :width (- left-margin (2 . width)))
25307 Center 1 character over left-margin (in header line):
25308 '(space :align-to (+ left-margin (0.5 . left-margin) -0.5))
25310 Different ways to express width of left fringe plus left margin minus one pixel:
25311 '(space :width (- (+ left-fringe left-margin) (1)))
25312 '(space :width (+ left-fringe left-margin (- (1))))
25313 '(space :width (+ left-fringe left-margin (-1)))
25315 If ALIGN_TO is NULL, returns the result in *RES. If ALIGN_TO is
25316 non-NULL, the value of *ALIGN_TO is a window-relative pixel
25317 coordinate, and *RES is the additional pixel width from that point
25318 till the end of the stretch glyph.
25320 WIDTH_P non-zero means take the width dimension or X coordinate of
25321 the object specified by PROP, WIDTH_P zero means take the height
25322 dimension or the Y coordinate. (Therefore, if ALIGN_TO is
25323 non-NULL, WIDTH_P should be non-zero.)
25325 FONT is the font of the face of the surrounding text.
25327 The return value is non-zero if width or height were successfully
25328 calculated, i.e. if PROP is a valid spec. */
25330 static bool
25331 calc_pixel_width_or_height (double *res, struct it *it, Lisp_Object prop,
25332 struct font *font, bool width_p, int *align_to)
25334 double pixels;
25336 # define OK_PIXELS(val) (*res = (val), true)
25337 # define OK_ALIGN_TO(val) (*align_to = (val), true)
25339 if (NILP (prop))
25340 return OK_PIXELS (0);
25342 eassert (FRAME_LIVE_P (it->f));
25344 if (SYMBOLP (prop))
25346 if (SCHARS (SYMBOL_NAME (prop)) == 2)
25348 char *unit = SSDATA (SYMBOL_NAME (prop));
25350 /* The UNIT expression, e.g. as part of (NUM . UNIT). */
25351 if (unit[0] == 'i' && unit[1] == 'n')
25352 pixels = 1.0;
25353 else if (unit[0] == 'm' && unit[1] == 'm')
25354 pixels = 25.4;
25355 else if (unit[0] == 'c' && unit[1] == 'm')
25356 pixels = 2.54;
25357 else
25358 pixels = 0;
25359 if (pixels > 0)
25361 double ppi = (width_p ? FRAME_RES_X (it->f)
25362 : FRAME_RES_Y (it->f));
25364 if (ppi > 0)
25365 return OK_PIXELS (ppi / pixels);
25366 return false;
25370 #ifdef HAVE_WINDOW_SYSTEM
25371 /* 'height': the height of FONT. */
25372 if (EQ (prop, Qheight))
25373 return OK_PIXELS (font
25374 ? normal_char_height (font, -1)
25375 : FRAME_LINE_HEIGHT (it->f));
25376 /* 'width': the width of FONT. */
25377 if (EQ (prop, Qwidth))
25378 return OK_PIXELS (font
25379 ? FONT_WIDTH (font)
25380 : FRAME_COLUMN_WIDTH (it->f));
25381 #else
25382 if (EQ (prop, Qheight) || EQ (prop, Qwidth))
25383 return OK_PIXELS (1);
25384 #endif
25386 /* 'text': the width or height of the text area. */
25387 if (EQ (prop, Qtext))
25388 return OK_PIXELS (width_p
25389 ? (window_box_width (it->w, TEXT_AREA)
25390 - it->lnum_pixel_width)
25391 : WINDOW_BOX_HEIGHT_NO_MODE_LINE (it->w));
25393 /* ':align_to'. First time we compute the value, window
25394 elements are interpreted as the position of the element's
25395 left edge. */
25396 if (align_to && *align_to < 0)
25398 *res = 0;
25399 /* 'left': left edge of the text area. */
25400 if (EQ (prop, Qleft))
25401 return OK_ALIGN_TO (window_box_left_offset (it->w, TEXT_AREA)
25402 + it->lnum_pixel_width);
25403 /* 'right': right edge of the text area. */
25404 if (EQ (prop, Qright))
25405 return OK_ALIGN_TO (window_box_right_offset (it->w, TEXT_AREA));
25406 /* 'center': the center of the text area. */
25407 if (EQ (prop, Qcenter))
25408 return OK_ALIGN_TO (window_box_left_offset (it->w, TEXT_AREA)
25409 + it->lnum_pixel_width
25410 + window_box_width (it->w, TEXT_AREA) / 2);
25411 /* 'left-fringe': left edge of the left fringe. */
25412 if (EQ (prop, Qleft_fringe))
25413 return OK_ALIGN_TO (WINDOW_HAS_FRINGES_OUTSIDE_MARGINS (it->w)
25414 ? WINDOW_LEFT_SCROLL_BAR_AREA_WIDTH (it->w)
25415 : window_box_right_offset (it->w, LEFT_MARGIN_AREA));
25416 /* 'right-fringe': left edge of the right fringe. */
25417 if (EQ (prop, Qright_fringe))
25418 return OK_ALIGN_TO (WINDOW_HAS_FRINGES_OUTSIDE_MARGINS (it->w)
25419 ? window_box_right_offset (it->w, RIGHT_MARGIN_AREA)
25420 : window_box_right_offset (it->w, TEXT_AREA));
25421 /* 'left-margin': left edge of the left display margin. */
25422 if (EQ (prop, Qleft_margin))
25423 return OK_ALIGN_TO (window_box_left_offset (it->w, LEFT_MARGIN_AREA));
25424 /* 'right-margin': left edge of the right display margin. */
25425 if (EQ (prop, Qright_margin))
25426 return OK_ALIGN_TO (window_box_left_offset (it->w, RIGHT_MARGIN_AREA));
25427 /* 'scroll-bar': left edge of the vertical scroll bar. */
25428 if (EQ (prop, Qscroll_bar))
25429 return OK_ALIGN_TO (WINDOW_HAS_VERTICAL_SCROLL_BAR_ON_LEFT (it->w)
25431 : (window_box_right_offset (it->w, RIGHT_MARGIN_AREA)
25432 + (WINDOW_HAS_FRINGES_OUTSIDE_MARGINS (it->w)
25433 ? WINDOW_RIGHT_FRINGE_WIDTH (it->w)
25434 : 0)));
25436 else
25438 /* Otherwise, the elements stand for their width. */
25439 if (EQ (prop, Qleft_fringe))
25440 return OK_PIXELS (WINDOW_LEFT_FRINGE_WIDTH (it->w));
25441 if (EQ (prop, Qright_fringe))
25442 return OK_PIXELS (WINDOW_RIGHT_FRINGE_WIDTH (it->w));
25443 if (EQ (prop, Qleft_margin))
25444 return OK_PIXELS (WINDOW_LEFT_MARGIN_WIDTH (it->w));
25445 if (EQ (prop, Qright_margin))
25446 return OK_PIXELS (WINDOW_RIGHT_MARGIN_WIDTH (it->w));
25447 if (EQ (prop, Qscroll_bar))
25448 return OK_PIXELS (WINDOW_SCROLL_BAR_AREA_WIDTH (it->w));
25451 prop = buffer_local_value (prop, it->w->contents);
25452 if (EQ (prop, Qunbound))
25453 prop = Qnil;
25456 if (NUMBERP (prop))
25458 int base_unit = (width_p
25459 ? FRAME_COLUMN_WIDTH (it->f)
25460 : FRAME_LINE_HEIGHT (it->f));
25461 if (width_p && align_to && *align_to < 0)
25462 return OK_PIXELS (XFLOATINT (prop) * base_unit + it->lnum_pixel_width);
25463 return OK_PIXELS (XFLOATINT (prop) * base_unit);
25466 if (CONSP (prop))
25468 Lisp_Object car = XCAR (prop);
25469 Lisp_Object cdr = XCDR (prop);
25471 if (SYMBOLP (car))
25473 #ifdef HAVE_WINDOW_SYSTEM
25474 /* '(image PROPS...)': width or height of the specified image. */
25475 if (FRAME_WINDOW_P (it->f)
25476 && valid_image_p (prop))
25478 ptrdiff_t id = lookup_image (it->f, prop);
25479 struct image *img = IMAGE_FROM_ID (it->f, id);
25481 return OK_PIXELS (width_p ? img->width : img->height);
25483 /* '(xwidget PROPS...)': dimensions of the specified xwidget. */
25484 if (FRAME_WINDOW_P (it->f) && valid_xwidget_spec_p (prop))
25486 /* TODO: Don't return dummy size. */
25487 return OK_PIXELS (100);
25489 #endif
25490 /* '(+ EXPR...)' or '(- EXPR...)' add or subtract
25491 recursively calculated values. */
25492 if (EQ (car, Qplus) || EQ (car, Qminus))
25494 bool first = true;
25495 double px;
25497 pixels = 0;
25498 while (CONSP (cdr))
25500 if (!calc_pixel_width_or_height (&px, it, XCAR (cdr),
25501 font, width_p, align_to))
25502 return false;
25503 if (first)
25504 pixels = (EQ (car, Qplus) ? px : -px), first = false;
25505 else
25506 pixels += px;
25507 cdr = XCDR (cdr);
25509 if (EQ (car, Qminus))
25510 pixels = -pixels;
25511 return OK_PIXELS (pixels);
25514 car = buffer_local_value (car, it->w->contents);
25515 if (EQ (car, Qunbound))
25516 car = Qnil;
25519 /* '(NUM)': absolute number of pixels. */
25520 if (NUMBERP (car))
25522 double fact;
25523 int offset =
25524 width_p && align_to && *align_to < 0 ? it->lnum_pixel_width : 0;
25525 pixels = XFLOATINT (car);
25526 if (NILP (cdr))
25527 return OK_PIXELS (pixels + offset);
25528 if (calc_pixel_width_or_height (&fact, it, cdr,
25529 font, width_p, align_to))
25530 return OK_PIXELS (pixels * fact + offset);
25531 return false;
25534 return false;
25537 return false;
25540 void
25541 get_font_ascent_descent (struct font *font, int *ascent, int *descent)
25543 #ifdef HAVE_WINDOW_SYSTEM
25544 normal_char_ascent_descent (font, -1, ascent, descent);
25545 #else
25546 *ascent = 1;
25547 *descent = 0;
25548 #endif
25552 /***********************************************************************
25553 Glyph Display
25554 ***********************************************************************/
25556 #ifdef HAVE_WINDOW_SYSTEM
25558 #ifdef GLYPH_DEBUG
25560 void
25561 dump_glyph_string (struct glyph_string *s)
25563 fprintf (stderr, "glyph string\n");
25564 fprintf (stderr, " x, y, w, h = %d, %d, %d, %d\n",
25565 s->x, s->y, s->width, s->height);
25566 fprintf (stderr, " ybase = %d\n", s->ybase);
25567 fprintf (stderr, " hl = %u\n", s->hl);
25568 fprintf (stderr, " left overhang = %d, right = %d\n",
25569 s->left_overhang, s->right_overhang);
25570 fprintf (stderr, " nchars = %d\n", s->nchars);
25571 fprintf (stderr, " extends to end of line = %d\n",
25572 s->extends_to_end_of_line_p);
25573 fprintf (stderr, " font height = %d\n", FONT_HEIGHT (s->font));
25574 fprintf (stderr, " bg width = %d\n", s->background_width);
25577 #endif /* GLYPH_DEBUG */
25579 /* Initialize glyph string S. CHAR2B is a suitably allocated vector
25580 of XChar2b structures for S; it can't be allocated in
25581 init_glyph_string because it must be allocated via `alloca'. W
25582 is the window on which S is drawn. ROW and AREA are the glyph row
25583 and area within the row from which S is constructed. START is the
25584 index of the first glyph structure covered by S. HL is a
25585 face-override for drawing S. */
25587 #ifdef HAVE_NTGUI
25588 #define OPTIONAL_HDC(hdc) HDC hdc,
25589 #define DECLARE_HDC(hdc) HDC hdc;
25590 #define ALLOCATE_HDC(hdc, f) hdc = get_frame_dc ((f))
25591 #define RELEASE_HDC(hdc, f) release_frame_dc ((f), (hdc))
25592 #endif
25594 #ifndef OPTIONAL_HDC
25595 #define OPTIONAL_HDC(hdc)
25596 #define DECLARE_HDC(hdc)
25597 #define ALLOCATE_HDC(hdc, f)
25598 #define RELEASE_HDC(hdc, f)
25599 #endif
25601 static void
25602 init_glyph_string (struct glyph_string *s,
25603 OPTIONAL_HDC (hdc)
25604 XChar2b *char2b, struct window *w, struct glyph_row *row,
25605 enum glyph_row_area area, int start, enum draw_glyphs_face hl)
25607 memset (s, 0, sizeof *s);
25608 s->w = w;
25609 s->f = XFRAME (w->frame);
25610 #ifdef HAVE_NTGUI
25611 s->hdc = hdc;
25612 #endif
25613 s->display = FRAME_X_DISPLAY (s->f);
25614 s->char2b = char2b;
25615 s->hl = hl;
25616 s->row = row;
25617 s->area = area;
25618 s->first_glyph = row->glyphs[area] + start;
25619 s->height = row->height;
25620 s->y = WINDOW_TO_FRAME_PIXEL_Y (w, row->y);
25621 s->ybase = s->y + row->ascent;
25625 /* Append the list of glyph strings with head H and tail T to the list
25626 with head *HEAD and tail *TAIL. Set *HEAD and *TAIL to the result. */
25628 static void
25629 append_glyph_string_lists (struct glyph_string **head, struct glyph_string **tail,
25630 struct glyph_string *h, struct glyph_string *t)
25632 if (h)
25634 if (*head)
25635 (*tail)->next = h;
25636 else
25637 *head = h;
25638 h->prev = *tail;
25639 *tail = t;
25644 /* Prepend the list of glyph strings with head H and tail T to the
25645 list with head *HEAD and tail *TAIL. Set *HEAD and *TAIL to the
25646 result. */
25648 static void
25649 prepend_glyph_string_lists (struct glyph_string **head, struct glyph_string **tail,
25650 struct glyph_string *h, struct glyph_string *t)
25652 if (h)
25654 if (*head)
25655 (*head)->prev = t;
25656 else
25657 *tail = t;
25658 t->next = *head;
25659 *head = h;
25664 /* Append glyph string S to the list with head *HEAD and tail *TAIL.
25665 Set *HEAD and *TAIL to the resulting list. */
25667 static void
25668 append_glyph_string (struct glyph_string **head, struct glyph_string **tail,
25669 struct glyph_string *s)
25671 s->next = s->prev = NULL;
25672 append_glyph_string_lists (head, tail, s, s);
25676 /* Get face and two-byte form of character C in face FACE_ID on frame F.
25677 The encoding of C is returned in *CHAR2B. DISPLAY_P means
25678 make sure that X resources for the face returned are allocated.
25679 Value is a pointer to a realized face that is ready for display if
25680 DISPLAY_P. */
25682 static struct face *
25683 get_char_face_and_encoding (struct frame *f, int c, int face_id,
25684 XChar2b *char2b, bool display_p)
25686 struct face *face = FACE_FROM_ID (f, face_id);
25687 unsigned code = 0;
25689 if (face->font)
25691 code = face->font->driver->encode_char (face->font, c);
25693 if (code == FONT_INVALID_CODE)
25694 code = 0;
25696 STORE_XCHAR2B (char2b, (code >> 8), (code & 0xFF));
25698 /* Make sure X resources of the face are allocated. */
25699 #ifdef HAVE_X_WINDOWS
25700 if (display_p)
25701 #endif
25703 eassert (face != NULL);
25704 prepare_face_for_display (f, face);
25707 return face;
25711 /* Get face and two-byte form of character glyph GLYPH on frame F.
25712 The encoding of GLYPH->u.ch is returned in *CHAR2B. Value is
25713 a pointer to a realized face that is ready for display. */
25715 static struct face *
25716 get_glyph_face_and_encoding (struct frame *f, struct glyph *glyph,
25717 XChar2b *char2b)
25719 struct face *face;
25720 unsigned code = 0;
25722 eassert (glyph->type == CHAR_GLYPH);
25723 face = FACE_FROM_ID (f, glyph->face_id);
25725 /* Make sure X resources of the face are allocated. */
25726 prepare_face_for_display (f, face);
25728 if (face->font)
25730 if (CHAR_BYTE8_P (glyph->u.ch))
25731 code = CHAR_TO_BYTE8 (glyph->u.ch);
25732 else
25733 code = face->font->driver->encode_char (face->font, glyph->u.ch);
25735 if (code == FONT_INVALID_CODE)
25736 code = 0;
25739 STORE_XCHAR2B (char2b, (code >> 8), (code & 0xFF));
25740 return face;
25744 /* Get glyph code of character C in FONT in the two-byte form CHAR2B.
25745 Return true iff FONT has a glyph for C. */
25747 static bool
25748 get_char_glyph_code (int c, struct font *font, XChar2b *char2b)
25750 unsigned code;
25752 if (CHAR_BYTE8_P (c))
25753 code = CHAR_TO_BYTE8 (c);
25754 else
25755 code = font->driver->encode_char (font, c);
25757 if (code == FONT_INVALID_CODE)
25758 return false;
25759 STORE_XCHAR2B (char2b, (code >> 8), (code & 0xFF));
25760 return true;
25764 /* Fill glyph string S with composition components specified by S->cmp.
25766 BASE_FACE is the base face of the composition.
25767 S->cmp_from is the index of the first component for S.
25769 OVERLAPS non-zero means S should draw the foreground only, and use
25770 its physical height for clipping. See also draw_glyphs.
25772 Value is the index of a component not in S. */
25774 static int
25775 fill_composite_glyph_string (struct glyph_string *s, struct face *base_face,
25776 int overlaps)
25778 int i;
25779 /* For all glyphs of this composition, starting at the offset
25780 S->cmp_from, until we reach the end of the definition or encounter a
25781 glyph that requires the different face, add it to S. */
25782 struct face *face;
25784 eassert (s);
25786 s->for_overlaps = overlaps;
25787 s->face = NULL;
25788 s->font = NULL;
25789 for (i = s->cmp_from; i < s->cmp->glyph_len; i++)
25791 int c = COMPOSITION_GLYPH (s->cmp, i);
25793 /* TAB in a composition means display glyphs with padding space
25794 on the left or right. */
25795 if (c != '\t')
25797 int face_id = FACE_FOR_CHAR (s->f, base_face->ascii_face, c,
25798 -1, Qnil);
25800 face = get_char_face_and_encoding (s->f, c, face_id,
25801 s->char2b + i, true);
25802 if (face)
25804 if (! s->face)
25806 s->face = face;
25807 s->font = s->face->font;
25809 else if (s->face != face)
25810 break;
25813 ++s->nchars;
25815 s->cmp_to = i;
25817 if (s->face == NULL)
25819 s->face = base_face->ascii_face;
25820 s->font = s->face->font;
25823 /* All glyph strings for the same composition has the same width,
25824 i.e. the width set for the first component of the composition. */
25825 s->width = s->first_glyph->pixel_width;
25827 /* If the specified font could not be loaded, use the frame's
25828 default font, but record the fact that we couldn't load it in
25829 the glyph string so that we can draw rectangles for the
25830 characters of the glyph string. */
25831 if (s->font == NULL)
25833 s->font_not_found_p = true;
25834 s->font = FRAME_FONT (s->f);
25837 /* Adjust base line for subscript/superscript text. */
25838 s->ybase += s->first_glyph->voffset;
25840 return s->cmp_to;
25843 static int
25844 fill_gstring_glyph_string (struct glyph_string *s, int face_id,
25845 int start, int end, int overlaps)
25847 struct glyph *glyph, *last;
25848 Lisp_Object lgstring;
25849 int i;
25851 s->for_overlaps = overlaps;
25852 glyph = s->row->glyphs[s->area] + start;
25853 last = s->row->glyphs[s->area] + end;
25854 s->cmp_id = glyph->u.cmp.id;
25855 s->cmp_from = glyph->slice.cmp.from;
25856 s->cmp_to = glyph->slice.cmp.to + 1;
25857 s->face = FACE_FROM_ID (s->f, face_id);
25858 lgstring = composition_gstring_from_id (s->cmp_id);
25859 s->font = XFONT_OBJECT (LGSTRING_FONT (lgstring));
25860 glyph++;
25861 while (glyph < last
25862 && glyph->u.cmp.automatic
25863 && glyph->u.cmp.id == s->cmp_id
25864 && s->cmp_to == glyph->slice.cmp.from)
25865 s->cmp_to = (glyph++)->slice.cmp.to + 1;
25867 for (i = s->cmp_from; i < s->cmp_to; i++)
25869 Lisp_Object lglyph = LGSTRING_GLYPH (lgstring, i);
25870 unsigned code = LGLYPH_CODE (lglyph);
25872 STORE_XCHAR2B ((s->char2b + i), code >> 8, code & 0xFF);
25874 s->width = composition_gstring_width (lgstring, s->cmp_from, s->cmp_to, NULL);
25875 return glyph - s->row->glyphs[s->area];
25879 /* Fill glyph string S from a sequence glyphs for glyphless characters.
25880 See the comment of fill_glyph_string for arguments.
25881 Value is the index of the first glyph not in S. */
25884 static int
25885 fill_glyphless_glyph_string (struct glyph_string *s, int face_id,
25886 int start, int end, int overlaps)
25888 struct glyph *glyph, *last;
25889 int voffset;
25891 eassert (s->first_glyph->type == GLYPHLESS_GLYPH);
25892 s->for_overlaps = overlaps;
25893 glyph = s->row->glyphs[s->area] + start;
25894 last = s->row->glyphs[s->area] + end;
25895 voffset = glyph->voffset;
25896 s->face = FACE_FROM_ID (s->f, face_id);
25897 s->font = s->face->font ? s->face->font : FRAME_FONT (s->f);
25898 s->nchars = 1;
25899 s->width = glyph->pixel_width;
25900 glyph++;
25901 while (glyph < last
25902 && glyph->type == GLYPHLESS_GLYPH
25903 && glyph->voffset == voffset
25904 && glyph->face_id == face_id)
25906 s->nchars++;
25907 s->width += glyph->pixel_width;
25908 glyph++;
25910 s->ybase += voffset;
25911 return glyph - s->row->glyphs[s->area];
25915 /* Fill glyph string S from a sequence of character glyphs.
25917 FACE_ID is the face id of the string. START is the index of the
25918 first glyph to consider, END is the index of the last + 1.
25919 OVERLAPS non-zero means S should draw the foreground only, and use
25920 its physical height for clipping. See also draw_glyphs.
25922 Value is the index of the first glyph not in S. */
25924 static int
25925 fill_glyph_string (struct glyph_string *s, int face_id,
25926 int start, int end, int overlaps)
25928 struct glyph *glyph, *last;
25929 int voffset;
25930 bool glyph_not_available_p;
25932 eassert (s->f == XFRAME (s->w->frame));
25933 eassert (s->nchars == 0);
25934 eassert (start >= 0 && end > start);
25936 s->for_overlaps = overlaps;
25937 glyph = s->row->glyphs[s->area] + start;
25938 last = s->row->glyphs[s->area] + end;
25939 voffset = glyph->voffset;
25940 s->padding_p = glyph->padding_p;
25941 glyph_not_available_p = glyph->glyph_not_available_p;
25943 while (glyph < last
25944 && glyph->type == CHAR_GLYPH
25945 && glyph->voffset == voffset
25946 /* Same face id implies same font, nowadays. */
25947 && glyph->face_id == face_id
25948 && glyph->glyph_not_available_p == glyph_not_available_p)
25950 s->face = get_glyph_face_and_encoding (s->f, glyph,
25951 s->char2b + s->nchars);
25952 ++s->nchars;
25953 eassert (s->nchars <= end - start);
25954 s->width += glyph->pixel_width;
25955 if (glyph++->padding_p != s->padding_p)
25956 break;
25959 s->font = s->face->font;
25961 /* If the specified font could not be loaded, use the frame's font,
25962 but record the fact that we couldn't load it in
25963 S->font_not_found_p so that we can draw rectangles for the
25964 characters of the glyph string. */
25965 if (s->font == NULL || glyph_not_available_p)
25967 s->font_not_found_p = true;
25968 s->font = FRAME_FONT (s->f);
25971 /* Adjust base line for subscript/superscript text. */
25972 s->ybase += voffset;
25974 eassert (s->face && s->face->gc);
25975 return glyph - s->row->glyphs[s->area];
25979 /* Fill glyph string S from image glyph S->first_glyph. */
25981 static void
25982 fill_image_glyph_string (struct glyph_string *s)
25984 eassert (s->first_glyph->type == IMAGE_GLYPH);
25985 s->img = IMAGE_FROM_ID (s->f, s->first_glyph->u.img_id);
25986 eassert (s->img);
25987 s->slice = s->first_glyph->slice.img;
25988 s->face = FACE_FROM_ID (s->f, s->first_glyph->face_id);
25989 s->font = s->face->font;
25990 s->width = s->first_glyph->pixel_width;
25992 /* Adjust base line for subscript/superscript text. */
25993 s->ybase += s->first_glyph->voffset;
25997 #ifdef HAVE_XWIDGETS
25998 static void
25999 fill_xwidget_glyph_string (struct glyph_string *s)
26001 eassert (s->first_glyph->type == XWIDGET_GLYPH);
26002 s->face = FACE_FROM_ID (s->f, s->first_glyph->face_id);
26003 s->font = s->face->font;
26004 s->width = s->first_glyph->pixel_width;
26005 s->ybase += s->first_glyph->voffset;
26006 s->xwidget = s->first_glyph->u.xwidget;
26008 #endif
26009 /* Fill glyph string S from a sequence of stretch glyphs.
26011 START is the index of the first glyph to consider,
26012 END is the index of the last + 1.
26014 Value is the index of the first glyph not in S. */
26016 static int
26017 fill_stretch_glyph_string (struct glyph_string *s, int start, int end)
26019 struct glyph *glyph, *last;
26020 int voffset, face_id;
26022 eassert (s->first_glyph->type == STRETCH_GLYPH);
26024 glyph = s->row->glyphs[s->area] + start;
26025 last = s->row->glyphs[s->area] + end;
26026 face_id = glyph->face_id;
26027 s->face = FACE_FROM_ID (s->f, face_id);
26028 s->font = s->face->font;
26029 s->width = glyph->pixel_width;
26030 s->nchars = 1;
26031 voffset = glyph->voffset;
26033 for (++glyph;
26034 (glyph < last
26035 && glyph->type == STRETCH_GLYPH
26036 && glyph->voffset == voffset
26037 && glyph->face_id == face_id);
26038 ++glyph)
26039 s->width += glyph->pixel_width;
26041 /* Adjust base line for subscript/superscript text. */
26042 s->ybase += voffset;
26044 /* The case that face->gc == 0 is handled when drawing the glyph
26045 string by calling prepare_face_for_display. */
26046 eassert (s->face);
26047 return glyph - s->row->glyphs[s->area];
26050 static struct font_metrics *
26051 get_per_char_metric (struct font *font, XChar2b *char2b)
26053 static struct font_metrics metrics;
26054 unsigned code;
26056 if (! font)
26057 return NULL;
26058 code = (XCHAR2B_BYTE1 (char2b) << 8) | XCHAR2B_BYTE2 (char2b);
26059 if (code == FONT_INVALID_CODE)
26060 return NULL;
26061 font->driver->text_extents (font, &code, 1, &metrics);
26062 return &metrics;
26065 /* A subroutine that computes "normal" values of ASCENT and DESCENT
26066 for FONT. Values are taken from font-global ones, except for fonts
26067 that claim preposterously large values, but whose glyphs actually
26068 have reasonable dimensions. C is the character to use for metrics
26069 if the font-global values are too large; if C is negative, the
26070 function selects a default character. */
26071 static void
26072 normal_char_ascent_descent (struct font *font, int c, int *ascent, int *descent)
26074 *ascent = FONT_BASE (font);
26075 *descent = FONT_DESCENT (font);
26077 if (FONT_TOO_HIGH (font))
26079 XChar2b char2b;
26081 /* Get metrics of C, defaulting to a reasonably sized ASCII
26082 character. */
26083 if (get_char_glyph_code (c >= 0 ? c : '{', font, &char2b))
26085 struct font_metrics *pcm = get_per_char_metric (font, &char2b);
26087 if (!(pcm->width == 0 && pcm->rbearing == 0 && pcm->lbearing == 0))
26089 /* We add 1 pixel to character dimensions as heuristics
26090 that produces nicer display, e.g. when the face has
26091 the box attribute. */
26092 *ascent = pcm->ascent + 1;
26093 *descent = pcm->descent + 1;
26099 /* A subroutine that computes a reasonable "normal character height"
26100 for fonts that claim preposterously large vertical dimensions, but
26101 whose glyphs are actually reasonably sized. C is the character
26102 whose metrics to use for those fonts, or -1 for default
26103 character. */
26104 static int
26105 normal_char_height (struct font *font, int c)
26107 int ascent, descent;
26109 normal_char_ascent_descent (font, c, &ascent, &descent);
26111 return ascent + descent;
26114 /* EXPORT for RIF:
26115 Set *LEFT and *RIGHT to the left and right overhang of GLYPH on
26116 frame F. Overhangs of glyphs other than type CHAR_GLYPH are
26117 assumed to be zero. */
26119 void
26120 x_get_glyph_overhangs (struct glyph *glyph, struct frame *f, int *left, int *right)
26122 *left = *right = 0;
26124 if (glyph->type == CHAR_GLYPH)
26126 XChar2b char2b;
26127 struct face *face = get_glyph_face_and_encoding (f, glyph, &char2b);
26128 if (face->font)
26130 struct font_metrics *pcm = get_per_char_metric (face->font, &char2b);
26131 if (pcm)
26133 if (pcm->rbearing > pcm->width)
26134 *right = pcm->rbearing - pcm->width;
26135 if (pcm->lbearing < 0)
26136 *left = -pcm->lbearing;
26140 else if (glyph->type == COMPOSITE_GLYPH)
26142 if (! glyph->u.cmp.automatic)
26144 struct composition *cmp = composition_table[glyph->u.cmp.id];
26146 if (cmp->rbearing > cmp->pixel_width)
26147 *right = cmp->rbearing - cmp->pixel_width;
26148 if (cmp->lbearing < 0)
26149 *left = - cmp->lbearing;
26151 else
26153 Lisp_Object gstring = composition_gstring_from_id (glyph->u.cmp.id);
26154 struct font_metrics metrics;
26156 composition_gstring_width (gstring, glyph->slice.cmp.from,
26157 glyph->slice.cmp.to + 1, &metrics);
26158 if (metrics.rbearing > metrics.width)
26159 *right = metrics.rbearing - metrics.width;
26160 if (metrics.lbearing < 0)
26161 *left = - metrics.lbearing;
26167 /* Return the index of the first glyph preceding glyph string S that
26168 is overwritten by S because of S's left overhang. Value is -1
26169 if no glyphs are overwritten. */
26171 static int
26172 left_overwritten (struct glyph_string *s)
26174 int k;
26176 if (s->left_overhang)
26178 int x = 0, i;
26179 struct glyph *glyphs = s->row->glyphs[s->area];
26180 int first = s->first_glyph - glyphs;
26182 for (i = first - 1; i >= 0 && x > -s->left_overhang; --i)
26183 x -= glyphs[i].pixel_width;
26185 k = i + 1;
26187 else
26188 k = -1;
26190 return k;
26194 /* Return the index of the first glyph preceding glyph string S that
26195 is overwriting S because of its right overhang. Value is -1 if no
26196 glyph in front of S overwrites S. */
26198 static int
26199 left_overwriting (struct glyph_string *s)
26201 int i, k, x;
26202 struct glyph *glyphs = s->row->glyphs[s->area];
26203 int first = s->first_glyph - glyphs;
26205 k = -1;
26206 x = 0;
26207 for (i = first - 1; i >= 0; --i)
26209 int left, right;
26210 x_get_glyph_overhangs (glyphs + i, s->f, &left, &right);
26211 if (x + right > 0)
26212 k = i;
26213 x -= glyphs[i].pixel_width;
26216 return k;
26220 /* Return the index of the last glyph following glyph string S that is
26221 overwritten by S because of S's right overhang. Value is -1 if
26222 no such glyph is found. */
26224 static int
26225 right_overwritten (struct glyph_string *s)
26227 int k = -1;
26229 if (s->right_overhang)
26231 int x = 0, i;
26232 struct glyph *glyphs = s->row->glyphs[s->area];
26233 int first = (s->first_glyph - glyphs
26234 + (s->first_glyph->type == COMPOSITE_GLYPH ? 1 : s->nchars));
26235 int end = s->row->used[s->area];
26237 for (i = first; i < end && s->right_overhang > x; ++i)
26238 x += glyphs[i].pixel_width;
26240 k = i;
26243 return k;
26247 /* Return the index of the last glyph following glyph string S that
26248 overwrites S because of its left overhang. Value is negative
26249 if no such glyph is found. */
26251 static int
26252 right_overwriting (struct glyph_string *s)
26254 int i, k, x;
26255 int end = s->row->used[s->area];
26256 struct glyph *glyphs = s->row->glyphs[s->area];
26257 int first = (s->first_glyph - glyphs
26258 + (s->first_glyph->type == COMPOSITE_GLYPH ? 1 : s->nchars));
26260 k = -1;
26261 x = 0;
26262 for (i = first; i < end; ++i)
26264 int left, right;
26265 x_get_glyph_overhangs (glyphs + i, s->f, &left, &right);
26266 if (x - left < 0)
26267 k = i;
26268 x += glyphs[i].pixel_width;
26271 return k;
26275 /* Set background width of glyph string S. START is the index of the
26276 first glyph following S. LAST_X is the right-most x-position + 1
26277 in the drawing area. */
26279 static void
26280 set_glyph_string_background_width (struct glyph_string *s, int start, int last_x)
26282 /* If the face of this glyph string has to be drawn to the end of
26283 the drawing area, set S->extends_to_end_of_line_p. */
26285 if (start == s->row->used[s->area]
26286 && ((s->row->fill_line_p
26287 && (s->hl == DRAW_NORMAL_TEXT
26288 || s->hl == DRAW_IMAGE_RAISED
26289 || s->hl == DRAW_IMAGE_SUNKEN))
26290 || s->hl == DRAW_MOUSE_FACE))
26291 s->extends_to_end_of_line_p = true;
26293 /* If S extends its face to the end of the line, set its
26294 background_width to the distance to the right edge of the drawing
26295 area. */
26296 if (s->extends_to_end_of_line_p)
26297 s->background_width = last_x - s->x + 1;
26298 else
26299 s->background_width = s->width;
26303 /* Return glyph string that shares background with glyph string S and
26304 whose `background_width' member has been set. */
26306 static struct glyph_string *
26307 glyph_string_containing_background_width (struct glyph_string *s)
26309 if (s->cmp)
26310 while (s->cmp_from)
26311 s = s->prev;
26313 return s;
26317 /* Compute overhangs and x-positions for glyph string S and its
26318 predecessors, or successors. X is the starting x-position for S.
26319 BACKWARD_P means process predecessors. */
26321 static void
26322 compute_overhangs_and_x (struct glyph_string *s, int x, bool backward_p)
26324 if (backward_p)
26326 while (s)
26328 if (FRAME_RIF (s->f)->compute_glyph_string_overhangs)
26329 FRAME_RIF (s->f)->compute_glyph_string_overhangs (s);
26330 if (!s->cmp || s->cmp_to == s->cmp->glyph_len)
26331 x -= s->width;
26332 s->x = x;
26333 s = s->prev;
26336 else
26338 while (s)
26340 if (FRAME_RIF (s->f)->compute_glyph_string_overhangs)
26341 FRAME_RIF (s->f)->compute_glyph_string_overhangs (s);
26342 s->x = x;
26343 if (!s->cmp || s->cmp_to == s->cmp->glyph_len)
26344 x += s->width;
26345 s = s->next;
26352 /* The following macros are only called from draw_glyphs below.
26353 They reference the following parameters of that function directly:
26354 `w', `row', `area', and `overlap_p'
26355 as well as the following local variables:
26356 `s', `f', and `hdc' (in W32) */
26358 #ifdef HAVE_NTGUI
26359 /* On W32, silently add local `hdc' variable to argument list of
26360 init_glyph_string. */
26361 #define INIT_GLYPH_STRING(s, char2b, w, row, area, start, hl) \
26362 init_glyph_string (s, hdc, char2b, w, row, area, start, hl)
26363 #else
26364 #define INIT_GLYPH_STRING(s, char2b, w, row, area, start, hl) \
26365 init_glyph_string (s, char2b, w, row, area, start, hl)
26366 #endif
26368 /* Add a glyph string for a stretch glyph to the list of strings
26369 between HEAD and TAIL. START is the index of the stretch glyph in
26370 row area AREA of glyph row ROW. END is the index of the last glyph
26371 in that glyph row area. X is the current output position assigned
26372 to the new glyph string constructed. HL overrides that face of the
26373 glyph; e.g. it is DRAW_CURSOR if a cursor has to be drawn. LAST_X
26374 is the right-most x-position of the drawing area. */
26376 /* SunOS 4 bundled cc, barfed on continuations in the arg lists here
26377 and below -- keep them on one line. */
26378 #define BUILD_STRETCH_GLYPH_STRING(START, END, HEAD, TAIL, HL, X, LAST_X) \
26379 do \
26381 s = alloca (sizeof *s); \
26382 INIT_GLYPH_STRING (s, NULL, w, row, area, START, HL); \
26383 START = fill_stretch_glyph_string (s, START, END); \
26384 append_glyph_string (&HEAD, &TAIL, s); \
26385 s->x = (X); \
26387 while (false)
26390 /* Add a glyph string for an image glyph to the list of strings
26391 between HEAD and TAIL. START is the index of the image glyph in
26392 row area AREA of glyph row ROW. END is the index of the last glyph
26393 in that glyph row area. X is the current output position assigned
26394 to the new glyph string constructed. HL overrides that face of the
26395 glyph; e.g. it is DRAW_CURSOR if a cursor has to be drawn. LAST_X
26396 is the right-most x-position of the drawing area. */
26398 #define BUILD_IMAGE_GLYPH_STRING(START, END, HEAD, TAIL, HL, X, LAST_X) \
26399 do \
26401 s = alloca (sizeof *s); \
26402 INIT_GLYPH_STRING (s, NULL, w, row, area, START, HL); \
26403 fill_image_glyph_string (s); \
26404 append_glyph_string (&HEAD, &TAIL, s); \
26405 ++START; \
26406 s->x = (X); \
26408 while (false)
26410 #ifndef HAVE_XWIDGETS
26411 # define BUILD_XWIDGET_GLYPH_STRING(START, END, HEAD, TAIL, HL, X, LAST_X) \
26412 eassume (false)
26413 #else
26414 # define BUILD_XWIDGET_GLYPH_STRING(START, END, HEAD, TAIL, HL, X, LAST_X) \
26415 do \
26417 s = alloca (sizeof *s); \
26418 INIT_GLYPH_STRING (s, NULL, w, row, area, START, HL); \
26419 fill_xwidget_glyph_string (s); \
26420 append_glyph_string (&(HEAD), &(TAIL), s); \
26421 ++(START); \
26422 s->x = (X); \
26424 while (false)
26425 #endif
26427 /* Add a glyph string for a sequence of character glyphs to the list
26428 of strings between HEAD and TAIL. START is the index of the first
26429 glyph in row area AREA of glyph row ROW that is part of the new
26430 glyph string. END is the index of the last glyph in that glyph row
26431 area. X is the current output position assigned to the new glyph
26432 string constructed. HL overrides that face of the glyph; e.g. it
26433 is DRAW_CURSOR if a cursor has to be drawn. LAST_X is the
26434 right-most x-position of the drawing area. */
26436 #define BUILD_CHAR_GLYPH_STRINGS(START, END, HEAD, TAIL, HL, X, LAST_X) \
26437 do \
26439 int face_id; \
26440 XChar2b *char2b; \
26442 face_id = (row)->glyphs[area][START].face_id; \
26444 s = alloca (sizeof *s); \
26445 SAFE_NALLOCA (char2b, 1, (END) - (START)); \
26446 INIT_GLYPH_STRING (s, char2b, w, row, area, START, HL); \
26447 append_glyph_string (&HEAD, &TAIL, s); \
26448 s->x = (X); \
26449 START = fill_glyph_string (s, face_id, START, END, overlaps); \
26451 while (false)
26454 /* Add a glyph string for a composite sequence to the list of strings
26455 between HEAD and TAIL. START is the index of the first glyph in
26456 row area AREA of glyph row ROW that is part of the new glyph
26457 string. END is the index of the last glyph in that glyph row area.
26458 X is the current output position assigned to the new glyph string
26459 constructed. HL overrides that face of the glyph; e.g. it is
26460 DRAW_CURSOR if a cursor has to be drawn. LAST_X is the right-most
26461 x-position of the drawing area. */
26463 #define BUILD_COMPOSITE_GLYPH_STRING(START, END, HEAD, TAIL, HL, X, LAST_X) \
26464 do { \
26465 int face_id = (row)->glyphs[area][START].face_id; \
26466 struct face *base_face = FACE_FROM_ID (f, face_id); \
26467 ptrdiff_t cmp_id = (row)->glyphs[area][START].u.cmp.id; \
26468 struct composition *cmp = composition_table[cmp_id]; \
26469 XChar2b *char2b; \
26470 struct glyph_string *first_s = NULL; \
26471 int n; \
26473 SAFE_NALLOCA (char2b, 1, cmp->glyph_len); \
26475 /* Make glyph_strings for each glyph sequence that is drawable by \
26476 the same face, and append them to HEAD/TAIL. */ \
26477 for (n = 0; n < cmp->glyph_len;) \
26479 s = alloca (sizeof *s); \
26480 INIT_GLYPH_STRING (s, char2b, w, row, area, START, HL); \
26481 append_glyph_string (&(HEAD), &(TAIL), s); \
26482 s->cmp = cmp; \
26483 s->cmp_from = n; \
26484 s->x = (X); \
26485 if (n == 0) \
26486 first_s = s; \
26487 n = fill_composite_glyph_string (s, base_face, overlaps); \
26490 ++START; \
26491 s = first_s; \
26492 } while (false)
26495 /* Add a glyph string for a glyph-string sequence to the list of strings
26496 between HEAD and TAIL. */
26498 #define BUILD_GSTRING_GLYPH_STRING(START, END, HEAD, TAIL, HL, X, LAST_X) \
26499 do { \
26500 int face_id; \
26501 XChar2b *char2b; \
26502 Lisp_Object gstring; \
26504 face_id = (row)->glyphs[area][START].face_id; \
26505 gstring = (composition_gstring_from_id \
26506 ((row)->glyphs[area][START].u.cmp.id)); \
26507 s = alloca (sizeof *s); \
26508 SAFE_NALLOCA (char2b, 1, LGSTRING_GLYPH_LEN (gstring)); \
26509 INIT_GLYPH_STRING (s, char2b, w, row, area, START, HL); \
26510 append_glyph_string (&(HEAD), &(TAIL), s); \
26511 s->x = (X); \
26512 START = fill_gstring_glyph_string (s, face_id, START, END, overlaps); \
26513 } while (false)
26516 /* Add a glyph string for a sequence of glyphless character's glyphs
26517 to the list of strings between HEAD and TAIL. The meanings of
26518 arguments are the same as those of BUILD_CHAR_GLYPH_STRINGS. */
26520 #define BUILD_GLYPHLESS_GLYPH_STRING(START, END, HEAD, TAIL, HL, X, LAST_X) \
26521 do \
26523 int face_id; \
26525 face_id = (row)->glyphs[area][START].face_id; \
26527 s = alloca (sizeof *s); \
26528 INIT_GLYPH_STRING (s, NULL, w, row, area, START, HL); \
26529 append_glyph_string (&HEAD, &TAIL, s); \
26530 s->x = (X); \
26531 START = fill_glyphless_glyph_string (s, face_id, START, END, \
26532 overlaps); \
26534 while (false)
26537 /* Build a list of glyph strings between HEAD and TAIL for the glyphs
26538 of AREA of glyph row ROW on window W between indices START and END.
26539 HL overrides the face for drawing glyph strings, e.g. it is
26540 DRAW_CURSOR to draw a cursor. X and LAST_X are start and end
26541 x-positions of the drawing area.
26543 This is an ugly monster macro construct because we must use alloca
26544 to allocate glyph strings (because draw_glyphs can be called
26545 asynchronously). */
26547 #define BUILD_GLYPH_STRINGS_1(START, END, HEAD, TAIL, HL, X, LAST_X) \
26548 do \
26550 HEAD = TAIL = NULL; \
26551 while (START < END) \
26553 struct glyph *first_glyph = (row)->glyphs[area] + START; \
26554 switch (first_glyph->type) \
26556 case CHAR_GLYPH: \
26557 BUILD_CHAR_GLYPH_STRINGS (START, END, HEAD, TAIL, \
26558 HL, X, LAST_X); \
26559 break; \
26561 case COMPOSITE_GLYPH: \
26562 if (first_glyph->u.cmp.automatic) \
26563 BUILD_GSTRING_GLYPH_STRING (START, END, HEAD, TAIL, \
26564 HL, X, LAST_X); \
26565 else \
26566 BUILD_COMPOSITE_GLYPH_STRING (START, END, HEAD, TAIL, \
26567 HL, X, LAST_X); \
26568 break; \
26570 case STRETCH_GLYPH: \
26571 BUILD_STRETCH_GLYPH_STRING (START, END, HEAD, TAIL, \
26572 HL, X, LAST_X); \
26573 break; \
26575 case IMAGE_GLYPH: \
26576 BUILD_IMAGE_GLYPH_STRING (START, END, HEAD, TAIL, \
26577 HL, X, LAST_X); \
26578 break;
26580 #define BUILD_GLYPH_STRINGS_XW(START, END, HEAD, TAIL, HL, X, LAST_X) \
26581 case XWIDGET_GLYPH: \
26582 BUILD_XWIDGET_GLYPH_STRING (START, END, HEAD, TAIL, \
26583 HL, X, LAST_X); \
26584 break;
26586 #define BUILD_GLYPH_STRINGS_2(START, END, HEAD, TAIL, HL, X, LAST_X) \
26587 case GLYPHLESS_GLYPH: \
26588 BUILD_GLYPHLESS_GLYPH_STRING (START, END, HEAD, TAIL, \
26589 HL, X, LAST_X); \
26590 break; \
26592 default: \
26593 emacs_abort (); \
26596 if (s) \
26598 set_glyph_string_background_width (s, START, LAST_X); \
26599 (X) += s->width; \
26602 } while (false)
26605 #define BUILD_GLYPH_STRINGS(START, END, HEAD, TAIL, HL, X, LAST_X) \
26606 BUILD_GLYPH_STRINGS_1(START, END, HEAD, TAIL, HL, X, LAST_X) \
26607 BUILD_GLYPH_STRINGS_XW(START, END, HEAD, TAIL, HL, X, LAST_X) \
26608 BUILD_GLYPH_STRINGS_2(START, END, HEAD, TAIL, HL, X, LAST_X)
26611 /* Draw glyphs between START and END in AREA of ROW on window W,
26612 starting at x-position X. X is relative to AREA in W. HL is a
26613 face-override with the following meaning:
26615 DRAW_NORMAL_TEXT draw normally
26616 DRAW_CURSOR draw in cursor face
26617 DRAW_MOUSE_FACE draw in mouse face.
26618 DRAW_INVERSE_VIDEO draw in mode line face
26619 DRAW_IMAGE_SUNKEN draw an image with a sunken relief around it
26620 DRAW_IMAGE_RAISED draw an image with a raised relief around it
26622 If OVERLAPS is non-zero, draw only the foreground of characters and
26623 clip to the physical height of ROW. Non-zero value also defines
26624 the overlapping part to be drawn:
26626 OVERLAPS_PRED overlap with preceding rows
26627 OVERLAPS_SUCC overlap with succeeding rows
26628 OVERLAPS_BOTH overlap with both preceding/succeeding rows
26629 OVERLAPS_ERASED_CURSOR overlap with erased cursor area
26631 Value is the x-position reached, relative to AREA of W. */
26633 static int
26634 draw_glyphs (struct window *w, int x, struct glyph_row *row,
26635 enum glyph_row_area area, ptrdiff_t start, ptrdiff_t end,
26636 enum draw_glyphs_face hl, int overlaps)
26638 struct glyph_string *head, *tail;
26639 struct glyph_string *s;
26640 struct glyph_string *clip_head = NULL, *clip_tail = NULL;
26641 int i, j, x_reached, last_x, area_left = 0;
26642 struct frame *f = XFRAME (WINDOW_FRAME (w));
26643 DECLARE_HDC (hdc);
26645 ALLOCATE_HDC (hdc, f);
26647 /* Let's rather be paranoid than getting a SEGV. */
26648 end = min (end, row->used[area]);
26649 start = clip_to_bounds (0, start, end);
26651 /* Translate X to frame coordinates. Set last_x to the right
26652 end of the drawing area. */
26653 if (row->full_width_p)
26655 /* X is relative to the left edge of W, without scroll bars
26656 or fringes. */
26657 area_left = WINDOW_LEFT_EDGE_X (w);
26658 last_x = (WINDOW_LEFT_EDGE_X (w) + WINDOW_PIXEL_WIDTH (w)
26659 - (row->mode_line_p ? WINDOW_RIGHT_DIVIDER_WIDTH (w) : 0));
26661 else
26663 area_left = window_box_left (w, area);
26664 last_x = area_left + window_box_width (w, area);
26666 x += area_left;
26668 /* Build a doubly-linked list of glyph_string structures between
26669 head and tail from what we have to draw. Note that the macro
26670 BUILD_GLYPH_STRINGS will modify its start parameter. That's
26671 the reason we use a separate variable `i'. */
26672 i = start;
26673 USE_SAFE_ALLOCA;
26674 BUILD_GLYPH_STRINGS (i, end, head, tail, hl, x, last_x);
26675 if (tail)
26677 s = glyph_string_containing_background_width (tail);
26678 x_reached = s->x + s->background_width;
26680 else
26681 x_reached = x;
26683 /* If there are any glyphs with lbearing < 0 or rbearing > width in
26684 the row, redraw some glyphs in front or following the glyph
26685 strings built above. */
26686 if (head && !overlaps && row->contains_overlapping_glyphs_p)
26688 struct glyph_string *h, *t;
26689 Mouse_HLInfo *hlinfo = MOUSE_HL_INFO (f);
26690 int mouse_beg_col UNINIT, mouse_end_col UNINIT;
26691 bool check_mouse_face = false;
26692 int dummy_x = 0;
26694 /* If mouse highlighting is on, we may need to draw adjacent
26695 glyphs using mouse-face highlighting. */
26696 if (area == TEXT_AREA && row->mouse_face_p
26697 && hlinfo->mouse_face_beg_row >= 0
26698 && hlinfo->mouse_face_end_row >= 0)
26700 ptrdiff_t row_vpos = MATRIX_ROW_VPOS (row, w->current_matrix);
26702 if (row_vpos >= hlinfo->mouse_face_beg_row
26703 && row_vpos <= hlinfo->mouse_face_end_row)
26705 check_mouse_face = true;
26706 mouse_beg_col = (row_vpos == hlinfo->mouse_face_beg_row)
26707 ? hlinfo->mouse_face_beg_col : 0;
26708 mouse_end_col = (row_vpos == hlinfo->mouse_face_end_row)
26709 ? hlinfo->mouse_face_end_col
26710 : row->used[TEXT_AREA];
26714 /* Compute overhangs for all glyph strings. */
26715 if (FRAME_RIF (f)->compute_glyph_string_overhangs)
26716 for (s = head; s; s = s->next)
26717 FRAME_RIF (f)->compute_glyph_string_overhangs (s);
26719 /* Prepend glyph strings for glyphs in front of the first glyph
26720 string that are overwritten because of the first glyph
26721 string's left overhang. The background of all strings
26722 prepended must be drawn because the first glyph string
26723 draws over it. */
26724 i = left_overwritten (head);
26725 if (i >= 0)
26727 enum draw_glyphs_face overlap_hl;
26729 /* If this row contains mouse highlighting, attempt to draw
26730 the overlapped glyphs with the correct highlight. This
26731 code fails if the overlap encompasses more than one glyph
26732 and mouse-highlight spans only some of these glyphs.
26733 However, making it work perfectly involves a lot more
26734 code, and I don't know if the pathological case occurs in
26735 practice, so we'll stick to this for now. --- cyd */
26736 if (check_mouse_face
26737 && mouse_beg_col < start && mouse_end_col > i)
26738 overlap_hl = DRAW_MOUSE_FACE;
26739 else
26740 overlap_hl = DRAW_NORMAL_TEXT;
26742 if (hl != overlap_hl)
26743 clip_head = head;
26744 j = i;
26745 BUILD_GLYPH_STRINGS (j, start, h, t,
26746 overlap_hl, dummy_x, last_x);
26747 start = i;
26748 compute_overhangs_and_x (t, head->x, true);
26749 prepend_glyph_string_lists (&head, &tail, h, t);
26750 if (clip_head == NULL)
26751 clip_head = head;
26754 /* Prepend glyph strings for glyphs in front of the first glyph
26755 string that overwrite that glyph string because of their
26756 right overhang. For these strings, only the foreground must
26757 be drawn, because it draws over the glyph string at `head'.
26758 The background must not be drawn because this would overwrite
26759 right overhangs of preceding glyphs for which no glyph
26760 strings exist. */
26761 i = left_overwriting (head);
26762 if (i >= 0)
26764 enum draw_glyphs_face overlap_hl;
26766 if (check_mouse_face
26767 && mouse_beg_col < start && mouse_end_col > i)
26768 overlap_hl = DRAW_MOUSE_FACE;
26769 else
26770 overlap_hl = DRAW_NORMAL_TEXT;
26772 if (hl == overlap_hl || clip_head == NULL)
26773 clip_head = head;
26774 BUILD_GLYPH_STRINGS (i, start, h, t,
26775 overlap_hl, dummy_x, last_x);
26776 for (s = h; s; s = s->next)
26777 s->background_filled_p = true;
26778 compute_overhangs_and_x (t, head->x, true);
26779 prepend_glyph_string_lists (&head, &tail, h, t);
26782 /* Append glyphs strings for glyphs following the last glyph
26783 string tail that are overwritten by tail. The background of
26784 these strings has to be drawn because tail's foreground draws
26785 over it. */
26786 i = right_overwritten (tail);
26787 if (i >= 0)
26789 enum draw_glyphs_face overlap_hl;
26791 if (check_mouse_face
26792 && mouse_beg_col < i && mouse_end_col > end)
26793 overlap_hl = DRAW_MOUSE_FACE;
26794 else
26795 overlap_hl = DRAW_NORMAL_TEXT;
26797 if (hl != overlap_hl)
26798 clip_tail = tail;
26799 BUILD_GLYPH_STRINGS (end, i, h, t,
26800 overlap_hl, x, last_x);
26801 /* Because BUILD_GLYPH_STRINGS updates the first argument,
26802 we don't have `end = i;' here. */
26803 compute_overhangs_and_x (h, tail->x + tail->width, false);
26804 append_glyph_string_lists (&head, &tail, h, t);
26805 if (clip_tail == NULL)
26806 clip_tail = tail;
26809 /* Append glyph strings for glyphs following the last glyph
26810 string tail that overwrite tail. The foreground of such
26811 glyphs has to be drawn because it writes into the background
26812 of tail. The background must not be drawn because it could
26813 paint over the foreground of following glyphs. */
26814 i = right_overwriting (tail);
26815 if (i >= 0)
26817 enum draw_glyphs_face overlap_hl;
26818 if (check_mouse_face
26819 && mouse_beg_col < i && mouse_end_col > end)
26820 overlap_hl = DRAW_MOUSE_FACE;
26821 else
26822 overlap_hl = DRAW_NORMAL_TEXT;
26824 if (hl == overlap_hl || clip_tail == NULL)
26825 clip_tail = tail;
26826 i++; /* We must include the Ith glyph. */
26827 BUILD_GLYPH_STRINGS (end, i, h, t,
26828 overlap_hl, x, last_x);
26829 for (s = h; s; s = s->next)
26830 s->background_filled_p = true;
26831 compute_overhangs_and_x (h, tail->x + tail->width, false);
26832 append_glyph_string_lists (&head, &tail, h, t);
26834 tail = glyph_string_containing_background_width (tail);
26835 if (clip_tail)
26836 clip_tail = glyph_string_containing_background_width (clip_tail);
26837 if (clip_head || clip_tail)
26838 for (s = head; s; s = s->next)
26840 s->clip_head = clip_head;
26841 s->clip_tail = clip_tail;
26845 /* Draw all strings. */
26846 for (s = head; s; s = s->next)
26847 FRAME_RIF (f)->draw_glyph_string (s);
26849 #ifndef HAVE_NS
26850 /* When focus a sole frame and move horizontally, this clears on_p
26851 causing a failure to erase prev cursor position. */
26852 if (area == TEXT_AREA
26853 && !row->full_width_p
26854 /* When drawing overlapping rows, only the glyph strings'
26855 foreground is drawn, which doesn't erase a cursor
26856 completely. */
26857 && !overlaps)
26859 int x0 = clip_head ? clip_head->x : (head ? head->x : x);
26860 int x1 = (clip_tail ? clip_tail->x + clip_tail->background_width
26861 : (tail ? tail->x + tail->background_width : x));
26862 x0 -= area_left;
26863 x1 -= area_left;
26865 notice_overwritten_cursor (w, TEXT_AREA, x0, x1,
26866 row->y, MATRIX_ROW_BOTTOM_Y (row));
26868 #endif
26870 /* Value is the x-position up to which drawn, relative to AREA of W.
26871 This doesn't include parts drawn because of overhangs. */
26872 if (row->full_width_p)
26873 x_reached = FRAME_TO_WINDOW_PIXEL_X (w, x_reached);
26874 else
26875 x_reached -= area_left;
26877 RELEASE_HDC (hdc, f);
26879 SAFE_FREE ();
26880 return x_reached;
26883 /* Find the first glyph in the run of underlined glyphs preceding the
26884 beginning of glyph string S, and return its font (which could be
26885 NULL). This is needed because that font determines the underline
26886 position and thickness for the entire run of the underlined glyphs.
26887 This function is called from the draw_glyph_string method of GUI
26888 frame's redisplay interface (RIF) when it needs to draw in an
26889 underlined face. */
26890 struct font *
26891 font_for_underline_metrics (struct glyph_string *s)
26893 struct glyph *g0 = s->row->glyphs[s->area], *g;
26895 for (g = s->first_glyph - 1; g >= g0; g--)
26897 struct face *prev_face = FACE_FROM_ID (s->f, g->face_id);
26898 if (!(prev_face && prev_face->underline_p))
26899 break;
26902 /* If preceding glyphs are not underlined, use the font of S. */
26903 if (g == s->first_glyph - 1)
26904 return s->font;
26905 else
26907 /* Otherwise use the font of the last glyph we saw in the above
26908 loop whose face had the underline_p flag set. */
26909 return FACE_FROM_ID (s->f, g[1].face_id)->font;
26913 /* Expand row matrix if too narrow. Don't expand if area
26914 is not present. */
26916 #define IT_EXPAND_MATRIX_WIDTH(it, area) \
26918 if (!it->f->fonts_changed \
26919 && (it->glyph_row->glyphs[area] \
26920 < it->glyph_row->glyphs[area + 1])) \
26922 it->w->ncols_scale_factor++; \
26923 it->f->fonts_changed = true; \
26927 /* Store one glyph for IT->char_to_display in IT->glyph_row.
26928 Called from x_produce_glyphs when IT->glyph_row is non-null. */
26930 static void
26931 append_glyph (struct it *it)
26933 struct glyph *glyph;
26934 enum glyph_row_area area = it->area;
26936 eassert (it->glyph_row);
26937 eassert (it->char_to_display != '\n' && it->char_to_display != '\t');
26939 glyph = it->glyph_row->glyphs[area] + it->glyph_row->used[area];
26940 if (glyph < it->glyph_row->glyphs[area + 1])
26942 /* If the glyph row is reversed, we need to prepend the glyph
26943 rather than append it. */
26944 if (it->glyph_row->reversed_p && area == TEXT_AREA)
26946 struct glyph *g;
26948 /* Make room for the additional glyph. */
26949 for (g = glyph - 1; g >= it->glyph_row->glyphs[area]; g--)
26950 g[1] = *g;
26951 glyph = it->glyph_row->glyphs[area];
26953 glyph->charpos = CHARPOS (it->position);
26954 glyph->object = it->object;
26955 if (it->pixel_width > 0)
26957 eassert (it->pixel_width <= SHRT_MAX);
26958 glyph->pixel_width = it->pixel_width;
26959 glyph->padding_p = false;
26961 else
26963 /* Assure at least 1-pixel width. Otherwise, cursor can't
26964 be displayed correctly. */
26965 glyph->pixel_width = 1;
26966 glyph->padding_p = true;
26968 glyph->ascent = it->ascent;
26969 glyph->descent = it->descent;
26970 glyph->voffset = it->voffset;
26971 glyph->type = CHAR_GLYPH;
26972 glyph->avoid_cursor_p = it->avoid_cursor_p;
26973 glyph->multibyte_p = it->multibyte_p;
26974 if (it->glyph_row->reversed_p && area == TEXT_AREA)
26976 /* In R2L rows, the left and the right box edges need to be
26977 drawn in reverse direction. */
26978 glyph->right_box_line_p = it->start_of_box_run_p;
26979 glyph->left_box_line_p = it->end_of_box_run_p;
26981 else
26983 glyph->left_box_line_p = it->start_of_box_run_p;
26984 glyph->right_box_line_p = it->end_of_box_run_p;
26986 glyph->overlaps_vertically_p = (it->phys_ascent > it->ascent
26987 || it->phys_descent > it->descent);
26988 glyph->glyph_not_available_p = it->glyph_not_available_p;
26989 glyph->face_id = it->face_id;
26990 glyph->u.ch = it->char_to_display;
26991 glyph->slice.img = null_glyph_slice;
26992 glyph->font_type = FONT_TYPE_UNKNOWN;
26993 if (it->bidi_p)
26995 glyph->resolved_level = it->bidi_it.resolved_level;
26996 eassert ((it->bidi_it.type & 7) == it->bidi_it.type);
26997 glyph->bidi_type = it->bidi_it.type;
26999 else
27001 glyph->resolved_level = 0;
27002 glyph->bidi_type = UNKNOWN_BT;
27004 ++it->glyph_row->used[area];
27006 else
27007 IT_EXPAND_MATRIX_WIDTH (it, area);
27010 /* Store one glyph for the composition IT->cmp_it.id in
27011 IT->glyph_row. Called from x_produce_glyphs when IT->glyph_row is
27012 non-null. */
27014 static void
27015 append_composite_glyph (struct it *it)
27017 struct glyph *glyph;
27018 enum glyph_row_area area = it->area;
27020 eassert (it->glyph_row);
27022 glyph = it->glyph_row->glyphs[area] + it->glyph_row->used[area];
27023 if (glyph < it->glyph_row->glyphs[area + 1])
27025 /* If the glyph row is reversed, we need to prepend the glyph
27026 rather than append it. */
27027 if (it->glyph_row->reversed_p && it->area == TEXT_AREA)
27029 struct glyph *g;
27031 /* Make room for the new glyph. */
27032 for (g = glyph - 1; g >= it->glyph_row->glyphs[it->area]; g--)
27033 g[1] = *g;
27034 glyph = it->glyph_row->glyphs[it->area];
27036 glyph->charpos = it->cmp_it.charpos;
27037 glyph->object = it->object;
27038 eassert (it->pixel_width <= SHRT_MAX);
27039 glyph->pixel_width = it->pixel_width;
27040 glyph->ascent = it->ascent;
27041 glyph->descent = it->descent;
27042 glyph->voffset = it->voffset;
27043 glyph->type = COMPOSITE_GLYPH;
27044 if (it->cmp_it.ch < 0)
27046 glyph->u.cmp.automatic = false;
27047 glyph->u.cmp.id = it->cmp_it.id;
27048 glyph->slice.cmp.from = glyph->slice.cmp.to = 0;
27050 else
27052 glyph->u.cmp.automatic = true;
27053 glyph->u.cmp.id = it->cmp_it.id;
27054 glyph->slice.cmp.from = it->cmp_it.from;
27055 glyph->slice.cmp.to = it->cmp_it.to - 1;
27057 glyph->avoid_cursor_p = it->avoid_cursor_p;
27058 glyph->multibyte_p = it->multibyte_p;
27059 if (it->glyph_row->reversed_p && area == TEXT_AREA)
27061 /* In R2L rows, the left and the right box edges need to be
27062 drawn in reverse direction. */
27063 glyph->right_box_line_p = it->start_of_box_run_p;
27064 glyph->left_box_line_p = it->end_of_box_run_p;
27066 else
27068 glyph->left_box_line_p = it->start_of_box_run_p;
27069 glyph->right_box_line_p = it->end_of_box_run_p;
27071 glyph->overlaps_vertically_p = (it->phys_ascent > it->ascent
27072 || it->phys_descent > it->descent);
27073 glyph->padding_p = false;
27074 glyph->glyph_not_available_p = false;
27075 glyph->face_id = it->face_id;
27076 glyph->font_type = FONT_TYPE_UNKNOWN;
27077 if (it->bidi_p)
27079 glyph->resolved_level = it->bidi_it.resolved_level;
27080 eassert ((it->bidi_it.type & 7) == it->bidi_it.type);
27081 glyph->bidi_type = it->bidi_it.type;
27083 ++it->glyph_row->used[area];
27085 else
27086 IT_EXPAND_MATRIX_WIDTH (it, area);
27090 /* Change IT->ascent and IT->height according to the setting of
27091 IT->voffset. */
27093 static void
27094 take_vertical_position_into_account (struct it *it)
27096 if (it->voffset)
27098 if (it->voffset < 0)
27099 /* Increase the ascent so that we can display the text higher
27100 in the line. */
27101 it->ascent -= it->voffset;
27102 else
27103 /* Increase the descent so that we can display the text lower
27104 in the line. */
27105 it->descent += it->voffset;
27110 /* Produce glyphs/get display metrics for the image IT is loaded with.
27111 See the description of struct display_iterator in dispextern.h for
27112 an overview of struct display_iterator. */
27114 static void
27115 produce_image_glyph (struct it *it)
27117 struct image *img;
27118 struct face *face;
27119 int glyph_ascent, crop;
27120 struct glyph_slice slice;
27122 eassert (it->what == IT_IMAGE);
27124 face = FACE_FROM_ID (it->f, it->face_id);
27125 /* Make sure X resources of the face is loaded. */
27126 prepare_face_for_display (it->f, face);
27128 if (it->image_id < 0)
27130 /* Fringe bitmap. */
27131 it->ascent = it->phys_ascent = 0;
27132 it->descent = it->phys_descent = 0;
27133 it->pixel_width = 0;
27134 it->nglyphs = 0;
27135 return;
27138 img = IMAGE_FROM_ID (it->f, it->image_id);
27139 /* Make sure X resources of the image is loaded. */
27140 prepare_image_for_display (it->f, img);
27142 slice.x = slice.y = 0;
27143 slice.width = img->width;
27144 slice.height = img->height;
27146 if (INTEGERP (it->slice.x))
27147 slice.x = XINT (it->slice.x);
27148 else if (FLOATP (it->slice.x))
27149 slice.x = XFLOAT_DATA (it->slice.x) * img->width;
27151 if (INTEGERP (it->slice.y))
27152 slice.y = XINT (it->slice.y);
27153 else if (FLOATP (it->slice.y))
27154 slice.y = XFLOAT_DATA (it->slice.y) * img->height;
27156 if (INTEGERP (it->slice.width))
27157 slice.width = XINT (it->slice.width);
27158 else if (FLOATP (it->slice.width))
27159 slice.width = XFLOAT_DATA (it->slice.width) * img->width;
27161 if (INTEGERP (it->slice.height))
27162 slice.height = XINT (it->slice.height);
27163 else if (FLOATP (it->slice.height))
27164 slice.height = XFLOAT_DATA (it->slice.height) * img->height;
27166 if (slice.x >= img->width)
27167 slice.x = img->width;
27168 if (slice.y >= img->height)
27169 slice.y = img->height;
27170 if (slice.x + slice.width >= img->width)
27171 slice.width = img->width - slice.x;
27172 if (slice.y + slice.height > img->height)
27173 slice.height = img->height - slice.y;
27175 if (slice.width == 0 || slice.height == 0)
27176 return;
27178 it->ascent = it->phys_ascent = glyph_ascent = image_ascent (img, face, &slice);
27180 it->descent = slice.height - glyph_ascent;
27181 if (slice.y == 0)
27182 it->descent += img->vmargin;
27183 if (slice.y + slice.height == img->height)
27184 it->descent += img->vmargin;
27185 it->phys_descent = it->descent;
27187 it->pixel_width = slice.width;
27188 if (slice.x == 0)
27189 it->pixel_width += img->hmargin;
27190 if (slice.x + slice.width == img->width)
27191 it->pixel_width += img->hmargin;
27193 /* It's quite possible for images to have an ascent greater than
27194 their height, so don't get confused in that case. */
27195 if (it->descent < 0)
27196 it->descent = 0;
27198 it->nglyphs = 1;
27200 if (face->box != FACE_NO_BOX)
27202 if (face->box_line_width > 0)
27204 if (slice.y == 0)
27205 it->ascent += face->box_line_width;
27206 if (slice.y + slice.height == img->height)
27207 it->descent += face->box_line_width;
27210 if (it->start_of_box_run_p && slice.x == 0)
27211 it->pixel_width += eabs (face->box_line_width);
27212 if (it->end_of_box_run_p && slice.x + slice.width == img->width)
27213 it->pixel_width += eabs (face->box_line_width);
27216 take_vertical_position_into_account (it);
27218 /* Automatically crop wide image glyphs at right edge so we can
27219 draw the cursor on same display row. */
27220 if ((crop = it->pixel_width - (it->last_visible_x - it->current_x), crop > 0)
27221 && (it->hpos == 0 || it->pixel_width > it->last_visible_x / 4))
27223 it->pixel_width -= crop;
27224 slice.width -= crop;
27227 if (it->glyph_row)
27229 struct glyph *glyph;
27230 enum glyph_row_area area = it->area;
27232 glyph = it->glyph_row->glyphs[area] + it->glyph_row->used[area];
27233 if (it->glyph_row->reversed_p)
27235 struct glyph *g;
27237 /* Make room for the new glyph. */
27238 for (g = glyph - 1; g >= it->glyph_row->glyphs[it->area]; g--)
27239 g[1] = *g;
27240 glyph = it->glyph_row->glyphs[it->area];
27242 if (glyph < it->glyph_row->glyphs[area + 1])
27244 glyph->charpos = CHARPOS (it->position);
27245 glyph->object = it->object;
27246 glyph->pixel_width = clip_to_bounds (-1, it->pixel_width, SHRT_MAX);
27247 glyph->ascent = glyph_ascent;
27248 glyph->descent = it->descent;
27249 glyph->voffset = it->voffset;
27250 glyph->type = IMAGE_GLYPH;
27251 glyph->avoid_cursor_p = it->avoid_cursor_p;
27252 glyph->multibyte_p = it->multibyte_p;
27253 if (it->glyph_row->reversed_p && area == TEXT_AREA)
27255 /* In R2L rows, the left and the right box edges need to be
27256 drawn in reverse direction. */
27257 glyph->right_box_line_p = it->start_of_box_run_p;
27258 glyph->left_box_line_p = it->end_of_box_run_p;
27260 else
27262 glyph->left_box_line_p = it->start_of_box_run_p;
27263 glyph->right_box_line_p = it->end_of_box_run_p;
27265 glyph->overlaps_vertically_p = false;
27266 glyph->padding_p = false;
27267 glyph->glyph_not_available_p = false;
27268 glyph->face_id = it->face_id;
27269 glyph->u.img_id = img->id;
27270 glyph->slice.img = slice;
27271 glyph->font_type = FONT_TYPE_UNKNOWN;
27272 if (it->bidi_p)
27274 glyph->resolved_level = it->bidi_it.resolved_level;
27275 eassert ((it->bidi_it.type & 7) == it->bidi_it.type);
27276 glyph->bidi_type = it->bidi_it.type;
27278 ++it->glyph_row->used[area];
27280 else
27281 IT_EXPAND_MATRIX_WIDTH (it, area);
27285 static void
27286 produce_xwidget_glyph (struct it *it)
27288 #ifdef HAVE_XWIDGETS
27289 struct xwidget *xw;
27290 int glyph_ascent, crop;
27291 eassert (it->what == IT_XWIDGET);
27293 struct face *face = FACE_FROM_ID (it->f, it->face_id);
27294 /* Make sure X resources of the face is loaded. */
27295 prepare_face_for_display (it->f, face);
27297 xw = it->xwidget;
27298 it->ascent = it->phys_ascent = glyph_ascent = xw->height/2;
27299 it->descent = xw->height/2;
27300 it->phys_descent = it->descent;
27301 it->pixel_width = xw->width;
27302 /* It's quite possible for images to have an ascent greater than
27303 their height, so don't get confused in that case. */
27304 if (it->descent < 0)
27305 it->descent = 0;
27307 it->nglyphs = 1;
27309 if (face->box != FACE_NO_BOX)
27311 if (face->box_line_width > 0)
27313 it->ascent += face->box_line_width;
27314 it->descent += face->box_line_width;
27317 if (it->start_of_box_run_p)
27318 it->pixel_width += eabs (face->box_line_width);
27319 it->pixel_width += eabs (face->box_line_width);
27322 take_vertical_position_into_account (it);
27324 /* Automatically crop wide image glyphs at right edge so we can
27325 draw the cursor on same display row. */
27326 crop = it->pixel_width - (it->last_visible_x - it->current_x);
27327 if (crop > 0 && (it->hpos == 0 || it->pixel_width > it->last_visible_x / 4))
27328 it->pixel_width -= crop;
27330 if (it->glyph_row)
27332 enum glyph_row_area area = it->area;
27333 struct glyph *glyph
27334 = it->glyph_row->glyphs[area] + it->glyph_row->used[area];
27336 if (it->glyph_row->reversed_p)
27338 struct glyph *g;
27340 /* Make room for the new glyph. */
27341 for (g = glyph - 1; g >= it->glyph_row->glyphs[it->area]; g--)
27342 g[1] = *g;
27343 glyph = it->glyph_row->glyphs[it->area];
27345 if (glyph < it->glyph_row->glyphs[area + 1])
27347 glyph->charpos = CHARPOS (it->position);
27348 glyph->object = it->object;
27349 glyph->pixel_width = clip_to_bounds (-1, it->pixel_width, SHRT_MAX);
27350 glyph->ascent = glyph_ascent;
27351 glyph->descent = it->descent;
27352 glyph->voffset = it->voffset;
27353 glyph->type = XWIDGET_GLYPH;
27354 glyph->avoid_cursor_p = it->avoid_cursor_p;
27355 glyph->multibyte_p = it->multibyte_p;
27356 if (it->glyph_row->reversed_p && area == TEXT_AREA)
27358 /* In R2L rows, the left and the right box edges need to be
27359 drawn in reverse direction. */
27360 glyph->right_box_line_p = it->start_of_box_run_p;
27361 glyph->left_box_line_p = it->end_of_box_run_p;
27363 else
27365 glyph->left_box_line_p = it->start_of_box_run_p;
27366 glyph->right_box_line_p = it->end_of_box_run_p;
27368 glyph->overlaps_vertically_p = 0;
27369 glyph->padding_p = 0;
27370 glyph->glyph_not_available_p = 0;
27371 glyph->face_id = it->face_id;
27372 glyph->u.xwidget = it->xwidget;
27373 glyph->font_type = FONT_TYPE_UNKNOWN;
27374 if (it->bidi_p)
27376 glyph->resolved_level = it->bidi_it.resolved_level;
27377 eassert ((it->bidi_it.type & 7) == it->bidi_it.type);
27378 glyph->bidi_type = it->bidi_it.type;
27380 ++it->glyph_row->used[area];
27382 else
27383 IT_EXPAND_MATRIX_WIDTH (it, area);
27385 #endif
27388 /* Append a stretch glyph to IT->glyph_row. OBJECT is the source
27389 of the glyph, WIDTH and HEIGHT are the width and height of the
27390 stretch. ASCENT is the ascent of the glyph (0 <= ASCENT <= HEIGHT). */
27392 static void
27393 append_stretch_glyph (struct it *it, Lisp_Object object,
27394 int width, int height, int ascent)
27396 struct glyph *glyph;
27397 enum glyph_row_area area = it->area;
27399 eassert (ascent >= 0 && ascent <= height);
27401 glyph = it->glyph_row->glyphs[area] + it->glyph_row->used[area];
27402 if (glyph < it->glyph_row->glyphs[area + 1])
27404 /* If the glyph row is reversed, we need to prepend the glyph
27405 rather than append it. */
27406 if (it->glyph_row->reversed_p && area == TEXT_AREA)
27408 struct glyph *g;
27410 /* Make room for the additional glyph. */
27411 for (g = glyph - 1; g >= it->glyph_row->glyphs[area]; g--)
27412 g[1] = *g;
27413 glyph = it->glyph_row->glyphs[area];
27415 /* Decrease the width of the first glyph of the row that
27416 begins before first_visible_x (e.g., due to hscroll).
27417 This is so the overall width of the row becomes smaller
27418 by the scroll amount, and the stretch glyph appended by
27419 extend_face_to_end_of_line will be wider, to shift the
27420 row glyphs to the right. (In L2R rows, the corresponding
27421 left-shift effect is accomplished by setting row->x to a
27422 negative value, which won't work with R2L rows.)
27424 This must leave us with a positive value of WIDTH, since
27425 otherwise the call to move_it_in_display_line_to at the
27426 beginning of display_line would have got past the entire
27427 first glyph, and then it->current_x would have been
27428 greater or equal to it->first_visible_x. */
27429 if (it->current_x < it->first_visible_x)
27430 width -= it->first_visible_x - it->current_x;
27431 eassert (width > 0);
27433 glyph->charpos = CHARPOS (it->position);
27434 glyph->object = object;
27435 /* FIXME: It would be better to use TYPE_MAX here, but
27436 __typeof__ is not portable enough... */
27437 glyph->pixel_width = clip_to_bounds (-1, width, SHRT_MAX);
27438 glyph->ascent = ascent;
27439 glyph->descent = height - ascent;
27440 glyph->voffset = it->voffset;
27441 glyph->type = STRETCH_GLYPH;
27442 glyph->avoid_cursor_p = it->avoid_cursor_p;
27443 glyph->multibyte_p = it->multibyte_p;
27444 if (it->glyph_row->reversed_p && area == TEXT_AREA)
27446 /* In R2L rows, the left and the right box edges need to be
27447 drawn in reverse direction. */
27448 glyph->right_box_line_p = it->start_of_box_run_p;
27449 glyph->left_box_line_p = it->end_of_box_run_p;
27451 else
27453 glyph->left_box_line_p = it->start_of_box_run_p;
27454 glyph->right_box_line_p = it->end_of_box_run_p;
27456 glyph->overlaps_vertically_p = false;
27457 glyph->padding_p = false;
27458 glyph->glyph_not_available_p = false;
27459 glyph->face_id = it->face_id;
27460 glyph->u.stretch.ascent = ascent;
27461 glyph->u.stretch.height = height;
27462 glyph->slice.img = null_glyph_slice;
27463 glyph->font_type = FONT_TYPE_UNKNOWN;
27464 if (it->bidi_p)
27466 glyph->resolved_level = it->bidi_it.resolved_level;
27467 eassert ((it->bidi_it.type & 7) == it->bidi_it.type);
27468 glyph->bidi_type = it->bidi_it.type;
27470 else
27472 glyph->resolved_level = 0;
27473 glyph->bidi_type = UNKNOWN_BT;
27475 ++it->glyph_row->used[area];
27477 else
27478 IT_EXPAND_MATRIX_WIDTH (it, area);
27481 #endif /* HAVE_WINDOW_SYSTEM */
27483 /* Produce a stretch glyph for iterator IT. IT->object is the value
27484 of the glyph property displayed. The value must be a list
27485 `(space KEYWORD VALUE ...)' with the following KEYWORD/VALUE pairs
27486 being recognized:
27488 1. `:width WIDTH' specifies that the space should be WIDTH *
27489 canonical char width wide. WIDTH may be an integer or floating
27490 point number.
27492 2. `:relative-width FACTOR' specifies that the width of the stretch
27493 should be computed from the width of the first character having the
27494 `glyph' property, and should be FACTOR times that width.
27496 3. `:align-to HPOS' specifies that the space should be wide enough
27497 to reach HPOS, a value in canonical character units.
27499 Exactly one of the above pairs must be present.
27501 4. `:height HEIGHT' specifies that the height of the stretch produced
27502 should be HEIGHT, measured in canonical character units.
27504 5. `:relative-height FACTOR' specifies that the height of the
27505 stretch should be FACTOR times the height of the characters having
27506 the glyph property.
27508 Either none or exactly one of 4 or 5 must be present.
27510 6. `:ascent ASCENT' specifies that ASCENT percent of the height
27511 of the stretch should be used for the ascent of the stretch.
27512 ASCENT must be in the range 0 <= ASCENT <= 100. */
27514 void
27515 produce_stretch_glyph (struct it *it)
27517 /* (space :width WIDTH :height HEIGHT ...) */
27518 Lisp_Object prop, plist;
27519 int width = 0, height = 0, align_to = -1;
27520 bool zero_width_ok_p = false;
27521 double tem;
27522 struct font *font = NULL;
27524 #ifdef HAVE_WINDOW_SYSTEM
27525 int ascent = 0;
27526 bool zero_height_ok_p = false;
27528 if (FRAME_WINDOW_P (it->f))
27530 struct face *face = FACE_FROM_ID (it->f, it->face_id);
27531 font = face->font ? face->font : FRAME_FONT (it->f);
27532 prepare_face_for_display (it->f, face);
27534 #endif
27536 /* List should start with `space'. */
27537 eassert (CONSP (it->object) && EQ (XCAR (it->object), Qspace));
27538 plist = XCDR (it->object);
27540 /* Compute the width of the stretch. */
27541 if ((prop = Fplist_get (plist, QCwidth), !NILP (prop))
27542 && calc_pixel_width_or_height (&tem, it, prop, font, true, 0))
27544 /* Absolute width `:width WIDTH' specified and valid. */
27545 zero_width_ok_p = true;
27546 width = (int)tem;
27548 else if (prop = Fplist_get (plist, QCrelative_width), NUMVAL (prop) > 0)
27550 /* Relative width `:relative-width FACTOR' specified and valid.
27551 Compute the width of the characters having the `glyph'
27552 property. */
27553 struct it it2;
27554 unsigned char *p = BYTE_POS_ADDR (IT_BYTEPOS (*it));
27556 it2 = *it;
27557 if (it->multibyte_p)
27558 it2.c = it2.char_to_display = STRING_CHAR_AND_LENGTH (p, it2.len);
27559 else
27561 it2.c = it2.char_to_display = *p, it2.len = 1;
27562 if (! ASCII_CHAR_P (it2.c))
27563 it2.char_to_display = BYTE8_TO_CHAR (it2.c);
27566 it2.glyph_row = NULL;
27567 it2.what = IT_CHARACTER;
27568 PRODUCE_GLYPHS (&it2);
27569 width = NUMVAL (prop) * it2.pixel_width;
27571 else if ((prop = Fplist_get (plist, QCalign_to), !NILP (prop))
27572 && calc_pixel_width_or_height (&tem, it, prop, font, true,
27573 &align_to))
27575 if (it->glyph_row == NULL || !it->glyph_row->mode_line_p)
27576 align_to = (align_to < 0
27578 : align_to - window_box_left_offset (it->w, TEXT_AREA));
27579 else if (align_to < 0)
27580 align_to = window_box_left_offset (it->w, TEXT_AREA);
27581 width = max (0, (int)tem + align_to - it->current_x);
27582 zero_width_ok_p = true;
27584 else
27585 /* Nothing specified -> width defaults to canonical char width. */
27586 width = FRAME_COLUMN_WIDTH (it->f);
27588 if (width <= 0 && (width < 0 || !zero_width_ok_p))
27589 width = 1;
27591 #ifdef HAVE_WINDOW_SYSTEM
27592 /* Compute height. */
27593 if (FRAME_WINDOW_P (it->f))
27595 int default_height = normal_char_height (font, ' ');
27597 if ((prop = Fplist_get (plist, QCheight), !NILP (prop))
27598 && calc_pixel_width_or_height (&tem, it, prop, font, false, 0))
27600 height = (int)tem;
27601 zero_height_ok_p = true;
27603 else if (prop = Fplist_get (plist, QCrelative_height),
27604 NUMVAL (prop) > 0)
27605 height = default_height * NUMVAL (prop);
27606 else
27607 height = default_height;
27609 if (height <= 0 && (height < 0 || !zero_height_ok_p))
27610 height = 1;
27612 /* Compute percentage of height used for ascent. If
27613 `:ascent ASCENT' is present and valid, use that. Otherwise,
27614 derive the ascent from the font in use. */
27615 if (prop = Fplist_get (plist, QCascent),
27616 NUMVAL (prop) > 0 && NUMVAL (prop) <= 100)
27617 ascent = height * NUMVAL (prop) / 100.0;
27618 else if (!NILP (prop)
27619 && calc_pixel_width_or_height (&tem, it, prop, font, false, 0))
27620 ascent = min (max (0, (int)tem), height);
27621 else
27622 ascent = (height * FONT_BASE (font)) / FONT_HEIGHT (font);
27624 else
27625 #endif /* HAVE_WINDOW_SYSTEM */
27626 height = 1;
27628 if (width > 0 && it->line_wrap != TRUNCATE
27629 && it->current_x + width > it->last_visible_x)
27631 width = it->last_visible_x - it->current_x;
27632 #ifdef HAVE_WINDOW_SYSTEM
27633 /* Subtract one more pixel from the stretch width, but only on
27634 GUI frames, since on a TTY each glyph is one "pixel" wide. */
27635 width -= FRAME_WINDOW_P (it->f);
27636 #endif
27639 if (width > 0 && height > 0 && it->glyph_row)
27641 Lisp_Object o_object = it->object;
27642 Lisp_Object object = it->stack[it->sp - 1].string;
27643 int n = width;
27645 if (!STRINGP (object))
27646 object = it->w->contents;
27647 #ifdef HAVE_WINDOW_SYSTEM
27648 if (FRAME_WINDOW_P (it->f))
27649 append_stretch_glyph (it, object, width, height, ascent);
27650 else
27651 #endif
27653 it->object = object;
27654 it->char_to_display = ' ';
27655 it->pixel_width = it->len = 1;
27656 while (n--)
27657 tty_append_glyph (it);
27658 it->object = o_object;
27662 it->pixel_width = width;
27663 #ifdef HAVE_WINDOW_SYSTEM
27664 if (FRAME_WINDOW_P (it->f))
27666 it->ascent = it->phys_ascent = ascent;
27667 it->descent = it->phys_descent = height - it->ascent;
27668 it->nglyphs = width > 0 && height > 0;
27669 take_vertical_position_into_account (it);
27671 else
27672 #endif
27673 it->nglyphs = width;
27676 /* Get information about special display element WHAT in an
27677 environment described by IT. WHAT is one of IT_TRUNCATION or
27678 IT_CONTINUATION. Maybe produce glyphs for WHAT if IT has a
27679 non-null glyph_row member. This function ensures that fields like
27680 face_id, c, len of IT are left untouched. */
27682 static void
27683 produce_special_glyphs (struct it *it, enum display_element_type what)
27685 struct it temp_it;
27686 Lisp_Object gc;
27687 GLYPH glyph;
27689 temp_it = *it;
27690 temp_it.object = Qnil;
27691 memset (&temp_it.current, 0, sizeof temp_it.current);
27693 if (what == IT_CONTINUATION)
27695 /* Continuation glyph. For R2L lines, we mirror it by hand. */
27696 if (it->bidi_it.paragraph_dir == R2L)
27697 SET_GLYPH_FROM_CHAR (glyph, '/');
27698 else
27699 SET_GLYPH_FROM_CHAR (glyph, '\\');
27700 if (it->dp
27701 && (gc = DISP_CONTINUE_GLYPH (it->dp), GLYPH_CODE_P (gc)))
27703 /* FIXME: Should we mirror GC for R2L lines? */
27704 SET_GLYPH_FROM_GLYPH_CODE (glyph, gc);
27705 spec_glyph_lookup_face (XWINDOW (it->window), &glyph);
27708 else if (what == IT_TRUNCATION)
27710 /* Truncation glyph. */
27711 SET_GLYPH_FROM_CHAR (glyph, '$');
27712 if (it->dp
27713 && (gc = DISP_TRUNC_GLYPH (it->dp), GLYPH_CODE_P (gc)))
27715 /* FIXME: Should we mirror GC for R2L lines? */
27716 SET_GLYPH_FROM_GLYPH_CODE (glyph, gc);
27717 spec_glyph_lookup_face (XWINDOW (it->window), &glyph);
27720 else
27721 emacs_abort ();
27723 #ifdef HAVE_WINDOW_SYSTEM
27724 /* On a GUI frame, when the right fringe (left fringe for R2L rows)
27725 is turned off, we precede the truncation/continuation glyphs by a
27726 stretch glyph whose width is computed such that these special
27727 glyphs are aligned at the window margin, even when very different
27728 fonts are used in different glyph rows. */
27729 if (FRAME_WINDOW_P (temp_it.f)
27730 /* init_iterator calls this with it->glyph_row == NULL, and it
27731 wants only the pixel width of the truncation/continuation
27732 glyphs. */
27733 && temp_it.glyph_row
27734 /* insert_left_trunc_glyphs calls us at the beginning of the
27735 row, and it has its own calculation of the stretch glyph
27736 width. */
27737 && temp_it.glyph_row->used[TEXT_AREA] > 0
27738 && (temp_it.glyph_row->reversed_p
27739 ? WINDOW_LEFT_FRINGE_WIDTH (temp_it.w)
27740 : WINDOW_RIGHT_FRINGE_WIDTH (temp_it.w)) == 0)
27742 int stretch_width = temp_it.last_visible_x - temp_it.current_x;
27744 if (stretch_width > 0)
27746 struct face *face = FACE_FROM_ID (temp_it.f, temp_it.face_id);
27747 struct font *font =
27748 face->font ? face->font : FRAME_FONT (temp_it.f);
27749 int stretch_ascent =
27750 (((temp_it.ascent + temp_it.descent)
27751 * FONT_BASE (font)) / FONT_HEIGHT (font));
27753 append_stretch_glyph (&temp_it, Qnil, stretch_width,
27754 temp_it.ascent + temp_it.descent,
27755 stretch_ascent);
27758 #endif
27760 temp_it.dp = NULL;
27761 temp_it.what = IT_CHARACTER;
27762 temp_it.c = temp_it.char_to_display = GLYPH_CHAR (glyph);
27763 temp_it.face_id = GLYPH_FACE (glyph);
27764 temp_it.len = CHAR_BYTES (temp_it.c);
27766 PRODUCE_GLYPHS (&temp_it);
27767 it->pixel_width = temp_it.pixel_width;
27768 it->nglyphs = temp_it.nglyphs;
27771 #ifdef HAVE_WINDOW_SYSTEM
27773 /* Calculate line-height and line-spacing properties.
27774 An integer value specifies explicit pixel value.
27775 A float value specifies relative value to current face height.
27776 A cons (float . face-name) specifies relative value to
27777 height of specified face font.
27779 Returns height in pixels, or nil. */
27781 static Lisp_Object
27782 calc_line_height_property (struct it *it, Lisp_Object val, struct font *font,
27783 int boff, bool override)
27785 Lisp_Object face_name = Qnil;
27786 int ascent, descent, height;
27788 if (NILP (val) || INTEGERP (val) || (override && EQ (val, Qt)))
27789 return val;
27791 if (CONSP (val))
27793 face_name = XCAR (val);
27794 val = XCDR (val);
27795 if (!NUMBERP (val))
27796 val = make_number (1);
27797 if (NILP (face_name))
27799 height = it->ascent + it->descent;
27800 goto scale;
27804 if (NILP (face_name))
27806 font = FRAME_FONT (it->f);
27807 boff = FRAME_BASELINE_OFFSET (it->f);
27809 else if (EQ (face_name, Qt))
27811 override = false;
27813 else
27815 int face_id;
27816 struct face *face;
27818 face_id = lookup_named_face (it->f, face_name, false);
27819 face = FACE_FROM_ID_OR_NULL (it->f, face_id);
27820 if (face == NULL || ((font = face->font) == NULL))
27821 return make_number (-1);
27822 boff = font->baseline_offset;
27823 if (font->vertical_centering)
27824 boff = VCENTER_BASELINE_OFFSET (font, it->f) - boff;
27827 normal_char_ascent_descent (font, -1, &ascent, &descent);
27829 if (override)
27831 it->override_ascent = ascent;
27832 it->override_descent = descent;
27833 it->override_boff = boff;
27836 height = ascent + descent;
27838 scale:
27839 if (FLOATP (val))
27840 height = (int)(XFLOAT_DATA (val) * height);
27841 else if (INTEGERP (val))
27842 height *= XINT (val);
27844 return make_number (height);
27848 /* Append a glyph for a glyphless character to IT->glyph_row. FACE_ID
27849 is a face ID to be used for the glyph. FOR_NO_FONT is true if
27850 and only if this is for a character for which no font was found.
27852 If the display method (it->glyphless_method) is
27853 GLYPHLESS_DISPLAY_ACRONYM or GLYPHLESS_DISPLAY_HEX_CODE, LEN is a
27854 length of the acronym or the hexadecimal string, UPPER_XOFF and
27855 UPPER_YOFF are pixel offsets for the upper part of the string,
27856 LOWER_XOFF and LOWER_YOFF are for the lower part.
27858 For the other display methods, LEN through LOWER_YOFF are zero. */
27860 static void
27861 append_glyphless_glyph (struct it *it, int face_id, bool for_no_font, int len,
27862 short upper_xoff, short upper_yoff,
27863 short lower_xoff, short lower_yoff)
27865 struct glyph *glyph;
27866 enum glyph_row_area area = it->area;
27868 glyph = it->glyph_row->glyphs[area] + it->glyph_row->used[area];
27869 if (glyph < it->glyph_row->glyphs[area + 1])
27871 /* If the glyph row is reversed, we need to prepend the glyph
27872 rather than append it. */
27873 if (it->glyph_row->reversed_p && area == TEXT_AREA)
27875 struct glyph *g;
27877 /* Make room for the additional glyph. */
27878 for (g = glyph - 1; g >= it->glyph_row->glyphs[area]; g--)
27879 g[1] = *g;
27880 glyph = it->glyph_row->glyphs[area];
27882 glyph->charpos = CHARPOS (it->position);
27883 glyph->object = it->object;
27884 eassert (it->pixel_width <= SHRT_MAX);
27885 glyph->pixel_width = it->pixel_width;
27886 glyph->ascent = it->ascent;
27887 glyph->descent = it->descent;
27888 glyph->voffset = it->voffset;
27889 glyph->type = GLYPHLESS_GLYPH;
27890 glyph->u.glyphless.method = it->glyphless_method;
27891 glyph->u.glyphless.for_no_font = for_no_font;
27892 glyph->u.glyphless.len = len;
27893 glyph->u.glyphless.ch = it->c;
27894 glyph->slice.glyphless.upper_xoff = upper_xoff;
27895 glyph->slice.glyphless.upper_yoff = upper_yoff;
27896 glyph->slice.glyphless.lower_xoff = lower_xoff;
27897 glyph->slice.glyphless.lower_yoff = lower_yoff;
27898 glyph->avoid_cursor_p = it->avoid_cursor_p;
27899 glyph->multibyte_p = it->multibyte_p;
27900 if (it->glyph_row->reversed_p && area == TEXT_AREA)
27902 /* In R2L rows, the left and the right box edges need to be
27903 drawn in reverse direction. */
27904 glyph->right_box_line_p = it->start_of_box_run_p;
27905 glyph->left_box_line_p = it->end_of_box_run_p;
27907 else
27909 glyph->left_box_line_p = it->start_of_box_run_p;
27910 glyph->right_box_line_p = it->end_of_box_run_p;
27912 glyph->overlaps_vertically_p = (it->phys_ascent > it->ascent
27913 || it->phys_descent > it->descent);
27914 glyph->padding_p = false;
27915 glyph->glyph_not_available_p = false;
27916 glyph->face_id = face_id;
27917 glyph->font_type = FONT_TYPE_UNKNOWN;
27918 if (it->bidi_p)
27920 glyph->resolved_level = it->bidi_it.resolved_level;
27921 eassert ((it->bidi_it.type & 7) == it->bidi_it.type);
27922 glyph->bidi_type = it->bidi_it.type;
27924 ++it->glyph_row->used[area];
27926 else
27927 IT_EXPAND_MATRIX_WIDTH (it, area);
27931 /* Produce a glyph for a glyphless character for iterator IT.
27932 IT->glyphless_method specifies which method to use for displaying
27933 the character. See the description of enum
27934 glyphless_display_method in dispextern.h for the detail.
27936 FOR_NO_FONT is true if and only if this is for a character for
27937 which no font was found. ACRONYM, if non-nil, is an acronym string
27938 for the character. */
27940 static void
27941 produce_glyphless_glyph (struct it *it, bool for_no_font, Lisp_Object acronym)
27943 int face_id;
27944 struct face *face;
27945 struct font *font;
27946 int base_width, base_height, width, height;
27947 short upper_xoff, upper_yoff, lower_xoff, lower_yoff;
27948 int len;
27950 /* Get the metrics of the base font. We always refer to the current
27951 ASCII face. */
27952 face = FACE_FROM_ID (it->f, it->face_id)->ascii_face;
27953 font = face->font ? face->font : FRAME_FONT (it->f);
27954 normal_char_ascent_descent (font, -1, &it->ascent, &it->descent);
27955 it->ascent += font->baseline_offset;
27956 it->descent -= font->baseline_offset;
27957 base_height = it->ascent + it->descent;
27958 base_width = font->average_width;
27960 face_id = merge_glyphless_glyph_face (it);
27962 if (it->glyphless_method == GLYPHLESS_DISPLAY_THIN_SPACE)
27964 it->pixel_width = THIN_SPACE_WIDTH;
27965 len = 0;
27966 upper_xoff = upper_yoff = lower_xoff = lower_yoff = 0;
27968 else if (it->glyphless_method == GLYPHLESS_DISPLAY_EMPTY_BOX)
27970 width = CHARACTER_WIDTH (it->c);
27971 if (width == 0)
27972 width = 1;
27973 else if (width > 4)
27974 width = 4;
27975 it->pixel_width = base_width * width;
27976 len = 0;
27977 upper_xoff = upper_yoff = lower_xoff = lower_yoff = 0;
27979 else
27981 char buf[7];
27982 const char *str;
27983 unsigned int code[6];
27984 int upper_len;
27985 int ascent, descent;
27986 struct font_metrics metrics_upper, metrics_lower;
27988 face = FACE_FROM_ID (it->f, face_id);
27989 font = face->font ? face->font : FRAME_FONT (it->f);
27990 prepare_face_for_display (it->f, face);
27992 if (it->glyphless_method == GLYPHLESS_DISPLAY_ACRONYM)
27994 if (! STRINGP (acronym) && CHAR_TABLE_P (Vglyphless_char_display))
27995 acronym = CHAR_TABLE_REF (Vglyphless_char_display, it->c);
27996 if (CONSP (acronym))
27997 acronym = XCAR (acronym);
27998 str = STRINGP (acronym) ? SSDATA (acronym) : "";
28000 else
28002 eassert (it->glyphless_method == GLYPHLESS_DISPLAY_HEX_CODE);
28003 sprintf (buf, "%0*X", it->c < 0x10000 ? 4 : 6, it->c + 0u);
28004 str = buf;
28006 for (len = 0; str[len] && ASCII_CHAR_P (str[len]) && len < 6; len++)
28007 code[len] = font->driver->encode_char (font, str[len]);
28008 upper_len = (len + 1) / 2;
28009 font->driver->text_extents (font, code, upper_len,
28010 &metrics_upper);
28011 font->driver->text_extents (font, code + upper_len, len - upper_len,
28012 &metrics_lower);
28016 /* +4 is for vertical bars of a box plus 1-pixel spaces at both side. */
28017 width = max (metrics_upper.width, metrics_lower.width) + 4;
28018 upper_xoff = upper_yoff = 2; /* the typical case */
28019 if (base_width >= width)
28021 /* Align the upper to the left, the lower to the right. */
28022 it->pixel_width = base_width;
28023 lower_xoff = base_width - 2 - metrics_lower.width;
28025 else
28027 /* Center the shorter one. */
28028 it->pixel_width = width;
28029 if (metrics_upper.width >= metrics_lower.width)
28030 lower_xoff = (width - metrics_lower.width) / 2;
28031 else
28033 /* FIXME: This code doesn't look right. It formerly was
28034 missing the "lower_xoff = 0;", which couldn't have
28035 been right since it left lower_xoff uninitialized. */
28036 lower_xoff = 0;
28037 upper_xoff = (width - metrics_upper.width) / 2;
28041 /* +5 is for horizontal bars of a box plus 1-pixel spaces at
28042 top, bottom, and between upper and lower strings. */
28043 height = (metrics_upper.ascent + metrics_upper.descent
28044 + metrics_lower.ascent + metrics_lower.descent) + 5;
28045 /* Center vertically.
28046 H:base_height, D:base_descent
28047 h:height, ld:lower_descent, la:lower_ascent, ud:upper_descent
28049 ascent = - (D - H/2 - h/2 + 1); "+ 1" for rounding up
28050 descent = D - H/2 + h/2;
28051 lower_yoff = descent - 2 - ld;
28052 upper_yoff = lower_yoff - la - 1 - ud; */
28053 ascent = - (it->descent - (base_height + height + 1) / 2);
28054 descent = it->descent - (base_height - height) / 2;
28055 lower_yoff = descent - 2 - metrics_lower.descent;
28056 upper_yoff = (lower_yoff - metrics_lower.ascent - 1
28057 - metrics_upper.descent);
28058 /* Don't make the height shorter than the base height. */
28059 if (height > base_height)
28061 it->ascent = ascent;
28062 it->descent = descent;
28066 it->phys_ascent = it->ascent;
28067 it->phys_descent = it->descent;
28068 if (it->glyph_row)
28069 append_glyphless_glyph (it, face_id, for_no_font, len,
28070 upper_xoff, upper_yoff,
28071 lower_xoff, lower_yoff);
28072 it->nglyphs = 1;
28073 take_vertical_position_into_account (it);
28077 /* RIF:
28078 Produce glyphs/get display metrics for the display element IT is
28079 loaded with. See the description of struct it in dispextern.h
28080 for an overview of struct it. */
28082 void
28083 x_produce_glyphs (struct it *it)
28085 int extra_line_spacing = it->extra_line_spacing;
28087 it->glyph_not_available_p = false;
28089 if (it->what == IT_CHARACTER)
28091 XChar2b char2b;
28092 struct face *face = FACE_FROM_ID (it->f, it->face_id);
28093 struct font *font = face->font;
28094 struct font_metrics *pcm = NULL;
28095 int boff; /* Baseline offset. */
28097 if (font == NULL)
28099 /* When no suitable font is found, display this character by
28100 the method specified in the first extra slot of
28101 Vglyphless_char_display. */
28102 Lisp_Object acronym = lookup_glyphless_char_display (-1, it);
28104 eassert (it->what == IT_GLYPHLESS);
28105 produce_glyphless_glyph (it, true,
28106 STRINGP (acronym) ? acronym : Qnil);
28107 goto done;
28110 boff = font->baseline_offset;
28111 if (font->vertical_centering)
28112 boff = VCENTER_BASELINE_OFFSET (font, it->f) - boff;
28114 if (it->char_to_display != '\n' && it->char_to_display != '\t')
28116 it->nglyphs = 1;
28118 if (it->override_ascent >= 0)
28120 it->ascent = it->override_ascent;
28121 it->descent = it->override_descent;
28122 boff = it->override_boff;
28124 else
28126 it->ascent = FONT_BASE (font) + boff;
28127 it->descent = FONT_DESCENT (font) - boff;
28130 if (get_char_glyph_code (it->char_to_display, font, &char2b))
28132 pcm = get_per_char_metric (font, &char2b);
28133 if (pcm->width == 0
28134 && pcm->rbearing == 0 && pcm->lbearing == 0)
28135 pcm = NULL;
28138 if (pcm)
28140 it->phys_ascent = pcm->ascent + boff;
28141 it->phys_descent = pcm->descent - boff;
28142 it->pixel_width = pcm->width;
28143 /* Don't use font-global values for ascent and descent
28144 if they result in an exceedingly large line height. */
28145 if (it->override_ascent < 0)
28147 if (FONT_TOO_HIGH (font))
28149 it->ascent = it->phys_ascent;
28150 it->descent = it->phys_descent;
28151 /* These limitations are enforced by an
28152 assertion near the end of this function. */
28153 if (it->ascent < 0)
28154 it->ascent = 0;
28155 if (it->descent < 0)
28156 it->descent = 0;
28160 else
28162 it->glyph_not_available_p = true;
28163 it->phys_ascent = it->ascent;
28164 it->phys_descent = it->descent;
28165 it->pixel_width = font->space_width;
28168 if (it->constrain_row_ascent_descent_p)
28170 if (it->descent > it->max_descent)
28172 it->ascent += it->descent - it->max_descent;
28173 it->descent = it->max_descent;
28175 if (it->ascent > it->max_ascent)
28177 it->descent = min (it->max_descent, it->descent + it->ascent - it->max_ascent);
28178 it->ascent = it->max_ascent;
28180 it->phys_ascent = min (it->phys_ascent, it->ascent);
28181 it->phys_descent = min (it->phys_descent, it->descent);
28182 extra_line_spacing = 0;
28185 /* If this is a space inside a region of text with
28186 `space-width' property, change its width. */
28187 bool stretched_p
28188 = it->char_to_display == ' ' && !NILP (it->space_width);
28189 if (stretched_p)
28190 it->pixel_width *= XFLOATINT (it->space_width);
28192 /* If face has a box, add the box thickness to the character
28193 height. If character has a box line to the left and/or
28194 right, add the box line width to the character's width. */
28195 if (face->box != FACE_NO_BOX)
28197 int thick = face->box_line_width;
28199 if (thick > 0)
28201 it->ascent += thick;
28202 it->descent += thick;
28204 else
28205 thick = -thick;
28207 if (it->start_of_box_run_p)
28208 it->pixel_width += thick;
28209 if (it->end_of_box_run_p)
28210 it->pixel_width += thick;
28213 /* If face has an overline, add the height of the overline
28214 (1 pixel) and a 1 pixel margin to the character height. */
28215 if (face->overline_p)
28216 it->ascent += overline_margin;
28218 if (it->constrain_row_ascent_descent_p)
28220 if (it->ascent > it->max_ascent)
28221 it->ascent = it->max_ascent;
28222 if (it->descent > it->max_descent)
28223 it->descent = it->max_descent;
28226 take_vertical_position_into_account (it);
28228 /* If we have to actually produce glyphs, do it. */
28229 if (it->glyph_row)
28231 if (stretched_p)
28233 /* Translate a space with a `space-width' property
28234 into a stretch glyph. */
28235 int ascent = (((it->ascent + it->descent) * FONT_BASE (font))
28236 / FONT_HEIGHT (font));
28237 append_stretch_glyph (it, it->object, it->pixel_width,
28238 it->ascent + it->descent, ascent);
28240 else
28241 append_glyph (it);
28243 /* If characters with lbearing or rbearing are displayed
28244 in this line, record that fact in a flag of the
28245 glyph row. This is used to optimize X output code. */
28246 if (pcm && (pcm->lbearing < 0 || pcm->rbearing > pcm->width))
28247 it->glyph_row->contains_overlapping_glyphs_p = true;
28249 if (! stretched_p && it->pixel_width == 0)
28250 /* We assure that all visible glyphs have at least 1-pixel
28251 width. */
28252 it->pixel_width = 1;
28254 else if (it->char_to_display == '\n')
28256 /* A newline has no width, but we need the height of the
28257 line. But if previous part of the line sets a height,
28258 don't increase that height. */
28260 Lisp_Object height;
28261 Lisp_Object total_height = Qnil;
28263 it->override_ascent = -1;
28264 it->pixel_width = 0;
28265 it->nglyphs = 0;
28267 height = get_it_property (it, Qline_height);
28268 /* Split (line-height total-height) list. */
28269 if (CONSP (height)
28270 && CONSP (XCDR (height))
28271 && NILP (XCDR (XCDR (height))))
28273 total_height = XCAR (XCDR (height));
28274 height = XCAR (height);
28276 height = calc_line_height_property (it, height, font, boff, true);
28278 if (it->override_ascent >= 0)
28280 it->ascent = it->override_ascent;
28281 it->descent = it->override_descent;
28282 boff = it->override_boff;
28284 else
28286 if (FONT_TOO_HIGH (font))
28288 it->ascent = font->pixel_size + boff - 1;
28289 it->descent = -boff + 1;
28290 if (it->descent < 0)
28291 it->descent = 0;
28293 else
28295 it->ascent = FONT_BASE (font) + boff;
28296 it->descent = FONT_DESCENT (font) - boff;
28300 if (EQ (height, Qt))
28302 if (it->descent > it->max_descent)
28304 it->ascent += it->descent - it->max_descent;
28305 it->descent = it->max_descent;
28307 if (it->ascent > it->max_ascent)
28309 it->descent = min (it->max_descent, it->descent + it->ascent - it->max_ascent);
28310 it->ascent = it->max_ascent;
28312 it->phys_ascent = min (it->phys_ascent, it->ascent);
28313 it->phys_descent = min (it->phys_descent, it->descent);
28314 it->constrain_row_ascent_descent_p = true;
28315 extra_line_spacing = 0;
28317 else
28319 Lisp_Object spacing;
28321 it->phys_ascent = it->ascent;
28322 it->phys_descent = it->descent;
28324 if ((it->max_ascent > 0 || it->max_descent > 0)
28325 && face->box != FACE_NO_BOX
28326 && face->box_line_width > 0)
28328 it->ascent += face->box_line_width;
28329 it->descent += face->box_line_width;
28331 if (!NILP (height)
28332 && XINT (height) > it->ascent + it->descent)
28333 it->ascent = XINT (height) - it->descent;
28335 if (!NILP (total_height))
28336 spacing = calc_line_height_property (it, total_height, font,
28337 boff, false);
28338 else
28340 spacing = get_it_property (it, Qline_spacing);
28341 spacing = calc_line_height_property (it, spacing, font,
28342 boff, false);
28344 if (INTEGERP (spacing))
28346 extra_line_spacing = XINT (spacing);
28347 if (!NILP (total_height))
28348 extra_line_spacing -= (it->phys_ascent + it->phys_descent);
28352 else /* i.e. (it->char_to_display == '\t') */
28354 if (font->space_width > 0)
28356 int tab_width = it->tab_width * font->space_width;
28357 int x = it->current_x + it->continuation_lines_width;
28358 int x0 = x;
28359 /* Adjust for line numbers, if needed. */
28360 if (!NILP (Vdisplay_line_numbers) && it->line_number_produced_p)
28362 x -= it->lnum_pixel_width;
28363 /* Restore the original TAB width, if required. */
28364 if (x + it->tab_offset >= it->first_visible_x)
28365 x += it->tab_offset;
28368 int next_tab_x = ((1 + x + tab_width - 1) / tab_width) * tab_width;
28370 /* If the distance from the current position to the next tab
28371 stop is less than a space character width, use the
28372 tab stop after that. */
28373 if (next_tab_x - x < font->space_width)
28374 next_tab_x += tab_width;
28375 if (!NILP (Vdisplay_line_numbers) && it->line_number_produced_p)
28377 next_tab_x += it->lnum_pixel_width;
28378 /* If the line is hscrolled, and the TAB starts before
28379 the first visible pixel, simulate negative row->x. */
28380 if (x < it->first_visible_x)
28382 next_tab_x -= it->first_visible_x - x;
28383 it->tab_offset = it->first_visible_x - x;
28385 else
28386 next_tab_x -= it->tab_offset;
28389 it->pixel_width = next_tab_x - x0;
28390 it->nglyphs = 1;
28391 if (FONT_TOO_HIGH (font))
28393 if (get_char_glyph_code (' ', font, &char2b))
28395 pcm = get_per_char_metric (font, &char2b);
28396 if (pcm->width == 0
28397 && pcm->rbearing == 0 && pcm->lbearing == 0)
28398 pcm = NULL;
28401 if (pcm)
28403 it->ascent = pcm->ascent + boff;
28404 it->descent = pcm->descent - boff;
28406 else
28408 it->ascent = font->pixel_size + boff - 1;
28409 it->descent = -boff + 1;
28411 if (it->ascent < 0)
28412 it->ascent = 0;
28413 if (it->descent < 0)
28414 it->descent = 0;
28416 else
28418 it->ascent = FONT_BASE (font) + boff;
28419 it->descent = FONT_DESCENT (font) - boff;
28421 it->phys_ascent = it->ascent;
28422 it->phys_descent = it->descent;
28424 if (it->glyph_row)
28426 append_stretch_glyph (it, it->object, it->pixel_width,
28427 it->ascent + it->descent, it->ascent);
28430 else
28432 it->pixel_width = 0;
28433 it->nglyphs = 1;
28437 if (FONT_TOO_HIGH (font))
28439 int font_ascent, font_descent;
28441 /* For very large fonts, where we ignore the declared font
28442 dimensions, and go by per-character metrics instead,
28443 don't let the row ascent and descent values (and the row
28444 height computed from them) be smaller than the "normal"
28445 character metrics. This avoids unpleasant effects
28446 whereby lines on display would change their height
28447 depending on which characters are shown. */
28448 normal_char_ascent_descent (font, -1, &font_ascent, &font_descent);
28449 it->max_ascent = max (it->max_ascent, font_ascent);
28450 it->max_descent = max (it->max_descent, font_descent);
28453 else if (it->what == IT_COMPOSITION && it->cmp_it.ch < 0)
28455 /* A static composition.
28457 Note: A composition is represented as one glyph in the
28458 glyph matrix. There are no padding glyphs.
28460 Important note: pixel_width, ascent, and descent are the
28461 values of what is drawn by draw_glyphs (i.e. the values of
28462 the overall glyphs composed). */
28463 struct face *face = FACE_FROM_ID (it->f, it->face_id);
28464 int boff; /* baseline offset */
28465 struct composition *cmp = composition_table[it->cmp_it.id];
28466 int glyph_len = cmp->glyph_len;
28467 struct font *font = face->font;
28469 it->nglyphs = 1;
28471 /* If we have not yet calculated pixel size data of glyphs of
28472 the composition for the current face font, calculate them
28473 now. Theoretically, we have to check all fonts for the
28474 glyphs, but that requires much time and memory space. So,
28475 here we check only the font of the first glyph. This may
28476 lead to incorrect display, but it's very rare, and C-l
28477 (recenter-top-bottom) can correct the display anyway. */
28478 if (! cmp->font || cmp->font != font)
28480 /* Ascent and descent of the font of the first character
28481 of this composition (adjusted by baseline offset).
28482 Ascent and descent of overall glyphs should not be less
28483 than these, respectively. */
28484 int font_ascent, font_descent, font_height;
28485 /* Bounding box of the overall glyphs. */
28486 int leftmost, rightmost, lowest, highest;
28487 int lbearing, rbearing;
28488 int i, width, ascent, descent;
28489 int c;
28490 XChar2b char2b;
28491 struct font_metrics *pcm;
28492 ptrdiff_t pos;
28494 eassume (0 < glyph_len); /* See Bug#8512. */
28496 c = COMPOSITION_GLYPH (cmp, glyph_len - 1);
28497 while (c == '\t' && 0 < --glyph_len);
28499 bool right_padded = glyph_len < cmp->glyph_len;
28500 for (i = 0; i < glyph_len; i++)
28502 c = COMPOSITION_GLYPH (cmp, i);
28503 if (c != '\t')
28504 break;
28505 cmp->offsets[i * 2] = cmp->offsets[i * 2 + 1] = 0;
28507 bool left_padded = i > 0;
28509 pos = (STRINGP (it->string) ? IT_STRING_CHARPOS (*it)
28510 : IT_CHARPOS (*it));
28511 /* If no suitable font is found, use the default font. */
28512 bool font_not_found_p = font == NULL;
28513 if (font_not_found_p)
28515 face = face->ascii_face;
28516 font = face->font;
28518 boff = font->baseline_offset;
28519 if (font->vertical_centering)
28520 boff = VCENTER_BASELINE_OFFSET (font, it->f) - boff;
28521 normal_char_ascent_descent (font, -1, &font_ascent, &font_descent);
28522 font_ascent += boff;
28523 font_descent -= boff;
28524 font_height = font_ascent + font_descent;
28526 cmp->font = font;
28528 pcm = NULL;
28529 if (! font_not_found_p)
28531 get_char_face_and_encoding (it->f, c, it->face_id,
28532 &char2b, false);
28533 pcm = get_per_char_metric (font, &char2b);
28536 /* Initialize the bounding box. */
28537 if (pcm)
28539 width = cmp->glyph_len > 0 ? pcm->width : 0;
28540 ascent = pcm->ascent;
28541 descent = pcm->descent;
28542 lbearing = pcm->lbearing;
28543 rbearing = pcm->rbearing;
28545 else
28547 width = cmp->glyph_len > 0 ? font->space_width : 0;
28548 ascent = FONT_BASE (font);
28549 descent = FONT_DESCENT (font);
28550 lbearing = 0;
28551 rbearing = width;
28554 rightmost = width;
28555 leftmost = 0;
28556 lowest = - descent + boff;
28557 highest = ascent + boff;
28559 if (! font_not_found_p
28560 && font->default_ascent
28561 && CHAR_TABLE_P (Vuse_default_ascent)
28562 && !NILP (Faref (Vuse_default_ascent,
28563 make_number (it->char_to_display))))
28564 highest = font->default_ascent + boff;
28566 /* Draw the first glyph at the normal position. It may be
28567 shifted to right later if some other glyphs are drawn
28568 at the left. */
28569 cmp->offsets[i * 2] = 0;
28570 cmp->offsets[i * 2 + 1] = boff;
28571 cmp->lbearing = lbearing;
28572 cmp->rbearing = rbearing;
28574 /* Set cmp->offsets for the remaining glyphs. */
28575 for (i++; i < glyph_len; i++)
28577 int left, right, btm, top;
28578 int ch = COMPOSITION_GLYPH (cmp, i);
28579 int face_id;
28580 struct face *this_face;
28582 if (ch == '\t')
28583 ch = ' ';
28584 face_id = FACE_FOR_CHAR (it->f, face, ch, pos, it->string);
28585 this_face = FACE_FROM_ID (it->f, face_id);
28586 font = this_face->font;
28588 if (font == NULL)
28589 pcm = NULL;
28590 else
28592 get_char_face_and_encoding (it->f, ch, face_id,
28593 &char2b, false);
28594 pcm = get_per_char_metric (font, &char2b);
28596 if (! pcm)
28597 cmp->offsets[i * 2] = cmp->offsets[i * 2 + 1] = 0;
28598 else
28600 width = pcm->width;
28601 ascent = pcm->ascent;
28602 descent = pcm->descent;
28603 lbearing = pcm->lbearing;
28604 rbearing = pcm->rbearing;
28605 if (cmp->method != COMPOSITION_WITH_RULE_ALTCHARS)
28607 /* Relative composition with or without
28608 alternate chars. */
28609 left = (leftmost + rightmost - width) / 2;
28610 btm = - descent + boff;
28611 if (font->relative_compose
28612 && (! CHAR_TABLE_P (Vignore_relative_composition)
28613 || NILP (Faref (Vignore_relative_composition,
28614 make_number (ch)))))
28617 if (- descent >= font->relative_compose)
28618 /* One extra pixel between two glyphs. */
28619 btm = highest + 1;
28620 else if (ascent <= 0)
28621 /* One extra pixel between two glyphs. */
28622 btm = lowest - 1 - ascent - descent;
28625 else
28627 /* A composition rule is specified by an integer
28628 value that encodes global and new reference
28629 points (GREF and NREF). GREF and NREF are
28630 specified by numbers as below:
28632 0---1---2 -- ascent
28636 9--10--11 -- center
28638 ---3---4---5--- baseline
28640 6---7---8 -- descent
28642 int rule = COMPOSITION_RULE (cmp, i);
28643 int gref, nref, grefx, grefy, nrefx, nrefy, xoff, yoff;
28645 COMPOSITION_DECODE_RULE (rule, gref, nref, xoff, yoff);
28646 grefx = gref % 3, nrefx = nref % 3;
28647 grefy = gref / 3, nrefy = nref / 3;
28648 if (xoff)
28649 xoff = font_height * (xoff - 128) / 256;
28650 if (yoff)
28651 yoff = font_height * (yoff - 128) / 256;
28653 left = (leftmost
28654 + grefx * (rightmost - leftmost) / 2
28655 - nrefx * width / 2
28656 + xoff);
28658 btm = ((grefy == 0 ? highest
28659 : grefy == 1 ? 0
28660 : grefy == 2 ? lowest
28661 : (highest + lowest) / 2)
28662 - (nrefy == 0 ? ascent + descent
28663 : nrefy == 1 ? descent - boff
28664 : nrefy == 2 ? 0
28665 : (ascent + descent) / 2)
28666 + yoff);
28669 cmp->offsets[i * 2] = left;
28670 cmp->offsets[i * 2 + 1] = btm + descent;
28672 /* Update the bounding box of the overall glyphs. */
28673 if (width > 0)
28675 right = left + width;
28676 if (left < leftmost)
28677 leftmost = left;
28678 if (right > rightmost)
28679 rightmost = right;
28681 top = btm + descent + ascent;
28682 if (top > highest)
28683 highest = top;
28684 if (btm < lowest)
28685 lowest = btm;
28687 if (cmp->lbearing > left + lbearing)
28688 cmp->lbearing = left + lbearing;
28689 if (cmp->rbearing < left + rbearing)
28690 cmp->rbearing = left + rbearing;
28694 /* If there are glyphs whose x-offsets are negative,
28695 shift all glyphs to the right and make all x-offsets
28696 non-negative. */
28697 if (leftmost < 0)
28699 for (i = 0; i < cmp->glyph_len; i++)
28700 cmp->offsets[i * 2] -= leftmost;
28701 rightmost -= leftmost;
28702 cmp->lbearing -= leftmost;
28703 cmp->rbearing -= leftmost;
28706 if (left_padded && cmp->lbearing < 0)
28708 for (i = 0; i < cmp->glyph_len; i++)
28709 cmp->offsets[i * 2] -= cmp->lbearing;
28710 rightmost -= cmp->lbearing;
28711 cmp->rbearing -= cmp->lbearing;
28712 cmp->lbearing = 0;
28714 if (right_padded && rightmost < cmp->rbearing)
28716 rightmost = cmp->rbearing;
28719 cmp->pixel_width = rightmost;
28720 cmp->ascent = highest;
28721 cmp->descent = - lowest;
28722 if (cmp->ascent < font_ascent)
28723 cmp->ascent = font_ascent;
28724 if (cmp->descent < font_descent)
28725 cmp->descent = font_descent;
28728 if (it->glyph_row
28729 && (cmp->lbearing < 0
28730 || cmp->rbearing > cmp->pixel_width))
28731 it->glyph_row->contains_overlapping_glyphs_p = true;
28733 it->pixel_width = cmp->pixel_width;
28734 it->ascent = it->phys_ascent = cmp->ascent;
28735 it->descent = it->phys_descent = cmp->descent;
28736 if (face->box != FACE_NO_BOX)
28738 int thick = face->box_line_width;
28740 if (thick > 0)
28742 it->ascent += thick;
28743 it->descent += thick;
28745 else
28746 thick = - thick;
28748 if (it->start_of_box_run_p)
28749 it->pixel_width += thick;
28750 if (it->end_of_box_run_p)
28751 it->pixel_width += thick;
28754 /* If face has an overline, add the height of the overline
28755 (1 pixel) and a 1 pixel margin to the character height. */
28756 if (face->overline_p)
28757 it->ascent += overline_margin;
28759 take_vertical_position_into_account (it);
28760 if (it->ascent < 0)
28761 it->ascent = 0;
28762 if (it->descent < 0)
28763 it->descent = 0;
28765 if (it->glyph_row && cmp->glyph_len > 0)
28766 append_composite_glyph (it);
28768 else if (it->what == IT_COMPOSITION)
28770 /* A dynamic (automatic) composition. */
28771 struct face *face = FACE_FROM_ID (it->f, it->face_id);
28772 Lisp_Object gstring;
28773 struct font_metrics metrics;
28775 it->nglyphs = 1;
28777 gstring = composition_gstring_from_id (it->cmp_it.id);
28778 it->pixel_width
28779 = composition_gstring_width (gstring, it->cmp_it.from, it->cmp_it.to,
28780 &metrics);
28781 if (it->glyph_row
28782 && (metrics.lbearing < 0 || metrics.rbearing > metrics.width))
28783 it->glyph_row->contains_overlapping_glyphs_p = true;
28784 it->ascent = it->phys_ascent = metrics.ascent;
28785 it->descent = it->phys_descent = metrics.descent;
28786 if (face->box != FACE_NO_BOX)
28788 int thick = face->box_line_width;
28790 if (thick > 0)
28792 it->ascent += thick;
28793 it->descent += thick;
28795 else
28796 thick = - thick;
28798 if (it->start_of_box_run_p)
28799 it->pixel_width += thick;
28800 if (it->end_of_box_run_p)
28801 it->pixel_width += thick;
28803 /* If face has an overline, add the height of the overline
28804 (1 pixel) and a 1 pixel margin to the character height. */
28805 if (face->overline_p)
28806 it->ascent += overline_margin;
28807 take_vertical_position_into_account (it);
28808 if (it->ascent < 0)
28809 it->ascent = 0;
28810 if (it->descent < 0)
28811 it->descent = 0;
28813 if (it->glyph_row)
28814 append_composite_glyph (it);
28816 else if (it->what == IT_GLYPHLESS)
28817 produce_glyphless_glyph (it, false, Qnil);
28818 else if (it->what == IT_IMAGE)
28819 produce_image_glyph (it);
28820 else if (it->what == IT_STRETCH)
28821 produce_stretch_glyph (it);
28822 else if (it->what == IT_XWIDGET)
28823 produce_xwidget_glyph (it);
28825 done:
28826 /* Accumulate dimensions. Note: can't assume that it->descent > 0
28827 because this isn't true for images with `:ascent 100'. */
28828 eassert (it->ascent >= 0 && it->descent >= 0);
28829 if (it->area == TEXT_AREA)
28830 it->current_x += it->pixel_width;
28832 if (extra_line_spacing > 0)
28834 it->descent += extra_line_spacing;
28835 if (extra_line_spacing > it->max_extra_line_spacing)
28836 it->max_extra_line_spacing = extra_line_spacing;
28839 it->max_ascent = max (it->max_ascent, it->ascent);
28840 it->max_descent = max (it->max_descent, it->descent);
28841 it->max_phys_ascent = max (it->max_phys_ascent, it->phys_ascent);
28842 it->max_phys_descent = max (it->max_phys_descent, it->phys_descent);
28845 /* EXPORT for RIF:
28846 Output LEN glyphs starting at START at the nominal cursor position.
28847 Advance the nominal cursor over the text. UPDATED_ROW is the glyph row
28848 being updated, and UPDATED_AREA is the area of that row being updated. */
28850 void
28851 x_write_glyphs (struct window *w, struct glyph_row *updated_row,
28852 struct glyph *start, enum glyph_row_area updated_area, int len)
28854 int x, hpos, chpos = w->phys_cursor.hpos;
28856 eassert (updated_row);
28857 /* When the window is hscrolled, cursor hpos can legitimately be out
28858 of bounds, but we draw the cursor at the corresponding window
28859 margin in that case. */
28860 if (!updated_row->reversed_p && chpos < 0)
28861 chpos = 0;
28862 if (updated_row->reversed_p && chpos >= updated_row->used[TEXT_AREA])
28863 chpos = updated_row->used[TEXT_AREA] - 1;
28865 block_input ();
28867 /* Write glyphs. */
28869 hpos = start - updated_row->glyphs[updated_area];
28870 x = draw_glyphs (w, w->output_cursor.x,
28871 updated_row, updated_area,
28872 hpos, hpos + len,
28873 DRAW_NORMAL_TEXT, 0);
28875 /* Invalidate old phys cursor if the glyph at its hpos is redrawn. */
28876 if (updated_area == TEXT_AREA
28877 && w->phys_cursor_on_p
28878 && w->phys_cursor.vpos == w->output_cursor.vpos
28879 && chpos >= hpos
28880 && chpos < hpos + len)
28881 w->phys_cursor_on_p = false;
28883 unblock_input ();
28885 /* Advance the output cursor. */
28886 w->output_cursor.hpos += len;
28887 w->output_cursor.x = x;
28891 /* EXPORT for RIF:
28892 Insert LEN glyphs from START at the nominal cursor position. */
28894 void
28895 x_insert_glyphs (struct window *w, struct glyph_row *updated_row,
28896 struct glyph *start, enum glyph_row_area updated_area, int len)
28898 struct frame *f;
28899 int line_height, shift_by_width, shifted_region_width;
28900 struct glyph_row *row;
28901 struct glyph *glyph;
28902 int frame_x, frame_y;
28903 ptrdiff_t hpos;
28905 eassert (updated_row);
28906 block_input ();
28907 f = XFRAME (WINDOW_FRAME (w));
28909 /* Get the height of the line we are in. */
28910 row = updated_row;
28911 line_height = row->height;
28913 /* Get the width of the glyphs to insert. */
28914 shift_by_width = 0;
28915 for (glyph = start; glyph < start + len; ++glyph)
28916 shift_by_width += glyph->pixel_width;
28918 /* Get the width of the region to shift right. */
28919 shifted_region_width = (window_box_width (w, updated_area)
28920 - w->output_cursor.x
28921 - shift_by_width);
28923 /* Shift right. */
28924 frame_x = window_box_left (w, updated_area) + w->output_cursor.x;
28925 frame_y = WINDOW_TO_FRAME_PIXEL_Y (w, w->output_cursor.y);
28927 FRAME_RIF (f)->shift_glyphs_for_insert (f, frame_x, frame_y, shifted_region_width,
28928 line_height, shift_by_width);
28930 /* Write the glyphs. */
28931 hpos = start - row->glyphs[updated_area];
28932 draw_glyphs (w, w->output_cursor.x, row, updated_area,
28933 hpos, hpos + len,
28934 DRAW_NORMAL_TEXT, 0);
28936 /* Advance the output cursor. */
28937 w->output_cursor.hpos += len;
28938 w->output_cursor.x += shift_by_width;
28939 unblock_input ();
28943 /* EXPORT for RIF:
28944 Erase the current text line from the nominal cursor position
28945 (inclusive) to pixel column TO_X (exclusive). The idea is that
28946 everything from TO_X onward is already erased.
28948 TO_X is a pixel position relative to UPDATED_AREA of currently
28949 updated window W. TO_X == -1 means clear to the end of this area. */
28951 void
28952 x_clear_end_of_line (struct window *w, struct glyph_row *updated_row,
28953 enum glyph_row_area updated_area, int to_x)
28955 struct frame *f;
28956 int max_x, min_y, max_y;
28957 int from_x, from_y, to_y;
28959 eassert (updated_row);
28960 f = XFRAME (w->frame);
28962 if (updated_row->full_width_p)
28963 max_x = (WINDOW_PIXEL_WIDTH (w)
28964 - (updated_row->mode_line_p ? WINDOW_RIGHT_DIVIDER_WIDTH (w) : 0));
28965 else
28966 max_x = window_box_width (w, updated_area);
28967 max_y = window_text_bottom_y (w);
28969 /* TO_X == 0 means don't do anything. TO_X < 0 means clear to end
28970 of window. For TO_X > 0, truncate to end of drawing area. */
28971 if (to_x == 0)
28972 return;
28973 else if (to_x < 0)
28974 to_x = max_x;
28975 else
28976 to_x = min (to_x, max_x);
28978 to_y = min (max_y, w->output_cursor.y + updated_row->height);
28980 /* Notice if the cursor will be cleared by this operation. */
28981 if (!updated_row->full_width_p)
28982 notice_overwritten_cursor (w, updated_area,
28983 w->output_cursor.x, -1,
28984 updated_row->y,
28985 MATRIX_ROW_BOTTOM_Y (updated_row));
28987 from_x = w->output_cursor.x;
28989 /* Translate to frame coordinates. */
28990 if (updated_row->full_width_p)
28992 from_x = WINDOW_TO_FRAME_PIXEL_X (w, from_x);
28993 to_x = WINDOW_TO_FRAME_PIXEL_X (w, to_x);
28995 else
28997 int area_left = window_box_left (w, updated_area);
28998 from_x += area_left;
28999 to_x += area_left;
29002 min_y = WINDOW_HEADER_LINE_HEIGHT (w);
29003 from_y = WINDOW_TO_FRAME_PIXEL_Y (w, max (min_y, w->output_cursor.y));
29004 to_y = WINDOW_TO_FRAME_PIXEL_Y (w, to_y);
29006 /* Prevent inadvertently clearing to end of the X window. */
29007 if (to_x > from_x && to_y > from_y)
29009 block_input ();
29010 FRAME_RIF (f)->clear_frame_area (f, from_x, from_y,
29011 to_x - from_x, to_y - from_y);
29012 unblock_input ();
29016 #endif /* HAVE_WINDOW_SYSTEM */
29020 /***********************************************************************
29021 Cursor types
29022 ***********************************************************************/
29024 /* Value is the internal representation of the specified cursor type
29025 ARG. If type is BAR_CURSOR, return in *WIDTH the specified width
29026 of the bar cursor. */
29028 static enum text_cursor_kinds
29029 get_specified_cursor_type (Lisp_Object arg, int *width)
29031 enum text_cursor_kinds type;
29033 if (NILP (arg))
29034 return NO_CURSOR;
29036 if (EQ (arg, Qbox))
29037 return FILLED_BOX_CURSOR;
29039 if (EQ (arg, Qhollow))
29040 return HOLLOW_BOX_CURSOR;
29042 if (EQ (arg, Qbar))
29044 *width = 2;
29045 return BAR_CURSOR;
29048 if (CONSP (arg)
29049 && EQ (XCAR (arg), Qbar)
29050 && RANGED_INTEGERP (0, XCDR (arg), INT_MAX))
29052 *width = XINT (XCDR (arg));
29053 return BAR_CURSOR;
29056 if (EQ (arg, Qhbar))
29058 *width = 2;
29059 return HBAR_CURSOR;
29062 if (CONSP (arg)
29063 && EQ (XCAR (arg), Qhbar)
29064 && RANGED_INTEGERP (0, XCDR (arg), INT_MAX))
29066 *width = XINT (XCDR (arg));
29067 return HBAR_CURSOR;
29070 /* Treat anything unknown as "hollow box cursor".
29071 It was bad to signal an error; people have trouble fixing
29072 .Xdefaults with Emacs, when it has something bad in it. */
29073 type = HOLLOW_BOX_CURSOR;
29075 return type;
29078 /* Set the default cursor types for specified frame. */
29079 void
29080 set_frame_cursor_types (struct frame *f, Lisp_Object arg)
29082 int width = 1;
29083 Lisp_Object tem;
29085 FRAME_DESIRED_CURSOR (f) = get_specified_cursor_type (arg, &width);
29086 FRAME_CURSOR_WIDTH (f) = width;
29088 /* By default, set up the blink-off state depending on the on-state. */
29090 tem = Fassoc (arg, Vblink_cursor_alist, Qnil);
29091 if (!NILP (tem))
29093 FRAME_BLINK_OFF_CURSOR (f)
29094 = get_specified_cursor_type (XCDR (tem), &width);
29095 FRAME_BLINK_OFF_CURSOR_WIDTH (f) = width;
29097 else
29098 FRAME_BLINK_OFF_CURSOR (f) = DEFAULT_CURSOR;
29100 /* Make sure the cursor gets redrawn. */
29101 f->cursor_type_changed = true;
29105 #ifdef HAVE_WINDOW_SYSTEM
29107 /* Return the cursor we want to be displayed in window W. Return
29108 width of bar/hbar cursor through WIDTH arg. Return with
29109 ACTIVE_CURSOR arg set to true if cursor in window W is `active'
29110 (i.e. if the `system caret' should track this cursor).
29112 In a mini-buffer window, we want the cursor only to appear if we
29113 are reading input from this window. For the selected window, we
29114 want the cursor type given by the frame parameter or buffer local
29115 setting of cursor-type. If explicitly marked off, draw no cursor.
29116 In all other cases, we want a hollow box cursor. */
29118 static enum text_cursor_kinds
29119 get_window_cursor_type (struct window *w, struct glyph *glyph, int *width,
29120 bool *active_cursor)
29122 struct frame *f = XFRAME (w->frame);
29123 struct buffer *b = XBUFFER (w->contents);
29124 int cursor_type = DEFAULT_CURSOR;
29125 Lisp_Object alt_cursor;
29126 bool non_selected = false;
29128 *active_cursor = true;
29130 /* Echo area */
29131 if (cursor_in_echo_area
29132 && FRAME_HAS_MINIBUF_P (f)
29133 && EQ (FRAME_MINIBUF_WINDOW (f), echo_area_window))
29135 if (w == XWINDOW (echo_area_window))
29137 if (EQ (BVAR (b, cursor_type), Qt) || NILP (BVAR (b, cursor_type)))
29139 *width = FRAME_CURSOR_WIDTH (f);
29140 return FRAME_DESIRED_CURSOR (f);
29142 else
29143 return get_specified_cursor_type (BVAR (b, cursor_type), width);
29146 *active_cursor = false;
29147 non_selected = true;
29150 /* Detect a nonselected window or nonselected frame. */
29151 else if (w != XWINDOW (f->selected_window)
29152 || f != FRAME_DISPLAY_INFO (f)->x_highlight_frame)
29154 *active_cursor = false;
29156 if (MINI_WINDOW_P (w) && minibuf_level == 0)
29157 return NO_CURSOR;
29159 non_selected = true;
29162 /* Never display a cursor in a window in which cursor-type is nil. */
29163 if (NILP (BVAR (b, cursor_type)))
29164 return NO_CURSOR;
29166 /* Get the normal cursor type for this window. */
29167 if (EQ (BVAR (b, cursor_type), Qt))
29169 cursor_type = FRAME_DESIRED_CURSOR (f);
29170 *width = FRAME_CURSOR_WIDTH (f);
29172 else
29173 cursor_type = get_specified_cursor_type (BVAR (b, cursor_type), width);
29175 /* Use cursor-in-non-selected-windows instead
29176 for non-selected window or frame. */
29177 if (non_selected)
29179 alt_cursor = BVAR (b, cursor_in_non_selected_windows);
29180 if (!EQ (Qt, alt_cursor))
29181 return get_specified_cursor_type (alt_cursor, width);
29182 /* t means modify the normal cursor type. */
29183 if (cursor_type == FILLED_BOX_CURSOR)
29184 cursor_type = HOLLOW_BOX_CURSOR;
29185 else if (cursor_type == BAR_CURSOR && *width > 1)
29186 --*width;
29187 return cursor_type;
29190 /* Use normal cursor if not blinked off. */
29191 if (!w->cursor_off_p)
29193 if (glyph != NULL && glyph->type == XWIDGET_GLYPH)
29194 return NO_CURSOR;
29195 if (glyph != NULL && glyph->type == IMAGE_GLYPH)
29197 if (cursor_type == FILLED_BOX_CURSOR)
29199 /* Using a block cursor on large images can be very annoying.
29200 So use a hollow cursor for "large" images.
29201 If image is not transparent (no mask), also use hollow cursor. */
29202 struct image *img = IMAGE_OPT_FROM_ID (f, glyph->u.img_id);
29203 if (img != NULL && IMAGEP (img->spec))
29205 /* Arbitrarily, interpret "Large" as >32x32 and >NxN
29206 where N = size of default frame font size.
29207 This should cover most of the "tiny" icons people may use. */
29208 if (!img->mask
29209 || img->width > max (32, WINDOW_FRAME_COLUMN_WIDTH (w))
29210 || img->height > max (32, WINDOW_FRAME_LINE_HEIGHT (w)))
29211 cursor_type = HOLLOW_BOX_CURSOR;
29214 else if (cursor_type != NO_CURSOR)
29216 /* Display current only supports BOX and HOLLOW cursors for images.
29217 So for now, unconditionally use a HOLLOW cursor when cursor is
29218 not a solid box cursor. */
29219 cursor_type = HOLLOW_BOX_CURSOR;
29222 return cursor_type;
29225 /* Cursor is blinked off, so determine how to "toggle" it. */
29227 /* First look for an entry matching the buffer's cursor-type in blink-cursor-alist. */
29228 if ((alt_cursor = Fassoc (BVAR (b, cursor_type), Vblink_cursor_alist, Qnil), !NILP (alt_cursor)))
29229 return get_specified_cursor_type (XCDR (alt_cursor), width);
29231 /* Then see if frame has specified a specific blink off cursor type. */
29232 if (FRAME_BLINK_OFF_CURSOR (f) != DEFAULT_CURSOR)
29234 *width = FRAME_BLINK_OFF_CURSOR_WIDTH (f);
29235 return FRAME_BLINK_OFF_CURSOR (f);
29238 #if false
29239 /* Some people liked having a permanently visible blinking cursor,
29240 while others had very strong opinions against it. So it was
29241 decided to remove it. KFS 2003-09-03 */
29243 /* Finally perform built-in cursor blinking:
29244 filled box <-> hollow box
29245 wide [h]bar <-> narrow [h]bar
29246 narrow [h]bar <-> no cursor
29247 other type <-> no cursor */
29249 if (cursor_type == FILLED_BOX_CURSOR)
29250 return HOLLOW_BOX_CURSOR;
29252 if ((cursor_type == BAR_CURSOR || cursor_type == HBAR_CURSOR) && *width > 1)
29254 *width = 1;
29255 return cursor_type;
29257 #endif
29259 return NO_CURSOR;
29263 /* Notice when the text cursor of window W has been completely
29264 overwritten by a drawing operation that outputs glyphs in AREA
29265 starting at X0 and ending at X1 in the line starting at Y0 and
29266 ending at Y1. X coordinates are area-relative. X1 < 0 means all
29267 the rest of the line after X0 has been written. Y coordinates
29268 are window-relative. */
29270 static void
29271 notice_overwritten_cursor (struct window *w, enum glyph_row_area area,
29272 int x0, int x1, int y0, int y1)
29274 int cx0, cx1, cy0, cy1;
29275 struct glyph_row *row;
29277 if (!w->phys_cursor_on_p)
29278 return;
29279 if (area != TEXT_AREA)
29280 return;
29282 if (w->phys_cursor.vpos < 0
29283 || w->phys_cursor.vpos >= w->current_matrix->nrows
29284 || (row = w->current_matrix->rows + w->phys_cursor.vpos,
29285 !(row->enabled_p && MATRIX_ROW_DISPLAYS_TEXT_P (row))))
29286 return;
29288 if (row->cursor_in_fringe_p)
29290 row->cursor_in_fringe_p = false;
29291 draw_fringe_bitmap (w, row, row->reversed_p);
29292 w->phys_cursor_on_p = false;
29293 return;
29296 cx0 = w->phys_cursor.x;
29297 cx1 = cx0 + w->phys_cursor_width;
29298 if (x0 > cx0 || (x1 >= 0 && x1 < cx1))
29299 return;
29301 /* The cursor image will be completely removed from the
29302 screen if the output area intersects the cursor area in
29303 y-direction. When we draw in [y0 y1[, and some part of
29304 the cursor is at y < y0, that part must have been drawn
29305 before. When scrolling, the cursor is erased before
29306 actually scrolling, so we don't come here. When not
29307 scrolling, the rows above the old cursor row must have
29308 changed, and in this case these rows must have written
29309 over the cursor image.
29311 Likewise if part of the cursor is below y1, with the
29312 exception of the cursor being in the first blank row at
29313 the buffer and window end because update_text_area
29314 doesn't draw that row. (Except when it does, but
29315 that's handled in update_text_area.) */
29317 cy0 = w->phys_cursor.y;
29318 cy1 = cy0 + w->phys_cursor_height;
29319 if ((y0 < cy0 || y0 >= cy1) && (y1 <= cy0 || y1 >= cy1))
29320 return;
29322 w->phys_cursor_on_p = false;
29325 #endif /* HAVE_WINDOW_SYSTEM */
29328 /************************************************************************
29329 Mouse Face
29330 ************************************************************************/
29332 #ifdef HAVE_WINDOW_SYSTEM
29334 /* EXPORT for RIF:
29335 Fix the display of area AREA of overlapping row ROW in window W
29336 with respect to the overlapping part OVERLAPS. */
29338 void
29339 x_fix_overlapping_area (struct window *w, struct glyph_row *row,
29340 enum glyph_row_area area, int overlaps)
29342 int i, x;
29344 block_input ();
29346 x = 0;
29347 for (i = 0; i < row->used[area];)
29349 if (row->glyphs[area][i].overlaps_vertically_p)
29351 int start = i, start_x = x;
29355 x += row->glyphs[area][i].pixel_width;
29356 ++i;
29358 while (i < row->used[area]
29359 && row->glyphs[area][i].overlaps_vertically_p);
29361 draw_glyphs (w, start_x, row, area,
29362 start, i,
29363 DRAW_NORMAL_TEXT, overlaps);
29365 else
29367 x += row->glyphs[area][i].pixel_width;
29368 ++i;
29372 unblock_input ();
29376 /* EXPORT:
29377 Draw the cursor glyph of window W in glyph row ROW. See the
29378 comment of draw_glyphs for the meaning of HL. */
29380 void
29381 draw_phys_cursor_glyph (struct window *w, struct glyph_row *row,
29382 enum draw_glyphs_face hl)
29384 /* If cursor hpos is out of bounds, don't draw garbage. This can
29385 happen in mini-buffer windows when switching between echo area
29386 glyphs and mini-buffer. */
29387 if ((row->reversed_p
29388 ? (w->phys_cursor.hpos >= 0)
29389 : (w->phys_cursor.hpos < row->used[TEXT_AREA])))
29391 bool on_p = w->phys_cursor_on_p;
29392 int x1;
29393 int hpos = w->phys_cursor.hpos;
29395 /* When the window is hscrolled, cursor hpos can legitimately be
29396 out of bounds, but we draw the cursor at the corresponding
29397 window margin in that case. */
29398 if (!row->reversed_p && hpos < 0)
29399 hpos = 0;
29400 if (row->reversed_p && hpos >= row->used[TEXT_AREA])
29401 hpos = row->used[TEXT_AREA] - 1;
29403 x1 = draw_glyphs (w, w->phys_cursor.x, row, TEXT_AREA, hpos, hpos + 1,
29404 hl, 0);
29405 w->phys_cursor_on_p = on_p;
29407 if (hl == DRAW_CURSOR)
29408 w->phys_cursor_width = x1 - w->phys_cursor.x;
29409 /* When we erase the cursor, and ROW is overlapped by other
29410 rows, make sure that these overlapping parts of other rows
29411 are redrawn. */
29412 else if (hl == DRAW_NORMAL_TEXT && row->overlapped_p)
29414 w->phys_cursor_width = x1 - w->phys_cursor.x;
29416 if (row > w->current_matrix->rows
29417 && MATRIX_ROW_OVERLAPS_SUCC_P (row - 1))
29418 x_fix_overlapping_area (w, row - 1, TEXT_AREA,
29419 OVERLAPS_ERASED_CURSOR);
29421 if (MATRIX_ROW_BOTTOM_Y (row) < window_text_bottom_y (w)
29422 && MATRIX_ROW_OVERLAPS_PRED_P (row + 1))
29423 x_fix_overlapping_area (w, row + 1, TEXT_AREA,
29424 OVERLAPS_ERASED_CURSOR);
29430 /* Erase the image of a cursor of window W from the screen. */
29432 void
29433 erase_phys_cursor (struct window *w)
29435 struct frame *f = XFRAME (w->frame);
29436 Mouse_HLInfo *hlinfo = MOUSE_HL_INFO (f);
29437 int hpos = w->phys_cursor.hpos;
29438 int vpos = w->phys_cursor.vpos;
29439 bool mouse_face_here_p = false;
29440 struct glyph_matrix *active_glyphs = w->current_matrix;
29441 struct glyph_row *cursor_row;
29442 struct glyph *cursor_glyph;
29443 enum draw_glyphs_face hl;
29445 /* No cursor displayed or row invalidated => nothing to do on the
29446 screen. */
29447 if (w->phys_cursor_type == NO_CURSOR)
29448 goto mark_cursor_off;
29450 /* VPOS >= active_glyphs->nrows means that window has been resized.
29451 Don't bother to erase the cursor. */
29452 if (vpos >= active_glyphs->nrows)
29453 goto mark_cursor_off;
29455 /* If row containing cursor is marked invalid, there is nothing we
29456 can do. */
29457 cursor_row = MATRIX_ROW (active_glyphs, vpos);
29458 if (!cursor_row->enabled_p)
29459 goto mark_cursor_off;
29461 /* If line spacing is > 0, old cursor may only be partially visible in
29462 window after split-window. So adjust visible height. */
29463 cursor_row->visible_height = min (cursor_row->visible_height,
29464 window_text_bottom_y (w) - cursor_row->y);
29466 /* If row is completely invisible, don't attempt to delete a cursor which
29467 isn't there. This can happen if cursor is at top of a window, and
29468 we switch to a buffer with a header line in that window. */
29469 if (cursor_row->visible_height <= 0)
29470 goto mark_cursor_off;
29472 /* If cursor is in the fringe, erase by drawing actual bitmap there. */
29473 if (cursor_row->cursor_in_fringe_p)
29475 cursor_row->cursor_in_fringe_p = false;
29476 draw_fringe_bitmap (w, cursor_row, cursor_row->reversed_p);
29477 goto mark_cursor_off;
29480 /* This can happen when the new row is shorter than the old one.
29481 In this case, either draw_glyphs or clear_end_of_line
29482 should have cleared the cursor. Note that we wouldn't be
29483 able to erase the cursor in this case because we don't have a
29484 cursor glyph at hand. */
29485 if ((cursor_row->reversed_p
29486 ? (w->phys_cursor.hpos < 0)
29487 : (w->phys_cursor.hpos >= cursor_row->used[TEXT_AREA])))
29488 goto mark_cursor_off;
29490 /* When the window is hscrolled, cursor hpos can legitimately be out
29491 of bounds, but we draw the cursor at the corresponding window
29492 margin in that case. */
29493 if (!cursor_row->reversed_p && hpos < 0)
29494 hpos = 0;
29495 if (cursor_row->reversed_p && hpos >= cursor_row->used[TEXT_AREA])
29496 hpos = cursor_row->used[TEXT_AREA] - 1;
29498 /* If the cursor is in the mouse face area, redisplay that when
29499 we clear the cursor. */
29500 if (! NILP (hlinfo->mouse_face_window)
29501 && coords_in_mouse_face_p (w, hpos, vpos)
29502 /* Don't redraw the cursor's spot in mouse face if it is at the
29503 end of a line (on a newline). The cursor appears there, but
29504 mouse highlighting does not. */
29505 && cursor_row->used[TEXT_AREA] > hpos && hpos >= 0)
29506 mouse_face_here_p = true;
29508 /* Maybe clear the display under the cursor. */
29509 if (w->phys_cursor_type == HOLLOW_BOX_CURSOR)
29511 int x, y;
29512 int header_line_height = WINDOW_HEADER_LINE_HEIGHT (w);
29513 int width;
29515 cursor_glyph = get_phys_cursor_glyph (w);
29516 if (cursor_glyph == NULL)
29517 goto mark_cursor_off;
29519 width = cursor_glyph->pixel_width;
29520 x = w->phys_cursor.x;
29521 if (x < 0)
29523 width += x;
29524 x = 0;
29526 width = min (width, window_box_width (w, TEXT_AREA) - x);
29527 y = WINDOW_TO_FRAME_PIXEL_Y (w, max (header_line_height, cursor_row->y));
29528 x = WINDOW_TEXT_TO_FRAME_PIXEL_X (w, x);
29530 if (width > 0)
29531 FRAME_RIF (f)->clear_frame_area (f, x, y, width, cursor_row->visible_height);
29534 /* Erase the cursor by redrawing the character underneath it. */
29535 if (mouse_face_here_p)
29536 hl = DRAW_MOUSE_FACE;
29537 else
29538 hl = DRAW_NORMAL_TEXT;
29539 draw_phys_cursor_glyph (w, cursor_row, hl);
29541 mark_cursor_off:
29542 w->phys_cursor_on_p = false;
29543 w->phys_cursor_type = NO_CURSOR;
29547 /* Display or clear cursor of window W. If !ON, clear the cursor.
29548 If ON, display the cursor; where to put the cursor is specified by
29549 HPOS, VPOS, X and Y. */
29551 void
29552 display_and_set_cursor (struct window *w, bool on,
29553 int hpos, int vpos, int x, int y)
29555 struct frame *f = XFRAME (w->frame);
29556 int new_cursor_type;
29557 int new_cursor_width;
29558 bool active_cursor;
29559 struct glyph_row *glyph_row;
29560 struct glyph *glyph;
29562 /* This is pointless on invisible frames, and dangerous on garbaged
29563 windows and frames; in the latter case, the frame or window may
29564 be in the midst of changing its size, and x and y may be off the
29565 window. */
29566 if (! FRAME_VISIBLE_P (f)
29567 || vpos >= w->current_matrix->nrows
29568 || hpos >= w->current_matrix->matrix_w)
29569 return;
29571 /* If cursor is off and we want it off, return quickly. */
29572 if (!on && !w->phys_cursor_on_p)
29573 return;
29575 glyph_row = MATRIX_ROW (w->current_matrix, vpos);
29576 /* If cursor row is not enabled, we don't really know where to
29577 display the cursor. */
29578 if (!glyph_row->enabled_p)
29580 w->phys_cursor_on_p = false;
29581 return;
29584 /* A frame might be marked garbaged even though its cursor position
29585 is correct, and will not change upon subsequent redisplay. This
29586 happens in some rare situations, like toggling the sort order in
29587 Dired windows. We've already established that VPOS is valid, so
29588 it shouldn't do any harm to record the cursor position, as we are
29589 going to return without acting on it anyway. Otherwise, expose
29590 events might come in and call update_window_cursor, which will
29591 blindly use outdated values in w->phys_cursor. */
29592 if (FRAME_GARBAGED_P (f))
29594 if (on)
29596 w->phys_cursor.x = x;
29597 w->phys_cursor.y = glyph_row->y;
29598 w->phys_cursor.hpos = hpos;
29599 w->phys_cursor.vpos = vpos;
29601 return;
29604 glyph = NULL;
29605 if (0 <= hpos && hpos < glyph_row->used[TEXT_AREA])
29606 glyph = glyph_row->glyphs[TEXT_AREA] + hpos;
29608 eassert (input_blocked_p ());
29610 /* Set new_cursor_type to the cursor we want to be displayed. */
29611 new_cursor_type = get_window_cursor_type (w, glyph,
29612 &new_cursor_width, &active_cursor);
29614 /* If cursor is currently being shown and we don't want it to be or
29615 it is in the wrong place, or the cursor type is not what we want,
29616 erase it. */
29617 if (w->phys_cursor_on_p
29618 && (!on
29619 || w->phys_cursor.x != x
29620 || w->phys_cursor.y != y
29621 /* HPOS can be negative in R2L rows whose
29622 exact_window_width_line_p flag is set (i.e. their newline
29623 would "overflow into the fringe"). */
29624 || hpos < 0
29625 || new_cursor_type != w->phys_cursor_type
29626 || ((new_cursor_type == BAR_CURSOR || new_cursor_type == HBAR_CURSOR)
29627 && new_cursor_width != w->phys_cursor_width)))
29628 erase_phys_cursor (w);
29630 /* Don't check phys_cursor_on_p here because that flag is only set
29631 to false in some cases where we know that the cursor has been
29632 completely erased, to avoid the extra work of erasing the cursor
29633 twice. In other words, phys_cursor_on_p can be true and the cursor
29634 still not be visible, or it has only been partly erased. */
29635 if (on)
29637 w->phys_cursor_ascent = glyph_row->ascent;
29638 w->phys_cursor_height = glyph_row->height;
29640 /* Set phys_cursor_.* before x_draw_.* is called because some
29641 of them may need the information. */
29642 w->phys_cursor.x = x;
29643 w->phys_cursor.y = glyph_row->y;
29644 w->phys_cursor.hpos = hpos;
29645 w->phys_cursor.vpos = vpos;
29648 FRAME_RIF (f)->draw_window_cursor (w, glyph_row, x, y,
29649 new_cursor_type, new_cursor_width,
29650 on, active_cursor);
29654 /* Switch the display of W's cursor on or off, according to the value
29655 of ON. */
29657 static void
29658 update_window_cursor (struct window *w, bool on)
29660 /* Don't update cursor in windows whose frame is in the process
29661 of being deleted. */
29662 if (w->current_matrix)
29664 int hpos = w->phys_cursor.hpos;
29665 int vpos = w->phys_cursor.vpos;
29666 struct glyph_row *row;
29668 if (vpos >= w->current_matrix->nrows
29669 || hpos >= w->current_matrix->matrix_w)
29670 return;
29672 row = MATRIX_ROW (w->current_matrix, vpos);
29674 /* When the window is hscrolled, cursor hpos can legitimately be
29675 out of bounds, but we draw the cursor at the corresponding
29676 window margin in that case. */
29677 if (!row->reversed_p && hpos < 0)
29678 hpos = 0;
29679 if (row->reversed_p && hpos >= row->used[TEXT_AREA])
29680 hpos = row->used[TEXT_AREA] - 1;
29682 block_input ();
29683 display_and_set_cursor (w, on, hpos, vpos,
29684 w->phys_cursor.x, w->phys_cursor.y);
29685 unblock_input ();
29690 /* Call update_window_cursor with parameter ON_P on all leaf windows
29691 in the window tree rooted at W. */
29693 static void
29694 update_cursor_in_window_tree (struct window *w, bool on_p)
29696 while (w)
29698 if (WINDOWP (w->contents))
29699 update_cursor_in_window_tree (XWINDOW (w->contents), on_p);
29700 else
29701 update_window_cursor (w, on_p);
29703 w = NILP (w->next) ? 0 : XWINDOW (w->next);
29708 /* EXPORT:
29709 Display the cursor on window W, or clear it, according to ON_P.
29710 Don't change the cursor's position. */
29712 void
29713 x_update_cursor (struct frame *f, bool on_p)
29715 update_cursor_in_window_tree (XWINDOW (f->root_window), on_p);
29719 /* EXPORT:
29720 Clear the cursor of window W to background color, and mark the
29721 cursor as not shown. This is used when the text where the cursor
29722 is about to be rewritten. */
29724 void
29725 x_clear_cursor (struct window *w)
29727 if (FRAME_VISIBLE_P (XFRAME (w->frame)) && w->phys_cursor_on_p)
29728 update_window_cursor (w, false);
29731 #endif /* HAVE_WINDOW_SYSTEM */
29733 /* Implementation of draw_row_with_mouse_face for GUI sessions, GPM,
29734 and MSDOS. */
29735 static void
29736 draw_row_with_mouse_face (struct window *w, int start_x, struct glyph_row *row,
29737 int start_hpos, int end_hpos,
29738 enum draw_glyphs_face draw)
29740 #ifdef HAVE_WINDOW_SYSTEM
29741 if (FRAME_WINDOW_P (XFRAME (w->frame)))
29743 draw_glyphs (w, start_x, row, TEXT_AREA, start_hpos, end_hpos, draw, 0);
29744 return;
29746 #endif
29747 #if defined (HAVE_GPM) || defined (MSDOS) || defined (WINDOWSNT)
29748 tty_draw_row_with_mouse_face (w, row, start_hpos, end_hpos, draw);
29749 #endif
29752 /* Display the active region described by mouse_face_* according to DRAW. */
29754 static void
29755 show_mouse_face (Mouse_HLInfo *hlinfo, enum draw_glyphs_face draw)
29757 struct window *w = XWINDOW (hlinfo->mouse_face_window);
29758 struct frame *f = XFRAME (WINDOW_FRAME (w));
29760 if (/* If window is in the process of being destroyed, don't bother
29761 to do anything. */
29762 w->current_matrix != NULL
29763 /* Don't update mouse highlight if hidden. */
29764 && (draw != DRAW_MOUSE_FACE || !hlinfo->mouse_face_hidden)
29765 /* Recognize when we are called to operate on rows that don't exist
29766 anymore. This can happen when a window is split. */
29767 && hlinfo->mouse_face_end_row < w->current_matrix->nrows)
29769 bool phys_cursor_on_p = w->phys_cursor_on_p;
29770 struct glyph_row *row, *first, *last;
29772 first = MATRIX_ROW (w->current_matrix, hlinfo->mouse_face_beg_row);
29773 last = MATRIX_ROW (w->current_matrix, hlinfo->mouse_face_end_row);
29775 for (row = first; row <= last && row->enabled_p; ++row)
29777 int start_hpos, end_hpos, start_x;
29779 /* For all but the first row, the highlight starts at column 0. */
29780 if (row == first)
29782 /* R2L rows have BEG and END in reversed order, but the
29783 screen drawing geometry is always left to right. So
29784 we need to mirror the beginning and end of the
29785 highlighted area in R2L rows. */
29786 if (!row->reversed_p)
29788 start_hpos = hlinfo->mouse_face_beg_col;
29789 start_x = hlinfo->mouse_face_beg_x;
29791 else if (row == last)
29793 start_hpos = hlinfo->mouse_face_end_col;
29794 start_x = hlinfo->mouse_face_end_x;
29796 else
29798 start_hpos = 0;
29799 start_x = 0;
29802 else if (row->reversed_p && row == last)
29804 start_hpos = hlinfo->mouse_face_end_col;
29805 start_x = hlinfo->mouse_face_end_x;
29807 else
29809 start_hpos = 0;
29810 start_x = 0;
29813 if (row == last)
29815 if (!row->reversed_p)
29816 end_hpos = hlinfo->mouse_face_end_col;
29817 else if (row == first)
29818 end_hpos = hlinfo->mouse_face_beg_col;
29819 else
29821 end_hpos = row->used[TEXT_AREA];
29822 if (draw == DRAW_NORMAL_TEXT)
29823 row->fill_line_p = true; /* Clear to end of line. */
29826 else if (row->reversed_p && row == first)
29827 end_hpos = hlinfo->mouse_face_beg_col;
29828 else
29830 end_hpos = row->used[TEXT_AREA];
29831 if (draw == DRAW_NORMAL_TEXT)
29832 row->fill_line_p = true; /* Clear to end of line. */
29835 if (end_hpos > start_hpos)
29837 draw_row_with_mouse_face (w, start_x, row,
29838 start_hpos, end_hpos, draw);
29840 row->mouse_face_p
29841 = draw == DRAW_MOUSE_FACE || draw == DRAW_IMAGE_RAISED;
29845 /* When we've written over the cursor, arrange for it to
29846 be displayed again. */
29847 if (FRAME_WINDOW_P (f)
29848 && phys_cursor_on_p && !w->phys_cursor_on_p)
29850 #ifdef HAVE_WINDOW_SYSTEM
29851 int hpos = w->phys_cursor.hpos;
29853 /* When the window is hscrolled, cursor hpos can legitimately be
29854 out of bounds, but we draw the cursor at the corresponding
29855 window margin in that case. */
29856 if (!row->reversed_p && hpos < 0)
29857 hpos = 0;
29858 if (row->reversed_p && hpos >= row->used[TEXT_AREA])
29859 hpos = row->used[TEXT_AREA] - 1;
29861 block_input ();
29862 display_and_set_cursor (w, true, hpos, w->phys_cursor.vpos,
29863 w->phys_cursor.x, w->phys_cursor.y);
29864 unblock_input ();
29865 #endif /* HAVE_WINDOW_SYSTEM */
29869 #ifdef HAVE_WINDOW_SYSTEM
29870 /* Change the mouse cursor. */
29871 if (FRAME_WINDOW_P (f) && NILP (do_mouse_tracking))
29873 #if ! defined (USE_GTK) && ! defined (HAVE_NS)
29874 if (draw == DRAW_NORMAL_TEXT
29875 && !EQ (hlinfo->mouse_face_window, f->tool_bar_window))
29876 FRAME_RIF (f)->define_frame_cursor (f, FRAME_X_OUTPUT (f)->text_cursor);
29877 else
29878 #endif
29879 if (draw == DRAW_MOUSE_FACE)
29880 FRAME_RIF (f)->define_frame_cursor (f, FRAME_X_OUTPUT (f)->hand_cursor);
29881 else
29882 FRAME_RIF (f)->define_frame_cursor (f, FRAME_X_OUTPUT (f)->nontext_cursor);
29884 #endif /* HAVE_WINDOW_SYSTEM */
29887 /* EXPORT:
29888 Clear out the mouse-highlighted active region.
29889 Redraw it un-highlighted first. Value is true if mouse
29890 face was actually drawn unhighlighted. */
29892 bool
29893 clear_mouse_face (Mouse_HLInfo *hlinfo)
29895 bool cleared
29896 = !hlinfo->mouse_face_hidden && !NILP (hlinfo->mouse_face_window);
29897 if (cleared)
29898 show_mouse_face (hlinfo, DRAW_NORMAL_TEXT);
29899 hlinfo->mouse_face_beg_row = hlinfo->mouse_face_beg_col = -1;
29900 hlinfo->mouse_face_end_row = hlinfo->mouse_face_end_col = -1;
29901 hlinfo->mouse_face_window = Qnil;
29902 hlinfo->mouse_face_overlay = Qnil;
29903 return cleared;
29906 /* Return true if the coordinates HPOS and VPOS on windows W are
29907 within the mouse face on that window. */
29908 static bool
29909 coords_in_mouse_face_p (struct window *w, int hpos, int vpos)
29911 Mouse_HLInfo *hlinfo = MOUSE_HL_INFO (XFRAME (w->frame));
29913 /* Quickly resolve the easy cases. */
29914 if (!(WINDOWP (hlinfo->mouse_face_window)
29915 && XWINDOW (hlinfo->mouse_face_window) == w))
29916 return false;
29917 if (vpos < hlinfo->mouse_face_beg_row
29918 || vpos > hlinfo->mouse_face_end_row)
29919 return false;
29920 if (vpos > hlinfo->mouse_face_beg_row
29921 && vpos < hlinfo->mouse_face_end_row)
29922 return true;
29924 if (!MATRIX_ROW (w->current_matrix, vpos)->reversed_p)
29926 if (hlinfo->mouse_face_beg_row == hlinfo->mouse_face_end_row)
29928 if (hlinfo->mouse_face_beg_col <= hpos && hpos < hlinfo->mouse_face_end_col)
29929 return true;
29931 else if ((vpos == hlinfo->mouse_face_beg_row
29932 && hpos >= hlinfo->mouse_face_beg_col)
29933 || (vpos == hlinfo->mouse_face_end_row
29934 && hpos < hlinfo->mouse_face_end_col))
29935 return true;
29937 else
29939 if (hlinfo->mouse_face_beg_row == hlinfo->mouse_face_end_row)
29941 if (hlinfo->mouse_face_end_col < hpos && hpos <= hlinfo->mouse_face_beg_col)
29942 return true;
29944 else if ((vpos == hlinfo->mouse_face_beg_row
29945 && hpos <= hlinfo->mouse_face_beg_col)
29946 || (vpos == hlinfo->mouse_face_end_row
29947 && hpos > hlinfo->mouse_face_end_col))
29948 return true;
29950 return false;
29954 /* EXPORT:
29955 True if physical cursor of window W is within mouse face. */
29957 bool
29958 cursor_in_mouse_face_p (struct window *w)
29960 int hpos = w->phys_cursor.hpos;
29961 int vpos = w->phys_cursor.vpos;
29962 struct glyph_row *row = MATRIX_ROW (w->current_matrix, vpos);
29964 /* When the window is hscrolled, cursor hpos can legitimately be out
29965 of bounds, but we draw the cursor at the corresponding window
29966 margin in that case. */
29967 if (!row->reversed_p && hpos < 0)
29968 hpos = 0;
29969 if (row->reversed_p && hpos >= row->used[TEXT_AREA])
29970 hpos = row->used[TEXT_AREA] - 1;
29972 return coords_in_mouse_face_p (w, hpos, vpos);
29977 /* Find the glyph rows START_ROW and END_ROW of window W that display
29978 characters between buffer positions START_CHARPOS and END_CHARPOS
29979 (excluding END_CHARPOS). DISP_STRING is a display string that
29980 covers these buffer positions. This is similar to
29981 row_containing_pos, but is more accurate when bidi reordering makes
29982 buffer positions change non-linearly with glyph rows. */
29983 static void
29984 rows_from_pos_range (struct window *w,
29985 ptrdiff_t start_charpos, ptrdiff_t end_charpos,
29986 Lisp_Object disp_string,
29987 struct glyph_row **start, struct glyph_row **end)
29989 struct glyph_row *first = MATRIX_FIRST_TEXT_ROW (w->current_matrix);
29990 int last_y = window_text_bottom_y (w);
29991 struct glyph_row *row;
29993 *start = NULL;
29994 *end = NULL;
29996 while (!first->enabled_p
29997 && first < MATRIX_BOTTOM_TEXT_ROW (w->current_matrix, w))
29998 first++;
30000 /* Find the START row. */
30001 for (row = first;
30002 row->enabled_p && MATRIX_ROW_BOTTOM_Y (row) <= last_y;
30003 row++)
30005 /* A row can potentially be the START row if the range of the
30006 characters it displays intersects the range
30007 [START_CHARPOS..END_CHARPOS). */
30008 if (! ((start_charpos < MATRIX_ROW_START_CHARPOS (row)
30009 && end_charpos < MATRIX_ROW_START_CHARPOS (row))
30010 /* See the commentary in row_containing_pos, for the
30011 explanation of the complicated way to check whether
30012 some position is beyond the end of the characters
30013 displayed by a row. */
30014 || ((start_charpos > MATRIX_ROW_END_CHARPOS (row)
30015 || (start_charpos == MATRIX_ROW_END_CHARPOS (row)
30016 && !row->ends_at_zv_p
30017 && !MATRIX_ROW_ENDS_IN_MIDDLE_OF_CHAR_P (row)))
30018 && (end_charpos > MATRIX_ROW_END_CHARPOS (row)
30019 || (end_charpos == MATRIX_ROW_END_CHARPOS (row)
30020 && !row->ends_at_zv_p
30021 && !MATRIX_ROW_ENDS_IN_MIDDLE_OF_CHAR_P (row))))))
30023 /* Found a candidate row. Now make sure at least one of the
30024 glyphs it displays has a charpos from the range
30025 [START_CHARPOS..END_CHARPOS).
30027 This is not obvious because bidi reordering could make
30028 buffer positions of a row be 1,2,3,102,101,100, and if we
30029 want to highlight characters in [50..60), we don't want
30030 this row, even though [50..60) does intersect [1..103),
30031 the range of character positions given by the row's start
30032 and end positions. */
30033 struct glyph *g = row->glyphs[TEXT_AREA];
30034 struct glyph *e = g + row->used[TEXT_AREA];
30036 while (g < e)
30038 if (((BUFFERP (g->object) || NILP (g->object))
30039 && start_charpos <= g->charpos && g->charpos < end_charpos)
30040 /* A glyph that comes from DISP_STRING is by
30041 definition to be highlighted. */
30042 || EQ (g->object, disp_string))
30043 *start = row;
30044 g++;
30046 if (*start)
30047 break;
30051 /* Find the END row. */
30052 if (!*start
30053 /* If the last row is partially visible, start looking for END
30054 from that row, instead of starting from FIRST. */
30055 && !(row->enabled_p
30056 && row->y < last_y && MATRIX_ROW_BOTTOM_Y (row) > last_y))
30057 row = first;
30058 for ( ; row->enabled_p && MATRIX_ROW_BOTTOM_Y (row) <= last_y; row++)
30060 struct glyph_row *next = row + 1;
30061 ptrdiff_t next_start = MATRIX_ROW_START_CHARPOS (next);
30063 if (!next->enabled_p
30064 || next >= MATRIX_BOTTOM_TEXT_ROW (w->current_matrix, w)
30065 /* The first row >= START whose range of displayed characters
30066 does NOT intersect the range [START_CHARPOS..END_CHARPOS]
30067 is the row END + 1. */
30068 || (start_charpos < next_start
30069 && end_charpos < next_start)
30070 || ((start_charpos > MATRIX_ROW_END_CHARPOS (next)
30071 || (start_charpos == MATRIX_ROW_END_CHARPOS (next)
30072 && !next->ends_at_zv_p
30073 && !MATRIX_ROW_ENDS_IN_MIDDLE_OF_CHAR_P (next)))
30074 && (end_charpos > MATRIX_ROW_END_CHARPOS (next)
30075 || (end_charpos == MATRIX_ROW_END_CHARPOS (next)
30076 && !next->ends_at_zv_p
30077 && !MATRIX_ROW_ENDS_IN_MIDDLE_OF_CHAR_P (next)))))
30079 *end = row;
30080 break;
30082 else
30084 /* If the next row's edges intersect [START_CHARPOS..END_CHARPOS],
30085 but none of the characters it displays are in the range, it is
30086 also END + 1. */
30087 struct glyph *g = next->glyphs[TEXT_AREA];
30088 struct glyph *s = g;
30089 struct glyph *e = g + next->used[TEXT_AREA];
30091 while (g < e)
30093 if (((BUFFERP (g->object) || NILP (g->object))
30094 && ((start_charpos <= g->charpos && g->charpos < end_charpos)
30095 /* If the buffer position of the first glyph in
30096 the row is equal to END_CHARPOS, it means
30097 the last character to be highlighted is the
30098 newline of ROW, and we must consider NEXT as
30099 END, not END+1. */
30100 || (((!next->reversed_p && g == s)
30101 || (next->reversed_p && g == e - 1))
30102 && (g->charpos == end_charpos
30103 /* Special case for when NEXT is an
30104 empty line at ZV. */
30105 || (g->charpos == -1
30106 && !row->ends_at_zv_p
30107 && next_start == end_charpos)))))
30108 /* A glyph that comes from DISP_STRING is by
30109 definition to be highlighted. */
30110 || EQ (g->object, disp_string))
30111 break;
30112 g++;
30114 if (g == e)
30116 *end = row;
30117 break;
30119 /* The first row that ends at ZV must be the last to be
30120 highlighted. */
30121 else if (next->ends_at_zv_p)
30123 *end = next;
30124 break;
30130 /* This function sets the mouse_face_* elements of HLINFO, assuming
30131 the mouse cursor is on a glyph with buffer charpos MOUSE_CHARPOS in
30132 window WINDOW. START_CHARPOS and END_CHARPOS are buffer positions
30133 for the overlay or run of text properties specifying the mouse
30134 face. BEFORE_STRING and AFTER_STRING, if non-nil, are a
30135 before-string and after-string that must also be highlighted.
30136 DISP_STRING, if non-nil, is a display string that may cover some
30137 or all of the highlighted text. */
30139 static void
30140 mouse_face_from_buffer_pos (Lisp_Object window,
30141 Mouse_HLInfo *hlinfo,
30142 ptrdiff_t mouse_charpos,
30143 ptrdiff_t start_charpos,
30144 ptrdiff_t end_charpos,
30145 Lisp_Object before_string,
30146 Lisp_Object after_string,
30147 Lisp_Object disp_string)
30149 struct window *w = XWINDOW (window);
30150 struct glyph_row *first = MATRIX_FIRST_TEXT_ROW (w->current_matrix);
30151 struct glyph_row *r1, *r2;
30152 struct glyph *glyph, *end;
30153 ptrdiff_t ignore, pos;
30154 int x;
30156 eassert (NILP (disp_string) || STRINGP (disp_string));
30157 eassert (NILP (before_string) || STRINGP (before_string));
30158 eassert (NILP (after_string) || STRINGP (after_string));
30160 /* Find the rows corresponding to START_CHARPOS and END_CHARPOS. */
30161 rows_from_pos_range (w, start_charpos, end_charpos, disp_string, &r1, &r2);
30162 if (r1 == NULL)
30163 r1 = MATRIX_ROW (w->current_matrix, w->window_end_vpos);
30164 /* If the before-string or display-string contains newlines,
30165 rows_from_pos_range skips to its last row. Move back. */
30166 if (!NILP (before_string) || !NILP (disp_string))
30168 struct glyph_row *prev;
30169 while ((prev = r1 - 1, prev >= first)
30170 && MATRIX_ROW_END_CHARPOS (prev) == start_charpos
30171 && prev->used[TEXT_AREA] > 0)
30173 struct glyph *beg = prev->glyphs[TEXT_AREA];
30174 glyph = beg + prev->used[TEXT_AREA];
30175 while (--glyph >= beg && NILP (glyph->object));
30176 if (glyph < beg
30177 || !(EQ (glyph->object, before_string)
30178 || EQ (glyph->object, disp_string)))
30179 break;
30180 r1 = prev;
30183 if (r2 == NULL)
30185 r2 = MATRIX_ROW (w->current_matrix, w->window_end_vpos);
30186 hlinfo->mouse_face_past_end = true;
30188 else if (!NILP (after_string))
30190 /* If the after-string has newlines, advance to its last row. */
30191 struct glyph_row *next;
30192 struct glyph_row *last
30193 = MATRIX_ROW (w->current_matrix, w->window_end_vpos);
30195 for (next = r2 + 1;
30196 next <= last
30197 && next->used[TEXT_AREA] > 0
30198 && EQ (next->glyphs[TEXT_AREA]->object, after_string);
30199 ++next)
30200 r2 = next;
30202 /* The rest of the display engine assumes that mouse_face_beg_row is
30203 either above mouse_face_end_row or identical to it. But with
30204 bidi-reordered continued lines, the row for START_CHARPOS could
30205 be below the row for END_CHARPOS. If so, swap the rows and store
30206 them in correct order. */
30207 if (r1->y > r2->y)
30209 struct glyph_row *tem = r2;
30211 r2 = r1;
30212 r1 = tem;
30215 hlinfo->mouse_face_beg_row = MATRIX_ROW_VPOS (r1, w->current_matrix);
30216 hlinfo->mouse_face_end_row = MATRIX_ROW_VPOS (r2, w->current_matrix);
30218 /* For a bidi-reordered row, the positions of BEFORE_STRING,
30219 AFTER_STRING, DISP_STRING, START_CHARPOS, and END_CHARPOS
30220 could be anywhere in the row and in any order. The strategy
30221 below is to find the leftmost and the rightmost glyph that
30222 belongs to either of these 3 strings, or whose position is
30223 between START_CHARPOS and END_CHARPOS, and highlight all the
30224 glyphs between those two. This may cover more than just the text
30225 between START_CHARPOS and END_CHARPOS if the range of characters
30226 strides the bidi level boundary, e.g. if the beginning is in R2L
30227 text while the end is in L2R text or vice versa. */
30228 if (!r1->reversed_p)
30230 /* This row is in a left to right paragraph. Scan it left to
30231 right. */
30232 glyph = r1->glyphs[TEXT_AREA];
30233 end = glyph + r1->used[TEXT_AREA];
30234 x = r1->x;
30236 /* Skip truncation glyphs at the start of the glyph row. */
30237 if (MATRIX_ROW_DISPLAYS_TEXT_P (r1))
30238 for (; glyph < end
30239 && NILP (glyph->object)
30240 && glyph->charpos < 0;
30241 ++glyph)
30242 x += glyph->pixel_width;
30244 /* Scan the glyph row, looking for BEFORE_STRING, AFTER_STRING,
30245 or DISP_STRING, and the first glyph from buffer whose
30246 position is between START_CHARPOS and END_CHARPOS. */
30247 for (; glyph < end
30248 && !NILP (glyph->object)
30249 && !EQ (glyph->object, disp_string)
30250 && !(BUFFERP (glyph->object)
30251 && (glyph->charpos >= start_charpos
30252 && glyph->charpos < end_charpos));
30253 ++glyph)
30255 /* BEFORE_STRING or AFTER_STRING are only relevant if they
30256 are present at buffer positions between START_CHARPOS and
30257 END_CHARPOS, or if they come from an overlay. */
30258 if (EQ (glyph->object, before_string))
30260 pos = string_buffer_position (before_string,
30261 start_charpos);
30262 /* If pos == 0, it means before_string came from an
30263 overlay, not from a buffer position. */
30264 if (!pos || (pos >= start_charpos && pos < end_charpos))
30265 break;
30267 else if (EQ (glyph->object, after_string))
30269 pos = string_buffer_position (after_string, end_charpos);
30270 if (!pos || (pos >= start_charpos && pos < end_charpos))
30271 break;
30273 x += glyph->pixel_width;
30275 hlinfo->mouse_face_beg_x = x;
30276 hlinfo->mouse_face_beg_col = glyph - r1->glyphs[TEXT_AREA];
30278 else
30280 /* This row is in a right to left paragraph. Scan it right to
30281 left. */
30282 struct glyph *g;
30284 end = r1->glyphs[TEXT_AREA] - 1;
30285 glyph = end + r1->used[TEXT_AREA];
30287 /* Skip truncation glyphs at the start of the glyph row. */
30288 if (MATRIX_ROW_DISPLAYS_TEXT_P (r1))
30289 for (; glyph > end
30290 && NILP (glyph->object)
30291 && glyph->charpos < 0;
30292 --glyph)
30295 /* Scan the glyph row, looking for BEFORE_STRING, AFTER_STRING,
30296 or DISP_STRING, and the first glyph from buffer whose
30297 position is between START_CHARPOS and END_CHARPOS. */
30298 for (; glyph > end
30299 && !NILP (glyph->object)
30300 && !EQ (glyph->object, disp_string)
30301 && !(BUFFERP (glyph->object)
30302 && (glyph->charpos >= start_charpos
30303 && glyph->charpos < end_charpos));
30304 --glyph)
30306 /* BEFORE_STRING or AFTER_STRING are only relevant if they
30307 are present at buffer positions between START_CHARPOS and
30308 END_CHARPOS, or if they come from an overlay. */
30309 if (EQ (glyph->object, before_string))
30311 pos = string_buffer_position (before_string, start_charpos);
30312 /* If pos == 0, it means before_string came from an
30313 overlay, not from a buffer position. */
30314 if (!pos || (pos >= start_charpos && pos < end_charpos))
30315 break;
30317 else if (EQ (glyph->object, after_string))
30319 pos = string_buffer_position (after_string, end_charpos);
30320 if (!pos || (pos >= start_charpos && pos < end_charpos))
30321 break;
30325 glyph++; /* first glyph to the right of the highlighted area */
30326 for (g = r1->glyphs[TEXT_AREA], x = r1->x; g < glyph; g++)
30327 x += g->pixel_width;
30328 hlinfo->mouse_face_beg_x = x;
30329 hlinfo->mouse_face_beg_col = glyph - r1->glyphs[TEXT_AREA];
30332 /* If the highlight ends in a different row, compute GLYPH and END
30333 for the end row. Otherwise, reuse the values computed above for
30334 the row where the highlight begins. */
30335 if (r2 != r1)
30337 if (!r2->reversed_p)
30339 glyph = r2->glyphs[TEXT_AREA];
30340 end = glyph + r2->used[TEXT_AREA];
30341 x = r2->x;
30343 else
30345 end = r2->glyphs[TEXT_AREA] - 1;
30346 glyph = end + r2->used[TEXT_AREA];
30350 if (!r2->reversed_p)
30352 /* Skip truncation and continuation glyphs near the end of the
30353 row, and also blanks and stretch glyphs inserted by
30354 extend_face_to_end_of_line. */
30355 while (end > glyph
30356 && NILP ((end - 1)->object))
30357 --end;
30358 /* Scan the rest of the glyph row from the end, looking for the
30359 first glyph that comes from BEFORE_STRING, AFTER_STRING, or
30360 DISP_STRING, or whose position is between START_CHARPOS
30361 and END_CHARPOS */
30362 for (--end;
30363 end > glyph
30364 && !NILP (end->object)
30365 && !EQ (end->object, disp_string)
30366 && !(BUFFERP (end->object)
30367 && (end->charpos >= start_charpos
30368 && end->charpos < end_charpos));
30369 --end)
30371 /* BEFORE_STRING or AFTER_STRING are only relevant if they
30372 are present at buffer positions between START_CHARPOS and
30373 END_CHARPOS, or if they come from an overlay. */
30374 if (EQ (end->object, before_string))
30376 pos = string_buffer_position (before_string, start_charpos);
30377 if (!pos || (pos >= start_charpos && pos < end_charpos))
30378 break;
30380 else if (EQ (end->object, after_string))
30382 pos = string_buffer_position (after_string, end_charpos);
30383 if (!pos || (pos >= start_charpos && pos < end_charpos))
30384 break;
30387 /* Find the X coordinate of the last glyph to be highlighted. */
30388 for (; glyph <= end; ++glyph)
30389 x += glyph->pixel_width;
30391 hlinfo->mouse_face_end_x = x;
30392 hlinfo->mouse_face_end_col = glyph - r2->glyphs[TEXT_AREA];
30394 else
30396 /* Skip truncation and continuation glyphs near the end of the
30397 row, and also blanks and stretch glyphs inserted by
30398 extend_face_to_end_of_line. */
30399 x = r2->x;
30400 end++;
30401 while (end < glyph
30402 && NILP (end->object))
30404 x += end->pixel_width;
30405 ++end;
30407 /* Scan the rest of the glyph row from the end, looking for the
30408 first glyph that comes from BEFORE_STRING, AFTER_STRING, or
30409 DISP_STRING, or whose position is between START_CHARPOS
30410 and END_CHARPOS */
30411 for ( ;
30412 end < glyph
30413 && !NILP (end->object)
30414 && !EQ (end->object, disp_string)
30415 && !(BUFFERP (end->object)
30416 && (end->charpos >= start_charpos
30417 && end->charpos < end_charpos));
30418 ++end)
30420 /* BEFORE_STRING or AFTER_STRING are only relevant if they
30421 are present at buffer positions between START_CHARPOS and
30422 END_CHARPOS, or if they come from an overlay. */
30423 if (EQ (end->object, before_string))
30425 pos = string_buffer_position (before_string, start_charpos);
30426 if (!pos || (pos >= start_charpos && pos < end_charpos))
30427 break;
30429 else if (EQ (end->object, after_string))
30431 pos = string_buffer_position (after_string, end_charpos);
30432 if (!pos || (pos >= start_charpos && pos < end_charpos))
30433 break;
30435 x += end->pixel_width;
30437 /* If we exited the above loop because we arrived at the last
30438 glyph of the row, and its buffer position is still not in
30439 range, it means the last character in range is the preceding
30440 newline. Bump the end column and x values to get past the
30441 last glyph. */
30442 if (end == glyph
30443 && BUFFERP (end->object)
30444 && (end->charpos < start_charpos
30445 || end->charpos >= end_charpos))
30447 x += end->pixel_width;
30448 ++end;
30450 hlinfo->mouse_face_end_x = x;
30451 hlinfo->mouse_face_end_col = end - r2->glyphs[TEXT_AREA];
30454 hlinfo->mouse_face_window = window;
30455 hlinfo->mouse_face_face_id
30456 = face_at_buffer_position (w, mouse_charpos, &ignore,
30457 mouse_charpos + 1,
30458 !hlinfo->mouse_face_hidden, -1);
30459 show_mouse_face (hlinfo, DRAW_MOUSE_FACE);
30462 /* The following function is not used anymore (replaced with
30463 mouse_face_from_string_pos), but I leave it here for the time
30464 being, in case someone would. */
30466 #if false /* not used */
30468 /* Find the position of the glyph for position POS in OBJECT in
30469 window W's current matrix, and return in *X, *Y the pixel
30470 coordinates, and return in *HPOS, *VPOS the column/row of the glyph.
30472 RIGHT_P means return the position of the right edge of the glyph.
30473 !RIGHT_P means return the left edge position.
30475 If no glyph for POS exists in the matrix, return the position of
30476 the glyph with the next smaller position that is in the matrix, if
30477 RIGHT_P is false. If RIGHT_P, and no glyph for POS
30478 exists in the matrix, return the position of the glyph with the
30479 next larger position in OBJECT.
30481 Value is true if a glyph was found. */
30483 static bool
30484 fast_find_string_pos (struct window *w, ptrdiff_t pos, Lisp_Object object,
30485 int *hpos, int *vpos, int *x, int *y, bool right_p)
30487 int yb = window_text_bottom_y (w);
30488 struct glyph_row *r;
30489 struct glyph *best_glyph = NULL;
30490 struct glyph_row *best_row = NULL;
30491 int best_x = 0;
30493 for (r = MATRIX_FIRST_TEXT_ROW (w->current_matrix);
30494 r->enabled_p && r->y < yb;
30495 ++r)
30497 struct glyph *g = r->glyphs[TEXT_AREA];
30498 struct glyph *e = g + r->used[TEXT_AREA];
30499 int gx;
30501 for (gx = r->x; g < e; gx += g->pixel_width, ++g)
30502 if (EQ (g->object, object))
30504 if (g->charpos == pos)
30506 best_glyph = g;
30507 best_x = gx;
30508 best_row = r;
30509 goto found;
30511 else if (best_glyph == NULL
30512 || ((eabs (g->charpos - pos)
30513 < eabs (best_glyph->charpos - pos))
30514 && (right_p
30515 ? g->charpos < pos
30516 : g->charpos > pos)))
30518 best_glyph = g;
30519 best_x = gx;
30520 best_row = r;
30525 found:
30527 if (best_glyph)
30529 *x = best_x;
30530 *hpos = best_glyph - best_row->glyphs[TEXT_AREA];
30532 if (right_p)
30534 *x += best_glyph->pixel_width;
30535 ++*hpos;
30538 *y = best_row->y;
30539 *vpos = MATRIX_ROW_VPOS (best_row, w->current_matrix);
30542 return best_glyph != NULL;
30544 #endif /* not used */
30546 /* Find the positions of the first and the last glyphs in window W's
30547 current matrix that occlude positions [STARTPOS..ENDPOS) in OBJECT
30548 (assumed to be a string), and return in HLINFO's mouse_face_*
30549 members the pixel and column/row coordinates of those glyphs. */
30551 static void
30552 mouse_face_from_string_pos (struct window *w, Mouse_HLInfo *hlinfo,
30553 Lisp_Object object,
30554 ptrdiff_t startpos, ptrdiff_t endpos)
30556 int yb = window_text_bottom_y (w);
30557 struct glyph_row *r;
30558 struct glyph *g, *e;
30559 int gx;
30560 bool found = false;
30562 /* Find the glyph row with at least one position in the range
30563 [STARTPOS..ENDPOS), and the first glyph in that row whose
30564 position belongs to that range. */
30565 for (r = MATRIX_FIRST_TEXT_ROW (w->current_matrix);
30566 r->enabled_p && r->y < yb;
30567 ++r)
30569 if (!r->reversed_p)
30571 g = r->glyphs[TEXT_AREA];
30572 e = g + r->used[TEXT_AREA];
30573 for (gx = r->x; g < e; gx += g->pixel_width, ++g)
30574 if (EQ (g->object, object)
30575 && startpos <= g->charpos && g->charpos < endpos)
30577 hlinfo->mouse_face_beg_row
30578 = MATRIX_ROW_VPOS (r, w->current_matrix);
30579 hlinfo->mouse_face_beg_col = g - r->glyphs[TEXT_AREA];
30580 hlinfo->mouse_face_beg_x = gx;
30581 found = true;
30582 break;
30585 else
30587 struct glyph *g1;
30589 e = r->glyphs[TEXT_AREA];
30590 g = e + r->used[TEXT_AREA];
30591 for ( ; g > e; --g)
30592 if (EQ ((g-1)->object, object)
30593 && startpos <= (g-1)->charpos && (g-1)->charpos < endpos)
30595 hlinfo->mouse_face_beg_row
30596 = MATRIX_ROW_VPOS (r, w->current_matrix);
30597 hlinfo->mouse_face_beg_col = g - r->glyphs[TEXT_AREA];
30598 for (gx = r->x, g1 = r->glyphs[TEXT_AREA]; g1 < g; ++g1)
30599 gx += g1->pixel_width;
30600 hlinfo->mouse_face_beg_x = gx;
30601 found = true;
30602 break;
30605 if (found)
30606 break;
30609 if (!found)
30610 return;
30612 /* Starting with the next row, look for the first row which does NOT
30613 include any glyphs whose positions are in the range. */
30614 for (++r; r->enabled_p && r->y < yb; ++r)
30616 g = r->glyphs[TEXT_AREA];
30617 e = g + r->used[TEXT_AREA];
30618 found = false;
30619 for ( ; g < e; ++g)
30620 if (EQ (g->object, object)
30621 && startpos <= g->charpos && g->charpos < endpos)
30623 found = true;
30624 break;
30626 if (!found)
30627 break;
30630 /* The highlighted region ends on the previous row. */
30631 r--;
30633 /* Set the end row. */
30634 hlinfo->mouse_face_end_row = MATRIX_ROW_VPOS (r, w->current_matrix);
30636 /* Compute and set the end column and the end column's horizontal
30637 pixel coordinate. */
30638 if (!r->reversed_p)
30640 g = r->glyphs[TEXT_AREA];
30641 e = g + r->used[TEXT_AREA];
30642 for ( ; e > g; --e)
30643 if (EQ ((e-1)->object, object)
30644 && startpos <= (e-1)->charpos && (e-1)->charpos < endpos)
30645 break;
30646 hlinfo->mouse_face_end_col = e - g;
30648 for (gx = r->x; g < e; ++g)
30649 gx += g->pixel_width;
30650 hlinfo->mouse_face_end_x = gx;
30652 else
30654 e = r->glyphs[TEXT_AREA];
30655 g = e + r->used[TEXT_AREA];
30656 for (gx = r->x ; e < g; ++e)
30658 if (EQ (e->object, object)
30659 && startpos <= e->charpos && e->charpos < endpos)
30660 break;
30661 gx += e->pixel_width;
30663 hlinfo->mouse_face_end_col = e - r->glyphs[TEXT_AREA];
30664 hlinfo->mouse_face_end_x = gx;
30668 #ifdef HAVE_WINDOW_SYSTEM
30670 /* See if position X, Y is within a hot-spot of an image. */
30672 static bool
30673 on_hot_spot_p (Lisp_Object hot_spot, int x, int y)
30675 if (!CONSP (hot_spot))
30676 return false;
30678 if (EQ (XCAR (hot_spot), Qrect))
30680 /* CDR is (Top-Left . Bottom-Right) = ((x0 . y0) . (x1 . y1)) */
30681 Lisp_Object rect = XCDR (hot_spot);
30682 Lisp_Object tem;
30683 if (!CONSP (rect))
30684 return false;
30685 if (!CONSP (XCAR (rect)))
30686 return false;
30687 if (!CONSP (XCDR (rect)))
30688 return false;
30689 if (!(tem = XCAR (XCAR (rect)), INTEGERP (tem) && x >= XINT (tem)))
30690 return false;
30691 if (!(tem = XCDR (XCAR (rect)), INTEGERP (tem) && y >= XINT (tem)))
30692 return false;
30693 if (!(tem = XCAR (XCDR (rect)), INTEGERP (tem) && x <= XINT (tem)))
30694 return false;
30695 if (!(tem = XCDR (XCDR (rect)), INTEGERP (tem) && y <= XINT (tem)))
30696 return false;
30697 return true;
30699 else if (EQ (XCAR (hot_spot), Qcircle))
30701 /* CDR is (Center . Radius) = ((x0 . y0) . r) */
30702 Lisp_Object circ = XCDR (hot_spot);
30703 Lisp_Object lr, lx0, ly0;
30704 if (CONSP (circ)
30705 && CONSP (XCAR (circ))
30706 && (lr = XCDR (circ), NUMBERP (lr))
30707 && (lx0 = XCAR (XCAR (circ)), INTEGERP (lx0))
30708 && (ly0 = XCDR (XCAR (circ)), INTEGERP (ly0)))
30710 double r = XFLOATINT (lr);
30711 double dx = XINT (lx0) - x;
30712 double dy = XINT (ly0) - y;
30713 return (dx * dx + dy * dy <= r * r);
30716 else if (EQ (XCAR (hot_spot), Qpoly))
30718 /* CDR is [x0 y0 x1 y1 x2 y2 ...x(n-1) y(n-1)] */
30719 if (VECTORP (XCDR (hot_spot)))
30721 struct Lisp_Vector *v = XVECTOR (XCDR (hot_spot));
30722 Lisp_Object *poly = v->contents;
30723 ptrdiff_t n = v->header.size;
30724 ptrdiff_t i;
30725 bool inside = false;
30726 Lisp_Object lx, ly;
30727 int x0, y0;
30729 /* Need an even number of coordinates, and at least 3 edges. */
30730 if (n < 6 || n & 1)
30731 return false;
30733 /* Count edge segments intersecting line from (X,Y) to (X,infinity).
30734 If count is odd, we are inside polygon. Pixels on edges
30735 may or may not be included depending on actual geometry of the
30736 polygon. */
30737 if ((lx = poly[n-2], !INTEGERP (lx))
30738 || (ly = poly[n-1], !INTEGERP (lx)))
30739 return false;
30740 x0 = XINT (lx), y0 = XINT (ly);
30741 for (i = 0; i < n; i += 2)
30743 int x1 = x0, y1 = y0;
30744 if ((lx = poly[i], !INTEGERP (lx))
30745 || (ly = poly[i+1], !INTEGERP (ly)))
30746 return false;
30747 x0 = XINT (lx), y0 = XINT (ly);
30749 /* Does this segment cross the X line? */
30750 if (x0 >= x)
30752 if (x1 >= x)
30753 continue;
30755 else if (x1 < x)
30756 continue;
30757 if (y > y0 && y > y1)
30758 continue;
30759 if (y < y0 + ((y1 - y0) * (x - x0)) / (x1 - x0))
30760 inside = !inside;
30762 return inside;
30765 return false;
30768 Lisp_Object
30769 find_hot_spot (Lisp_Object map, int x, int y)
30771 while (CONSP (map))
30773 if (CONSP (XCAR (map))
30774 && on_hot_spot_p (XCAR (XCAR (map)), x, y))
30775 return XCAR (map);
30776 map = XCDR (map);
30779 return Qnil;
30782 DEFUN ("lookup-image-map", Flookup_image_map, Slookup_image_map,
30783 3, 3, 0,
30784 doc: /* Lookup in image map MAP coordinates X and Y.
30785 An image map is an alist where each element has the format (AREA ID PLIST).
30786 An AREA is specified as either a rectangle, a circle, or a polygon:
30787 A rectangle is a cons (rect . ((x0 . y0) . (x1 . y1))) specifying the
30788 pixel coordinates of the upper left and bottom right corners.
30789 A circle is a cons (circle . ((x0 . y0) . r)) specifying the center
30790 and the radius of the circle; r may be a float or integer.
30791 A polygon is a cons (poly . [x0 y0 x1 y1 ...]) where each pair in the
30792 vector describes one corner in the polygon.
30793 Returns the alist element for the first matching AREA in MAP. */)
30794 (Lisp_Object map, Lisp_Object x, Lisp_Object y)
30796 if (NILP (map))
30797 return Qnil;
30799 CHECK_NUMBER (x);
30800 CHECK_NUMBER (y);
30802 return find_hot_spot (map,
30803 clip_to_bounds (INT_MIN, XINT (x), INT_MAX),
30804 clip_to_bounds (INT_MIN, XINT (y), INT_MAX));
30806 #endif /* HAVE_WINDOW_SYSTEM */
30809 /* Display frame CURSOR, optionally using shape defined by POINTER. */
30810 static void
30811 define_frame_cursor1 (struct frame *f, Cursor cursor, Lisp_Object pointer)
30813 #ifdef HAVE_WINDOW_SYSTEM
30814 if (!FRAME_WINDOW_P (f))
30815 return;
30817 /* Do not change cursor shape while dragging mouse. */
30818 if (EQ (do_mouse_tracking, Qdragging))
30819 return;
30821 if (!NILP (pointer))
30823 if (EQ (pointer, Qarrow))
30824 cursor = FRAME_X_OUTPUT (f)->nontext_cursor;
30825 else if (EQ (pointer, Qhand))
30826 cursor = FRAME_X_OUTPUT (f)->hand_cursor;
30827 else if (EQ (pointer, Qtext))
30828 cursor = FRAME_X_OUTPUT (f)->text_cursor;
30829 else if (EQ (pointer, intern ("hdrag")))
30830 cursor = FRAME_X_OUTPUT (f)->horizontal_drag_cursor;
30831 else if (EQ (pointer, intern ("nhdrag")))
30832 cursor = FRAME_X_OUTPUT (f)->vertical_drag_cursor;
30833 # ifdef HAVE_X_WINDOWS
30834 else if (EQ (pointer, intern ("vdrag")))
30835 cursor = FRAME_DISPLAY_INFO (f)->vertical_scroll_bar_cursor;
30836 # endif
30837 else if (EQ (pointer, intern ("hourglass")))
30838 cursor = FRAME_X_OUTPUT (f)->hourglass_cursor;
30839 else if (EQ (pointer, Qmodeline))
30840 cursor = FRAME_X_OUTPUT (f)->modeline_cursor;
30841 else
30842 cursor = FRAME_X_OUTPUT (f)->nontext_cursor;
30845 if (cursor != No_Cursor)
30846 FRAME_RIF (f)->define_frame_cursor (f, cursor);
30847 #endif
30850 /* Take proper action when mouse has moved to the mode or header line
30851 or marginal area AREA of window W, x-position X and y-position Y.
30852 X is relative to the start of the text display area of W, so the
30853 width of bitmap areas and scroll bars must be subtracted to get a
30854 position relative to the start of the mode line. */
30856 static void
30857 note_mode_line_or_margin_highlight (Lisp_Object window, int x, int y,
30858 enum window_part area)
30860 struct window *w = XWINDOW (window);
30861 struct frame *f = XFRAME (w->frame);
30862 Mouse_HLInfo *hlinfo = MOUSE_HL_INFO (f);
30863 Cursor cursor = No_Cursor;
30864 Lisp_Object pointer = Qnil;
30865 int dx, dy, width, height;
30866 ptrdiff_t charpos;
30867 Lisp_Object string, object = Qnil;
30868 Lisp_Object pos UNINIT;
30869 Lisp_Object mouse_face;
30870 int original_x_pixel = x;
30871 struct glyph * glyph = NULL, * row_start_glyph = NULL;
30872 struct glyph_row *row UNINIT;
30874 if (area == ON_MODE_LINE || area == ON_HEADER_LINE)
30876 int x0;
30877 struct glyph *end;
30879 /* Kludge alert: mode_line_string takes X/Y in pixels, but
30880 returns them in row/column units! */
30881 string = mode_line_string (w, area, &x, &y, &charpos,
30882 &object, &dx, &dy, &width, &height);
30884 row = (area == ON_MODE_LINE
30885 ? MATRIX_MODE_LINE_ROW (w->current_matrix)
30886 : MATRIX_HEADER_LINE_ROW (w->current_matrix));
30888 /* Find the glyph under the mouse pointer. */
30889 if (row->mode_line_p && row->enabled_p)
30891 glyph = row_start_glyph = row->glyphs[TEXT_AREA];
30892 end = glyph + row->used[TEXT_AREA];
30894 for (x0 = original_x_pixel;
30895 glyph < end && x0 >= glyph->pixel_width;
30896 ++glyph)
30897 x0 -= glyph->pixel_width;
30899 if (glyph >= end)
30900 glyph = NULL;
30903 else
30905 x -= WINDOW_LEFT_SCROLL_BAR_AREA_WIDTH (w);
30906 /* Kludge alert: marginal_area_string takes X/Y in pixels, but
30907 returns them in row/column units! */
30908 string = marginal_area_string (w, area, &x, &y, &charpos,
30909 &object, &dx, &dy, &width, &height);
30912 Lisp_Object help = Qnil;
30914 #ifdef HAVE_WINDOW_SYSTEM
30915 if (IMAGEP (object))
30917 Lisp_Object image_map, hotspot;
30918 if ((image_map = Fplist_get (XCDR (object), QCmap),
30919 !NILP (image_map))
30920 && (hotspot = find_hot_spot (image_map, dx, dy),
30921 CONSP (hotspot))
30922 && (hotspot = XCDR (hotspot), CONSP (hotspot)))
30924 Lisp_Object plist;
30926 /* Could check XCAR (hotspot) to see if we enter/leave this hot-spot.
30927 If so, we could look for mouse-enter, mouse-leave
30928 properties in PLIST (and do something...). */
30929 hotspot = XCDR (hotspot);
30930 if (CONSP (hotspot)
30931 && (plist = XCAR (hotspot), CONSP (plist)))
30933 pointer = Fplist_get (plist, Qpointer);
30934 if (NILP (pointer))
30935 pointer = Qhand;
30936 help = Fplist_get (plist, Qhelp_echo);
30937 if (!NILP (help))
30939 help_echo_string = help;
30940 XSETWINDOW (help_echo_window, w);
30941 help_echo_object = w->contents;
30942 help_echo_pos = charpos;
30946 if (NILP (pointer))
30947 pointer = Fplist_get (XCDR (object), QCpointer);
30949 #endif /* HAVE_WINDOW_SYSTEM */
30951 if (STRINGP (string))
30952 pos = make_number (charpos);
30954 /* Set the help text and mouse pointer. If the mouse is on a part
30955 of the mode line without any text (e.g. past the right edge of
30956 the mode line text), use that windows's mode line help echo if it
30957 has been set. */
30958 if (STRINGP (string) || area == ON_MODE_LINE)
30960 /* Arrange to display the help by setting the global variables
30961 help_echo_string, help_echo_object, and help_echo_pos. */
30962 if (NILP (help))
30964 if (STRINGP (string))
30965 help = Fget_text_property (pos, Qhelp_echo, string);
30967 if (!NILP (help))
30969 help_echo_string = help;
30970 XSETWINDOW (help_echo_window, w);
30971 help_echo_object = string;
30972 help_echo_pos = charpos;
30974 else if (area == ON_MODE_LINE
30975 && !NILP (w->mode_line_help_echo))
30977 help_echo_string = w->mode_line_help_echo;
30978 XSETWINDOW (help_echo_window, w);
30979 help_echo_object = Qnil;
30980 help_echo_pos = -1;
30984 #ifdef HAVE_WINDOW_SYSTEM
30985 /* Change the mouse pointer according to what is under it. */
30986 if (FRAME_WINDOW_P (f))
30988 bool draggable = (! WINDOW_BOTTOMMOST_P (w)
30989 || minibuf_level
30990 || NILP (Vresize_mini_windows));
30992 if (STRINGP (string))
30994 cursor = FRAME_X_OUTPUT (f)->nontext_cursor;
30996 if (NILP (pointer))
30997 pointer = Fget_text_property (pos, Qpointer, string);
30999 /* Change the mouse pointer according to what is under X/Y. */
31000 if (NILP (pointer)
31001 && (area == ON_MODE_LINE || area == ON_HEADER_LINE))
31003 Lisp_Object map;
31005 map = Fget_text_property (pos, Qlocal_map, string);
31006 if (!KEYMAPP (map))
31007 map = Fget_text_property (pos, Qkeymap, string);
31008 if (!KEYMAPP (map) && draggable && area == ON_MODE_LINE)
31009 cursor = FRAME_X_OUTPUT (f)->vertical_drag_cursor;
31012 else if (draggable && area == ON_MODE_LINE)
31013 cursor = FRAME_X_OUTPUT (f)->vertical_drag_cursor;
31014 else
31015 cursor = FRAME_X_OUTPUT (f)->nontext_cursor;
31017 #endif
31020 /* Change the mouse face according to what is under X/Y. */
31021 bool mouse_face_shown = false;
31023 if (STRINGP (string))
31025 mouse_face = Fget_text_property (pos, Qmouse_face, string);
31026 if (!NILP (Vmouse_highlight) && !NILP (mouse_face)
31027 && ((area == ON_MODE_LINE) || (area == ON_HEADER_LINE))
31028 && glyph)
31030 Lisp_Object b, e;
31032 struct glyph * tmp_glyph;
31034 int gpos;
31035 int gseq_length;
31036 int total_pixel_width;
31037 ptrdiff_t begpos, endpos, ignore;
31039 int vpos, hpos;
31041 b = Fprevious_single_property_change (make_number (charpos + 1),
31042 Qmouse_face, string, Qnil);
31043 if (NILP (b))
31044 begpos = 0;
31045 else
31046 begpos = XINT (b);
31048 e = Fnext_single_property_change (pos, Qmouse_face, string, Qnil);
31049 if (NILP (e))
31050 endpos = SCHARS (string);
31051 else
31052 endpos = XINT (e);
31054 /* Calculate the glyph position GPOS of GLYPH in the
31055 displayed string, relative to the beginning of the
31056 highlighted part of the string.
31058 Note: GPOS is different from CHARPOS. CHARPOS is the
31059 position of GLYPH in the internal string object. A mode
31060 line string format has structures which are converted to
31061 a flattened string by the Emacs Lisp interpreter. The
31062 internal string is an element of those structures. The
31063 displayed string is the flattened string. */
31064 tmp_glyph = row_start_glyph;
31065 while (tmp_glyph < glyph
31066 && (!(EQ (tmp_glyph->object, glyph->object)
31067 && begpos <= tmp_glyph->charpos
31068 && tmp_glyph->charpos < endpos)))
31069 tmp_glyph++;
31070 gpos = glyph - tmp_glyph;
31072 /* Calculate the length GSEQ_LENGTH of the glyph sequence of
31073 the highlighted part of the displayed string to which
31074 GLYPH belongs. Note: GSEQ_LENGTH is different from
31075 SCHARS (STRING), because the latter returns the length of
31076 the internal string. */
31077 for (tmp_glyph = row->glyphs[TEXT_AREA] + row->used[TEXT_AREA] - 1;
31078 tmp_glyph > glyph
31079 && (!(EQ (tmp_glyph->object, glyph->object)
31080 && begpos <= tmp_glyph->charpos
31081 && tmp_glyph->charpos < endpos));
31082 tmp_glyph--)
31084 gseq_length = gpos + (tmp_glyph - glyph) + 1;
31086 /* Calculate the total pixel width of all the glyphs between
31087 the beginning of the highlighted area and GLYPH. */
31088 total_pixel_width = 0;
31089 for (tmp_glyph = glyph - gpos; tmp_glyph != glyph; tmp_glyph++)
31090 total_pixel_width += tmp_glyph->pixel_width;
31092 /* Pre calculation of re-rendering position. Note: X is in
31093 column units here, after the call to mode_line_string or
31094 marginal_area_string. */
31095 hpos = x - gpos;
31096 vpos = (area == ON_MODE_LINE
31097 ? (w->current_matrix)->nrows - 1
31098 : 0);
31100 /* If GLYPH's position is included in the region that is
31101 already drawn in mouse face, we have nothing to do. */
31102 if ( EQ (window, hlinfo->mouse_face_window)
31103 && (!row->reversed_p
31104 ? (hlinfo->mouse_face_beg_col <= hpos
31105 && hpos < hlinfo->mouse_face_end_col)
31106 /* In R2L rows we swap BEG and END, see below. */
31107 : (hlinfo->mouse_face_end_col <= hpos
31108 && hpos < hlinfo->mouse_face_beg_col))
31109 && hlinfo->mouse_face_beg_row == vpos )
31110 return;
31112 if (clear_mouse_face (hlinfo))
31113 cursor = No_Cursor;
31115 if (!row->reversed_p)
31117 hlinfo->mouse_face_beg_col = hpos;
31118 hlinfo->mouse_face_beg_x = original_x_pixel
31119 - (total_pixel_width + dx);
31120 hlinfo->mouse_face_end_col = hpos + gseq_length;
31121 hlinfo->mouse_face_end_x = 0;
31123 else
31125 /* In R2L rows, show_mouse_face expects BEG and END
31126 coordinates to be swapped. */
31127 hlinfo->mouse_face_end_col = hpos;
31128 hlinfo->mouse_face_end_x = original_x_pixel
31129 - (total_pixel_width + dx);
31130 hlinfo->mouse_face_beg_col = hpos + gseq_length;
31131 hlinfo->mouse_face_beg_x = 0;
31134 hlinfo->mouse_face_beg_row = vpos;
31135 hlinfo->mouse_face_end_row = hlinfo->mouse_face_beg_row;
31136 hlinfo->mouse_face_past_end = false;
31137 hlinfo->mouse_face_window = window;
31139 hlinfo->mouse_face_face_id = face_at_string_position (w, string,
31140 charpos,
31141 0, &ignore,
31142 glyph->face_id,
31143 true);
31144 show_mouse_face (hlinfo, DRAW_MOUSE_FACE);
31145 mouse_face_shown = true;
31147 if (NILP (pointer))
31148 pointer = Qhand;
31152 /* If mouse-face doesn't need to be shown, clear any existing
31153 mouse-face. */
31154 if ((area == ON_MODE_LINE || area == ON_HEADER_LINE) && !mouse_face_shown)
31155 clear_mouse_face (hlinfo);
31157 define_frame_cursor1 (f, cursor, pointer);
31161 /* EXPORT:
31162 Take proper action when the mouse has moved to position X, Y on
31163 frame F with regards to highlighting portions of display that have
31164 mouse-face properties. Also de-highlight portions of display where
31165 the mouse was before, set the mouse pointer shape as appropriate
31166 for the mouse coordinates, and activate help echo (tooltips).
31167 X and Y can be negative or out of range. */
31169 void
31170 note_mouse_highlight (struct frame *f, int x, int y)
31172 Mouse_HLInfo *hlinfo = MOUSE_HL_INFO (f);
31173 enum window_part part = ON_NOTHING;
31174 Lisp_Object window;
31175 struct window *w;
31176 Cursor cursor = No_Cursor;
31177 Lisp_Object pointer = Qnil; /* Takes precedence over cursor! */
31178 struct buffer *b;
31180 /* When a menu is active, don't highlight because this looks odd. */
31181 #if defined (USE_X_TOOLKIT) || defined (USE_GTK) || defined (HAVE_NS) || defined (MSDOS)
31182 if (popup_activated ())
31183 return;
31184 #endif
31186 if (!f->glyphs_initialized_p
31187 || f->pointer_invisible)
31188 return;
31190 hlinfo->mouse_face_mouse_x = x;
31191 hlinfo->mouse_face_mouse_y = y;
31192 hlinfo->mouse_face_mouse_frame = f;
31194 if (hlinfo->mouse_face_defer)
31195 return;
31197 /* Which window is that in? */
31198 window = window_from_coordinates (f, x, y, &part, true);
31200 /* If displaying active text in another window, clear that. */
31201 if (! EQ (window, hlinfo->mouse_face_window)
31202 /* Also clear if we move out of text area in same window. */
31203 || (!NILP (hlinfo->mouse_face_window)
31204 && !NILP (window)
31205 && part != ON_TEXT
31206 && part != ON_MODE_LINE
31207 && part != ON_HEADER_LINE))
31208 clear_mouse_face (hlinfo);
31210 /* Reset help_echo_string. It will get recomputed below. */
31211 help_echo_string = Qnil;
31213 #ifdef HAVE_WINDOW_SYSTEM
31214 /* If the cursor is on the internal border of FRAME and FRAME's
31215 internal border is draggable, provide some visual feedback. */
31216 if (FRAME_INTERNAL_BORDER_WIDTH (f) > 0
31217 && !NILP (get_frame_param (f, Qdrag_internal_border)))
31219 enum internal_border_part part = frame_internal_border_part (f, x, y);
31221 switch (part)
31223 case INTERNAL_BORDER_NONE:
31224 if (cursor != FRAME_X_OUTPUT (f)->nontext_cursor)
31225 /* Reset cursor. */
31226 cursor = FRAME_X_OUTPUT (f)->nontext_cursor;
31227 break;
31228 case INTERNAL_BORDER_LEFT_EDGE:
31229 cursor = FRAME_X_OUTPUT (f)->left_edge_cursor;
31230 break;
31231 case INTERNAL_BORDER_TOP_LEFT_CORNER:
31232 cursor = FRAME_X_OUTPUT (f)->top_left_corner_cursor;
31233 break;
31234 case INTERNAL_BORDER_TOP_EDGE:
31235 cursor = FRAME_X_OUTPUT (f)->top_edge_cursor;
31236 break;
31237 case INTERNAL_BORDER_TOP_RIGHT_CORNER:
31238 cursor = FRAME_X_OUTPUT (f)->top_right_corner_cursor;
31239 break;
31240 case INTERNAL_BORDER_RIGHT_EDGE:
31241 cursor = FRAME_X_OUTPUT (f)->right_edge_cursor;
31242 break;
31243 case INTERNAL_BORDER_BOTTOM_RIGHT_CORNER:
31244 cursor = FRAME_X_OUTPUT (f)->bottom_right_corner_cursor;
31245 break;
31246 case INTERNAL_BORDER_BOTTOM_EDGE:
31247 cursor = FRAME_X_OUTPUT (f)->bottom_edge_cursor;
31248 break;
31249 case INTERNAL_BORDER_BOTTOM_LEFT_CORNER:
31250 cursor = FRAME_X_OUTPUT (f)->bottom_left_corner_cursor;
31251 break;
31252 default:
31253 /* This should not happen. */
31254 if (cursor != FRAME_X_OUTPUT (f)->nontext_cursor)
31255 cursor = FRAME_X_OUTPUT (f)->nontext_cursor;
31258 if (cursor != FRAME_X_OUTPUT (f)->nontext_cursor)
31260 /* Do we really want a help echo here? */
31261 help_echo_string = build_string ("drag-mouse-1: resize frame");
31262 goto set_cursor;
31265 #endif /* HAVE_WINDOW_SYSTEM */
31267 /* Not on a window -> return. */
31268 if (!WINDOWP (window))
31269 return;
31271 /* Convert to window-relative pixel coordinates. */
31272 w = XWINDOW (window);
31273 frame_to_window_pixel_xy (w, &x, &y);
31275 #if defined (HAVE_WINDOW_SYSTEM) && ! defined (USE_GTK) && ! defined (HAVE_NS)
31276 /* Handle tool-bar window differently since it doesn't display a
31277 buffer. */
31278 if (EQ (window, f->tool_bar_window))
31280 note_tool_bar_highlight (f, x, y);
31281 return;
31283 #endif
31285 /* Mouse is on the mode, header line or margin? */
31286 if (part == ON_MODE_LINE || part == ON_HEADER_LINE
31287 || part == ON_LEFT_MARGIN || part == ON_RIGHT_MARGIN)
31289 note_mode_line_or_margin_highlight (window, x, y, part);
31291 #ifdef HAVE_WINDOW_SYSTEM
31292 if (part == ON_LEFT_MARGIN || part == ON_RIGHT_MARGIN)
31294 cursor = FRAME_X_OUTPUT (f)->nontext_cursor;
31295 /* Show non-text cursor (Bug#16647). */
31296 goto set_cursor;
31298 else
31299 #endif
31300 return;
31303 #ifdef HAVE_WINDOW_SYSTEM
31304 if (part == ON_VERTICAL_BORDER)
31306 cursor = FRAME_X_OUTPUT (f)->horizontal_drag_cursor;
31307 help_echo_string = build_string ("drag-mouse-1: resize");
31308 goto set_cursor;
31310 else if (part == ON_RIGHT_DIVIDER)
31312 cursor = FRAME_X_OUTPUT (f)->horizontal_drag_cursor;
31313 help_echo_string = build_string ("drag-mouse-1: resize");
31314 goto set_cursor;
31316 else if (part == ON_BOTTOM_DIVIDER)
31317 if (! WINDOW_BOTTOMMOST_P (w)
31318 || minibuf_level
31319 || NILP (Vresize_mini_windows))
31321 cursor = FRAME_X_OUTPUT (f)->vertical_drag_cursor;
31322 help_echo_string = build_string ("drag-mouse-1: resize");
31323 goto set_cursor;
31325 else
31326 cursor = FRAME_X_OUTPUT (f)->nontext_cursor;
31327 else if (part == ON_LEFT_FRINGE || part == ON_RIGHT_FRINGE
31328 || part == ON_VERTICAL_SCROLL_BAR
31329 || part == ON_HORIZONTAL_SCROLL_BAR)
31330 cursor = FRAME_X_OUTPUT (f)->nontext_cursor;
31331 else
31332 cursor = FRAME_X_OUTPUT (f)->text_cursor;
31333 #endif
31335 /* Are we in a window whose display is up to date?
31336 And verify the buffer's text has not changed. */
31337 b = XBUFFER (w->contents);
31338 if (part == ON_TEXT && w->window_end_valid && !window_outdated (w))
31340 int hpos, vpos, dx, dy, area = LAST_AREA;
31341 ptrdiff_t pos;
31342 struct glyph *glyph;
31343 Lisp_Object object;
31344 Lisp_Object mouse_face = Qnil, position;
31345 Lisp_Object *overlay_vec = NULL;
31346 ptrdiff_t i, noverlays;
31347 struct buffer *obuf;
31348 ptrdiff_t obegv, ozv;
31349 bool same_region;
31351 /* Find the glyph under X/Y. */
31352 glyph = x_y_to_hpos_vpos (w, x, y, &hpos, &vpos, &dx, &dy, &area);
31354 #ifdef HAVE_WINDOW_SYSTEM
31355 /* Look for :pointer property on image. */
31356 if (glyph != NULL && glyph->type == IMAGE_GLYPH)
31358 struct image *img = IMAGE_OPT_FROM_ID (f, glyph->u.img_id);
31359 if (img != NULL && IMAGEP (img->spec))
31361 Lisp_Object image_map, hotspot;
31362 if ((image_map = Fplist_get (XCDR (img->spec), QCmap),
31363 !NILP (image_map))
31364 && (hotspot = find_hot_spot (image_map,
31365 glyph->slice.img.x + dx,
31366 glyph->slice.img.y + dy),
31367 CONSP (hotspot))
31368 && (hotspot = XCDR (hotspot), CONSP (hotspot)))
31370 Lisp_Object plist;
31372 /* Could check XCAR (hotspot) to see if we enter/leave
31373 this hot-spot.
31374 If so, we could look for mouse-enter, mouse-leave
31375 properties in PLIST (and do something...). */
31376 hotspot = XCDR (hotspot);
31377 if (CONSP (hotspot)
31378 && (plist = XCAR (hotspot), CONSP (plist)))
31380 pointer = Fplist_get (plist, Qpointer);
31381 if (NILP (pointer))
31382 pointer = Qhand;
31383 help_echo_string = Fplist_get (plist, Qhelp_echo);
31384 if (!NILP (help_echo_string))
31386 help_echo_window = window;
31387 help_echo_object = glyph->object;
31388 help_echo_pos = glyph->charpos;
31392 if (NILP (pointer))
31393 pointer = Fplist_get (XCDR (img->spec), QCpointer);
31396 #endif /* HAVE_WINDOW_SYSTEM */
31398 /* Clear mouse face if X/Y not over text. */
31399 if (glyph == NULL
31400 || area != TEXT_AREA
31401 || !MATRIX_ROW_DISPLAYS_TEXT_P (MATRIX_ROW (w->current_matrix, vpos))
31402 /* Glyph's OBJECT is nil for glyphs inserted by the
31403 display engine for its internal purposes, like truncation
31404 and continuation glyphs and blanks beyond the end of
31405 line's text on text terminals. If we are over such a
31406 glyph, we are not over any text. */
31407 || NILP (glyph->object)
31408 /* R2L rows have a stretch glyph at their front, which
31409 stands for no text, whereas L2R rows have no glyphs at
31410 all beyond the end of text. Treat such stretch glyphs
31411 like we do with NULL glyphs in L2R rows. */
31412 || (MATRIX_ROW (w->current_matrix, vpos)->reversed_p
31413 && glyph == MATRIX_ROW_GLYPH_START (w->current_matrix, vpos)
31414 && glyph->type == STRETCH_GLYPH
31415 && glyph->avoid_cursor_p))
31417 if (clear_mouse_face (hlinfo))
31418 cursor = No_Cursor;
31419 if (FRAME_WINDOW_P (f) && NILP (pointer))
31421 #ifdef HAVE_WINDOW_SYSTEM
31422 if (area != TEXT_AREA)
31423 cursor = FRAME_X_OUTPUT (f)->nontext_cursor;
31424 else
31425 pointer = Vvoid_text_area_pointer;
31426 #endif
31428 goto set_cursor;
31431 pos = glyph->charpos;
31432 object = glyph->object;
31433 if (!STRINGP (object) && !BUFFERP (object))
31434 goto set_cursor;
31436 /* If we get an out-of-range value, return now; avoid an error. */
31437 if (BUFFERP (object) && pos > BUF_Z (b))
31438 goto set_cursor;
31440 /* Make the window's buffer temporarily current for
31441 overlays_at and compute_char_face. */
31442 obuf = current_buffer;
31443 current_buffer = b;
31444 obegv = BEGV;
31445 ozv = ZV;
31446 BEGV = BEG;
31447 ZV = Z;
31449 /* Is this char mouse-active or does it have help-echo? */
31450 position = make_number (pos);
31452 USE_SAFE_ALLOCA;
31454 if (BUFFERP (object))
31456 /* Put all the overlays we want in a vector in overlay_vec. */
31457 GET_OVERLAYS_AT (pos, overlay_vec, noverlays, NULL, false);
31458 /* Sort overlays into increasing priority order. */
31459 noverlays = sort_overlays (overlay_vec, noverlays, w);
31461 else
31462 noverlays = 0;
31464 if (NILP (Vmouse_highlight))
31466 clear_mouse_face (hlinfo);
31467 goto check_help_echo;
31470 same_region = coords_in_mouse_face_p (w, hpos, vpos);
31472 if (same_region)
31473 cursor = No_Cursor;
31475 /* Check mouse-face highlighting. */
31476 if (! same_region
31477 /* If there exists an overlay with mouse-face overlapping
31478 the one we are currently highlighting, we have to check
31479 if we enter the overlapping overlay, and then highlight
31480 only that. Skip the check when mouse-face highlighting
31481 is currently hidden to avoid Bug#30519. */
31482 || (!hlinfo->mouse_face_hidden
31483 && OVERLAYP (hlinfo->mouse_face_overlay)
31484 && mouse_face_overlay_overlaps (hlinfo->mouse_face_overlay)))
31486 /* Find the highest priority overlay with a mouse-face. */
31487 Lisp_Object overlay = Qnil;
31488 for (i = noverlays - 1; i >= 0 && NILP (overlay); --i)
31490 mouse_face = Foverlay_get (overlay_vec[i], Qmouse_face);
31491 if (!NILP (mouse_face))
31492 overlay = overlay_vec[i];
31495 /* If we're highlighting the same overlay as before, there's
31496 no need to do that again. */
31497 if (!NILP (overlay) && EQ (overlay, hlinfo->mouse_face_overlay))
31498 goto check_help_echo;
31500 /* Clear the display of the old active region, if any. */
31501 if (clear_mouse_face (hlinfo))
31502 cursor = No_Cursor;
31504 /* Record the overlay, if any, to be highlighted. */
31505 hlinfo->mouse_face_overlay = overlay;
31507 /* If no overlay applies, get a text property. */
31508 if (NILP (overlay))
31509 mouse_face = Fget_text_property (position, Qmouse_face, object);
31511 /* Next, compute the bounds of the mouse highlighting and
31512 display it. */
31513 if (!NILP (mouse_face) && STRINGP (object))
31515 /* The mouse-highlighting comes from a display string
31516 with a mouse-face. */
31517 Lisp_Object s, e;
31518 ptrdiff_t ignore;
31520 s = Fprevious_single_property_change
31521 (make_number (pos + 1), Qmouse_face, object, Qnil);
31522 e = Fnext_single_property_change
31523 (position, Qmouse_face, object, Qnil);
31524 if (NILP (s))
31525 s = make_number (0);
31526 if (NILP (e))
31527 e = make_number (SCHARS (object));
31528 mouse_face_from_string_pos (w, hlinfo, object,
31529 XINT (s), XINT (e));
31530 hlinfo->mouse_face_past_end = false;
31531 hlinfo->mouse_face_window = window;
31532 hlinfo->mouse_face_face_id
31533 = face_at_string_position (w, object, pos, 0, &ignore,
31534 glyph->face_id, true);
31535 show_mouse_face (hlinfo, DRAW_MOUSE_FACE);
31536 cursor = No_Cursor;
31538 else
31540 /* The mouse-highlighting, if any, comes from an overlay
31541 or text property in the buffer. */
31542 Lisp_Object buffer UNINIT;
31543 Lisp_Object disp_string UNINIT;
31545 if (STRINGP (object))
31547 /* If we are on a display string with no mouse-face,
31548 check if the text under it has one. */
31549 struct glyph_row *r = MATRIX_ROW (w->current_matrix, vpos);
31550 ptrdiff_t start = MATRIX_ROW_START_CHARPOS (r);
31551 pos = string_buffer_position (object, start);
31552 if (pos > 0)
31554 mouse_face = get_char_property_and_overlay
31555 (make_number (pos), Qmouse_face, w->contents, &overlay);
31556 buffer = w->contents;
31557 disp_string = object;
31560 else
31562 buffer = object;
31563 disp_string = Qnil;
31566 if (!NILP (mouse_face))
31568 Lisp_Object before, after;
31569 Lisp_Object before_string, after_string;
31570 /* To correctly find the limits of mouse highlight
31571 in a bidi-reordered buffer, we must not use the
31572 optimization of limiting the search in
31573 previous-single-property-change and
31574 next-single-property-change, because
31575 rows_from_pos_range needs the real start and end
31576 positions to DTRT in this case. That's because
31577 the first row visible in a window does not
31578 necessarily display the character whose position
31579 is the smallest. */
31580 Lisp_Object lim1
31581 = NILP (BVAR (XBUFFER (buffer), bidi_display_reordering))
31582 ? Fmarker_position (w->start)
31583 : Qnil;
31584 Lisp_Object lim2
31585 = NILP (BVAR (XBUFFER (buffer), bidi_display_reordering))
31586 ? make_number (BUF_Z (XBUFFER (buffer))
31587 - w->window_end_pos)
31588 : Qnil;
31590 if (NILP (overlay))
31592 /* Handle the text property case. */
31593 before = Fprevious_single_property_change
31594 (make_number (pos + 1), Qmouse_face, buffer, lim1);
31595 after = Fnext_single_property_change
31596 (make_number (pos), Qmouse_face, buffer, lim2);
31597 before_string = after_string = Qnil;
31599 else
31601 /* Handle the overlay case. */
31602 before = Foverlay_start (overlay);
31603 after = Foverlay_end (overlay);
31604 before_string = Foverlay_get (overlay, Qbefore_string);
31605 after_string = Foverlay_get (overlay, Qafter_string);
31607 if (!STRINGP (before_string)) before_string = Qnil;
31608 if (!STRINGP (after_string)) after_string = Qnil;
31611 mouse_face_from_buffer_pos (window, hlinfo, pos,
31612 NILP (before)
31614 : XFASTINT (before),
31615 NILP (after)
31616 ? BUF_Z (XBUFFER (buffer))
31617 : XFASTINT (after),
31618 before_string, after_string,
31619 disp_string);
31620 cursor = No_Cursor;
31625 check_help_echo:
31627 /* Look for a `help-echo' property. */
31628 if (NILP (help_echo_string)) {
31629 Lisp_Object help, overlay;
31631 /* Check overlays first. */
31632 help = overlay = Qnil;
31633 for (i = noverlays - 1; i >= 0 && NILP (help); --i)
31635 overlay = overlay_vec[i];
31636 help = Foverlay_get (overlay, Qhelp_echo);
31639 if (!NILP (help))
31641 help_echo_string = help;
31642 help_echo_window = window;
31643 help_echo_object = overlay;
31644 help_echo_pos = pos;
31646 else
31648 Lisp_Object obj = glyph->object;
31649 ptrdiff_t charpos = glyph->charpos;
31651 /* Try text properties. */
31652 if (STRINGP (obj)
31653 && charpos >= 0
31654 && charpos < SCHARS (obj))
31656 help = Fget_text_property (make_number (charpos),
31657 Qhelp_echo, obj);
31658 if (NILP (help))
31660 /* If the string itself doesn't specify a help-echo,
31661 see if the buffer text ``under'' it does. */
31662 struct glyph_row *r
31663 = MATRIX_ROW (w->current_matrix, vpos);
31664 ptrdiff_t start = MATRIX_ROW_START_CHARPOS (r);
31665 ptrdiff_t p = string_buffer_position (obj, start);
31666 if (p > 0)
31668 help = Fget_char_property (make_number (p),
31669 Qhelp_echo, w->contents);
31670 if (!NILP (help))
31672 charpos = p;
31673 obj = w->contents;
31678 else if (BUFFERP (obj)
31679 && charpos >= BEGV
31680 && charpos < ZV)
31681 help = Fget_text_property (make_number (charpos), Qhelp_echo,
31682 obj);
31684 if (!NILP (help))
31686 help_echo_string = help;
31687 help_echo_window = window;
31688 help_echo_object = obj;
31689 help_echo_pos = charpos;
31694 #ifdef HAVE_WINDOW_SYSTEM
31695 /* Look for a `pointer' property. */
31696 if (FRAME_WINDOW_P (f) && NILP (pointer))
31698 /* Check overlays first. */
31699 for (i = noverlays - 1; i >= 0 && NILP (pointer); --i)
31700 pointer = Foverlay_get (overlay_vec[i], Qpointer);
31702 if (NILP (pointer))
31704 Lisp_Object obj = glyph->object;
31705 ptrdiff_t charpos = glyph->charpos;
31707 /* Try text properties. */
31708 if (STRINGP (obj)
31709 && charpos >= 0
31710 && charpos < SCHARS (obj))
31712 pointer = Fget_text_property (make_number (charpos),
31713 Qpointer, obj);
31714 if (NILP (pointer))
31716 /* If the string itself doesn't specify a pointer,
31717 see if the buffer text ``under'' it does. */
31718 struct glyph_row *r
31719 = MATRIX_ROW (w->current_matrix, vpos);
31720 ptrdiff_t start = MATRIX_ROW_START_CHARPOS (r);
31721 ptrdiff_t p = string_buffer_position (obj, start);
31722 if (p > 0)
31723 pointer = Fget_char_property (make_number (p),
31724 Qpointer, w->contents);
31727 else if (BUFFERP (obj)
31728 && charpos >= BEGV
31729 && charpos < ZV)
31730 pointer = Fget_text_property (make_number (charpos),
31731 Qpointer, obj);
31734 #endif /* HAVE_WINDOW_SYSTEM */
31736 BEGV = obegv;
31737 ZV = ozv;
31738 current_buffer = obuf;
31739 SAFE_FREE ();
31742 set_cursor:
31743 define_frame_cursor1 (f, cursor, pointer);
31747 /* EXPORT for RIF:
31748 Clear any mouse-face on window W. This function is part of the
31749 redisplay interface, and is called from try_window_id and similar
31750 functions to ensure the mouse-highlight is off. */
31752 void
31753 x_clear_window_mouse_face (struct window *w)
31755 Mouse_HLInfo *hlinfo = MOUSE_HL_INFO (XFRAME (w->frame));
31756 Lisp_Object window;
31758 block_input ();
31759 XSETWINDOW (window, w);
31760 if (EQ (window, hlinfo->mouse_face_window))
31761 clear_mouse_face (hlinfo);
31762 unblock_input ();
31766 /* EXPORT:
31767 Just discard the mouse face information for frame F, if any.
31768 This is used when the size of F is changed. */
31770 void
31771 cancel_mouse_face (struct frame *f)
31773 Lisp_Object window;
31774 Mouse_HLInfo *hlinfo = MOUSE_HL_INFO (f);
31776 window = hlinfo->mouse_face_window;
31777 if (! NILP (window) && XFRAME (XWINDOW (window)->frame) == f)
31778 reset_mouse_highlight (hlinfo);
31783 /***********************************************************************
31784 Exposure Events
31785 ***********************************************************************/
31787 #ifdef HAVE_WINDOW_SYSTEM
31789 /* Redraw the part of glyph row area AREA of glyph row ROW on window W
31790 which intersects rectangle R. R is in window-relative coordinates. */
31792 static void
31793 expose_area (struct window *w, struct glyph_row *row, XRectangle *r,
31794 enum glyph_row_area area)
31796 struct glyph *first = row->glyphs[area];
31797 struct glyph *end = row->glyphs[area] + row->used[area];
31798 struct glyph *last;
31799 int first_x, start_x, x;
31801 if (area == TEXT_AREA && row->fill_line_p)
31802 /* If row extends face to end of line write the whole line. */
31803 draw_glyphs (w, 0, row, area,
31804 0, row->used[area],
31805 DRAW_NORMAL_TEXT, 0);
31806 else
31808 /* Set START_X to the window-relative start position for drawing glyphs of
31809 AREA. The first glyph of the text area can be partially visible.
31810 The first glyphs of other areas cannot. */
31811 start_x = window_box_left_offset (w, area);
31812 x = start_x;
31813 if (area == TEXT_AREA)
31814 x += row->x;
31816 /* Find the first glyph that must be redrawn. */
31817 while (first < end
31818 && x + first->pixel_width < r->x)
31820 x += first->pixel_width;
31821 ++first;
31824 /* Find the last one. */
31825 last = first;
31826 first_x = x;
31827 /* Use a signed int intermediate value to avoid catastrophic
31828 failures due to comparison between signed and unsigned, when
31829 x is negative (can happen for wide images that are hscrolled). */
31830 int r_end = r->x + r->width;
31831 while (last < end && x < r_end)
31833 x += last->pixel_width;
31834 ++last;
31837 /* Repaint. */
31838 if (last > first)
31839 draw_glyphs (w, first_x - start_x, row, area,
31840 first - row->glyphs[area], last - row->glyphs[area],
31841 DRAW_NORMAL_TEXT, 0);
31846 /* Redraw the parts of the glyph row ROW on window W intersecting
31847 rectangle R. R is in window-relative coordinates. Value is
31848 true if mouse-face was overwritten. */
31850 static bool
31851 expose_line (struct window *w, struct glyph_row *row, XRectangle *r)
31853 eassert (row->enabled_p);
31855 if (row->mode_line_p || w->pseudo_window_p)
31856 draw_glyphs (w, 0, row, TEXT_AREA,
31857 0, row->used[TEXT_AREA],
31858 DRAW_NORMAL_TEXT, 0);
31859 else
31861 if (row->used[LEFT_MARGIN_AREA])
31862 expose_area (w, row, r, LEFT_MARGIN_AREA);
31863 if (row->used[TEXT_AREA])
31864 expose_area (w, row, r, TEXT_AREA);
31865 if (row->used[RIGHT_MARGIN_AREA])
31866 expose_area (w, row, r, RIGHT_MARGIN_AREA);
31867 draw_row_fringe_bitmaps (w, row);
31870 return row->mouse_face_p;
31874 /* Redraw those parts of glyphs rows during expose event handling that
31875 overlap other rows. Redrawing of an exposed line writes over parts
31876 of lines overlapping that exposed line; this function fixes that.
31878 W is the window being exposed. FIRST_OVERLAPPING_ROW is the first
31879 row in W's current matrix that is exposed and overlaps other rows.
31880 LAST_OVERLAPPING_ROW is the last such row. */
31882 static void
31883 expose_overlaps (struct window *w,
31884 struct glyph_row *first_overlapping_row,
31885 struct glyph_row *last_overlapping_row,
31886 XRectangle *r)
31888 struct glyph_row *row;
31890 for (row = first_overlapping_row; row <= last_overlapping_row; ++row)
31891 if (row->overlapping_p)
31893 eassert (row->enabled_p && !row->mode_line_p);
31895 row->clip = r;
31896 if (row->used[LEFT_MARGIN_AREA])
31897 x_fix_overlapping_area (w, row, LEFT_MARGIN_AREA, OVERLAPS_BOTH);
31899 if (row->used[TEXT_AREA])
31900 x_fix_overlapping_area (w, row, TEXT_AREA, OVERLAPS_BOTH);
31902 if (row->used[RIGHT_MARGIN_AREA])
31903 x_fix_overlapping_area (w, row, RIGHT_MARGIN_AREA, OVERLAPS_BOTH);
31904 row->clip = NULL;
31909 /* Return true if W's cursor intersects rectangle R. */
31911 static bool
31912 phys_cursor_in_rect_p (struct window *w, XRectangle *r)
31914 XRectangle cr, result;
31915 struct glyph *cursor_glyph;
31916 struct glyph_row *row;
31918 if (w->phys_cursor.vpos >= 0
31919 && w->phys_cursor.vpos < w->current_matrix->nrows
31920 && (row = MATRIX_ROW (w->current_matrix, w->phys_cursor.vpos),
31921 row->enabled_p)
31922 && row->cursor_in_fringe_p)
31924 /* Cursor is in the fringe. */
31925 cr.x = window_box_right_offset (w,
31926 (WINDOW_HAS_FRINGES_OUTSIDE_MARGINS (w)
31927 ? RIGHT_MARGIN_AREA
31928 : TEXT_AREA));
31929 cr.y = row->y;
31930 cr.width = WINDOW_RIGHT_FRINGE_WIDTH (w);
31931 cr.height = row->height;
31932 return x_intersect_rectangles (&cr, r, &result);
31935 cursor_glyph = get_phys_cursor_glyph (w);
31936 if (cursor_glyph)
31938 /* r is relative to W's box, but w->phys_cursor.x is relative
31939 to left edge of W's TEXT area. Adjust it. */
31940 cr.x = window_box_left_offset (w, TEXT_AREA) + w->phys_cursor.x;
31941 cr.y = w->phys_cursor.y;
31942 cr.width = cursor_glyph->pixel_width;
31943 cr.height = w->phys_cursor_height;
31944 /* ++KFS: W32 version used W32-specific IntersectRect here, but
31945 I assume the effect is the same -- and this is portable. */
31946 return x_intersect_rectangles (&cr, r, &result);
31948 /* If we don't understand the format, pretend we're not in the hot-spot. */
31949 return false;
31953 /* EXPORT:
31954 Draw a vertical window border to the right of window W if W doesn't
31955 have vertical scroll bars. */
31957 void
31958 x_draw_vertical_border (struct window *w)
31960 struct frame *f = XFRAME (WINDOW_FRAME (w));
31962 /* We could do better, if we knew what type of scroll-bar the adjacent
31963 windows (on either side) have... But we don't :-(
31964 However, I think this works ok. ++KFS 2003-04-25 */
31966 /* Redraw borders between horizontally adjacent windows. Don't
31967 do it for frames with vertical scroll bars because either the
31968 right scroll bar of a window, or the left scroll bar of its
31969 neighbor will suffice as a border. */
31970 if (FRAME_HAS_VERTICAL_SCROLL_BARS (f) || FRAME_RIGHT_DIVIDER_WIDTH (f))
31971 return;
31973 /* Note: It is necessary to redraw both the left and the right
31974 borders, for when only this single window W is being
31975 redisplayed. */
31976 if (!WINDOW_RIGHTMOST_P (w)
31977 && !WINDOW_HAS_VERTICAL_SCROLL_BAR_ON_RIGHT (w))
31979 int x0, x1, y0, y1;
31981 window_box_edges (w, &x0, &y0, &x1, &y1);
31982 y1 -= 1;
31984 if (WINDOW_LEFT_FRINGE_WIDTH (w) == 0)
31985 x1 -= 1;
31987 FRAME_RIF (f)->draw_vertical_window_border (w, x1, y0, y1);
31990 if (!WINDOW_LEFTMOST_P (w)
31991 && !WINDOW_HAS_VERTICAL_SCROLL_BAR_ON_LEFT (w))
31993 int x0, x1, y0, y1;
31995 window_box_edges (w, &x0, &y0, &x1, &y1);
31996 y1 -= 1;
31998 if (WINDOW_LEFT_FRINGE_WIDTH (w) == 0)
31999 x0 -= 1;
32001 FRAME_RIF (f)->draw_vertical_window_border (w, x0, y0, y1);
32006 /* Draw window dividers for window W. */
32008 void
32009 x_draw_right_divider (struct window *w)
32011 struct frame *f = WINDOW_XFRAME (w);
32013 if (w->mini || w->pseudo_window_p)
32014 return;
32015 else if (WINDOW_RIGHT_DIVIDER_WIDTH (w))
32017 int x0 = WINDOW_RIGHT_EDGE_X (w) - WINDOW_RIGHT_DIVIDER_WIDTH (w);
32018 int x1 = WINDOW_RIGHT_EDGE_X (w);
32019 int y0 = WINDOW_TOP_EDGE_Y (w);
32020 int y1 = WINDOW_BOTTOM_EDGE_Y (w);
32022 /* If W is horizontally combined and has a right sibling, don't
32023 draw over any bottom divider. */
32024 if (WINDOW_BOTTOM_DIVIDER_WIDTH (w)
32025 && !NILP (w->parent)
32026 && WINDOW_HORIZONTAL_COMBINATION_P (XWINDOW (w->parent))
32027 && !NILP (w->next))
32028 y1 -= WINDOW_BOTTOM_DIVIDER_WIDTH (w);
32030 FRAME_RIF (f)->draw_window_divider (w, x0, x1, y0, y1);
32034 static void
32035 x_draw_bottom_divider (struct window *w)
32037 struct frame *f = XFRAME (WINDOW_FRAME (w));
32039 if (w->mini || w->pseudo_window_p)
32040 return;
32041 else if (WINDOW_BOTTOM_DIVIDER_WIDTH (w))
32043 int x0 = WINDOW_LEFT_EDGE_X (w);
32044 int x1 = WINDOW_RIGHT_EDGE_X (w);
32045 int y0 = WINDOW_BOTTOM_EDGE_Y (w) - WINDOW_BOTTOM_DIVIDER_WIDTH (w);
32046 int y1 = WINDOW_BOTTOM_EDGE_Y (w);
32047 struct window *p = !NILP (w->parent) ? XWINDOW (w->parent) : NULL;
32049 /* If W is vertically combined and has a sibling below, don't draw
32050 over any right divider. */
32051 if (WINDOW_RIGHT_DIVIDER_WIDTH (w)
32052 && p
32053 && ((WINDOW_VERTICAL_COMBINATION_P (p)
32054 && !NILP (w->next))
32055 || (WINDOW_HORIZONTAL_COMBINATION_P (p)
32056 && NILP (w->next)
32057 && !NILP (p->parent)
32058 && WINDOW_VERTICAL_COMBINATION_P (XWINDOW (p->parent))
32059 && !NILP (XWINDOW (p->parent)->next))))
32060 x1 -= WINDOW_RIGHT_DIVIDER_WIDTH (w);
32062 FRAME_RIF (f)->draw_window_divider (w, x0, x1, y0, y1);
32066 /* Redraw the part of window W intersection rectangle FR. Pixel
32067 coordinates in FR are frame-relative. Call this function with
32068 input blocked. Value is true if the exposure overwrites
32069 mouse-face. */
32071 static bool
32072 expose_window (struct window *w, XRectangle *fr)
32074 struct frame *f = XFRAME (w->frame);
32075 XRectangle wr, r;
32076 bool mouse_face_overwritten_p = false;
32078 /* If window is not yet fully initialized, do nothing. This can
32079 happen when toolkit scroll bars are used and a window is split.
32080 Reconfiguring the scroll bar will generate an expose for a newly
32081 created window. */
32082 if (w->current_matrix == NULL)
32083 return false;
32085 /* When we're currently updating the window, display and current
32086 matrix usually don't agree. Arrange for a thorough display
32087 later. */
32088 if (w->must_be_updated_p)
32090 SET_FRAME_GARBAGED (f);
32091 return false;
32094 /* Frame-relative pixel rectangle of W. */
32095 wr.x = WINDOW_LEFT_EDGE_X (w);
32096 wr.y = WINDOW_TOP_EDGE_Y (w);
32097 wr.width = WINDOW_PIXEL_WIDTH (w);
32098 wr.height = WINDOW_PIXEL_HEIGHT (w);
32100 if (x_intersect_rectangles (fr, &wr, &r))
32102 int yb = window_text_bottom_y (w);
32103 struct glyph_row *row;
32104 struct glyph_row *first_overlapping_row, *last_overlapping_row;
32106 TRACE ((stderr, "expose_window (%d, %d, %d, %d)\n",
32107 r.x, r.y, r.width, r.height));
32109 /* Convert to window coordinates. */
32110 r.x -= WINDOW_LEFT_EDGE_X (w);
32111 r.y -= WINDOW_TOP_EDGE_Y (w);
32113 /* Turn off the cursor. */
32114 bool cursor_cleared_p = (!w->pseudo_window_p
32115 && phys_cursor_in_rect_p (w, &r));
32116 if (cursor_cleared_p)
32117 x_clear_cursor (w);
32119 /* If the row containing the cursor extends face to end of line,
32120 then expose_area might overwrite the cursor outside the
32121 rectangle and thus notice_overwritten_cursor might clear
32122 w->phys_cursor_on_p. We remember the original value and
32123 check later if it is changed. */
32124 bool phys_cursor_on_p = w->phys_cursor_on_p;
32126 /* Use a signed int intermediate value to avoid catastrophic
32127 failures due to comparison between signed and unsigned, when
32128 y0 or y1 is negative (can happen for tall images). */
32129 int r_bottom = r.y + r.height;
32131 /* Update lines intersecting rectangle R. */
32132 first_overlapping_row = last_overlapping_row = NULL;
32133 for (row = w->current_matrix->rows;
32134 row->enabled_p;
32135 ++row)
32137 int y0 = row->y;
32138 int y1 = MATRIX_ROW_BOTTOM_Y (row);
32140 if ((y0 >= r.y && y0 < r_bottom)
32141 || (y1 > r.y && y1 < r_bottom)
32142 || (r.y >= y0 && r.y < y1)
32143 || (r_bottom > y0 && r_bottom < y1))
32145 /* A header line may be overlapping, but there is no need
32146 to fix overlapping areas for them. KFS 2005-02-12 */
32147 if (row->overlapping_p && !row->mode_line_p)
32149 if (first_overlapping_row == NULL)
32150 first_overlapping_row = row;
32151 last_overlapping_row = row;
32154 row->clip = fr;
32155 if (expose_line (w, row, &r))
32156 mouse_face_overwritten_p = true;
32157 row->clip = NULL;
32159 else if (row->overlapping_p)
32161 /* We must redraw a row overlapping the exposed area. */
32162 if (y0 < r.y
32163 ? y0 + row->phys_height > r.y
32164 : y0 + row->ascent - row->phys_ascent < r.y +r.height)
32166 if (first_overlapping_row == NULL)
32167 first_overlapping_row = row;
32168 last_overlapping_row = row;
32172 if (y1 >= yb)
32173 break;
32176 /* Display the mode line if there is one. */
32177 if (window_wants_mode_line (w)
32178 && (row = MATRIX_MODE_LINE_ROW (w->current_matrix),
32179 row->enabled_p)
32180 && row->y < r_bottom)
32182 if (expose_line (w, row, &r))
32183 mouse_face_overwritten_p = true;
32186 if (!w->pseudo_window_p)
32188 /* Fix the display of overlapping rows. */
32189 if (first_overlapping_row)
32190 expose_overlaps (w, first_overlapping_row, last_overlapping_row,
32191 fr);
32193 /* Draw border between windows. */
32194 if (WINDOW_RIGHT_DIVIDER_WIDTH (w))
32195 x_draw_right_divider (w);
32196 else
32197 x_draw_vertical_border (w);
32199 if (WINDOW_BOTTOM_DIVIDER_WIDTH (w))
32200 x_draw_bottom_divider (w);
32202 /* Turn the cursor on again. */
32203 if (cursor_cleared_p
32204 || (phys_cursor_on_p && !w->phys_cursor_on_p))
32205 update_window_cursor (w, true);
32209 return mouse_face_overwritten_p;
32214 /* Redraw (parts) of all windows in the window tree rooted at W that
32215 intersect R. R contains frame pixel coordinates. Value is
32216 true if the exposure overwrites mouse-face. */
32218 static bool
32219 expose_window_tree (struct window *w, XRectangle *r)
32221 struct frame *f = XFRAME (w->frame);
32222 bool mouse_face_overwritten_p = false;
32224 while (w && !FRAME_GARBAGED_P (f))
32226 mouse_face_overwritten_p
32227 |= (WINDOWP (w->contents)
32228 ? expose_window_tree (XWINDOW (w->contents), r)
32229 : expose_window (w, r));
32231 w = NILP (w->next) ? NULL : XWINDOW (w->next);
32234 return mouse_face_overwritten_p;
32238 /* EXPORT:
32239 Redisplay an exposed area of frame F. X and Y are the upper-left
32240 corner of the exposed rectangle. W and H are width and height of
32241 the exposed area. All are pixel values. W or H zero means redraw
32242 the entire frame. */
32244 void
32245 expose_frame (struct frame *f, int x, int y, int w, int h)
32247 XRectangle r;
32248 bool mouse_face_overwritten_p = false;
32250 TRACE ((stderr, "expose_frame "));
32252 /* No need to redraw if frame will be redrawn soon. */
32253 if (FRAME_GARBAGED_P (f))
32255 TRACE ((stderr, " garbaged\n"));
32256 return;
32259 /* If basic faces haven't been realized yet, there is no point in
32260 trying to redraw anything. This can happen when we get an expose
32261 event while Emacs is starting, e.g. by moving another window. */
32262 if (FRAME_FACE_CACHE (f) == NULL
32263 || FRAME_FACE_CACHE (f)->used < BASIC_FACE_ID_SENTINEL)
32265 TRACE ((stderr, " no faces\n"));
32266 return;
32269 if (w == 0 || h == 0)
32271 r.x = r.y = 0;
32272 r.width = FRAME_TEXT_WIDTH (f);
32273 r.height = FRAME_TEXT_HEIGHT (f);
32275 else
32277 r.x = x;
32278 r.y = y;
32279 r.width = w;
32280 r.height = h;
32283 TRACE ((stderr, "(%d, %d, %d, %d)\n", r.x, r.y, r.width, r.height));
32284 mouse_face_overwritten_p = expose_window_tree (XWINDOW (f->root_window), &r);
32286 #if ! defined (USE_GTK) && ! defined (HAVE_NS)
32287 if (WINDOWP (f->tool_bar_window))
32288 mouse_face_overwritten_p
32289 |= expose_window (XWINDOW (f->tool_bar_window), &r);
32290 #endif
32292 #ifdef HAVE_X_WINDOWS
32293 #ifndef MSDOS
32294 #if ! defined (USE_X_TOOLKIT) && ! defined (USE_GTK)
32295 if (WINDOWP (f->menu_bar_window))
32296 mouse_face_overwritten_p
32297 |= expose_window (XWINDOW (f->menu_bar_window), &r);
32298 #endif /* not USE_X_TOOLKIT and not USE_GTK */
32299 #endif
32300 #endif
32302 /* Some window managers support a focus-follows-mouse style with
32303 delayed raising of frames. Imagine a partially obscured frame,
32304 and moving the mouse into partially obscured mouse-face on that
32305 frame. The visible part of the mouse-face will be highlighted,
32306 then the WM raises the obscured frame. With at least one WM, KDE
32307 2.1, Emacs is not getting any event for the raising of the frame
32308 (even tried with SubstructureRedirectMask), only Expose events.
32309 These expose events will draw text normally, i.e. not
32310 highlighted. Which means we must redo the highlight here.
32311 Subsume it under ``we love X''. --gerd 2001-08-15 */
32312 /* Included in Windows version because Windows most likely does not
32313 do the right thing if any third party tool offers
32314 focus-follows-mouse with delayed raise. --jason 2001-10-12 */
32315 if (mouse_face_overwritten_p && !FRAME_GARBAGED_P (f))
32317 Mouse_HLInfo *hlinfo = MOUSE_HL_INFO (f);
32318 if (f == hlinfo->mouse_face_mouse_frame)
32320 int mouse_x = hlinfo->mouse_face_mouse_x;
32321 int mouse_y = hlinfo->mouse_face_mouse_y;
32322 clear_mouse_face (hlinfo);
32323 note_mouse_highlight (f, mouse_x, mouse_y);
32329 /* EXPORT:
32330 Determine the intersection of two rectangles R1 and R2. Return
32331 the intersection in *RESULT. Value is true if RESULT is not
32332 empty. */
32334 bool
32335 x_intersect_rectangles (XRectangle *r1, XRectangle *r2, XRectangle *result)
32337 XRectangle *left, *right;
32338 XRectangle *upper, *lower;
32339 bool intersection_p = false;
32341 /* Rearrange so that R1 is the left-most rectangle. */
32342 if (r1->x < r2->x)
32343 left = r1, right = r2;
32344 else
32345 left = r2, right = r1;
32347 /* X0 of the intersection is right.x0, if this is inside R1,
32348 otherwise there is no intersection. */
32349 if (right->x <= left->x + left->width)
32351 result->x = right->x;
32353 /* The right end of the intersection is the minimum of
32354 the right ends of left and right. */
32355 result->width = (min (left->x + left->width, right->x + right->width)
32356 - result->x);
32358 /* Same game for Y. */
32359 if (r1->y < r2->y)
32360 upper = r1, lower = r2;
32361 else
32362 upper = r2, lower = r1;
32364 /* The upper end of the intersection is lower.y0, if this is inside
32365 of upper. Otherwise, there is no intersection. */
32366 if (lower->y <= upper->y + upper->height)
32368 result->y = lower->y;
32370 /* The lower end of the intersection is the minimum of the lower
32371 ends of upper and lower. */
32372 result->height = (min (lower->y + lower->height,
32373 upper->y + upper->height)
32374 - result->y);
32375 intersection_p = true;
32379 return intersection_p;
32382 #endif /* HAVE_WINDOW_SYSTEM */
32385 /***********************************************************************
32386 Initialization
32387 ***********************************************************************/
32389 void
32390 syms_of_xdisp (void)
32392 Vwith_echo_area_save_vector = Qnil;
32393 staticpro (&Vwith_echo_area_save_vector);
32395 Vmessage_stack = Qnil;
32396 staticpro (&Vmessage_stack);
32398 /* Non-nil means don't actually do any redisplay. */
32399 DEFSYM (Qinhibit_redisplay, "inhibit-redisplay");
32401 DEFSYM (Qredisplay_internal_xC_functionx, "redisplay_internal (C function)");
32403 DEFVAR_BOOL("inhibit-message", inhibit_message,
32404 doc: /* Non-nil means calls to `message' are not displayed.
32405 They are still logged to the *Messages* buffer. */);
32406 inhibit_message = 0;
32408 message_dolog_marker1 = Fmake_marker ();
32409 staticpro (&message_dolog_marker1);
32410 message_dolog_marker2 = Fmake_marker ();
32411 staticpro (&message_dolog_marker2);
32412 message_dolog_marker3 = Fmake_marker ();
32413 staticpro (&message_dolog_marker3);
32415 defsubr (&Sset_buffer_redisplay);
32416 #ifdef GLYPH_DEBUG
32417 defsubr (&Sdump_frame_glyph_matrix);
32418 defsubr (&Sdump_glyph_matrix);
32419 defsubr (&Sdump_glyph_row);
32420 defsubr (&Sdump_tool_bar_row);
32421 defsubr (&Strace_redisplay);
32422 defsubr (&Strace_to_stderr);
32423 #endif
32424 #ifdef HAVE_WINDOW_SYSTEM
32425 defsubr (&Stool_bar_height);
32426 defsubr (&Slookup_image_map);
32427 #endif
32428 defsubr (&Sline_pixel_height);
32429 defsubr (&Sformat_mode_line);
32430 defsubr (&Sinvisible_p);
32431 defsubr (&Scurrent_bidi_paragraph_direction);
32432 defsubr (&Swindow_text_pixel_size);
32433 defsubr (&Smove_point_visually);
32434 defsubr (&Sbidi_find_overridden_directionality);
32436 DEFSYM (Qmenu_bar_update_hook, "menu-bar-update-hook");
32437 DEFSYM (Qoverriding_terminal_local_map, "overriding-terminal-local-map");
32438 DEFSYM (Qoverriding_local_map, "overriding-local-map");
32439 DEFSYM (Qwindow_scroll_functions, "window-scroll-functions");
32440 DEFSYM (Qredisplay_end_trigger_functions, "redisplay-end-trigger-functions");
32441 DEFSYM (Qinhibit_point_motion_hooks, "inhibit-point-motion-hooks");
32442 DEFSYM (Qeval, "eval");
32443 DEFSYM (QCdata, ":data");
32445 /* Names of text properties relevant for redisplay. */
32446 DEFSYM (Qdisplay, "display");
32447 DEFSYM (Qspace_width, "space-width");
32448 DEFSYM (Qraise, "raise");
32449 DEFSYM (Qslice, "slice");
32450 DEFSYM (Qspace, "space");
32451 DEFSYM (Qmargin, "margin");
32452 DEFSYM (Qpointer, "pointer");
32453 DEFSYM (Qleft_margin, "left-margin");
32454 DEFSYM (Qright_margin, "right-margin");
32455 DEFSYM (Qcenter, "center");
32456 DEFSYM (Qline_height, "line-height");
32457 DEFSYM (QCalign_to, ":align-to");
32458 DEFSYM (QCrelative_width, ":relative-width");
32459 DEFSYM (QCrelative_height, ":relative-height");
32460 DEFSYM (QCeval, ":eval");
32461 DEFSYM (QCpropertize, ":propertize");
32462 DEFSYM (QCfile, ":file");
32463 DEFSYM (Qfontified, "fontified");
32464 DEFSYM (Qfontification_functions, "fontification-functions");
32466 /* Name of the symbol which disables Lisp evaluation in 'display'
32467 properties. This is used by enriched.el. */
32468 DEFSYM (Qdisable_eval, "disable-eval");
32470 /* Name of the face used to highlight trailing whitespace. */
32471 DEFSYM (Qtrailing_whitespace, "trailing-whitespace");
32473 /* Names of the faces used to display line numbers. */
32474 DEFSYM (Qline_number, "line-number");
32475 DEFSYM (Qline_number_current_line, "line-number-current-line");
32476 /* Name of a text property which disables line-number display. */
32477 DEFSYM (Qdisplay_line_numbers_disable, "display-line-numbers-disable");
32479 /* Name and number of the face used to highlight escape glyphs. */
32480 DEFSYM (Qescape_glyph, "escape-glyph");
32482 /* Name and number of the face used to highlight non-breaking
32483 spaces/hyphens. */
32484 DEFSYM (Qnobreak_space, "nobreak-space");
32485 DEFSYM (Qnobreak_hyphen, "nobreak-hyphen");
32487 /* The symbol 'image' which is the car of the lists used to represent
32488 images in Lisp. Also a tool bar style. */
32489 DEFSYM (Qimage, "image");
32491 /* Tool bar styles. */
32492 DEFSYM (Qtext, "text");
32493 DEFSYM (Qboth, "both");
32494 DEFSYM (Qboth_horiz, "both-horiz");
32495 DEFSYM (Qtext_image_horiz, "text-image-horiz");
32497 /* The image map types. */
32498 DEFSYM (QCmap, ":map");
32499 DEFSYM (QCpointer, ":pointer");
32500 DEFSYM (Qrect, "rect");
32501 DEFSYM (Qcircle, "circle");
32502 DEFSYM (Qpoly, "poly");
32504 DEFSYM (Qinhibit_menubar_update, "inhibit-menubar-update");
32506 DEFSYM (Qgrow_only, "grow-only");
32507 DEFSYM (Qinhibit_eval_during_redisplay, "inhibit-eval-during-redisplay");
32508 DEFSYM (Qposition, "position");
32509 DEFSYM (Qbuffer_position, "buffer-position");
32510 DEFSYM (Qobject, "object");
32512 /* Cursor shapes. */
32513 DEFSYM (Qbar, "bar");
32514 DEFSYM (Qhbar, "hbar");
32515 DEFSYM (Qbox, "box");
32516 DEFSYM (Qhollow, "hollow");
32518 /* Pointer shapes. */
32519 DEFSYM (Qhand, "hand");
32520 DEFSYM (Qarrow, "arrow");
32521 /* also Qtext */
32523 DEFSYM (Qdragging, "dragging");
32525 DEFSYM (Qinhibit_free_realized_faces, "inhibit-free-realized-faces");
32527 list_of_error = list1 (list2 (Qerror, Qvoid_variable));
32528 staticpro (&list_of_error);
32530 /* Values of those variables at last redisplay are stored as
32531 properties on 'overlay-arrow-position' symbol. However, if
32532 Voverlay_arrow_position is a marker, last-arrow-position is its
32533 numerical position. */
32534 DEFSYM (Qlast_arrow_position, "last-arrow-position");
32535 DEFSYM (Qlast_arrow_string, "last-arrow-string");
32537 /* Alternative overlay-arrow-string and overlay-arrow-bitmap
32538 properties on a symbol in overlay-arrow-variable-list. */
32539 DEFSYM (Qoverlay_arrow_string, "overlay-arrow-string");
32540 DEFSYM (Qoverlay_arrow_bitmap, "overlay-arrow-bitmap");
32542 echo_buffer[0] = echo_buffer[1] = Qnil;
32543 staticpro (&echo_buffer[0]);
32544 staticpro (&echo_buffer[1]);
32546 echo_area_buffer[0] = echo_area_buffer[1] = Qnil;
32547 staticpro (&echo_area_buffer[0]);
32548 staticpro (&echo_area_buffer[1]);
32550 Vmessages_buffer_name = build_pure_c_string ("*Messages*");
32551 staticpro (&Vmessages_buffer_name);
32553 mode_line_proptrans_alist = Qnil;
32554 staticpro (&mode_line_proptrans_alist);
32555 mode_line_string_list = Qnil;
32556 staticpro (&mode_line_string_list);
32557 mode_line_string_face = Qnil;
32558 staticpro (&mode_line_string_face);
32559 mode_line_string_face_prop = Qnil;
32560 staticpro (&mode_line_string_face_prop);
32561 Vmode_line_unwind_vector = Qnil;
32562 staticpro (&Vmode_line_unwind_vector);
32564 DEFSYM (Qmode_line_default_help_echo, "mode-line-default-help-echo");
32566 help_echo_string = Qnil;
32567 staticpro (&help_echo_string);
32568 help_echo_object = Qnil;
32569 staticpro (&help_echo_object);
32570 help_echo_window = Qnil;
32571 staticpro (&help_echo_window);
32572 previous_help_echo_string = Qnil;
32573 staticpro (&previous_help_echo_string);
32574 help_echo_pos = -1;
32576 DEFSYM (Qright_to_left, "right-to-left");
32577 DEFSYM (Qleft_to_right, "left-to-right");
32578 defsubr (&Sbidi_resolved_levels);
32580 #ifdef HAVE_WINDOW_SYSTEM
32581 DEFVAR_BOOL ("x-stretch-cursor", x_stretch_cursor_p,
32582 doc: /* Non-nil means draw block cursor as wide as the glyph under it.
32583 For example, if a block cursor is over a tab, it will be drawn as
32584 wide as that tab on the display. */);
32585 x_stretch_cursor_p = 0;
32586 #endif
32588 DEFVAR_LISP ("show-trailing-whitespace", Vshow_trailing_whitespace,
32589 doc: /* Non-nil means highlight trailing whitespace.
32590 The face used for trailing whitespace is `trailing-whitespace'. */);
32591 Vshow_trailing_whitespace = Qnil;
32593 DEFVAR_LISP ("nobreak-char-display", Vnobreak_char_display,
32594 doc: /* Control highlighting of non-ASCII space and hyphen chars.
32595 If the value is t, Emacs highlights non-ASCII chars which have the
32596 same appearance as an ASCII space or hyphen, using the `nobreak-space'
32597 or `nobreak-hyphen' face respectively.
32599 U+00A0 (no-break space), U+00AD (soft hyphen), U+2010 (hyphen), and
32600 U+2011 (non-breaking hyphen) are affected.
32602 Any other non-nil value means to display these characters as an escape
32603 glyph followed by an ordinary space or hyphen.
32605 A value of nil means no special handling of these characters. */);
32606 Vnobreak_char_display = Qt;
32608 DEFVAR_LISP ("void-text-area-pointer", Vvoid_text_area_pointer,
32609 doc: /* The pointer shape to show in void text areas.
32610 A value of nil means to show the text pointer. Other options are
32611 `arrow', `text', `hand', `vdrag', `hdrag', `nhdrag', `modeline', and
32612 `hourglass'. */);
32613 Vvoid_text_area_pointer = Qarrow;
32615 DEFVAR_LISP ("inhibit-redisplay", Vinhibit_redisplay,
32616 doc: /* Non-nil means don't actually do any redisplay.
32617 This is used for internal purposes. */);
32618 Vinhibit_redisplay = Qnil;
32620 DEFVAR_LISP ("global-mode-string", Vglobal_mode_string,
32621 doc: /* String (or mode line construct) included (normally) in `mode-line-format'. */);
32622 Vglobal_mode_string = Qnil;
32624 DEFVAR_LISP ("overlay-arrow-position", Voverlay_arrow_position,
32625 doc: /* Marker for where to display an arrow on top of the buffer text.
32626 This must be the beginning of a line in order to work.
32627 See also `overlay-arrow-string'. */);
32628 Voverlay_arrow_position = Qnil;
32630 DEFVAR_LISP ("overlay-arrow-string", Voverlay_arrow_string,
32631 doc: /* String to display as an arrow in non-window frames.
32632 See also `overlay-arrow-position'. */);
32633 Voverlay_arrow_string = build_pure_c_string ("=>");
32635 DEFVAR_LISP ("overlay-arrow-variable-list", Voverlay_arrow_variable_list,
32636 doc: /* List of variables (symbols) which hold markers for overlay arrows.
32637 The symbols on this list are examined during redisplay to determine
32638 where to display overlay arrows. */);
32639 Voverlay_arrow_variable_list
32640 = list1 (intern_c_string ("overlay-arrow-position"));
32642 DEFVAR_INT ("scroll-step", emacs_scroll_step,
32643 doc: /* The number of lines to try scrolling a window by when point moves out.
32644 If that fails to bring point back on frame, point is centered instead.
32645 If this is zero, point is always centered after it moves off frame.
32646 If you want scrolling to always be a line at a time, you should set
32647 `scroll-conservatively' to a large value rather than set this to 1. */);
32649 DEFVAR_INT ("scroll-conservatively", scroll_conservatively,
32650 doc: /* Scroll up to this many lines, to bring point back on screen.
32651 If point moves off-screen, redisplay will scroll by up to
32652 `scroll-conservatively' lines in order to bring point just barely
32653 onto the screen again. If that cannot be done, then redisplay
32654 recenters point as usual.
32656 If the value is greater than 100, redisplay will never recenter point,
32657 but will always scroll just enough text to bring point into view, even
32658 if you move far away.
32660 A value of zero means always recenter point if it moves off screen. */);
32661 scroll_conservatively = 0;
32663 DEFVAR_INT ("scroll-margin", scroll_margin,
32664 doc: /* Number of lines of margin at the top and bottom of a window.
32665 Trigger automatic scrolling whenever point gets within this many lines
32666 of the top or bottom of the window (see info node `Auto Scrolling'). */);
32667 scroll_margin = 0;
32669 DEFVAR_LISP ("maximum-scroll-margin", Vmaximum_scroll_margin,
32670 doc: /* Maximum effective value of `scroll-margin'.
32671 Given as a fraction of the current window's lines. The value should
32672 be a floating point number between 0.0 and 0.5. The effective maximum
32673 is limited to (/ (1- window-lines) 2). Non-float values for this
32674 variable are ignored and the default 0.25 is used instead. */);
32675 Vmaximum_scroll_margin = make_float (0.25);
32677 DEFVAR_LISP ("display-pixels-per-inch", Vdisplay_pixels_per_inch,
32678 doc: /* Pixels per inch value for non-window system displays.
32679 Value is a number or a cons (WIDTH-DPI . HEIGHT-DPI). */);
32680 Vdisplay_pixels_per_inch = make_float (72.0);
32682 #ifdef GLYPH_DEBUG
32683 DEFVAR_INT ("debug-end-pos", debug_end_pos, doc: /* Don't ask. */);
32684 #endif
32686 DEFVAR_LISP ("truncate-partial-width-windows",
32687 Vtruncate_partial_width_windows,
32688 doc: /* Non-nil means truncate lines in windows narrower than the frame.
32689 For an integer value, truncate lines in each window narrower than the
32690 full frame width, provided the total window width in column units is less
32691 than that integer; otherwise, respect the value of `truncate-lines'.
32692 The total width of the window is as returned by `window-total-width', it
32693 includes the fringes, the continuation and truncation glyphs, the
32694 display margins (if any), and the scroll bar
32696 For any other non-nil value, truncate lines in all windows that do
32697 not span the full frame width.
32699 A value of nil means to respect the value of `truncate-lines'.
32701 If `word-wrap' is enabled, you might want to reduce this. */);
32702 Vtruncate_partial_width_windows = make_number (50);
32704 DEFVAR_LISP ("line-number-display-limit", Vline_number_display_limit,
32705 doc: /* Maximum buffer size for which line number should be displayed.
32706 If the buffer is bigger than this, the line number does not appear
32707 in the mode line. A value of nil means no limit. */);
32708 Vline_number_display_limit = Qnil;
32710 DEFVAR_INT ("line-number-display-limit-width",
32711 line_number_display_limit_width,
32712 doc: /* Maximum line width (in characters) for line number display.
32713 If the average length of the lines near point is bigger than this, then the
32714 line number may be omitted from the mode line. */);
32715 line_number_display_limit_width = 200;
32717 DEFVAR_BOOL ("highlight-nonselected-windows", highlight_nonselected_windows,
32718 doc: /* Non-nil means highlight region even in nonselected windows. */);
32719 highlight_nonselected_windows = false;
32721 DEFVAR_BOOL ("multiple-frames", multiple_frames,
32722 doc: /* Non-nil if more than one frame is visible on this display.
32723 Minibuffer-only frames don't count, but iconified frames do.
32724 This variable is not guaranteed to be accurate except while processing
32725 `frame-title-format' and `icon-title-format'. */);
32727 DEFVAR_LISP ("frame-title-format", Vframe_title_format,
32728 doc: /* Template for displaying the title bar of visible frames.
32729 \(Assuming the window manager supports this feature.)
32731 This variable has the same structure as `mode-line-format', except that
32732 the %c, %C, and %l constructs are ignored. It is used only on frames for
32733 which no explicit name has been set (see `modify-frame-parameters'). */);
32735 DEFVAR_LISP ("icon-title-format", Vicon_title_format,
32736 doc: /* Template for displaying the title bar of an iconified frame.
32737 \(Assuming the window manager supports this feature.)
32738 This variable has the same structure as `mode-line-format' (which see),
32739 and is used only on frames for which no explicit name has been set
32740 \(see `modify-frame-parameters'). */);
32741 Vicon_title_format
32742 = Vframe_title_format
32743 = listn (CONSTYPE_PURE, 3,
32744 intern_c_string ("multiple-frames"),
32745 build_pure_c_string ("%b"),
32746 listn (CONSTYPE_PURE, 4,
32747 empty_unibyte_string,
32748 intern_c_string ("invocation-name"),
32749 build_pure_c_string ("@"),
32750 intern_c_string ("system-name")));
32752 DEFVAR_LISP ("message-log-max", Vmessage_log_max,
32753 doc: /* Maximum number of lines to keep in the message log buffer.
32754 If nil, disable message logging. If t, log messages but don't truncate
32755 the buffer when it becomes large. */);
32756 Vmessage_log_max = make_number (1000);
32758 DEFVAR_LISP ("window-scroll-functions", Vwindow_scroll_functions,
32759 doc: /* List of functions to call before redisplaying a window with scrolling.
32760 Each function is called with two arguments, the window and its new
32761 display-start position.
32762 These functions are called whenever the `window-start' marker is modified,
32763 either to point into another buffer (e.g. via `set-window-buffer') or another
32764 place in the same buffer.
32765 When each function is called, the `window-start' marker of its window
32766 argument has been already set to the new value, and the buffer which that
32767 window will display is set to be the current buffer.
32768 Note that the value of `window-end' is not valid when these functions are
32769 called.
32771 Warning: Do not use this feature to alter the way the window
32772 is scrolled. It is not designed for that, and such use probably won't
32773 work. */);
32774 Vwindow_scroll_functions = Qnil;
32776 DEFVAR_LISP ("redisplay-end-trigger-functions", Vredisplay_end_trigger_functions,
32777 doc: /* Functions called when redisplay of a window reaches the end trigger.
32778 Each function is called with two arguments, the window and the end trigger value.
32779 See `set-window-redisplay-end-trigger'. */);
32780 Vredisplay_end_trigger_functions = Qnil;
32782 DEFVAR_LISP ("mouse-autoselect-window", Vmouse_autoselect_window,
32783 doc: /* Non-nil means autoselect window with mouse pointer.
32784 If nil, do not autoselect windows.
32785 A positive number means delay autoselection by that many seconds: a
32786 window is autoselected only after the mouse has remained in that
32787 window for the duration of the delay.
32788 A negative number has a similar effect, but causes windows to be
32789 autoselected only after the mouse has stopped moving. (Because of
32790 the way Emacs compares mouse events, you will occasionally wait twice
32791 that time before the window gets selected.)
32792 Any other value means to autoselect window instantaneously when the
32793 mouse pointer enters it.
32795 Autoselection selects the minibuffer only if it is active, and never
32796 unselects the minibuffer if it is active.
32798 When customizing this variable make sure that the actual value of
32799 `focus-follows-mouse' matches the behavior of your window manager. */);
32800 Vmouse_autoselect_window = Qnil;
32802 DEFVAR_LISP ("auto-resize-tool-bars", Vauto_resize_tool_bars,
32803 doc: /* Non-nil means automatically resize tool-bars.
32804 This dynamically changes the tool-bar's height to the minimum height
32805 that is needed to make all tool-bar items visible.
32806 If value is `grow-only', the tool-bar's height is only increased
32807 automatically; to decrease the tool-bar height, use \\[recenter]. */);
32808 Vauto_resize_tool_bars = Qt;
32810 DEFVAR_BOOL ("auto-raise-tool-bar-buttons", auto_raise_tool_bar_buttons_p,
32811 doc: /* Non-nil means raise tool-bar buttons when the mouse moves over them. */);
32812 auto_raise_tool_bar_buttons_p = true;
32814 DEFVAR_BOOL ("make-cursor-line-fully-visible", make_cursor_line_fully_visible_p,
32815 doc: /* Non-nil means to scroll (recenter) cursor line if it is not fully visible. */);
32816 make_cursor_line_fully_visible_p = true;
32818 DEFVAR_LISP ("tool-bar-border", Vtool_bar_border,
32819 doc: /* Border below tool-bar in pixels.
32820 If an integer, use it as the height of the border.
32821 If it is one of `internal-border-width' or `border-width', use the
32822 value of the corresponding frame parameter.
32823 Otherwise, no border is added below the tool-bar. */);
32824 Vtool_bar_border = Qinternal_border_width;
32826 DEFVAR_LISP ("tool-bar-button-margin", Vtool_bar_button_margin,
32827 doc: /* Margin around tool-bar buttons in pixels.
32828 If an integer, use that for both horizontal and vertical margins.
32829 Otherwise, value should be a pair of integers `(HORZ . VERT)' with
32830 HORZ specifying the horizontal margin, and VERT specifying the
32831 vertical margin. */);
32832 Vtool_bar_button_margin = make_number (DEFAULT_TOOL_BAR_BUTTON_MARGIN);
32834 DEFVAR_INT ("tool-bar-button-relief", tool_bar_button_relief,
32835 doc: /* Relief thickness of tool-bar buttons. */);
32836 tool_bar_button_relief = DEFAULT_TOOL_BAR_BUTTON_RELIEF;
32838 DEFVAR_LISP ("tool-bar-style", Vtool_bar_style,
32839 doc: /* Tool bar style to use.
32840 It can be one of
32841 image - show images only
32842 text - show text only
32843 both - show both, text below image
32844 both-horiz - show text to the right of the image
32845 text-image-horiz - show text to the left of the image
32846 any other - use system default or image if no system default.
32848 This variable only affects the GTK+ toolkit version of Emacs. */);
32849 Vtool_bar_style = Qnil;
32851 DEFVAR_INT ("tool-bar-max-label-size", tool_bar_max_label_size,
32852 doc: /* Maximum number of characters a label can have to be shown.
32853 The tool bar style must also show labels for this to have any effect, see
32854 `tool-bar-style'. */);
32855 tool_bar_max_label_size = DEFAULT_TOOL_BAR_LABEL_SIZE;
32857 DEFVAR_LISP ("fontification-functions", Vfontification_functions,
32858 doc: /* List of functions to call to fontify regions of text.
32859 Each function is called with one argument POS. Functions must
32860 fontify a region starting at POS in the current buffer, and give
32861 fontified regions the property `fontified'. */);
32862 Vfontification_functions = Qnil;
32863 Fmake_variable_buffer_local (Qfontification_functions);
32865 DEFVAR_BOOL ("unibyte-display-via-language-environment",
32866 unibyte_display_via_language_environment,
32867 doc: /* Non-nil means display unibyte text according to language environment.
32868 Specifically, this means that raw bytes in the range 160-255 decimal
32869 are displayed by converting them to the equivalent multibyte characters
32870 according to the current language environment. As a result, they are
32871 displayed according to the current fontset.
32873 Note that this variable affects only how these bytes are displayed,
32874 but does not change the fact they are interpreted as raw bytes. */);
32875 unibyte_display_via_language_environment = false;
32877 DEFVAR_LISP ("max-mini-window-height", Vmax_mini_window_height,
32878 doc: /* Maximum height for resizing mini-windows (the minibuffer and the echo area).
32879 If a float, it specifies a fraction of the mini-window frame's height.
32880 If an integer, it specifies a number of lines. */);
32881 Vmax_mini_window_height = make_float (0.25);
32883 DEFVAR_LISP ("resize-mini-windows", Vresize_mini_windows,
32884 doc: /* How to resize mini-windows (the minibuffer and the echo area).
32885 A value of nil means don't automatically resize mini-windows.
32886 A value of t means resize them to fit the text displayed in them.
32887 A value of `grow-only', the default, means let mini-windows grow only;
32888 they return to their normal size when the minibuffer is closed, or the
32889 echo area becomes empty. */);
32890 /* Contrary to the doc string, we initialize this to nil, so that
32891 loading loadup.el won't try to resize windows before loading
32892 window.el, where some functions we need to call for this live.
32893 We assign the 'grow-only' value right after loading window.el
32894 during loadup. */
32895 Vresize_mini_windows = Qnil;
32897 DEFVAR_LISP ("blink-cursor-alist", Vblink_cursor_alist,
32898 doc: /* Alist specifying how to blink the cursor off.
32899 Each element has the form (ON-STATE . OFF-STATE). Whenever the
32900 `cursor-type' frame-parameter or variable equals ON-STATE,
32901 comparing using `equal', Emacs uses OFF-STATE to specify
32902 how to blink it off. ON-STATE and OFF-STATE are values for
32903 the `cursor-type' frame parameter.
32905 If a frame's ON-STATE has no entry in this list,
32906 the frame's other specifications determine how to blink the cursor off. */);
32907 Vblink_cursor_alist = Qnil;
32909 DEFVAR_LISP ("auto-hscroll-mode", automatic_hscrolling,
32910 doc: /* Allow or disallow automatic horizontal scrolling of windows.
32911 The value `current-line' means the line displaying point in each window
32912 is automatically scrolled horizontally to make point visible.
32913 Any other non-nil value means all the lines in a window are automatically
32914 scrolled horizontally to make point visible. */);
32915 automatic_hscrolling = Qt;
32916 DEFSYM (Qauto_hscroll_mode, "auto-hscroll-mode");
32917 DEFSYM (Qcurrent_line, "current-line");
32919 DEFVAR_INT ("hscroll-margin", hscroll_margin,
32920 doc: /* How many columns away from the window edge point is allowed to get
32921 before automatic hscrolling will horizontally scroll the window. */);
32922 hscroll_margin = 5;
32924 DEFVAR_LISP ("hscroll-step", Vhscroll_step,
32925 doc: /* How many columns to scroll the window when point gets too close to the edge.
32926 When point is less than `hscroll-margin' columns from the window
32927 edge, automatic hscrolling will scroll the window by the amount of columns
32928 determined by this variable. If its value is a positive integer, scroll that
32929 many columns. If it's a positive floating-point number, it specifies the
32930 fraction of the window's width to scroll. If it's nil or zero, point will be
32931 centered horizontally after the scroll. Any other value, including negative
32932 numbers, are treated as if the value were zero.
32934 Automatic hscrolling always moves point outside the scroll margin, so if
32935 point was more than scroll step columns inside the margin, the window will
32936 scroll more than the value given by the scroll step.
32938 Note that the lower bound for automatic hscrolling specified by `scroll-left'
32939 and `scroll-right' overrides this variable's effect. */);
32940 Vhscroll_step = make_number (0);
32942 DEFVAR_BOOL ("message-truncate-lines", message_truncate_lines,
32943 doc: /* If non-nil, messages are truncated instead of resizing the echo area.
32944 Bind this around calls to `message' to let it take effect. */);
32945 message_truncate_lines = false;
32947 DEFVAR_LISP ("menu-bar-update-hook", Vmenu_bar_update_hook,
32948 doc: /* Normal hook run to update the menu bar definitions.
32949 Redisplay runs this hook before it redisplays the menu bar.
32950 This is used to update menus such as Buffers, whose contents depend on
32951 various data. */);
32952 Vmenu_bar_update_hook = Qnil;
32954 DEFVAR_LISP ("menu-updating-frame", Vmenu_updating_frame,
32955 doc: /* Frame for which we are updating a menu.
32956 The enable predicate for a menu binding should check this variable. */);
32957 Vmenu_updating_frame = Qnil;
32959 DEFVAR_BOOL ("inhibit-menubar-update", inhibit_menubar_update,
32960 doc: /* Non-nil means don't update menu bars. Internal use only. */);
32961 inhibit_menubar_update = false;
32963 DEFVAR_LISP ("wrap-prefix", Vwrap_prefix,
32964 doc: /* Prefix prepended to all continuation lines at display time.
32965 The value may be a string, an image, or a stretch-glyph; it is
32966 interpreted in the same way as the value of a `display' text property.
32968 This variable is overridden by any `wrap-prefix' text or overlay
32969 property.
32971 To add a prefix to non-continuation lines, use `line-prefix'. */);
32972 Vwrap_prefix = Qnil;
32973 DEFSYM (Qwrap_prefix, "wrap-prefix");
32974 Fmake_variable_buffer_local (Qwrap_prefix);
32976 DEFVAR_LISP ("line-prefix", Vline_prefix,
32977 doc: /* Prefix prepended to all non-continuation lines at display time.
32978 The value may be a string, an image, or a stretch-glyph; it is
32979 interpreted in the same way as the value of a `display' text property.
32981 This variable is overridden by any `line-prefix' text or overlay
32982 property.
32984 To add a prefix to continuation lines, use `wrap-prefix'. */);
32985 Vline_prefix = Qnil;
32986 DEFSYM (Qline_prefix, "line-prefix");
32987 Fmake_variable_buffer_local (Qline_prefix);
32989 DEFVAR_LISP ("display-line-numbers", Vdisplay_line_numbers,
32990 doc: /* Non-nil means display line numbers.
32991 If the value is t, display the absolute number of each line of a buffer
32992 shown in a window. Absolute line numbers count from the beginning of
32993 the current narrowing, or from buffer beginning. If the value is
32994 `relative', display for each line not containing the window's point its
32995 relative number instead, i.e. the number of the line relative to the
32996 line showing the window's point.
32998 In either case, line numbers are displayed at the beginning of each
32999 non-continuation line that displays buffer text, i.e. after each newline
33000 character that comes from the buffer. The value `visual' is like
33001 `relative' but counts screen lines instead of buffer lines. In practice
33002 this means that continuation lines count as well when calculating the
33003 relative number of a line.
33005 Lisp programs can disable display of a line number of a particular
33006 buffer line by putting the `display-line-numbers-disable' text property
33007 or overlay property on the first visible character of that line. */);
33008 Vdisplay_line_numbers = Qnil;
33009 DEFSYM (Qdisplay_line_numbers, "display-line-numbers");
33010 Fmake_variable_buffer_local (Qdisplay_line_numbers);
33011 DEFSYM (Qrelative, "relative");
33012 DEFSYM (Qvisual, "visual");
33014 DEFVAR_LISP ("display-line-numbers-width", Vdisplay_line_numbers_width,
33015 doc: /* Minimum width of space reserved for line number display.
33016 A positive number means reserve that many columns for line numbers,
33017 even if the actual number needs less space.
33018 The default value of nil means compute the space dynamically.
33019 Any other value is treated as nil. */);
33020 Vdisplay_line_numbers_width = Qnil;
33021 DEFSYM (Qdisplay_line_numbers_width, "display-line-numbers-width");
33022 Fmake_variable_buffer_local (Qdisplay_line_numbers_width);
33024 DEFVAR_LISP ("display-line-numbers-current-absolute",
33025 Vdisplay_line_numbers_current_absolute,
33026 doc: /* Non-nil means display absolute number of current line.
33027 This variable has effect only when `display-line-numbers' is
33028 either `relative' or `visual'. */);
33029 Vdisplay_line_numbers_current_absolute = Qt;
33031 DEFVAR_BOOL ("display-line-numbers-widen", display_line_numbers_widen,
33032 doc: /* Non-nil means display line numbers disregarding any narrowing. */);
33033 display_line_numbers_widen = false;
33034 DEFSYM (Qdisplay_line_numbers_widen, "display-line-numbers-widen");
33035 Fmake_variable_buffer_local (Qdisplay_line_numbers_widen);
33037 DEFVAR_BOOL ("inhibit-eval-during-redisplay", inhibit_eval_during_redisplay,
33038 doc: /* Non-nil means don't eval Lisp during redisplay. */);
33039 inhibit_eval_during_redisplay = false;
33041 DEFVAR_BOOL ("inhibit-free-realized-faces", inhibit_free_realized_faces,
33042 doc: /* Non-nil means don't free realized faces. Internal use only. */);
33043 inhibit_free_realized_faces = false;
33045 DEFVAR_BOOL ("inhibit-bidi-mirroring", inhibit_bidi_mirroring,
33046 doc: /* Non-nil means don't mirror characters even when bidi context requires that.
33047 Intended for use during debugging and for testing bidi display;
33048 see biditest.el in the test suite. */);
33049 inhibit_bidi_mirroring = false;
33051 #ifdef GLYPH_DEBUG
33052 DEFVAR_BOOL ("inhibit-try-window-id", inhibit_try_window_id,
33053 doc: /* Inhibit try_window_id display optimization. */);
33054 inhibit_try_window_id = false;
33056 DEFVAR_BOOL ("inhibit-try-window-reusing", inhibit_try_window_reusing,
33057 doc: /* Inhibit try_window_reusing display optimization. */);
33058 inhibit_try_window_reusing = false;
33060 DEFVAR_BOOL ("inhibit-try-cursor-movement", inhibit_try_cursor_movement,
33061 doc: /* Inhibit try_cursor_movement display optimization. */);
33062 inhibit_try_cursor_movement = false;
33063 #endif /* GLYPH_DEBUG */
33065 DEFVAR_INT ("overline-margin", overline_margin,
33066 doc: /* Space between overline and text, in pixels.
33067 The default value is 2: the height of the overline (1 pixel) plus 1 pixel
33068 margin to the character height. */);
33069 overline_margin = 2;
33071 DEFVAR_INT ("underline-minimum-offset",
33072 underline_minimum_offset,
33073 doc: /* Minimum distance between baseline and underline.
33074 This can improve legibility of underlined text at small font sizes,
33075 particularly when using variable `x-use-underline-position-properties'
33076 with fonts that specify an UNDERLINE_POSITION relatively close to the
33077 baseline. The default value is 1. */);
33078 underline_minimum_offset = 1;
33079 DEFSYM (Qunderline_minimum_offset, "underline-minimum-offset");
33081 DEFVAR_BOOL ("display-hourglass", display_hourglass_p,
33082 doc: /* Non-nil means show an hourglass pointer, when Emacs is busy.
33083 This feature only works when on a window system that can change
33084 cursor shapes. */);
33085 display_hourglass_p = true;
33087 DEFVAR_LISP ("hourglass-delay", Vhourglass_delay,
33088 doc: /* Seconds to wait before displaying an hourglass pointer when Emacs is busy. */);
33089 Vhourglass_delay = make_number (DEFAULT_HOURGLASS_DELAY);
33091 #ifdef HAVE_WINDOW_SYSTEM
33092 hourglass_atimer = NULL;
33093 hourglass_shown_p = false;
33094 #endif /* HAVE_WINDOW_SYSTEM */
33096 /* Name of the face used to display glyphless characters. */
33097 DEFSYM (Qglyphless_char, "glyphless-char");
33099 /* Method symbols for Vglyphless_char_display. */
33100 DEFSYM (Qhex_code, "hex-code");
33101 DEFSYM (Qempty_box, "empty-box");
33102 DEFSYM (Qthin_space, "thin-space");
33103 DEFSYM (Qzero_width, "zero-width");
33105 DEFVAR_LISP ("pre-redisplay-function", Vpre_redisplay_function,
33106 doc: /* Function run just before redisplay.
33107 It is called with one argument, which is the set of windows that are to
33108 be redisplayed. This set can be nil (meaning, only the selected window),
33109 or t (meaning all windows). */);
33110 Vpre_redisplay_function = intern ("ignore");
33112 /* Symbol for the purpose of Vglyphless_char_display. */
33113 DEFSYM (Qglyphless_char_display, "glyphless-char-display");
33114 Fput (Qglyphless_char_display, Qchar_table_extra_slots, make_number (1));
33116 DEFVAR_LISP ("glyphless-char-display", Vglyphless_char_display,
33117 doc: /* Char-table defining glyphless characters.
33118 Each element, if non-nil, should be one of the following:
33119 an ASCII acronym string: display this string in a box
33120 `hex-code': display the hexadecimal code of a character in a box
33121 `empty-box': display as an empty box
33122 `thin-space': display as 1-pixel width space
33123 `zero-width': don't display
33124 An element may also be a cons cell (GRAPHICAL . TEXT), which specifies the
33125 display method for graphical terminals and text terminals respectively.
33126 GRAPHICAL and TEXT should each have one of the values listed above.
33128 The char-table has one extra slot to control the display of a character for
33129 which no font is found. This slot only takes effect on graphical terminals.
33130 Its value should be an ASCII acronym string, `hex-code', `empty-box', or
33131 `thin-space'. The default is `empty-box'.
33133 If a character has a non-nil entry in an active display table, the
33134 display table takes effect; in this case, Emacs does not consult
33135 `glyphless-char-display' at all. */);
33136 Vglyphless_char_display = Fmake_char_table (Qglyphless_char_display, Qnil);
33137 Fset_char_table_extra_slot (Vglyphless_char_display, make_number (0),
33138 Qempty_box);
33140 DEFVAR_LISP ("debug-on-message", Vdebug_on_message,
33141 doc: /* If non-nil, debug if a message matching this regexp is displayed. */);
33142 Vdebug_on_message = Qnil;
33144 DEFVAR_LISP ("redisplay--all-windows-cause", Vredisplay__all_windows_cause,
33145 doc: /* */);
33146 Vredisplay__all_windows_cause = Fmake_hash_table (0, NULL);
33148 DEFVAR_LISP ("redisplay--mode-lines-cause", Vredisplay__mode_lines_cause,
33149 doc: /* */);
33150 Vredisplay__mode_lines_cause = Fmake_hash_table (0, NULL);
33152 DEFVAR_BOOL ("redisplay--inhibit-bidi", redisplay__inhibit_bidi,
33153 doc: /* Non-nil means it is not safe to attempt bidi reordering for display. */);
33154 /* Initialize to t, since we need to disable reordering until
33155 loadup.el successfully loads charprop.el. */
33156 redisplay__inhibit_bidi = true;
33158 DEFVAR_BOOL ("display-raw-bytes-as-hex", display_raw_bytes_as_hex,
33159 doc: /* Non-nil means display raw bytes in hexadecimal format.
33160 The default is to use octal format (\200) whereas hexadecimal (\x80)
33161 may be more familiar to users. */);
33162 display_raw_bytes_as_hex = false;
33167 /* Initialize this module when Emacs starts. */
33169 void
33170 init_xdisp (void)
33172 CHARPOS (this_line_start_pos) = 0;
33174 if (!noninteractive)
33176 struct window *m = XWINDOW (minibuf_window);
33177 Lisp_Object frame = m->frame;
33178 struct frame *f = XFRAME (frame);
33179 Lisp_Object root = FRAME_ROOT_WINDOW (f);
33180 struct window *r = XWINDOW (root);
33181 int i;
33183 echo_area_window = minibuf_window;
33185 r->top_line = FRAME_TOP_MARGIN (f);
33186 r->pixel_top = r->top_line * FRAME_LINE_HEIGHT (f);
33187 r->total_cols = FRAME_COLS (f);
33188 r->pixel_width = r->total_cols * FRAME_COLUMN_WIDTH (f);
33189 r->total_lines = FRAME_TOTAL_LINES (f) - 1 - FRAME_TOP_MARGIN (f);
33190 r->pixel_height = r->total_lines * FRAME_LINE_HEIGHT (f);
33192 m->top_line = FRAME_TOTAL_LINES (f) - 1;
33193 m->pixel_top = m->top_line * FRAME_LINE_HEIGHT (f);
33194 m->total_cols = FRAME_COLS (f);
33195 m->pixel_width = m->total_cols * FRAME_COLUMN_WIDTH (f);
33196 m->total_lines = 1;
33197 m->pixel_height = m->total_lines * FRAME_LINE_HEIGHT (f);
33199 scratch_glyph_row.glyphs[TEXT_AREA] = scratch_glyphs;
33200 scratch_glyph_row.glyphs[TEXT_AREA + 1]
33201 = scratch_glyphs + MAX_SCRATCH_GLYPHS;
33203 /* The default ellipsis glyphs `...'. */
33204 for (i = 0; i < 3; ++i)
33205 default_invis_vector[i] = make_number ('.');
33209 /* Allocate the buffer for frame titles.
33210 Also used for `format-mode-line'. */
33211 int size = 100;
33212 mode_line_noprop_buf = xmalloc (size);
33213 mode_line_noprop_buf_end = mode_line_noprop_buf + size;
33214 mode_line_noprop_ptr = mode_line_noprop_buf;
33215 mode_line_target = MODE_LINE_DISPLAY;
33218 help_echo_showing_p = false;
33221 #ifdef HAVE_WINDOW_SYSTEM
33223 /* Platform-independent portion of hourglass implementation. */
33225 /* Timer function of hourglass_atimer. */
33227 static void
33228 show_hourglass (struct atimer *timer)
33230 /* The timer implementation will cancel this timer automatically
33231 after this function has run. Set hourglass_atimer to null
33232 so that we know the timer doesn't have to be canceled. */
33233 hourglass_atimer = NULL;
33235 if (!hourglass_shown_p)
33237 Lisp_Object tail, frame;
33239 block_input ();
33241 FOR_EACH_FRAME (tail, frame)
33243 struct frame *f = XFRAME (frame);
33245 if (FRAME_LIVE_P (f) && FRAME_WINDOW_P (f)
33246 && FRAME_RIF (f)->show_hourglass)
33247 FRAME_RIF (f)->show_hourglass (f);
33250 hourglass_shown_p = true;
33251 unblock_input ();
33255 /* Cancel a currently active hourglass timer, and start a new one. */
33257 void
33258 start_hourglass (void)
33260 struct timespec delay;
33262 cancel_hourglass ();
33264 if (INTEGERP (Vhourglass_delay)
33265 && XINT (Vhourglass_delay) > 0)
33266 delay = make_timespec (min (XINT (Vhourglass_delay),
33267 TYPE_MAXIMUM (time_t)),
33269 else if (FLOATP (Vhourglass_delay)
33270 && XFLOAT_DATA (Vhourglass_delay) > 0)
33271 delay = dtotimespec (XFLOAT_DATA (Vhourglass_delay));
33272 else
33273 delay = make_timespec (DEFAULT_HOURGLASS_DELAY, 0);
33275 hourglass_atimer = start_atimer (ATIMER_RELATIVE, delay,
33276 show_hourglass, NULL);
33279 /* Cancel the hourglass cursor timer if active, hide a busy cursor if
33280 shown. */
33282 void
33283 cancel_hourglass (void)
33285 if (hourglass_atimer)
33287 cancel_atimer (hourglass_atimer);
33288 hourglass_atimer = NULL;
33291 if (hourglass_shown_p)
33293 Lisp_Object tail, frame;
33295 block_input ();
33297 FOR_EACH_FRAME (tail, frame)
33299 struct frame *f = XFRAME (frame);
33301 if (FRAME_LIVE_P (f) && FRAME_WINDOW_P (f)
33302 && FRAME_RIF (f)->hide_hourglass)
33303 FRAME_RIF (f)->hide_hourglass (f);
33304 #ifdef HAVE_NTGUI
33305 /* No cursors on non GUI frames - restore to stock arrow cursor. */
33306 else if (!FRAME_W32_P (f))
33307 w32_arrow_cursor ();
33308 #endif
33311 hourglass_shown_p = false;
33312 unblock_input ();
33316 #endif /* HAVE_WINDOW_SYSTEM */