Remove redundant test in fns.c
[emacs.git] / src / xdisp.c
blob9170d6b777f9099ca937bc897039752634023a05
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 if (charpos >= 0
1385 && (((!it.bidi_p || it.bidi_it.scan_dir != -1)
1386 && IT_CHARPOS (it) >= charpos)
1387 /* When scanning backwards under bidi iteration, move_it_to
1388 stops at or _before_ CHARPOS, because it stops at or to
1389 the _right_ of the character at CHARPOS. */
1390 || (it.bidi_p && it.bidi_it.scan_dir == -1
1391 && IT_CHARPOS (it) <= charpos)))
1393 /* We have reached CHARPOS, or passed it. How the call to
1394 move_it_to can overshoot: (i) If CHARPOS is on invisible text
1395 or covered by a display property, move_it_to stops at the end
1396 of the invisible text, to the right of CHARPOS. (ii) If
1397 CHARPOS is in a display vector, move_it_to stops on its last
1398 glyph. */
1399 int top_x = it.current_x;
1400 int top_y = it.current_y;
1401 int window_top_y = WINDOW_HEADER_LINE_HEIGHT (w);
1402 int bottom_y;
1403 struct it save_it;
1404 void *save_it_data = NULL;
1406 /* Calling line_bottom_y may change it.method, it.position, etc. */
1407 SAVE_IT (save_it, it, save_it_data);
1408 last_height = 0;
1409 bottom_y = line_bottom_y (&it);
1410 if (top_y < window_top_y)
1411 visible_p = bottom_y > window_top_y;
1412 else if (top_y < it.last_visible_y)
1413 visible_p = true;
1414 if (bottom_y >= it.last_visible_y
1415 && it.bidi_p && it.bidi_it.scan_dir == -1
1416 && IT_CHARPOS (it) < charpos)
1418 /* When the last line of the window is scanned backwards
1419 under bidi iteration, we could be duped into thinking
1420 that we have passed CHARPOS, when in fact move_it_to
1421 simply stopped short of CHARPOS because it reached
1422 last_visible_y. To see if that's what happened, we call
1423 move_it_to again with a slightly larger vertical limit,
1424 and see if it actually moved vertically; if it did, we
1425 didn't really reach CHARPOS, which is beyond window end. */
1426 /* Why 10? because we don't know how many canonical lines
1427 will the height of the next line(s) be. So we guess. */
1428 int ten_more_lines = 10 * default_line_pixel_height (w);
1430 move_it_to (&it, charpos, -1, bottom_y + ten_more_lines, -1,
1431 MOVE_TO_POS | MOVE_TO_Y);
1432 if (it.current_y > top_y)
1433 visible_p = false;
1436 RESTORE_IT (&it, &save_it, save_it_data);
1437 if (visible_p)
1439 if (it.method == GET_FROM_DISPLAY_VECTOR)
1441 /* We stopped on the last glyph of a display vector.
1442 Try and recompute. Hack alert! */
1443 if (charpos < 2 || top.charpos >= charpos)
1444 top_x = it.glyph_row->x;
1445 else
1447 struct it it2, it2_prev;
1448 /* The idea is to get to the previous buffer
1449 position, consume the character there, and use
1450 the pixel coordinates we get after that. But if
1451 the previous buffer position is also displayed
1452 from a display vector, we need to consume all of
1453 the glyphs from that display vector. */
1454 start_display (&it2, w, top);
1455 move_it_to (&it2, charpos - 1, -1, -1, -1, MOVE_TO_POS);
1456 /* If we didn't get to CHARPOS - 1, there's some
1457 replacing display property at that position, and
1458 we stopped after it. That is exactly the place
1459 whose coordinates we want. */
1460 if (IT_CHARPOS (it2) != charpos - 1)
1461 it2_prev = it2;
1462 else
1464 /* Iterate until we get out of the display
1465 vector that displays the character at
1466 CHARPOS - 1. */
1467 do {
1468 get_next_display_element (&it2);
1469 PRODUCE_GLYPHS (&it2);
1470 it2_prev = it2;
1471 set_iterator_to_next (&it2, true);
1472 } while (it2.method == GET_FROM_DISPLAY_VECTOR
1473 && IT_CHARPOS (it2) < charpos);
1475 if (ITERATOR_AT_END_OF_LINE_P (&it2_prev)
1476 || it2_prev.current_x > it2_prev.last_visible_x)
1477 top_x = it.glyph_row->x;
1478 else
1480 top_x = it2_prev.current_x;
1481 top_y = it2_prev.current_y;
1485 else if (IT_CHARPOS (it) != charpos)
1487 Lisp_Object cpos = make_number (charpos);
1488 Lisp_Object spec = Fget_char_property (cpos, Qdisplay, Qnil);
1489 Lisp_Object string = string_from_display_spec (spec);
1490 struct text_pos tpos;
1491 bool newline_in_string
1492 = (STRINGP (string)
1493 && memchr (SDATA (string), '\n', SBYTES (string)));
1495 SET_TEXT_POS (tpos, charpos, CHAR_TO_BYTE (charpos));
1496 bool replacing_spec_p
1497 = (!NILP (spec)
1498 && handle_display_spec (NULL, spec, Qnil, Qnil, &tpos,
1499 charpos, FRAME_WINDOW_P (it.f)));
1500 /* The tricky code below is needed because there's a
1501 discrepancy between move_it_to and how we set cursor
1502 when PT is at the beginning of a portion of text
1503 covered by a display property or an overlay with a
1504 display property, or the display line ends in a
1505 newline from a display string. move_it_to will stop
1506 _after_ such display strings, whereas
1507 set_cursor_from_row conspires with cursor_row_p to
1508 place the cursor on the first glyph produced from the
1509 display string. */
1511 /* We have overshoot PT because it is covered by a
1512 display property that replaces the text it covers.
1513 If the string includes embedded newlines, we are also
1514 in the wrong display line. Backtrack to the correct
1515 line, where the display property begins. */
1516 if (replacing_spec_p)
1518 Lisp_Object startpos, endpos;
1519 EMACS_INT start, end;
1520 struct it it3;
1522 /* Find the first and the last buffer positions
1523 covered by the display string. */
1524 endpos =
1525 Fnext_single_char_property_change (cpos, Qdisplay,
1526 Qnil, Qnil);
1527 startpos =
1528 Fprevious_single_char_property_change (endpos, Qdisplay,
1529 Qnil, Qnil);
1530 start = XFASTINT (startpos);
1531 end = XFASTINT (endpos);
1532 /* Move to the last buffer position before the
1533 display property. */
1534 start_display (&it3, w, top);
1535 if (start > CHARPOS (top))
1536 move_it_to (&it3, start - 1, -1, -1, -1, MOVE_TO_POS);
1537 /* Move forward one more line if the position before
1538 the display string is a newline or if it is the
1539 rightmost character on a line that is
1540 continued or word-wrapped. */
1541 if (it3.method == GET_FROM_BUFFER
1542 && (it3.c == '\n'
1543 || FETCH_BYTE (IT_BYTEPOS (it3)) == '\n'))
1544 move_it_by_lines (&it3, 1);
1545 else if (move_it_in_display_line_to (&it3, -1,
1546 it3.current_x
1547 + it3.pixel_width,
1548 MOVE_TO_X)
1549 == MOVE_LINE_CONTINUED)
1551 move_it_by_lines (&it3, 1);
1552 /* When we are under word-wrap, the #$@%!
1553 move_it_by_lines moves 2 lines, so we need to
1554 fix that up. */
1555 if (it3.line_wrap == WORD_WRAP)
1556 move_it_by_lines (&it3, -1);
1559 /* Record the vertical coordinate of the display
1560 line where we wound up. */
1561 top_y = it3.current_y;
1562 if (it3.bidi_p)
1564 /* When characters are reordered for display,
1565 the character displayed to the left of the
1566 display string could be _after_ the display
1567 property in the logical order. Use the
1568 smallest vertical position of these two. */
1569 start_display (&it3, w, top);
1570 move_it_to (&it3, end + 1, -1, -1, -1, MOVE_TO_POS);
1571 if (it3.current_y < top_y)
1572 top_y = it3.current_y;
1574 /* Move from the top of the window to the beginning
1575 of the display line where the display string
1576 begins. */
1577 start_display (&it3, w, top);
1578 move_it_to (&it3, -1, 0, top_y, -1, MOVE_TO_X | MOVE_TO_Y);
1579 /* If it3_moved stays false after the 'while' loop
1580 below, that means we already were at a newline
1581 before the loop (e.g., the display string begins
1582 with a newline), so we don't need to (and cannot)
1583 inspect the glyphs of it3.glyph_row, because
1584 PRODUCE_GLYPHS will not produce anything for a
1585 newline, and thus it3.glyph_row stays at its
1586 stale content it got at top of the window. */
1587 bool it3_moved = false;
1588 /* Finally, advance the iterator until we hit the
1589 first display element whose character position is
1590 CHARPOS, or until the first newline from the
1591 display string, which signals the end of the
1592 display line. */
1593 while (get_next_display_element (&it3))
1595 PRODUCE_GLYPHS (&it3);
1596 if (IT_CHARPOS (it3) == charpos
1597 || ITERATOR_AT_END_OF_LINE_P (&it3))
1598 break;
1599 it3_moved = true;
1600 set_iterator_to_next (&it3, false);
1602 top_x = it3.current_x - it3.pixel_width;
1603 /* Normally, we would exit the above loop because we
1604 found the display element whose character
1605 position is CHARPOS. For the contingency that we
1606 didn't, and stopped at the first newline from the
1607 display string, move back over the glyphs
1608 produced from the string, until we find the
1609 rightmost glyph not from the string. */
1610 if (it3_moved
1611 && newline_in_string
1612 && IT_CHARPOS (it3) != charpos && EQ (it3.object, string))
1614 struct glyph *g = it3.glyph_row->glyphs[TEXT_AREA]
1615 + it3.glyph_row->used[TEXT_AREA];
1617 while (EQ ((g - 1)->object, string))
1619 --g;
1620 top_x -= g->pixel_width;
1622 eassert (g < it3.glyph_row->glyphs[TEXT_AREA]
1623 + it3.glyph_row->used[TEXT_AREA]);
1628 *x = top_x;
1629 *y = max (top_y + max (0, it.max_ascent - it.ascent), window_top_y);
1630 *rtop = max (0, window_top_y - top_y);
1631 *rbot = max (0, bottom_y - it.last_visible_y);
1632 *rowh = max (0, (min (bottom_y, it.last_visible_y)
1633 - max (top_y, window_top_y)));
1634 *vpos = it.vpos;
1635 if (it.bidi_it.paragraph_dir == R2L)
1636 r2l = true;
1639 else
1641 /* Either we were asked to provide info about WINDOW_END, or
1642 CHARPOS is in the partially visible glyph row at end of
1643 window. */
1644 struct it it2;
1645 void *it2data = NULL;
1647 SAVE_IT (it2, it, it2data);
1648 if (IT_CHARPOS (it) < ZV && FETCH_BYTE (IT_BYTEPOS (it)) != '\n')
1649 move_it_by_lines (&it, 1);
1650 if (charpos < IT_CHARPOS (it)
1651 || (it.what == IT_EOB && charpos == IT_CHARPOS (it)))
1653 visible_p = true;
1654 RESTORE_IT (&it2, &it2, it2data);
1655 move_it_to (&it2, charpos, -1, -1, -1, MOVE_TO_POS);
1656 *x = it2.current_x;
1657 *y = it2.current_y + it2.max_ascent - it2.ascent;
1658 *rtop = max (0, -it2.current_y);
1659 *rbot = max (0, ((it2.current_y + it2.max_ascent + it2.max_descent)
1660 - it.last_visible_y));
1661 *rowh = max (0, (min (it2.current_y + it2.max_ascent + it2.max_descent,
1662 it.last_visible_y)
1663 - max (it2.current_y,
1664 WINDOW_HEADER_LINE_HEIGHT (w))));
1665 *vpos = it2.vpos;
1666 if (it2.bidi_it.paragraph_dir == R2L)
1667 r2l = true;
1669 else
1670 bidi_unshelve_cache (it2data, true);
1672 bidi_unshelve_cache (itdata, false);
1674 if (old_buffer)
1675 set_buffer_internal_1 (old_buffer);
1677 if (visible_p)
1679 if (w->hscroll > 0)
1680 *x -=
1681 window_hscroll_limited (w, WINDOW_XFRAME (w))
1682 * WINDOW_FRAME_COLUMN_WIDTH (w);
1683 /* For lines in an R2L paragraph, we need to mirror the X pixel
1684 coordinate wrt the text area. For the reasons, see the
1685 commentary in buffer_posn_from_coords and the explanation of
1686 the geometry used by the move_it_* functions at the end of
1687 the large commentary near the beginning of this file. */
1688 if (r2l)
1689 *x = window_box_width (w, TEXT_AREA) - *x - 1;
1692 #if false
1693 /* Debugging code. */
1694 if (visible_p)
1695 fprintf (stderr, "+pv pt=%d vs=%d --> x=%d y=%d rt=%d rb=%d rh=%d vp=%d\n",
1696 charpos, w->vscroll, *x, *y, *rtop, *rbot, *rowh, *vpos);
1697 else
1698 fprintf (stderr, "-pv pt=%d vs=%d\n", charpos, w->vscroll);
1699 #endif
1701 /* Restore potentially overwritten values. */
1702 w->mode_line_height = prev_mode_line_height;
1703 w->header_line_height = prev_header_line_height;
1705 return visible_p;
1709 /* Return the next character from STR. Return in *LEN the length of
1710 the character. This is like STRING_CHAR_AND_LENGTH but never
1711 returns an invalid character. If we find one, we return a `?', but
1712 with the length of the invalid character. */
1714 static int
1715 string_char_and_length (const unsigned char *str, int *len)
1717 int c;
1719 c = STRING_CHAR_AND_LENGTH (str, *len);
1720 if (!CHAR_VALID_P (c))
1721 /* We may not change the length here because other places in Emacs
1722 don't use this function, i.e. they silently accept invalid
1723 characters. */
1724 c = '?';
1726 return c;
1731 /* Given a position POS containing a valid character and byte position
1732 in STRING, return the position NCHARS ahead (NCHARS >= 0). */
1734 static struct text_pos
1735 string_pos_nchars_ahead (struct text_pos pos, Lisp_Object string, ptrdiff_t nchars)
1737 eassert (STRINGP (string) && nchars >= 0);
1739 if (STRING_MULTIBYTE (string))
1741 const unsigned char *p = SDATA (string) + BYTEPOS (pos);
1742 int len;
1744 while (nchars--)
1746 string_char_and_length (p, &len);
1747 p += len;
1748 CHARPOS (pos) += 1;
1749 BYTEPOS (pos) += len;
1752 else
1753 SET_TEXT_POS (pos, CHARPOS (pos) + nchars, BYTEPOS (pos) + nchars);
1755 return pos;
1759 /* Value is the text position, i.e. character and byte position,
1760 for character position CHARPOS in STRING. */
1762 static struct text_pos
1763 string_pos (ptrdiff_t charpos, Lisp_Object string)
1765 struct text_pos pos;
1766 eassert (STRINGP (string));
1767 eassert (charpos >= 0);
1768 SET_TEXT_POS (pos, charpos, string_char_to_byte (string, charpos));
1769 return pos;
1773 /* Value is a text position, i.e. character and byte position, for
1774 character position CHARPOS in C string S. MULTIBYTE_P
1775 means recognize multibyte characters. */
1777 static struct text_pos
1778 c_string_pos (ptrdiff_t charpos, const char *s, bool multibyte_p)
1780 struct text_pos pos;
1782 eassert (s != NULL);
1783 eassert (charpos >= 0);
1785 if (multibyte_p)
1787 int len;
1789 SET_TEXT_POS (pos, 0, 0);
1790 while (charpos--)
1792 string_char_and_length ((const unsigned char *) s, &len);
1793 s += len;
1794 CHARPOS (pos) += 1;
1795 BYTEPOS (pos) += len;
1798 else
1799 SET_TEXT_POS (pos, charpos, charpos);
1801 return pos;
1805 /* Value is the number of characters in C string S. MULTIBYTE_P
1806 means recognize multibyte characters. */
1808 static ptrdiff_t
1809 number_of_chars (const char *s, bool multibyte_p)
1811 ptrdiff_t nchars;
1813 if (multibyte_p)
1815 ptrdiff_t rest = strlen (s);
1816 int len;
1817 const unsigned char *p = (const unsigned char *) s;
1819 for (nchars = 0; rest > 0; ++nchars)
1821 string_char_and_length (p, &len);
1822 rest -= len, p += len;
1825 else
1826 nchars = strlen (s);
1828 return nchars;
1832 /* Compute byte position NEWPOS->bytepos corresponding to
1833 NEWPOS->charpos. POS is a known position in string STRING.
1834 NEWPOS->charpos must be >= POS.charpos. */
1836 static void
1837 compute_string_pos (struct text_pos *newpos, struct text_pos pos, Lisp_Object string)
1839 eassert (STRINGP (string));
1840 eassert (CHARPOS (*newpos) >= CHARPOS (pos));
1842 if (STRING_MULTIBYTE (string))
1843 *newpos = string_pos_nchars_ahead (pos, string,
1844 CHARPOS (*newpos) - CHARPOS (pos));
1845 else
1846 BYTEPOS (*newpos) = CHARPOS (*newpos);
1849 /* EXPORT:
1850 Return an estimation of the pixel height of mode or header lines on
1851 frame F. FACE_ID specifies what line's height to estimate. */
1854 estimate_mode_line_height (struct frame *f, enum face_id face_id)
1856 #ifdef HAVE_WINDOW_SYSTEM
1857 if (FRAME_WINDOW_P (f))
1859 int height = FONT_HEIGHT (FRAME_FONT (f));
1861 /* This function is called so early when Emacs starts that the face
1862 cache and mode line face are not yet initialized. */
1863 if (FRAME_FACE_CACHE (f))
1865 struct face *face = FACE_FROM_ID_OR_NULL (f, face_id);
1866 if (face)
1868 if (face->font)
1869 height = normal_char_height (face->font, -1);
1870 if (face->box_line_width > 0)
1871 height += 2 * face->box_line_width;
1875 return height;
1877 #endif
1879 return 1;
1882 /* Given a pixel position (PIX_X, PIX_Y) on frame F, return glyph
1883 co-ordinates in (*X, *Y). Set *BOUNDS to the rectangle that the
1884 glyph at X, Y occupies, if BOUNDS != 0. If NOCLIP, do
1885 not force the value into range. */
1887 void
1888 pixel_to_glyph_coords (struct frame *f, int pix_x, int pix_y, int *x, int *y,
1889 NativeRectangle *bounds, bool noclip)
1892 #ifdef HAVE_WINDOW_SYSTEM
1893 if (FRAME_WINDOW_P (f))
1895 /* Arrange for the division in FRAME_PIXEL_X_TO_COL etc. to round down
1896 even for negative values. */
1897 if (pix_x < 0)
1898 pix_x -= FRAME_COLUMN_WIDTH (f) - 1;
1899 if (pix_y < 0)
1900 pix_y -= FRAME_LINE_HEIGHT (f) - 1;
1902 pix_x = FRAME_PIXEL_X_TO_COL (f, pix_x);
1903 pix_y = FRAME_PIXEL_Y_TO_LINE (f, pix_y);
1905 if (bounds)
1906 STORE_NATIVE_RECT (*bounds,
1907 FRAME_COL_TO_PIXEL_X (f, pix_x),
1908 FRAME_LINE_TO_PIXEL_Y (f, pix_y),
1909 FRAME_COLUMN_WIDTH (f) - 1,
1910 FRAME_LINE_HEIGHT (f) - 1);
1912 /* PXW: Should we clip pixels before converting to columns/lines? */
1913 if (!noclip)
1915 if (pix_x < 0)
1916 pix_x = 0;
1917 else if (pix_x > FRAME_TOTAL_COLS (f))
1918 pix_x = FRAME_TOTAL_COLS (f);
1920 if (pix_y < 0)
1921 pix_y = 0;
1922 else if (pix_y > FRAME_TOTAL_LINES (f))
1923 pix_y = FRAME_TOTAL_LINES (f);
1926 #endif
1928 *x = pix_x;
1929 *y = pix_y;
1933 /* Find the glyph under window-relative coordinates X/Y in window W.
1934 Consider only glyphs from buffer text, i.e. no glyphs from overlay
1935 strings. Return in *HPOS and *VPOS the row and column number of
1936 the glyph found. Return in *AREA the glyph area containing X.
1937 Value is a pointer to the glyph found or null if X/Y is not on
1938 text, or we can't tell because W's current matrix is not up to
1939 date. */
1941 static struct glyph *
1942 x_y_to_hpos_vpos (struct window *w, int x, int y, int *hpos, int *vpos,
1943 int *dx, int *dy, int *area)
1945 struct glyph *glyph, *end;
1946 struct glyph_row *row = NULL;
1947 int x0, i;
1949 /* Find row containing Y. Give up if some row is not enabled. */
1950 for (i = 0; i < w->current_matrix->nrows; ++i)
1952 row = MATRIX_ROW (w->current_matrix, i);
1953 if (!row->enabled_p)
1954 return NULL;
1955 if (y >= row->y && y < MATRIX_ROW_BOTTOM_Y (row))
1956 break;
1959 *vpos = i;
1960 *hpos = 0;
1962 /* Give up if Y is not in the window. */
1963 if (i == w->current_matrix->nrows)
1964 return NULL;
1966 /* Get the glyph area containing X. */
1967 if (w->pseudo_window_p)
1969 *area = TEXT_AREA;
1970 x0 = 0;
1972 else
1974 if (x < window_box_left_offset (w, TEXT_AREA))
1976 *area = LEFT_MARGIN_AREA;
1977 x0 = window_box_left_offset (w, LEFT_MARGIN_AREA);
1979 else if (x < window_box_right_offset (w, TEXT_AREA))
1981 *area = TEXT_AREA;
1982 x0 = window_box_left_offset (w, TEXT_AREA) + min (row->x, 0);
1984 else
1986 *area = RIGHT_MARGIN_AREA;
1987 x0 = window_box_left_offset (w, RIGHT_MARGIN_AREA);
1991 /* Find glyph containing X. */
1992 glyph = row->glyphs[*area];
1993 end = glyph + row->used[*area];
1994 x -= x0;
1995 while (glyph < end && x >= glyph->pixel_width)
1997 x -= glyph->pixel_width;
1998 ++glyph;
2001 if (glyph == end)
2002 return NULL;
2004 if (dx)
2006 *dx = x;
2007 *dy = y - (row->y + row->ascent - glyph->ascent);
2010 *hpos = glyph - row->glyphs[*area];
2011 return glyph;
2014 /* Convert frame-relative x/y to coordinates relative to window W.
2015 Takes pseudo-windows into account. */
2017 static void
2018 frame_to_window_pixel_xy (struct window *w, int *x, int *y)
2020 if (w->pseudo_window_p)
2022 /* A pseudo-window is always full-width, and starts at the
2023 left edge of the frame, plus a frame border. */
2024 struct frame *f = XFRAME (w->frame);
2025 *x -= FRAME_INTERNAL_BORDER_WIDTH (f);
2026 *y = FRAME_TO_WINDOW_PIXEL_Y (w, *y);
2028 else
2030 *x -= WINDOW_LEFT_EDGE_X (w);
2031 *y = FRAME_TO_WINDOW_PIXEL_Y (w, *y);
2035 #ifdef HAVE_WINDOW_SYSTEM
2037 /* EXPORT:
2038 Return in RECTS[] at most N clipping rectangles for glyph string S.
2039 Return the number of stored rectangles. */
2042 get_glyph_string_clip_rects (struct glyph_string *s, NativeRectangle *rects, int n)
2044 XRectangle r;
2046 if (n <= 0)
2047 return 0;
2049 if (s->row->full_width_p)
2051 /* Draw full-width. X coordinates are relative to S->w->left_col. */
2052 r.x = WINDOW_LEFT_EDGE_X (s->w);
2053 if (s->row->mode_line_p)
2054 r.width = WINDOW_PIXEL_WIDTH (s->w) - WINDOW_RIGHT_DIVIDER_WIDTH (s->w);
2055 else
2056 r.width = WINDOW_PIXEL_WIDTH (s->w);
2058 /* Unless displaying a mode or menu bar line, which are always
2059 fully visible, clip to the visible part of the row. */
2060 if (s->w->pseudo_window_p)
2061 r.height = s->row->visible_height;
2062 else
2063 r.height = s->height;
2065 else
2067 /* This is a text line that may be partially visible. */
2068 r.x = window_box_left (s->w, s->area);
2069 r.width = window_box_width (s->w, s->area);
2070 r.height = s->row->visible_height;
2073 if (s->clip_head)
2074 if (r.x < s->clip_head->x)
2076 if (r.width >= s->clip_head->x - r.x)
2077 r.width -= s->clip_head->x - r.x;
2078 else
2079 r.width = 0;
2080 r.x = s->clip_head->x;
2082 if (s->clip_tail)
2083 if (r.x + r.width > s->clip_tail->x + s->clip_tail->background_width)
2085 if (s->clip_tail->x + s->clip_tail->background_width >= r.x)
2086 r.width = s->clip_tail->x + s->clip_tail->background_width - r.x;
2087 else
2088 r.width = 0;
2091 /* If S draws overlapping rows, it's sufficient to use the top and
2092 bottom of the window for clipping because this glyph string
2093 intentionally draws over other lines. */
2094 if (s->for_overlaps)
2096 r.y = WINDOW_HEADER_LINE_HEIGHT (s->w);
2097 r.height = window_text_bottom_y (s->w) - r.y;
2099 /* Alas, the above simple strategy does not work for the
2100 environments with anti-aliased text: if the same text is
2101 drawn onto the same place multiple times, it gets thicker.
2102 If the overlap we are processing is for the erased cursor, we
2103 take the intersection with the rectangle of the cursor. */
2104 if (s->for_overlaps & OVERLAPS_ERASED_CURSOR)
2106 XRectangle rc, r_save = r;
2108 rc.x = WINDOW_TEXT_TO_FRAME_PIXEL_X (s->w, s->w->phys_cursor.x);
2109 rc.y = s->w->phys_cursor.y;
2110 rc.width = s->w->phys_cursor_width;
2111 rc.height = s->w->phys_cursor_height;
2113 x_intersect_rectangles (&r_save, &rc, &r);
2116 else
2118 /* Don't use S->y for clipping because it doesn't take partially
2119 visible lines into account. For example, it can be negative for
2120 partially visible lines at the top of a window. */
2121 if (!s->row->full_width_p
2122 && MATRIX_ROW_PARTIALLY_VISIBLE_AT_TOP_P (s->w, s->row))
2123 r.y = WINDOW_HEADER_LINE_HEIGHT (s->w);
2124 else
2125 r.y = max (0, s->row->y);
2128 r.y = WINDOW_TO_FRAME_PIXEL_Y (s->w, r.y);
2130 /* If drawing the cursor, don't let glyph draw outside its
2131 advertised boundaries. Cleartype does this under some circumstances. */
2132 if (s->hl == DRAW_CURSOR)
2134 struct glyph *glyph = s->first_glyph;
2135 int height, max_y;
2137 if (s->x > r.x)
2139 if (r.width >= s->x - r.x)
2140 r.width -= s->x - r.x;
2141 else /* R2L hscrolled row with cursor outside text area */
2142 r.width = 0;
2143 r.x = s->x;
2145 r.width = min (r.width, glyph->pixel_width);
2147 /* If r.y is below window bottom, ensure that we still see a cursor. */
2148 height = min (glyph->ascent + glyph->descent,
2149 min (FRAME_LINE_HEIGHT (s->f), s->row->visible_height));
2150 max_y = window_text_bottom_y (s->w) - height;
2151 max_y = WINDOW_TO_FRAME_PIXEL_Y (s->w, max_y);
2152 if (s->ybase - glyph->ascent > max_y)
2154 r.y = max_y;
2155 r.height = height;
2157 else
2159 /* Don't draw cursor glyph taller than our actual glyph. */
2160 height = max (FRAME_LINE_HEIGHT (s->f), glyph->ascent + glyph->descent);
2161 if (height < r.height)
2163 max_y = r.y + r.height;
2164 r.y = min (max_y, max (r.y, s->ybase + glyph->descent - height));
2165 r.height = min (max_y - r.y, height);
2170 if (s->row->clip)
2172 XRectangle r_save = r;
2174 if (! x_intersect_rectangles (&r_save, s->row->clip, &r))
2175 r.width = 0;
2178 if ((s->for_overlaps & OVERLAPS_BOTH) == 0
2179 || ((s->for_overlaps & OVERLAPS_BOTH) == OVERLAPS_BOTH && n == 1))
2181 #ifdef CONVERT_FROM_XRECT
2182 CONVERT_FROM_XRECT (r, *rects);
2183 #else
2184 *rects = r;
2185 #endif
2186 return 1;
2188 else
2190 /* If we are processing overlapping and allowed to return
2191 multiple clipping rectangles, we exclude the row of the glyph
2192 string from the clipping rectangle. This is to avoid drawing
2193 the same text on the environment with anti-aliasing. */
2194 #ifdef CONVERT_FROM_XRECT
2195 XRectangle rs[2];
2196 #else
2197 XRectangle *rs = rects;
2198 #endif
2199 int i = 0, row_y = WINDOW_TO_FRAME_PIXEL_Y (s->w, s->row->y);
2201 if (s->for_overlaps & OVERLAPS_PRED)
2203 rs[i] = r;
2204 if (r.y + r.height > row_y)
2206 if (r.y < row_y)
2207 rs[i].height = row_y - r.y;
2208 else
2209 rs[i].height = 0;
2211 i++;
2213 if (s->for_overlaps & OVERLAPS_SUCC)
2215 rs[i] = r;
2216 if (r.y < row_y + s->row->visible_height)
2218 if (r.y + r.height > row_y + s->row->visible_height)
2220 rs[i].y = row_y + s->row->visible_height;
2221 rs[i].height = r.y + r.height - rs[i].y;
2223 else
2224 rs[i].height = 0;
2226 i++;
2229 n = i;
2230 #ifdef CONVERT_FROM_XRECT
2231 for (i = 0; i < n; i++)
2232 CONVERT_FROM_XRECT (rs[i], rects[i]);
2233 #endif
2234 return n;
2238 /* EXPORT:
2239 Return in *NR the clipping rectangle for glyph string S. */
2241 void
2242 get_glyph_string_clip_rect (struct glyph_string *s, NativeRectangle *nr)
2244 get_glyph_string_clip_rects (s, nr, 1);
2248 /* EXPORT:
2249 Return the position and height of the phys cursor in window W.
2250 Set w->phys_cursor_width to width of phys cursor.
2253 void
2254 get_phys_cursor_geometry (struct window *w, struct glyph_row *row,
2255 struct glyph *glyph, int *xp, int *yp, int *heightp)
2257 struct frame *f = XFRAME (WINDOW_FRAME (w));
2258 int x, y, wd, h, h0, y0, ascent;
2260 /* Compute the width of the rectangle to draw. If on a stretch
2261 glyph, and `x-stretch-block-cursor' is nil, don't draw a
2262 rectangle as wide as the glyph, but use a canonical character
2263 width instead. */
2264 wd = glyph->pixel_width;
2266 x = w->phys_cursor.x;
2267 if (x < 0)
2269 wd += x;
2270 x = 0;
2273 if (glyph->type == STRETCH_GLYPH
2274 && !x_stretch_cursor_p)
2275 wd = min (FRAME_COLUMN_WIDTH (f), wd);
2276 w->phys_cursor_width = wd;
2278 /* Don't let the hollow cursor glyph descend below the glyph row's
2279 ascent value, lest the hollow cursor looks funny. */
2280 y = w->phys_cursor.y;
2281 ascent = row->ascent;
2282 if (row->ascent < glyph->ascent)
2284 y -= glyph->ascent - row->ascent;
2285 ascent = glyph->ascent;
2288 /* If y is below window bottom, ensure that we still see a cursor. */
2289 h0 = min (FRAME_LINE_HEIGHT (f), row->visible_height);
2291 h = max (h0, ascent + glyph->descent);
2292 h0 = min (h0, ascent + glyph->descent);
2294 y0 = WINDOW_HEADER_LINE_HEIGHT (w);
2295 if (y < y0)
2297 h = max (h - (y0 - y) + 1, h0);
2298 y = y0 - 1;
2300 else
2302 y0 = window_text_bottom_y (w) - h0;
2303 if (y > y0)
2305 h += y - y0;
2306 y = y0;
2310 *xp = WINDOW_TEXT_TO_FRAME_PIXEL_X (w, x);
2311 *yp = WINDOW_TO_FRAME_PIXEL_Y (w, y);
2312 *heightp = h;
2316 * Remember which glyph the mouse is over.
2319 void
2320 remember_mouse_glyph (struct frame *f, int gx, int gy, NativeRectangle *rect)
2322 Lisp_Object window;
2323 struct window *w;
2324 struct glyph_row *r, *gr, *end_row;
2325 enum window_part part;
2326 enum glyph_row_area area;
2327 int x, y, width, height;
2329 /* Try to determine frame pixel position and size of the glyph under
2330 frame pixel coordinates X/Y on frame F. */
2332 if (window_resize_pixelwise)
2334 width = height = 1;
2335 goto virtual_glyph;
2337 else if (!f->glyphs_initialized_p
2338 || (window = window_from_coordinates (f, gx, gy, &part, false),
2339 NILP (window)))
2341 width = FRAME_SMALLEST_CHAR_WIDTH (f);
2342 height = FRAME_SMALLEST_FONT_HEIGHT (f);
2343 goto virtual_glyph;
2346 w = XWINDOW (window);
2347 width = WINDOW_FRAME_COLUMN_WIDTH (w);
2348 height = WINDOW_FRAME_LINE_HEIGHT (w);
2350 x = window_relative_x_coord (w, part, gx);
2351 y = gy - WINDOW_TOP_EDGE_Y (w);
2353 r = MATRIX_FIRST_TEXT_ROW (w->current_matrix);
2354 end_row = MATRIX_BOTTOM_TEXT_ROW (w->current_matrix, w);
2356 if (w->pseudo_window_p)
2358 area = TEXT_AREA;
2359 part = ON_MODE_LINE; /* Don't adjust margin. */
2360 goto text_glyph;
2363 switch (part)
2365 case ON_LEFT_MARGIN:
2366 area = LEFT_MARGIN_AREA;
2367 goto text_glyph;
2369 case ON_RIGHT_MARGIN:
2370 area = RIGHT_MARGIN_AREA;
2371 goto text_glyph;
2373 case ON_HEADER_LINE:
2374 case ON_MODE_LINE:
2375 gr = (part == ON_HEADER_LINE
2376 ? MATRIX_HEADER_LINE_ROW (w->current_matrix)
2377 : MATRIX_MODE_LINE_ROW (w->current_matrix));
2378 gy = gr->y;
2379 area = TEXT_AREA;
2380 goto text_glyph_row_found;
2382 case ON_TEXT:
2383 area = TEXT_AREA;
2385 text_glyph:
2386 gr = 0; gy = 0;
2387 for (; r <= end_row && r->enabled_p; ++r)
2388 if (r->y + r->height > y)
2390 gr = r; gy = r->y;
2391 break;
2394 text_glyph_row_found:
2395 if (gr && gy <= y)
2397 struct glyph *g = gr->glyphs[area];
2398 struct glyph *end = g + gr->used[area];
2400 height = gr->height;
2401 for (gx = gr->x; g < end; gx += g->pixel_width, ++g)
2402 if (gx + g->pixel_width > x)
2403 break;
2405 if (g < end)
2407 if (g->type == IMAGE_GLYPH)
2409 /* Don't remember when mouse is over image, as
2410 image may have hot-spots. */
2411 STORE_NATIVE_RECT (*rect, 0, 0, 0, 0);
2412 return;
2414 width = g->pixel_width;
2416 else
2418 /* Use nominal char spacing at end of line. */
2419 x -= gx;
2420 gx += (x / width) * width;
2423 if (part != ON_MODE_LINE && part != ON_HEADER_LINE)
2425 gx += window_box_left_offset (w, area);
2426 /* Don't expand over the modeline to make sure the vertical
2427 drag cursor is shown early enough. */
2428 height = min (height,
2429 max (0, WINDOW_BOX_HEIGHT_NO_MODE_LINE (w) - gy));
2432 else
2434 /* Use nominal line height at end of window. */
2435 gx = (x / width) * width;
2436 y -= gy;
2437 gy += (y / height) * height;
2438 if (part != ON_MODE_LINE && part != ON_HEADER_LINE)
2439 /* See comment above. */
2440 height = min (height,
2441 max (0, WINDOW_BOX_HEIGHT_NO_MODE_LINE (w) - gy));
2443 break;
2445 case ON_LEFT_FRINGE:
2446 gx = (WINDOW_HAS_FRINGES_OUTSIDE_MARGINS (w)
2447 ? WINDOW_LEFT_SCROLL_BAR_AREA_WIDTH (w)
2448 : window_box_right_offset (w, LEFT_MARGIN_AREA));
2449 width = WINDOW_LEFT_FRINGE_WIDTH (w);
2450 goto row_glyph;
2452 case ON_RIGHT_FRINGE:
2453 gx = (WINDOW_HAS_FRINGES_OUTSIDE_MARGINS (w)
2454 ? window_box_right_offset (w, RIGHT_MARGIN_AREA)
2455 : window_box_right_offset (w, TEXT_AREA));
2456 if (WINDOW_RIGHT_DIVIDER_WIDTH (w) == 0
2457 && !WINDOW_HAS_VERTICAL_SCROLL_BAR (w)
2458 && !WINDOW_RIGHTMOST_P (w))
2459 if (gx < WINDOW_PIXEL_WIDTH (w) - width)
2460 /* Make sure the vertical border can get her own glyph to the
2461 right of the one we build here. */
2462 width = WINDOW_RIGHT_FRINGE_WIDTH (w) - width;
2463 else
2464 width = WINDOW_PIXEL_WIDTH (w) - gx;
2465 else
2466 width = WINDOW_RIGHT_FRINGE_WIDTH (w);
2468 goto row_glyph;
2470 case ON_VERTICAL_BORDER:
2471 gx = WINDOW_PIXEL_WIDTH (w) - width;
2472 goto row_glyph;
2474 case ON_VERTICAL_SCROLL_BAR:
2475 gx = (WINDOW_HAS_VERTICAL_SCROLL_BAR_ON_LEFT (w)
2477 : (window_box_right_offset (w, RIGHT_MARGIN_AREA)
2478 + (WINDOW_HAS_FRINGES_OUTSIDE_MARGINS (w)
2479 ? WINDOW_RIGHT_FRINGE_WIDTH (w)
2480 : 0)));
2481 width = WINDOW_SCROLL_BAR_AREA_WIDTH (w);
2483 row_glyph:
2484 gr = 0, gy = 0;
2485 for (; r <= end_row && r->enabled_p; ++r)
2486 if (r->y + r->height > y)
2488 gr = r; gy = r->y;
2489 break;
2492 if (gr && gy <= y)
2493 height = gr->height;
2494 else
2496 /* Use nominal line height at end of window. */
2497 y -= gy;
2498 gy += (y / height) * height;
2500 break;
2502 case ON_RIGHT_DIVIDER:
2503 gx = WINDOW_PIXEL_WIDTH (w) - WINDOW_RIGHT_DIVIDER_WIDTH (w);
2504 width = WINDOW_RIGHT_DIVIDER_WIDTH (w);
2505 gy = 0;
2506 /* The bottom divider prevails. */
2507 height = WINDOW_PIXEL_HEIGHT (w) - WINDOW_BOTTOM_DIVIDER_WIDTH (w);
2508 goto add_edge;
2510 case ON_BOTTOM_DIVIDER:
2511 gx = 0;
2512 width = WINDOW_PIXEL_WIDTH (w);
2513 gy = WINDOW_PIXEL_HEIGHT (w) - WINDOW_BOTTOM_DIVIDER_WIDTH (w);
2514 height = WINDOW_BOTTOM_DIVIDER_WIDTH (w);
2515 goto add_edge;
2517 default:
2519 virtual_glyph:
2520 /* If there is no glyph under the mouse, then we divide the screen
2521 into a grid of the smallest glyph in the frame, and use that
2522 as our "glyph". */
2524 /* Arrange for the division in FRAME_PIXEL_X_TO_COL etc. to
2525 round down even for negative values. */
2526 if (gx < 0)
2527 gx -= width - 1;
2528 if (gy < 0)
2529 gy -= height - 1;
2531 gx = (gx / width) * width;
2532 gy = (gy / height) * height;
2534 goto store_rect;
2537 add_edge:
2538 gx += WINDOW_LEFT_EDGE_X (w);
2539 gy += WINDOW_TOP_EDGE_Y (w);
2541 store_rect:
2542 STORE_NATIVE_RECT (*rect, gx, gy, width, height);
2544 /* Visible feedback for debugging. */
2545 #if false && defined HAVE_X_WINDOWS
2546 XDrawRectangle (FRAME_X_DISPLAY (f), FRAME_X_DRAWABLE (f),
2547 f->output_data.x->normal_gc,
2548 gx, gy, width, height);
2549 #endif
2553 #endif /* HAVE_WINDOW_SYSTEM */
2555 static void
2556 adjust_window_ends (struct window *w, struct glyph_row *row, bool current)
2558 eassert (w);
2559 w->window_end_pos = Z - MATRIX_ROW_END_CHARPOS (row);
2560 w->window_end_bytepos = Z_BYTE - MATRIX_ROW_END_BYTEPOS (row);
2561 w->window_end_vpos
2562 = MATRIX_ROW_VPOS (row, current ? w->current_matrix : w->desired_matrix);
2565 static bool
2566 hscrolling_current_line_p (struct window *w)
2568 return (!w->suspend_auto_hscroll
2569 && EQ (Fbuffer_local_value (Qauto_hscroll_mode, w->contents),
2570 Qcurrent_line));
2573 /***********************************************************************
2574 Lisp form evaluation
2575 ***********************************************************************/
2577 /* Error handler for safe_eval and safe_call. */
2579 static Lisp_Object
2580 safe_eval_handler (Lisp_Object arg, ptrdiff_t nargs, Lisp_Object *args)
2582 add_to_log ("Error during redisplay: %S signaled %S",
2583 Flist (nargs, args), arg);
2584 return Qnil;
2587 /* Call function FUNC with the rest of NARGS - 1 arguments
2588 following. Return the result, or nil if something went
2589 wrong. Prevent redisplay during the evaluation. */
2591 static Lisp_Object
2592 safe__call (bool inhibit_quit, ptrdiff_t nargs, Lisp_Object func, va_list ap)
2594 Lisp_Object val;
2596 if (inhibit_eval_during_redisplay)
2597 val = Qnil;
2598 else
2600 ptrdiff_t i;
2601 ptrdiff_t count = SPECPDL_INDEX ();
2602 Lisp_Object *args;
2603 USE_SAFE_ALLOCA;
2604 SAFE_ALLOCA_LISP (args, nargs);
2606 args[0] = func;
2607 for (i = 1; i < nargs; i++)
2608 args[i] = va_arg (ap, Lisp_Object);
2610 specbind (Qinhibit_redisplay, Qt);
2611 if (inhibit_quit)
2612 specbind (Qinhibit_quit, Qt);
2613 /* Use Qt to ensure debugger does not run,
2614 so there is no possibility of wanting to redisplay. */
2615 val = internal_condition_case_n (Ffuncall, nargs, args, Qt,
2616 safe_eval_handler);
2617 SAFE_FREE ();
2618 val = unbind_to (count, val);
2621 return val;
2624 Lisp_Object
2625 safe_call (ptrdiff_t nargs, Lisp_Object func, ...)
2627 Lisp_Object retval;
2628 va_list ap;
2630 va_start (ap, func);
2631 retval = safe__call (false, nargs, func, ap);
2632 va_end (ap);
2633 return retval;
2636 /* Call function FN with one argument ARG.
2637 Return the result, or nil if something went wrong. */
2639 Lisp_Object
2640 safe_call1 (Lisp_Object fn, Lisp_Object arg)
2642 return safe_call (2, fn, arg);
2645 static Lisp_Object
2646 safe__call1 (bool inhibit_quit, Lisp_Object fn, ...)
2648 Lisp_Object retval;
2649 va_list ap;
2651 va_start (ap, fn);
2652 retval = safe__call (inhibit_quit, 2, fn, ap);
2653 va_end (ap);
2654 return retval;
2657 Lisp_Object
2658 safe_eval (Lisp_Object sexpr)
2660 return safe__call1 (false, Qeval, sexpr);
2663 static Lisp_Object
2664 safe__eval (bool inhibit_quit, Lisp_Object sexpr)
2666 return safe__call1 (inhibit_quit, Qeval, sexpr);
2669 /* Call function FN with two arguments ARG1 and ARG2.
2670 Return the result, or nil if something went wrong. */
2672 Lisp_Object
2673 safe_call2 (Lisp_Object fn, Lisp_Object arg1, Lisp_Object arg2)
2675 return safe_call (3, fn, arg1, arg2);
2680 /***********************************************************************
2681 Debugging
2682 ***********************************************************************/
2684 /* Define CHECK_IT to perform sanity checks on iterators.
2685 This is for debugging. It is too slow to do unconditionally. */
2687 static void
2688 CHECK_IT (struct it *it)
2690 #if false
2691 if (it->method == GET_FROM_STRING)
2693 eassert (STRINGP (it->string));
2694 eassert (IT_STRING_CHARPOS (*it) >= 0);
2696 else
2698 eassert (IT_STRING_CHARPOS (*it) < 0);
2699 if (it->method == GET_FROM_BUFFER)
2701 /* Check that character and byte positions agree. */
2702 eassert (IT_CHARPOS (*it) == BYTE_TO_CHAR (IT_BYTEPOS (*it)));
2706 if (it->dpvec)
2707 eassert (it->current.dpvec_index >= 0);
2708 else
2709 eassert (it->current.dpvec_index < 0);
2710 #endif
2714 /* Check that the window end of window W is what we expect it
2715 to be---the last row in the current matrix displaying text. */
2717 static void
2718 CHECK_WINDOW_END (struct window *w)
2720 #if defined GLYPH_DEBUG && defined ENABLE_CHECKING
2721 if (!MINI_WINDOW_P (w) && w->window_end_valid)
2723 struct glyph_row *row;
2724 eassert ((row = MATRIX_ROW (w->current_matrix, w->window_end_vpos),
2725 !row->enabled_p
2726 || MATRIX_ROW_DISPLAYS_TEXT_P (row)
2727 || MATRIX_ROW_VPOS (row, w->current_matrix) == 0));
2729 #endif
2732 /***********************************************************************
2733 Iterator initialization
2734 ***********************************************************************/
2736 /* Initialize IT for displaying current_buffer in window W, starting
2737 at character position CHARPOS. CHARPOS < 0 means that no buffer
2738 position is specified which is useful when the iterator is assigned
2739 a position later. BYTEPOS is the byte position corresponding to
2740 CHARPOS.
2742 If ROW is not null, calls to produce_glyphs with IT as parameter
2743 will produce glyphs in that row.
2745 BASE_FACE_ID is the id of a base face to use. It must be one of
2746 DEFAULT_FACE_ID for normal text, MODE_LINE_FACE_ID,
2747 MODE_LINE_INACTIVE_FACE_ID, or HEADER_LINE_FACE_ID for displaying
2748 mode lines, or TOOL_BAR_FACE_ID for displaying the tool-bar.
2750 If ROW is null and BASE_FACE_ID is equal to MODE_LINE_FACE_ID,
2751 MODE_LINE_INACTIVE_FACE_ID, or HEADER_LINE_FACE_ID, the iterator
2752 will be initialized to use the corresponding mode line glyph row of
2753 the desired matrix of W. */
2755 void
2756 init_iterator (struct it *it, struct window *w,
2757 ptrdiff_t charpos, ptrdiff_t bytepos,
2758 struct glyph_row *row, enum face_id base_face_id)
2760 enum face_id remapped_base_face_id = base_face_id;
2762 /* Some precondition checks. */
2763 eassert (w != NULL && it != NULL);
2764 eassert (charpos < 0 || (charpos >= BUF_BEG (current_buffer)
2765 && charpos <= ZV));
2767 /* If face attributes have been changed since the last redisplay,
2768 free realized faces now because they depend on face definitions
2769 that might have changed. Don't free faces while there might be
2770 desired matrices pending which reference these faces. */
2771 if (!inhibit_free_realized_faces)
2773 if (face_change)
2775 face_change = false;
2776 XFRAME (w->frame)->face_change = 0;
2777 free_all_realized_faces (Qnil);
2779 else if (XFRAME (w->frame)->face_change)
2781 XFRAME (w->frame)->face_change = 0;
2782 free_all_realized_faces (w->frame);
2786 /* Perhaps remap BASE_FACE_ID to a user-specified alternative. */
2787 if (! NILP (Vface_remapping_alist))
2788 remapped_base_face_id
2789 = lookup_basic_face (XFRAME (w->frame), base_face_id);
2791 /* Use one of the mode line rows of W's desired matrix if
2792 appropriate. */
2793 if (row == NULL)
2795 if (base_face_id == MODE_LINE_FACE_ID
2796 || base_face_id == MODE_LINE_INACTIVE_FACE_ID)
2797 row = MATRIX_MODE_LINE_ROW (w->desired_matrix);
2798 else if (base_face_id == HEADER_LINE_FACE_ID)
2799 row = MATRIX_HEADER_LINE_ROW (w->desired_matrix);
2802 /* Clear IT, and set it->object and other IT's Lisp objects to Qnil.
2803 Other parts of redisplay rely on that. */
2804 memclear (it, sizeof *it);
2805 it->current.overlay_string_index = -1;
2806 it->current.dpvec_index = -1;
2807 it->base_face_id = remapped_base_face_id;
2808 IT_STRING_CHARPOS (*it) = IT_STRING_BYTEPOS (*it) = -1;
2809 it->paragraph_embedding = L2R;
2810 it->bidi_it.w = w;
2812 /* The window in which we iterate over current_buffer: */
2813 XSETWINDOW (it->window, w);
2814 it->w = w;
2815 it->f = XFRAME (w->frame);
2817 it->cmp_it.id = -1;
2819 /* Extra space between lines (on window systems only). */
2820 if (base_face_id == DEFAULT_FACE_ID
2821 && FRAME_WINDOW_P (it->f))
2823 if (NATNUMP (BVAR (current_buffer, extra_line_spacing)))
2824 it->extra_line_spacing = XFASTINT (BVAR (current_buffer, extra_line_spacing));
2825 else if (FLOATP (BVAR (current_buffer, extra_line_spacing)))
2826 it->extra_line_spacing = (XFLOAT_DATA (BVAR (current_buffer, extra_line_spacing))
2827 * FRAME_LINE_HEIGHT (it->f));
2828 else if (it->f->extra_line_spacing > 0)
2829 it->extra_line_spacing = it->f->extra_line_spacing;
2832 /* If realized faces have been removed, e.g. because of face
2833 attribute changes of named faces, recompute them. When running
2834 in batch mode, the face cache of the initial frame is null. If
2835 we happen to get called, make a dummy face cache. */
2836 if (FRAME_FACE_CACHE (it->f) == NULL)
2837 init_frame_faces (it->f);
2838 if (FRAME_FACE_CACHE (it->f)->used == 0)
2839 recompute_basic_faces (it->f);
2841 it->override_ascent = -1;
2843 /* Are control characters displayed as `^C'? */
2844 it->ctl_arrow_p = !NILP (BVAR (current_buffer, ctl_arrow));
2846 /* -1 means everything between a CR and the following line end
2847 is invisible. >0 means lines indented more than this value are
2848 invisible. */
2849 it->selective = (INTEGERP (BVAR (current_buffer, selective_display))
2850 ? (clip_to_bounds
2851 (-1, XINT (BVAR (current_buffer, selective_display)),
2852 PTRDIFF_MAX))
2853 : (!NILP (BVAR (current_buffer, selective_display))
2854 ? -1 : 0));
2855 it->selective_display_ellipsis_p
2856 = !NILP (BVAR (current_buffer, selective_display_ellipses));
2858 /* Display table to use. */
2859 it->dp = window_display_table (w);
2861 /* Are multibyte characters enabled in current_buffer? */
2862 it->multibyte_p = !NILP (BVAR (current_buffer, enable_multibyte_characters));
2864 /* Get the position at which the redisplay_end_trigger hook should
2865 be run, if it is to be run at all. */
2866 if (MARKERP (w->redisplay_end_trigger)
2867 && XMARKER (w->redisplay_end_trigger)->buffer != 0)
2868 it->redisplay_end_trigger_charpos
2869 = marker_position (w->redisplay_end_trigger);
2870 else if (INTEGERP (w->redisplay_end_trigger))
2871 it->redisplay_end_trigger_charpos
2872 = clip_to_bounds (PTRDIFF_MIN, XINT (w->redisplay_end_trigger),
2873 PTRDIFF_MAX);
2875 it->tab_width = SANE_TAB_WIDTH (current_buffer);
2877 /* Are lines in the display truncated? */
2878 if (TRUNCATE != 0)
2879 it->line_wrap = TRUNCATE;
2880 if (base_face_id == DEFAULT_FACE_ID
2881 && !it->w->hscroll
2882 && (WINDOW_FULL_WIDTH_P (it->w)
2883 || NILP (Vtruncate_partial_width_windows)
2884 || (INTEGERP (Vtruncate_partial_width_windows)
2885 /* PXW: Shall we do something about this? */
2886 && (XINT (Vtruncate_partial_width_windows)
2887 <= WINDOW_TOTAL_COLS (it->w))))
2888 && NILP (BVAR (current_buffer, truncate_lines)))
2889 it->line_wrap = NILP (BVAR (current_buffer, word_wrap))
2890 ? WINDOW_WRAP : WORD_WRAP;
2892 /* Get dimensions of truncation and continuation glyphs. These are
2893 displayed as fringe bitmaps under X, but we need them for such
2894 frames when the fringes are turned off. The no_special_glyphs slot
2895 of the iterator's frame, when set, suppresses their display - by
2896 default for tooltip frames and when set via the 'no-special-glyphs'
2897 frame parameter. */
2898 #ifdef HAVE_WINDOW_SYSTEM
2899 if (!(FRAME_WINDOW_P (it->f) && it->f->no_special_glyphs))
2900 #endif
2902 if (it->line_wrap == TRUNCATE)
2904 /* We will need the truncation glyph. */
2905 eassert (it->glyph_row == NULL);
2906 produce_special_glyphs (it, IT_TRUNCATION);
2907 it->truncation_pixel_width = it->pixel_width;
2909 else
2911 /* We will need the continuation glyph. */
2912 eassert (it->glyph_row == NULL);
2913 produce_special_glyphs (it, IT_CONTINUATION);
2914 it->continuation_pixel_width = it->pixel_width;
2918 /* Reset these values to zero because the produce_special_glyphs
2919 above has changed them. */
2920 it->pixel_width = it->ascent = it->descent = 0;
2921 it->phys_ascent = it->phys_descent = 0;
2923 /* Set this after getting the dimensions of truncation and
2924 continuation glyphs, so that we don't produce glyphs when calling
2925 produce_special_glyphs, above. */
2926 it->glyph_row = row;
2927 it->area = TEXT_AREA;
2929 /* Get the dimensions of the display area. The display area
2930 consists of the visible window area plus a horizontally scrolled
2931 part to the left of the window. All x-values are relative to the
2932 start of this total display area. */
2933 if (base_face_id != DEFAULT_FACE_ID)
2935 /* Mode lines, menu bar in terminal frames. */
2936 it->first_visible_x = 0;
2937 it->last_visible_x = WINDOW_PIXEL_WIDTH (w);
2939 else
2941 /* When hscrolling only the current line, don't apply the
2942 hscroll here, it will be applied by display_line when it gets
2943 to laying out the line showing point. However, if the
2944 window's min_hscroll is positive, the user specified a lower
2945 bound for automatic hscrolling, so they expect the
2946 non-current lines to obey that hscroll amount. */
2947 if (hscrolling_current_line_p (w))
2949 if (w->min_hscroll > 0)
2950 it->first_visible_x = w->min_hscroll * FRAME_COLUMN_WIDTH (it->f);
2951 else
2952 it->first_visible_x = 0;
2954 else
2955 it->first_visible_x =
2956 window_hscroll_limited (w, it->f) * FRAME_COLUMN_WIDTH (it->f);
2957 it->last_visible_x = (it->first_visible_x
2958 + window_box_width (w, TEXT_AREA));
2960 /* If we truncate lines, leave room for the truncation glyph(s) at
2961 the right margin. Otherwise, leave room for the continuation
2962 glyph(s). Done only if the window has no right fringe. */
2963 if (WINDOW_RIGHT_FRINGE_WIDTH (it->w) == 0)
2965 if (it->line_wrap == TRUNCATE)
2966 it->last_visible_x -= it->truncation_pixel_width;
2967 else
2968 it->last_visible_x -= it->continuation_pixel_width;
2971 it->header_line_p = window_wants_header_line (w);
2972 it->current_y = WINDOW_HEADER_LINE_HEIGHT (w) + w->vscroll;
2975 /* Leave room for a border glyph. */
2976 if (!FRAME_WINDOW_P (it->f)
2977 && !WINDOW_RIGHTMOST_P (it->w))
2978 it->last_visible_x -= 1;
2980 it->last_visible_y = window_text_bottom_y (w);
2982 /* For mode lines and alike, arrange for the first glyph having a
2983 left box line if the face specifies a box. */
2984 if (base_face_id != DEFAULT_FACE_ID)
2986 struct face *face;
2988 it->face_id = remapped_base_face_id;
2990 /* If we have a boxed mode line, make the first character appear
2991 with a left box line. */
2992 face = FACE_FROM_ID_OR_NULL (it->f, remapped_base_face_id);
2993 if (face && face->box != FACE_NO_BOX)
2994 it->start_of_box_run_p = true;
2997 /* If a buffer position was specified, set the iterator there,
2998 getting overlays and face properties from that position. */
2999 if (charpos >= BUF_BEG (current_buffer))
3001 it->stop_charpos = charpos;
3002 it->end_charpos = ZV;
3003 eassert (charpos == BYTE_TO_CHAR (bytepos));
3004 IT_CHARPOS (*it) = charpos;
3005 IT_BYTEPOS (*it) = bytepos;
3007 /* We will rely on `reseat' to set this up properly, via
3008 handle_face_prop. */
3009 it->face_id = it->base_face_id;
3011 it->start = it->current;
3012 /* Do we need to reorder bidirectional text? Not if this is a
3013 unibyte buffer: by definition, none of the single-byte
3014 characters are strong R2L, so no reordering is needed. And
3015 bidi.c doesn't support unibyte buffers anyway. Also, don't
3016 reorder while we are loading loadup.el, since the tables of
3017 character properties needed for reordering are not yet
3018 available. */
3019 it->bidi_p =
3020 !redisplay__inhibit_bidi
3021 && !NILP (BVAR (current_buffer, bidi_display_reordering))
3022 && it->multibyte_p;
3024 /* If we are to reorder bidirectional text, init the bidi
3025 iterator. */
3026 if (it->bidi_p)
3028 /* Since we don't know at this point whether there will be
3029 any R2L lines in the window, we reserve space for
3030 truncation/continuation glyphs even if only the left
3031 fringe is absent. */
3032 if (base_face_id == DEFAULT_FACE_ID
3033 && WINDOW_LEFT_FRINGE_WIDTH (it->w) == 0
3034 && WINDOW_RIGHT_FRINGE_WIDTH (it->w) != 0)
3036 if (it->line_wrap == TRUNCATE)
3037 it->last_visible_x -= it->truncation_pixel_width;
3038 else
3039 it->last_visible_x -= it->continuation_pixel_width;
3041 /* Note the paragraph direction that this buffer wants to
3042 use. */
3043 if (EQ (BVAR (current_buffer, bidi_paragraph_direction),
3044 Qleft_to_right))
3045 it->paragraph_embedding = L2R;
3046 else if (EQ (BVAR (current_buffer, bidi_paragraph_direction),
3047 Qright_to_left))
3048 it->paragraph_embedding = R2L;
3049 else
3050 it->paragraph_embedding = NEUTRAL_DIR;
3051 bidi_unshelve_cache (NULL, false);
3052 bidi_init_it (charpos, IT_BYTEPOS (*it), FRAME_WINDOW_P (it->f),
3053 &it->bidi_it);
3056 /* Compute faces etc. */
3057 reseat (it, it->current.pos, true);
3060 CHECK_IT (it);
3064 /* Initialize IT for the display of window W with window start POS. */
3066 void
3067 start_display (struct it *it, struct window *w, struct text_pos pos)
3069 struct glyph_row *row;
3070 bool first_vpos = window_wants_header_line (w);
3072 row = w->desired_matrix->rows + first_vpos;
3073 init_iterator (it, w, CHARPOS (pos), BYTEPOS (pos), row, DEFAULT_FACE_ID);
3074 it->first_vpos = first_vpos;
3076 /* Don't reseat to previous visible line start if current start
3077 position is in a string or image. */
3078 if (it->method == GET_FROM_BUFFER && it->line_wrap != TRUNCATE)
3080 int first_y = it->current_y;
3082 /* If window start is not at a line start, skip forward to POS to
3083 get the correct continuation lines width. */
3084 bool start_at_line_beg_p = (CHARPOS (pos) == BEGV
3085 || FETCH_BYTE (BYTEPOS (pos) - 1) == '\n');
3086 if (!start_at_line_beg_p)
3088 int new_x;
3090 reseat_at_previous_visible_line_start (it);
3091 move_it_to (it, CHARPOS (pos), -1, -1, -1, MOVE_TO_POS);
3093 new_x = it->current_x + it->pixel_width;
3095 /* If lines are continued, this line may end in the middle
3096 of a multi-glyph character (e.g. a control character
3097 displayed as \003, or in the middle of an overlay
3098 string). In this case move_it_to above will not have
3099 taken us to the start of the continuation line but to the
3100 end of the continued line. */
3101 if (it->current_x > 0
3102 && it->line_wrap != TRUNCATE /* Lines are continued. */
3103 && (/* And glyph doesn't fit on the line. */
3104 new_x > it->last_visible_x
3105 /* Or it fits exactly and we're on a window
3106 system frame. */
3107 || (new_x == it->last_visible_x
3108 && FRAME_WINDOW_P (it->f)
3109 && ((it->bidi_p && it->bidi_it.paragraph_dir == R2L)
3110 ? WINDOW_LEFT_FRINGE_WIDTH (it->w)
3111 : WINDOW_RIGHT_FRINGE_WIDTH (it->w)))))
3113 if ((it->current.dpvec_index >= 0
3114 || it->current.overlay_string_index >= 0)
3115 /* If we are on a newline from a display vector or
3116 overlay string, then we are already at the end of
3117 a screen line; no need to go to the next line in
3118 that case, as this line is not really continued.
3119 (If we do go to the next line, C-e will not DTRT.) */
3120 && it->c != '\n')
3122 set_iterator_to_next (it, true);
3123 move_it_in_display_line_to (it, -1, -1, 0);
3126 it->continuation_lines_width += it->current_x;
3128 /* If the character at POS is displayed via a display
3129 vector, move_it_to above stops at the final glyph of
3130 IT->dpvec. To make the caller redisplay that character
3131 again (a.k.a. start at POS), we need to reset the
3132 dpvec_index to the beginning of IT->dpvec. */
3133 else if (it->current.dpvec_index >= 0)
3134 it->current.dpvec_index = 0;
3136 /* We're starting a new display line, not affected by the
3137 height of the continued line, so clear the appropriate
3138 fields in the iterator structure. */
3139 it->max_ascent = it->max_descent = 0;
3140 it->max_phys_ascent = it->max_phys_descent = 0;
3142 it->current_y = first_y;
3143 it->vpos = 0;
3144 it->current_x = it->hpos = 0;
3150 /* Return true if POS is a position in ellipses displayed for invisible
3151 text. W is the window we display, for text property lookup. */
3153 static bool
3154 in_ellipses_for_invisible_text_p (struct display_pos *pos, struct window *w)
3156 Lisp_Object prop, window;
3157 bool ellipses_p = false;
3158 ptrdiff_t charpos = CHARPOS (pos->pos);
3160 /* If POS specifies a position in a display vector, this might
3161 be for an ellipsis displayed for invisible text. We won't
3162 get the iterator set up for delivering that ellipsis unless
3163 we make sure that it gets aware of the invisible text. */
3164 if (pos->dpvec_index >= 0
3165 && pos->overlay_string_index < 0
3166 && CHARPOS (pos->string_pos) < 0
3167 && charpos > BEGV
3168 && (XSETWINDOW (window, w),
3169 prop = Fget_char_property (make_number (charpos),
3170 Qinvisible, window),
3171 TEXT_PROP_MEANS_INVISIBLE (prop) == 0))
3173 prop = Fget_char_property (make_number (charpos - 1), Qinvisible,
3174 window);
3175 ellipses_p = 2 == TEXT_PROP_MEANS_INVISIBLE (prop);
3178 return ellipses_p;
3182 /* Initialize IT for stepping through current_buffer in window W,
3183 starting at position POS that includes overlay string and display
3184 vector/ control character translation position information. Value
3185 is false if there are overlay strings with newlines at POS. */
3187 static bool
3188 init_from_display_pos (struct it *it, struct window *w, struct display_pos *pos)
3190 ptrdiff_t charpos = CHARPOS (pos->pos), bytepos = BYTEPOS (pos->pos);
3191 int i;
3192 bool overlay_strings_with_newlines = false;
3194 /* If POS specifies a position in a display vector, this might
3195 be for an ellipsis displayed for invisible text. We won't
3196 get the iterator set up for delivering that ellipsis unless
3197 we make sure that it gets aware of the invisible text. */
3198 if (in_ellipses_for_invisible_text_p (pos, w))
3200 --charpos;
3201 bytepos = 0;
3204 /* Keep in mind: the call to reseat in init_iterator skips invisible
3205 text, so we might end up at a position different from POS. This
3206 is only a problem when POS is a row start after a newline and an
3207 overlay starts there with an after-string, and the overlay has an
3208 invisible property. Since we don't skip invisible text in
3209 display_line and elsewhere immediately after consuming the
3210 newline before the row start, such a POS will not be in a string,
3211 but the call to init_iterator below will move us to the
3212 after-string. */
3213 init_iterator (it, w, charpos, bytepos, NULL, DEFAULT_FACE_ID);
3215 /* This only scans the current chunk -- it should scan all chunks.
3216 However, OVERLAY_STRING_CHUNK_SIZE has been increased from 3 in 21.1
3217 to 16 in 22.1 to make this a lesser problem. */
3218 for (i = 0; i < it->n_overlay_strings && i < OVERLAY_STRING_CHUNK_SIZE; ++i)
3220 const char *s = SSDATA (it->overlay_strings[i]);
3221 const char *e = s + SBYTES (it->overlay_strings[i]);
3223 while (s < e && *s != '\n')
3224 ++s;
3226 if (s < e)
3228 overlay_strings_with_newlines = true;
3229 break;
3233 /* If position is within an overlay string, set up IT to the right
3234 overlay string. */
3235 if (pos->overlay_string_index >= 0)
3237 int relative_index;
3239 /* If the first overlay string happens to have a `display'
3240 property for an image, the iterator will be set up for that
3241 image, and we have to undo that setup first before we can
3242 correct the overlay string index. */
3243 if (it->method == GET_FROM_IMAGE)
3244 pop_it (it);
3246 /* We already have the first chunk of overlay strings in
3247 IT->overlay_strings. Load more until the one for
3248 pos->overlay_string_index is in IT->overlay_strings. */
3249 if (pos->overlay_string_index >= OVERLAY_STRING_CHUNK_SIZE)
3251 ptrdiff_t n = pos->overlay_string_index / OVERLAY_STRING_CHUNK_SIZE;
3252 it->current.overlay_string_index = 0;
3253 while (n--)
3255 load_overlay_strings (it, 0);
3256 it->current.overlay_string_index += OVERLAY_STRING_CHUNK_SIZE;
3260 it->current.overlay_string_index = pos->overlay_string_index;
3261 relative_index = (it->current.overlay_string_index
3262 % OVERLAY_STRING_CHUNK_SIZE);
3263 it->string = it->overlay_strings[relative_index];
3264 eassert (STRINGP (it->string));
3265 it->current.string_pos = pos->string_pos;
3266 it->method = GET_FROM_STRING;
3267 it->end_charpos = SCHARS (it->string);
3268 /* Set up the bidi iterator for this overlay string. */
3269 if (it->bidi_p)
3271 it->bidi_it.string.lstring = it->string;
3272 it->bidi_it.string.s = NULL;
3273 it->bidi_it.string.schars = SCHARS (it->string);
3274 it->bidi_it.string.bufpos = it->overlay_strings_charpos;
3275 it->bidi_it.string.from_disp_str = it->string_from_display_prop_p;
3276 it->bidi_it.string.unibyte = !it->multibyte_p;
3277 it->bidi_it.w = it->w;
3278 bidi_init_it (IT_STRING_CHARPOS (*it), IT_STRING_BYTEPOS (*it),
3279 FRAME_WINDOW_P (it->f), &it->bidi_it);
3281 /* Synchronize the state of the bidi iterator with
3282 pos->string_pos. For any string position other than
3283 zero, this will be done automagically when we resume
3284 iteration over the string and get_visually_first_element
3285 is called. But if string_pos is zero, and the string is
3286 to be reordered for display, we need to resync manually,
3287 since it could be that the iteration state recorded in
3288 pos ended at string_pos of 0 moving backwards in string. */
3289 if (CHARPOS (pos->string_pos) == 0)
3291 get_visually_first_element (it);
3292 if (IT_STRING_CHARPOS (*it) != 0)
3293 do {
3294 /* Paranoia. */
3295 eassert (it->bidi_it.charpos < it->bidi_it.string.schars);
3296 bidi_move_to_visually_next (&it->bidi_it);
3297 } while (it->bidi_it.charpos != 0);
3299 eassert (IT_STRING_CHARPOS (*it) == it->bidi_it.charpos
3300 && IT_STRING_BYTEPOS (*it) == it->bidi_it.bytepos);
3304 if (CHARPOS (pos->string_pos) >= 0)
3306 /* Recorded position is not in an overlay string, but in another
3307 string. This can only be a string from a `display' property.
3308 IT should already be filled with that string. */
3309 it->current.string_pos = pos->string_pos;
3310 eassert (STRINGP (it->string));
3311 if (it->bidi_p)
3312 bidi_init_it (IT_STRING_CHARPOS (*it), IT_STRING_BYTEPOS (*it),
3313 FRAME_WINDOW_P (it->f), &it->bidi_it);
3316 /* Restore position in display vector translations, control
3317 character translations or ellipses. */
3318 if (pos->dpvec_index >= 0)
3320 if (it->dpvec == NULL)
3321 get_next_display_element (it);
3322 eassert (it->dpvec && it->current.dpvec_index == 0);
3323 it->current.dpvec_index = pos->dpvec_index;
3326 CHECK_IT (it);
3327 return !overlay_strings_with_newlines;
3331 /* Initialize IT for stepping through current_buffer in window W
3332 starting at ROW->start. */
3334 static void
3335 init_to_row_start (struct it *it, struct window *w, struct glyph_row *row)
3337 init_from_display_pos (it, w, &row->start);
3338 it->start = row->start;
3339 it->continuation_lines_width = row->continuation_lines_width;
3340 CHECK_IT (it);
3344 /* Initialize IT for stepping through current_buffer in window W
3345 starting in the line following ROW, i.e. starting at ROW->end.
3346 Value is false if there are overlay strings with newlines at ROW's
3347 end position. */
3349 static bool
3350 init_to_row_end (struct it *it, struct window *w, struct glyph_row *row)
3352 bool success = false;
3354 if (init_from_display_pos (it, w, &row->end))
3356 if (row->continued_p)
3357 it->continuation_lines_width
3358 = row->continuation_lines_width + row->pixel_width;
3359 CHECK_IT (it);
3360 success = true;
3363 return success;
3369 /***********************************************************************
3370 Text properties
3371 ***********************************************************************/
3373 /* Called when IT reaches IT->stop_charpos. Handle text property and
3374 overlay changes. Set IT->stop_charpos to the next position where
3375 to stop. */
3377 static void
3378 handle_stop (struct it *it)
3380 enum prop_handled handled;
3381 bool handle_overlay_change_p;
3382 struct props *p;
3384 it->dpvec = NULL;
3385 it->current.dpvec_index = -1;
3386 handle_overlay_change_p = !it->ignore_overlay_strings_at_pos_p;
3387 it->ellipsis_p = false;
3389 /* Use face of preceding text for ellipsis (if invisible) */
3390 if (it->selective_display_ellipsis_p)
3391 it->saved_face_id = it->face_id;
3393 /* Here's the description of the semantics of, and the logic behind,
3394 the various HANDLED_* statuses:
3396 HANDLED_NORMALLY means the handler did its job, and the loop
3397 should proceed to calling the next handler in order.
3399 HANDLED_RECOMPUTE_PROPS means the handler caused a significant
3400 change in the properties and overlays at current position, so the
3401 loop should be restarted, to re-invoke the handlers that were
3402 already called. This happens when fontification-functions were
3403 called by handle_fontified_prop, and actually fontified
3404 something. Another case where HANDLED_RECOMPUTE_PROPS is
3405 returned is when we discover overlay strings that need to be
3406 displayed right away. The loop below will continue for as long
3407 as the status is HANDLED_RECOMPUTE_PROPS.
3409 HANDLED_RETURN means return immediately to the caller, to
3410 continue iteration without calling any further handlers. This is
3411 used when we need to act on some property right away, for example
3412 when we need to display the ellipsis or a replacing display
3413 property, such as display string or image.
3415 HANDLED_OVERLAY_STRING_CONSUMED means an overlay string was just
3416 consumed, and the handler switched to the next overlay string.
3417 This signals the loop below to refrain from looking for more
3418 overlays before all the overlay strings of the current overlay
3419 are processed.
3421 Some of the handlers called by the loop push the iterator state
3422 onto the stack (see 'push_it'), and arrange for the iteration to
3423 continue with another object, such as an image, a display string,
3424 or an overlay string. In most such cases, it->stop_charpos is
3425 set to the first character of the string, so that when the
3426 iteration resumes, this function will immediately be called
3427 again, to examine the properties at the beginning of the string.
3429 When a display or overlay string is exhausted, the iterator state
3430 is popped (see 'pop_it'), and iteration continues with the
3431 previous object. Again, in many such cases this function is
3432 called again to find the next position where properties might
3433 change. */
3437 handled = HANDLED_NORMALLY;
3439 /* Call text property handlers. */
3440 for (p = it_props; p->handler; ++p)
3442 handled = p->handler (it);
3444 if (handled == HANDLED_RECOMPUTE_PROPS)
3445 break;
3446 else if (handled == HANDLED_RETURN)
3448 /* We still want to show before and after strings from
3449 overlays even if the actual buffer text is replaced. */
3450 if (!handle_overlay_change_p
3451 || it->sp > 1
3452 /* Don't call get_overlay_strings_1 if we already
3453 have overlay strings loaded, because doing so
3454 will load them again and push the iterator state
3455 onto the stack one more time, which is not
3456 expected by the rest of the code that processes
3457 overlay strings. */
3458 || (it->current.overlay_string_index < 0
3459 && !get_overlay_strings_1 (it, 0, false)))
3461 if (it->ellipsis_p)
3462 setup_for_ellipsis (it, 0);
3463 /* When handling a display spec, we might load an
3464 empty string. In that case, discard it here. We
3465 used to discard it in handle_single_display_spec,
3466 but that causes get_overlay_strings_1, above, to
3467 ignore overlay strings that we must check. */
3468 if (STRINGP (it->string) && !SCHARS (it->string))
3469 pop_it (it);
3470 return;
3472 else if (STRINGP (it->string) && !SCHARS (it->string))
3473 pop_it (it);
3474 else
3476 it->string_from_display_prop_p = false;
3477 it->from_disp_prop_p = false;
3478 handle_overlay_change_p = false;
3480 handled = HANDLED_RECOMPUTE_PROPS;
3481 break;
3483 else if (handled == HANDLED_OVERLAY_STRING_CONSUMED)
3484 handle_overlay_change_p = false;
3487 if (handled != HANDLED_RECOMPUTE_PROPS)
3489 /* Don't check for overlay strings below when set to deliver
3490 characters from a display vector. */
3491 if (it->method == GET_FROM_DISPLAY_VECTOR)
3492 handle_overlay_change_p = false;
3494 /* Handle overlay changes.
3495 This sets HANDLED to HANDLED_RECOMPUTE_PROPS
3496 if it finds overlays. */
3497 if (handle_overlay_change_p)
3498 handled = handle_overlay_change (it);
3501 if (it->ellipsis_p)
3503 setup_for_ellipsis (it, 0);
3504 break;
3507 while (handled == HANDLED_RECOMPUTE_PROPS);
3509 /* Determine where to stop next. */
3510 if (handled == HANDLED_NORMALLY)
3511 compute_stop_pos (it);
3515 /* Compute IT->stop_charpos from text property and overlay change
3516 information for IT's current position. */
3518 static void
3519 compute_stop_pos (struct it *it)
3521 register INTERVAL iv, next_iv;
3522 Lisp_Object object, limit, position;
3523 ptrdiff_t charpos, bytepos;
3525 if (STRINGP (it->string))
3527 /* Strings are usually short, so don't limit the search for
3528 properties. */
3529 it->stop_charpos = it->end_charpos;
3530 object = it->string;
3531 limit = Qnil;
3532 charpos = IT_STRING_CHARPOS (*it);
3533 bytepos = IT_STRING_BYTEPOS (*it);
3535 else
3537 ptrdiff_t pos;
3539 /* If end_charpos is out of range for some reason, such as a
3540 misbehaving display function, rationalize it (Bug#5984). */
3541 if (it->end_charpos > ZV)
3542 it->end_charpos = ZV;
3543 it->stop_charpos = it->end_charpos;
3545 /* If next overlay change is in front of the current stop pos
3546 (which is IT->end_charpos), stop there. Note: value of
3547 next_overlay_change is point-max if no overlay change
3548 follows. */
3549 charpos = IT_CHARPOS (*it);
3550 bytepos = IT_BYTEPOS (*it);
3551 pos = next_overlay_change (charpos);
3552 if (pos < it->stop_charpos)
3553 it->stop_charpos = pos;
3555 /* Set up variables for computing the stop position from text
3556 property changes. */
3557 XSETBUFFER (object, current_buffer);
3558 limit = make_number (IT_CHARPOS (*it) + TEXT_PROP_DISTANCE_LIMIT);
3561 /* Get the interval containing IT's position. Value is a null
3562 interval if there isn't such an interval. */
3563 position = make_number (charpos);
3564 iv = validate_interval_range (object, &position, &position, false);
3565 if (iv)
3567 Lisp_Object values_here[LAST_PROP_IDX];
3568 struct props *p;
3570 /* Get properties here. */
3571 for (p = it_props; p->handler; ++p)
3572 values_here[p->idx] = textget (iv->plist,
3573 builtin_lisp_symbol (p->name));
3575 /* Look for an interval following iv that has different
3576 properties. */
3577 for (next_iv = next_interval (iv);
3578 (next_iv
3579 && (NILP (limit)
3580 || XFASTINT (limit) > next_iv->position));
3581 next_iv = next_interval (next_iv))
3583 for (p = it_props; p->handler; ++p)
3585 Lisp_Object new_value = textget (next_iv->plist,
3586 builtin_lisp_symbol (p->name));
3587 if (!EQ (values_here[p->idx], new_value))
3588 break;
3591 if (p->handler)
3592 break;
3595 if (next_iv)
3597 if (INTEGERP (limit)
3598 && next_iv->position >= XFASTINT (limit))
3599 /* No text property change up to limit. */
3600 it->stop_charpos = min (XFASTINT (limit), it->stop_charpos);
3601 else
3602 /* Text properties change in next_iv. */
3603 it->stop_charpos = min (it->stop_charpos, next_iv->position);
3607 if (it->cmp_it.id < 0)
3609 ptrdiff_t stoppos = it->end_charpos;
3611 if (it->bidi_p && it->bidi_it.scan_dir < 0)
3612 stoppos = -1;
3613 composition_compute_stop_pos (&it->cmp_it, charpos, bytepos,
3614 stoppos, it->string);
3617 eassert (STRINGP (it->string)
3618 || (it->stop_charpos >= BEGV
3619 && it->stop_charpos >= IT_CHARPOS (*it)));
3623 /* Return the position of the next overlay change after POS in
3624 current_buffer. Value is point-max if no overlay change
3625 follows. This is like `next-overlay-change' but doesn't use
3626 xmalloc. */
3628 static ptrdiff_t
3629 next_overlay_change (ptrdiff_t pos)
3631 ptrdiff_t i, noverlays;
3632 ptrdiff_t endpos;
3633 Lisp_Object *overlays;
3634 USE_SAFE_ALLOCA;
3636 /* Get all overlays at the given position. */
3637 GET_OVERLAYS_AT (pos, overlays, noverlays, &endpos, true);
3639 /* If any of these overlays ends before endpos,
3640 use its ending point instead. */
3641 for (i = 0; i < noverlays; ++i)
3643 Lisp_Object oend;
3644 ptrdiff_t oendpos;
3646 oend = OVERLAY_END (overlays[i]);
3647 oendpos = OVERLAY_POSITION (oend);
3648 endpos = min (endpos, oendpos);
3651 SAFE_FREE ();
3652 return endpos;
3655 /* How many characters forward to search for a display property or
3656 display string. Searching too far forward makes the bidi display
3657 sluggish, especially in small windows. */
3658 #define MAX_DISP_SCAN 250
3660 /* Return the character position of a display string at or after
3661 position specified by POSITION. If no display string exists at or
3662 after POSITION, return ZV. A display string is either an overlay
3663 with `display' property whose value is a string, or a `display'
3664 text property whose value is a string. STRING is data about the
3665 string to iterate; if STRING->lstring is nil, we are iterating a
3666 buffer. FRAME_WINDOW_P is true when we are displaying a window
3667 on a GUI frame. DISP_PROP is set to zero if we searched
3668 MAX_DISP_SCAN characters forward without finding any display
3669 strings, non-zero otherwise. It is set to 2 if the display string
3670 uses any kind of `(space ...)' spec that will produce a stretch of
3671 white space in the text area. */
3672 ptrdiff_t
3673 compute_display_string_pos (struct text_pos *position,
3674 struct bidi_string_data *string,
3675 struct window *w,
3676 bool frame_window_p, int *disp_prop)
3678 /* OBJECT = nil means current buffer. */
3679 Lisp_Object object, object1;
3680 Lisp_Object pos, spec, limpos;
3681 bool string_p = string && (STRINGP (string->lstring) || string->s);
3682 ptrdiff_t eob = string_p ? string->schars : ZV;
3683 ptrdiff_t begb = string_p ? 0 : BEGV;
3684 ptrdiff_t bufpos, charpos = CHARPOS (*position);
3685 ptrdiff_t lim =
3686 (charpos < eob - MAX_DISP_SCAN) ? charpos + MAX_DISP_SCAN : eob;
3687 struct text_pos tpos;
3688 int rv = 0;
3690 if (string && STRINGP (string->lstring))
3691 object1 = object = string->lstring;
3692 else if (w && !string_p)
3694 XSETWINDOW (object, w);
3695 object1 = Qnil;
3697 else
3698 object1 = object = Qnil;
3700 *disp_prop = 1;
3702 if (charpos >= eob
3703 /* We don't support display properties whose values are strings
3704 that have display string properties. */
3705 || string->from_disp_str
3706 /* C strings cannot have display properties. */
3707 || (string->s && !STRINGP (object)))
3709 *disp_prop = 0;
3710 return eob;
3713 /* If the character at CHARPOS is where the display string begins,
3714 return CHARPOS. */
3715 pos = make_number (charpos);
3716 if (STRINGP (object))
3717 bufpos = string->bufpos;
3718 else
3719 bufpos = charpos;
3720 tpos = *position;
3721 if (!NILP (spec = Fget_char_property (pos, Qdisplay, object))
3722 && (charpos <= begb
3723 || !EQ (Fget_char_property (make_number (charpos - 1), Qdisplay,
3724 object),
3725 spec))
3726 && (rv = handle_display_spec (NULL, spec, object, Qnil, &tpos, bufpos,
3727 frame_window_p)))
3729 if (rv == 2)
3730 *disp_prop = 2;
3731 return charpos;
3734 /* Look forward for the first character with a `display' property
3735 that will replace the underlying text when displayed. */
3736 limpos = make_number (lim);
3737 do {
3738 pos = Fnext_single_char_property_change (pos, Qdisplay, object1, limpos);
3739 CHARPOS (tpos) = XFASTINT (pos);
3740 if (CHARPOS (tpos) >= lim)
3742 *disp_prop = 0;
3743 break;
3745 if (STRINGP (object))
3746 BYTEPOS (tpos) = string_char_to_byte (object, CHARPOS (tpos));
3747 else
3748 BYTEPOS (tpos) = CHAR_TO_BYTE (CHARPOS (tpos));
3749 spec = Fget_char_property (pos, Qdisplay, object);
3750 if (!STRINGP (object))
3751 bufpos = CHARPOS (tpos);
3752 } while (NILP (spec)
3753 || !(rv = handle_display_spec (NULL, spec, object, Qnil, &tpos,
3754 bufpos, frame_window_p)));
3755 if (rv == 2)
3756 *disp_prop = 2;
3758 return CHARPOS (tpos);
3761 /* Return the character position of the end of the display string that
3762 started at CHARPOS. If there's no display string at CHARPOS,
3763 return -1. A display string is either an overlay with `display'
3764 property whose value is a string or a `display' text property whose
3765 value is a string. */
3766 ptrdiff_t
3767 compute_display_string_end (ptrdiff_t charpos, struct bidi_string_data *string)
3769 /* OBJECT = nil means current buffer. */
3770 Lisp_Object object =
3771 (string && STRINGP (string->lstring)) ? string->lstring : Qnil;
3772 Lisp_Object pos = make_number (charpos);
3773 ptrdiff_t eob =
3774 (STRINGP (object) || (string && string->s)) ? string->schars : ZV;
3776 if (charpos >= eob || (string->s && !STRINGP (object)))
3777 return eob;
3779 /* It could happen that the display property or overlay was removed
3780 since we found it in compute_display_string_pos above. One way
3781 this can happen is if JIT font-lock was called (through
3782 handle_fontified_prop), and jit-lock-functions remove text
3783 properties or overlays from the portion of buffer that includes
3784 CHARPOS. Muse mode is known to do that, for example. In this
3785 case, we return -1 to the caller, to signal that no display
3786 string is actually present at CHARPOS. See bidi_fetch_char for
3787 how this is handled.
3789 An alternative would be to never look for display properties past
3790 it->stop_charpos. But neither compute_display_string_pos nor
3791 bidi_fetch_char that calls it know or care where the next
3792 stop_charpos is. */
3793 if (NILP (Fget_char_property (pos, Qdisplay, object)))
3794 return -1;
3796 /* Look forward for the first character where the `display' property
3797 changes. */
3798 pos = Fnext_single_char_property_change (pos, Qdisplay, object, Qnil);
3800 return XFASTINT (pos);
3805 /***********************************************************************
3806 Fontification
3807 ***********************************************************************/
3809 /* Handle changes in the `fontified' property of the current buffer by
3810 calling hook functions from Qfontification_functions to fontify
3811 regions of text. */
3813 static enum prop_handled
3814 handle_fontified_prop (struct it *it)
3816 Lisp_Object prop, pos;
3817 enum prop_handled handled = HANDLED_NORMALLY;
3819 if (!NILP (Vmemory_full))
3820 return handled;
3822 /* Get the value of the `fontified' property at IT's current buffer
3823 position. (The `fontified' property doesn't have a special
3824 meaning in strings.) If the value is nil, call functions from
3825 Qfontification_functions. */
3826 if (!STRINGP (it->string)
3827 && it->s == NULL
3828 && !NILP (Vfontification_functions)
3829 && !NILP (Vrun_hooks)
3830 && (pos = make_number (IT_CHARPOS (*it)),
3831 prop = Fget_char_property (pos, Qfontified, Qnil),
3832 /* Ignore the special cased nil value always present at EOB since
3833 no amount of fontifying will be able to change it. */
3834 NILP (prop) && IT_CHARPOS (*it) < Z))
3836 ptrdiff_t count = SPECPDL_INDEX ();
3837 Lisp_Object val;
3838 struct buffer *obuf = current_buffer;
3839 ptrdiff_t begv = BEGV, zv = ZV;
3840 bool old_clip_changed = current_buffer->clip_changed;
3842 val = Vfontification_functions;
3843 specbind (Qfontification_functions, Qnil);
3845 eassert (it->end_charpos == ZV);
3847 if (!CONSP (val) || EQ (XCAR (val), Qlambda))
3848 safe_call1 (val, pos);
3849 else
3851 Lisp_Object fns, fn;
3853 fns = Qnil;
3855 for (; CONSP (val); val = XCDR (val))
3857 fn = XCAR (val);
3859 if (EQ (fn, Qt))
3861 /* A value of t indicates this hook has a local
3862 binding; it means to run the global binding too.
3863 In a global value, t should not occur. If it
3864 does, we must ignore it to avoid an endless
3865 loop. */
3866 for (fns = Fdefault_value (Qfontification_functions);
3867 CONSP (fns);
3868 fns = XCDR (fns))
3870 fn = XCAR (fns);
3871 if (!EQ (fn, Qt))
3872 safe_call1 (fn, pos);
3875 else
3876 safe_call1 (fn, pos);
3880 unbind_to (count, Qnil);
3882 /* Fontification functions routinely call `save-restriction'.
3883 Normally, this tags clip_changed, which can confuse redisplay
3884 (see discussion in Bug#6671). Since we don't perform any
3885 special handling of fontification changes in the case where
3886 `save-restriction' isn't called, there's no point doing so in
3887 this case either. So, if the buffer's restrictions are
3888 actually left unchanged, reset clip_changed. */
3889 if (obuf == current_buffer)
3891 if (begv == BEGV && zv == ZV)
3892 current_buffer->clip_changed = old_clip_changed;
3894 /* There isn't much we can reasonably do to protect against
3895 misbehaving fontification, but here's a fig leaf. */
3896 else if (BUFFER_LIVE_P (obuf))
3897 set_buffer_internal_1 (obuf);
3899 /* The fontification code may have added/removed text.
3900 It could do even a lot worse, but let's at least protect against
3901 the most obvious case where only the text past `pos' gets changed',
3902 as is/was done in grep.el where some escapes sequences are turned
3903 into face properties (bug#7876). */
3904 it->end_charpos = ZV;
3906 /* Return HANDLED_RECOMPUTE_PROPS only if function fontified
3907 something. This avoids an endless loop if they failed to
3908 fontify the text for which reason ever. */
3909 if (!NILP (Fget_char_property (pos, Qfontified, Qnil)))
3910 handled = HANDLED_RECOMPUTE_PROPS;
3913 return handled;
3918 /***********************************************************************
3919 Faces
3920 ***********************************************************************/
3922 /* Set up iterator IT from face properties at its current position.
3923 Called from handle_stop. */
3925 static enum prop_handled
3926 handle_face_prop (struct it *it)
3928 int new_face_id;
3929 ptrdiff_t next_stop;
3931 if (!STRINGP (it->string))
3933 new_face_id
3934 = face_at_buffer_position (it->w,
3935 IT_CHARPOS (*it),
3936 &next_stop,
3937 (IT_CHARPOS (*it)
3938 + TEXT_PROP_DISTANCE_LIMIT),
3939 false, it->base_face_id);
3941 /* Is this a start of a run of characters with box face?
3942 Caveat: this can be called for a freshly initialized
3943 iterator; face_id is -1 in this case. We know that the new
3944 face will not change until limit, i.e. if the new face has a
3945 box, all characters up to limit will have one. But, as
3946 usual, we don't know whether limit is really the end. */
3947 if (new_face_id != it->face_id)
3949 struct face *new_face = FACE_FROM_ID (it->f, new_face_id);
3950 /* If it->face_id is -1, old_face below will be NULL, see
3951 the definition of FACE_FROM_ID_OR_NULL. This will happen
3952 if this is the initial call that gets the face. */
3953 struct face *old_face = FACE_FROM_ID_OR_NULL (it->f, it->face_id);
3955 /* If the value of face_id of the iterator is -1, we have to
3956 look in front of IT's position and see whether there is a
3957 face there that's different from new_face_id. */
3958 if (!old_face && IT_CHARPOS (*it) > BEG)
3960 int prev_face_id = face_before_it_pos (it);
3962 old_face = FACE_FROM_ID_OR_NULL (it->f, prev_face_id);
3965 /* If the new face has a box, but the old face does not,
3966 this is the start of a run of characters with box face,
3967 i.e. this character has a shadow on the left side. */
3968 it->start_of_box_run_p = (new_face->box != FACE_NO_BOX
3969 && (old_face == NULL || !old_face->box));
3970 it->face_box_p = new_face->box != FACE_NO_BOX;
3973 else
3975 int base_face_id;
3976 ptrdiff_t bufpos;
3977 int i;
3978 Lisp_Object from_overlay
3979 = (it->current.overlay_string_index >= 0
3980 ? it->string_overlays[it->current.overlay_string_index
3981 % OVERLAY_STRING_CHUNK_SIZE]
3982 : Qnil);
3984 /* See if we got to this string directly or indirectly from
3985 an overlay property. That includes the before-string or
3986 after-string of an overlay, strings in display properties
3987 provided by an overlay, their text properties, etc.
3989 FROM_OVERLAY is the overlay that brought us here, or nil if none. */
3990 if (! NILP (from_overlay))
3991 for (i = it->sp - 1; i >= 0; i--)
3993 if (it->stack[i].current.overlay_string_index >= 0)
3994 from_overlay
3995 = it->string_overlays[it->stack[i].current.overlay_string_index
3996 % OVERLAY_STRING_CHUNK_SIZE];
3997 else if (! NILP (it->stack[i].from_overlay))
3998 from_overlay = it->stack[i].from_overlay;
4000 if (!NILP (from_overlay))
4001 break;
4004 if (! NILP (from_overlay))
4006 bufpos = IT_CHARPOS (*it);
4007 /* For a string from an overlay, the base face depends
4008 only on text properties and ignores overlays. */
4009 base_face_id
4010 = face_for_overlay_string (it->w,
4011 IT_CHARPOS (*it),
4012 &next_stop,
4013 (IT_CHARPOS (*it)
4014 + TEXT_PROP_DISTANCE_LIMIT),
4015 false,
4016 from_overlay);
4018 else
4020 bufpos = 0;
4022 /* For strings from a `display' property, use the face at
4023 IT's current buffer position as the base face to merge
4024 with, so that overlay strings appear in the same face as
4025 surrounding text, unless they specify their own faces.
4026 For strings from wrap-prefix and line-prefix properties,
4027 use the default face, possibly remapped via
4028 Vface_remapping_alist. */
4029 /* Note that the fact that we use the face at _buffer_
4030 position means that a 'display' property on an overlay
4031 string will not inherit the face of that overlay string,
4032 but will instead revert to the face of buffer text
4033 covered by the overlay. This is visible, e.g., when the
4034 overlay specifies a box face, but neither the buffer nor
4035 the display string do. This sounds like a design bug,
4036 but Emacs always did that since v21.1, so changing that
4037 might be a big deal. */
4038 base_face_id = it->string_from_prefix_prop_p
4039 ? (!NILP (Vface_remapping_alist)
4040 ? lookup_basic_face (it->f, DEFAULT_FACE_ID)
4041 : DEFAULT_FACE_ID)
4042 : underlying_face_id (it);
4045 new_face_id = face_at_string_position (it->w,
4046 it->string,
4047 IT_STRING_CHARPOS (*it),
4048 bufpos,
4049 &next_stop,
4050 base_face_id, false);
4052 /* Is this a start of a run of characters with box? Caveat:
4053 this can be called for a freshly allocated iterator; face_id
4054 is -1 is this case. We know that the new face will not
4055 change until the next check pos, i.e. if the new face has a
4056 box, all characters up to that position will have a
4057 box. But, as usual, we don't know whether that position
4058 is really the end. */
4059 if (new_face_id != it->face_id)
4061 struct face *new_face = FACE_FROM_ID (it->f, new_face_id);
4062 struct face *old_face = FACE_FROM_ID_OR_NULL (it->f, it->face_id);
4064 /* If new face has a box but old face hasn't, this is the
4065 start of a run of characters with box, i.e. it has a
4066 shadow on the left side. */
4067 it->start_of_box_run_p
4068 = new_face->box && (old_face == NULL || !old_face->box);
4069 it->face_box_p = new_face->box != FACE_NO_BOX;
4073 it->face_id = new_face_id;
4074 return HANDLED_NORMALLY;
4078 /* Return the ID of the face ``underlying'' IT's current position,
4079 which is in a string. If the iterator is associated with a
4080 buffer, return the face at IT's current buffer position.
4081 Otherwise, use the iterator's base_face_id. */
4083 static int
4084 underlying_face_id (struct it *it)
4086 int face_id = it->base_face_id, i;
4088 eassert (STRINGP (it->string));
4090 for (i = it->sp - 1; i >= 0; --i)
4091 if (NILP (it->stack[i].string))
4092 face_id = it->stack[i].face_id;
4094 return face_id;
4098 /* Compute the face one character before or after the current position
4099 of IT, in the visual order. BEFORE_P means get the face
4100 in front (to the left in L2R paragraphs, to the right in R2L
4101 paragraphs) of IT's screen position. Value is the ID of the face. */
4103 static int
4104 face_before_or_after_it_pos (struct it *it, bool before_p)
4106 int face_id, limit;
4107 ptrdiff_t next_check_charpos;
4108 struct it it_copy;
4109 void *it_copy_data = NULL;
4111 eassert (it->s == NULL);
4113 if (STRINGP (it->string))
4115 ptrdiff_t bufpos, charpos;
4116 int base_face_id;
4118 /* No face change past the end of the string (for the case
4119 we are padding with spaces). No face change before the
4120 string start. */
4121 if (IT_STRING_CHARPOS (*it) >= SCHARS (it->string)
4122 || (IT_STRING_CHARPOS (*it) == 0 && before_p))
4123 return it->face_id;
4125 if (!it->bidi_p)
4127 /* Set charpos to the position before or after IT's current
4128 position, in the logical order, which in the non-bidi
4129 case is the same as the visual order. */
4130 if (before_p)
4131 charpos = IT_STRING_CHARPOS (*it) - 1;
4132 else if (it->what == IT_COMPOSITION)
4133 /* For composition, we must check the character after the
4134 composition. */
4135 charpos = IT_STRING_CHARPOS (*it) + it->cmp_it.nchars;
4136 else
4137 charpos = IT_STRING_CHARPOS (*it) + 1;
4139 else
4141 if (before_p)
4143 /* With bidi iteration, the character before the current
4144 in the visual order cannot be found by simple
4145 iteration, because "reverse" reordering is not
4146 supported. Instead, we need to start from the string
4147 beginning and go all the way to the current string
4148 position, remembering the previous position. */
4149 /* Ignore face changes before the first visible
4150 character on this display line. */
4151 if (it->current_x <= it->first_visible_x)
4152 return it->face_id;
4153 SAVE_IT (it_copy, *it, it_copy_data);
4154 IT_STRING_CHARPOS (it_copy) = 0;
4155 bidi_init_it (0, 0, FRAME_WINDOW_P (it_copy.f), &it_copy.bidi_it);
4159 charpos = IT_STRING_CHARPOS (it_copy);
4160 if (charpos >= SCHARS (it->string))
4161 break;
4162 bidi_move_to_visually_next (&it_copy.bidi_it);
4164 while (IT_STRING_CHARPOS (it_copy) != IT_STRING_CHARPOS (*it));
4166 RESTORE_IT (it, it, it_copy_data);
4168 else
4170 /* Set charpos to the string position of the character
4171 that comes after IT's current position in the visual
4172 order. */
4173 int n = (it->what == IT_COMPOSITION ? it->cmp_it.nchars : 1);
4175 it_copy = *it;
4176 while (n--)
4177 bidi_move_to_visually_next (&it_copy.bidi_it);
4179 charpos = it_copy.bidi_it.charpos;
4182 eassert (0 <= charpos && charpos <= SCHARS (it->string));
4184 if (it->current.overlay_string_index >= 0)
4185 bufpos = IT_CHARPOS (*it);
4186 else
4187 bufpos = 0;
4189 base_face_id = underlying_face_id (it);
4191 /* Get the face for ASCII, or unibyte. */
4192 face_id = face_at_string_position (it->w,
4193 it->string,
4194 charpos,
4195 bufpos,
4196 &next_check_charpos,
4197 base_face_id, false);
4199 /* Correct the face for charsets different from ASCII. Do it
4200 for the multibyte case only. The face returned above is
4201 suitable for unibyte text if IT->string is unibyte. */
4202 if (STRING_MULTIBYTE (it->string))
4204 struct text_pos pos1 = string_pos (charpos, it->string);
4205 const unsigned char *p = SDATA (it->string) + BYTEPOS (pos1);
4206 int c, len;
4207 struct face *face = FACE_FROM_ID (it->f, face_id);
4209 c = string_char_and_length (p, &len);
4210 face_id = FACE_FOR_CHAR (it->f, face, c, charpos, it->string);
4213 else
4215 struct text_pos pos;
4217 if ((IT_CHARPOS (*it) >= ZV && !before_p)
4218 || (IT_CHARPOS (*it) <= BEGV && before_p))
4219 return it->face_id;
4221 limit = IT_CHARPOS (*it) + TEXT_PROP_DISTANCE_LIMIT;
4222 pos = it->current.pos;
4224 if (!it->bidi_p)
4226 if (before_p)
4227 DEC_TEXT_POS (pos, it->multibyte_p);
4228 else
4230 if (it->what == IT_COMPOSITION)
4232 /* For composition, we must check the position after
4233 the composition. */
4234 pos.charpos += it->cmp_it.nchars;
4235 pos.bytepos += it->len;
4237 else
4238 INC_TEXT_POS (pos, it->multibyte_p);
4241 else
4243 if (before_p)
4245 int current_x;
4247 /* With bidi iteration, the character before the current
4248 in the visual order cannot be found by simple
4249 iteration, because "reverse" reordering is not
4250 supported. Instead, we need to use the move_it_*
4251 family of functions, and move to the previous
4252 character starting from the beginning of the visual
4253 line. */
4254 /* Ignore face changes before the first visible
4255 character on this display line. */
4256 if (it->current_x <= it->first_visible_x)
4257 return it->face_id;
4258 SAVE_IT (it_copy, *it, it_copy_data);
4259 /* Implementation note: Since move_it_in_display_line
4260 works in the iterator geometry, and thinks the first
4261 character is always the leftmost, even in R2L lines,
4262 we don't need to distinguish between the R2L and L2R
4263 cases here. */
4264 current_x = it_copy.current_x;
4265 move_it_vertically_backward (&it_copy, 0);
4266 move_it_in_display_line (&it_copy, ZV, current_x - 1, MOVE_TO_X);
4267 pos = it_copy.current.pos;
4268 RESTORE_IT (it, it, it_copy_data);
4270 else
4272 /* Set charpos to the buffer position of the character
4273 that comes after IT's current position in the visual
4274 order. */
4275 int n = (it->what == IT_COMPOSITION ? it->cmp_it.nchars : 1);
4277 it_copy = *it;
4278 while (n--)
4279 bidi_move_to_visually_next (&it_copy.bidi_it);
4281 SET_TEXT_POS (pos,
4282 it_copy.bidi_it.charpos, it_copy.bidi_it.bytepos);
4285 eassert (BEGV <= CHARPOS (pos) && CHARPOS (pos) <= ZV);
4287 /* Determine face for CHARSET_ASCII, or unibyte. */
4288 face_id = face_at_buffer_position (it->w,
4289 CHARPOS (pos),
4290 &next_check_charpos,
4291 limit, false, -1);
4293 /* Correct the face for charsets different from ASCII. Do it
4294 for the multibyte case only. The face returned above is
4295 suitable for unibyte text if current_buffer is unibyte. */
4296 if (it->multibyte_p)
4298 int c = FETCH_MULTIBYTE_CHAR (BYTEPOS (pos));
4299 struct face *face = FACE_FROM_ID (it->f, face_id);
4300 face_id = FACE_FOR_CHAR (it->f, face, c, CHARPOS (pos), Qnil);
4304 return face_id;
4309 /***********************************************************************
4310 Invisible text
4311 ***********************************************************************/
4313 /* Set up iterator IT from invisible properties at its current
4314 position. Called from handle_stop. */
4316 static enum prop_handled
4317 handle_invisible_prop (struct it *it)
4319 enum prop_handled handled = HANDLED_NORMALLY;
4320 int invis;
4321 Lisp_Object prop;
4323 if (STRINGP (it->string))
4325 Lisp_Object end_charpos, limit;
4327 /* Get the value of the invisible text property at the
4328 current position. Value will be nil if there is no such
4329 property. */
4330 end_charpos = make_number (IT_STRING_CHARPOS (*it));
4331 prop = Fget_text_property (end_charpos, Qinvisible, it->string);
4332 invis = TEXT_PROP_MEANS_INVISIBLE (prop);
4334 if (invis != 0 && IT_STRING_CHARPOS (*it) < it->end_charpos)
4336 /* Record whether we have to display an ellipsis for the
4337 invisible text. */
4338 bool display_ellipsis_p = (invis == 2);
4339 ptrdiff_t len, endpos;
4341 handled = HANDLED_RECOMPUTE_PROPS;
4343 /* Get the position at which the next visible text can be
4344 found in IT->string, if any. */
4345 endpos = len = SCHARS (it->string);
4346 XSETINT (limit, len);
4349 end_charpos
4350 = Fnext_single_property_change (end_charpos, Qinvisible,
4351 it->string, limit);
4352 /* Since LIMIT is always an integer, so should be the
4353 value returned by Fnext_single_property_change. */
4354 eassert (INTEGERP (end_charpos));
4355 if (INTEGERP (end_charpos))
4357 endpos = XFASTINT (end_charpos);
4358 prop = Fget_text_property (end_charpos, Qinvisible, it->string);
4359 invis = TEXT_PROP_MEANS_INVISIBLE (prop);
4360 if (invis == 2)
4361 display_ellipsis_p = true;
4363 else /* Should never happen; but if it does, exit the loop. */
4364 endpos = len;
4366 while (invis != 0 && endpos < len);
4368 if (display_ellipsis_p)
4369 it->ellipsis_p = true;
4371 if (endpos < len)
4373 /* Text at END_CHARPOS is visible. Move IT there. */
4374 struct text_pos old;
4375 ptrdiff_t oldpos;
4377 old = it->current.string_pos;
4378 oldpos = CHARPOS (old);
4379 if (it->bidi_p)
4381 if (it->bidi_it.first_elt
4382 && it->bidi_it.charpos < SCHARS (it->string))
4383 bidi_paragraph_init (it->paragraph_embedding,
4384 &it->bidi_it, true);
4385 /* Bidi-iterate out of the invisible text. */
4388 bidi_move_to_visually_next (&it->bidi_it);
4390 while (oldpos <= it->bidi_it.charpos
4391 && it->bidi_it.charpos < endpos
4392 && it->bidi_it.charpos < it->bidi_it.string.schars);
4394 IT_STRING_CHARPOS (*it) = it->bidi_it.charpos;
4395 IT_STRING_BYTEPOS (*it) = it->bidi_it.bytepos;
4396 if (IT_CHARPOS (*it) >= endpos)
4397 it->prev_stop = endpos;
4399 else
4401 IT_STRING_CHARPOS (*it) = endpos;
4402 compute_string_pos (&it->current.string_pos, old, it->string);
4405 else
4407 /* The rest of the string is invisible. If this is an
4408 overlay string, proceed with the next overlay string
4409 or whatever comes and return a character from there. */
4410 if (it->current.overlay_string_index >= 0
4411 && !display_ellipsis_p)
4413 next_overlay_string (it);
4414 /* Don't check for overlay strings when we just
4415 finished processing them. */
4416 handled = HANDLED_OVERLAY_STRING_CONSUMED;
4418 else
4420 IT_STRING_CHARPOS (*it) = SCHARS (it->string);
4421 IT_STRING_BYTEPOS (*it) = SBYTES (it->string);
4426 else
4428 ptrdiff_t newpos, next_stop, start_charpos, tem;
4429 Lisp_Object pos, overlay;
4431 /* First of all, is there invisible text at this position? */
4432 tem = start_charpos = IT_CHARPOS (*it);
4433 pos = make_number (tem);
4434 prop = get_char_property_and_overlay (pos, Qinvisible, it->window,
4435 &overlay);
4436 invis = TEXT_PROP_MEANS_INVISIBLE (prop);
4438 /* If we are on invisible text, skip over it. */
4439 if (invis != 0 && start_charpos < it->end_charpos)
4441 /* Record whether we have to display an ellipsis for the
4442 invisible text. */
4443 bool display_ellipsis_p = invis == 2;
4445 handled = HANDLED_RECOMPUTE_PROPS;
4447 /* Loop skipping over invisible text. The loop is left at
4448 ZV or with IT on the first char being visible again. */
4451 /* Try to skip some invisible text. Return value is the
4452 position reached which can be equal to where we start
4453 if there is nothing invisible there. This skips both
4454 over invisible text properties and overlays with
4455 invisible property. */
4456 newpos = skip_invisible (tem, &next_stop, ZV, it->window);
4458 /* If we skipped nothing at all we weren't at invisible
4459 text in the first place. If everything to the end of
4460 the buffer was skipped, end the loop. */
4461 if (newpos == tem || newpos >= ZV)
4462 invis = 0;
4463 else
4465 /* We skipped some characters but not necessarily
4466 all there are. Check if we ended up on visible
4467 text. Fget_char_property returns the property of
4468 the char before the given position, i.e. if we
4469 get invis = 0, this means that the char at
4470 newpos is visible. */
4471 pos = make_number (newpos);
4472 prop = Fget_char_property (pos, Qinvisible, it->window);
4473 invis = TEXT_PROP_MEANS_INVISIBLE (prop);
4476 /* If we ended up on invisible text, proceed to
4477 skip starting with next_stop. */
4478 if (invis != 0)
4479 tem = next_stop;
4481 /* If there are adjacent invisible texts, don't lose the
4482 second one's ellipsis. */
4483 if (invis == 2)
4484 display_ellipsis_p = true;
4486 while (invis != 0);
4488 /* The position newpos is now either ZV or on visible text. */
4489 if (it->bidi_p)
4491 ptrdiff_t bpos = CHAR_TO_BYTE (newpos);
4492 bool on_newline
4493 = bpos == ZV_BYTE || FETCH_BYTE (bpos) == '\n';
4494 bool after_newline
4495 = newpos <= BEGV || FETCH_BYTE (bpos - 1) == '\n';
4497 /* If the invisible text ends on a newline or on a
4498 character after a newline, we can avoid the costly,
4499 character by character, bidi iteration to NEWPOS, and
4500 instead simply reseat the iterator there. That's
4501 because all bidi reordering information is tossed at
4502 the newline. This is a big win for modes that hide
4503 complete lines, like Outline, Org, etc. */
4504 if (on_newline || after_newline)
4506 struct text_pos tpos;
4507 bidi_dir_t pdir = it->bidi_it.paragraph_dir;
4509 SET_TEXT_POS (tpos, newpos, bpos);
4510 reseat_1 (it, tpos, false);
4511 /* If we reseat on a newline/ZV, we need to prep the
4512 bidi iterator for advancing to the next character
4513 after the newline/EOB, keeping the current paragraph
4514 direction (so that PRODUCE_GLYPHS does TRT wrt
4515 prepending/appending glyphs to a glyph row). */
4516 if (on_newline)
4518 it->bidi_it.first_elt = false;
4519 it->bidi_it.paragraph_dir = pdir;
4520 it->bidi_it.ch = (bpos == ZV_BYTE) ? -1 : '\n';
4521 it->bidi_it.nchars = 1;
4522 it->bidi_it.ch_len = 1;
4525 else /* Must use the slow method. */
4527 /* With bidi iteration, the region of invisible text
4528 could start and/or end in the middle of a
4529 non-base embedding level. Therefore, we need to
4530 skip invisible text using the bidi iterator,
4531 starting at IT's current position, until we find
4532 ourselves outside of the invisible text.
4533 Skipping invisible text _after_ bidi iteration
4534 avoids affecting the visual order of the
4535 displayed text when invisible properties are
4536 added or removed. */
4537 if (it->bidi_it.first_elt && it->bidi_it.charpos < ZV)
4539 /* If we were `reseat'ed to a new paragraph,
4540 determine the paragraph base direction. We
4541 need to do it now because
4542 next_element_from_buffer may not have a
4543 chance to do it, if we are going to skip any
4544 text at the beginning, which resets the
4545 FIRST_ELT flag. */
4546 bidi_paragraph_init (it->paragraph_embedding,
4547 &it->bidi_it, true);
4551 bidi_move_to_visually_next (&it->bidi_it);
4553 while (it->stop_charpos <= it->bidi_it.charpos
4554 && it->bidi_it.charpos < newpos);
4555 IT_CHARPOS (*it) = it->bidi_it.charpos;
4556 IT_BYTEPOS (*it) = it->bidi_it.bytepos;
4557 /* If we overstepped NEWPOS, record its position in
4558 the iterator, so that we skip invisible text if
4559 later the bidi iteration lands us in the
4560 invisible region again. */
4561 if (IT_CHARPOS (*it) >= newpos)
4562 it->prev_stop = newpos;
4565 else
4567 IT_CHARPOS (*it) = newpos;
4568 IT_BYTEPOS (*it) = CHAR_TO_BYTE (newpos);
4571 if (display_ellipsis_p)
4573 /* Make sure that the glyphs of the ellipsis will get
4574 correct `charpos' values. If we would not update
4575 it->position here, the glyphs would belong to the
4576 last visible character _before_ the invisible
4577 text, which confuses `set_cursor_from_row'.
4579 We use the last invisible position instead of the
4580 first because this way the cursor is always drawn on
4581 the first "." of the ellipsis, whenever PT is inside
4582 the invisible text. Otherwise the cursor would be
4583 placed _after_ the ellipsis when the point is after the
4584 first invisible character. */
4585 if (!STRINGP (it->object))
4587 it->position.charpos = newpos - 1;
4588 it->position.bytepos = CHAR_TO_BYTE (it->position.charpos);
4592 /* If there are before-strings at the start of invisible
4593 text, and the text is invisible because of a text
4594 property, arrange to show before-strings because 20.x did
4595 it that way. (If the text is invisible because of an
4596 overlay property instead of a text property, this is
4597 already handled in the overlay code.) */
4598 if (NILP (overlay)
4599 && get_overlay_strings (it, it->stop_charpos))
4601 handled = HANDLED_RECOMPUTE_PROPS;
4602 if (it->sp > 0)
4604 it->stack[it->sp - 1].display_ellipsis_p = display_ellipsis_p;
4605 /* The call to get_overlay_strings above recomputes
4606 it->stop_charpos, but it only considers changes
4607 in properties and overlays beyond iterator's
4608 current position. This causes us to miss changes
4609 that happen exactly where the invisible property
4610 ended. So we play it safe here and force the
4611 iterator to check for potential stop positions
4612 immediately after the invisible text. Note that
4613 if get_overlay_strings returns true, it
4614 normally also pushed the iterator stack, so we
4615 need to update the stop position in the slot
4616 below the current one. */
4617 it->stack[it->sp - 1].stop_charpos
4618 = CHARPOS (it->stack[it->sp - 1].current.pos);
4621 else if (display_ellipsis_p)
4623 it->ellipsis_p = true;
4624 /* Let the ellipsis display before
4625 considering any properties of the following char.
4626 Fixes jasonr@gnu.org 01 Oct 07 bug. */
4627 handled = HANDLED_RETURN;
4632 return handled;
4636 /* Make iterator IT return `...' next.
4637 Replaces LEN characters from buffer. */
4639 static void
4640 setup_for_ellipsis (struct it *it, int len)
4642 /* Use the display table definition for `...'. Invalid glyphs
4643 will be handled by the method returning elements from dpvec. */
4644 if (it->dp && VECTORP (DISP_INVIS_VECTOR (it->dp)))
4646 struct Lisp_Vector *v = XVECTOR (DISP_INVIS_VECTOR (it->dp));
4647 it->dpvec = v->contents;
4648 it->dpend = v->contents + v->header.size;
4650 else
4652 /* Default `...'. */
4653 it->dpvec = default_invis_vector;
4654 it->dpend = default_invis_vector + 3;
4657 it->dpvec_char_len = len;
4658 it->current.dpvec_index = 0;
4659 it->dpvec_face_id = -1;
4661 /* Use IT->saved_face_id for the ellipsis, so that it has the same
4662 face as the preceding text. IT->saved_face_id was set in
4663 handle_stop to the face of the preceding character, and will be
4664 different from IT->face_id only if the invisible text skipped in
4665 handle_invisible_prop has some non-default face on its first
4666 character. We thus ignore the face of the invisible text when we
4667 display the ellipsis. IT's face is restored in set_iterator_to_next. */
4668 if (it->saved_face_id >= 0)
4669 it->face_id = it->saved_face_id;
4671 /* If the ellipsis represents buffer text, it means we advanced in
4672 the buffer, so we should no longer ignore overlay strings. */
4673 if (it->method == GET_FROM_BUFFER)
4674 it->ignore_overlay_strings_at_pos_p = false;
4676 it->method = GET_FROM_DISPLAY_VECTOR;
4677 it->ellipsis_p = true;
4682 /***********************************************************************
4683 'display' property
4684 ***********************************************************************/
4686 /* Set up iterator IT from `display' property at its current position.
4687 Called from handle_stop.
4688 We return HANDLED_RETURN if some part of the display property
4689 overrides the display of the buffer text itself.
4690 Otherwise we return HANDLED_NORMALLY. */
4692 static enum prop_handled
4693 handle_display_prop (struct it *it)
4695 Lisp_Object propval, object, overlay;
4696 struct text_pos *position;
4697 ptrdiff_t bufpos;
4698 /* Nonzero if some property replaces the display of the text itself. */
4699 int display_replaced = 0;
4701 if (STRINGP (it->string))
4703 object = it->string;
4704 position = &it->current.string_pos;
4705 bufpos = CHARPOS (it->current.pos);
4707 else
4709 XSETWINDOW (object, it->w);
4710 position = &it->current.pos;
4711 bufpos = CHARPOS (*position);
4714 /* Reset those iterator values set from display property values. */
4715 it->slice.x = it->slice.y = it->slice.width = it->slice.height = Qnil;
4716 it->space_width = Qnil;
4717 it->font_height = Qnil;
4718 it->voffset = 0;
4720 /* We don't support recursive `display' properties, i.e. string
4721 values that have a string `display' property, that have a string
4722 `display' property etc. */
4723 if (!it->string_from_display_prop_p)
4724 it->area = TEXT_AREA;
4726 propval = get_char_property_and_overlay (make_number (position->charpos),
4727 Qdisplay, object, &overlay);
4728 if (NILP (propval))
4729 return HANDLED_NORMALLY;
4730 /* Now OVERLAY is the overlay that gave us this property, or nil
4731 if it was a text property. */
4733 if (!STRINGP (it->string))
4734 object = it->w->contents;
4736 display_replaced = handle_display_spec (it, propval, object, overlay,
4737 position, bufpos,
4738 FRAME_WINDOW_P (it->f));
4739 return display_replaced != 0 ? HANDLED_RETURN : HANDLED_NORMALLY;
4742 /* Subroutine of handle_display_prop. Returns non-zero if the display
4743 specification in SPEC is a replacing specification, i.e. it would
4744 replace the text covered by `display' property with something else,
4745 such as an image or a display string. If SPEC includes any kind or
4746 `(space ...) specification, the value is 2; this is used by
4747 compute_display_string_pos, which see.
4749 See handle_single_display_spec for documentation of arguments.
4750 FRAME_WINDOW_P is true if the window being redisplayed is on a
4751 GUI frame; this argument is used only if IT is NULL, see below.
4753 IT can be NULL, if this is called by the bidi reordering code
4754 through compute_display_string_pos, which see. In that case, this
4755 function only examines SPEC, but does not otherwise "handle" it, in
4756 the sense that it doesn't set up members of IT from the display
4757 spec. */
4758 static int
4759 handle_display_spec (struct it *it, Lisp_Object spec, Lisp_Object object,
4760 Lisp_Object overlay, struct text_pos *position,
4761 ptrdiff_t bufpos, bool frame_window_p)
4763 int replacing = 0;
4764 bool enable_eval = true;
4766 /* Support (disable-eval PROP) which is used by enriched.el. */
4767 if (CONSP (spec) && EQ (XCAR (spec), Qdisable_eval))
4769 enable_eval = false;
4770 spec = XCAR (XCDR (spec));
4773 if (CONSP (spec)
4774 /* Simple specifications. */
4775 && !EQ (XCAR (spec), Qimage)
4776 #ifdef HAVE_XWIDGETS
4777 && !EQ (XCAR (spec), Qxwidget)
4778 #endif
4779 && !EQ (XCAR (spec), Qspace)
4780 && !EQ (XCAR (spec), Qwhen)
4781 && !EQ (XCAR (spec), Qslice)
4782 && !EQ (XCAR (spec), Qspace_width)
4783 && !EQ (XCAR (spec), Qheight)
4784 && !EQ (XCAR (spec), Qraise)
4785 /* Marginal area specifications. */
4786 && !(CONSP (XCAR (spec)) && EQ (XCAR (XCAR (spec)), Qmargin))
4787 && !EQ (XCAR (spec), Qleft_fringe)
4788 && !EQ (XCAR (spec), Qright_fringe)
4789 && !NILP (XCAR (spec)))
4791 for (; CONSP (spec); spec = XCDR (spec))
4793 int rv = handle_single_display_spec (it, XCAR (spec), object,
4794 overlay, position, bufpos,
4795 replacing, frame_window_p,
4796 enable_eval);
4797 if (rv != 0)
4799 replacing = rv;
4800 /* If some text in a string is replaced, `position' no
4801 longer points to the position of `object'. */
4802 if (!it || STRINGP (object))
4803 break;
4807 else if (VECTORP (spec))
4809 ptrdiff_t i;
4810 for (i = 0; i < ASIZE (spec); ++i)
4812 int rv = handle_single_display_spec (it, AREF (spec, i), object,
4813 overlay, position, bufpos,
4814 replacing, frame_window_p,
4815 enable_eval);
4816 if (rv != 0)
4818 replacing = rv;
4819 /* If some text in a string is replaced, `position' no
4820 longer points to the position of `object'. */
4821 if (!it || STRINGP (object))
4822 break;
4826 else
4827 replacing = handle_single_display_spec (it, spec, object, overlay, position,
4828 bufpos, 0, frame_window_p,
4829 enable_eval);
4830 return replacing;
4833 /* Value is the position of the end of the `display' property starting
4834 at START_POS in OBJECT. */
4836 static struct text_pos
4837 display_prop_end (struct it *it, Lisp_Object object, struct text_pos start_pos)
4839 Lisp_Object end;
4840 struct text_pos end_pos;
4842 end = Fnext_single_char_property_change (make_number (CHARPOS (start_pos)),
4843 Qdisplay, object, Qnil);
4844 CHARPOS (end_pos) = XFASTINT (end);
4845 if (STRINGP (object))
4846 compute_string_pos (&end_pos, start_pos, it->string);
4847 else
4848 BYTEPOS (end_pos) = CHAR_TO_BYTE (XFASTINT (end));
4850 return end_pos;
4854 /* Set up IT from a single `display' property specification SPEC. OBJECT
4855 is the object in which the `display' property was found. *POSITION
4856 is the position in OBJECT at which the `display' property was found.
4857 BUFPOS is the buffer position of OBJECT (different from POSITION if
4858 OBJECT is not a buffer). DISPLAY_REPLACED non-zero means that we
4859 previously saw a display specification which already replaced text
4860 display with something else, for example an image; we ignore such
4861 properties after the first one has been processed.
4863 OVERLAY is the overlay this `display' property came from,
4864 or nil if it was a text property.
4866 If SPEC is a `space' or `image' specification, and in some other
4867 cases too, set *POSITION to the position where the `display'
4868 property ends.
4870 If IT is NULL, only examine the property specification in SPEC, but
4871 don't set up IT. In that case, FRAME_WINDOW_P means SPEC
4872 is intended to be displayed in a window on a GUI frame.
4874 Enable evaluation of Lisp forms only if ENABLE_EVAL_P is true.
4876 Value is non-zero if something was found which replaces the display
4877 of buffer or string text. */
4879 static int
4880 handle_single_display_spec (struct it *it, Lisp_Object spec, Lisp_Object object,
4881 Lisp_Object overlay, struct text_pos *position,
4882 ptrdiff_t bufpos, int display_replaced,
4883 bool frame_window_p, bool enable_eval_p)
4885 Lisp_Object form;
4886 Lisp_Object location, value;
4887 struct text_pos start_pos = *position;
4889 /* If SPEC is a list of the form `(when FORM . VALUE)', evaluate FORM.
4890 If the result is non-nil, use VALUE instead of SPEC. */
4891 form = Qt;
4892 if (CONSP (spec) && EQ (XCAR (spec), Qwhen))
4894 spec = XCDR (spec);
4895 if (!CONSP (spec))
4896 return 0;
4897 form = XCAR (spec);
4898 spec = XCDR (spec);
4901 if (!NILP (form) && !EQ (form, Qt) && !enable_eval_p)
4902 form = Qnil;
4903 if (!NILP (form) && !EQ (form, Qt))
4905 ptrdiff_t count = SPECPDL_INDEX ();
4907 /* Bind `object' to the object having the `display' property, a
4908 buffer or string. Bind `position' to the position in the
4909 object where the property was found, and `buffer-position'
4910 to the current position in the buffer. */
4912 if (NILP (object))
4913 XSETBUFFER (object, current_buffer);
4914 specbind (Qobject, object);
4915 specbind (Qposition, make_number (CHARPOS (*position)));
4916 specbind (Qbuffer_position, make_number (bufpos));
4917 form = safe_eval (form);
4918 unbind_to (count, Qnil);
4921 if (NILP (form))
4922 return 0;
4924 /* Handle `(height HEIGHT)' specifications. */
4925 if (CONSP (spec)
4926 && EQ (XCAR (spec), Qheight)
4927 && CONSP (XCDR (spec)))
4929 if (it)
4931 if (!FRAME_WINDOW_P (it->f))
4932 return 0;
4934 it->font_height = XCAR (XCDR (spec));
4935 if (!NILP (it->font_height))
4937 int new_height = -1;
4939 if (CONSP (it->font_height)
4940 && (EQ (XCAR (it->font_height), Qplus)
4941 || EQ (XCAR (it->font_height), Qminus))
4942 && CONSP (XCDR (it->font_height))
4943 && RANGED_INTEGERP (0, XCAR (XCDR (it->font_height)), INT_MAX))
4945 /* `(+ N)' or `(- N)' where N is an integer. */
4946 int steps = XINT (XCAR (XCDR (it->font_height)));
4947 if (EQ (XCAR (it->font_height), Qplus))
4948 steps = - steps;
4949 it->face_id = smaller_face (it->f, it->face_id, steps);
4951 else if (FUNCTIONP (it->font_height) && enable_eval_p)
4953 /* Call function with current height as argument.
4954 Value is the new height. */
4955 struct face *face = FACE_FROM_ID (it->f, it->face_id);
4956 Lisp_Object height;
4957 height = safe_call1 (it->font_height,
4958 face->lface[LFACE_HEIGHT_INDEX]);
4959 if (NUMBERP (height))
4960 new_height = XFLOATINT (height);
4962 else if (NUMBERP (it->font_height))
4964 /* Value is a multiple of the canonical char height. */
4965 struct face *f;
4967 f = FACE_FROM_ID (it->f,
4968 lookup_basic_face (it->f, DEFAULT_FACE_ID));
4969 new_height = (XFLOATINT (it->font_height)
4970 * XINT (f->lface[LFACE_HEIGHT_INDEX]));
4972 else if (enable_eval_p)
4974 /* Evaluate IT->font_height with `height' bound to the
4975 current specified height to get the new height. */
4976 ptrdiff_t count = SPECPDL_INDEX ();
4977 struct face *face = FACE_FROM_ID (it->f, it->face_id);
4979 specbind (Qheight, face->lface[LFACE_HEIGHT_INDEX]);
4980 value = safe_eval (it->font_height);
4981 unbind_to (count, Qnil);
4983 if (NUMBERP (value))
4984 new_height = XFLOATINT (value);
4987 if (new_height > 0)
4988 it->face_id = face_with_height (it->f, it->face_id, new_height);
4992 return 0;
4995 /* Handle `(space-width WIDTH)'. */
4996 if (CONSP (spec)
4997 && EQ (XCAR (spec), Qspace_width)
4998 && CONSP (XCDR (spec)))
5000 if (it)
5002 if (!FRAME_WINDOW_P (it->f))
5003 return 0;
5005 value = XCAR (XCDR (spec));
5006 if (NUMBERP (value) && XFLOATINT (value) > 0)
5007 it->space_width = value;
5010 return 0;
5013 /* Handle `(slice X Y WIDTH HEIGHT)'. */
5014 if (CONSP (spec)
5015 && EQ (XCAR (spec), Qslice))
5017 Lisp_Object tem;
5019 if (it)
5021 if (!FRAME_WINDOW_P (it->f))
5022 return 0;
5024 if (tem = XCDR (spec), CONSP (tem))
5026 it->slice.x = XCAR (tem);
5027 if (tem = XCDR (tem), CONSP (tem))
5029 it->slice.y = XCAR (tem);
5030 if (tem = XCDR (tem), CONSP (tem))
5032 it->slice.width = XCAR (tem);
5033 if (tem = XCDR (tem), CONSP (tem))
5034 it->slice.height = XCAR (tem);
5040 return 0;
5043 /* Handle `(raise FACTOR)'. */
5044 if (CONSP (spec)
5045 && EQ (XCAR (spec), Qraise)
5046 && CONSP (XCDR (spec)))
5048 if (it)
5050 if (!FRAME_WINDOW_P (it->f))
5051 return 0;
5053 #ifdef HAVE_WINDOW_SYSTEM
5054 value = XCAR (XCDR (spec));
5055 if (NUMBERP (value))
5057 struct face *face = FACE_FROM_ID (it->f, it->face_id);
5058 it->voffset = - (XFLOATINT (value)
5059 * (normal_char_height (face->font, -1)));
5061 #endif /* HAVE_WINDOW_SYSTEM */
5064 return 0;
5067 /* Don't handle the other kinds of display specifications
5068 inside a string that we got from a `display' property. */
5069 if (it && it->string_from_display_prop_p)
5070 return 0;
5072 /* Characters having this form of property are not displayed, so
5073 we have to find the end of the property. */
5074 if (it)
5076 start_pos = *position;
5077 *position = display_prop_end (it, object, start_pos);
5078 /* If the display property comes from an overlay, don't consider
5079 any potential stop_charpos values before the end of that
5080 overlay. Since display_prop_end will happily find another
5081 'display' property coming from some other overlay or text
5082 property on buffer positions before this overlay's end, we
5083 need to ignore them, or else we risk displaying this
5084 overlay's display string/image twice. */
5085 if (!NILP (overlay))
5087 ptrdiff_t ovendpos = OVERLAY_POSITION (OVERLAY_END (overlay));
5089 /* Some borderline-sane Lisp might call us with the current
5090 buffer narrowed so that overlay-end is outside the
5091 POINT_MIN..POINT_MAX region, which will then cause
5092 various assertion violations and crashes down the road,
5093 starting with pop_it when it will attempt to use POSITION
5094 set below. Prevent that. */
5095 ovendpos = clip_to_bounds (BEGV, ovendpos, ZV);
5097 if (ovendpos > CHARPOS (*position))
5098 SET_TEXT_POS (*position, ovendpos, CHAR_TO_BYTE (ovendpos));
5101 value = Qnil;
5103 /* Stop the scan at that end position--we assume that all
5104 text properties change there. */
5105 if (it)
5106 it->stop_charpos = position->charpos;
5108 /* Handle `(left-fringe BITMAP [FACE])'
5109 and `(right-fringe BITMAP [FACE])'. */
5110 if (CONSP (spec)
5111 && (EQ (XCAR (spec), Qleft_fringe)
5112 || EQ (XCAR (spec), Qright_fringe))
5113 && CONSP (XCDR (spec)))
5115 if (it)
5117 if (!FRAME_WINDOW_P (it->f))
5118 /* If we return here, POSITION has been advanced
5119 across the text with this property. */
5121 /* Synchronize the bidi iterator with POSITION. This is
5122 needed because we are not going to push the iterator
5123 on behalf of this display property, so there will be
5124 no pop_it call to do this synchronization for us. */
5125 if (it->bidi_p)
5127 it->position = *position;
5128 iterate_out_of_display_property (it);
5129 *position = it->position;
5131 return 1;
5134 else if (!frame_window_p)
5135 return 1;
5137 #ifdef HAVE_WINDOW_SYSTEM
5138 value = XCAR (XCDR (spec));
5139 int fringe_bitmap = SYMBOLP (value) ? lookup_fringe_bitmap (value) : 0;
5140 if (! fringe_bitmap)
5141 /* If we return here, POSITION has been advanced
5142 across the text with this property. */
5144 if (it && it->bidi_p)
5146 it->position = *position;
5147 iterate_out_of_display_property (it);
5148 *position = it->position;
5150 return 1;
5153 if (it)
5155 int face_id = lookup_basic_face (it->f, DEFAULT_FACE_ID);
5157 if (CONSP (XCDR (XCDR (spec))))
5159 Lisp_Object face_name = XCAR (XCDR (XCDR (spec)));
5160 int face_id2 = lookup_derived_face (it->f, face_name,
5161 FRINGE_FACE_ID, false);
5162 if (face_id2 >= 0)
5163 face_id = face_id2;
5166 /* Save current settings of IT so that we can restore them
5167 when we are finished with the glyph property value. */
5168 push_it (it, position);
5170 it->area = TEXT_AREA;
5171 it->what = IT_IMAGE;
5172 it->image_id = -1; /* no image */
5173 it->position = start_pos;
5174 it->object = NILP (object) ? it->w->contents : object;
5175 it->method = GET_FROM_IMAGE;
5176 it->from_overlay = Qnil;
5177 it->face_id = face_id;
5178 it->from_disp_prop_p = true;
5180 /* Say that we haven't consumed the characters with
5181 `display' property yet. The call to pop_it in
5182 set_iterator_to_next will clean this up. */
5183 *position = start_pos;
5185 if (EQ (XCAR (spec), Qleft_fringe))
5187 it->left_user_fringe_bitmap = fringe_bitmap;
5188 it->left_user_fringe_face_id = face_id;
5190 else
5192 it->right_user_fringe_bitmap = fringe_bitmap;
5193 it->right_user_fringe_face_id = face_id;
5196 #endif /* HAVE_WINDOW_SYSTEM */
5197 return 1;
5200 /* Prepare to handle `((margin left-margin) ...)',
5201 `((margin right-margin) ...)' and `((margin nil) ...)'
5202 prefixes for display specifications. */
5203 location = Qunbound;
5204 if (CONSP (spec) && CONSP (XCAR (spec)))
5206 Lisp_Object tem;
5208 value = XCDR (spec);
5209 if (CONSP (value))
5210 value = XCAR (value);
5212 tem = XCAR (spec);
5213 if (EQ (XCAR (tem), Qmargin)
5214 && (tem = XCDR (tem),
5215 tem = CONSP (tem) ? XCAR (tem) : Qnil,
5216 (NILP (tem)
5217 || EQ (tem, Qleft_margin)
5218 || EQ (tem, Qright_margin))))
5219 location = tem;
5222 if (EQ (location, Qunbound))
5224 location = Qnil;
5225 value = spec;
5228 /* After this point, VALUE is the property after any
5229 margin prefix has been stripped. It must be a string,
5230 an image specification, or `(space ...)'.
5232 LOCATION specifies where to display: `left-margin',
5233 `right-margin' or nil. */
5235 bool valid_p = (STRINGP (value)
5236 #ifdef HAVE_WINDOW_SYSTEM
5237 || ((it ? FRAME_WINDOW_P (it->f) : frame_window_p)
5238 && valid_image_p (value))
5239 #endif /* not HAVE_WINDOW_SYSTEM */
5240 || (CONSP (value) && EQ (XCAR (value), Qspace))
5241 || ((it ? FRAME_WINDOW_P (it->f) : frame_window_p)
5242 && valid_xwidget_spec_p (value)));
5244 if (valid_p && display_replaced == 0)
5246 int retval = 1;
5248 if (!it)
5250 /* Callers need to know whether the display spec is any kind
5251 of `(space ...)' spec that is about to affect text-area
5252 display. */
5253 if (CONSP (value) && EQ (XCAR (value), Qspace) && NILP (location))
5254 retval = 2;
5255 return retval;
5258 /* Save current settings of IT so that we can restore them
5259 when we are finished with the glyph property value. */
5260 push_it (it, position);
5261 it->from_overlay = overlay;
5262 it->from_disp_prop_p = true;
5264 if (NILP (location))
5265 it->area = TEXT_AREA;
5266 else if (EQ (location, Qleft_margin))
5267 it->area = LEFT_MARGIN_AREA;
5268 else
5269 it->area = RIGHT_MARGIN_AREA;
5271 if (STRINGP (value))
5273 it->string = value;
5274 it->multibyte_p = STRING_MULTIBYTE (it->string);
5275 it->current.overlay_string_index = -1;
5276 IT_STRING_CHARPOS (*it) = IT_STRING_BYTEPOS (*it) = 0;
5277 it->end_charpos = it->string_nchars = SCHARS (it->string);
5278 it->method = GET_FROM_STRING;
5279 it->stop_charpos = 0;
5280 it->prev_stop = 0;
5281 it->base_level_stop = 0;
5282 it->string_from_display_prop_p = true;
5283 it->cmp_it.id = -1;
5284 /* Say that we haven't consumed the characters with
5285 `display' property yet. The call to pop_it in
5286 set_iterator_to_next will clean this up. */
5287 if (BUFFERP (object))
5288 *position = start_pos;
5290 /* Force paragraph direction to be that of the parent
5291 object. If the parent object's paragraph direction is
5292 not yet determined, default to L2R. */
5293 if (it->bidi_p && it->bidi_it.paragraph_dir == R2L)
5294 it->paragraph_embedding = it->bidi_it.paragraph_dir;
5295 else
5296 it->paragraph_embedding = L2R;
5298 /* Set up the bidi iterator for this display string. */
5299 if (it->bidi_p)
5301 it->bidi_it.string.lstring = it->string;
5302 it->bidi_it.string.s = NULL;
5303 it->bidi_it.string.schars = it->end_charpos;
5304 it->bidi_it.string.bufpos = bufpos;
5305 it->bidi_it.string.from_disp_str = true;
5306 it->bidi_it.string.unibyte = !it->multibyte_p;
5307 it->bidi_it.w = it->w;
5308 bidi_init_it (0, 0, FRAME_WINDOW_P (it->f), &it->bidi_it);
5311 else if (CONSP (value) && EQ (XCAR (value), Qspace))
5313 it->method = GET_FROM_STRETCH;
5314 it->object = value;
5315 *position = it->position = start_pos;
5316 retval = 1 + (it->area == TEXT_AREA);
5318 else if (valid_xwidget_spec_p (value))
5320 it->what = IT_XWIDGET;
5321 it->method = GET_FROM_XWIDGET;
5322 it->position = start_pos;
5323 it->object = NILP (object) ? it->w->contents : object;
5324 *position = start_pos;
5325 it->xwidget = lookup_xwidget (value);
5327 #ifdef HAVE_WINDOW_SYSTEM
5328 else
5330 it->what = IT_IMAGE;
5331 it->image_id = lookup_image (it->f, value);
5332 it->position = start_pos;
5333 it->object = NILP (object) ? it->w->contents : object;
5334 it->method = GET_FROM_IMAGE;
5336 /* Say that we haven't consumed the characters with
5337 `display' property yet. The call to pop_it in
5338 set_iterator_to_next will clean this up. */
5339 *position = start_pos;
5341 #endif /* HAVE_WINDOW_SYSTEM */
5343 return retval;
5346 /* Invalid property or property not supported. Restore
5347 POSITION to what it was before. */
5348 *position = start_pos;
5349 return 0;
5352 /* Check if PROP is a display property value whose text should be
5353 treated as intangible. OVERLAY is the overlay from which PROP
5354 came, or nil if it came from a text property. CHARPOS and BYTEPOS
5355 specify the buffer position covered by PROP. */
5357 bool
5358 display_prop_intangible_p (Lisp_Object prop, Lisp_Object overlay,
5359 ptrdiff_t charpos, ptrdiff_t bytepos)
5361 bool frame_window_p = FRAME_WINDOW_P (XFRAME (selected_frame));
5362 struct text_pos position;
5364 SET_TEXT_POS (position, charpos, bytepos);
5365 return (handle_display_spec (NULL, prop, Qnil, overlay,
5366 &position, charpos, frame_window_p)
5367 != 0);
5371 /* Return true if PROP is a display sub-property value containing STRING.
5373 Implementation note: this and the following function are really
5374 special cases of handle_display_spec and
5375 handle_single_display_spec, and should ideally use the same code.
5376 Until they do, these two pairs must be consistent and must be
5377 modified in sync. */
5379 static bool
5380 single_display_spec_string_p (Lisp_Object prop, Lisp_Object string)
5382 if (EQ (string, prop))
5383 return true;
5385 /* Skip over `when FORM'. */
5386 if (CONSP (prop) && EQ (XCAR (prop), Qwhen))
5388 prop = XCDR (prop);
5389 if (!CONSP (prop))
5390 return false;
5391 /* Actually, the condition following `when' should be eval'ed,
5392 like handle_single_display_spec does, and we should return
5393 false if it evaluates to nil. However, this function is
5394 called only when the buffer was already displayed and some
5395 glyph in the glyph matrix was found to come from a display
5396 string. Therefore, the condition was already evaluated, and
5397 the result was non-nil, otherwise the display string wouldn't
5398 have been displayed and we would have never been called for
5399 this property. Thus, we can skip the evaluation and assume
5400 its result is non-nil. */
5401 prop = XCDR (prop);
5404 if (CONSP (prop))
5405 /* Skip over `margin LOCATION'. */
5406 if (EQ (XCAR (prop), Qmargin))
5408 prop = XCDR (prop);
5409 if (!CONSP (prop))
5410 return false;
5412 prop = XCDR (prop);
5413 if (!CONSP (prop))
5414 return false;
5417 return EQ (prop, string) || (CONSP (prop) && EQ (XCAR (prop), string));
5421 /* Return true if STRING appears in the `display' property PROP. */
5423 static bool
5424 display_prop_string_p (Lisp_Object prop, Lisp_Object string)
5426 if (CONSP (prop)
5427 && !EQ (XCAR (prop), Qwhen)
5428 && !(CONSP (XCAR (prop)) && EQ (Qmargin, XCAR (XCAR (prop)))))
5430 /* A list of sub-properties. */
5431 while (CONSP (prop))
5433 if (single_display_spec_string_p (XCAR (prop), string))
5434 return true;
5435 prop = XCDR (prop);
5438 else if (VECTORP (prop))
5440 /* A vector of sub-properties. */
5441 ptrdiff_t i;
5442 for (i = 0; i < ASIZE (prop); ++i)
5443 if (single_display_spec_string_p (AREF (prop, i), string))
5444 return true;
5446 else
5447 return single_display_spec_string_p (prop, string);
5449 return false;
5452 /* Look for STRING in overlays and text properties in the current
5453 buffer, between character positions FROM and TO (excluding TO).
5454 BACK_P means look back (in this case, TO is supposed to be
5455 less than FROM).
5456 Value is the first character position where STRING was found, or
5457 zero if it wasn't found before hitting TO.
5459 This function may only use code that doesn't eval because it is
5460 called asynchronously from note_mouse_highlight. */
5462 static ptrdiff_t
5463 string_buffer_position_lim (Lisp_Object string,
5464 ptrdiff_t from, ptrdiff_t to, bool back_p)
5466 Lisp_Object limit, prop, pos;
5467 bool found = false;
5469 pos = make_number (max (from, BEGV));
5471 if (!back_p) /* looking forward */
5473 limit = make_number (min (to, ZV));
5474 while (!found && !EQ (pos, limit))
5476 prop = Fget_char_property (pos, Qdisplay, Qnil);
5477 if (!NILP (prop) && display_prop_string_p (prop, string))
5478 found = true;
5479 else
5480 pos = Fnext_single_char_property_change (pos, Qdisplay, Qnil,
5481 limit);
5484 else /* looking back */
5486 limit = make_number (max (to, BEGV));
5487 while (!found && !EQ (pos, limit))
5489 prop = Fget_char_property (pos, Qdisplay, Qnil);
5490 if (!NILP (prop) && display_prop_string_p (prop, string))
5491 found = true;
5492 else
5493 pos = Fprevious_single_char_property_change (pos, Qdisplay, Qnil,
5494 limit);
5498 return found ? XINT (pos) : 0;
5501 /* Determine which buffer position in current buffer STRING comes from.
5502 AROUND_CHARPOS is an approximate position where it could come from.
5503 Value is the buffer position or 0 if it couldn't be determined.
5505 This function is necessary because we don't record buffer positions
5506 in glyphs generated from strings (to keep struct glyph small).
5507 This function may only use code that doesn't eval because it is
5508 called asynchronously from note_mouse_highlight. */
5510 static ptrdiff_t
5511 string_buffer_position (Lisp_Object string, ptrdiff_t around_charpos)
5513 const int MAX_DISTANCE = 1000;
5514 ptrdiff_t found = string_buffer_position_lim (string, around_charpos,
5515 around_charpos + MAX_DISTANCE,
5516 false);
5518 if (!found)
5519 found = string_buffer_position_lim (string, around_charpos,
5520 around_charpos - MAX_DISTANCE, true);
5521 return found;
5526 /***********************************************************************
5527 `composition' property
5528 ***********************************************************************/
5530 /* Set up iterator IT from `composition' property at its current
5531 position. Called from handle_stop. */
5533 static enum prop_handled
5534 handle_composition_prop (struct it *it)
5536 Lisp_Object prop, string;
5537 ptrdiff_t pos, pos_byte, start, end;
5539 if (STRINGP (it->string))
5541 unsigned char *s;
5543 pos = IT_STRING_CHARPOS (*it);
5544 pos_byte = IT_STRING_BYTEPOS (*it);
5545 string = it->string;
5546 s = SDATA (string) + pos_byte;
5547 it->c = STRING_CHAR (s);
5549 else
5551 pos = IT_CHARPOS (*it);
5552 pos_byte = IT_BYTEPOS (*it);
5553 string = Qnil;
5554 it->c = FETCH_CHAR (pos_byte);
5557 /* If there's a valid composition and point is not inside of the
5558 composition (in the case that the composition is from the current
5559 buffer), draw a glyph composed from the composition components. */
5560 if (find_composition (pos, -1, &start, &end, &prop, string)
5561 && composition_valid_p (start, end, prop)
5562 && (STRINGP (it->string) || (PT <= start || PT >= end)))
5564 if (start < pos)
5565 /* As we can't handle this situation (perhaps font-lock added
5566 a new composition), we just return here hoping that next
5567 redisplay will detect this composition much earlier. */
5568 return HANDLED_NORMALLY;
5569 if (start != pos)
5571 if (STRINGP (it->string))
5572 pos_byte = string_char_to_byte (it->string, start);
5573 else
5574 pos_byte = CHAR_TO_BYTE (start);
5576 it->cmp_it.id = get_composition_id (start, pos_byte, end - start,
5577 prop, string);
5579 if (it->cmp_it.id >= 0)
5581 it->cmp_it.ch = -1;
5582 it->cmp_it.nchars = COMPOSITION_LENGTH (prop);
5583 it->cmp_it.nglyphs = -1;
5587 return HANDLED_NORMALLY;
5592 /***********************************************************************
5593 Overlay strings
5594 ***********************************************************************/
5596 /* The following structure is used to record overlay strings for
5597 later sorting in load_overlay_strings. */
5599 struct overlay_entry
5601 Lisp_Object overlay;
5602 Lisp_Object string;
5603 EMACS_INT priority;
5604 bool after_string_p;
5608 /* Set up iterator IT from overlay strings at its current position.
5609 Called from handle_stop. */
5611 static enum prop_handled
5612 handle_overlay_change (struct it *it)
5614 if (!STRINGP (it->string) && get_overlay_strings (it, 0))
5615 return HANDLED_RECOMPUTE_PROPS;
5616 else
5617 return HANDLED_NORMALLY;
5621 /* Set up the next overlay string for delivery by IT, if there is an
5622 overlay string to deliver. Called by set_iterator_to_next when the
5623 end of the current overlay string is reached. If there are more
5624 overlay strings to display, IT->string and
5625 IT->current.overlay_string_index are set appropriately here.
5626 Otherwise IT->string is set to nil. */
5628 static void
5629 next_overlay_string (struct it *it)
5631 ++it->current.overlay_string_index;
5632 if (it->current.overlay_string_index == it->n_overlay_strings)
5634 /* No more overlay strings. Restore IT's settings to what
5635 they were before overlay strings were processed, and
5636 continue to deliver from current_buffer. */
5638 it->ellipsis_p = it->stack[it->sp - 1].display_ellipsis_p;
5639 pop_it (it);
5640 eassert (it->sp > 0
5641 || (NILP (it->string)
5642 && it->method == GET_FROM_BUFFER
5643 && it->stop_charpos >= BEGV
5644 && it->stop_charpos <= it->end_charpos));
5645 it->current.overlay_string_index = -1;
5646 it->n_overlay_strings = 0;
5647 /* If there's an empty display string on the stack, pop the
5648 stack, to resync the bidi iterator with IT's position. Such
5649 empty strings are pushed onto the stack in
5650 get_overlay_strings_1. */
5651 if (it->sp > 0 && STRINGP (it->string) && !SCHARS (it->string))
5652 pop_it (it);
5654 /* Since we've exhausted overlay strings at this buffer
5655 position, set the flag to ignore overlays until we move to
5656 another position. (The flag will be reset in
5657 next_element_from_buffer.) But don't do that if the overlay
5658 strings were loaded at position other than the current one,
5659 which could happen if we called pop_it above, or if the
5660 overlay strings were loaded by handle_invisible_prop at the
5661 beginning of invisible text. */
5662 if (it->overlay_strings_charpos == IT_CHARPOS (*it))
5663 it->ignore_overlay_strings_at_pos_p = true;
5665 /* If we're at the end of the buffer, record that we have
5666 processed the overlay strings there already, so that
5667 next_element_from_buffer doesn't try it again. */
5668 if (NILP (it->string)
5669 && IT_CHARPOS (*it) >= it->end_charpos
5670 && it->overlay_strings_charpos >= it->end_charpos)
5671 it->overlay_strings_at_end_processed_p = true;
5672 /* Note: we reset overlay_strings_charpos only here, to make
5673 sure the just-processed overlays were indeed at EOB.
5674 Otherwise, overlays on text with invisible text property,
5675 which are processed with IT's position past the invisible
5676 text, might fool us into thinking the overlays at EOB were
5677 already processed (linum-mode can cause this, for
5678 example). */
5679 it->overlay_strings_charpos = -1;
5681 else
5683 /* There are more overlay strings to process. If
5684 IT->current.overlay_string_index has advanced to a position
5685 where we must load IT->overlay_strings with more strings, do
5686 it. We must load at the IT->overlay_strings_charpos where
5687 IT->n_overlay_strings was originally computed; when invisible
5688 text is present, this might not be IT_CHARPOS (Bug#7016). */
5689 int i = it->current.overlay_string_index % OVERLAY_STRING_CHUNK_SIZE;
5691 if (it->current.overlay_string_index && i == 0)
5692 load_overlay_strings (it, it->overlay_strings_charpos);
5694 /* Initialize IT to deliver display elements from the overlay
5695 string. */
5696 it->string = it->overlay_strings[i];
5697 it->multibyte_p = STRING_MULTIBYTE (it->string);
5698 SET_TEXT_POS (it->current.string_pos, 0, 0);
5699 it->method = GET_FROM_STRING;
5700 it->stop_charpos = 0;
5701 it->end_charpos = SCHARS (it->string);
5702 if (it->cmp_it.stop_pos >= 0)
5703 it->cmp_it.stop_pos = 0;
5704 it->prev_stop = 0;
5705 it->base_level_stop = 0;
5707 /* Set up the bidi iterator for this overlay string. */
5708 if (it->bidi_p)
5710 it->bidi_it.string.lstring = it->string;
5711 it->bidi_it.string.s = NULL;
5712 it->bidi_it.string.schars = SCHARS (it->string);
5713 it->bidi_it.string.bufpos = it->overlay_strings_charpos;
5714 it->bidi_it.string.from_disp_str = it->string_from_display_prop_p;
5715 it->bidi_it.string.unibyte = !it->multibyte_p;
5716 it->bidi_it.w = it->w;
5717 bidi_init_it (0, 0, FRAME_WINDOW_P (it->f), &it->bidi_it);
5721 CHECK_IT (it);
5725 /* Compare two overlay_entry structures E1 and E2. Used as a
5726 comparison function for qsort in load_overlay_strings. Overlay
5727 strings for the same position are sorted so that
5729 1. All after-strings come in front of before-strings, except
5730 when they come from the same overlay.
5732 2. Within after-strings, strings are sorted so that overlay strings
5733 from overlays with higher priorities come first.
5735 2. Within before-strings, strings are sorted so that overlay
5736 strings from overlays with higher priorities come last.
5738 Value is analogous to strcmp. */
5741 static int
5742 compare_overlay_entries (const void *e1, const void *e2)
5744 struct overlay_entry const *entry1 = e1;
5745 struct overlay_entry const *entry2 = e2;
5746 int result;
5748 if (entry1->after_string_p != entry2->after_string_p)
5750 /* Let after-strings appear in front of before-strings if
5751 they come from different overlays. */
5752 if (EQ (entry1->overlay, entry2->overlay))
5753 result = entry1->after_string_p ? 1 : -1;
5754 else
5755 result = entry1->after_string_p ? -1 : 1;
5757 else if (entry1->priority != entry2->priority)
5759 if (entry1->after_string_p)
5760 /* After-strings sorted in order of decreasing priority. */
5761 result = entry2->priority < entry1->priority ? -1 : 1;
5762 else
5763 /* Before-strings sorted in order of increasing priority. */
5764 result = entry1->priority < entry2->priority ? -1 : 1;
5766 else
5767 result = 0;
5769 return result;
5773 /* Load the vector IT->overlay_strings with overlay strings from IT's
5774 current buffer position, or from CHARPOS if that is > 0. Set
5775 IT->n_overlays to the total number of overlay strings found.
5777 Overlay strings are processed OVERLAY_STRING_CHUNK_SIZE strings at
5778 a time. On entry into load_overlay_strings,
5779 IT->current.overlay_string_index gives the number of overlay
5780 strings that have already been loaded by previous calls to this
5781 function.
5783 IT->add_overlay_start contains an additional overlay start
5784 position to consider for taking overlay strings from, if non-zero.
5785 This position comes into play when the overlay has an `invisible'
5786 property, and both before and after-strings. When we've skipped to
5787 the end of the overlay, because of its `invisible' property, we
5788 nevertheless want its before-string to appear.
5789 IT->add_overlay_start will contain the overlay start position
5790 in this case.
5792 Overlay strings are sorted so that after-string strings come in
5793 front of before-string strings. Within before and after-strings,
5794 strings are sorted by overlay priority. See also function
5795 compare_overlay_entries. */
5797 static void
5798 load_overlay_strings (struct it *it, ptrdiff_t charpos)
5800 Lisp_Object overlay, window, str, invisible;
5801 struct Lisp_Overlay *ov;
5802 ptrdiff_t start, end;
5803 ptrdiff_t n = 0, i, j;
5804 int invis;
5805 struct overlay_entry entriesbuf[20];
5806 ptrdiff_t size = ARRAYELTS (entriesbuf);
5807 struct overlay_entry *entries = entriesbuf;
5808 USE_SAFE_ALLOCA;
5810 if (charpos <= 0)
5811 charpos = IT_CHARPOS (*it);
5813 /* Append the overlay string STRING of overlay OVERLAY to vector
5814 `entries' which has size `size' and currently contains `n'
5815 elements. AFTER_P means STRING is an after-string of
5816 OVERLAY. */
5817 #define RECORD_OVERLAY_STRING(OVERLAY, STRING, AFTER_P) \
5818 do \
5820 Lisp_Object priority; \
5822 if (n == size) \
5824 struct overlay_entry *old = entries; \
5825 SAFE_NALLOCA (entries, 2, size); \
5826 memcpy (entries, old, size * sizeof *entries); \
5827 size *= 2; \
5830 entries[n].string = (STRING); \
5831 entries[n].overlay = (OVERLAY); \
5832 priority = Foverlay_get ((OVERLAY), Qpriority); \
5833 entries[n].priority = INTEGERP (priority) ? XINT (priority) : 0; \
5834 entries[n].after_string_p = (AFTER_P); \
5835 ++n; \
5837 while (false)
5839 /* Process overlay before the overlay center. */
5840 for (ov = current_buffer->overlays_before; ov; ov = ov->next)
5842 XSETMISC (overlay, ov);
5843 eassert (OVERLAYP (overlay));
5844 start = OVERLAY_POSITION (OVERLAY_START (overlay));
5845 end = OVERLAY_POSITION (OVERLAY_END (overlay));
5847 if (end < charpos)
5848 break;
5850 /* Skip this overlay if it doesn't start or end at IT's current
5851 position. */
5852 if (end != charpos && start != charpos)
5853 continue;
5855 /* Skip this overlay if it doesn't apply to IT->w. */
5856 window = Foverlay_get (overlay, Qwindow);
5857 if (WINDOWP (window) && XWINDOW (window) != it->w)
5858 continue;
5860 /* If the text ``under'' the overlay is invisible, both before-
5861 and after-strings from this overlay are visible; start and
5862 end position are indistinguishable. */
5863 invisible = Foverlay_get (overlay, Qinvisible);
5864 invis = TEXT_PROP_MEANS_INVISIBLE (invisible);
5866 /* If overlay has a non-empty before-string, record it. */
5867 if ((start == charpos || (end == charpos && invis != 0))
5868 && (str = Foverlay_get (overlay, Qbefore_string), STRINGP (str))
5869 && SCHARS (str))
5870 RECORD_OVERLAY_STRING (overlay, str, false);
5872 /* If overlay has a non-empty after-string, record it. */
5873 if ((end == charpos || (start == charpos && invis != 0))
5874 && (str = Foverlay_get (overlay, Qafter_string), STRINGP (str))
5875 && SCHARS (str))
5876 RECORD_OVERLAY_STRING (overlay, str, true);
5879 /* Process overlays after the overlay center. */
5880 for (ov = current_buffer->overlays_after; ov; ov = ov->next)
5882 XSETMISC (overlay, ov);
5883 eassert (OVERLAYP (overlay));
5884 start = OVERLAY_POSITION (OVERLAY_START (overlay));
5885 end = OVERLAY_POSITION (OVERLAY_END (overlay));
5887 if (start > charpos)
5888 break;
5890 /* Skip this overlay if it doesn't start or end at IT's current
5891 position. */
5892 if (end != charpos && start != charpos)
5893 continue;
5895 /* Skip this overlay if it doesn't apply to IT->w. */
5896 window = Foverlay_get (overlay, Qwindow);
5897 if (WINDOWP (window) && XWINDOW (window) != it->w)
5898 continue;
5900 /* If the text ``under'' the overlay is invisible, it has a zero
5901 dimension, and both before- and after-strings apply. */
5902 invisible = Foverlay_get (overlay, Qinvisible);
5903 invis = TEXT_PROP_MEANS_INVISIBLE (invisible);
5905 /* If overlay has a non-empty before-string, record it. */
5906 if ((start == charpos || (end == charpos && invis != 0))
5907 && (str = Foverlay_get (overlay, Qbefore_string), STRINGP (str))
5908 && SCHARS (str))
5909 RECORD_OVERLAY_STRING (overlay, str, false);
5911 /* If overlay has a non-empty after-string, record it. */
5912 if ((end == charpos || (start == charpos && invis != 0))
5913 && (str = Foverlay_get (overlay, Qafter_string), STRINGP (str))
5914 && SCHARS (str))
5915 RECORD_OVERLAY_STRING (overlay, str, true);
5918 #undef RECORD_OVERLAY_STRING
5920 /* Sort entries. */
5921 if (n > 1)
5922 qsort (entries, n, sizeof *entries, compare_overlay_entries);
5924 /* Record number of overlay strings, and where we computed it. */
5925 it->n_overlay_strings = n;
5926 it->overlay_strings_charpos = charpos;
5928 /* IT->current.overlay_string_index is the number of overlay strings
5929 that have already been consumed by IT. Copy some of the
5930 remaining overlay strings to IT->overlay_strings. */
5931 i = 0;
5932 j = it->current.overlay_string_index;
5933 while (i < OVERLAY_STRING_CHUNK_SIZE && j < n)
5935 it->overlay_strings[i] = entries[j].string;
5936 it->string_overlays[i++] = entries[j++].overlay;
5939 CHECK_IT (it);
5940 SAFE_FREE ();
5944 /* Get the first chunk of overlay strings at IT's current buffer
5945 position, or at CHARPOS if that is > 0. Value is true if at
5946 least one overlay string was found. */
5948 static bool
5949 get_overlay_strings_1 (struct it *it, ptrdiff_t charpos, bool compute_stop_p)
5951 /* Get the first OVERLAY_STRING_CHUNK_SIZE overlay strings to
5952 process. This fills IT->overlay_strings with strings, and sets
5953 IT->n_overlay_strings to the total number of strings to process.
5954 IT->pos.overlay_string_index has to be set temporarily to zero
5955 because load_overlay_strings needs this; it must be set to -1
5956 when no overlay strings are found because a zero value would
5957 indicate a position in the first overlay string. */
5958 it->current.overlay_string_index = 0;
5959 load_overlay_strings (it, charpos);
5961 /* If we found overlay strings, set up IT to deliver display
5962 elements from the first one. Otherwise set up IT to deliver
5963 from current_buffer. */
5964 if (it->n_overlay_strings)
5966 /* Make sure we know settings in current_buffer, so that we can
5967 restore meaningful values when we're done with the overlay
5968 strings. */
5969 if (compute_stop_p)
5970 compute_stop_pos (it);
5971 eassert (it->face_id >= 0);
5973 /* Save IT's settings. They are restored after all overlay
5974 strings have been processed. */
5975 eassert (!compute_stop_p || it->sp == 0);
5977 /* When called from handle_stop, there might be an empty display
5978 string loaded. In that case, don't bother saving it. But
5979 don't use this optimization with the bidi iterator, since we
5980 need the corresponding pop_it call to resync the bidi
5981 iterator's position with IT's position, after we are done
5982 with the overlay strings. (The corresponding call to pop_it
5983 in case of an empty display string is in
5984 next_overlay_string.) */
5985 if (!(!it->bidi_p
5986 && STRINGP (it->string) && !SCHARS (it->string)))
5987 push_it (it, NULL);
5989 /* Set up IT to deliver display elements from the first overlay
5990 string. */
5991 IT_STRING_CHARPOS (*it) = IT_STRING_BYTEPOS (*it) = 0;
5992 it->string = it->overlay_strings[0];
5993 it->from_overlay = Qnil;
5994 it->stop_charpos = 0;
5995 eassert (STRINGP (it->string));
5996 it->end_charpos = SCHARS (it->string);
5997 it->prev_stop = 0;
5998 it->base_level_stop = 0;
5999 it->multibyte_p = STRING_MULTIBYTE (it->string);
6000 it->method = GET_FROM_STRING;
6001 it->from_disp_prop_p = 0;
6002 it->cmp_it.id = -1;
6004 /* Force paragraph direction to be that of the parent
6005 buffer. */
6006 if (it->bidi_p && it->bidi_it.paragraph_dir == R2L)
6007 it->paragraph_embedding = it->bidi_it.paragraph_dir;
6008 else
6009 it->paragraph_embedding = L2R;
6011 /* Set up the bidi iterator for this overlay string. */
6012 if (it->bidi_p)
6014 ptrdiff_t pos = (charpos > 0 ? charpos : IT_CHARPOS (*it));
6016 it->bidi_it.string.lstring = it->string;
6017 it->bidi_it.string.s = NULL;
6018 it->bidi_it.string.schars = SCHARS (it->string);
6019 it->bidi_it.string.bufpos = pos;
6020 it->bidi_it.string.from_disp_str = it->string_from_display_prop_p;
6021 it->bidi_it.string.unibyte = !it->multibyte_p;
6022 it->bidi_it.w = it->w;
6023 bidi_init_it (0, 0, FRAME_WINDOW_P (it->f), &it->bidi_it);
6025 return true;
6028 it->current.overlay_string_index = -1;
6029 return false;
6032 static bool
6033 get_overlay_strings (struct it *it, ptrdiff_t charpos)
6035 it->string = Qnil;
6036 it->method = GET_FROM_BUFFER;
6038 get_overlay_strings_1 (it, charpos, true);
6040 CHECK_IT (it);
6042 /* Value is true if we found at least one overlay string. */
6043 return STRINGP (it->string);
6048 /***********************************************************************
6049 Saving and restoring state
6050 ***********************************************************************/
6052 /* Save current settings of IT on IT->stack. Called, for example,
6053 before setting up IT for an overlay string, to be able to restore
6054 IT's settings to what they were after the overlay string has been
6055 processed. If POSITION is non-NULL, it is the position to save on
6056 the stack instead of IT->position. */
6058 static void
6059 push_it (struct it *it, struct text_pos *position)
6061 struct iterator_stack_entry *p;
6063 eassert (it->sp < IT_STACK_SIZE);
6064 p = it->stack + it->sp;
6066 p->stop_charpos = it->stop_charpos;
6067 p->prev_stop = it->prev_stop;
6068 p->base_level_stop = it->base_level_stop;
6069 p->cmp_it = it->cmp_it;
6070 eassert (it->face_id >= 0);
6071 p->face_id = it->face_id;
6072 p->string = it->string;
6073 p->method = it->method;
6074 p->from_overlay = it->from_overlay;
6075 switch (p->method)
6077 case GET_FROM_IMAGE:
6078 p->u.image.object = it->object;
6079 p->u.image.image_id = it->image_id;
6080 p->u.image.slice = it->slice;
6081 break;
6082 case GET_FROM_STRETCH:
6083 p->u.stretch.object = it->object;
6084 break;
6085 case GET_FROM_XWIDGET:
6086 p->u.xwidget.object = it->object;
6087 break;
6088 case GET_FROM_BUFFER:
6089 case GET_FROM_DISPLAY_VECTOR:
6090 case GET_FROM_STRING:
6091 case GET_FROM_C_STRING:
6092 break;
6093 default:
6094 emacs_abort ();
6096 p->position = position ? *position : it->position;
6097 p->current = it->current;
6098 p->end_charpos = it->end_charpos;
6099 p->string_nchars = it->string_nchars;
6100 p->area = it->area;
6101 p->multibyte_p = it->multibyte_p;
6102 p->avoid_cursor_p = it->avoid_cursor_p;
6103 p->space_width = it->space_width;
6104 p->font_height = it->font_height;
6105 p->voffset = it->voffset;
6106 p->string_from_display_prop_p = it->string_from_display_prop_p;
6107 p->string_from_prefix_prop_p = it->string_from_prefix_prop_p;
6108 p->display_ellipsis_p = false;
6109 p->line_wrap = it->line_wrap;
6110 p->bidi_p = it->bidi_p;
6111 p->paragraph_embedding = it->paragraph_embedding;
6112 p->from_disp_prop_p = it->from_disp_prop_p;
6113 ++it->sp;
6115 /* Save the state of the bidi iterator as well. */
6116 if (it->bidi_p)
6117 bidi_push_it (&it->bidi_it);
6120 static void
6121 iterate_out_of_display_property (struct it *it)
6123 bool buffer_p = !STRINGP (it->string);
6124 ptrdiff_t eob = (buffer_p ? ZV : it->end_charpos);
6125 ptrdiff_t bob = (buffer_p ? BEGV : 0);
6127 eassert (eob >= CHARPOS (it->position) && CHARPOS (it->position) >= bob);
6129 /* Maybe initialize paragraph direction. If we are at the beginning
6130 of a new paragraph, next_element_from_buffer may not have a
6131 chance to do that. */
6132 if (it->bidi_it.first_elt && it->bidi_it.charpos < eob)
6133 bidi_paragraph_init (it->paragraph_embedding, &it->bidi_it, true);
6134 /* prev_stop can be zero, so check against BEGV as well. */
6135 while (it->bidi_it.charpos >= bob
6136 && it->prev_stop <= it->bidi_it.charpos
6137 && it->bidi_it.charpos < CHARPOS (it->position)
6138 && it->bidi_it.charpos < eob)
6139 bidi_move_to_visually_next (&it->bidi_it);
6140 /* Record the stop_pos we just crossed, for when we cross it
6141 back, maybe. */
6142 if (it->bidi_it.charpos > CHARPOS (it->position))
6143 it->prev_stop = CHARPOS (it->position);
6144 /* If we ended up not where pop_it put us, resync IT's
6145 positional members with the bidi iterator. */
6146 if (it->bidi_it.charpos != CHARPOS (it->position))
6147 SET_TEXT_POS (it->position, it->bidi_it.charpos, it->bidi_it.bytepos);
6148 if (buffer_p)
6149 it->current.pos = it->position;
6150 else
6151 it->current.string_pos = it->position;
6154 /* Restore IT's settings from IT->stack. Called, for example, when no
6155 more overlay strings must be processed, and we return to delivering
6156 display elements from a buffer, or when the end of a string from a
6157 `display' property is reached and we return to delivering display
6158 elements from an overlay string, or from a buffer. */
6160 static void
6161 pop_it (struct it *it)
6163 struct iterator_stack_entry *p;
6164 bool from_display_prop = it->from_disp_prop_p;
6165 ptrdiff_t prev_pos = IT_CHARPOS (*it);
6167 eassert (it->sp > 0);
6168 --it->sp;
6169 p = it->stack + it->sp;
6170 it->stop_charpos = p->stop_charpos;
6171 it->prev_stop = p->prev_stop;
6172 it->base_level_stop = p->base_level_stop;
6173 it->cmp_it = p->cmp_it;
6174 it->face_id = p->face_id;
6175 it->current = p->current;
6176 it->position = p->position;
6177 it->string = p->string;
6178 it->from_overlay = p->from_overlay;
6179 if (NILP (it->string))
6180 SET_TEXT_POS (it->current.string_pos, -1, -1);
6181 it->method = p->method;
6182 switch (it->method)
6184 case GET_FROM_IMAGE:
6185 it->image_id = p->u.image.image_id;
6186 it->object = p->u.image.object;
6187 it->slice = p->u.image.slice;
6188 break;
6189 case GET_FROM_XWIDGET:
6190 it->object = p->u.xwidget.object;
6191 break;
6192 case GET_FROM_STRETCH:
6193 it->object = p->u.stretch.object;
6194 break;
6195 case GET_FROM_BUFFER:
6196 it->object = it->w->contents;
6197 break;
6198 case GET_FROM_STRING:
6200 struct face *face = FACE_FROM_ID_OR_NULL (it->f, it->face_id);
6202 /* Restore the face_box_p flag, since it could have been
6203 overwritten by the face of the object that we just finished
6204 displaying. */
6205 if (face)
6206 it->face_box_p = face->box != FACE_NO_BOX;
6207 it->object = it->string;
6209 break;
6210 case GET_FROM_DISPLAY_VECTOR:
6211 if (it->s)
6212 it->method = GET_FROM_C_STRING;
6213 else if (STRINGP (it->string))
6214 it->method = GET_FROM_STRING;
6215 else
6217 it->method = GET_FROM_BUFFER;
6218 it->object = it->w->contents;
6220 break;
6221 case GET_FROM_C_STRING:
6222 break;
6223 default:
6224 emacs_abort ();
6226 it->end_charpos = p->end_charpos;
6227 it->string_nchars = p->string_nchars;
6228 it->area = p->area;
6229 it->multibyte_p = p->multibyte_p;
6230 it->avoid_cursor_p = p->avoid_cursor_p;
6231 it->space_width = p->space_width;
6232 it->font_height = p->font_height;
6233 it->voffset = p->voffset;
6234 it->string_from_display_prop_p = p->string_from_display_prop_p;
6235 it->string_from_prefix_prop_p = p->string_from_prefix_prop_p;
6236 it->line_wrap = p->line_wrap;
6237 it->bidi_p = p->bidi_p;
6238 it->paragraph_embedding = p->paragraph_embedding;
6239 it->from_disp_prop_p = p->from_disp_prop_p;
6240 if (it->bidi_p)
6242 bidi_pop_it (&it->bidi_it);
6243 /* Bidi-iterate until we get out of the portion of text, if any,
6244 covered by a `display' text property or by an overlay with
6245 `display' property. (We cannot just jump there, because the
6246 internal coherency of the bidi iterator state can not be
6247 preserved across such jumps.) We also must determine the
6248 paragraph base direction if the overlay we just processed is
6249 at the beginning of a new paragraph. */
6250 if (from_display_prop
6251 && (it->method == GET_FROM_BUFFER || it->method == GET_FROM_STRING))
6252 iterate_out_of_display_property (it);
6254 eassert ((BUFFERP (it->object)
6255 && IT_CHARPOS (*it) == it->bidi_it.charpos
6256 && IT_BYTEPOS (*it) == it->bidi_it.bytepos)
6257 || (STRINGP (it->object)
6258 && IT_STRING_CHARPOS (*it) == it->bidi_it.charpos
6259 && IT_STRING_BYTEPOS (*it) == it->bidi_it.bytepos)
6260 || (CONSP (it->object) && it->method == GET_FROM_STRETCH));
6262 /* If we move the iterator over text covered by a display property
6263 to a new buffer position, any info about previously seen overlays
6264 is no longer valid. */
6265 if (from_display_prop && it->sp == 0 && CHARPOS (it->position) != prev_pos)
6266 it->ignore_overlay_strings_at_pos_p = false;
6271 /***********************************************************************
6272 Moving over lines
6273 ***********************************************************************/
6275 /* Set IT's current position to the previous line start. */
6277 static void
6278 back_to_previous_line_start (struct it *it)
6280 ptrdiff_t cp = IT_CHARPOS (*it), bp = IT_BYTEPOS (*it);
6282 DEC_BOTH (cp, bp);
6283 IT_CHARPOS (*it) = find_newline_no_quit (cp, bp, -1, &IT_BYTEPOS (*it));
6287 /* Move IT to the next line start.
6289 Value is true if a newline was found. Set *SKIPPED_P to true if
6290 we skipped over part of the text (as opposed to moving the iterator
6291 continuously over the text). Otherwise, don't change the value
6292 of *SKIPPED_P.
6294 If BIDI_IT_PREV is non-NULL, store into it the state of the bidi
6295 iterator on the newline, if it was found.
6297 Newlines may come from buffer text, overlay strings, or strings
6298 displayed via the `display' property. That's the reason we can't
6299 simply use find_newline_no_quit.
6301 Note that this function may not skip over invisible text that is so
6302 because of text properties and immediately follows a newline. If
6303 it would, function reseat_at_next_visible_line_start, when called
6304 from set_iterator_to_next, would effectively make invisible
6305 characters following a newline part of the wrong glyph row, which
6306 leads to wrong cursor motion. */
6308 static bool
6309 forward_to_next_line_start (struct it *it, bool *skipped_p,
6310 struct bidi_it *bidi_it_prev)
6312 ptrdiff_t old_selective;
6313 bool newline_found_p = false;
6314 int n;
6315 const int MAX_NEWLINE_DISTANCE = 500;
6317 /* If already on a newline, just consume it to avoid unintended
6318 skipping over invisible text below. */
6319 if (it->what == IT_CHARACTER
6320 && it->c == '\n'
6321 && CHARPOS (it->position) == IT_CHARPOS (*it))
6323 if (it->bidi_p && bidi_it_prev)
6324 *bidi_it_prev = it->bidi_it;
6325 set_iterator_to_next (it, false);
6326 it->c = 0;
6327 return true;
6330 /* Don't handle selective display in the following. It's (a)
6331 unnecessary because it's done by the caller, and (b) leads to an
6332 infinite recursion because next_element_from_ellipsis indirectly
6333 calls this function. */
6334 old_selective = it->selective;
6335 it->selective = 0;
6337 /* Scan for a newline within MAX_NEWLINE_DISTANCE display elements
6338 from buffer text. */
6339 for (n = 0;
6340 !newline_found_p && n < MAX_NEWLINE_DISTANCE;
6341 n += !STRINGP (it->string))
6343 if (!get_next_display_element (it))
6344 return false;
6345 newline_found_p = it->what == IT_CHARACTER && it->c == '\n';
6346 if (newline_found_p && it->bidi_p && bidi_it_prev)
6347 *bidi_it_prev = it->bidi_it;
6348 set_iterator_to_next (it, false);
6351 /* If we didn't find a newline near enough, see if we can use a
6352 short-cut. */
6353 if (!newline_found_p)
6355 ptrdiff_t bytepos, start = IT_CHARPOS (*it);
6356 ptrdiff_t limit = find_newline_no_quit (start, IT_BYTEPOS (*it),
6357 1, &bytepos);
6358 Lisp_Object pos;
6360 eassert (!STRINGP (it->string));
6362 /* If there isn't any `display' property in sight, and no
6363 overlays, we can just use the position of the newline in
6364 buffer text. */
6365 if (it->stop_charpos >= limit
6366 || ((pos = Fnext_single_property_change (make_number (start),
6367 Qdisplay, Qnil,
6368 make_number (limit)),
6369 NILP (pos))
6370 && next_overlay_change (start) == ZV))
6372 if (!it->bidi_p)
6374 IT_CHARPOS (*it) = limit;
6375 IT_BYTEPOS (*it) = bytepos;
6377 else
6379 struct bidi_it bprev;
6381 /* Help bidi.c avoid expensive searches for display
6382 properties and overlays, by telling it that there are
6383 none up to `limit'. */
6384 if (it->bidi_it.disp_pos < limit)
6386 it->bidi_it.disp_pos = limit;
6387 it->bidi_it.disp_prop = 0;
6389 do {
6390 bprev = it->bidi_it;
6391 bidi_move_to_visually_next (&it->bidi_it);
6392 } while (it->bidi_it.charpos != limit);
6393 IT_CHARPOS (*it) = limit;
6394 IT_BYTEPOS (*it) = it->bidi_it.bytepos;
6395 if (bidi_it_prev)
6396 *bidi_it_prev = bprev;
6398 *skipped_p = newline_found_p = true;
6400 else
6402 while (!newline_found_p)
6404 if (!get_next_display_element (it))
6405 break;
6406 newline_found_p = ITERATOR_AT_END_OF_LINE_P (it);
6407 if (newline_found_p && it->bidi_p && bidi_it_prev)
6408 *bidi_it_prev = it->bidi_it;
6409 set_iterator_to_next (it, false);
6414 it->selective = old_selective;
6415 return newline_found_p;
6419 /* Set IT's current position to the previous visible line start. Skip
6420 invisible text that is so either due to text properties or due to
6421 selective display. Caution: this does not change IT->current_x and
6422 IT->hpos. */
6424 static void
6425 back_to_previous_visible_line_start (struct it *it)
6427 while (IT_CHARPOS (*it) > BEGV)
6429 back_to_previous_line_start (it);
6431 if (IT_CHARPOS (*it) <= BEGV)
6432 break;
6434 /* If selective > 0, then lines indented more than its value are
6435 invisible. */
6436 if (it->selective > 0
6437 && indented_beyond_p (IT_CHARPOS (*it), IT_BYTEPOS (*it),
6438 it->selective))
6439 continue;
6441 /* Check the newline before point for invisibility. */
6443 Lisp_Object prop;
6444 prop = Fget_char_property (make_number (IT_CHARPOS (*it) - 1),
6445 Qinvisible, it->window);
6446 if (TEXT_PROP_MEANS_INVISIBLE (prop) != 0)
6447 continue;
6450 if (IT_CHARPOS (*it) <= BEGV)
6451 break;
6454 struct it it2;
6455 void *it2data = NULL;
6456 ptrdiff_t pos;
6457 ptrdiff_t beg, end;
6458 Lisp_Object val, overlay;
6460 SAVE_IT (it2, *it, it2data);
6462 /* If newline is part of a composition, continue from start of composition */
6463 if (find_composition (IT_CHARPOS (*it), -1, &beg, &end, &val, Qnil)
6464 && beg < IT_CHARPOS (*it))
6465 goto replaced;
6467 /* If newline is replaced by a display property, find start of overlay
6468 or interval and continue search from that point. */
6469 pos = --IT_CHARPOS (it2);
6470 --IT_BYTEPOS (it2);
6471 it2.sp = 0;
6472 bidi_unshelve_cache (NULL, false);
6473 it2.string_from_display_prop_p = false;
6474 it2.from_disp_prop_p = false;
6475 if (handle_display_prop (&it2) == HANDLED_RETURN
6476 && !NILP (val = get_char_property_and_overlay
6477 (make_number (pos), Qdisplay, Qnil, &overlay))
6478 && (OVERLAYP (overlay)
6479 ? (beg = OVERLAY_POSITION (OVERLAY_START (overlay)))
6480 : get_property_and_range (pos, Qdisplay, &val, &beg, &end, Qnil)))
6482 RESTORE_IT (it, it, it2data);
6483 goto replaced;
6486 /* Newline is not replaced by anything -- so we are done. */
6487 RESTORE_IT (it, it, it2data);
6488 break;
6490 replaced:
6491 if (beg < BEGV)
6492 beg = BEGV;
6493 IT_CHARPOS (*it) = beg;
6494 IT_BYTEPOS (*it) = buf_charpos_to_bytepos (current_buffer, beg);
6498 it->continuation_lines_width = 0;
6500 eassert (IT_CHARPOS (*it) >= BEGV);
6501 eassert (IT_CHARPOS (*it) == BEGV
6502 || FETCH_BYTE (IT_BYTEPOS (*it) - 1) == '\n');
6503 CHECK_IT (it);
6507 /* Reseat iterator IT at the previous visible line start. Skip
6508 invisible text that is so either due to text properties or due to
6509 selective display. At the end, update IT's overlay information,
6510 face information etc. */
6512 void
6513 reseat_at_previous_visible_line_start (struct it *it)
6515 back_to_previous_visible_line_start (it);
6516 reseat (it, it->current.pos, true);
6517 CHECK_IT (it);
6521 /* Reseat iterator IT on the next visible line start in the current
6522 buffer. ON_NEWLINE_P means position IT on the newline
6523 preceding the line start. Skip over invisible text that is so
6524 because of selective display. Compute faces, overlays etc at the
6525 new position. Note that this function does not skip over text that
6526 is invisible because of text properties. */
6528 static void
6529 reseat_at_next_visible_line_start (struct it *it, bool on_newline_p)
6531 bool skipped_p = false;
6532 struct bidi_it bidi_it_prev;
6533 bool newline_found_p
6534 = forward_to_next_line_start (it, &skipped_p, &bidi_it_prev);
6536 /* Skip over lines that are invisible because they are indented
6537 more than the value of IT->selective. */
6538 if (it->selective > 0)
6539 while (IT_CHARPOS (*it) < ZV
6540 && indented_beyond_p (IT_CHARPOS (*it), IT_BYTEPOS (*it),
6541 it->selective))
6543 eassert (IT_BYTEPOS (*it) == BEGV
6544 || FETCH_BYTE (IT_BYTEPOS (*it) - 1) == '\n');
6545 newline_found_p =
6546 forward_to_next_line_start (it, &skipped_p, &bidi_it_prev);
6549 /* Position on the newline if that's what's requested. */
6550 if (on_newline_p && newline_found_p)
6552 if (STRINGP (it->string))
6554 if (IT_STRING_CHARPOS (*it) > 0)
6556 if (!it->bidi_p)
6558 --IT_STRING_CHARPOS (*it);
6559 --IT_STRING_BYTEPOS (*it);
6561 else
6563 /* We need to restore the bidi iterator to the state
6564 it had on the newline, and resync the IT's
6565 position with that. */
6566 it->bidi_it = bidi_it_prev;
6567 IT_STRING_CHARPOS (*it) = it->bidi_it.charpos;
6568 IT_STRING_BYTEPOS (*it) = it->bidi_it.bytepos;
6572 else if (IT_CHARPOS (*it) > BEGV)
6574 if (!it->bidi_p)
6576 --IT_CHARPOS (*it);
6577 --IT_BYTEPOS (*it);
6579 else
6581 /* We need to restore the bidi iterator to the state it
6582 had on the newline and resync IT with that. */
6583 it->bidi_it = bidi_it_prev;
6584 IT_CHARPOS (*it) = it->bidi_it.charpos;
6585 IT_BYTEPOS (*it) = it->bidi_it.bytepos;
6587 reseat (it, it->current.pos, false);
6590 else if (skipped_p)
6591 reseat (it, it->current.pos, false);
6593 CHECK_IT (it);
6598 /***********************************************************************
6599 Changing an iterator's position
6600 ***********************************************************************/
6602 /* Change IT's current position to POS in current_buffer.
6603 If FORCE_P, always check for text properties at the new position.
6604 Otherwise, text properties are only looked up if POS >=
6605 IT->check_charpos of a property. */
6607 static void
6608 reseat (struct it *it, struct text_pos pos, bool force_p)
6610 ptrdiff_t original_pos = IT_CHARPOS (*it);
6612 reseat_1 (it, pos, false);
6614 /* Determine where to check text properties. Avoid doing it
6615 where possible because text property lookup is very expensive. */
6616 if (force_p
6617 || CHARPOS (pos) > it->stop_charpos
6618 || CHARPOS (pos) < original_pos)
6620 if (it->bidi_p)
6622 /* For bidi iteration, we need to prime prev_stop and
6623 base_level_stop with our best estimations. */
6624 /* Implementation note: Of course, POS is not necessarily a
6625 stop position, so assigning prev_pos to it is a lie; we
6626 should have called compute_stop_backwards. However, if
6627 the current buffer does not include any R2L characters,
6628 that call would be a waste of cycles, because the
6629 iterator will never move back, and thus never cross this
6630 "fake" stop position. So we delay that backward search
6631 until the time we really need it, in next_element_from_buffer. */
6632 if (CHARPOS (pos) != it->prev_stop)
6633 it->prev_stop = CHARPOS (pos);
6634 if (CHARPOS (pos) < it->base_level_stop)
6635 it->base_level_stop = 0; /* meaning it's unknown */
6636 handle_stop (it);
6638 else
6640 handle_stop (it);
6641 it->prev_stop = it->base_level_stop = 0;
6646 CHECK_IT (it);
6650 /* Change IT's buffer position to POS. SET_STOP_P means set
6651 IT->stop_pos to POS, also. */
6653 static void
6654 reseat_1 (struct it *it, struct text_pos pos, bool set_stop_p)
6656 /* Don't call this function when scanning a C string. */
6657 eassert (it->s == NULL);
6659 /* POS must be a reasonable value. */
6660 eassert (CHARPOS (pos) >= BEGV && CHARPOS (pos) <= ZV);
6662 it->current.pos = it->position = pos;
6663 it->end_charpos = ZV;
6664 it->dpvec = NULL;
6665 it->current.dpvec_index = -1;
6666 it->current.overlay_string_index = -1;
6667 IT_STRING_CHARPOS (*it) = -1;
6668 IT_STRING_BYTEPOS (*it) = -1;
6669 it->string = Qnil;
6670 it->method = GET_FROM_BUFFER;
6671 it->object = it->w->contents;
6672 it->area = TEXT_AREA;
6673 it->multibyte_p = !NILP (BVAR (current_buffer, enable_multibyte_characters));
6674 it->sp = 0;
6675 it->string_from_display_prop_p = false;
6676 it->string_from_prefix_prop_p = false;
6678 it->from_disp_prop_p = false;
6679 it->face_before_selective_p = false;
6680 if (it->bidi_p)
6682 bidi_init_it (IT_CHARPOS (*it), IT_BYTEPOS (*it), FRAME_WINDOW_P (it->f),
6683 &it->bidi_it);
6684 bidi_unshelve_cache (NULL, false);
6685 it->bidi_it.paragraph_dir = NEUTRAL_DIR;
6686 it->bidi_it.string.s = NULL;
6687 it->bidi_it.string.lstring = Qnil;
6688 it->bidi_it.string.bufpos = 0;
6689 it->bidi_it.string.from_disp_str = false;
6690 it->bidi_it.string.unibyte = false;
6691 it->bidi_it.w = it->w;
6694 if (set_stop_p)
6696 it->stop_charpos = CHARPOS (pos);
6697 it->base_level_stop = CHARPOS (pos);
6699 /* This make the information stored in it->cmp_it invalidate. */
6700 it->cmp_it.id = -1;
6704 /* Set up IT for displaying a string, starting at CHARPOS in window W.
6705 If S is non-null, it is a C string to iterate over. Otherwise,
6706 STRING gives a Lisp string to iterate over.
6708 If PRECISION > 0, don't return more then PRECISION number of
6709 characters from the string.
6711 If FIELD_WIDTH > 0, return padding spaces until FIELD_WIDTH
6712 characters have been returned. FIELD_WIDTH < 0 means an infinite
6713 field width.
6715 MULTIBYTE = 0 means disable processing of multibyte characters,
6716 MULTIBYTE > 0 means enable it,
6717 MULTIBYTE < 0 means use IT->multibyte_p.
6719 IT must be initialized via a prior call to init_iterator before
6720 calling this function. */
6722 static void
6723 reseat_to_string (struct it *it, const char *s, Lisp_Object string,
6724 ptrdiff_t charpos, ptrdiff_t precision, int field_width,
6725 int multibyte)
6727 /* No text property checks performed by default, but see below. */
6728 it->stop_charpos = -1;
6730 /* Set iterator position and end position. */
6731 memset (&it->current, 0, sizeof it->current);
6732 it->current.overlay_string_index = -1;
6733 it->current.dpvec_index = -1;
6734 eassert (charpos >= 0);
6736 /* If STRING is specified, use its multibyteness, otherwise use the
6737 setting of MULTIBYTE, if specified. */
6738 if (multibyte >= 0)
6739 it->multibyte_p = multibyte > 0;
6741 /* Bidirectional reordering of strings is controlled by the default
6742 value of bidi-display-reordering. Don't try to reorder while
6743 loading loadup.el, as the necessary character property tables are
6744 not yet available. */
6745 it->bidi_p =
6746 !redisplay__inhibit_bidi
6747 && !NILP (BVAR (&buffer_defaults, bidi_display_reordering));
6749 if (s == NULL)
6751 eassert (STRINGP (string));
6752 it->string = string;
6753 it->s = NULL;
6754 it->end_charpos = it->string_nchars = SCHARS (string);
6755 it->method = GET_FROM_STRING;
6756 it->current.string_pos = string_pos (charpos, string);
6758 if (it->bidi_p)
6760 it->bidi_it.string.lstring = string;
6761 it->bidi_it.string.s = NULL;
6762 it->bidi_it.string.schars = it->end_charpos;
6763 it->bidi_it.string.bufpos = 0;
6764 it->bidi_it.string.from_disp_str = false;
6765 it->bidi_it.string.unibyte = !it->multibyte_p;
6766 it->bidi_it.w = it->w;
6767 bidi_init_it (charpos, IT_STRING_BYTEPOS (*it),
6768 FRAME_WINDOW_P (it->f), &it->bidi_it);
6771 else
6773 it->s = (const unsigned char *) s;
6774 it->string = Qnil;
6776 /* Note that we use IT->current.pos, not it->current.string_pos,
6777 for displaying C strings. */
6778 IT_STRING_CHARPOS (*it) = IT_STRING_BYTEPOS (*it) = -1;
6779 if (it->multibyte_p)
6781 it->current.pos = c_string_pos (charpos, s, true);
6782 it->end_charpos = it->string_nchars = number_of_chars (s, true);
6784 else
6786 IT_CHARPOS (*it) = IT_BYTEPOS (*it) = charpos;
6787 it->end_charpos = it->string_nchars = strlen (s);
6790 if (it->bidi_p)
6792 it->bidi_it.string.lstring = Qnil;
6793 it->bidi_it.string.s = (const unsigned char *) s;
6794 it->bidi_it.string.schars = it->end_charpos;
6795 it->bidi_it.string.bufpos = 0;
6796 it->bidi_it.string.from_disp_str = false;
6797 it->bidi_it.string.unibyte = !it->multibyte_p;
6798 it->bidi_it.w = it->w;
6799 bidi_init_it (charpos, IT_BYTEPOS (*it), FRAME_WINDOW_P (it->f),
6800 &it->bidi_it);
6802 it->method = GET_FROM_C_STRING;
6805 /* PRECISION > 0 means don't return more than PRECISION characters
6806 from the string. */
6807 if (precision > 0 && it->end_charpos - charpos > precision)
6809 it->end_charpos = it->string_nchars = charpos + precision;
6810 if (it->bidi_p)
6811 it->bidi_it.string.schars = it->end_charpos;
6814 /* FIELD_WIDTH > 0 means pad with spaces until FIELD_WIDTH
6815 characters have been returned. FIELD_WIDTH == 0 means don't pad,
6816 FIELD_WIDTH < 0 means infinite field width. This is useful for
6817 padding with `-' at the end of a mode line. */
6818 if (field_width < 0)
6819 field_width = DISP_INFINITY;
6820 /* Implementation note: We deliberately don't enlarge
6821 it->bidi_it.string.schars here to fit it->end_charpos, because
6822 the bidi iterator cannot produce characters out of thin air. */
6823 if (field_width > it->end_charpos - charpos)
6824 it->end_charpos = charpos + field_width;
6826 /* Use the standard display table for displaying strings. */
6827 if (DISP_TABLE_P (Vstandard_display_table))
6828 it->dp = XCHAR_TABLE (Vstandard_display_table);
6830 it->stop_charpos = charpos;
6831 it->prev_stop = charpos;
6832 it->base_level_stop = 0;
6833 if (it->bidi_p)
6835 it->bidi_it.first_elt = true;
6836 it->bidi_it.paragraph_dir = NEUTRAL_DIR;
6837 it->bidi_it.disp_pos = -1;
6839 if (s == NULL && it->multibyte_p)
6841 ptrdiff_t endpos = SCHARS (it->string);
6842 if (endpos > it->end_charpos)
6843 endpos = it->end_charpos;
6844 composition_compute_stop_pos (&it->cmp_it, charpos, -1, endpos,
6845 it->string);
6847 CHECK_IT (it);
6852 /***********************************************************************
6853 Iteration
6854 ***********************************************************************/
6856 /* Map enum it_method value to corresponding next_element_from_* function. */
6858 typedef bool (*next_element_function) (struct it *);
6860 static next_element_function const get_next_element[NUM_IT_METHODS] =
6862 next_element_from_buffer,
6863 next_element_from_display_vector,
6864 next_element_from_string,
6865 next_element_from_c_string,
6866 next_element_from_image,
6867 next_element_from_stretch,
6868 next_element_from_xwidget,
6871 #define GET_NEXT_DISPLAY_ELEMENT(it) (*get_next_element[(it)->method]) (it)
6874 /* Return true iff a character at CHARPOS (and BYTEPOS) is composed
6875 (possibly with the following characters). */
6877 #define CHAR_COMPOSED_P(IT,CHARPOS,BYTEPOS,END_CHARPOS) \
6878 ((IT)->cmp_it.id >= 0 \
6879 || ((IT)->cmp_it.stop_pos == (CHARPOS) \
6880 && composition_reseat_it (&(IT)->cmp_it, CHARPOS, BYTEPOS, \
6881 END_CHARPOS, (IT)->w, \
6882 FACE_FROM_ID_OR_NULL ((IT)->f, \
6883 (IT)->face_id), \
6884 (IT)->string)))
6887 /* Lookup the char-table Vglyphless_char_display for character C (-1
6888 if we want information for no-font case), and return the display
6889 method symbol. By side-effect, update it->what and
6890 it->glyphless_method. This function is called from
6891 get_next_display_element for each character element, and from
6892 x_produce_glyphs when no suitable font was found. */
6894 Lisp_Object
6895 lookup_glyphless_char_display (int c, struct it *it)
6897 Lisp_Object glyphless_method = Qnil;
6899 if (CHAR_TABLE_P (Vglyphless_char_display)
6900 && CHAR_TABLE_EXTRA_SLOTS (XCHAR_TABLE (Vglyphless_char_display)) >= 1)
6902 if (c >= 0)
6904 glyphless_method = CHAR_TABLE_REF (Vglyphless_char_display, c);
6905 if (CONSP (glyphless_method))
6906 glyphless_method = FRAME_WINDOW_P (it->f)
6907 ? XCAR (glyphless_method)
6908 : XCDR (glyphless_method);
6910 else
6911 glyphless_method = XCHAR_TABLE (Vglyphless_char_display)->extras[0];
6914 retry:
6915 if (NILP (glyphless_method))
6917 if (c >= 0)
6918 /* The default is to display the character by a proper font. */
6919 return Qnil;
6920 /* The default for the no-font case is to display an empty box. */
6921 glyphless_method = Qempty_box;
6923 if (EQ (glyphless_method, Qzero_width))
6925 if (c >= 0)
6926 return glyphless_method;
6927 /* This method can't be used for the no-font case. */
6928 glyphless_method = Qempty_box;
6930 if (EQ (glyphless_method, Qthin_space))
6931 it->glyphless_method = GLYPHLESS_DISPLAY_THIN_SPACE;
6932 else if (EQ (glyphless_method, Qempty_box))
6933 it->glyphless_method = GLYPHLESS_DISPLAY_EMPTY_BOX;
6934 else if (EQ (glyphless_method, Qhex_code))
6935 it->glyphless_method = GLYPHLESS_DISPLAY_HEX_CODE;
6936 else if (STRINGP (glyphless_method))
6937 it->glyphless_method = GLYPHLESS_DISPLAY_ACRONYM;
6938 else
6940 /* Invalid value. We use the default method. */
6941 glyphless_method = Qnil;
6942 goto retry;
6944 it->what = IT_GLYPHLESS;
6945 return glyphless_method;
6948 /* Merge escape glyph face and cache the result. */
6950 static struct frame *last_escape_glyph_frame = NULL;
6951 static int last_escape_glyph_face_id = (1 << FACE_ID_BITS);
6952 static int last_escape_glyph_merged_face_id = 0;
6954 static int
6955 merge_escape_glyph_face (struct it *it)
6957 int face_id;
6959 if (it->f == last_escape_glyph_frame
6960 && it->face_id == last_escape_glyph_face_id)
6961 face_id = last_escape_glyph_merged_face_id;
6962 else
6964 /* Merge the `escape-glyph' face into the current face. */
6965 face_id = merge_faces (it->f, Qescape_glyph, 0, it->face_id);
6966 last_escape_glyph_frame = it->f;
6967 last_escape_glyph_face_id = it->face_id;
6968 last_escape_glyph_merged_face_id = face_id;
6970 return face_id;
6973 /* Likewise for glyphless glyph face. */
6975 static struct frame *last_glyphless_glyph_frame = NULL;
6976 static int last_glyphless_glyph_face_id = (1 << FACE_ID_BITS);
6977 static int last_glyphless_glyph_merged_face_id = 0;
6980 merge_glyphless_glyph_face (struct it *it)
6982 int face_id;
6984 if (it->f == last_glyphless_glyph_frame
6985 && it->face_id == last_glyphless_glyph_face_id)
6986 face_id = last_glyphless_glyph_merged_face_id;
6987 else
6989 /* Merge the `glyphless-char' face into the current face. */
6990 face_id = merge_faces (it->f, Qglyphless_char, 0, it->face_id);
6991 last_glyphless_glyph_frame = it->f;
6992 last_glyphless_glyph_face_id = it->face_id;
6993 last_glyphless_glyph_merged_face_id = face_id;
6995 return face_id;
6998 /* Forget the `escape-glyph' and `glyphless-char' faces. This should
6999 be called before redisplaying windows, and when the frame's face
7000 cache is freed. */
7001 void
7002 forget_escape_and_glyphless_faces (void)
7004 last_escape_glyph_frame = NULL;
7005 last_escape_glyph_face_id = (1 << FACE_ID_BITS);
7006 last_glyphless_glyph_frame = NULL;
7007 last_glyphless_glyph_face_id = (1 << FACE_ID_BITS);
7010 /* Load IT's display element fields with information about the next
7011 display element from the current position of IT. Value is false if
7012 end of buffer (or C string) is reached. */
7014 static bool
7015 get_next_display_element (struct it *it)
7017 /* True means that we found a display element. False means that
7018 we hit the end of what we iterate over. Performance note: the
7019 function pointer `method' used here turns out to be faster than
7020 using a sequence of if-statements. */
7021 bool success_p;
7023 get_next:
7024 success_p = GET_NEXT_DISPLAY_ELEMENT (it);
7026 if (it->what == IT_CHARACTER)
7028 /* UAX#9, L4: "A character is depicted by a mirrored glyph if
7029 and only if (a) the resolved directionality of that character
7030 is R..." */
7031 /* FIXME: Do we need an exception for characters from display
7032 tables? */
7033 if (it->bidi_p && it->bidi_it.type == STRONG_R
7034 && !inhibit_bidi_mirroring)
7035 it->c = bidi_mirror_char (it->c);
7036 /* Map via display table or translate control characters.
7037 IT->c, IT->len etc. have been set to the next character by
7038 the function call above. If we have a display table, and it
7039 contains an entry for IT->c, translate it. Don't do this if
7040 IT->c itself comes from a display table, otherwise we could
7041 end up in an infinite recursion. (An alternative could be to
7042 count the recursion depth of this function and signal an
7043 error when a certain maximum depth is reached.) Is it worth
7044 it? */
7045 if (success_p && it->dpvec == NULL)
7047 Lisp_Object dv;
7048 struct charset *unibyte = CHARSET_FROM_ID (charset_unibyte);
7049 bool nonascii_space_p = false;
7050 bool nonascii_hyphen_p = false;
7051 int c = it->c; /* This is the character to display. */
7053 if (! it->multibyte_p && ! ASCII_CHAR_P (c))
7055 eassert (SINGLE_BYTE_CHAR_P (c));
7056 if (unibyte_display_via_language_environment)
7058 c = DECODE_CHAR (unibyte, c);
7059 if (c < 0)
7060 c = BYTE8_TO_CHAR (it->c);
7062 else
7063 c = BYTE8_TO_CHAR (it->c);
7066 if (it->dp
7067 && (dv = DISP_CHAR_VECTOR (it->dp, c),
7068 VECTORP (dv)))
7070 struct Lisp_Vector *v = XVECTOR (dv);
7072 /* Return the first character from the display table
7073 entry, if not empty. If empty, don't display the
7074 current character. */
7075 if (v->header.size)
7077 it->dpvec_char_len = it->len;
7078 it->dpvec = v->contents;
7079 it->dpend = v->contents + v->header.size;
7080 it->current.dpvec_index = 0;
7081 it->dpvec_face_id = -1;
7082 it->saved_face_id = it->face_id;
7083 it->method = GET_FROM_DISPLAY_VECTOR;
7084 it->ellipsis_p = false;
7086 else
7088 set_iterator_to_next (it, false);
7090 goto get_next;
7093 if (! NILP (lookup_glyphless_char_display (c, it)))
7095 if (it->what == IT_GLYPHLESS)
7096 goto done;
7097 /* Don't display this character. */
7098 set_iterator_to_next (it, false);
7099 goto get_next;
7102 /* If `nobreak-char-display' is non-nil, we display
7103 non-ASCII spaces and hyphens specially. */
7104 if (! ASCII_CHAR_P (c) && ! NILP (Vnobreak_char_display))
7106 if (c == NO_BREAK_SPACE)
7107 nonascii_space_p = true;
7108 else if (c == SOFT_HYPHEN || c == HYPHEN
7109 || c == NON_BREAKING_HYPHEN)
7110 nonascii_hyphen_p = true;
7113 /* Translate control characters into `\003' or `^C' form.
7114 Control characters coming from a display table entry are
7115 currently not translated because we use IT->dpvec to hold
7116 the translation. This could easily be changed but I
7117 don't believe that it is worth doing.
7119 The characters handled by `nobreak-char-display' must be
7120 translated too.
7122 Non-printable characters and raw-byte characters are also
7123 translated to octal or hexadecimal form. */
7124 if (((c < ' ' || c == 127) /* ASCII control chars. */
7125 ? (it->area != TEXT_AREA
7126 /* In mode line, treat \n, \t like other crl chars. */
7127 || (c != '\t'
7128 && it->glyph_row
7129 && (it->glyph_row->mode_line_p || it->avoid_cursor_p))
7130 || (c != '\n' && c != '\t'))
7131 : (nonascii_space_p
7132 || nonascii_hyphen_p
7133 || CHAR_BYTE8_P (c)
7134 || ! CHAR_PRINTABLE_P (c))))
7136 /* C is a control character, non-ASCII space/hyphen,
7137 raw-byte, or a non-printable character which must be
7138 displayed either as '\003' or as `^C' where the '\\'
7139 and '^' can be defined in the display table. Fill
7140 IT->ctl_chars with glyphs for what we have to
7141 display. Then, set IT->dpvec to these glyphs. */
7142 Lisp_Object gc;
7143 int ctl_len;
7144 int face_id;
7145 int lface_id = 0;
7146 int escape_glyph;
7148 /* Handle control characters with ^. */
7150 if (ASCII_CHAR_P (c) && it->ctl_arrow_p)
7152 int g;
7154 g = '^'; /* default glyph for Control */
7155 /* Set IT->ctl_chars[0] to the glyph for `^'. */
7156 if (it->dp
7157 && (gc = DISP_CTRL_GLYPH (it->dp), GLYPH_CODE_P (gc)))
7159 g = GLYPH_CODE_CHAR (gc);
7160 lface_id = GLYPH_CODE_FACE (gc);
7163 face_id = (lface_id
7164 ? merge_faces (it->f, Qt, lface_id, it->face_id)
7165 : merge_escape_glyph_face (it));
7167 XSETINT (it->ctl_chars[0], g);
7168 XSETINT (it->ctl_chars[1], c ^ 0100);
7169 ctl_len = 2;
7170 goto display_control;
7173 /* Handle non-ascii space in the mode where it only gets
7174 highlighting. */
7176 if (nonascii_space_p && EQ (Vnobreak_char_display, Qt))
7178 /* Merge `nobreak-space' into the current face. */
7179 face_id = merge_faces (it->f, Qnobreak_space, 0,
7180 it->face_id);
7181 XSETINT (it->ctl_chars[0], ' ');
7182 ctl_len = 1;
7183 goto display_control;
7186 /* Handle non-ascii hyphens in the mode where it only
7187 gets highlighting. */
7189 if (nonascii_hyphen_p && EQ (Vnobreak_char_display, Qt))
7191 /* Merge `nobreak-space' into the current face. */
7192 face_id = merge_faces (it->f, Qnobreak_hyphen, 0,
7193 it->face_id);
7194 XSETINT (it->ctl_chars[0], '-');
7195 ctl_len = 1;
7196 goto display_control;
7199 /* Handle sequences that start with the "escape glyph". */
7201 /* the default escape glyph is \. */
7202 escape_glyph = '\\';
7204 if (it->dp
7205 && (gc = DISP_ESCAPE_GLYPH (it->dp), GLYPH_CODE_P (gc)))
7207 escape_glyph = GLYPH_CODE_CHAR (gc);
7208 lface_id = GLYPH_CODE_FACE (gc);
7211 face_id = (lface_id
7212 ? merge_faces (it->f, Qt, lface_id, it->face_id)
7213 : merge_escape_glyph_face (it));
7215 /* Draw non-ASCII space/hyphen with escape glyph: */
7217 if (nonascii_space_p || nonascii_hyphen_p)
7219 XSETINT (it->ctl_chars[0], escape_glyph);
7220 XSETINT (it->ctl_chars[1], nonascii_space_p ? ' ' : '-');
7221 ctl_len = 2;
7222 goto display_control;
7226 char str[10];
7227 int len, i;
7229 if (CHAR_BYTE8_P (c))
7230 /* Display \200 or \x80 instead of \17777600. */
7231 c = CHAR_TO_BYTE8 (c);
7232 const char *format_string = display_raw_bytes_as_hex
7233 ? "x%02x"
7234 : "%03o";
7235 len = sprintf (str, format_string, c + 0u);
7237 XSETINT (it->ctl_chars[0], escape_glyph);
7238 for (i = 0; i < len; i++)
7239 XSETINT (it->ctl_chars[i + 1], str[i]);
7240 ctl_len = len + 1;
7243 display_control:
7244 /* Set up IT->dpvec and return first character from it. */
7245 it->dpvec_char_len = it->len;
7246 it->dpvec = it->ctl_chars;
7247 it->dpend = it->dpvec + ctl_len;
7248 it->current.dpvec_index = 0;
7249 it->dpvec_face_id = face_id;
7250 it->saved_face_id = it->face_id;
7251 it->method = GET_FROM_DISPLAY_VECTOR;
7252 it->ellipsis_p = false;
7253 goto get_next;
7255 it->char_to_display = c;
7257 else if (success_p)
7259 it->char_to_display = it->c;
7263 #ifdef HAVE_WINDOW_SYSTEM
7264 /* Adjust face id for a multibyte character. There are no multibyte
7265 character in unibyte text. */
7266 if ((it->what == IT_CHARACTER || it->what == IT_COMPOSITION)
7267 && it->multibyte_p
7268 && success_p
7269 && FRAME_WINDOW_P (it->f))
7271 struct face *face = FACE_FROM_ID (it->f, it->face_id);
7273 if (it->what == IT_COMPOSITION && it->cmp_it.ch >= 0)
7275 /* Automatic composition with glyph-string. */
7276 Lisp_Object gstring = composition_gstring_from_id (it->cmp_it.id);
7278 it->face_id = face_for_font (it->f, LGSTRING_FONT (gstring), face);
7280 else
7282 ptrdiff_t pos = (it->s ? -1
7283 : STRINGP (it->string) ? IT_STRING_CHARPOS (*it)
7284 : IT_CHARPOS (*it));
7285 int c;
7287 if (it->what == IT_CHARACTER)
7288 c = it->char_to_display;
7289 else
7291 struct composition *cmp = composition_table[it->cmp_it.id];
7292 int i;
7294 c = ' ';
7295 for (i = 0; i < cmp->glyph_len; i++)
7296 /* TAB in a composition means display glyphs with
7297 padding space on the left or right. */
7298 if ((c = COMPOSITION_GLYPH (cmp, i)) != '\t')
7299 break;
7301 it->face_id = FACE_FOR_CHAR (it->f, face, c, pos, it->string);
7304 #endif /* HAVE_WINDOW_SYSTEM */
7306 done:
7307 /* Is this character the last one of a run of characters with
7308 box? If yes, set IT->end_of_box_run_p to true. */
7309 if (it->face_box_p
7310 && it->s == NULL)
7312 if (it->method == GET_FROM_STRING && it->sp)
7314 int face_id = underlying_face_id (it);
7315 struct face *face = FACE_FROM_ID_OR_NULL (it->f, face_id);
7317 if (face)
7319 if (face->box == FACE_NO_BOX)
7321 /* If the box comes from face properties in a
7322 display string, check faces in that string. */
7323 int string_face_id = face_after_it_pos (it);
7324 it->end_of_box_run_p
7325 = (FACE_FROM_ID (it->f, string_face_id)->box
7326 == FACE_NO_BOX);
7328 /* Otherwise, the box comes from the underlying face.
7329 If this is the last string character displayed, check
7330 the next buffer location. */
7331 else if ((IT_STRING_CHARPOS (*it) >= SCHARS (it->string) - 1)
7332 /* n_overlay_strings is unreliable unless
7333 overlay_string_index is non-negative. */
7334 && ((it->current.overlay_string_index >= 0
7335 && (it->current.overlay_string_index
7336 == it->n_overlay_strings - 1))
7337 /* A string from display property. */
7338 || it->from_disp_prop_p))
7340 ptrdiff_t ignore;
7341 int next_face_id;
7342 bool text_from_string = false;
7343 /* Normally, the next buffer location is stored in
7344 IT->current.pos... */
7345 struct text_pos pos = it->current.pos;
7347 /* ...but for a string from a display property, the
7348 next buffer position is stored in the 'position'
7349 member of the iteration stack slot below the
7350 current one, see handle_single_display_spec. By
7351 contrast, it->current.pos was not yet updated to
7352 point to that buffer position; that will happen
7353 in pop_it, after we finish displaying the current
7354 string. Note that we already checked above that
7355 it->sp is positive, so subtracting one from it is
7356 safe. */
7357 if (it->from_disp_prop_p)
7359 int stackp = it->sp - 1;
7361 /* Find the stack level with data from buffer. */
7362 while (stackp >= 0
7363 && STRINGP ((it->stack + stackp)->string))
7364 stackp--;
7365 if (stackp < 0)
7367 /* If no stack slot was found for iterating
7368 a buffer, we are displaying text from a
7369 string, most probably the mode line or
7370 the header line, and that string has a
7371 display string on some of its
7372 characters. */
7373 text_from_string = true;
7374 pos = it->stack[it->sp - 1].position;
7376 else
7377 pos = (it->stack + stackp)->position;
7379 else
7380 INC_TEXT_POS (pos, it->multibyte_p);
7382 if (text_from_string)
7384 Lisp_Object base_string = it->stack[it->sp - 1].string;
7386 if (CHARPOS (pos) >= SCHARS (base_string) - 1)
7387 it->end_of_box_run_p = true;
7388 else
7390 next_face_id
7391 = face_at_string_position (it->w, base_string,
7392 CHARPOS (pos), 0,
7393 &ignore, face_id, false);
7394 it->end_of_box_run_p
7395 = (FACE_FROM_ID (it->f, next_face_id)->box
7396 == FACE_NO_BOX);
7399 else if (CHARPOS (pos) >= ZV)
7400 it->end_of_box_run_p = true;
7401 else
7403 next_face_id =
7404 face_at_buffer_position (it->w, CHARPOS (pos), &ignore,
7405 CHARPOS (pos)
7406 + TEXT_PROP_DISTANCE_LIMIT,
7407 false, -1);
7408 it->end_of_box_run_p
7409 = (FACE_FROM_ID (it->f, next_face_id)->box
7410 == FACE_NO_BOX);
7415 /* next_element_from_display_vector sets this flag according to
7416 faces of the display vector glyphs, see there. */
7417 else if (it->method != GET_FROM_DISPLAY_VECTOR)
7419 int face_id = face_after_it_pos (it);
7420 it->end_of_box_run_p
7421 = (face_id != it->face_id
7422 && FACE_FROM_ID (it->f, face_id)->box == FACE_NO_BOX);
7425 /* If we reached the end of the object we've been iterating (e.g., a
7426 display string or an overlay string), and there's something on
7427 IT->stack, proceed with what's on the stack. It doesn't make
7428 sense to return false if there's unprocessed stuff on the stack,
7429 because otherwise that stuff will never be displayed. */
7430 if (!success_p && it->sp > 0)
7432 set_iterator_to_next (it, false);
7433 success_p = get_next_display_element (it);
7436 /* Value is false if end of buffer or string reached. */
7437 return success_p;
7441 /* Move IT to the next display element.
7443 RESEAT_P means if called on a newline in buffer text,
7444 skip to the next visible line start.
7446 Functions get_next_display_element and set_iterator_to_next are
7447 separate because I find this arrangement easier to handle than a
7448 get_next_display_element function that also increments IT's
7449 position. The way it is we can first look at an iterator's current
7450 display element, decide whether it fits on a line, and if it does,
7451 increment the iterator position. The other way around we probably
7452 would either need a flag indicating whether the iterator has to be
7453 incremented the next time, or we would have to implement a
7454 decrement position function which would not be easy to write. */
7456 void
7457 set_iterator_to_next (struct it *it, bool reseat_p)
7459 /* Reset flags indicating start and end of a sequence of characters
7460 with box. Reset them at the start of this function because
7461 moving the iterator to a new position might set them. */
7462 it->start_of_box_run_p = it->end_of_box_run_p = false;
7464 switch (it->method)
7466 case GET_FROM_BUFFER:
7467 /* The current display element of IT is a character from
7468 current_buffer. Advance in the buffer, and maybe skip over
7469 invisible lines that are so because of selective display. */
7470 if (ITERATOR_AT_END_OF_LINE_P (it) && reseat_p)
7471 reseat_at_next_visible_line_start (it, false);
7472 else if (it->cmp_it.id >= 0)
7474 /* We are currently getting glyphs from a composition. */
7475 if (! it->bidi_p)
7477 IT_CHARPOS (*it) += it->cmp_it.nchars;
7478 IT_BYTEPOS (*it) += it->cmp_it.nbytes;
7480 else
7482 int i;
7484 /* Update IT's char/byte positions to point to the first
7485 character of the next grapheme cluster, or to the
7486 character visually after the current composition. */
7487 for (i = 0; i < it->cmp_it.nchars; i++)
7488 bidi_move_to_visually_next (&it->bidi_it);
7489 IT_BYTEPOS (*it) = it->bidi_it.bytepos;
7490 IT_CHARPOS (*it) = it->bidi_it.charpos;
7493 if ((! it->bidi_p || ! it->cmp_it.reversed_p)
7494 && it->cmp_it.to < it->cmp_it.nglyphs)
7496 /* Composition created while scanning forward. Proceed
7497 to the next grapheme cluster. */
7498 it->cmp_it.from = it->cmp_it.to;
7500 else if ((it->bidi_p && it->cmp_it.reversed_p)
7501 && it->cmp_it.from > 0)
7503 /* Composition created while scanning backward. Proceed
7504 to the previous grapheme cluster. */
7505 it->cmp_it.to = it->cmp_it.from;
7507 else
7509 /* No more grapheme clusters in this composition.
7510 Find the next stop position. */
7511 ptrdiff_t stop = it->end_charpos;
7513 if (it->bidi_it.scan_dir < 0)
7514 /* Now we are scanning backward and don't know
7515 where to stop. */
7516 stop = -1;
7517 composition_compute_stop_pos (&it->cmp_it, IT_CHARPOS (*it),
7518 IT_BYTEPOS (*it), stop, Qnil);
7521 else
7523 eassert (it->len != 0);
7525 if (!it->bidi_p)
7527 IT_BYTEPOS (*it) += it->len;
7528 IT_CHARPOS (*it) += 1;
7530 else
7532 int prev_scan_dir = it->bidi_it.scan_dir;
7533 /* If this is a new paragraph, determine its base
7534 direction (a.k.a. its base embedding level). */
7535 if (it->bidi_it.new_paragraph)
7536 bidi_paragraph_init (it->paragraph_embedding, &it->bidi_it,
7537 false);
7538 bidi_move_to_visually_next (&it->bidi_it);
7539 IT_BYTEPOS (*it) = it->bidi_it.bytepos;
7540 IT_CHARPOS (*it) = it->bidi_it.charpos;
7541 if (prev_scan_dir != it->bidi_it.scan_dir)
7543 /* As the scan direction was changed, we must
7544 re-compute the stop position for composition. */
7545 ptrdiff_t stop = it->end_charpos;
7546 if (it->bidi_it.scan_dir < 0)
7547 stop = -1;
7548 composition_compute_stop_pos (&it->cmp_it, IT_CHARPOS (*it),
7549 IT_BYTEPOS (*it), stop, Qnil);
7552 eassert (IT_BYTEPOS (*it) == CHAR_TO_BYTE (IT_CHARPOS (*it)));
7554 break;
7556 case GET_FROM_C_STRING:
7557 /* Current display element of IT is from a C string. */
7558 if (!it->bidi_p
7559 /* If the string position is beyond string's end, it means
7560 next_element_from_c_string is padding the string with
7561 blanks, in which case we bypass the bidi iterator,
7562 because it cannot deal with such virtual characters. */
7563 || IT_CHARPOS (*it) >= it->bidi_it.string.schars)
7565 IT_BYTEPOS (*it) += it->len;
7566 IT_CHARPOS (*it) += 1;
7568 else
7570 bidi_move_to_visually_next (&it->bidi_it);
7571 IT_BYTEPOS (*it) = it->bidi_it.bytepos;
7572 IT_CHARPOS (*it) = it->bidi_it.charpos;
7574 break;
7576 case GET_FROM_DISPLAY_VECTOR:
7577 /* Current display element of IT is from a display table entry.
7578 Advance in the display table definition. Reset it to null if
7579 end reached, and continue with characters from buffers/
7580 strings. */
7581 ++it->current.dpvec_index;
7583 /* Restore face of the iterator to what they were before the
7584 display vector entry (these entries may contain faces). */
7585 it->face_id = it->saved_face_id;
7587 if (it->dpvec + it->current.dpvec_index >= it->dpend)
7589 bool recheck_faces = it->ellipsis_p;
7591 if (it->s)
7592 it->method = GET_FROM_C_STRING;
7593 else if (STRINGP (it->string))
7594 it->method = GET_FROM_STRING;
7595 else
7597 it->method = GET_FROM_BUFFER;
7598 it->object = it->w->contents;
7601 it->dpvec = NULL;
7602 it->current.dpvec_index = -1;
7604 /* Skip over characters which were displayed via IT->dpvec. */
7605 if (it->dpvec_char_len < 0)
7606 reseat_at_next_visible_line_start (it, true);
7607 else if (it->dpvec_char_len > 0)
7609 it->len = it->dpvec_char_len;
7610 set_iterator_to_next (it, reseat_p);
7613 /* Maybe recheck faces after display vector. */
7614 if (recheck_faces)
7616 if (it->method == GET_FROM_STRING)
7617 it->stop_charpos = IT_STRING_CHARPOS (*it);
7618 else
7619 it->stop_charpos = IT_CHARPOS (*it);
7622 break;
7624 case GET_FROM_STRING:
7625 /* Current display element is a character from a Lisp string. */
7626 eassert (it->s == NULL && STRINGP (it->string));
7627 /* Don't advance past string end. These conditions are true
7628 when set_iterator_to_next is called at the end of
7629 get_next_display_element, in which case the Lisp string is
7630 already exhausted, and all we want is pop the iterator
7631 stack. */
7632 if (it->current.overlay_string_index >= 0)
7634 /* This is an overlay string, so there's no padding with
7635 spaces, and the number of characters in the string is
7636 where the string ends. */
7637 if (IT_STRING_CHARPOS (*it) >= SCHARS (it->string))
7638 goto consider_string_end;
7640 else
7642 /* Not an overlay string. There could be padding, so test
7643 against it->end_charpos. */
7644 if (IT_STRING_CHARPOS (*it) >= it->end_charpos)
7645 goto consider_string_end;
7647 if (it->cmp_it.id >= 0)
7649 /* We are delivering display elements from a composition.
7650 Update the string position past the grapheme cluster
7651 we've just processed. */
7652 if (! it->bidi_p)
7654 IT_STRING_CHARPOS (*it) += it->cmp_it.nchars;
7655 IT_STRING_BYTEPOS (*it) += it->cmp_it.nbytes;
7657 else
7659 int i;
7661 for (i = 0; i < it->cmp_it.nchars; i++)
7662 bidi_move_to_visually_next (&it->bidi_it);
7663 IT_STRING_BYTEPOS (*it) = it->bidi_it.bytepos;
7664 IT_STRING_CHARPOS (*it) = it->bidi_it.charpos;
7667 /* Did we exhaust all the grapheme clusters of this
7668 composition? */
7669 if ((! it->bidi_p || ! it->cmp_it.reversed_p)
7670 && (it->cmp_it.to < it->cmp_it.nglyphs))
7672 /* Not all the grapheme clusters were processed yet;
7673 advance to the next cluster. */
7674 it->cmp_it.from = it->cmp_it.to;
7676 else if ((it->bidi_p && it->cmp_it.reversed_p)
7677 && it->cmp_it.from > 0)
7679 /* Likewise: advance to the next cluster, but going in
7680 the reverse direction. */
7681 it->cmp_it.to = it->cmp_it.from;
7683 else
7685 /* This composition was fully processed; find the next
7686 candidate place for checking for composed
7687 characters. */
7688 /* Always limit string searches to the string length;
7689 any padding spaces are not part of the string, and
7690 there cannot be any compositions in that padding. */
7691 ptrdiff_t stop = SCHARS (it->string);
7693 if (it->bidi_p && it->bidi_it.scan_dir < 0)
7694 stop = -1;
7695 else if (it->end_charpos < stop)
7697 /* Cf. PRECISION in reseat_to_string: we might be
7698 limited in how many of the string characters we
7699 need to deliver. */
7700 stop = it->end_charpos;
7702 composition_compute_stop_pos (&it->cmp_it,
7703 IT_STRING_CHARPOS (*it),
7704 IT_STRING_BYTEPOS (*it), stop,
7705 it->string);
7708 else
7710 if (!it->bidi_p
7711 /* If the string position is beyond string's end, it
7712 means next_element_from_string is padding the string
7713 with blanks, in which case we bypass the bidi
7714 iterator, because it cannot deal with such virtual
7715 characters. */
7716 || IT_STRING_CHARPOS (*it) >= it->bidi_it.string.schars)
7718 IT_STRING_BYTEPOS (*it) += it->len;
7719 IT_STRING_CHARPOS (*it) += 1;
7721 else
7723 int prev_scan_dir = it->bidi_it.scan_dir;
7725 bidi_move_to_visually_next (&it->bidi_it);
7726 IT_STRING_BYTEPOS (*it) = it->bidi_it.bytepos;
7727 IT_STRING_CHARPOS (*it) = it->bidi_it.charpos;
7728 /* If the scan direction changes, we may need to update
7729 the place where to check for composed characters. */
7730 if (prev_scan_dir != it->bidi_it.scan_dir)
7732 ptrdiff_t stop = SCHARS (it->string);
7734 if (it->bidi_it.scan_dir < 0)
7735 stop = -1;
7736 else if (it->end_charpos < stop)
7737 stop = it->end_charpos;
7739 composition_compute_stop_pos (&it->cmp_it,
7740 IT_STRING_CHARPOS (*it),
7741 IT_STRING_BYTEPOS (*it), stop,
7742 it->string);
7747 consider_string_end:
7749 if (it->current.overlay_string_index >= 0)
7751 /* IT->string is an overlay string. Advance to the
7752 next, if there is one. */
7753 if (IT_STRING_CHARPOS (*it) >= SCHARS (it->string))
7755 it->ellipsis_p = false;
7756 next_overlay_string (it);
7757 if (it->ellipsis_p)
7758 setup_for_ellipsis (it, 0);
7761 else
7763 /* IT->string is not an overlay string. If we reached
7764 its end, and there is something on IT->stack, proceed
7765 with what is on the stack. This can be either another
7766 string, this time an overlay string, or a buffer. */
7767 if (IT_STRING_CHARPOS (*it) == SCHARS (it->string)
7768 && it->sp > 0)
7770 pop_it (it);
7771 if (it->method == GET_FROM_STRING)
7772 goto consider_string_end;
7775 break;
7777 case GET_FROM_IMAGE:
7778 case GET_FROM_STRETCH:
7779 case GET_FROM_XWIDGET:
7781 /* The position etc with which we have to proceed are on
7782 the stack. The position may be at the end of a string,
7783 if the `display' property takes up the whole string. */
7784 eassert (it->sp > 0);
7785 pop_it (it);
7786 if (it->method == GET_FROM_STRING)
7787 goto consider_string_end;
7788 break;
7790 default:
7791 /* There are no other methods defined, so this should be a bug. */
7792 emacs_abort ();
7795 eassert (it->method != GET_FROM_STRING
7796 || (STRINGP (it->string)
7797 && IT_STRING_CHARPOS (*it) >= 0));
7800 /* Load IT's display element fields with information about the next
7801 display element which comes from a display table entry or from the
7802 result of translating a control character to one of the forms `^C'
7803 or `\003'.
7805 IT->dpvec holds the glyphs to return as characters.
7806 IT->saved_face_id holds the face id before the display vector--it
7807 is restored into IT->face_id in set_iterator_to_next. */
7809 static bool
7810 next_element_from_display_vector (struct it *it)
7812 Lisp_Object gc;
7813 int prev_face_id = it->face_id;
7814 int next_face_id;
7816 /* Precondition. */
7817 eassert (it->dpvec && it->current.dpvec_index >= 0);
7819 it->face_id = it->saved_face_id;
7821 /* KFS: This code used to check ip->dpvec[0] instead of the current element.
7822 That seemed totally bogus - so I changed it... */
7823 if (it->dpend - it->dpvec > 0 /* empty dpvec[] is invalid */
7824 && (gc = it->dpvec[it->current.dpvec_index], GLYPH_CODE_P (gc)))
7826 struct face *this_face, *prev_face, *next_face;
7828 it->c = GLYPH_CODE_CHAR (gc);
7829 it->len = CHAR_BYTES (it->c);
7831 /* The entry may contain a face id to use. Such a face id is
7832 the id of a Lisp face, not a realized face. A face id of
7833 zero means no face is specified. */
7834 if (it->dpvec_face_id >= 0)
7835 it->face_id = it->dpvec_face_id;
7836 else
7838 int lface_id = GLYPH_CODE_FACE (gc);
7839 if (lface_id > 0)
7840 it->face_id = merge_faces (it->f, Qt, lface_id,
7841 it->saved_face_id);
7844 /* Glyphs in the display vector could have the box face, so we
7845 need to set the related flags in the iterator, as
7846 appropriate. */
7847 this_face = FACE_FROM_ID_OR_NULL (it->f, it->face_id);
7848 prev_face = FACE_FROM_ID_OR_NULL (it->f, prev_face_id);
7850 /* Is this character the first character of a box-face run? */
7851 it->start_of_box_run_p = (this_face && this_face->box != FACE_NO_BOX
7852 && (!prev_face
7853 || prev_face->box == FACE_NO_BOX));
7855 /* For the last character of the box-face run, we need to look
7856 either at the next glyph from the display vector, or at the
7857 face we saw before the display vector. */
7858 next_face_id = it->saved_face_id;
7859 if (it->current.dpvec_index < it->dpend - it->dpvec - 1)
7861 if (it->dpvec_face_id >= 0)
7862 next_face_id = it->dpvec_face_id;
7863 else
7865 int lface_id =
7866 GLYPH_CODE_FACE (it->dpvec[it->current.dpvec_index + 1]);
7868 if (lface_id > 0)
7869 next_face_id = merge_faces (it->f, Qt, lface_id,
7870 it->saved_face_id);
7873 next_face = FACE_FROM_ID_OR_NULL (it->f, next_face_id);
7874 it->end_of_box_run_p = (this_face && this_face->box != FACE_NO_BOX
7875 && (!next_face
7876 || next_face->box == FACE_NO_BOX));
7877 it->face_box_p = this_face && this_face->box != FACE_NO_BOX;
7879 else
7880 /* Display table entry is invalid. Return a space. */
7881 it->c = ' ', it->len = 1;
7883 /* Don't change position and object of the iterator here. They are
7884 still the values of the character that had this display table
7885 entry or was translated, and that's what we want. */
7886 it->what = IT_CHARACTER;
7887 return true;
7890 /* Get the first element of string/buffer in the visual order, after
7891 being reseated to a new position in a string or a buffer. */
7892 static void
7893 get_visually_first_element (struct it *it)
7895 bool string_p = STRINGP (it->string) || it->s;
7896 ptrdiff_t eob = (string_p ? it->bidi_it.string.schars : ZV);
7897 ptrdiff_t bob = (string_p ? 0 : BEGV);
7899 if (STRINGP (it->string))
7901 it->bidi_it.charpos = IT_STRING_CHARPOS (*it);
7902 it->bidi_it.bytepos = IT_STRING_BYTEPOS (*it);
7904 else
7906 it->bidi_it.charpos = IT_CHARPOS (*it);
7907 it->bidi_it.bytepos = IT_BYTEPOS (*it);
7910 if (it->bidi_it.charpos == eob)
7912 /* Nothing to do, but reset the FIRST_ELT flag, like
7913 bidi_paragraph_init does, because we are not going to
7914 call it. */
7915 it->bidi_it.first_elt = false;
7917 else if (it->bidi_it.charpos == bob
7918 || (!string_p
7919 && (FETCH_CHAR (it->bidi_it.bytepos - 1) == '\n'
7920 || FETCH_CHAR (it->bidi_it.bytepos) == '\n')))
7922 /* If we are at the beginning of a line/string, we can produce
7923 the next element right away. */
7924 bidi_paragraph_init (it->paragraph_embedding, &it->bidi_it, true);
7925 bidi_move_to_visually_next (&it->bidi_it);
7927 else
7929 ptrdiff_t orig_bytepos = it->bidi_it.bytepos;
7931 /* We need to prime the bidi iterator starting at the line's or
7932 string's beginning, before we will be able to produce the
7933 next element. */
7934 if (string_p)
7935 it->bidi_it.charpos = it->bidi_it.bytepos = 0;
7936 else
7937 it->bidi_it.charpos = find_newline_no_quit (IT_CHARPOS (*it),
7938 IT_BYTEPOS (*it), -1,
7939 &it->bidi_it.bytepos);
7940 bidi_paragraph_init (it->paragraph_embedding, &it->bidi_it, true);
7943 /* Now return to buffer/string position where we were asked
7944 to get the next display element, and produce that. */
7945 bidi_move_to_visually_next (&it->bidi_it);
7947 while (it->bidi_it.bytepos != orig_bytepos
7948 && it->bidi_it.charpos < eob);
7951 /* Adjust IT's position information to where we ended up. */
7952 if (STRINGP (it->string))
7954 IT_STRING_CHARPOS (*it) = it->bidi_it.charpos;
7955 IT_STRING_BYTEPOS (*it) = it->bidi_it.bytepos;
7957 else
7959 IT_CHARPOS (*it) = it->bidi_it.charpos;
7960 IT_BYTEPOS (*it) = it->bidi_it.bytepos;
7963 if (STRINGP (it->string) || !it->s)
7965 ptrdiff_t stop, charpos, bytepos;
7967 if (STRINGP (it->string))
7969 eassert (!it->s);
7970 stop = SCHARS (it->string);
7971 if (stop > it->end_charpos)
7972 stop = it->end_charpos;
7973 charpos = IT_STRING_CHARPOS (*it);
7974 bytepos = IT_STRING_BYTEPOS (*it);
7976 else
7978 stop = it->end_charpos;
7979 charpos = IT_CHARPOS (*it);
7980 bytepos = IT_BYTEPOS (*it);
7982 if (it->bidi_it.scan_dir < 0)
7983 stop = -1;
7984 composition_compute_stop_pos (&it->cmp_it, charpos, bytepos, stop,
7985 it->string);
7989 /* Load IT with the next display element from Lisp string IT->string.
7990 IT->current.string_pos is the current position within the string.
7991 If IT->current.overlay_string_index >= 0, the Lisp string is an
7992 overlay string. */
7994 static bool
7995 next_element_from_string (struct it *it)
7997 struct text_pos position;
7999 eassert (STRINGP (it->string));
8000 eassert (!it->bidi_p || EQ (it->string, it->bidi_it.string.lstring));
8001 eassert (IT_STRING_CHARPOS (*it) >= 0);
8002 position = it->current.string_pos;
8004 /* With bidi reordering, the character to display might not be the
8005 character at IT_STRING_CHARPOS. BIDI_IT.FIRST_ELT means
8006 that we were reseat()ed to a new string, whose paragraph
8007 direction is not known. */
8008 if (it->bidi_p && it->bidi_it.first_elt)
8010 get_visually_first_element (it);
8011 SET_TEXT_POS (position, IT_STRING_CHARPOS (*it), IT_STRING_BYTEPOS (*it));
8014 /* Time to check for invisible text? */
8015 if (IT_STRING_CHARPOS (*it) < it->end_charpos)
8017 if (IT_STRING_CHARPOS (*it) >= it->stop_charpos)
8019 if (!(!it->bidi_p
8020 || BIDI_AT_BASE_LEVEL (it->bidi_it)
8021 || IT_STRING_CHARPOS (*it) == it->stop_charpos))
8023 /* With bidi non-linear iteration, we could find
8024 ourselves far beyond the last computed stop_charpos,
8025 with several other stop positions in between that we
8026 missed. Scan them all now, in buffer's logical
8027 order, until we find and handle the last stop_charpos
8028 that precedes our current position. */
8029 handle_stop_backwards (it, it->stop_charpos);
8030 return GET_NEXT_DISPLAY_ELEMENT (it);
8032 else
8034 if (it->bidi_p)
8036 /* Take note of the stop position we just moved
8037 across, for when we will move back across it. */
8038 it->prev_stop = it->stop_charpos;
8039 /* If we are at base paragraph embedding level, take
8040 note of the last stop position seen at this
8041 level. */
8042 if (BIDI_AT_BASE_LEVEL (it->bidi_it))
8043 it->base_level_stop = it->stop_charpos;
8045 handle_stop (it);
8047 /* Since a handler may have changed IT->method, we must
8048 recurse here. */
8049 return GET_NEXT_DISPLAY_ELEMENT (it);
8052 else if (it->bidi_p
8053 /* If we are before prev_stop, we may have overstepped
8054 on our way backwards a stop_pos, and if so, we need
8055 to handle that stop_pos. */
8056 && IT_STRING_CHARPOS (*it) < it->prev_stop
8057 /* We can sometimes back up for reasons that have nothing
8058 to do with bidi reordering. E.g., compositions. The
8059 code below is only needed when we are above the base
8060 embedding level, so test for that explicitly. */
8061 && !BIDI_AT_BASE_LEVEL (it->bidi_it))
8063 /* If we lost track of base_level_stop, we have no better
8064 place for handle_stop_backwards to start from than string
8065 beginning. This happens, e.g., when we were reseated to
8066 the previous screenful of text by vertical-motion. */
8067 if (it->base_level_stop <= 0
8068 || IT_STRING_CHARPOS (*it) < it->base_level_stop)
8069 it->base_level_stop = 0;
8070 handle_stop_backwards (it, it->base_level_stop);
8071 return GET_NEXT_DISPLAY_ELEMENT (it);
8075 if (it->current.overlay_string_index >= 0)
8077 /* Get the next character from an overlay string. In overlay
8078 strings, there is no field width or padding with spaces to
8079 do. */
8080 if (IT_STRING_CHARPOS (*it) >= SCHARS (it->string))
8082 it->what = IT_EOB;
8083 return false;
8085 else if (CHAR_COMPOSED_P (it, IT_STRING_CHARPOS (*it),
8086 IT_STRING_BYTEPOS (*it),
8087 it->bidi_it.scan_dir < 0
8088 ? -1
8089 : SCHARS (it->string))
8090 && next_element_from_composition (it))
8092 return true;
8094 else if (STRING_MULTIBYTE (it->string))
8096 const unsigned char *s = (SDATA (it->string)
8097 + IT_STRING_BYTEPOS (*it));
8098 it->c = string_char_and_length (s, &it->len);
8100 else
8102 it->c = SREF (it->string, IT_STRING_BYTEPOS (*it));
8103 it->len = 1;
8106 else
8108 /* Get the next character from a Lisp string that is not an
8109 overlay string. Such strings come from the mode line, for
8110 example. We may have to pad with spaces, or truncate the
8111 string. See also next_element_from_c_string. */
8112 if (IT_STRING_CHARPOS (*it) >= it->end_charpos)
8114 it->what = IT_EOB;
8115 return false;
8117 else if (IT_STRING_CHARPOS (*it) >= it->string_nchars)
8119 /* Pad with spaces. */
8120 it->c = ' ', it->len = 1;
8121 CHARPOS (position) = BYTEPOS (position) = -1;
8123 else if (CHAR_COMPOSED_P (it, IT_STRING_CHARPOS (*it),
8124 IT_STRING_BYTEPOS (*it),
8125 it->bidi_it.scan_dir < 0
8126 ? -1
8127 : it->string_nchars)
8128 && next_element_from_composition (it))
8130 return true;
8132 else if (STRING_MULTIBYTE (it->string))
8134 const unsigned char *s = (SDATA (it->string)
8135 + IT_STRING_BYTEPOS (*it));
8136 it->c = string_char_and_length (s, &it->len);
8138 else
8140 it->c = SREF (it->string, IT_STRING_BYTEPOS (*it));
8141 it->len = 1;
8145 /* Record what we have and where it came from. */
8146 it->what = IT_CHARACTER;
8147 it->object = it->string;
8148 it->position = position;
8149 return true;
8153 /* Load IT with next display element from C string IT->s.
8154 IT->string_nchars is the maximum number of characters to return
8155 from the string. IT->end_charpos may be greater than
8156 IT->string_nchars when this function is called, in which case we
8157 may have to return padding spaces. Value is false if end of string
8158 reached, including padding spaces. */
8160 static bool
8161 next_element_from_c_string (struct it *it)
8163 bool success_p = true;
8165 eassert (it->s);
8166 eassert (!it->bidi_p || it->s == it->bidi_it.string.s);
8167 it->what = IT_CHARACTER;
8168 BYTEPOS (it->position) = CHARPOS (it->position) = 0;
8169 it->object = make_number (0);
8171 /* With bidi reordering, the character to display might not be the
8172 character at IT_CHARPOS. BIDI_IT.FIRST_ELT means that
8173 we were reseated to a new string, whose paragraph direction is
8174 not known. */
8175 if (it->bidi_p && it->bidi_it.first_elt)
8176 get_visually_first_element (it);
8178 /* IT's position can be greater than IT->string_nchars in case a
8179 field width or precision has been specified when the iterator was
8180 initialized. */
8181 if (IT_CHARPOS (*it) >= it->end_charpos)
8183 /* End of the game. */
8184 it->what = IT_EOB;
8185 success_p = false;
8187 else if (IT_CHARPOS (*it) >= it->string_nchars)
8189 /* Pad with spaces. */
8190 it->c = ' ', it->len = 1;
8191 BYTEPOS (it->position) = CHARPOS (it->position) = -1;
8193 else if (it->multibyte_p)
8194 it->c = string_char_and_length (it->s + IT_BYTEPOS (*it), &it->len);
8195 else
8196 it->c = it->s[IT_BYTEPOS (*it)], it->len = 1;
8198 return success_p;
8202 /* Set up IT to return characters from an ellipsis, if appropriate.
8203 The definition of the ellipsis glyphs may come from a display table
8204 entry. This function fills IT with the first glyph from the
8205 ellipsis if an ellipsis is to be displayed. */
8207 static bool
8208 next_element_from_ellipsis (struct it *it)
8210 if (it->selective_display_ellipsis_p)
8211 setup_for_ellipsis (it, it->len);
8212 else
8214 /* The face at the current position may be different from the
8215 face we find after the invisible text. Remember what it
8216 was in IT->saved_face_id, and signal that it's there by
8217 setting face_before_selective_p. */
8218 it->saved_face_id = it->face_id;
8219 it->method = GET_FROM_BUFFER;
8220 it->object = it->w->contents;
8221 reseat_at_next_visible_line_start (it, true);
8222 it->face_before_selective_p = true;
8225 return GET_NEXT_DISPLAY_ELEMENT (it);
8229 /* Deliver an image display element. The iterator IT is already
8230 filled with image information (done in handle_display_prop). Value
8231 is always true. */
8234 static bool
8235 next_element_from_image (struct it *it)
8237 it->what = IT_IMAGE;
8238 return true;
8241 static bool
8242 next_element_from_xwidget (struct it *it)
8244 it->what = IT_XWIDGET;
8245 return true;
8249 /* Fill iterator IT with next display element from a stretch glyph
8250 property. IT->object is the value of the text property. Value is
8251 always true. */
8253 static bool
8254 next_element_from_stretch (struct it *it)
8256 it->what = IT_STRETCH;
8257 return true;
8260 /* Scan backwards from IT's current position until we find a stop
8261 position, or until BEGV. This is called when we find ourself
8262 before both the last known prev_stop and base_level_stop while
8263 reordering bidirectional text. */
8265 static void
8266 compute_stop_pos_backwards (struct it *it)
8268 const int SCAN_BACK_LIMIT = 1000;
8269 struct text_pos pos;
8270 struct display_pos save_current = it->current;
8271 struct text_pos save_position = it->position;
8272 ptrdiff_t charpos = IT_CHARPOS (*it);
8273 ptrdiff_t where_we_are = charpos;
8274 ptrdiff_t save_stop_pos = it->stop_charpos;
8275 ptrdiff_t save_end_pos = it->end_charpos;
8277 eassert (NILP (it->string) && !it->s);
8278 eassert (it->bidi_p);
8279 it->bidi_p = false;
8282 it->end_charpos = min (charpos + 1, ZV);
8283 charpos = max (charpos - SCAN_BACK_LIMIT, BEGV);
8284 SET_TEXT_POS (pos, charpos, CHAR_TO_BYTE (charpos));
8285 reseat_1 (it, pos, false);
8286 compute_stop_pos (it);
8287 /* We must advance forward, right? */
8288 if (it->stop_charpos <= charpos)
8289 emacs_abort ();
8291 while (charpos > BEGV && it->stop_charpos >= it->end_charpos);
8293 if (it->stop_charpos <= where_we_are)
8294 it->prev_stop = it->stop_charpos;
8295 else
8296 it->prev_stop = BEGV;
8297 it->bidi_p = true;
8298 it->current = save_current;
8299 it->position = save_position;
8300 it->stop_charpos = save_stop_pos;
8301 it->end_charpos = save_end_pos;
8304 /* Scan forward from CHARPOS in the current buffer/string, until we
8305 find a stop position > current IT's position. Then handle the stop
8306 position before that. This is called when we bump into a stop
8307 position while reordering bidirectional text. CHARPOS should be
8308 the last previously processed stop_pos (or BEGV/0, if none were
8309 processed yet) whose position is less that IT's current
8310 position. */
8312 static void
8313 handle_stop_backwards (struct it *it, ptrdiff_t charpos)
8315 bool bufp = !STRINGP (it->string);
8316 ptrdiff_t where_we_are = (bufp ? IT_CHARPOS (*it) : IT_STRING_CHARPOS (*it));
8317 struct display_pos save_current = it->current;
8318 struct text_pos save_position = it->position;
8319 struct text_pos pos1;
8320 ptrdiff_t next_stop;
8322 /* Scan in strict logical order. */
8323 eassert (it->bidi_p);
8324 it->bidi_p = false;
8327 it->prev_stop = charpos;
8328 if (bufp)
8330 SET_TEXT_POS (pos1, charpos, CHAR_TO_BYTE (charpos));
8331 reseat_1 (it, pos1, false);
8333 else
8334 it->current.string_pos = string_pos (charpos, it->string);
8335 compute_stop_pos (it);
8336 /* We must advance forward, right? */
8337 if (it->stop_charpos <= it->prev_stop)
8338 emacs_abort ();
8339 charpos = it->stop_charpos;
8341 while (charpos <= where_we_are);
8343 it->bidi_p = true;
8344 it->current = save_current;
8345 it->position = save_position;
8346 next_stop = it->stop_charpos;
8347 it->stop_charpos = it->prev_stop;
8348 handle_stop (it);
8349 it->stop_charpos = next_stop;
8352 /* Load IT with the next display element from current_buffer. Value
8353 is false if end of buffer reached. IT->stop_charpos is the next
8354 position at which to stop and check for text properties or buffer
8355 end. */
8357 static bool
8358 next_element_from_buffer (struct it *it)
8360 bool success_p = true;
8362 eassert (IT_CHARPOS (*it) >= BEGV);
8363 eassert (NILP (it->string) && !it->s);
8364 eassert (!it->bidi_p
8365 || (EQ (it->bidi_it.string.lstring, Qnil)
8366 && it->bidi_it.string.s == NULL));
8368 /* With bidi reordering, the character to display might not be the
8369 character at IT_CHARPOS. BIDI_IT.FIRST_ELT means that
8370 we were reseat()ed to a new buffer position, which is potentially
8371 a different paragraph. */
8372 if (it->bidi_p && it->bidi_it.first_elt)
8374 get_visually_first_element (it);
8375 SET_TEXT_POS (it->position, IT_CHARPOS (*it), IT_BYTEPOS (*it));
8378 if (IT_CHARPOS (*it) >= it->stop_charpos)
8380 if (IT_CHARPOS (*it) >= it->end_charpos)
8382 bool overlay_strings_follow_p;
8384 /* End of the game, except when overlay strings follow that
8385 haven't been returned yet. */
8386 if (it->overlay_strings_at_end_processed_p)
8387 overlay_strings_follow_p = false;
8388 else
8390 it->overlay_strings_at_end_processed_p = true;
8391 overlay_strings_follow_p = get_overlay_strings (it, 0);
8394 if (overlay_strings_follow_p)
8395 success_p = GET_NEXT_DISPLAY_ELEMENT (it);
8396 else
8398 it->what = IT_EOB;
8399 it->position = it->current.pos;
8400 success_p = false;
8403 else if (!(!it->bidi_p
8404 || BIDI_AT_BASE_LEVEL (it->bidi_it)
8405 || IT_CHARPOS (*it) == it->stop_charpos))
8407 /* With bidi non-linear iteration, we could find ourselves
8408 far beyond the last computed stop_charpos, with several
8409 other stop positions in between that we missed. Scan
8410 them all now, in buffer's logical order, until we find
8411 and handle the last stop_charpos that precedes our
8412 current position. */
8413 handle_stop_backwards (it, it->stop_charpos);
8414 it->ignore_overlay_strings_at_pos_p = false;
8415 return GET_NEXT_DISPLAY_ELEMENT (it);
8417 else
8419 if (it->bidi_p)
8421 /* Take note of the stop position we just moved across,
8422 for when we will move back across it. */
8423 it->prev_stop = it->stop_charpos;
8424 /* If we are at base paragraph embedding level, take
8425 note of the last stop position seen at this
8426 level. */
8427 if (BIDI_AT_BASE_LEVEL (it->bidi_it))
8428 it->base_level_stop = it->stop_charpos;
8430 handle_stop (it);
8431 it->ignore_overlay_strings_at_pos_p = false;
8432 return GET_NEXT_DISPLAY_ELEMENT (it);
8435 else if (it->bidi_p
8436 /* If we are before prev_stop, we may have overstepped on
8437 our way backwards a stop_pos, and if so, we need to
8438 handle that stop_pos. */
8439 && IT_CHARPOS (*it) < it->prev_stop
8440 /* We can sometimes back up for reasons that have nothing
8441 to do with bidi reordering. E.g., compositions. The
8442 code below is only needed when we are above the base
8443 embedding level, so test for that explicitly. */
8444 && !BIDI_AT_BASE_LEVEL (it->bidi_it))
8446 if (it->base_level_stop <= 0
8447 || IT_CHARPOS (*it) < it->base_level_stop)
8449 /* If we lost track of base_level_stop, we need to find
8450 prev_stop by looking backwards. This happens, e.g., when
8451 we were reseated to the previous screenful of text by
8452 vertical-motion. */
8453 it->base_level_stop = BEGV;
8454 compute_stop_pos_backwards (it);
8455 handle_stop_backwards (it, it->prev_stop);
8457 else
8458 handle_stop_backwards (it, it->base_level_stop);
8459 it->ignore_overlay_strings_at_pos_p = false;
8460 return GET_NEXT_DISPLAY_ELEMENT (it);
8462 else
8464 /* No face changes, overlays etc. in sight, so just return a
8465 character from current_buffer. */
8466 unsigned char *p;
8467 ptrdiff_t stop;
8469 /* We moved to the next buffer position, so any info about
8470 previously seen overlays is no longer valid. */
8471 it->ignore_overlay_strings_at_pos_p = false;
8473 /* Maybe run the redisplay end trigger hook. Performance note:
8474 This doesn't seem to cost measurable time. */
8475 if (it->redisplay_end_trigger_charpos
8476 && it->glyph_row
8477 && IT_CHARPOS (*it) >= it->redisplay_end_trigger_charpos)
8478 run_redisplay_end_trigger_hook (it);
8480 stop = it->bidi_it.scan_dir < 0 ? -1 : it->end_charpos;
8481 if (CHAR_COMPOSED_P (it, IT_CHARPOS (*it), IT_BYTEPOS (*it),
8482 stop)
8483 && next_element_from_composition (it))
8485 return true;
8488 /* Get the next character, maybe multibyte. */
8489 p = BYTE_POS_ADDR (IT_BYTEPOS (*it));
8490 if (it->multibyte_p && !ASCII_CHAR_P (*p))
8491 it->c = STRING_CHAR_AND_LENGTH (p, it->len);
8492 else
8493 it->c = *p, it->len = 1;
8495 /* Record what we have and where it came from. */
8496 it->what = IT_CHARACTER;
8497 it->object = it->w->contents;
8498 it->position = it->current.pos;
8500 /* Normally we return the character found above, except when we
8501 really want to return an ellipsis for selective display. */
8502 if (it->selective)
8504 if (it->c == '\n')
8506 /* A value of selective > 0 means hide lines indented more
8507 than that number of columns. */
8508 if (it->selective > 0
8509 && IT_CHARPOS (*it) + 1 < ZV
8510 && indented_beyond_p (IT_CHARPOS (*it) + 1,
8511 IT_BYTEPOS (*it) + 1,
8512 it->selective))
8514 success_p = next_element_from_ellipsis (it);
8515 it->dpvec_char_len = -1;
8518 else if (it->c == '\r' && it->selective == -1)
8520 /* A value of selective == -1 means that everything from the
8521 CR to the end of the line is invisible, with maybe an
8522 ellipsis displayed for it. */
8523 success_p = next_element_from_ellipsis (it);
8524 it->dpvec_char_len = -1;
8529 /* Value is false if end of buffer reached. */
8530 eassert (!success_p || it->what != IT_CHARACTER || it->len > 0);
8531 return success_p;
8535 /* Run the redisplay end trigger hook for IT. */
8537 static void
8538 run_redisplay_end_trigger_hook (struct it *it)
8540 /* IT->glyph_row should be non-null, i.e. we should be actually
8541 displaying something, or otherwise we should not run the hook. */
8542 eassert (it->glyph_row);
8544 ptrdiff_t charpos = it->redisplay_end_trigger_charpos;
8545 it->redisplay_end_trigger_charpos = 0;
8547 /* Since we are *trying* to run these functions, don't try to run
8548 them again, even if they get an error. */
8549 wset_redisplay_end_trigger (it->w, Qnil);
8550 CALLN (Frun_hook_with_args, Qredisplay_end_trigger_functions, it->window,
8551 make_number (charpos));
8553 /* Notice if it changed the face of the character we are on. */
8554 handle_face_prop (it);
8558 /* Deliver a composition display element. Unlike the other
8559 next_element_from_XXX, this function is not registered in the array
8560 get_next_element[]. It is called from next_element_from_buffer and
8561 next_element_from_string when necessary. */
8563 static bool
8564 next_element_from_composition (struct it *it)
8566 it->what = IT_COMPOSITION;
8567 it->len = it->cmp_it.nbytes;
8568 if (STRINGP (it->string))
8570 if (it->c < 0)
8572 IT_STRING_CHARPOS (*it) += it->cmp_it.nchars;
8573 IT_STRING_BYTEPOS (*it) += it->cmp_it.nbytes;
8574 return false;
8576 it->position = it->current.string_pos;
8577 it->object = it->string;
8578 it->c = composition_update_it (&it->cmp_it, IT_STRING_CHARPOS (*it),
8579 IT_STRING_BYTEPOS (*it), it->string);
8581 else
8583 if (it->c < 0)
8585 IT_CHARPOS (*it) += it->cmp_it.nchars;
8586 IT_BYTEPOS (*it) += it->cmp_it.nbytes;
8587 if (it->bidi_p)
8589 if (it->bidi_it.new_paragraph)
8590 bidi_paragraph_init (it->paragraph_embedding, &it->bidi_it,
8591 false);
8592 /* Resync the bidi iterator with IT's new position.
8593 FIXME: this doesn't support bidirectional text. */
8594 while (it->bidi_it.charpos < IT_CHARPOS (*it))
8595 bidi_move_to_visually_next (&it->bidi_it);
8597 return false;
8599 it->position = it->current.pos;
8600 it->object = it->w->contents;
8601 it->c = composition_update_it (&it->cmp_it, IT_CHARPOS (*it),
8602 IT_BYTEPOS (*it), Qnil);
8604 return true;
8609 /***********************************************************************
8610 Moving an iterator without producing glyphs
8611 ***********************************************************************/
8613 /* Check if iterator is at a position corresponding to a valid buffer
8614 position after some move_it_ call. */
8616 #define IT_POS_VALID_AFTER_MOVE_P(it) \
8617 ((it)->method != GET_FROM_STRING || IT_STRING_CHARPOS (*it) == 0)
8620 /* Move iterator IT to a specified buffer or X position within one
8621 line on the display without producing glyphs.
8623 OP should be a bit mask including some or all of these bits:
8624 MOVE_TO_X: Stop upon reaching x-position TO_X.
8625 MOVE_TO_POS: Stop upon reaching buffer or string position TO_CHARPOS.
8626 Regardless of OP's value, stop upon reaching the end of the display line.
8628 TO_X is normally a value 0 <= TO_X <= IT->last_visible_x.
8629 This means, in particular, that TO_X includes window's horizontal
8630 scroll amount.
8632 The return value has several possible values that
8633 say what condition caused the scan to stop:
8635 MOVE_POS_MATCH_OR_ZV
8636 - when TO_POS or ZV was reached.
8638 MOVE_X_REACHED
8639 -when TO_X was reached before TO_POS or ZV were reached.
8641 MOVE_LINE_CONTINUED
8642 - when we reached the end of the display area and the line must
8643 be continued.
8645 MOVE_LINE_TRUNCATED
8646 - when we reached the end of the display area and the line is
8647 truncated.
8649 MOVE_NEWLINE_OR_CR
8650 - when we stopped at a line end, i.e. a newline or a CR and selective
8651 display is on. */
8653 static enum move_it_result
8654 move_it_in_display_line_to (struct it *it,
8655 ptrdiff_t to_charpos, int to_x,
8656 enum move_operation_enum op)
8658 enum move_it_result result = MOVE_UNDEFINED;
8659 struct glyph_row *saved_glyph_row;
8660 struct it wrap_it, atpos_it, atx_it, ppos_it;
8661 void *wrap_data = NULL, *atpos_data = NULL, *atx_data = NULL;
8662 void *ppos_data = NULL;
8663 bool may_wrap = false;
8664 enum it_method prev_method = it->method;
8665 ptrdiff_t closest_pos UNINIT;
8666 ptrdiff_t prev_pos = IT_CHARPOS (*it);
8667 bool saw_smaller_pos = prev_pos < to_charpos;
8668 bool line_number_pending = false;
8670 /* Don't produce glyphs in produce_glyphs. */
8671 saved_glyph_row = it->glyph_row;
8672 it->glyph_row = NULL;
8674 /* Use wrap_it to save a copy of IT wherever a word wrap could
8675 occur. Use atpos_it to save a copy of IT at the desired buffer
8676 position, if found, so that we can scan ahead and check if the
8677 word later overshoots the window edge. Use atx_it similarly, for
8678 pixel positions. */
8679 wrap_it.sp = -1;
8680 atpos_it.sp = -1;
8681 atx_it.sp = -1;
8683 /* Use ppos_it under bidi reordering to save a copy of IT for the
8684 initial position. We restore that position in IT when we have
8685 scanned the entire display line without finding a match for
8686 TO_CHARPOS and all the character positions are greater than
8687 TO_CHARPOS. We then restart the scan from the initial position,
8688 and stop at CLOSEST_POS, which is a position > TO_CHARPOS that is
8689 the closest to TO_CHARPOS. */
8690 if (it->bidi_p)
8692 if ((op & MOVE_TO_POS) && IT_CHARPOS (*it) >= to_charpos)
8694 SAVE_IT (ppos_it, *it, ppos_data);
8695 closest_pos = IT_CHARPOS (*it);
8697 else
8698 closest_pos = ZV;
8701 #define BUFFER_POS_REACHED_P() \
8702 ((op & MOVE_TO_POS) != 0 \
8703 && BUFFERP (it->object) \
8704 && (IT_CHARPOS (*it) == to_charpos \
8705 || ((!it->bidi_p \
8706 || BIDI_AT_BASE_LEVEL (it->bidi_it)) \
8707 && IT_CHARPOS (*it) > to_charpos) \
8708 || (it->what == IT_COMPOSITION \
8709 && ((IT_CHARPOS (*it) > to_charpos \
8710 && to_charpos >= it->cmp_it.charpos) \
8711 || (IT_CHARPOS (*it) < to_charpos \
8712 && to_charpos <= it->cmp_it.charpos)))) \
8713 && (it->method == GET_FROM_BUFFER \
8714 || (it->method == GET_FROM_DISPLAY_VECTOR \
8715 && it->dpvec + it->current.dpvec_index + 1 >= it->dpend)))
8717 if (it->hpos == 0)
8719 /* If line numbers are being displayed, produce a line number. */
8720 if (should_produce_line_number (it))
8722 if (it->current_x == it->first_visible_x)
8723 maybe_produce_line_number (it);
8724 else
8725 line_number_pending = true;
8727 /* If there's a line-/wrap-prefix, handle it. */
8728 if (it->method == GET_FROM_BUFFER)
8729 handle_line_prefix (it);
8732 if (IT_CHARPOS (*it) < CHARPOS (this_line_min_pos))
8733 SET_TEXT_POS (this_line_min_pos, IT_CHARPOS (*it), IT_BYTEPOS (*it));
8735 while (true)
8737 int x, i, ascent = 0, descent = 0;
8739 /* Utility macro to reset an iterator with x, ascent, and descent. */
8740 #define IT_RESET_X_ASCENT_DESCENT(IT) \
8741 ((IT)->current_x = x, (IT)->max_ascent = ascent, \
8742 (IT)->max_descent = descent)
8744 /* Stop if we move beyond TO_CHARPOS (after an image or a
8745 display string or stretch glyph). */
8746 if ((op & MOVE_TO_POS) != 0
8747 && BUFFERP (it->object)
8748 && it->method == GET_FROM_BUFFER
8749 && (((!it->bidi_p
8750 /* When the iterator is at base embedding level, we
8751 are guaranteed that characters are delivered for
8752 display in strictly increasing order of their
8753 buffer positions. */
8754 || BIDI_AT_BASE_LEVEL (it->bidi_it))
8755 && IT_CHARPOS (*it) > to_charpos)
8756 || (it->bidi_p
8757 && (prev_method == GET_FROM_IMAGE
8758 || prev_method == GET_FROM_STRETCH
8759 || prev_method == GET_FROM_STRING)
8760 /* Passed TO_CHARPOS from left to right. */
8761 && ((prev_pos < to_charpos
8762 && IT_CHARPOS (*it) > to_charpos)
8763 /* Passed TO_CHARPOS from right to left. */
8764 || (prev_pos > to_charpos
8765 && IT_CHARPOS (*it) < to_charpos)))))
8767 if (it->line_wrap != WORD_WRAP || wrap_it.sp < 0)
8769 result = MOVE_POS_MATCH_OR_ZV;
8770 break;
8772 else if (it->line_wrap == WORD_WRAP && atpos_it.sp < 0)
8773 /* If wrap_it is valid, the current position might be in a
8774 word that is wrapped. So, save the iterator in
8775 atpos_it and continue to see if wrapping happens. */
8776 SAVE_IT (atpos_it, *it, atpos_data);
8779 /* Stop when ZV reached.
8780 We used to stop here when TO_CHARPOS reached as well, but that is
8781 too soon if this glyph does not fit on this line. So we handle it
8782 explicitly below. */
8783 if (!get_next_display_element (it))
8785 result = MOVE_POS_MATCH_OR_ZV;
8786 break;
8789 if (it->line_wrap == TRUNCATE)
8791 /* If it->pixel_width is zero, the last PRODUCE_GLYPHS call
8792 produced something that doesn't consume any screen estate
8793 in the text area, so we don't want to exit the loop at
8794 TO_CHARPOS, before we produce the glyph for that buffer
8795 position. This happens, e.g., when there's an overlay at
8796 TO_CHARPOS that draws a fringe bitmap. */
8797 if (BUFFER_POS_REACHED_P ()
8798 && (it->pixel_width > 0
8799 || IT_CHARPOS (*it) > to_charpos
8800 || it->area != TEXT_AREA))
8802 result = MOVE_POS_MATCH_OR_ZV;
8803 break;
8806 else
8808 if (it->line_wrap == WORD_WRAP && it->area == TEXT_AREA)
8810 if (IT_DISPLAYING_WHITESPACE (it))
8811 may_wrap = true;
8812 else if (may_wrap)
8814 /* We have reached a glyph that follows one or more
8815 whitespace characters. If the position is
8816 already found, we are done. */
8817 if (atpos_it.sp >= 0)
8819 RESTORE_IT (it, &atpos_it, atpos_data);
8820 result = MOVE_POS_MATCH_OR_ZV;
8821 goto done;
8823 if (atx_it.sp >= 0)
8825 RESTORE_IT (it, &atx_it, atx_data);
8826 result = MOVE_X_REACHED;
8827 goto done;
8829 /* Otherwise, we can wrap here. */
8830 SAVE_IT (wrap_it, *it, wrap_data);
8831 may_wrap = false;
8836 /* Remember the line height for the current line, in case
8837 the next element doesn't fit on the line. */
8838 ascent = it->max_ascent;
8839 descent = it->max_descent;
8841 /* The call to produce_glyphs will get the metrics of the
8842 display element IT is loaded with. Record the x-position
8843 before this display element, in case it doesn't fit on the
8844 line. */
8845 x = it->current_x;
8847 PRODUCE_GLYPHS (it);
8849 if (it->area != TEXT_AREA)
8851 prev_method = it->method;
8852 if (it->method == GET_FROM_BUFFER)
8853 prev_pos = IT_CHARPOS (*it);
8854 set_iterator_to_next (it, true);
8855 if (IT_CHARPOS (*it) < CHARPOS (this_line_min_pos))
8856 SET_TEXT_POS (this_line_min_pos,
8857 IT_CHARPOS (*it), IT_BYTEPOS (*it));
8858 if (it->bidi_p
8859 && (op & MOVE_TO_POS)
8860 && IT_CHARPOS (*it) > to_charpos
8861 && IT_CHARPOS (*it) < closest_pos)
8862 closest_pos = IT_CHARPOS (*it);
8863 continue;
8866 /* The number of glyphs we get back in IT->nglyphs will normally
8867 be 1 except when IT->c is (i) a TAB, or (ii) a multi-glyph
8868 character on a terminal frame, or (iii) a line end. For the
8869 second case, IT->nglyphs - 1 padding glyphs will be present.
8870 (On X frames, there is only one glyph produced for a
8871 composite character.)
8873 The behavior implemented below means, for continuation lines,
8874 that as many spaces of a TAB as fit on the current line are
8875 displayed there. For terminal frames, as many glyphs of a
8876 multi-glyph character are displayed in the current line, too.
8877 This is what the old redisplay code did, and we keep it that
8878 way. Under X, the whole shape of a complex character must
8879 fit on the line or it will be completely displayed in the
8880 next line.
8882 Note that both for tabs and padding glyphs, all glyphs have
8883 the same width. */
8884 if (it->nglyphs)
8886 /* More than one glyph or glyph doesn't fit on line. All
8887 glyphs have the same width. */
8888 int single_glyph_width = it->pixel_width / it->nglyphs;
8889 int new_x;
8890 int x_before_this_char = x;
8891 int hpos_before_this_char = it->hpos;
8893 for (i = 0; i < it->nglyphs; ++i, x = new_x)
8895 new_x = x + single_glyph_width;
8897 /* We want to leave anything reaching TO_X to the caller. */
8898 if ((op & MOVE_TO_X) && new_x > to_x)
8900 if (BUFFER_POS_REACHED_P ())
8902 if (it->line_wrap != WORD_WRAP || wrap_it.sp < 0)
8903 goto buffer_pos_reached;
8904 if (atpos_it.sp < 0)
8906 SAVE_IT (atpos_it, *it, atpos_data);
8907 IT_RESET_X_ASCENT_DESCENT (&atpos_it);
8910 else
8912 if (it->line_wrap != WORD_WRAP || wrap_it.sp < 0)
8914 it->current_x = x;
8915 result = MOVE_X_REACHED;
8916 break;
8918 if (atx_it.sp < 0)
8920 SAVE_IT (atx_it, *it, atx_data);
8921 IT_RESET_X_ASCENT_DESCENT (&atx_it);
8926 if (/* Lines are continued. */
8927 it->line_wrap != TRUNCATE
8928 && (/* And glyph doesn't fit on the line. */
8929 new_x > it->last_visible_x
8930 /* Or it fits exactly and we're on a window
8931 system frame. */
8932 || (new_x == it->last_visible_x
8933 && FRAME_WINDOW_P (it->f)
8934 && ((it->bidi_p && it->bidi_it.paragraph_dir == R2L)
8935 ? WINDOW_LEFT_FRINGE_WIDTH (it->w)
8936 : WINDOW_RIGHT_FRINGE_WIDTH (it->w)))))
8938 bool moved_forward = false;
8940 if (/* IT->hpos == 0 means the very first glyph
8941 doesn't fit on the line, e.g. a wide image. */
8942 it->hpos == 0
8943 || (new_x == it->last_visible_x
8944 && FRAME_WINDOW_P (it->f)))
8946 ++it->hpos;
8947 it->current_x = new_x;
8949 /* The character's last glyph just barely fits
8950 in this row. */
8951 if (i == it->nglyphs - 1)
8953 /* If this is the destination position,
8954 return a position *before* it in this row,
8955 now that we know it fits in this row. */
8956 if (BUFFER_POS_REACHED_P ())
8958 bool can_wrap = true;
8960 /* If we are at a whitespace character
8961 that barely fits on this screen line,
8962 but the next character is also
8963 whitespace, we cannot wrap here. */
8964 if (it->line_wrap == WORD_WRAP
8965 && wrap_it.sp >= 0
8966 && may_wrap
8967 && IT_OVERFLOW_NEWLINE_INTO_FRINGE (it))
8969 struct it tem_it;
8970 void *tem_data = NULL;
8972 SAVE_IT (tem_it, *it, tem_data);
8973 set_iterator_to_next (it, true);
8974 if (get_next_display_element (it)
8975 && IT_DISPLAYING_WHITESPACE (it))
8976 can_wrap = false;
8977 RESTORE_IT (it, &tem_it, tem_data);
8979 if (it->line_wrap != WORD_WRAP
8980 || wrap_it.sp < 0
8981 /* If we've just found whitespace
8982 where we can wrap, effectively
8983 ignore the previous wrap point --
8984 it is no longer relevant, but we
8985 won't have an opportunity to
8986 update it, since we've reached
8987 the edge of this screen line. */
8988 || (may_wrap && can_wrap
8989 && IT_OVERFLOW_NEWLINE_INTO_FRINGE (it)))
8991 it->hpos = hpos_before_this_char;
8992 it->current_x = x_before_this_char;
8993 result = MOVE_POS_MATCH_OR_ZV;
8994 break;
8996 if (it->line_wrap == WORD_WRAP
8997 && atpos_it.sp < 0)
8999 SAVE_IT (atpos_it, *it, atpos_data);
9000 atpos_it.current_x = x_before_this_char;
9001 atpos_it.hpos = hpos_before_this_char;
9005 prev_method = it->method;
9006 if (it->method == GET_FROM_BUFFER)
9007 prev_pos = IT_CHARPOS (*it);
9008 set_iterator_to_next (it, true);
9009 if (IT_CHARPOS (*it) < CHARPOS (this_line_min_pos))
9010 SET_TEXT_POS (this_line_min_pos,
9011 IT_CHARPOS (*it), IT_BYTEPOS (*it));
9012 /* On graphical terminals, newlines may
9013 "overflow" into the fringe if
9014 overflow-newline-into-fringe is non-nil.
9015 On text terminals, and on graphical
9016 terminals with no right margin, newlines
9017 may overflow into the last glyph on the
9018 display line.*/
9019 if (!FRAME_WINDOW_P (it->f)
9020 || ((it->bidi_p
9021 && it->bidi_it.paragraph_dir == R2L)
9022 ? WINDOW_LEFT_FRINGE_WIDTH (it->w)
9023 : WINDOW_RIGHT_FRINGE_WIDTH (it->w)) == 0
9024 || IT_OVERFLOW_NEWLINE_INTO_FRINGE (it))
9026 if (!get_next_display_element (it))
9028 result = MOVE_POS_MATCH_OR_ZV;
9029 break;
9031 moved_forward = true;
9032 if (BUFFER_POS_REACHED_P ())
9034 if (ITERATOR_AT_END_OF_LINE_P (it))
9035 result = MOVE_POS_MATCH_OR_ZV;
9036 else
9037 result = MOVE_LINE_CONTINUED;
9038 break;
9040 if (ITERATOR_AT_END_OF_LINE_P (it)
9041 && (it->line_wrap != WORD_WRAP
9042 || wrap_it.sp < 0
9043 || IT_OVERFLOW_NEWLINE_INTO_FRINGE (it)))
9045 result = MOVE_NEWLINE_OR_CR;
9046 break;
9051 else
9052 IT_RESET_X_ASCENT_DESCENT (it);
9054 /* If the screen line ends with whitespace, and we
9055 are under word-wrap, don't use wrap_it: it is no
9056 longer relevant, but we won't have an opportunity
9057 to update it, since we are done with this screen
9058 line. */
9059 if (may_wrap && IT_OVERFLOW_NEWLINE_INTO_FRINGE (it)
9060 /* If the character after the one which set the
9061 may_wrap flag is also whitespace, we can't
9062 wrap here, since the screen line cannot be
9063 wrapped in the middle of whitespace.
9064 Therefore, wrap_it _is_ relevant in that
9065 case. */
9066 && !(moved_forward && IT_DISPLAYING_WHITESPACE (it)))
9068 /* If we've found TO_X, go back there, as we now
9069 know the last word fits on this screen line. */
9070 if ((op & MOVE_TO_X) && new_x == it->last_visible_x
9071 && atx_it.sp >= 0)
9073 RESTORE_IT (it, &atx_it, atx_data);
9074 atpos_it.sp = -1;
9075 atx_it.sp = -1;
9076 result = MOVE_X_REACHED;
9077 break;
9080 else if (wrap_it.sp >= 0)
9082 RESTORE_IT (it, &wrap_it, wrap_data);
9083 atpos_it.sp = -1;
9084 atx_it.sp = -1;
9087 TRACE_MOVE ((stderr, "move_it_in: continued at %d\n",
9088 IT_CHARPOS (*it)));
9089 result = MOVE_LINE_CONTINUED;
9090 break;
9093 if (BUFFER_POS_REACHED_P ())
9095 if (it->line_wrap != WORD_WRAP || wrap_it.sp < 0)
9096 goto buffer_pos_reached;
9097 if (it->line_wrap == WORD_WRAP && atpos_it.sp < 0)
9099 SAVE_IT (atpos_it, *it, atpos_data);
9100 IT_RESET_X_ASCENT_DESCENT (&atpos_it);
9104 if (new_x > it->first_visible_x)
9106 /* If we have reached the visible portion of the
9107 screen line, produce the line number if needed. */
9108 if (line_number_pending)
9110 line_number_pending = false;
9111 it->current_x = it->first_visible_x;
9112 maybe_produce_line_number (it);
9113 it->current_x += new_x - it->first_visible_x;
9115 /* Glyph is visible. Increment number of glyphs that
9116 would be displayed. */
9117 ++it->hpos;
9121 if (result != MOVE_UNDEFINED)
9122 break;
9124 else if (BUFFER_POS_REACHED_P ())
9126 buffer_pos_reached:
9127 IT_RESET_X_ASCENT_DESCENT (it);
9128 result = MOVE_POS_MATCH_OR_ZV;
9129 break;
9131 else if ((op & MOVE_TO_X) && it->current_x >= to_x)
9133 /* Stop when TO_X specified and reached. This check is
9134 necessary here because of lines consisting of a line end,
9135 only. The line end will not produce any glyphs and we
9136 would never get MOVE_X_REACHED. */
9137 eassert (it->nglyphs == 0);
9138 result = MOVE_X_REACHED;
9139 break;
9142 /* Is this a line end? If yes, we're done. */
9143 if (ITERATOR_AT_END_OF_LINE_P (it))
9145 /* If we are past TO_CHARPOS, but never saw any character
9146 positions smaller than TO_CHARPOS, return
9147 MOVE_POS_MATCH_OR_ZV, like the unidirectional display
9148 did. */
9149 if (it->bidi_p && (op & MOVE_TO_POS) != 0)
9151 if (!saw_smaller_pos && IT_CHARPOS (*it) > to_charpos)
9153 if (closest_pos < ZV)
9155 RESTORE_IT (it, &ppos_it, ppos_data);
9156 /* Don't recurse if closest_pos is equal to
9157 to_charpos, since we have just tried that. */
9158 if (closest_pos != to_charpos)
9159 move_it_in_display_line_to (it, closest_pos, -1,
9160 MOVE_TO_POS);
9161 result = MOVE_POS_MATCH_OR_ZV;
9163 else
9164 goto buffer_pos_reached;
9166 else if (it->line_wrap == WORD_WRAP && atpos_it.sp >= 0
9167 && IT_CHARPOS (*it) > to_charpos)
9168 goto buffer_pos_reached;
9169 else
9170 result = MOVE_NEWLINE_OR_CR;
9172 else
9173 result = MOVE_NEWLINE_OR_CR;
9174 /* If we've processed the newline, make sure this flag is
9175 reset, as it must only be set when the newline itself is
9176 processed. */
9177 if (result == MOVE_NEWLINE_OR_CR)
9178 it->constrain_row_ascent_descent_p = false;
9179 break;
9182 prev_method = it->method;
9183 if (it->method == GET_FROM_BUFFER)
9184 prev_pos = IT_CHARPOS (*it);
9185 /* The current display element has been consumed. Advance
9186 to the next. */
9187 set_iterator_to_next (it, true);
9188 if (IT_CHARPOS (*it) < CHARPOS (this_line_min_pos))
9189 SET_TEXT_POS (this_line_min_pos, IT_CHARPOS (*it), IT_BYTEPOS (*it));
9190 if (IT_CHARPOS (*it) < to_charpos)
9191 saw_smaller_pos = true;
9192 if (it->bidi_p
9193 && (op & MOVE_TO_POS)
9194 && IT_CHARPOS (*it) >= to_charpos
9195 && IT_CHARPOS (*it) < closest_pos)
9196 closest_pos = IT_CHARPOS (*it);
9198 /* Stop if lines are truncated and IT's current x-position is
9199 past the right edge of the window now. */
9200 if (it->line_wrap == TRUNCATE
9201 && it->current_x >= it->last_visible_x)
9203 if (!FRAME_WINDOW_P (it->f)
9204 || ((it->bidi_p && it->bidi_it.paragraph_dir == R2L)
9205 ? WINDOW_LEFT_FRINGE_WIDTH (it->w)
9206 : WINDOW_RIGHT_FRINGE_WIDTH (it->w)) == 0
9207 || IT_OVERFLOW_NEWLINE_INTO_FRINGE (it))
9209 bool at_eob_p = false;
9211 if ((at_eob_p = !get_next_display_element (it))
9212 || BUFFER_POS_REACHED_P ()
9213 /* If we are past TO_CHARPOS, but never saw any
9214 character positions smaller than TO_CHARPOS,
9215 return MOVE_POS_MATCH_OR_ZV, like the
9216 unidirectional display did. */
9217 || (it->bidi_p && (op & MOVE_TO_POS) != 0
9218 && !saw_smaller_pos
9219 && IT_CHARPOS (*it) > to_charpos))
9221 if (it->bidi_p
9222 && !BUFFER_POS_REACHED_P ()
9223 && !at_eob_p && closest_pos < ZV)
9225 RESTORE_IT (it, &ppos_it, ppos_data);
9226 if (closest_pos != to_charpos)
9227 move_it_in_display_line_to (it, closest_pos, -1,
9228 MOVE_TO_POS);
9230 result = MOVE_POS_MATCH_OR_ZV;
9231 break;
9233 if (ITERATOR_AT_END_OF_LINE_P (it))
9235 result = MOVE_NEWLINE_OR_CR;
9236 break;
9239 else if (it->bidi_p && (op & MOVE_TO_POS) != 0
9240 && !saw_smaller_pos
9241 && IT_CHARPOS (*it) > to_charpos)
9243 if (closest_pos < ZV)
9245 RESTORE_IT (it, &ppos_it, ppos_data);
9246 if (closest_pos != to_charpos)
9247 move_it_in_display_line_to (it, closest_pos, -1,
9248 MOVE_TO_POS);
9250 result = MOVE_POS_MATCH_OR_ZV;
9251 break;
9253 result = MOVE_LINE_TRUNCATED;
9254 break;
9256 #undef IT_RESET_X_ASCENT_DESCENT
9259 #undef BUFFER_POS_REACHED_P
9261 /* If we scanned beyond TO_POS, restore the saved iterator either to
9262 the wrap point (if found), or to atpos/atx location. We decide which
9263 data to use to restore the saved iterator state by their X coordinates,
9264 since buffer positions might increase non-monotonically with screen
9265 coordinates due to bidi reordering. */
9266 if (result == MOVE_LINE_CONTINUED
9267 && it->line_wrap == WORD_WRAP
9268 && wrap_it.sp >= 0
9269 && ((atpos_it.sp >= 0 && wrap_it.current_x < atpos_it.current_x)
9270 || (atx_it.sp >= 0 && wrap_it.current_x < atx_it.current_x)))
9271 RESTORE_IT (it, &wrap_it, wrap_data);
9272 else if (atpos_it.sp >= 0)
9273 RESTORE_IT (it, &atpos_it, atpos_data);
9274 else if (atx_it.sp >= 0)
9275 RESTORE_IT (it, &atx_it, atx_data);
9277 done:
9279 if (atpos_data)
9280 bidi_unshelve_cache (atpos_data, true);
9281 if (atx_data)
9282 bidi_unshelve_cache (atx_data, true);
9283 if (wrap_data)
9284 bidi_unshelve_cache (wrap_data, true);
9285 if (ppos_data)
9286 bidi_unshelve_cache (ppos_data, true);
9288 /* Restore the iterator settings altered at the beginning of this
9289 function. */
9290 it->glyph_row = saved_glyph_row;
9291 return result;
9294 /* For external use. */
9295 void
9296 move_it_in_display_line (struct it *it,
9297 ptrdiff_t to_charpos, int to_x,
9298 enum move_operation_enum op)
9300 if (it->line_wrap == WORD_WRAP
9301 && (op & MOVE_TO_X))
9303 struct it save_it;
9304 void *save_data = NULL;
9305 int skip;
9307 SAVE_IT (save_it, *it, save_data);
9308 skip = move_it_in_display_line_to (it, to_charpos, to_x, op);
9309 /* When word-wrap is on, TO_X may lie past the end
9310 of a wrapped line. Then it->current is the
9311 character on the next line, so backtrack to the
9312 space before the wrap point. */
9313 if (skip == MOVE_LINE_CONTINUED)
9315 int prev_x = max (it->current_x - 1, 0);
9316 RESTORE_IT (it, &save_it, save_data);
9317 move_it_in_display_line_to
9318 (it, -1, prev_x, MOVE_TO_X);
9320 else
9321 bidi_unshelve_cache (save_data, true);
9323 else
9324 move_it_in_display_line_to (it, to_charpos, to_x, op);
9328 /* Move IT forward until it satisfies one or more of the criteria in
9329 TO_CHARPOS, TO_X, TO_Y, and TO_VPOS.
9331 OP is a bit-mask that specifies where to stop, and in particular,
9332 which of those four position arguments makes a difference. See the
9333 description of enum move_operation_enum.
9335 If TO_CHARPOS is in invisible text, e.g. a truncated part of a
9336 screen line, this function will set IT to the next position that is
9337 displayed to the right of TO_CHARPOS on the screen.
9339 Return the maximum pixel length of any line scanned but never more
9340 than it.last_visible_x. */
9343 move_it_to (struct it *it, ptrdiff_t to_charpos, int to_x, int to_y, int to_vpos, int op)
9345 enum move_it_result skip, skip2 = MOVE_X_REACHED;
9346 int line_height, line_start_x = 0, reached = 0;
9347 int max_current_x = 0;
9348 void *backup_data = NULL;
9350 for (;;)
9352 if (op & MOVE_TO_VPOS)
9354 /* If no TO_CHARPOS and no TO_X specified, stop at the
9355 start of the line TO_VPOS. */
9356 if ((op & (MOVE_TO_X | MOVE_TO_POS)) == 0)
9358 if (it->vpos == to_vpos)
9360 reached = 1;
9361 break;
9363 else
9364 skip = move_it_in_display_line_to (it, -1, -1, 0);
9366 else
9368 /* TO_VPOS >= 0 means stop at TO_X in the line at
9369 TO_VPOS, or at TO_POS, whichever comes first. */
9370 if (it->vpos == to_vpos)
9372 reached = 2;
9373 break;
9376 skip = move_it_in_display_line_to (it, to_charpos, to_x, op);
9378 if (skip == MOVE_POS_MATCH_OR_ZV || it->vpos == to_vpos)
9380 reached = 3;
9381 break;
9383 else if (skip == MOVE_X_REACHED && it->vpos != to_vpos)
9385 /* We have reached TO_X but not in the line we want. */
9386 skip = move_it_in_display_line_to (it, to_charpos,
9387 -1, MOVE_TO_POS);
9388 if (skip == MOVE_POS_MATCH_OR_ZV)
9390 reached = 4;
9391 break;
9396 else if (op & MOVE_TO_Y)
9398 struct it it_backup;
9400 if (it->line_wrap == WORD_WRAP)
9401 SAVE_IT (it_backup, *it, backup_data);
9403 /* TO_Y specified means stop at TO_X in the line containing
9404 TO_Y---or at TO_CHARPOS if this is reached first. The
9405 problem is that we can't really tell whether the line
9406 contains TO_Y before we have completely scanned it, and
9407 this may skip past TO_X. What we do is to first scan to
9408 TO_X.
9410 If TO_X is not specified, use a TO_X of zero. The reason
9411 is to make the outcome of this function more predictable.
9412 If we didn't use TO_X == 0, we would stop at the end of
9413 the line which is probably not what a caller would expect
9414 to happen. */
9415 skip = move_it_in_display_line_to
9416 (it, to_charpos, ((op & MOVE_TO_X) ? to_x : 0),
9417 (MOVE_TO_X | (op & MOVE_TO_POS)));
9419 /* If TO_CHARPOS is reached or ZV, we don't have to do more. */
9420 if (skip == MOVE_POS_MATCH_OR_ZV)
9421 reached = 5;
9422 else if (skip == MOVE_X_REACHED)
9424 /* If TO_X was reached, we want to know whether TO_Y is
9425 in the line. We know this is the case if the already
9426 scanned glyphs make the line tall enough. Otherwise,
9427 we must check by scanning the rest of the line. */
9428 line_height = it->max_ascent + it->max_descent;
9429 if (to_y >= it->current_y
9430 && to_y < it->current_y + line_height)
9432 reached = 6;
9433 break;
9435 SAVE_IT (it_backup, *it, backup_data);
9436 TRACE_MOVE ((stderr, "move_it: from %d\n", IT_CHARPOS (*it)));
9437 skip2 = move_it_in_display_line_to (it, to_charpos, -1,
9438 op & MOVE_TO_POS);
9439 TRACE_MOVE ((stderr, "move_it: to %d\n", IT_CHARPOS (*it)));
9440 line_height = it->max_ascent + it->max_descent;
9441 TRACE_MOVE ((stderr, "move_it: line_height = %d\n", line_height));
9443 if (to_y >= it->current_y
9444 && to_y < it->current_y + line_height)
9446 /* If TO_Y is in this line and TO_X was reached
9447 above, we scanned too far. We have to restore
9448 IT's settings to the ones before skipping. But
9449 keep the more accurate values of max_ascent and
9450 max_descent we've found while skipping the rest
9451 of the line, for the sake of callers, such as
9452 pos_visible_p, that need to know the line
9453 height. */
9454 int max_ascent = it->max_ascent;
9455 int max_descent = it->max_descent;
9457 RESTORE_IT (it, &it_backup, backup_data);
9458 it->max_ascent = max_ascent;
9459 it->max_descent = max_descent;
9460 reached = 6;
9462 else
9464 skip = skip2;
9465 if (skip == MOVE_POS_MATCH_OR_ZV)
9466 reached = 7;
9469 else
9471 /* Check whether TO_Y is in this line. */
9472 line_height = it->max_ascent + it->max_descent;
9473 TRACE_MOVE ((stderr, "move_it: line_height = %d\n", line_height));
9475 if (to_y >= it->current_y
9476 && to_y < it->current_y + line_height)
9478 if (to_y > it->current_y)
9479 max_current_x = max (it->current_x, max_current_x);
9481 /* When word-wrap is on, TO_X may lie past the end
9482 of a wrapped line. Then it->current is the
9483 character on the next line, so backtrack to the
9484 space before the wrap point. */
9485 if (skip == MOVE_LINE_CONTINUED
9486 && it->line_wrap == WORD_WRAP)
9488 int prev_x = max (it->current_x - 1, 0);
9489 RESTORE_IT (it, &it_backup, backup_data);
9490 skip = move_it_in_display_line_to
9491 (it, -1, prev_x, MOVE_TO_X);
9494 reached = 6;
9498 if (reached)
9500 max_current_x = max (it->current_x, max_current_x);
9501 break;
9504 else if (BUFFERP (it->object)
9505 && (it->method == GET_FROM_BUFFER
9506 || it->method == GET_FROM_STRETCH)
9507 && IT_CHARPOS (*it) >= to_charpos
9508 /* Under bidi iteration, a call to set_iterator_to_next
9509 can scan far beyond to_charpos if the initial
9510 portion of the next line needs to be reordered. In
9511 that case, give move_it_in_display_line_to another
9512 chance below. */
9513 && !(it->bidi_p
9514 && it->bidi_it.scan_dir == -1))
9515 skip = MOVE_POS_MATCH_OR_ZV;
9516 else
9517 skip = move_it_in_display_line_to (it, to_charpos, -1, MOVE_TO_POS);
9519 switch (skip)
9521 case MOVE_POS_MATCH_OR_ZV:
9522 max_current_x = max (it->current_x, max_current_x);
9523 reached = 8;
9524 goto out;
9526 case MOVE_NEWLINE_OR_CR:
9527 max_current_x = max (it->current_x, max_current_x);
9528 set_iterator_to_next (it, true);
9529 it->continuation_lines_width = 0;
9530 break;
9532 case MOVE_LINE_TRUNCATED:
9533 max_current_x = it->last_visible_x;
9534 it->continuation_lines_width = 0;
9535 reseat_at_next_visible_line_start (it, false);
9536 if ((op & MOVE_TO_POS) != 0
9537 && IT_CHARPOS (*it) > to_charpos)
9539 reached = 9;
9540 goto out;
9542 break;
9544 case MOVE_LINE_CONTINUED:
9545 max_current_x = it->last_visible_x;
9546 /* For continued lines ending in a tab, some of the glyphs
9547 associated with the tab are displayed on the current
9548 line. Since it->current_x does not include these glyphs,
9549 we use it->last_visible_x instead. */
9550 if (it->c == '\t')
9552 it->continuation_lines_width += it->last_visible_x;
9553 /* When moving by vpos, ensure that the iterator really
9554 advances to the next line (bug#847, bug#969). Fixme:
9555 do we need to do this in other circumstances? */
9556 if (it->current_x != it->last_visible_x
9557 && (op & MOVE_TO_VPOS)
9558 && !(op & (MOVE_TO_X | MOVE_TO_POS)))
9560 line_start_x = it->current_x + it->pixel_width
9561 - it->last_visible_x;
9562 if (FRAME_WINDOW_P (it->f))
9564 struct face *face = FACE_FROM_ID (it->f, it->face_id);
9565 struct font *face_font = face->font;
9567 /* When display_line produces a continued line
9568 that ends in a TAB, it skips a tab stop that
9569 is closer than the font's space character
9570 width (see x_produce_glyphs where it produces
9571 the stretch glyph which represents a TAB).
9572 We need to reproduce the same logic here. */
9573 eassert (face_font);
9574 if (face_font)
9576 if (line_start_x < face_font->space_width)
9577 line_start_x
9578 += it->tab_width * face_font->space_width;
9581 set_iterator_to_next (it, false);
9584 else
9585 it->continuation_lines_width += it->current_x;
9586 break;
9588 default:
9589 emacs_abort ();
9592 /* Reset/increment for the next run. */
9593 recenter_overlay_lists (current_buffer, IT_CHARPOS (*it));
9594 it->current_x = line_start_x;
9595 line_start_x = 0;
9596 it->hpos = 0;
9597 it->current_y += it->max_ascent + it->max_descent;
9598 ++it->vpos;
9599 last_height = it->max_ascent + it->max_descent;
9600 it->max_ascent = it->max_descent = 0;
9603 out:
9605 /* On text terminals, we may stop at the end of a line in the middle
9606 of a multi-character glyph. If the glyph itself is continued,
9607 i.e. it is actually displayed on the next line, don't treat this
9608 stopping point as valid; move to the next line instead (unless
9609 that brings us offscreen). */
9610 if (!FRAME_WINDOW_P (it->f)
9611 && op & MOVE_TO_POS
9612 && IT_CHARPOS (*it) == to_charpos
9613 && it->what == IT_CHARACTER
9614 && it->nglyphs > 1
9615 && it->line_wrap == WINDOW_WRAP
9616 && it->current_x == it->last_visible_x - 1
9617 && it->c != '\n'
9618 && it->c != '\t'
9619 && it->w->window_end_valid
9620 && it->vpos < it->w->window_end_vpos)
9622 it->continuation_lines_width += it->current_x;
9623 it->current_x = it->hpos = it->max_ascent = it->max_descent = 0;
9624 it->current_y += it->max_ascent + it->max_descent;
9625 ++it->vpos;
9626 last_height = it->max_ascent + it->max_descent;
9629 if (backup_data)
9630 bidi_unshelve_cache (backup_data, true);
9632 TRACE_MOVE ((stderr, "move_it_to: reached %d\n", reached));
9634 return max_current_x;
9638 /* Move iterator IT backward by a specified y-distance DY, DY >= 0.
9640 If DY > 0, move IT backward at least that many pixels. DY = 0
9641 means move IT backward to the preceding line start or BEGV. This
9642 function may move over more than DY pixels if IT->current_y - DY
9643 ends up in the middle of a line; in this case IT->current_y will be
9644 set to the top of the line moved to. */
9646 void
9647 move_it_vertically_backward (struct it *it, int dy)
9649 int nlines, h;
9650 struct it it2, it3;
9651 void *it2data = NULL, *it3data = NULL;
9652 ptrdiff_t start_pos;
9653 int nchars_per_row
9654 = (it->last_visible_x - it->first_visible_x) / FRAME_COLUMN_WIDTH (it->f);
9655 ptrdiff_t pos_limit;
9657 move_further_back:
9658 eassert (dy >= 0);
9660 start_pos = IT_CHARPOS (*it);
9662 /* Estimate how many newlines we must move back. */
9663 nlines = max (1, dy / default_line_pixel_height (it->w));
9664 if (it->line_wrap == TRUNCATE || nchars_per_row == 0)
9665 pos_limit = BEGV;
9666 else
9667 pos_limit = max (start_pos - nlines * nchars_per_row, BEGV);
9669 /* Set the iterator's position that many lines back. But don't go
9670 back more than NLINES full screen lines -- this wins a day with
9671 buffers which have very long lines. */
9672 while (nlines-- && IT_CHARPOS (*it) > pos_limit)
9673 back_to_previous_visible_line_start (it);
9675 /* Reseat the iterator here. When moving backward, we don't want
9676 reseat to skip forward over invisible text, set up the iterator
9677 to deliver from overlay strings at the new position etc. So,
9678 use reseat_1 here. */
9679 reseat_1 (it, it->current.pos, true);
9681 /* We are now surely at a line start. */
9682 it->current_x = it->hpos = 0; /* FIXME: this is incorrect when bidi
9683 reordering is in effect. */
9684 it->continuation_lines_width = 0;
9686 /* Move forward and see what y-distance we moved. First move to the
9687 start of the next line so that we get its height. We need this
9688 height to be able to tell whether we reached the specified
9689 y-distance. */
9690 SAVE_IT (it2, *it, it2data);
9691 it2.max_ascent = it2.max_descent = 0;
9694 move_it_to (&it2, start_pos, -1, -1, it2.vpos + 1,
9695 MOVE_TO_POS | MOVE_TO_VPOS);
9697 while (!(IT_POS_VALID_AFTER_MOVE_P (&it2)
9698 /* If we are in a display string which starts at START_POS,
9699 and that display string includes a newline, and we are
9700 right after that newline (i.e. at the beginning of a
9701 display line), exit the loop, because otherwise we will
9702 infloop, since move_it_to will see that it is already at
9703 START_POS and will not move. */
9704 || (it2.method == GET_FROM_STRING
9705 && IT_CHARPOS (it2) == start_pos
9706 && SREF (it2.string, IT_STRING_BYTEPOS (it2) - 1) == '\n')));
9707 eassert (IT_CHARPOS (*it) >= BEGV);
9708 SAVE_IT (it3, it2, it3data);
9710 move_it_to (&it2, start_pos, -1, -1, -1, MOVE_TO_POS);
9711 eassert (IT_CHARPOS (*it) >= BEGV);
9712 /* H is the actual vertical distance from the position in *IT
9713 and the starting position. */
9714 h = it2.current_y - it->current_y;
9715 /* NLINES is the distance in number of lines. */
9716 nlines = it2.vpos - it->vpos;
9718 /* Correct IT's y and vpos position
9719 so that they are relative to the starting point. */
9720 it->vpos -= nlines;
9721 it->current_y -= h;
9723 if (dy == 0)
9725 /* DY == 0 means move to the start of the screen line. The
9726 value of nlines is > 0 if continuation lines were involved,
9727 or if the original IT position was at start of a line. */
9728 RESTORE_IT (it, it, it2data);
9729 if (nlines > 0)
9730 move_it_by_lines (it, nlines);
9731 /* The above code moves us to some position NLINES down,
9732 usually to its first glyph (leftmost in an L2R line), but
9733 that's not necessarily the start of the line, under bidi
9734 reordering. We want to get to the character position
9735 that is immediately after the newline of the previous
9736 line. */
9737 if (it->bidi_p
9738 && !it->continuation_lines_width
9739 && !STRINGP (it->string)
9740 && IT_CHARPOS (*it) > BEGV
9741 && FETCH_BYTE (IT_BYTEPOS (*it) - 1) != '\n')
9743 ptrdiff_t cp = IT_CHARPOS (*it), bp = IT_BYTEPOS (*it);
9745 DEC_BOTH (cp, bp);
9746 cp = find_newline_no_quit (cp, bp, -1, NULL);
9747 move_it_to (it, cp, -1, -1, -1, MOVE_TO_POS);
9749 bidi_unshelve_cache (it3data, true);
9751 else
9753 /* The y-position we try to reach, relative to *IT.
9754 Note that H has been subtracted in front of the if-statement. */
9755 int target_y = it->current_y + h - dy;
9756 int y0 = it3.current_y;
9757 int y1;
9758 int line_height;
9760 RESTORE_IT (&it3, &it3, it3data);
9761 y1 = line_bottom_y (&it3);
9762 line_height = y1 - y0;
9763 RESTORE_IT (it, it, it2data);
9764 /* If we did not reach target_y, try to move further backward if
9765 we can. If we moved too far backward, try to move forward. */
9766 if (target_y < it->current_y
9767 /* This is heuristic. In a window that's 3 lines high, with
9768 a line height of 13 pixels each, recentering with point
9769 on the bottom line will try to move -39/2 = 19 pixels
9770 backward. Try to avoid moving into the first line. */
9771 && (it->current_y - target_y
9772 > min (window_box_height (it->w), line_height * 2 / 3))
9773 && IT_CHARPOS (*it) > BEGV)
9775 TRACE_MOVE ((stderr, " not far enough -> move_vert %d\n",
9776 target_y - it->current_y));
9777 dy = it->current_y - target_y;
9778 goto move_further_back;
9780 else if (target_y >= it->current_y + line_height
9781 && IT_CHARPOS (*it) < ZV)
9783 /* Should move forward by at least one line, maybe more.
9785 Note: Calling move_it_by_lines can be expensive on
9786 terminal frames, where compute_motion is used (via
9787 vmotion) to do the job, when there are very long lines
9788 and truncate-lines is nil. That's the reason for
9789 treating terminal frames specially here. */
9791 if (!FRAME_WINDOW_P (it->f))
9792 move_it_vertically (it, target_y - it->current_y);
9793 else
9797 move_it_by_lines (it, 1);
9799 while (target_y >= line_bottom_y (it) && IT_CHARPOS (*it) < ZV);
9806 /* Move IT by a specified amount of pixel lines DY. DY negative means
9807 move backwards. DY = 0 means move to start of screen line. At the
9808 end, IT will be on the start of a screen line. */
9810 void
9811 move_it_vertically (struct it *it, int dy)
9813 if (dy <= 0)
9814 move_it_vertically_backward (it, -dy);
9815 else
9817 TRACE_MOVE ((stderr, "move_it_v: from %d, %d\n", IT_CHARPOS (*it), dy));
9818 move_it_to (it, ZV, -1, it->current_y + dy, -1,
9819 MOVE_TO_POS | MOVE_TO_Y);
9820 TRACE_MOVE ((stderr, "move_it_v: to %d\n", IT_CHARPOS (*it)));
9822 /* If buffer ends in ZV without a newline, move to the start of
9823 the line to satisfy the post-condition. */
9824 if (IT_CHARPOS (*it) == ZV
9825 && ZV > BEGV
9826 && FETCH_BYTE (IT_BYTEPOS (*it) - 1) != '\n')
9827 move_it_by_lines (it, 0);
9832 /* Move iterator IT past the end of the text line it is in. */
9834 void
9835 move_it_past_eol (struct it *it)
9837 enum move_it_result rc;
9839 rc = move_it_in_display_line_to (it, Z, 0, MOVE_TO_POS);
9840 if (rc == MOVE_NEWLINE_OR_CR)
9841 set_iterator_to_next (it, false);
9845 /* Move IT by a specified number DVPOS of screen lines down. DVPOS
9846 negative means move up. DVPOS == 0 means move to the start of the
9847 screen line.
9849 Optimization idea: If we would know that IT->f doesn't use
9850 a face with proportional font, we could be faster for
9851 truncate-lines nil. */
9853 void
9854 move_it_by_lines (struct it *it, ptrdiff_t dvpos)
9857 /* The commented-out optimization uses vmotion on terminals. This
9858 gives bad results, because elements like it->what, on which
9859 callers such as pos_visible_p rely, aren't updated. */
9860 /* struct position pos;
9861 if (!FRAME_WINDOW_P (it->f))
9863 struct text_pos textpos;
9865 pos = *vmotion (IT_CHARPOS (*it), dvpos, it->w);
9866 SET_TEXT_POS (textpos, pos.bufpos, pos.bytepos);
9867 reseat (it, textpos, true);
9868 it->vpos += pos.vpos;
9869 it->current_y += pos.vpos;
9871 else */
9873 if (dvpos == 0)
9875 /* DVPOS == 0 means move to the start of the screen line. */
9876 move_it_vertically_backward (it, 0);
9877 /* Let next call to line_bottom_y calculate real line height. */
9878 last_height = 0;
9880 else if (dvpos > 0)
9882 move_it_to (it, -1, -1, -1, it->vpos + dvpos, MOVE_TO_VPOS);
9883 if (!IT_POS_VALID_AFTER_MOVE_P (it))
9885 /* Only move to the next buffer position if we ended up in a
9886 string from display property, not in an overlay string
9887 (before-string or after-string). That is because the
9888 latter don't conceal the underlying buffer position, so
9889 we can ask to move the iterator to the exact position we
9890 are interested in. Note that, even if we are already at
9891 IT_CHARPOS (*it), the call below is not a no-op, as it
9892 will detect that we are at the end of the string, pop the
9893 iterator, and compute it->current_x and it->hpos
9894 correctly. */
9895 move_it_to (it, IT_CHARPOS (*it) + it->string_from_display_prop_p,
9896 -1, -1, -1, MOVE_TO_POS);
9899 else
9901 struct it it2;
9902 void *it2data = NULL;
9903 ptrdiff_t start_charpos, i;
9904 int nchars_per_row
9905 = (it->last_visible_x - it->first_visible_x) / FRAME_COLUMN_WIDTH (it->f);
9906 bool hit_pos_limit = false;
9907 ptrdiff_t pos_limit;
9909 /* Start at the beginning of the screen line containing IT's
9910 position. This may actually move vertically backwards,
9911 in case of overlays, so adjust dvpos accordingly. */
9912 dvpos += it->vpos;
9913 move_it_vertically_backward (it, 0);
9914 dvpos -= it->vpos;
9916 /* Go back -DVPOS buffer lines, but no farther than -DVPOS full
9917 screen lines, and reseat the iterator there. */
9918 start_charpos = IT_CHARPOS (*it);
9919 if (it->line_wrap == TRUNCATE || nchars_per_row == 0)
9920 pos_limit = BEGV;
9921 else
9922 pos_limit = max (start_charpos + dvpos * nchars_per_row, BEGV);
9924 for (i = -dvpos; i > 0 && IT_CHARPOS (*it) > pos_limit; --i)
9925 back_to_previous_visible_line_start (it);
9926 if (i > 0 && IT_CHARPOS (*it) <= pos_limit)
9927 hit_pos_limit = true;
9928 reseat (it, it->current.pos, true);
9930 /* Move further back if we end up in a string or an image. */
9931 while (!IT_POS_VALID_AFTER_MOVE_P (it))
9933 /* First try to move to start of display line. */
9934 dvpos += it->vpos;
9935 move_it_vertically_backward (it, 0);
9936 dvpos -= it->vpos;
9937 if (IT_POS_VALID_AFTER_MOVE_P (it))
9938 break;
9939 /* If start of line is still in string or image,
9940 move further back. */
9941 back_to_previous_visible_line_start (it);
9942 reseat (it, it->current.pos, true);
9943 dvpos--;
9946 it->current_x = it->hpos = 0;
9948 /* Above call may have moved too far if continuation lines
9949 are involved. Scan forward and see if it did. */
9950 SAVE_IT (it2, *it, it2data);
9951 it2.vpos = it2.current_y = 0;
9952 move_it_to (&it2, start_charpos, -1, -1, -1, MOVE_TO_POS);
9953 it->vpos -= it2.vpos;
9954 it->current_y -= it2.current_y;
9955 it->current_x = it->hpos = 0;
9957 /* If we moved too far back, move IT some lines forward. */
9958 if (it2.vpos > -dvpos)
9960 int delta = it2.vpos + dvpos;
9962 RESTORE_IT (&it2, &it2, it2data);
9963 SAVE_IT (it2, *it, it2data);
9964 move_it_to (it, -1, -1, -1, it->vpos + delta, MOVE_TO_VPOS);
9965 /* Move back again if we got too far ahead. */
9966 if (IT_CHARPOS (*it) >= start_charpos)
9967 RESTORE_IT (it, &it2, it2data);
9968 else
9969 bidi_unshelve_cache (it2data, true);
9971 else if (hit_pos_limit && pos_limit > BEGV
9972 && dvpos < 0 && it2.vpos < -dvpos)
9974 /* If we hit the limit, but still didn't make it far enough
9975 back, that means there's a display string with a newline
9976 covering a large chunk of text, and that caused
9977 back_to_previous_visible_line_start try to go too far.
9978 Punish those who commit such atrocities by going back
9979 until we've reached DVPOS, after lifting the limit, which
9980 could make it slow for very long lines. "If it hurts,
9981 don't do that!" */
9982 dvpos += it2.vpos;
9983 RESTORE_IT (it, it, it2data);
9984 for (i = -dvpos; i > 0; --i)
9986 back_to_previous_visible_line_start (it);
9987 it->vpos--;
9989 reseat_1 (it, it->current.pos, true);
9991 else
9992 RESTORE_IT (it, it, it2data);
9997 partial_line_height (struct it *it_origin)
9999 int partial_height;
10000 void *it_data = NULL;
10001 struct it it;
10002 SAVE_IT (it, *it_origin, it_data);
10003 move_it_to (&it, ZV, -1, it.last_visible_y, -1,
10004 MOVE_TO_POS | MOVE_TO_Y);
10005 if (it.what == IT_EOB)
10007 int vis_height = it.last_visible_y - it.current_y;
10008 int height = it.ascent + it.descent;
10009 partial_height = (vis_height < height) ? vis_height : 0;
10011 else
10013 int last_line_y = it.current_y;
10014 move_it_by_lines (&it, 1);
10015 partial_height = (it.current_y > it.last_visible_y)
10016 ? it.last_visible_y - last_line_y : 0;
10018 RESTORE_IT (&it, &it, it_data);
10019 return partial_height;
10022 /* Return true if IT points into the middle of a display vector. */
10024 bool
10025 in_display_vector_p (struct it *it)
10027 return (it->method == GET_FROM_DISPLAY_VECTOR
10028 && it->current.dpvec_index > 0
10029 && it->dpvec + it->current.dpvec_index != it->dpend);
10032 DEFUN ("window-text-pixel-size", Fwindow_text_pixel_size, Swindow_text_pixel_size, 0, 6, 0,
10033 doc: /* Return the size of the text of WINDOW's buffer in pixels.
10034 WINDOW must be a live window and defaults to the selected one. The
10035 return value is a cons of the maximum pixel-width of any text line and
10036 the maximum pixel-height of all text lines.
10038 The optional argument FROM, if non-nil, specifies the first text
10039 position and defaults to the minimum accessible position of the buffer.
10040 If FROM is t, use the minimum accessible position that starts a
10041 non-empty line. TO, if non-nil, specifies the last text position and
10042 defaults to the maximum accessible position of the buffer. If TO is t,
10043 use the maximum accessible position that ends a non-empty line.
10045 The optional argument X-LIMIT, if non-nil, specifies the maximum text
10046 width that can be returned. X-LIMIT nil or omitted, means to use the
10047 pixel-width of WINDOW's body; use this if you want to know how high
10048 WINDOW should be become in order to fit all of its buffer's text with
10049 the width of WINDOW unaltered. Use the maximum width WINDOW may assume
10050 if you intend to change WINDOW's width. In any case, text whose
10051 x-coordinate is beyond X-LIMIT is ignored. Since calculating the width
10052 of long lines can take some time, it's always a good idea to make this
10053 argument as small as possible; in particular, if the buffer contains
10054 long lines that shall be truncated anyway.
10056 The optional argument Y-LIMIT, if non-nil, specifies the maximum text
10057 height (excluding the height of the mode- or header-line, if any) that
10058 can be returned. Text lines whose y-coordinate is beyond Y-LIMIT are
10059 ignored. Since calculating the text height of a large buffer can take
10060 some time, it makes sense to specify this argument if the size of the
10061 buffer is large or unknown.
10063 Optional argument MODE-AND-HEADER-LINE nil or omitted means do not
10064 include the height of the mode- or header-line of WINDOW in the return
10065 value. If it is either the symbol `mode-line' or `header-line', include
10066 only the height of that line, if present, in the return value. If t,
10067 include the height of both, if present, in the return value. */)
10068 (Lisp_Object window, Lisp_Object from, Lisp_Object to, Lisp_Object x_limit,
10069 Lisp_Object y_limit, Lisp_Object mode_and_header_line)
10071 struct window *w = decode_live_window (window);
10072 Lisp_Object buffer = w->contents;
10073 struct buffer *b;
10074 struct it it;
10075 struct buffer *old_b = NULL;
10076 ptrdiff_t start, end, pos;
10077 struct text_pos startp;
10078 void *itdata = NULL;
10079 int c, max_x = 0, max_y = 0, x = 0, y = 0;
10081 CHECK_BUFFER (buffer);
10082 b = XBUFFER (buffer);
10084 if (b != current_buffer)
10086 old_b = current_buffer;
10087 set_buffer_internal (b);
10090 if (NILP (from))
10091 start = BEGV;
10092 else if (EQ (from, Qt))
10094 start = pos = BEGV;
10095 while ((pos++ < ZV) && (c = FETCH_CHAR (pos))
10096 && (c == ' ' || c == '\t' || c == '\n' || c == '\r'))
10097 start = pos;
10098 while ((pos-- > BEGV) && (c = FETCH_CHAR (pos)) && (c == ' ' || c == '\t'))
10099 start = pos;
10101 else
10103 CHECK_NUMBER_COERCE_MARKER (from);
10104 start = min (max (XINT (from), BEGV), ZV);
10107 if (NILP (to))
10108 end = ZV;
10109 else if (EQ (to, Qt))
10111 end = pos = ZV;
10112 while ((pos-- > BEGV) && (c = FETCH_CHAR (pos))
10113 && (c == ' ' || c == '\t' || c == '\n' || c == '\r'))
10114 end = pos;
10115 while ((pos++ < ZV) && (c = FETCH_CHAR (pos)) && (c == ' ' || c == '\t'))
10116 end = pos;
10118 else
10120 CHECK_NUMBER_COERCE_MARKER (to);
10121 end = max (start, min (XINT (to), ZV));
10124 if (!NILP (x_limit) && RANGED_INTEGERP (0, x_limit, INT_MAX))
10125 max_x = XINT (x_limit);
10127 if (NILP (y_limit))
10128 max_y = INT_MAX;
10129 else if (RANGED_INTEGERP (0, y_limit, INT_MAX))
10130 max_y = XINT (y_limit);
10132 itdata = bidi_shelve_cache ();
10133 SET_TEXT_POS (startp, start, CHAR_TO_BYTE (start));
10134 start_display (&it, w, startp);
10136 if (NILP (x_limit))
10137 x = move_it_to (&it, end, -1, max_y, -1, MOVE_TO_POS | MOVE_TO_Y);
10138 else
10140 it.last_visible_x = max_x;
10141 /* Actually, we never want move_it_to stop at to_x. But to make
10142 sure that move_it_in_display_line_to always moves far enough,
10143 we set it to INT_MAX and specify MOVE_TO_X. */
10144 x = move_it_to (&it, end, INT_MAX, max_y, -1,
10145 MOVE_TO_POS | MOVE_TO_X | MOVE_TO_Y);
10146 /* Don't return more than X-LIMIT. */
10147 if (x > max_x)
10148 x = max_x;
10151 /* Subtract height of header-line which was counted automatically by
10152 start_display. */
10153 y = it.current_y + it.max_ascent + it.max_descent
10154 - WINDOW_HEADER_LINE_HEIGHT (w);
10155 /* Don't return more than Y-LIMIT. */
10156 if (y > max_y)
10157 y = max_y;
10159 if (EQ (mode_and_header_line, Qheader_line)
10160 || EQ (mode_and_header_line, Qt))
10161 /* Re-add height of header-line as requested. */
10162 y = y + WINDOW_HEADER_LINE_HEIGHT (w);
10164 if (EQ (mode_and_header_line, Qmode_line)
10165 || EQ (mode_and_header_line, Qt))
10166 /* Add height of mode-line as requested. */
10167 y = y + WINDOW_MODE_LINE_HEIGHT (w);
10169 bidi_unshelve_cache (itdata, false);
10171 if (old_b)
10172 set_buffer_internal (old_b);
10174 return Fcons (make_number (x), make_number (y));
10177 /***********************************************************************
10178 Messages
10179 ***********************************************************************/
10181 /* Return the number of arguments the format string FORMAT needs. */
10183 static ptrdiff_t
10184 format_nargs (char const *format)
10186 ptrdiff_t nargs = 0;
10187 for (char const *p = format; (p = strchr (p, '%')); p++)
10188 if (p[1] == '%')
10189 p++;
10190 else
10191 nargs++;
10192 return nargs;
10195 /* Add a message with format string FORMAT and formatted arguments
10196 to *Messages*. */
10198 void
10199 add_to_log (const char *format, ...)
10201 va_list ap;
10202 va_start (ap, format);
10203 vadd_to_log (format, ap);
10204 va_end (ap);
10207 void
10208 vadd_to_log (char const *format, va_list ap)
10210 ptrdiff_t form_nargs = format_nargs (format);
10211 ptrdiff_t nargs = 1 + form_nargs;
10212 Lisp_Object args[10];
10213 eassert (nargs <= ARRAYELTS (args));
10214 AUTO_STRING (args0, format);
10215 args[0] = args0;
10216 for (ptrdiff_t i = 1; i <= nargs; i++)
10217 args[i] = va_arg (ap, Lisp_Object);
10218 Lisp_Object msg = Qnil;
10219 msg = Fformat_message (nargs, args);
10221 ptrdiff_t len = SBYTES (msg) + 1;
10222 USE_SAFE_ALLOCA;
10223 char *buffer = SAFE_ALLOCA (len);
10224 memcpy (buffer, SDATA (msg), len);
10226 message_dolog (buffer, len - 1, true, STRING_MULTIBYTE (msg));
10227 SAFE_FREE ();
10231 /* Output a newline in the *Messages* buffer if "needs" one. */
10233 void
10234 message_log_maybe_newline (void)
10236 if (message_log_need_newline)
10237 message_dolog ("", 0, true, false);
10241 /* Add a string M of length NBYTES to the message log, optionally
10242 terminated with a newline when NLFLAG is true. MULTIBYTE, if
10243 true, means interpret the contents of M as multibyte. This
10244 function calls low-level routines in order to bypass text property
10245 hooks, etc. which might not be safe to run.
10247 This may GC (insert may run before/after change hooks),
10248 so the buffer M must NOT point to a Lisp string. */
10250 void
10251 message_dolog (const char *m, ptrdiff_t nbytes, bool nlflag, bool multibyte)
10253 const unsigned char *msg = (const unsigned char *) m;
10255 if (!NILP (Vmemory_full))
10256 return;
10258 if (!NILP (Vmessage_log_max))
10260 struct buffer *oldbuf;
10261 Lisp_Object oldpoint, oldbegv, oldzv;
10262 int old_windows_or_buffers_changed = windows_or_buffers_changed;
10263 ptrdiff_t point_at_end = 0;
10264 ptrdiff_t zv_at_end = 0;
10265 Lisp_Object old_deactivate_mark;
10267 old_deactivate_mark = Vdeactivate_mark;
10268 oldbuf = current_buffer;
10270 /* Ensure the Messages buffer exists, and switch to it.
10271 If we created it, set the major-mode. */
10272 bool newbuffer = NILP (Fget_buffer (Vmessages_buffer_name));
10273 Fset_buffer (Fget_buffer_create (Vmessages_buffer_name));
10274 if (newbuffer
10275 && !NILP (Ffboundp (intern ("messages-buffer-mode"))))
10276 call0 (intern ("messages-buffer-mode"));
10278 bset_undo_list (current_buffer, Qt);
10279 bset_cache_long_scans (current_buffer, Qnil);
10281 oldpoint = message_dolog_marker1;
10282 set_marker_restricted_both (oldpoint, Qnil, PT, PT_BYTE);
10283 oldbegv = message_dolog_marker2;
10284 set_marker_restricted_both (oldbegv, Qnil, BEGV, BEGV_BYTE);
10285 oldzv = message_dolog_marker3;
10286 set_marker_restricted_both (oldzv, Qnil, ZV, ZV_BYTE);
10288 if (PT == Z)
10289 point_at_end = 1;
10290 if (ZV == Z)
10291 zv_at_end = 1;
10293 BEGV = BEG;
10294 BEGV_BYTE = BEG_BYTE;
10295 ZV = Z;
10296 ZV_BYTE = Z_BYTE;
10297 TEMP_SET_PT_BOTH (Z, Z_BYTE);
10299 /* Insert the string--maybe converting multibyte to single byte
10300 or vice versa, so that all the text fits the buffer. */
10301 if (multibyte
10302 && NILP (BVAR (current_buffer, enable_multibyte_characters)))
10304 ptrdiff_t i;
10305 int c, char_bytes;
10306 char work[1];
10308 /* Convert a multibyte string to single-byte
10309 for the *Message* buffer. */
10310 for (i = 0; i < nbytes; i += char_bytes)
10312 c = string_char_and_length (msg + i, &char_bytes);
10313 work[0] = CHAR_TO_BYTE8 (c);
10314 insert_1_both (work, 1, 1, true, false, false);
10317 else if (! multibyte
10318 && ! NILP (BVAR (current_buffer, enable_multibyte_characters)))
10320 ptrdiff_t i;
10321 int c, char_bytes;
10322 unsigned char str[MAX_MULTIBYTE_LENGTH];
10323 /* Convert a single-byte string to multibyte
10324 for the *Message* buffer. */
10325 for (i = 0; i < nbytes; i++)
10327 c = msg[i];
10328 MAKE_CHAR_MULTIBYTE (c);
10329 char_bytes = CHAR_STRING (c, str);
10330 insert_1_both ((char *) str, 1, char_bytes, true, false, false);
10333 else if (nbytes)
10334 insert_1_both (m, chars_in_text (msg, nbytes), nbytes,
10335 true, false, false);
10337 if (nlflag)
10339 ptrdiff_t this_bol, this_bol_byte, prev_bol, prev_bol_byte;
10340 printmax_t dups;
10342 insert_1_both ("\n", 1, 1, true, false, false);
10344 scan_newline (Z, Z_BYTE, BEG, BEG_BYTE, -2, false);
10345 this_bol = PT;
10346 this_bol_byte = PT_BYTE;
10348 /* See if this line duplicates the previous one.
10349 If so, combine duplicates. */
10350 if (this_bol > BEG)
10352 scan_newline (PT, PT_BYTE, BEG, BEG_BYTE, -2, false);
10353 prev_bol = PT;
10354 prev_bol_byte = PT_BYTE;
10356 dups = message_log_check_duplicate (prev_bol_byte,
10357 this_bol_byte);
10358 if (dups)
10360 del_range_both (prev_bol, prev_bol_byte,
10361 this_bol, this_bol_byte, false);
10362 if (dups > 1)
10364 char dupstr[sizeof " [ times]"
10365 + INT_STRLEN_BOUND (printmax_t)];
10367 /* If you change this format, don't forget to also
10368 change message_log_check_duplicate. */
10369 int duplen = sprintf (dupstr, " [%"pMd" times]", dups);
10370 TEMP_SET_PT_BOTH (Z - 1, Z_BYTE - 1);
10371 insert_1_both (dupstr, duplen, duplen,
10372 true, false, true);
10377 /* If we have more than the desired maximum number of lines
10378 in the *Messages* buffer now, delete the oldest ones.
10379 This is safe because we don't have undo in this buffer. */
10381 if (NATNUMP (Vmessage_log_max))
10383 scan_newline (Z, Z_BYTE, BEG, BEG_BYTE,
10384 -XFASTINT (Vmessage_log_max) - 1, false);
10385 del_range_both (BEG, BEG_BYTE, PT, PT_BYTE, false);
10388 BEGV = marker_position (oldbegv);
10389 BEGV_BYTE = marker_byte_position (oldbegv);
10391 if (zv_at_end)
10393 ZV = Z;
10394 ZV_BYTE = Z_BYTE;
10396 else
10398 ZV = marker_position (oldzv);
10399 ZV_BYTE = marker_byte_position (oldzv);
10402 if (point_at_end)
10403 TEMP_SET_PT_BOTH (Z, Z_BYTE);
10404 else
10405 /* We can't do Fgoto_char (oldpoint) because it will run some
10406 Lisp code. */
10407 TEMP_SET_PT_BOTH (marker_position (oldpoint),
10408 marker_byte_position (oldpoint));
10410 unchain_marker (XMARKER (oldpoint));
10411 unchain_marker (XMARKER (oldbegv));
10412 unchain_marker (XMARKER (oldzv));
10414 /* We called insert_1_both above with its 5th argument (PREPARE)
10415 false, which prevents insert_1_both from calling
10416 prepare_to_modify_buffer, which in turns prevents us from
10417 incrementing windows_or_buffers_changed even if *Messages* is
10418 shown in some window. So we must manually set
10419 windows_or_buffers_changed here to make up for that. */
10420 windows_or_buffers_changed = old_windows_or_buffers_changed;
10421 bset_redisplay (current_buffer);
10423 set_buffer_internal (oldbuf);
10425 message_log_need_newline = !nlflag;
10426 Vdeactivate_mark = old_deactivate_mark;
10431 /* We are at the end of the buffer after just having inserted a newline.
10432 (Note: We depend on the fact we won't be crossing the gap.)
10433 Check to see if the most recent message looks a lot like the previous one.
10434 Return 0 if different, 1 if the new one should just replace it, or a
10435 value N > 1 if we should also append " [N times]". */
10437 static intmax_t
10438 message_log_check_duplicate (ptrdiff_t prev_bol_byte, ptrdiff_t this_bol_byte)
10440 ptrdiff_t i;
10441 ptrdiff_t len = Z_BYTE - 1 - this_bol_byte;
10442 bool seen_dots = false;
10443 unsigned char *p1 = BUF_BYTE_ADDRESS (current_buffer, prev_bol_byte);
10444 unsigned char *p2 = BUF_BYTE_ADDRESS (current_buffer, this_bol_byte);
10446 for (i = 0; i < len; i++)
10448 if (i >= 3 && p1[i - 3] == '.' && p1[i - 2] == '.' && p1[i - 1] == '.')
10449 seen_dots = true;
10450 if (p1[i] != p2[i])
10451 return seen_dots;
10453 p1 += len;
10454 if (*p1 == '\n')
10455 return 2;
10456 if (*p1++ == ' ' && *p1++ == '[')
10458 char *pend;
10459 intmax_t n = strtoimax ((char *) p1, &pend, 10);
10460 if (0 < n && n < INTMAX_MAX && strncmp (pend, " times]\n", 8) == 0)
10461 return n + 1;
10463 return 0;
10467 /* Display an echo area message M with a specified length of NBYTES
10468 bytes. The string may include null characters. If M is not a
10469 string, clear out any existing message, and let the mini-buffer
10470 text show through.
10472 This function cancels echoing. */
10474 void
10475 message3 (Lisp_Object m)
10477 clear_message (true, true);
10478 cancel_echoing ();
10480 /* First flush out any partial line written with print. */
10481 message_log_maybe_newline ();
10482 if (STRINGP (m))
10484 ptrdiff_t nbytes = SBYTES (m);
10485 bool multibyte = STRING_MULTIBYTE (m);
10486 char *buffer;
10487 USE_SAFE_ALLOCA;
10488 SAFE_ALLOCA_STRING (buffer, m);
10489 message_dolog (buffer, nbytes, true, multibyte);
10490 SAFE_FREE ();
10492 if (! inhibit_message)
10493 message3_nolog (m);
10496 /* Log the message M to stderr. Log an empty line if M is not a string. */
10498 static void
10499 message_to_stderr (Lisp_Object m)
10501 if (noninteractive_need_newline)
10503 noninteractive_need_newline = false;
10504 fputc ('\n', stderr);
10506 if (STRINGP (m))
10508 Lisp_Object coding_system = Vlocale_coding_system;
10509 Lisp_Object s;
10511 if (!NILP (Vcoding_system_for_write))
10512 coding_system = Vcoding_system_for_write;
10513 if (!NILP (coding_system))
10514 s = code_convert_string_norecord (m, coding_system, true);
10515 else
10516 s = m;
10518 fwrite (SDATA (s), SBYTES (s), 1, stderr);
10520 if (!cursor_in_echo_area)
10521 fputc ('\n', stderr);
10522 fflush (stderr);
10525 /* The non-logging version of message3.
10526 This does not cancel echoing, because it is used for echoing.
10527 Perhaps we need to make a separate function for echoing
10528 and make this cancel echoing. */
10530 void
10531 message3_nolog (Lisp_Object m)
10533 struct frame *sf = SELECTED_FRAME ();
10535 if (FRAME_INITIAL_P (sf))
10536 message_to_stderr (m);
10537 /* Error messages get reported properly by cmd_error, so this must be just an
10538 informative message; if the frame hasn't really been initialized yet, just
10539 toss it. */
10540 else if (INTERACTIVE && sf->glyphs_initialized_p)
10542 /* Get the frame containing the mini-buffer
10543 that the selected frame is using. */
10544 Lisp_Object mini_window = FRAME_MINIBUF_WINDOW (sf);
10545 Lisp_Object frame = XWINDOW (mini_window)->frame;
10546 struct frame *f = XFRAME (frame);
10548 if (FRAME_VISIBLE_P (sf) && !FRAME_VISIBLE_P (f))
10549 Fmake_frame_visible (frame);
10551 if (STRINGP (m) && SCHARS (m) > 0)
10553 set_message (m);
10554 if (minibuffer_auto_raise)
10555 Fraise_frame (frame);
10556 /* Assume we are not echoing.
10557 (If we are, echo_now will override this.) */
10558 echo_message_buffer = Qnil;
10560 else
10561 clear_message (true, true);
10563 do_pending_window_change (false);
10564 echo_area_display (true);
10565 do_pending_window_change (false);
10566 if (FRAME_TERMINAL (f)->frame_up_to_date_hook)
10567 (*FRAME_TERMINAL (f)->frame_up_to_date_hook) (f);
10572 /* Display a null-terminated echo area message M. If M is 0, clear
10573 out any existing message, and let the mini-buffer text show through.
10575 The buffer M must continue to exist until after the echo area gets
10576 cleared or some other message gets displayed there. Do not pass
10577 text that is stored in a Lisp string. Do not pass text in a buffer
10578 that was alloca'd. */
10580 void
10581 message1 (const char *m)
10583 message3 (m ? build_unibyte_string (m) : Qnil);
10587 /* The non-logging counterpart of message1. */
10589 void
10590 message1_nolog (const char *m)
10592 message3_nolog (m ? build_unibyte_string (m) : Qnil);
10595 /* Display a message M which contains a single %s
10596 which gets replaced with STRING. */
10598 void
10599 message_with_string (const char *m, Lisp_Object string, bool log)
10601 CHECK_STRING (string);
10603 bool need_message;
10604 if (noninteractive)
10605 need_message = !!m;
10606 else if (!INTERACTIVE)
10607 need_message = false;
10608 else
10610 /* The frame whose minibuffer we're going to display the message on.
10611 It may be larger than the selected frame, so we need
10612 to use its buffer, not the selected frame's buffer. */
10613 Lisp_Object mini_window;
10614 struct frame *f, *sf = SELECTED_FRAME ();
10616 /* Get the frame containing the minibuffer
10617 that the selected frame is using. */
10618 mini_window = FRAME_MINIBUF_WINDOW (sf);
10619 f = XFRAME (WINDOW_FRAME (XWINDOW (mini_window)));
10621 /* Error messages get reported properly by cmd_error, so this must be
10622 just an informative message; if the frame hasn't really been
10623 initialized yet, just toss it. */
10624 need_message = f->glyphs_initialized_p;
10627 if (need_message)
10629 AUTO_STRING (fmt, m);
10630 Lisp_Object msg = CALLN (Fformat_message, fmt, string);
10632 if (noninteractive)
10633 message_to_stderr (msg);
10634 else
10636 if (log)
10637 message3 (msg);
10638 else
10639 message3_nolog (msg);
10641 /* Print should start at the beginning of the message
10642 buffer next time. */
10643 message_buf_print = false;
10649 /* Dump an informative message to the minibuf. If M is 0, clear out
10650 any existing message, and let the mini-buffer text show through.
10652 The message must be safe ASCII (because when Emacs is
10653 non-interactive the message is sent straight to stderr without
10654 encoding first) and the format must not contain ` or ' (because
10655 this function does not account for `text-quoting-style'). If your
10656 message and format do not fit into this category, convert your
10657 arguments to Lisp objects and use Fmessage instead. */
10659 static void ATTRIBUTE_FORMAT_PRINTF (1, 0)
10660 vmessage (const char *m, va_list ap)
10662 if (noninteractive)
10664 if (m)
10666 if (noninteractive_need_newline)
10667 putc ('\n', stderr);
10668 noninteractive_need_newline = false;
10669 vfprintf (stderr, m, ap);
10670 if (!cursor_in_echo_area)
10671 fprintf (stderr, "\n");
10672 fflush (stderr);
10675 else if (INTERACTIVE)
10677 /* The frame whose mini-buffer we're going to display the message
10678 on. It may be larger than the selected frame, so we need to
10679 use its buffer, not the selected frame's buffer. */
10680 Lisp_Object mini_window;
10681 struct frame *f, *sf = SELECTED_FRAME ();
10683 /* Get the frame containing the mini-buffer
10684 that the selected frame is using. */
10685 mini_window = FRAME_MINIBUF_WINDOW (sf);
10686 f = XFRAME (WINDOW_FRAME (XWINDOW (mini_window)));
10688 /* Error messages get reported properly by cmd_error, so this must be
10689 just an informative message; if the frame hasn't really been
10690 initialized yet, just toss it. */
10691 if (f->glyphs_initialized_p)
10693 if (m)
10695 ptrdiff_t len;
10696 ptrdiff_t maxsize = FRAME_MESSAGE_BUF_SIZE (f);
10697 USE_SAFE_ALLOCA;
10698 char *message_buf = SAFE_ALLOCA (maxsize + 1);
10700 len = doprnt (message_buf, maxsize, m, 0, ap);
10702 message3 (make_string (message_buf, len));
10703 SAFE_FREE ();
10705 else
10706 message1 (0);
10708 /* Print should start at the beginning of the message
10709 buffer next time. */
10710 message_buf_print = false;
10715 /* See vmessage for restrictions on the text of the message. */
10716 void
10717 message (const char *m, ...)
10719 va_list ap;
10720 va_start (ap, m);
10721 vmessage (m, ap);
10722 va_end (ap);
10726 /* Display the current message in the current mini-buffer. This is
10727 only called from error handlers in process.c, and is not time
10728 critical. */
10730 void
10731 update_echo_area (void)
10733 if (!NILP (echo_area_buffer[0]))
10735 Lisp_Object string;
10736 string = Fcurrent_message ();
10737 message3 (string);
10742 /* Make sure echo area buffers in `echo_buffers' are live.
10743 If they aren't, make new ones. */
10745 static void
10746 ensure_echo_area_buffers (void)
10748 for (int i = 0; i < 2; i++)
10749 if (!BUFFERP (echo_buffer[i])
10750 || !BUFFER_LIVE_P (XBUFFER (echo_buffer[i])))
10752 Lisp_Object old_buffer = echo_buffer[i];
10753 static char const name_fmt[] = " *Echo Area %d*";
10754 char name[sizeof name_fmt + INT_STRLEN_BOUND (int)];
10755 AUTO_STRING_WITH_LEN (lname, name, sprintf (name, name_fmt, i));
10756 echo_buffer[i] = Fget_buffer_create (lname);
10757 bset_truncate_lines (XBUFFER (echo_buffer[i]), Qnil);
10758 /* to force word wrap in echo area -
10759 it was decided to postpone this*/
10760 /* XBUFFER (echo_buffer[i])->word_wrap = Qt; */
10762 for (int j = 0; j < 2; j++)
10763 if (EQ (old_buffer, echo_area_buffer[j]))
10764 echo_area_buffer[j] = echo_buffer[i];
10769 /* Call FN with args A1..A2 with either the current or last displayed
10770 echo_area_buffer as current buffer.
10772 WHICH zero means use the current message buffer
10773 echo_area_buffer[0]. If that is nil, choose a suitable buffer
10774 from echo_buffer[] and clear it.
10776 WHICH > 0 means use echo_area_buffer[1]. If that is nil, choose a
10777 suitable buffer from echo_buffer[] and clear it.
10779 If WHICH < 0, set echo_area_buffer[1] to echo_area_buffer[0], so
10780 that the current message becomes the last displayed one, choose a
10781 suitable buffer for echo_area_buffer[0], and clear it.
10783 Value is what FN returns. */
10785 static bool
10786 with_echo_area_buffer (struct window *w, int which,
10787 bool (*fn) (ptrdiff_t, Lisp_Object),
10788 ptrdiff_t a1, Lisp_Object a2)
10790 Lisp_Object buffer;
10791 bool this_one, the_other, clear_buffer_p, rc;
10792 ptrdiff_t count = SPECPDL_INDEX ();
10794 /* If buffers aren't live, make new ones. */
10795 ensure_echo_area_buffers ();
10797 clear_buffer_p = false;
10799 if (which == 0)
10800 this_one = false, the_other = true;
10801 else if (which > 0)
10802 this_one = true, the_other = false;
10803 else
10805 this_one = false, the_other = true;
10806 clear_buffer_p = true;
10808 /* We need a fresh one in case the current echo buffer equals
10809 the one containing the last displayed echo area message. */
10810 if (!NILP (echo_area_buffer[this_one])
10811 && EQ (echo_area_buffer[this_one], echo_area_buffer[the_other]))
10812 echo_area_buffer[this_one] = Qnil;
10815 /* Choose a suitable buffer from echo_buffer[] if we don't
10816 have one. */
10817 if (NILP (echo_area_buffer[this_one]))
10819 echo_area_buffer[this_one]
10820 = (EQ (echo_area_buffer[the_other], echo_buffer[this_one])
10821 ? echo_buffer[the_other]
10822 : echo_buffer[this_one]);
10823 clear_buffer_p = true;
10826 buffer = echo_area_buffer[this_one];
10828 /* Don't get confused by reusing the buffer used for echoing
10829 for a different purpose. */
10830 if (echo_kboard == NULL && EQ (buffer, echo_message_buffer))
10831 cancel_echoing ();
10833 record_unwind_protect (unwind_with_echo_area_buffer,
10834 with_echo_area_buffer_unwind_data (w));
10836 /* Make the echo area buffer current. Note that for display
10837 purposes, it is not necessary that the displayed window's buffer
10838 == current_buffer, except for text property lookup. So, let's
10839 only set that buffer temporarily here without doing a full
10840 Fset_window_buffer. We must also change w->pointm, though,
10841 because otherwise an assertions in unshow_buffer fails, and Emacs
10842 aborts. */
10843 set_buffer_internal_1 (XBUFFER (buffer));
10844 if (w)
10846 wset_buffer (w, buffer);
10847 set_marker_both (w->pointm, buffer, BEG, BEG_BYTE);
10848 set_marker_both (w->old_pointm, buffer, BEG, BEG_BYTE);
10851 bset_undo_list (current_buffer, Qt);
10852 bset_read_only (current_buffer, Qnil);
10853 specbind (Qinhibit_read_only, Qt);
10854 specbind (Qinhibit_modification_hooks, Qt);
10856 if (clear_buffer_p && Z > BEG)
10857 del_range (BEG, Z);
10859 eassert (BEGV >= BEG);
10860 eassert (ZV <= Z && ZV >= BEGV);
10862 rc = fn (a1, a2);
10864 eassert (BEGV >= BEG);
10865 eassert (ZV <= Z && ZV >= BEGV);
10867 unbind_to (count, Qnil);
10868 return rc;
10872 /* Save state that should be preserved around the call to the function
10873 FN called in with_echo_area_buffer. */
10875 static Lisp_Object
10876 with_echo_area_buffer_unwind_data (struct window *w)
10878 int i = 0;
10879 Lisp_Object vector, tmp;
10881 /* Reduce consing by keeping one vector in
10882 Vwith_echo_area_save_vector. */
10883 vector = Vwith_echo_area_save_vector;
10884 Vwith_echo_area_save_vector = Qnil;
10886 if (NILP (vector))
10887 vector = Fmake_vector (make_number (11), Qnil);
10889 XSETBUFFER (tmp, current_buffer); ASET (vector, i, tmp); ++i;
10890 ASET (vector, i, Vdeactivate_mark); ++i;
10891 ASET (vector, i, make_number (windows_or_buffers_changed)); ++i;
10893 if (w)
10895 XSETWINDOW (tmp, w); ASET (vector, i, tmp); ++i;
10896 ASET (vector, i, w->contents); ++i;
10897 ASET (vector, i, make_number (marker_position (w->pointm))); ++i;
10898 ASET (vector, i, make_number (marker_byte_position (w->pointm))); ++i;
10899 ASET (vector, i, make_number (marker_position (w->old_pointm))); ++i;
10900 ASET (vector, i, make_number (marker_byte_position (w->old_pointm))); ++i;
10901 ASET (vector, i, make_number (marker_position (w->start))); ++i;
10902 ASET (vector, i, make_number (marker_byte_position (w->start))); ++i;
10904 else
10906 int end = i + 8;
10907 for (; i < end; ++i)
10908 ASET (vector, i, Qnil);
10911 eassert (i == ASIZE (vector));
10912 return vector;
10916 /* Restore global state from VECTOR which was created by
10917 with_echo_area_buffer_unwind_data. */
10919 static void
10920 unwind_with_echo_area_buffer (Lisp_Object vector)
10922 set_buffer_internal_1 (XBUFFER (AREF (vector, 0)));
10923 Vdeactivate_mark = AREF (vector, 1);
10924 windows_or_buffers_changed = XFASTINT (AREF (vector, 2));
10926 if (WINDOWP (AREF (vector, 3)))
10928 struct window *w;
10929 Lisp_Object buffer;
10931 w = XWINDOW (AREF (vector, 3));
10932 buffer = AREF (vector, 4);
10934 wset_buffer (w, buffer);
10935 set_marker_both (w->pointm, buffer,
10936 XFASTINT (AREF (vector, 5)),
10937 XFASTINT (AREF (vector, 6)));
10938 set_marker_both (w->old_pointm, buffer,
10939 XFASTINT (AREF (vector, 7)),
10940 XFASTINT (AREF (vector, 8)));
10941 set_marker_both (w->start, buffer,
10942 XFASTINT (AREF (vector, 9)),
10943 XFASTINT (AREF (vector, 10)));
10946 Vwith_echo_area_save_vector = vector;
10950 /* Set up the echo area for use by print functions. MULTIBYTE_P
10951 means we will print multibyte. */
10953 void
10954 setup_echo_area_for_printing (bool multibyte_p)
10956 /* If we can't find an echo area any more, exit. */
10957 if (! FRAME_LIVE_P (XFRAME (selected_frame)))
10958 Fkill_emacs (Qnil);
10960 ensure_echo_area_buffers ();
10962 if (!message_buf_print)
10964 /* A message has been output since the last time we printed.
10965 Choose a fresh echo area buffer. */
10966 if (EQ (echo_area_buffer[1], echo_buffer[0]))
10967 echo_area_buffer[0] = echo_buffer[1];
10968 else
10969 echo_area_buffer[0] = echo_buffer[0];
10971 /* Switch to that buffer and clear it. */
10972 set_buffer_internal (XBUFFER (echo_area_buffer[0]));
10973 bset_truncate_lines (current_buffer, Qnil);
10975 if (Z > BEG)
10977 ptrdiff_t count = SPECPDL_INDEX ();
10978 specbind (Qinhibit_read_only, Qt);
10979 /* Note that undo recording is always disabled. */
10980 del_range (BEG, Z);
10981 unbind_to (count, Qnil);
10983 TEMP_SET_PT_BOTH (BEG, BEG_BYTE);
10985 /* Set up the buffer for the multibyteness we need. We always
10986 set it to be multibyte, except when
10987 unibyte-display-via-language-environment is non-nil and the
10988 buffer from which we are called is unibyte, because in that
10989 case unibyte characters should not be displayed as octal
10990 escapes. */
10991 if (unibyte_display_via_language_environment
10992 && !multibyte_p
10993 && !NILP (BVAR (current_buffer, enable_multibyte_characters)))
10994 Fset_buffer_multibyte (Qnil);
10995 else if (NILP (BVAR (current_buffer, enable_multibyte_characters)))
10996 Fset_buffer_multibyte (Qt);
10998 /* Raise the frame containing the echo area. */
10999 if (minibuffer_auto_raise)
11001 struct frame *sf = SELECTED_FRAME ();
11002 Lisp_Object mini_window;
11003 mini_window = FRAME_MINIBUF_WINDOW (sf);
11004 Fraise_frame (WINDOW_FRAME (XWINDOW (mini_window)));
11007 message_log_maybe_newline ();
11008 message_buf_print = true;
11010 else
11012 if (NILP (echo_area_buffer[0]))
11014 if (EQ (echo_area_buffer[1], echo_buffer[0]))
11015 echo_area_buffer[0] = echo_buffer[1];
11016 else
11017 echo_area_buffer[0] = echo_buffer[0];
11020 if (current_buffer != XBUFFER (echo_area_buffer[0]))
11022 /* Someone switched buffers between print requests. */
11023 set_buffer_internal (XBUFFER (echo_area_buffer[0]));
11024 bset_truncate_lines (current_buffer, Qnil);
11030 /* Display an echo area message in window W. Value is true if W's
11031 height is changed. If display_last_displayed_message_p,
11032 display the message that was last displayed, otherwise
11033 display the current message. */
11035 static bool
11036 display_echo_area (struct window *w)
11038 bool no_message_p, window_height_changed_p;
11040 /* Temporarily disable garbage collections while displaying the echo
11041 area. This is done because a GC can print a message itself.
11042 That message would modify the echo area buffer's contents while a
11043 redisplay of the buffer is going on, and seriously confuse
11044 redisplay. */
11045 ptrdiff_t count = inhibit_garbage_collection ();
11047 /* If there is no message, we must call display_echo_area_1
11048 nevertheless because it resizes the window. But we will have to
11049 reset the echo_area_buffer in question to nil at the end because
11050 with_echo_area_buffer will sets it to an empty buffer. */
11051 bool i = display_last_displayed_message_p;
11052 /* According to the C99, C11 and C++11 standards, the integral value
11053 of a "bool" is always 0 or 1, so this array access is safe here,
11054 if oddly typed. */
11055 no_message_p = NILP (echo_area_buffer[i]);
11057 window_height_changed_p
11058 = with_echo_area_buffer (w, display_last_displayed_message_p,
11059 display_echo_area_1,
11060 (intptr_t) w, Qnil);
11062 if (no_message_p)
11063 echo_area_buffer[i] = Qnil;
11065 unbind_to (count, Qnil);
11066 return window_height_changed_p;
11070 /* Helper for display_echo_area. Display the current buffer which
11071 contains the current echo area message in window W, a mini-window,
11072 a pointer to which is passed in A1. A2..A4 are currently not used.
11073 Change the height of W so that all of the message is displayed.
11074 Value is true if height of W was changed. */
11076 static bool
11077 display_echo_area_1 (ptrdiff_t a1, Lisp_Object a2)
11079 intptr_t i1 = a1;
11080 struct window *w = (struct window *) i1;
11081 Lisp_Object window;
11082 struct text_pos start;
11084 /* We are about to enter redisplay without going through
11085 redisplay_internal, so we need to forget these faces by hand
11086 here. */
11087 forget_escape_and_glyphless_faces ();
11089 /* Do this before displaying, so that we have a large enough glyph
11090 matrix for the display. If we can't get enough space for the
11091 whole text, display the last N lines. That works by setting w->start. */
11092 bool window_height_changed_p = resize_mini_window (w, false);
11094 /* Use the starting position chosen by resize_mini_window. */
11095 SET_TEXT_POS_FROM_MARKER (start, w->start);
11097 /* Display. */
11098 clear_glyph_matrix (w->desired_matrix);
11099 XSETWINDOW (window, w);
11100 try_window (window, start, 0);
11102 return window_height_changed_p;
11106 /* Resize the echo area window to exactly the size needed for the
11107 currently displayed message, if there is one. If a mini-buffer
11108 is active, don't shrink it. */
11110 void
11111 resize_echo_area_exactly (void)
11113 if (BUFFERP (echo_area_buffer[0])
11114 && WINDOWP (echo_area_window))
11116 struct window *w = XWINDOW (echo_area_window);
11117 Lisp_Object resize_exactly = (minibuf_level == 0 ? Qt : Qnil);
11118 bool resized_p = with_echo_area_buffer (w, 0, resize_mini_window_1,
11119 (intptr_t) w, resize_exactly);
11120 if (resized_p)
11122 windows_or_buffers_changed = 42;
11123 update_mode_lines = 30;
11124 redisplay_internal ();
11130 /* Callback function for with_echo_area_buffer, when used from
11131 resize_echo_area_exactly. A1 contains a pointer to the window to
11132 resize, EXACTLY non-nil means resize the mini-window exactly to the
11133 size of the text displayed. A3 and A4 are not used. Value is what
11134 resize_mini_window returns. */
11136 static bool
11137 resize_mini_window_1 (ptrdiff_t a1, Lisp_Object exactly)
11139 intptr_t i1 = a1;
11140 return resize_mini_window ((struct window *) i1, !NILP (exactly));
11144 /* Resize mini-window W to fit the size of its contents. EXACT_P
11145 means size the window exactly to the size needed. Otherwise, it's
11146 only enlarged until W's buffer is empty.
11148 Set W->start to the right place to begin display. If the whole
11149 contents fit, start at the beginning. Otherwise, start so as
11150 to make the end of the contents appear. This is particularly
11151 important for y-or-n-p, but seems desirable generally.
11153 Value is true if the window height has been changed. */
11155 bool
11156 resize_mini_window (struct window *w, bool exact_p)
11158 struct frame *f = XFRAME (w->frame);
11159 bool window_height_changed_p = false;
11161 eassert (MINI_WINDOW_P (w));
11163 /* By default, start display at the beginning. */
11164 set_marker_both (w->start, w->contents,
11165 BUF_BEGV (XBUFFER (w->contents)),
11166 BUF_BEGV_BYTE (XBUFFER (w->contents)));
11168 /* Don't resize windows while redisplaying a window; it would
11169 confuse redisplay functions when the size of the window they are
11170 displaying changes from under them. Such a resizing can happen,
11171 for instance, when which-func prints a long message while
11172 we are running fontification-functions. We're running these
11173 functions with safe_call which binds inhibit-redisplay to t. */
11174 if (!NILP (Vinhibit_redisplay))
11175 return false;
11177 /* Nil means don't try to resize. */
11178 if (NILP (Vresize_mini_windows)
11179 || (FRAME_X_P (f) && FRAME_X_OUTPUT (f) == NULL))
11180 return false;
11182 if (!FRAME_MINIBUF_ONLY_P (f))
11184 struct it it;
11185 int total_height = (WINDOW_PIXEL_HEIGHT (XWINDOW (FRAME_ROOT_WINDOW (f)))
11186 + WINDOW_PIXEL_HEIGHT (w));
11187 int unit = FRAME_LINE_HEIGHT (f);
11188 int height, max_height;
11189 struct text_pos start;
11190 struct buffer *old_current_buffer = NULL;
11192 if (current_buffer != XBUFFER (w->contents))
11194 old_current_buffer = current_buffer;
11195 set_buffer_internal (XBUFFER (w->contents));
11198 init_iterator (&it, w, BEGV, BEGV_BYTE, NULL, DEFAULT_FACE_ID);
11200 /* Compute the max. number of lines specified by the user. */
11201 if (FLOATP (Vmax_mini_window_height))
11202 max_height = XFLOAT_DATA (Vmax_mini_window_height) * total_height;
11203 else if (INTEGERP (Vmax_mini_window_height))
11204 max_height = XINT (Vmax_mini_window_height) * unit;
11205 else
11206 max_height = total_height / 4;
11208 /* Correct that max. height if it's bogus. */
11209 max_height = clip_to_bounds (unit, max_height, total_height);
11211 /* Find out the height of the text in the window. */
11212 if (it.line_wrap == TRUNCATE)
11213 height = unit;
11214 else
11216 last_height = 0;
11217 move_it_to (&it, ZV, -1, -1, -1, MOVE_TO_POS);
11218 if (it.max_ascent == 0 && it.max_descent == 0)
11219 height = it.current_y + last_height;
11220 else
11221 height = it.current_y + it.max_ascent + it.max_descent;
11222 height -= min (it.extra_line_spacing, it.max_extra_line_spacing);
11225 /* Compute a suitable window start. */
11226 if (height > max_height)
11228 height = (max_height / unit) * unit;
11229 init_iterator (&it, w, ZV, ZV_BYTE, NULL, DEFAULT_FACE_ID);
11230 move_it_vertically_backward (&it, height - unit);
11231 start = it.current.pos;
11233 else
11234 SET_TEXT_POS (start, BEGV, BEGV_BYTE);
11235 SET_MARKER_FROM_TEXT_POS (w->start, start);
11237 if (EQ (Vresize_mini_windows, Qgrow_only))
11239 /* Let it grow only, until we display an empty message, in which
11240 case the window shrinks again. */
11241 if (height > WINDOW_PIXEL_HEIGHT (w))
11243 int old_height = WINDOW_PIXEL_HEIGHT (w);
11245 FRAME_WINDOWS_FROZEN (f) = true;
11246 grow_mini_window (w, height - WINDOW_PIXEL_HEIGHT (w), true);
11247 window_height_changed_p = WINDOW_PIXEL_HEIGHT (w) != old_height;
11249 else if (height < WINDOW_PIXEL_HEIGHT (w)
11250 && (exact_p || BEGV == ZV))
11252 int old_height = WINDOW_PIXEL_HEIGHT (w);
11254 FRAME_WINDOWS_FROZEN (f) = false;
11255 shrink_mini_window (w, true);
11256 window_height_changed_p = WINDOW_PIXEL_HEIGHT (w) != old_height;
11259 else
11261 /* Always resize to exact size needed. */
11262 if (height > WINDOW_PIXEL_HEIGHT (w))
11264 int old_height = WINDOW_PIXEL_HEIGHT (w);
11266 FRAME_WINDOWS_FROZEN (f) = true;
11267 grow_mini_window (w, height - WINDOW_PIXEL_HEIGHT (w), true);
11268 window_height_changed_p = WINDOW_PIXEL_HEIGHT (w) != old_height;
11270 else if (height < WINDOW_PIXEL_HEIGHT (w))
11272 int old_height = WINDOW_PIXEL_HEIGHT (w);
11274 FRAME_WINDOWS_FROZEN (f) = false;
11275 shrink_mini_window (w, true);
11277 if (height)
11279 FRAME_WINDOWS_FROZEN (f) = true;
11280 grow_mini_window (w, height - WINDOW_PIXEL_HEIGHT (w), true);
11283 window_height_changed_p = WINDOW_PIXEL_HEIGHT (w) != old_height;
11287 if (old_current_buffer)
11288 set_buffer_internal (old_current_buffer);
11291 return window_height_changed_p;
11295 /* Value is the current message, a string, or nil if there is no
11296 current message. */
11298 Lisp_Object
11299 current_message (void)
11301 Lisp_Object msg;
11303 if (!BUFFERP (echo_area_buffer[0]))
11304 msg = Qnil;
11305 else
11307 with_echo_area_buffer (0, 0, current_message_1,
11308 (intptr_t) &msg, Qnil);
11309 if (NILP (msg))
11310 echo_area_buffer[0] = Qnil;
11313 return msg;
11317 static bool
11318 current_message_1 (ptrdiff_t a1, Lisp_Object a2)
11320 intptr_t i1 = a1;
11321 Lisp_Object *msg = (Lisp_Object *) i1;
11323 if (Z > BEG)
11324 *msg = make_buffer_string (BEG, Z, true);
11325 else
11326 *msg = Qnil;
11327 return false;
11331 /* Push the current message on Vmessage_stack for later restoration
11332 by restore_message. Value is true if the current message isn't
11333 empty. This is a relatively infrequent operation, so it's not
11334 worth optimizing. */
11336 bool
11337 push_message (void)
11339 Lisp_Object msg = current_message ();
11340 Vmessage_stack = Fcons (msg, Vmessage_stack);
11341 return STRINGP (msg);
11345 /* Restore message display from the top of Vmessage_stack. */
11347 void
11348 restore_message (void)
11350 eassert (CONSP (Vmessage_stack));
11351 message3_nolog (XCAR (Vmessage_stack));
11355 /* Handler for unwind-protect calling pop_message. */
11357 void
11358 pop_message_unwind (void)
11360 /* Pop the top-most entry off Vmessage_stack. */
11361 eassert (CONSP (Vmessage_stack));
11362 Vmessage_stack = XCDR (Vmessage_stack);
11366 /* Check that Vmessage_stack is nil. Called from emacs.c when Emacs
11367 exits. If the stack is not empty, we have a missing pop_message
11368 somewhere. */
11370 void
11371 check_message_stack (void)
11373 if (!NILP (Vmessage_stack))
11374 emacs_abort ();
11378 /* Truncate to NCHARS what will be displayed in the echo area the next
11379 time we display it---but don't redisplay it now. */
11381 void
11382 truncate_echo_area (ptrdiff_t nchars)
11384 if (nchars == 0)
11385 echo_area_buffer[0] = Qnil;
11386 else if (!noninteractive
11387 && INTERACTIVE
11388 && !NILP (echo_area_buffer[0]))
11390 struct frame *sf = SELECTED_FRAME ();
11391 /* Error messages get reported properly by cmd_error, so this must be
11392 just an informative message; if the frame hasn't really been
11393 initialized yet, just toss it. */
11394 if (sf->glyphs_initialized_p)
11395 with_echo_area_buffer (0, 0, truncate_message_1, nchars, Qnil);
11400 /* Helper function for truncate_echo_area. Truncate the current
11401 message to at most NCHARS characters. */
11403 static bool
11404 truncate_message_1 (ptrdiff_t nchars, Lisp_Object a2)
11406 if (BEG + nchars < Z)
11407 del_range (BEG + nchars, Z);
11408 if (Z == BEG)
11409 echo_area_buffer[0] = Qnil;
11410 return false;
11413 /* Set the current message to STRING. */
11415 static void
11416 set_message (Lisp_Object string)
11418 eassert (STRINGP (string));
11420 message_enable_multibyte = STRING_MULTIBYTE (string);
11422 with_echo_area_buffer (0, -1, set_message_1, 0, string);
11423 message_buf_print = false;
11424 help_echo_showing_p = false;
11426 if (STRINGP (Vdebug_on_message)
11427 && STRINGP (string)
11428 && fast_string_match (Vdebug_on_message, string) >= 0)
11429 call_debugger (list2 (Qerror, string));
11433 /* Helper function for set_message. First argument is ignored and second
11434 argument has the same meaning as for set_message.
11435 This function is called with the echo area buffer being current. */
11437 static bool
11438 set_message_1 (ptrdiff_t a1, Lisp_Object string)
11440 eassert (STRINGP (string));
11442 /* Change multibyteness of the echo buffer appropriately. We always
11443 set it to be multibyte, except when
11444 unibyte-display-via-language-environment is non-nil and the
11445 string to display is unibyte, because in that case unibyte
11446 characters should not be displayed as octal escapes. */
11447 if (!message_enable_multibyte
11448 && unibyte_display_via_language_environment
11449 && !NILP (BVAR (current_buffer, enable_multibyte_characters)))
11450 Fset_buffer_multibyte (Qnil);
11451 else if (NILP (BVAR (current_buffer, enable_multibyte_characters)))
11452 Fset_buffer_multibyte (Qt);
11454 bset_truncate_lines (current_buffer, message_truncate_lines ? Qt : Qnil);
11455 if (!NILP (BVAR (current_buffer, bidi_display_reordering)))
11456 bset_bidi_paragraph_direction (current_buffer, Qleft_to_right);
11458 /* Insert new message at BEG. */
11459 TEMP_SET_PT_BOTH (BEG, BEG_BYTE);
11461 /* This function takes care of single/multibyte conversion.
11462 We just have to ensure that the echo area buffer has the right
11463 setting of enable_multibyte_characters. */
11464 insert_from_string (string, 0, 0, SCHARS (string), SBYTES (string), true);
11466 return false;
11470 /* Clear messages. CURRENT_P means clear the current message.
11471 LAST_DISPLAYED_P means clear the message last displayed. */
11473 void
11474 clear_message (bool current_p, bool last_displayed_p)
11476 if (current_p)
11478 echo_area_buffer[0] = Qnil;
11479 message_cleared_p = true;
11482 if (last_displayed_p)
11483 echo_area_buffer[1] = Qnil;
11485 message_buf_print = false;
11488 /* Clear garbaged frames.
11490 This function is used where the old redisplay called
11491 redraw_garbaged_frames which in turn called redraw_frame which in
11492 turn called clear_frame. The call to clear_frame was a source of
11493 flickering. I believe a clear_frame is not necessary. It should
11494 suffice in the new redisplay to invalidate all current matrices,
11495 and ensure a complete redisplay of all windows. */
11497 static void
11498 clear_garbaged_frames (void)
11500 if (frame_garbaged)
11502 Lisp_Object tail, frame;
11503 struct frame *sf = SELECTED_FRAME ();
11505 FOR_EACH_FRAME (tail, frame)
11507 struct frame *f = XFRAME (frame);
11509 if (FRAME_VISIBLE_P (f) && FRAME_GARBAGED_P (f))
11511 if (f->resized_p
11512 /* It makes no sense to redraw a non-selected TTY
11513 frame, since that will actually clear the
11514 selected frame, and might leave the selected
11515 frame with corrupted display, if it happens not
11516 to be marked garbaged. */
11517 && !(f != sf && (FRAME_TERMCAP_P (f) || FRAME_MSDOS_P (f))))
11518 redraw_frame (f);
11519 else
11520 clear_current_matrices (f);
11522 #if defined (HAVE_WINDOW_SYSTEM) && !defined (HAVE_NS)
11523 x_clear_under_internal_border (f);
11524 #endif /* HAVE_WINDOW_SYSTEM && !HAVE_NS */
11526 fset_redisplay (f);
11527 f->garbaged = false;
11528 f->resized_p = false;
11532 frame_garbaged = false;
11537 /* Redisplay the echo area of the selected frame. If UPDATE_FRAME_P, update
11538 selected_frame. */
11540 static void
11541 echo_area_display (bool update_frame_p)
11543 Lisp_Object mini_window;
11544 struct window *w;
11545 struct frame *f;
11546 bool window_height_changed_p = false;
11547 struct frame *sf = SELECTED_FRAME ();
11549 mini_window = FRAME_MINIBUF_WINDOW (sf);
11550 if (NILP (mini_window))
11551 return;
11553 w = XWINDOW (mini_window);
11554 f = XFRAME (WINDOW_FRAME (w));
11556 /* Don't display if frame is invisible or not yet initialized. */
11557 if (!FRAME_VISIBLE_P (f) || !f->glyphs_initialized_p)
11558 return;
11560 #ifdef HAVE_WINDOW_SYSTEM
11561 /* When Emacs starts, selected_frame may be the initial terminal
11562 frame. If we let this through, a message would be displayed on
11563 the terminal. */
11564 if (FRAME_INITIAL_P (XFRAME (selected_frame)))
11565 return;
11566 #endif /* HAVE_WINDOW_SYSTEM */
11568 /* Redraw garbaged frames. */
11569 clear_garbaged_frames ();
11571 if (!NILP (echo_area_buffer[0]) || minibuf_level == 0)
11573 echo_area_window = mini_window;
11574 window_height_changed_p = display_echo_area (w);
11575 w->must_be_updated_p = true;
11577 /* Update the display, unless called from redisplay_internal.
11578 Also don't update the screen during redisplay itself. The
11579 update will happen at the end of redisplay, and an update
11580 here could cause confusion. */
11581 if (update_frame_p && !redisplaying_p)
11583 int n = 0;
11585 /* If the display update has been interrupted by pending
11586 input, update mode lines in the frame. Due to the
11587 pending input, it might have been that redisplay hasn't
11588 been called, so that mode lines above the echo area are
11589 garbaged. This looks odd, so we prevent it here. */
11590 if (!display_completed)
11592 n = redisplay_mode_lines (FRAME_ROOT_WINDOW (f), false);
11594 #if defined (HAVE_WINDOW_SYSTEM) && !defined (HAVE_NS)
11595 x_clear_under_internal_border (f);
11596 #endif /* HAVE_WINDOW_SYSTEM && !HAVE_NS */
11600 if (window_height_changed_p
11601 /* Don't do this if Emacs is shutting down. Redisplay
11602 needs to run hooks. */
11603 && !NILP (Vrun_hooks))
11605 /* Must update other windows. Likewise as in other
11606 cases, don't let this update be interrupted by
11607 pending input. */
11608 ptrdiff_t count = SPECPDL_INDEX ();
11609 specbind (Qredisplay_dont_pause, Qt);
11610 fset_redisplay (f);
11611 redisplay_internal ();
11612 unbind_to (count, Qnil);
11614 else if (FRAME_WINDOW_P (f) && n == 0)
11616 /* Window configuration is the same as before.
11617 Can do with a display update of the echo area,
11618 unless we displayed some mode lines. */
11619 update_single_window (w);
11620 flush_frame (f);
11622 else
11623 update_frame (f, true, true);
11625 /* If cursor is in the echo area, make sure that the next
11626 redisplay displays the minibuffer, so that the cursor will
11627 be replaced with what the minibuffer wants. */
11628 if (cursor_in_echo_area)
11629 wset_redisplay (XWINDOW (mini_window));
11632 else if (!EQ (mini_window, selected_window))
11633 wset_redisplay (XWINDOW (mini_window));
11635 /* Last displayed message is now the current message. */
11636 echo_area_buffer[1] = echo_area_buffer[0];
11637 /* Inform read_char that we're not echoing. */
11638 echo_message_buffer = Qnil;
11640 /* Prevent redisplay optimization in redisplay_internal by resetting
11641 this_line_start_pos. This is done because the mini-buffer now
11642 displays the message instead of its buffer text. */
11643 if (EQ (mini_window, selected_window))
11644 CHARPOS (this_line_start_pos) = 0;
11646 if (window_height_changed_p)
11648 fset_redisplay (f);
11650 /* If window configuration was changed, frames may have been
11651 marked garbaged. Clear them or we will experience
11652 surprises wrt scrolling.
11653 FIXME: How/why/when? */
11654 clear_garbaged_frames ();
11658 /* True if W's buffer was changed but not saved. */
11660 static bool
11661 window_buffer_changed (struct window *w)
11663 struct buffer *b = XBUFFER (w->contents);
11665 eassert (BUFFER_LIVE_P (b));
11667 return (BUF_SAVE_MODIFF (b) < BUF_MODIFF (b)) != w->last_had_star;
11670 /* True if W has %c or %C in its mode line and mode line should be updated. */
11672 static bool
11673 mode_line_update_needed (struct window *w)
11675 return (w->column_number_displayed != -1
11676 && !(PT == w->last_point && !window_outdated (w))
11677 && (w->column_number_displayed != current_column ()));
11680 /* True if window start of W is frozen and may not be changed during
11681 redisplay. */
11683 static bool
11684 window_frozen_p (struct window *w)
11686 if (FRAME_WINDOWS_FROZEN (XFRAME (WINDOW_FRAME (w))))
11688 Lisp_Object window;
11690 XSETWINDOW (window, w);
11691 if (MINI_WINDOW_P (w))
11692 return false;
11693 else if (EQ (window, selected_window))
11694 return false;
11695 else if (MINI_WINDOW_P (XWINDOW (selected_window))
11696 && EQ (window, Vminibuf_scroll_window))
11697 /* This special window can't be frozen too. */
11698 return false;
11699 else
11700 return true;
11702 return false;
11705 /***********************************************************************
11706 Mode Lines and Frame Titles
11707 ***********************************************************************/
11709 /* A buffer for constructing non-propertized mode-line strings and
11710 frame titles in it; allocated from the heap in init_xdisp and
11711 resized as needed in store_mode_line_noprop_char. */
11713 static char *mode_line_noprop_buf;
11715 /* The buffer's end, and a current output position in it. */
11717 static char *mode_line_noprop_buf_end;
11718 static char *mode_line_noprop_ptr;
11720 #define MODE_LINE_NOPROP_LEN(start) \
11721 ((mode_line_noprop_ptr - mode_line_noprop_buf) - start)
11723 static enum {
11724 MODE_LINE_DISPLAY = 0,
11725 MODE_LINE_TITLE,
11726 MODE_LINE_NOPROP,
11727 MODE_LINE_STRING
11728 } mode_line_target;
11730 /* Alist that caches the results of :propertize.
11731 Each element is (PROPERTIZED-STRING . PROPERTY-LIST). */
11732 static Lisp_Object mode_line_proptrans_alist;
11734 /* List of strings making up the mode-line. */
11735 static Lisp_Object mode_line_string_list;
11737 /* Base face property when building propertized mode line string. */
11738 static Lisp_Object mode_line_string_face;
11739 static Lisp_Object mode_line_string_face_prop;
11742 /* Unwind data for mode line strings */
11744 static Lisp_Object Vmode_line_unwind_vector;
11746 static Lisp_Object
11747 format_mode_line_unwind_data (struct frame *target_frame,
11748 struct buffer *obuf,
11749 Lisp_Object owin,
11750 bool save_proptrans)
11752 Lisp_Object vector, tmp;
11754 /* Reduce consing by keeping one vector in
11755 Vwith_echo_area_save_vector. */
11756 vector = Vmode_line_unwind_vector;
11757 Vmode_line_unwind_vector = Qnil;
11759 if (NILP (vector))
11760 vector = Fmake_vector (make_number (10), Qnil);
11762 ASET (vector, 0, make_number (mode_line_target));
11763 ASET (vector, 1, make_number (MODE_LINE_NOPROP_LEN (0)));
11764 ASET (vector, 2, mode_line_string_list);
11765 ASET (vector, 3, save_proptrans ? mode_line_proptrans_alist : Qt);
11766 ASET (vector, 4, mode_line_string_face);
11767 ASET (vector, 5, mode_line_string_face_prop);
11769 if (obuf)
11770 XSETBUFFER (tmp, obuf);
11771 else
11772 tmp = Qnil;
11773 ASET (vector, 6, tmp);
11774 ASET (vector, 7, owin);
11775 if (target_frame)
11777 /* Similarly to `with-selected-window', if the operation selects
11778 a window on another frame, we must restore that frame's
11779 selected window, and (for a tty) the top-frame. */
11780 ASET (vector, 8, target_frame->selected_window);
11781 if (FRAME_TERMCAP_P (target_frame))
11782 ASET (vector, 9, FRAME_TTY (target_frame)->top_frame);
11785 return vector;
11788 static void
11789 unwind_format_mode_line (Lisp_Object vector)
11791 Lisp_Object old_window = AREF (vector, 7);
11792 Lisp_Object target_frame_window = AREF (vector, 8);
11793 Lisp_Object old_top_frame = AREF (vector, 9);
11795 mode_line_target = XINT (AREF (vector, 0));
11796 mode_line_noprop_ptr = mode_line_noprop_buf + XINT (AREF (vector, 1));
11797 mode_line_string_list = AREF (vector, 2);
11798 if (! EQ (AREF (vector, 3), Qt))
11799 mode_line_proptrans_alist = AREF (vector, 3);
11800 mode_line_string_face = AREF (vector, 4);
11801 mode_line_string_face_prop = AREF (vector, 5);
11803 /* Select window before buffer, since it may change the buffer. */
11804 if (!NILP (old_window))
11806 /* If the operation that we are unwinding had selected a window
11807 on a different frame, reset its frame-selected-window. For a
11808 text terminal, reset its top-frame if necessary. */
11809 if (!NILP (target_frame_window))
11811 Lisp_Object frame
11812 = WINDOW_FRAME (XWINDOW (target_frame_window));
11814 if (!EQ (frame, WINDOW_FRAME (XWINDOW (old_window))))
11815 Fselect_window (target_frame_window, Qt);
11817 if (!NILP (old_top_frame) && !EQ (old_top_frame, frame))
11818 Fselect_frame (old_top_frame, Qt);
11821 Fselect_window (old_window, Qt);
11824 if (!NILP (AREF (vector, 6)))
11826 set_buffer_internal_1 (XBUFFER (AREF (vector, 6)));
11827 ASET (vector, 6, Qnil);
11830 Vmode_line_unwind_vector = vector;
11834 /* Store a single character C for the frame title in mode_line_noprop_buf.
11835 Re-allocate mode_line_noprop_buf if necessary. */
11837 static void
11838 store_mode_line_noprop_char (char c)
11840 /* If output position has reached the end of the allocated buffer,
11841 increase the buffer's size. */
11842 if (mode_line_noprop_ptr == mode_line_noprop_buf_end)
11844 ptrdiff_t len = MODE_LINE_NOPROP_LEN (0);
11845 ptrdiff_t size = len;
11846 mode_line_noprop_buf =
11847 xpalloc (mode_line_noprop_buf, &size, 1, STRING_BYTES_BOUND, 1);
11848 mode_line_noprop_buf_end = mode_line_noprop_buf + size;
11849 mode_line_noprop_ptr = mode_line_noprop_buf + len;
11852 *mode_line_noprop_ptr++ = c;
11856 /* Store part of a frame title in mode_line_noprop_buf, beginning at
11857 mode_line_noprop_ptr. STRING is the string to store. Do not copy
11858 characters that yield more columns than PRECISION; PRECISION <= 0
11859 means copy the whole string. Pad with spaces until FIELD_WIDTH
11860 number of characters have been copied; FIELD_WIDTH <= 0 means don't
11861 pad. Called from display_mode_element when it is used to build a
11862 frame title. */
11864 static int
11865 store_mode_line_noprop (const char *string, int field_width, int precision)
11867 const unsigned char *str = (const unsigned char *) string;
11868 int n = 0;
11869 ptrdiff_t dummy, nbytes;
11871 /* Copy at most PRECISION chars from STR. */
11872 nbytes = strlen (string);
11873 n += c_string_width (str, nbytes, precision, &dummy, &nbytes);
11874 while (nbytes--)
11875 store_mode_line_noprop_char (*str++);
11877 /* Fill up with spaces until FIELD_WIDTH reached. */
11878 while (field_width > 0
11879 && n < field_width)
11881 store_mode_line_noprop_char (' ');
11882 ++n;
11885 return n;
11888 /***********************************************************************
11889 Frame Titles
11890 ***********************************************************************/
11892 #ifdef HAVE_WINDOW_SYSTEM
11894 /* Set the title of FRAME, if it has changed. The title format is
11895 Vicon_title_format if FRAME is iconified, otherwise it is
11896 frame_title_format. */
11898 static void
11899 x_consider_frame_title (Lisp_Object frame)
11901 struct frame *f = XFRAME (frame);
11903 if ((FRAME_WINDOW_P (f)
11904 || FRAME_MINIBUF_ONLY_P (f)
11905 || f->explicit_name)
11906 && !FRAME_TOOLTIP_P (f))
11908 /* Do we have more than one visible frame on this X display? */
11909 Lisp_Object tail, other_frame, fmt;
11910 ptrdiff_t title_start;
11911 char *title;
11912 ptrdiff_t len;
11913 struct it it;
11914 ptrdiff_t count = SPECPDL_INDEX ();
11916 FOR_EACH_FRAME (tail, other_frame)
11918 struct frame *tf = XFRAME (other_frame);
11920 if (tf != f
11921 && FRAME_KBOARD (tf) == FRAME_KBOARD (f)
11922 && !FRAME_MINIBUF_ONLY_P (tf)
11923 && !FRAME_PARENT_FRAME (tf)
11924 && !FRAME_TOOLTIP_P (tf)
11925 && (FRAME_VISIBLE_P (tf) || FRAME_ICONIFIED_P (tf)))
11926 break;
11929 /* Set global variable indicating that multiple frames exist. */
11930 multiple_frames = CONSP (tail);
11932 /* Switch to the buffer of selected window of the frame. Set up
11933 mode_line_target so that display_mode_element will output into
11934 mode_line_noprop_buf; then display the title. */
11935 record_unwind_protect (unwind_format_mode_line,
11936 format_mode_line_unwind_data
11937 (f, current_buffer, selected_window, false));
11938 /* select-frame calls resize_mini_window, which could resize the
11939 mini-window and by that undo the effect of this redisplay
11940 cycle wrt minibuffer and echo-area display. Binding
11941 inhibit-redisplay to t makes the call to resize_mini_window a
11942 no-op, thus avoiding the adverse side effects. */
11943 specbind (Qinhibit_redisplay, Qt);
11945 Fselect_window (f->selected_window, Qt);
11946 set_buffer_internal_1
11947 (XBUFFER (XWINDOW (f->selected_window)->contents));
11948 fmt = FRAME_ICONIFIED_P (f) ? Vicon_title_format : Vframe_title_format;
11950 mode_line_target = MODE_LINE_TITLE;
11951 title_start = MODE_LINE_NOPROP_LEN (0);
11952 init_iterator (&it, XWINDOW (f->selected_window), -1, -1,
11953 NULL, DEFAULT_FACE_ID);
11954 display_mode_element (&it, 0, -1, -1, fmt, Qnil, false);
11955 len = MODE_LINE_NOPROP_LEN (title_start);
11956 title = mode_line_noprop_buf + title_start;
11957 unbind_to (count, Qnil);
11959 /* Set the title only if it's changed. This avoids consing in
11960 the common case where it hasn't. (If it turns out that we've
11961 already wasted too much time by walking through the list with
11962 display_mode_element, then we might need to optimize at a
11963 higher level than this.) */
11964 if (! STRINGP (f->name)
11965 || SBYTES (f->name) != len
11966 || memcmp (title, SDATA (f->name), len) != 0)
11967 x_implicitly_set_name (f, make_string (title, len), Qnil);
11971 #endif /* not HAVE_WINDOW_SYSTEM */
11974 /***********************************************************************
11975 Menu Bars
11976 ***********************************************************************/
11978 /* True if we will not redisplay all visible windows. */
11979 #define REDISPLAY_SOME_P() \
11980 ((windows_or_buffers_changed == 0 \
11981 || windows_or_buffers_changed == REDISPLAY_SOME) \
11982 && (update_mode_lines == 0 \
11983 || update_mode_lines == REDISPLAY_SOME))
11985 /* Prepare for redisplay by updating menu-bar item lists when
11986 appropriate. This can call eval. */
11988 static void
11989 prepare_menu_bars (void)
11991 bool all_windows = windows_or_buffers_changed || update_mode_lines;
11992 bool some_windows = REDISPLAY_SOME_P ();
11994 if (FUNCTIONP (Vpre_redisplay_function))
11996 Lisp_Object windows = all_windows ? Qt : Qnil;
11997 if (all_windows && some_windows)
11999 Lisp_Object ws = window_list ();
12000 for (windows = Qnil; CONSP (ws); ws = XCDR (ws))
12002 Lisp_Object this = XCAR (ws);
12003 struct window *w = XWINDOW (this);
12004 if (w->redisplay
12005 || XFRAME (w->frame)->redisplay
12006 || XBUFFER (w->contents)->text->redisplay)
12008 windows = Fcons (this, windows);
12012 safe__call1 (true, Vpre_redisplay_function, windows);
12015 /* Update all frame titles based on their buffer names, etc. We do
12016 this before the menu bars so that the buffer-menu will show the
12017 up-to-date frame titles. */
12018 #ifdef HAVE_WINDOW_SYSTEM
12019 if (all_windows)
12021 Lisp_Object tail, frame;
12023 FOR_EACH_FRAME (tail, frame)
12025 struct frame *f = XFRAME (frame);
12026 struct window *w = XWINDOW (FRAME_SELECTED_WINDOW (f));
12027 if (some_windows
12028 && !f->redisplay
12029 && !w->redisplay
12030 && !XBUFFER (w->contents)->text->redisplay)
12031 continue;
12033 if (!FRAME_TOOLTIP_P (f)
12034 && !FRAME_PARENT_FRAME (f)
12035 && (FRAME_ICONIFIED_P (f)
12036 || FRAME_VISIBLE_P (f) == 1
12037 /* Exclude TTY frames that are obscured because they
12038 are not the top frame on their console. This is
12039 because x_consider_frame_title actually switches
12040 to the frame, which for TTY frames means it is
12041 marked as garbaged, and will be completely
12042 redrawn on the next redisplay cycle. This causes
12043 TTY frames to be completely redrawn, when there
12044 are more than one of them, even though nothing
12045 should be changed on display. */
12046 || (FRAME_VISIBLE_P (f) == 2 && FRAME_WINDOW_P (f))))
12047 x_consider_frame_title (frame);
12050 #endif /* HAVE_WINDOW_SYSTEM */
12052 /* Update the menu bar item lists, if appropriate. This has to be
12053 done before any actual redisplay or generation of display lines. */
12055 if (all_windows)
12057 Lisp_Object tail, frame;
12058 ptrdiff_t count = SPECPDL_INDEX ();
12059 /* True means that update_menu_bar has run its hooks
12060 so any further calls to update_menu_bar shouldn't do so again. */
12061 bool menu_bar_hooks_run = false;
12063 record_unwind_save_match_data ();
12065 FOR_EACH_FRAME (tail, frame)
12067 struct frame *f = XFRAME (frame);
12068 struct window *w = XWINDOW (FRAME_SELECTED_WINDOW (f));
12070 /* Ignore tooltip frame. */
12071 if (FRAME_TOOLTIP_P (f))
12072 continue;
12074 if (some_windows
12075 && !f->redisplay
12076 && !w->redisplay
12077 && !XBUFFER (w->contents)->text->redisplay)
12078 continue;
12080 run_window_size_change_functions (frame);
12082 if (FRAME_PARENT_FRAME (f))
12083 continue;
12085 menu_bar_hooks_run = update_menu_bar (f, false, menu_bar_hooks_run);
12086 #ifdef HAVE_WINDOW_SYSTEM
12087 update_tool_bar (f, false);
12088 #endif
12091 unbind_to (count, Qnil);
12093 else
12095 struct frame *sf = SELECTED_FRAME ();
12096 update_menu_bar (sf, true, false);
12097 #ifdef HAVE_WINDOW_SYSTEM
12098 update_tool_bar (sf, true);
12099 #endif
12104 /* Update the menu bar item list for frame F. This has to be done
12105 before we start to fill in any display lines, because it can call
12106 eval.
12108 If SAVE_MATCH_DATA, we must save and restore it here.
12110 If HOOKS_RUN, a previous call to update_menu_bar
12111 already ran the menu bar hooks for this redisplay, so there
12112 is no need to run them again. The return value is the
12113 updated value of this flag, to pass to the next call. */
12115 static bool
12116 update_menu_bar (struct frame *f, bool save_match_data, bool hooks_run)
12118 Lisp_Object window;
12119 struct window *w;
12121 /* If called recursively during a menu update, do nothing. This can
12122 happen when, for instance, an activate-menubar-hook causes a
12123 redisplay. */
12124 if (inhibit_menubar_update)
12125 return hooks_run;
12127 window = FRAME_SELECTED_WINDOW (f);
12128 w = XWINDOW (window);
12130 if (FRAME_WINDOW_P (f)
12132 #if defined (USE_X_TOOLKIT) || defined (HAVE_NTGUI) \
12133 || defined (HAVE_NS) || defined (USE_GTK)
12134 FRAME_EXTERNAL_MENU_BAR (f)
12135 #else
12136 FRAME_MENU_BAR_LINES (f) > 0
12137 #endif
12138 : FRAME_MENU_BAR_LINES (f) > 0)
12140 /* If the user has switched buffers or windows, we need to
12141 recompute to reflect the new bindings. But we'll
12142 recompute when update_mode_lines is set too; that means
12143 that people can use force-mode-line-update to request
12144 that the menu bar be recomputed. The adverse effect on
12145 the rest of the redisplay algorithm is about the same as
12146 windows_or_buffers_changed anyway. */
12147 if (windows_or_buffers_changed
12148 /* This used to test w->update_mode_line, but we believe
12149 there is no need to recompute the menu in that case. */
12150 || update_mode_lines
12151 || window_buffer_changed (w))
12153 struct buffer *prev = current_buffer;
12154 ptrdiff_t count = SPECPDL_INDEX ();
12156 specbind (Qinhibit_menubar_update, Qt);
12158 set_buffer_internal_1 (XBUFFER (w->contents));
12159 if (save_match_data)
12160 record_unwind_save_match_data ();
12161 if (NILP (Voverriding_local_map_menu_flag))
12163 specbind (Qoverriding_terminal_local_map, Qnil);
12164 specbind (Qoverriding_local_map, Qnil);
12167 if (!hooks_run)
12169 /* Run the Lucid hook. */
12170 safe_run_hooks (Qactivate_menubar_hook);
12172 /* If it has changed current-menubar from previous value,
12173 really recompute the menu-bar from the value. */
12174 if (! NILP (Vlucid_menu_bar_dirty_flag))
12175 call0 (Qrecompute_lucid_menubar);
12177 safe_run_hooks (Qmenu_bar_update_hook);
12179 hooks_run = true;
12182 XSETFRAME (Vmenu_updating_frame, f);
12183 fset_menu_bar_items (f, menu_bar_items (FRAME_MENU_BAR_ITEMS (f)));
12185 /* Redisplay the menu bar in case we changed it. */
12186 #if defined (USE_X_TOOLKIT) || defined (HAVE_NTGUI) \
12187 || defined (HAVE_NS) || defined (USE_GTK)
12188 if (FRAME_WINDOW_P (f))
12190 #if defined (HAVE_NS)
12191 /* All frames on Mac OS share the same menubar. So only
12192 the selected frame should be allowed to set it. */
12193 if (f == SELECTED_FRAME ())
12194 #endif
12195 set_frame_menubar (f, false, false);
12197 else
12198 /* On a terminal screen, the menu bar is an ordinary screen
12199 line, and this makes it get updated. */
12200 w->update_mode_line = true;
12201 #else /* ! (USE_X_TOOLKIT || HAVE_NTGUI || HAVE_NS || USE_GTK) */
12202 /* In the non-toolkit version, the menu bar is an ordinary screen
12203 line, and this makes it get updated. */
12204 w->update_mode_line = true;
12205 #endif /* ! (USE_X_TOOLKIT || HAVE_NTGUI || HAVE_NS || USE_GTK) */
12207 unbind_to (count, Qnil);
12208 set_buffer_internal_1 (prev);
12212 return hooks_run;
12215 /***********************************************************************
12216 Tool-bars
12217 ***********************************************************************/
12219 #ifdef HAVE_WINDOW_SYSTEM
12221 /* Select `frame' temporarily without running all the code in
12222 do_switch_frame.
12223 FIXME: Maybe do_switch_frame should be trimmed down similarly
12224 when `norecord' is set. */
12225 static void
12226 fast_set_selected_frame (Lisp_Object frame)
12228 if (!EQ (selected_frame, frame))
12230 selected_frame = frame;
12231 selected_window = XFRAME (frame)->selected_window;
12235 /* Update the tool-bar item list for frame F. This has to be done
12236 before we start to fill in any display lines. Called from
12237 prepare_menu_bars. If SAVE_MATCH_DATA, we must save
12238 and restore it here. */
12240 static void
12241 update_tool_bar (struct frame *f, bool save_match_data)
12243 #if defined (USE_GTK) || defined (HAVE_NS)
12244 bool do_update = FRAME_EXTERNAL_TOOL_BAR (f);
12245 #else
12246 bool do_update = (WINDOWP (f->tool_bar_window)
12247 && WINDOW_TOTAL_LINES (XWINDOW (f->tool_bar_window)) > 0);
12248 #endif
12250 if (do_update)
12252 Lisp_Object window;
12253 struct window *w;
12255 window = FRAME_SELECTED_WINDOW (f);
12256 w = XWINDOW (window);
12258 /* If the user has switched buffers or windows, we need to
12259 recompute to reflect the new bindings. But we'll
12260 recompute when update_mode_lines is set too; that means
12261 that people can use force-mode-line-update to request
12262 that the menu bar be recomputed. The adverse effect on
12263 the rest of the redisplay algorithm is about the same as
12264 windows_or_buffers_changed anyway. */
12265 if (windows_or_buffers_changed
12266 || w->update_mode_line
12267 || update_mode_lines
12268 || window_buffer_changed (w))
12270 struct buffer *prev = current_buffer;
12271 ptrdiff_t count = SPECPDL_INDEX ();
12272 Lisp_Object frame, new_tool_bar;
12273 int new_n_tool_bar;
12275 /* Set current_buffer to the buffer of the selected
12276 window of the frame, so that we get the right local
12277 keymaps. */
12278 set_buffer_internal_1 (XBUFFER (w->contents));
12280 /* Save match data, if we must. */
12281 if (save_match_data)
12282 record_unwind_save_match_data ();
12284 /* Make sure that we don't accidentally use bogus keymaps. */
12285 if (NILP (Voverriding_local_map_menu_flag))
12287 specbind (Qoverriding_terminal_local_map, Qnil);
12288 specbind (Qoverriding_local_map, Qnil);
12291 /* We must temporarily set the selected frame to this frame
12292 before calling tool_bar_items, because the calculation of
12293 the tool-bar keymap uses the selected frame (see
12294 `tool-bar-make-keymap' in tool-bar.el). */
12295 eassert (EQ (selected_window,
12296 /* Since we only explicitly preserve selected_frame,
12297 check that selected_window would be redundant. */
12298 XFRAME (selected_frame)->selected_window));
12299 record_unwind_protect (fast_set_selected_frame, selected_frame);
12300 XSETFRAME (frame, f);
12301 fast_set_selected_frame (frame);
12303 /* Build desired tool-bar items from keymaps. */
12304 new_tool_bar
12305 = tool_bar_items (Fcopy_sequence (f->tool_bar_items),
12306 &new_n_tool_bar);
12308 /* Redisplay the tool-bar if we changed it. */
12309 if (new_n_tool_bar != f->n_tool_bar_items
12310 || NILP (Fequal (new_tool_bar, f->tool_bar_items)))
12312 /* Redisplay that happens asynchronously due to an expose event
12313 may access f->tool_bar_items. Make sure we update both
12314 variables within BLOCK_INPUT so no such event interrupts. */
12315 block_input ();
12316 fset_tool_bar_items (f, new_tool_bar);
12317 f->n_tool_bar_items = new_n_tool_bar;
12318 w->update_mode_line = true;
12319 unblock_input ();
12322 unbind_to (count, Qnil);
12323 set_buffer_internal_1 (prev);
12328 #if ! defined (USE_GTK) && ! defined (HAVE_NS)
12330 /* Set F->desired_tool_bar_string to a Lisp string representing frame
12331 F's desired tool-bar contents. F->tool_bar_items must have
12332 been set up previously by calling prepare_menu_bars. */
12334 static void
12335 build_desired_tool_bar_string (struct frame *f)
12337 int i, size, size_needed;
12338 Lisp_Object image, plist;
12340 image = plist = Qnil;
12342 /* Prepare F->desired_tool_bar_string. If we can reuse it, do so.
12343 Otherwise, make a new string. */
12345 /* The size of the string we might be able to reuse. */
12346 size = (STRINGP (f->desired_tool_bar_string)
12347 ? SCHARS (f->desired_tool_bar_string)
12348 : 0);
12350 /* We need one space in the string for each image. */
12351 size_needed = f->n_tool_bar_items;
12353 /* Reuse f->desired_tool_bar_string, if possible. */
12354 if (size < size_needed || NILP (f->desired_tool_bar_string))
12355 fset_desired_tool_bar_string
12356 (f, Fmake_string (make_number (size_needed), make_number (' '), Qnil));
12357 else
12359 AUTO_LIST4 (props, Qdisplay, Qnil, Qmenu_item, Qnil);
12360 Fremove_text_properties (make_number (0), make_number (size),
12361 props, f->desired_tool_bar_string);
12364 /* Put a `display' property on the string for the images to display,
12365 put a `menu_item' property on tool-bar items with a value that
12366 is the index of the item in F's tool-bar item vector. */
12367 for (i = 0; i < f->n_tool_bar_items; ++i)
12369 #define PROP(IDX) \
12370 AREF (f->tool_bar_items, i * TOOL_BAR_ITEM_NSLOTS + (IDX))
12372 bool enabled_p = !NILP (PROP (TOOL_BAR_ITEM_ENABLED_P));
12373 bool selected_p = !NILP (PROP (TOOL_BAR_ITEM_SELECTED_P));
12374 int hmargin, vmargin, relief, idx, end;
12376 /* If image is a vector, choose the image according to the
12377 button state. */
12378 image = PROP (TOOL_BAR_ITEM_IMAGES);
12379 if (VECTORP (image))
12381 if (enabled_p)
12382 idx = (selected_p
12383 ? TOOL_BAR_IMAGE_ENABLED_SELECTED
12384 : TOOL_BAR_IMAGE_ENABLED_DESELECTED);
12385 else
12386 idx = (selected_p
12387 ? TOOL_BAR_IMAGE_DISABLED_SELECTED
12388 : TOOL_BAR_IMAGE_DISABLED_DESELECTED);
12390 eassert (ASIZE (image) >= idx);
12391 image = AREF (image, idx);
12393 else
12394 idx = -1;
12396 /* Ignore invalid image specifications. */
12397 if (!valid_image_p (image))
12398 continue;
12400 /* Display the tool-bar button pressed, or depressed. */
12401 plist = Fcopy_sequence (XCDR (image));
12403 /* Compute margin and relief to draw. */
12404 relief = (tool_bar_button_relief >= 0
12405 ? tool_bar_button_relief
12406 : DEFAULT_TOOL_BAR_BUTTON_RELIEF);
12407 hmargin = vmargin = relief;
12409 if (RANGED_INTEGERP (1, Vtool_bar_button_margin,
12410 INT_MAX - max (hmargin, vmargin)))
12412 hmargin += XFASTINT (Vtool_bar_button_margin);
12413 vmargin += XFASTINT (Vtool_bar_button_margin);
12415 else if (CONSP (Vtool_bar_button_margin))
12417 if (RANGED_INTEGERP (1, XCAR (Vtool_bar_button_margin),
12418 INT_MAX - hmargin))
12419 hmargin += XFASTINT (XCAR (Vtool_bar_button_margin));
12421 if (RANGED_INTEGERP (1, XCDR (Vtool_bar_button_margin),
12422 INT_MAX - vmargin))
12423 vmargin += XFASTINT (XCDR (Vtool_bar_button_margin));
12426 if (auto_raise_tool_bar_buttons_p)
12428 /* Add a `:relief' property to the image spec if the item is
12429 selected. */
12430 if (selected_p)
12432 plist = Fplist_put (plist, QCrelief, make_number (-relief));
12433 hmargin -= relief;
12434 vmargin -= relief;
12437 else
12439 /* If image is selected, display it pressed, i.e. with a
12440 negative relief. If it's not selected, display it with a
12441 raised relief. */
12442 plist = Fplist_put (plist, QCrelief,
12443 (selected_p
12444 ? make_number (-relief)
12445 : make_number (relief)));
12446 hmargin -= relief;
12447 vmargin -= relief;
12450 /* Put a margin around the image. */
12451 if (hmargin || vmargin)
12453 if (hmargin == vmargin)
12454 plist = Fplist_put (plist, QCmargin, make_number (hmargin));
12455 else
12456 plist = Fplist_put (plist, QCmargin,
12457 Fcons (make_number (hmargin),
12458 make_number (vmargin)));
12461 /* If button is not enabled, and we don't have special images
12462 for the disabled state, make the image appear disabled by
12463 applying an appropriate algorithm to it. */
12464 if (!enabled_p && idx < 0)
12465 plist = Fplist_put (plist, QCconversion, Qdisabled);
12467 /* Put a `display' text property on the string for the image to
12468 display. Put a `menu-item' property on the string that gives
12469 the start of this item's properties in the tool-bar items
12470 vector. */
12471 image = Fcons (Qimage, plist);
12472 AUTO_LIST4 (props, Qdisplay, image, Qmenu_item,
12473 make_number (i * TOOL_BAR_ITEM_NSLOTS));
12475 /* Let the last image hide all remaining spaces in the tool bar
12476 string. The string can be longer than needed when we reuse a
12477 previous string. */
12478 if (i + 1 == f->n_tool_bar_items)
12479 end = SCHARS (f->desired_tool_bar_string);
12480 else
12481 end = i + 1;
12482 Fadd_text_properties (make_number (i), make_number (end),
12483 props, f->desired_tool_bar_string);
12484 #undef PROP
12489 /* Display one line of the tool-bar of frame IT->f.
12491 HEIGHT specifies the desired height of the tool-bar line.
12492 If the actual height of the glyph row is less than HEIGHT, the
12493 row's height is increased to HEIGHT, and the icons are centered
12494 vertically in the new height.
12496 If HEIGHT is -1, we are counting needed tool-bar lines, so don't
12497 count a final empty row in case the tool-bar width exactly matches
12498 the window width.
12501 static void
12502 display_tool_bar_line (struct it *it, int height)
12504 struct glyph_row *row = it->glyph_row;
12505 int max_x = it->last_visible_x;
12506 struct glyph *last;
12508 /* Don't extend on a previously drawn tool bar items (Bug#16058). */
12509 clear_glyph_row (row);
12510 row->enabled_p = true;
12511 row->y = it->current_y;
12513 /* Note that this isn't made use of if the face hasn't a box,
12514 so there's no need to check the face here. */
12515 it->start_of_box_run_p = true;
12517 while (it->current_x < max_x)
12519 int x, n_glyphs_before, i, nglyphs;
12520 struct it it_before;
12522 /* Get the next display element. */
12523 if (!get_next_display_element (it))
12525 /* Don't count empty row if we are counting needed tool-bar lines. */
12526 if (height < 0 && !it->hpos)
12527 return;
12528 break;
12531 /* Produce glyphs. */
12532 n_glyphs_before = row->used[TEXT_AREA];
12533 it_before = *it;
12535 PRODUCE_GLYPHS (it);
12537 nglyphs = row->used[TEXT_AREA] - n_glyphs_before;
12538 i = 0;
12539 x = it_before.current_x;
12540 while (i < nglyphs)
12542 struct glyph *glyph = row->glyphs[TEXT_AREA] + n_glyphs_before + i;
12544 if (x + glyph->pixel_width > max_x)
12546 /* Glyph doesn't fit on line. Backtrack. */
12547 row->used[TEXT_AREA] = n_glyphs_before;
12548 *it = it_before;
12549 /* If this is the only glyph on this line, it will never fit on the
12550 tool-bar, so skip it. But ensure there is at least one glyph,
12551 so we don't accidentally disable the tool-bar. */
12552 if (n_glyphs_before == 0
12553 && (it->vpos > 0 || IT_STRING_CHARPOS (*it) < it->end_charpos-1))
12554 break;
12555 goto out;
12558 ++it->hpos;
12559 x += glyph->pixel_width;
12560 ++i;
12563 /* Stop at line end. */
12564 if (ITERATOR_AT_END_OF_LINE_P (it))
12565 break;
12567 set_iterator_to_next (it, true);
12570 out:;
12572 row->displays_text_p = row->used[TEXT_AREA] != 0;
12574 /* Use default face for the border below the tool bar.
12576 FIXME: When auto-resize-tool-bars is grow-only, there is
12577 no additional border below the possibly empty tool-bar lines.
12578 So to make the extra empty lines look "normal", we have to
12579 use the tool-bar face for the border too. */
12580 if (!MATRIX_ROW_DISPLAYS_TEXT_P (row)
12581 && !EQ (Vauto_resize_tool_bars, Qgrow_only))
12582 it->face_id = DEFAULT_FACE_ID;
12584 extend_face_to_end_of_line (it);
12585 last = row->glyphs[TEXT_AREA] + row->used[TEXT_AREA] - 1;
12586 last->right_box_line_p = true;
12587 if (last == row->glyphs[TEXT_AREA])
12588 last->left_box_line_p = true;
12590 /* Make line the desired height and center it vertically. */
12591 if ((height -= it->max_ascent + it->max_descent) > 0)
12593 /* Don't add more than one line height. */
12594 height %= FRAME_LINE_HEIGHT (it->f);
12595 it->max_ascent += height / 2;
12596 it->max_descent += (height + 1) / 2;
12599 compute_line_metrics (it);
12601 /* If line is empty, make it occupy the rest of the tool-bar. */
12602 if (!MATRIX_ROW_DISPLAYS_TEXT_P (row))
12604 row->height = row->phys_height = it->last_visible_y - row->y;
12605 row->visible_height = row->height;
12606 row->ascent = row->phys_ascent = 0;
12607 row->extra_line_spacing = 0;
12610 row->full_width_p = true;
12611 row->continued_p = false;
12612 row->truncated_on_left_p = false;
12613 row->truncated_on_right_p = false;
12615 it->current_x = it->hpos = 0;
12616 it->current_y += row->height;
12617 ++it->vpos;
12618 ++it->glyph_row;
12622 /* Value is the number of pixels needed to make all tool-bar items of
12623 frame F visible. The actual number of glyph rows needed is
12624 returned in *N_ROWS if non-NULL. */
12625 static int
12626 tool_bar_height (struct frame *f, int *n_rows, bool pixelwise)
12628 struct window *w = XWINDOW (f->tool_bar_window);
12629 struct it it;
12630 /* tool_bar_height is called from redisplay_tool_bar after building
12631 the desired matrix, so use (unused) mode-line row as temporary row to
12632 avoid destroying the first tool-bar row. */
12633 struct glyph_row *temp_row = MATRIX_MODE_LINE_ROW (w->desired_matrix);
12635 /* Initialize an iterator for iteration over
12636 F->desired_tool_bar_string in the tool-bar window of frame F. */
12637 init_iterator (&it, w, -1, -1, temp_row, TOOL_BAR_FACE_ID);
12638 temp_row->reversed_p = false;
12639 it.first_visible_x = 0;
12640 it.last_visible_x = WINDOW_PIXEL_WIDTH (w);
12641 reseat_to_string (&it, NULL, f->desired_tool_bar_string, 0, 0, 0, -1);
12642 it.paragraph_embedding = L2R;
12644 while (!ITERATOR_AT_END_P (&it))
12646 clear_glyph_row (temp_row);
12647 it.glyph_row = temp_row;
12648 display_tool_bar_line (&it, -1);
12650 clear_glyph_row (temp_row);
12652 /* f->n_tool_bar_rows == 0 means "unknown"; -1 means no tool-bar. */
12653 if (n_rows)
12654 *n_rows = it.vpos > 0 ? it.vpos : -1;
12656 if (pixelwise)
12657 return it.current_y;
12658 else
12659 return (it.current_y + FRAME_LINE_HEIGHT (f) - 1) / FRAME_LINE_HEIGHT (f);
12662 #endif /* !USE_GTK && !HAVE_NS */
12664 DEFUN ("tool-bar-height", Ftool_bar_height, Stool_bar_height,
12665 0, 2, 0,
12666 doc: /* Return the number of lines occupied by the tool bar of FRAME.
12667 If FRAME is nil or omitted, use the selected frame. Optional argument
12668 PIXELWISE non-nil means return the height of the tool bar in pixels. */)
12669 (Lisp_Object frame, Lisp_Object pixelwise)
12671 int height = 0;
12673 #if ! defined (USE_GTK) && ! defined (HAVE_NS)
12674 struct frame *f = decode_any_frame (frame);
12676 if (WINDOWP (f->tool_bar_window)
12677 && WINDOW_PIXEL_HEIGHT (XWINDOW (f->tool_bar_window)) > 0)
12679 update_tool_bar (f, true);
12680 if (f->n_tool_bar_items)
12682 build_desired_tool_bar_string (f);
12683 height = tool_bar_height (f, NULL, !NILP (pixelwise));
12686 #endif
12688 return make_number (height);
12692 /* Display the tool-bar of frame F. Value is true if tool-bar's
12693 height should be changed. */
12694 static bool
12695 redisplay_tool_bar (struct frame *f)
12697 f->tool_bar_redisplayed = true;
12698 #if defined (USE_GTK) || defined (HAVE_NS)
12700 if (FRAME_EXTERNAL_TOOL_BAR (f))
12701 update_frame_tool_bar (f);
12702 return false;
12704 #else /* !USE_GTK && !HAVE_NS */
12706 struct window *w;
12707 struct it it;
12708 struct glyph_row *row;
12710 /* If frame hasn't a tool-bar window or if it is zero-height, don't
12711 do anything. This means you must start with tool-bar-lines
12712 non-zero to get the auto-sizing effect. Or in other words, you
12713 can turn off tool-bars by specifying tool-bar-lines zero. */
12714 if (!WINDOWP (f->tool_bar_window)
12715 || (w = XWINDOW (f->tool_bar_window),
12716 WINDOW_TOTAL_LINES (w) == 0))
12717 return false;
12719 /* Set up an iterator for the tool-bar window. */
12720 init_iterator (&it, w, -1, -1, w->desired_matrix->rows, TOOL_BAR_FACE_ID);
12721 it.first_visible_x = 0;
12722 it.last_visible_x = WINDOW_PIXEL_WIDTH (w);
12723 row = it.glyph_row;
12724 row->reversed_p = false;
12726 /* Build a string that represents the contents of the tool-bar. */
12727 build_desired_tool_bar_string (f);
12728 reseat_to_string (&it, NULL, f->desired_tool_bar_string, 0, 0, 0, -1);
12729 /* FIXME: This should be controlled by a user option. But it
12730 doesn't make sense to have an R2L tool bar if the menu bar cannot
12731 be drawn also R2L, and making the menu bar R2L is tricky due
12732 toolkit-specific code that implements it. If an R2L tool bar is
12733 ever supported, display_tool_bar_line should also be augmented to
12734 call unproduce_glyphs like display_line and display_string
12735 do. */
12736 it.paragraph_embedding = L2R;
12738 if (f->n_tool_bar_rows == 0)
12740 int new_height = tool_bar_height (f, &f->n_tool_bar_rows, true);
12742 if (new_height != WINDOW_PIXEL_HEIGHT (w))
12744 x_change_tool_bar_height (f, new_height);
12745 frame_default_tool_bar_height = new_height;
12746 /* Always do that now. */
12747 clear_glyph_matrix (w->desired_matrix);
12748 f->fonts_changed = true;
12749 return true;
12753 /* Display as many lines as needed to display all tool-bar items. */
12755 if (f->n_tool_bar_rows > 0)
12757 int border, rows, height, extra;
12759 if (TYPE_RANGED_INTEGERP (int, Vtool_bar_border))
12760 border = XINT (Vtool_bar_border);
12761 else if (EQ (Vtool_bar_border, Qinternal_border_width))
12762 border = FRAME_INTERNAL_BORDER_WIDTH (f);
12763 else if (EQ (Vtool_bar_border, Qborder_width))
12764 border = f->border_width;
12765 else
12766 border = 0;
12767 if (border < 0)
12768 border = 0;
12770 rows = f->n_tool_bar_rows;
12771 height = max (1, (it.last_visible_y - border) / rows);
12772 extra = it.last_visible_y - border - height * rows;
12774 while (it.current_y < it.last_visible_y)
12776 int h = 0;
12777 if (extra > 0 && rows-- > 0)
12779 h = (extra + rows - 1) / rows;
12780 extra -= h;
12782 display_tool_bar_line (&it, height + h);
12785 else
12787 while (it.current_y < it.last_visible_y)
12788 display_tool_bar_line (&it, 0);
12791 /* It doesn't make much sense to try scrolling in the tool-bar
12792 window, so don't do it. */
12793 w->desired_matrix->no_scrolling_p = true;
12794 w->must_be_updated_p = true;
12796 if (!NILP (Vauto_resize_tool_bars))
12798 bool change_height_p = true;
12800 /* If we couldn't display everything, change the tool-bar's
12801 height if there is room for more. */
12802 if (IT_STRING_CHARPOS (it) < it.end_charpos)
12803 change_height_p = true;
12805 /* We subtract 1 because display_tool_bar_line advances the
12806 glyph_row pointer before returning to its caller. We want to
12807 examine the last glyph row produced by
12808 display_tool_bar_line. */
12809 row = it.glyph_row - 1;
12811 /* If there are blank lines at the end, except for a partially
12812 visible blank line at the end that is smaller than
12813 FRAME_LINE_HEIGHT, change the tool-bar's height. */
12814 if (!MATRIX_ROW_DISPLAYS_TEXT_P (row)
12815 && row->height >= FRAME_LINE_HEIGHT (f))
12816 change_height_p = true;
12818 /* If row displays tool-bar items, but is partially visible,
12819 change the tool-bar's height. */
12820 if (MATRIX_ROW_DISPLAYS_TEXT_P (row)
12821 && MATRIX_ROW_BOTTOM_Y (row) > it.last_visible_y)
12822 change_height_p = true;
12824 /* Resize windows as needed by changing the `tool-bar-lines'
12825 frame parameter. */
12826 if (change_height_p)
12828 int nrows;
12829 int new_height = tool_bar_height (f, &nrows, true);
12831 change_height_p = ((EQ (Vauto_resize_tool_bars, Qgrow_only)
12832 && !f->minimize_tool_bar_window_p)
12833 ? (new_height > WINDOW_PIXEL_HEIGHT (w))
12834 : (new_height != WINDOW_PIXEL_HEIGHT (w)));
12835 f->minimize_tool_bar_window_p = false;
12837 if (change_height_p)
12839 x_change_tool_bar_height (f, new_height);
12840 frame_default_tool_bar_height = new_height;
12841 clear_glyph_matrix (w->desired_matrix);
12842 f->n_tool_bar_rows = nrows;
12843 f->fonts_changed = true;
12845 return true;
12850 f->minimize_tool_bar_window_p = false;
12851 return false;
12853 #endif /* USE_GTK || HAVE_NS */
12856 #if ! defined (USE_GTK) && ! defined (HAVE_NS)
12858 /* Get information about the tool-bar item which is displayed in GLYPH
12859 on frame F. Return in *PROP_IDX the index where tool-bar item
12860 properties start in F->tool_bar_items. Value is false if
12861 GLYPH doesn't display a tool-bar item. */
12863 static bool
12864 tool_bar_item_info (struct frame *f, struct glyph *glyph, int *prop_idx)
12866 Lisp_Object prop;
12867 int charpos;
12869 /* This function can be called asynchronously, which means we must
12870 exclude any possibility that Fget_text_property signals an
12871 error. */
12872 charpos = min (SCHARS (f->current_tool_bar_string), glyph->charpos);
12873 charpos = max (0, charpos);
12875 /* Get the text property `menu-item' at pos. The value of that
12876 property is the start index of this item's properties in
12877 F->tool_bar_items. */
12878 prop = Fget_text_property (make_number (charpos),
12879 Qmenu_item, f->current_tool_bar_string);
12880 if (! INTEGERP (prop))
12881 return false;
12882 *prop_idx = XINT (prop);
12883 return true;
12887 /* Get information about the tool-bar item at position X/Y on frame F.
12888 Return in *GLYPH a pointer to the glyph of the tool-bar item in
12889 the current matrix of the tool-bar window of F, or NULL if not
12890 on a tool-bar item. Return in *PROP_IDX the index of the tool-bar
12891 item in F->tool_bar_items. Value is
12893 -1 if X/Y is not on a tool-bar item
12894 0 if X/Y is on the same item that was highlighted before.
12895 1 otherwise. */
12897 static int
12898 get_tool_bar_item (struct frame *f, int x, int y, struct glyph **glyph,
12899 int *hpos, int *vpos, int *prop_idx)
12901 Mouse_HLInfo *hlinfo = MOUSE_HL_INFO (f);
12902 struct window *w = XWINDOW (f->tool_bar_window);
12903 int area;
12905 /* Find the glyph under X/Y. */
12906 *glyph = x_y_to_hpos_vpos (w, x, y, hpos, vpos, 0, 0, &area);
12907 if (*glyph == NULL)
12908 return -1;
12910 /* Get the start of this tool-bar item's properties in
12911 f->tool_bar_items. */
12912 if (!tool_bar_item_info (f, *glyph, prop_idx))
12913 return -1;
12915 /* Is mouse on the highlighted item? */
12916 if (EQ (f->tool_bar_window, hlinfo->mouse_face_window)
12917 && *vpos >= hlinfo->mouse_face_beg_row
12918 && *vpos <= hlinfo->mouse_face_end_row
12919 && (*vpos > hlinfo->mouse_face_beg_row
12920 || *hpos >= hlinfo->mouse_face_beg_col)
12921 && (*vpos < hlinfo->mouse_face_end_row
12922 || *hpos < hlinfo->mouse_face_end_col
12923 || hlinfo->mouse_face_past_end))
12924 return 0;
12926 return 1;
12930 /* EXPORT:
12931 Handle mouse button event on the tool-bar of frame F, at
12932 frame-relative coordinates X/Y. DOWN_P is true for a button press,
12933 false for button release. MODIFIERS is event modifiers for button
12934 release. */
12936 void
12937 handle_tool_bar_click (struct frame *f, int x, int y, bool down_p,
12938 int modifiers)
12940 Mouse_HLInfo *hlinfo = MOUSE_HL_INFO (f);
12941 struct window *w = XWINDOW (f->tool_bar_window);
12942 int hpos, vpos, prop_idx;
12943 struct glyph *glyph;
12944 Lisp_Object enabled_p;
12945 int ts;
12947 /* If not on the highlighted tool-bar item, and mouse-highlight is
12948 non-nil, return. This is so we generate the tool-bar button
12949 click only when the mouse button is released on the same item as
12950 where it was pressed. However, when mouse-highlight is disabled,
12951 generate the click when the button is released regardless of the
12952 highlight, since tool-bar items are not highlighted in that
12953 case. */
12954 frame_to_window_pixel_xy (w, &x, &y);
12955 ts = get_tool_bar_item (f, x, y, &glyph, &hpos, &vpos, &prop_idx);
12956 if (ts == -1
12957 || (ts != 0 && !NILP (Vmouse_highlight)))
12958 return;
12960 /* When mouse-highlight is off, generate the click for the item
12961 where the button was pressed, disregarding where it was
12962 released. */
12963 if (NILP (Vmouse_highlight) && !down_p)
12964 prop_idx = f->last_tool_bar_item;
12966 /* If item is disabled, do nothing. */
12967 enabled_p = AREF (f->tool_bar_items, prop_idx + TOOL_BAR_ITEM_ENABLED_P);
12968 if (NILP (enabled_p))
12969 return;
12971 if (down_p)
12973 /* Show item in pressed state. */
12974 if (!NILP (Vmouse_highlight))
12975 show_mouse_face (hlinfo, DRAW_IMAGE_SUNKEN);
12976 f->last_tool_bar_item = prop_idx;
12978 else
12980 Lisp_Object key, frame;
12981 struct input_event event;
12982 EVENT_INIT (event);
12984 /* Show item in released state. */
12985 if (!NILP (Vmouse_highlight))
12986 show_mouse_face (hlinfo, DRAW_IMAGE_RAISED);
12988 key = AREF (f->tool_bar_items, prop_idx + TOOL_BAR_ITEM_KEY);
12990 XSETFRAME (frame, f);
12991 event.kind = TOOL_BAR_EVENT;
12992 event.frame_or_window = frame;
12993 event.arg = frame;
12994 kbd_buffer_store_event (&event);
12996 event.kind = TOOL_BAR_EVENT;
12997 event.frame_or_window = frame;
12998 event.arg = key;
12999 event.modifiers = modifiers;
13000 kbd_buffer_store_event (&event);
13001 f->last_tool_bar_item = -1;
13006 /* Possibly highlight a tool-bar item on frame F when mouse moves to
13007 tool-bar window-relative coordinates X/Y. Called from
13008 note_mouse_highlight. */
13010 static void
13011 note_tool_bar_highlight (struct frame *f, int x, int y)
13013 Lisp_Object window = f->tool_bar_window;
13014 struct window *w = XWINDOW (window);
13015 Display_Info *dpyinfo = FRAME_DISPLAY_INFO (f);
13016 Mouse_HLInfo *hlinfo = MOUSE_HL_INFO (f);
13017 int hpos, vpos;
13018 struct glyph *glyph;
13019 struct glyph_row *row;
13020 int i;
13021 Lisp_Object enabled_p;
13022 int prop_idx;
13023 enum draw_glyphs_face draw = DRAW_IMAGE_RAISED;
13024 bool mouse_down_p;
13025 int rc;
13027 /* Function note_mouse_highlight is called with negative X/Y
13028 values when mouse moves outside of the frame. */
13029 if (x <= 0 || y <= 0)
13031 clear_mouse_face (hlinfo);
13032 return;
13035 rc = get_tool_bar_item (f, x, y, &glyph, &hpos, &vpos, &prop_idx);
13036 if (rc < 0)
13038 /* Not on tool-bar item. */
13039 clear_mouse_face (hlinfo);
13040 return;
13042 else if (rc == 0)
13043 /* On same tool-bar item as before. */
13044 goto set_help_echo;
13046 clear_mouse_face (hlinfo);
13048 /* Mouse is down, but on different tool-bar item? */
13049 mouse_down_p = (x_mouse_grabbed (dpyinfo)
13050 && f == dpyinfo->last_mouse_frame);
13052 if (mouse_down_p && f->last_tool_bar_item != prop_idx)
13053 return;
13055 draw = mouse_down_p ? DRAW_IMAGE_SUNKEN : DRAW_IMAGE_RAISED;
13057 /* If tool-bar item is not enabled, don't highlight it. */
13058 enabled_p = AREF (f->tool_bar_items, prop_idx + TOOL_BAR_ITEM_ENABLED_P);
13059 if (!NILP (enabled_p) && !NILP (Vmouse_highlight))
13061 /* Compute the x-position of the glyph. In front and past the
13062 image is a space. We include this in the highlighted area. */
13063 row = MATRIX_ROW (w->current_matrix, vpos);
13064 for (i = x = 0; i < hpos; ++i)
13065 x += row->glyphs[TEXT_AREA][i].pixel_width;
13067 /* Record this as the current active region. */
13068 hlinfo->mouse_face_beg_col = hpos;
13069 hlinfo->mouse_face_beg_row = vpos;
13070 hlinfo->mouse_face_beg_x = x;
13071 hlinfo->mouse_face_past_end = false;
13073 hlinfo->mouse_face_end_col = hpos + 1;
13074 hlinfo->mouse_face_end_row = vpos;
13075 hlinfo->mouse_face_end_x = x + glyph->pixel_width;
13076 hlinfo->mouse_face_window = window;
13077 hlinfo->mouse_face_face_id = TOOL_BAR_FACE_ID;
13079 /* Display it as active. */
13080 show_mouse_face (hlinfo, draw);
13083 set_help_echo:
13085 /* Set help_echo_string to a help string to display for this tool-bar item.
13086 XTread_socket does the rest. */
13087 help_echo_object = help_echo_window = Qnil;
13088 help_echo_pos = -1;
13089 help_echo_string = AREF (f->tool_bar_items, prop_idx + TOOL_BAR_ITEM_HELP);
13090 if (NILP (help_echo_string))
13091 help_echo_string = AREF (f->tool_bar_items, prop_idx + TOOL_BAR_ITEM_CAPTION);
13094 #endif /* !USE_GTK && !HAVE_NS */
13096 #endif /* HAVE_WINDOW_SYSTEM */
13100 /************************************************************************
13101 Horizontal scrolling
13102 ************************************************************************/
13104 /* For all leaf windows in the window tree rooted at WINDOW, set their
13105 hscroll value so that PT is (i) visible in the window, and (ii) so
13106 that it is not within a certain margin at the window's left and
13107 right border. Value is true if any window's hscroll has been
13108 changed. */
13110 static bool
13111 hscroll_window_tree (Lisp_Object window)
13113 bool hscrolled_p = false;
13114 bool hscroll_relative_p = FLOATP (Vhscroll_step);
13115 int hscroll_step_abs = 0;
13116 double hscroll_step_rel = 0;
13118 if (hscroll_relative_p)
13120 hscroll_step_rel = XFLOAT_DATA (Vhscroll_step);
13121 if (hscroll_step_rel < 0)
13123 hscroll_relative_p = false;
13124 hscroll_step_abs = 0;
13127 else if (TYPE_RANGED_INTEGERP (int, Vhscroll_step))
13129 hscroll_step_abs = XINT (Vhscroll_step);
13130 if (hscroll_step_abs < 0)
13131 hscroll_step_abs = 0;
13133 else
13134 hscroll_step_abs = 0;
13136 while (WINDOWP (window))
13138 struct window *w = XWINDOW (window);
13140 if (WINDOWP (w->contents))
13141 hscrolled_p |= hscroll_window_tree (w->contents);
13142 else if (w->cursor.vpos >= 0)
13144 int h_margin;
13145 int text_area_width;
13146 struct glyph_row *cursor_row;
13147 struct glyph_row *bottom_row;
13149 bottom_row = MATRIX_BOTTOM_TEXT_ROW (w->desired_matrix, w);
13150 if (w->cursor.vpos < bottom_row - w->desired_matrix->rows)
13151 cursor_row = MATRIX_ROW (w->desired_matrix, w->cursor.vpos);
13152 else
13153 cursor_row = bottom_row - 1;
13155 if (!cursor_row->enabled_p)
13157 bottom_row = MATRIX_BOTTOM_TEXT_ROW (w->current_matrix, w);
13158 if (w->cursor.vpos < bottom_row - w->current_matrix->rows)
13159 cursor_row = MATRIX_ROW (w->current_matrix, w->cursor.vpos);
13160 else
13161 cursor_row = bottom_row - 1;
13163 bool row_r2l_p = cursor_row->reversed_p;
13164 bool hscl = hscrolling_current_line_p (w);
13165 int x_offset = 0;
13166 /* When line numbers are displayed, we need to account for
13167 the horizontal space they consume. */
13168 if (!NILP (Vdisplay_line_numbers))
13170 struct glyph *g;
13171 if (!row_r2l_p)
13173 for (g = cursor_row->glyphs[TEXT_AREA];
13174 g < cursor_row->glyphs[TEXT_AREA]
13175 + cursor_row->used[TEXT_AREA];
13176 g++)
13178 if (!(NILP (g->object) && g->charpos < 0))
13179 break;
13180 x_offset += g->pixel_width;
13183 else
13185 for (g = cursor_row->glyphs[TEXT_AREA]
13186 + cursor_row->used[TEXT_AREA];
13187 g > cursor_row->glyphs[TEXT_AREA];
13188 g--)
13190 if (!(NILP ((g - 1)->object) && (g - 1)->charpos < 0))
13191 break;
13192 x_offset += (g - 1)->pixel_width;
13196 if (cursor_row->truncated_on_left_p)
13198 /* On TTY frames, don't count the left truncation glyph. */
13199 struct frame *f = XFRAME (WINDOW_FRAME (w));
13200 x_offset -= (FRAME_TERMCAP_P (f) || FRAME_MSDOS_P (f));
13203 text_area_width = window_box_width (w, TEXT_AREA);
13205 /* Scroll when cursor is inside this scroll margin. */
13206 h_margin = hscroll_margin * WINDOW_FRAME_COLUMN_WIDTH (w);
13208 /* If the position of this window's point has explicitly
13209 changed, no more suspend auto hscrolling. */
13210 if (w->suspend_auto_hscroll
13211 && NILP (Fequal (Fwindow_point (window),
13212 Fwindow_old_point (window))))
13214 w->suspend_auto_hscroll = false;
13215 /* When hscrolling just the current line, and the rest
13216 of lines were temporarily hscrolled, but no longer
13217 are, force thorough redisplay of this window, to show
13218 the effect of disabling hscroll suspension immediately. */
13219 if (w->min_hscroll == 0 && w->hscroll > 0
13220 && EQ (Fbuffer_local_value (Qauto_hscroll_mode, w->contents),
13221 Qcurrent_line))
13222 SET_FRAME_GARBAGED (XFRAME (w->frame));
13225 /* Remember window point. */
13226 Fset_marker (w->old_pointm,
13227 ((w == XWINDOW (selected_window))
13228 ? make_number (BUF_PT (XBUFFER (w->contents)))
13229 : Fmarker_position (w->pointm)),
13230 w->contents);
13232 if (!NILP (Fbuffer_local_value (Qauto_hscroll_mode, w->contents))
13233 && !w->suspend_auto_hscroll
13234 /* In some pathological cases, like restoring a window
13235 configuration into a frame that is much smaller than
13236 the one from which the configuration was saved, we
13237 get glyph rows whose start and end have zero buffer
13238 positions, which we cannot handle below. Just skip
13239 such windows. */
13240 && CHARPOS (cursor_row->start.pos) >= BUF_BEG (w->contents)
13241 /* For left-to-right rows, hscroll when cursor is either
13242 (i) inside the right hscroll margin, or (ii) if it is
13243 inside the left margin and the window is already
13244 hscrolled. */
13245 && ((!row_r2l_p
13246 && ((w->hscroll && w->cursor.x <= h_margin + x_offset)
13247 || (cursor_row->enabled_p
13248 && cursor_row->truncated_on_right_p
13249 && (w->cursor.x >= text_area_width - h_margin))))
13250 /* For right-to-left rows, the logic is similar,
13251 except that rules for scrolling to left and right
13252 are reversed. E.g., if cursor.x <= h_margin, we
13253 need to hscroll "to the right" unconditionally,
13254 and that will scroll the screen to the left so as
13255 to reveal the next portion of the row. */
13256 || (row_r2l_p
13257 && ((cursor_row->enabled_p
13258 /* FIXME: It is confusing to set the
13259 truncated_on_right_p flag when R2L rows
13260 are actually truncated on the left. */
13261 && cursor_row->truncated_on_right_p
13262 && w->cursor.x <= h_margin)
13263 || (w->hscroll
13264 && (w->cursor.x >= (text_area_width - h_margin
13265 - x_offset)))))
13266 /* This last condition is needed when moving
13267 vertically from an hscrolled line to a short line
13268 that doesn't need to be hscrolled. If we omit
13269 this condition, the line from which we move will
13270 remain hscrolled. */
13271 || (hscl
13272 && w->hscroll != w->min_hscroll
13273 && !cursor_row->truncated_on_left_p)))
13275 struct it it;
13276 ptrdiff_t hscroll;
13277 struct buffer *saved_current_buffer;
13278 ptrdiff_t pt;
13279 int wanted_x;
13281 /* Find point in a display of infinite width. */
13282 saved_current_buffer = current_buffer;
13283 current_buffer = XBUFFER (w->contents);
13285 if (w == XWINDOW (selected_window))
13286 pt = PT;
13287 else
13288 pt = clip_to_bounds (BEGV, marker_position (w->pointm), ZV);
13290 /* Move iterator to pt starting at cursor_row->start in
13291 a line with infinite width. */
13292 init_to_row_start (&it, w, cursor_row);
13293 if (hscl)
13294 it.first_visible_x = window_hscroll_limited (w, it.f)
13295 * FRAME_COLUMN_WIDTH (it.f);
13296 it.last_visible_x = DISP_INFINITY;
13297 move_it_in_display_line_to (&it, pt, -1, MOVE_TO_POS);
13298 /* If the line ends in an overlay string with a newline,
13299 we might infloop, because displaying the window will
13300 want to put the cursor after the overlay, i.e. at X
13301 coordinate of zero on the next screen line. So we
13302 use the buffer position prior to the overlay string
13303 instead. */
13304 if (it.method == GET_FROM_STRING && pt > 1)
13306 init_to_row_start (&it, w, cursor_row);
13307 if (hscl)
13308 it.first_visible_x = (window_hscroll_limited (w, it.f)
13309 * FRAME_COLUMN_WIDTH (it.f));
13310 move_it_in_display_line_to (&it, pt - 1, -1, MOVE_TO_POS);
13312 current_buffer = saved_current_buffer;
13314 /* Position cursor in window. */
13315 if (!hscroll_relative_p && hscroll_step_abs == 0)
13316 hscroll = max (0, (it.current_x
13317 - (ITERATOR_AT_END_OF_LINE_P (&it)
13318 ? (text_area_width - 4 * FRAME_COLUMN_WIDTH (it.f))
13319 : (text_area_width / 2))))
13320 / FRAME_COLUMN_WIDTH (it.f);
13321 else if ((!row_r2l_p
13322 && w->cursor.x >= text_area_width - h_margin)
13323 || (row_r2l_p && w->cursor.x <= h_margin))
13325 if (hscroll_relative_p)
13326 wanted_x = text_area_width * (1 - hscroll_step_rel)
13327 - h_margin;
13328 else
13329 wanted_x = text_area_width
13330 - hscroll_step_abs * FRAME_COLUMN_WIDTH (it.f)
13331 - h_margin;
13332 hscroll
13333 = max (0, it.current_x - wanted_x) / FRAME_COLUMN_WIDTH (it.f);
13335 else
13337 if (hscroll_relative_p)
13338 wanted_x = text_area_width * hscroll_step_rel
13339 + h_margin;
13340 else
13341 wanted_x = hscroll_step_abs * FRAME_COLUMN_WIDTH (it.f)
13342 + h_margin;
13343 hscroll
13344 = max (0, it.current_x - wanted_x) / FRAME_COLUMN_WIDTH (it.f);
13346 hscroll = max (hscroll, w->min_hscroll);
13348 /* Don't prevent redisplay optimizations if hscroll
13349 hasn't changed, as it will unnecessarily slow down
13350 redisplay. */
13351 if (w->hscroll != hscroll
13352 /* When hscrolling only the current line, we need to
13353 report hscroll even if its value is equal to the
13354 previous one, because the new line might need a
13355 different value. */
13356 || (hscl && w->last_cursor_vpos != w->cursor.vpos))
13358 struct buffer *b = XBUFFER (w->contents);
13359 b->prevent_redisplay_optimizations_p = true;
13360 w->hscroll = hscroll;
13361 hscrolled_p = true;
13366 window = w->next;
13369 /* Value is true if hscroll of any leaf window has been changed. */
13370 return hscrolled_p;
13374 /* Set hscroll so that cursor is visible and not inside horizontal
13375 scroll margins for all windows in the tree rooted at WINDOW. See
13376 also hscroll_window_tree above. Value is true if any window's
13377 hscroll has been changed. If it has, desired matrices on the frame
13378 of WINDOW are cleared. */
13380 static bool
13381 hscroll_windows (Lisp_Object window)
13383 bool hscrolled_p = hscroll_window_tree (window);
13384 if (hscrolled_p)
13385 clear_desired_matrices (XFRAME (WINDOW_FRAME (XWINDOW (window))));
13386 return hscrolled_p;
13391 /************************************************************************
13392 Redisplay
13393 ************************************************************************/
13395 /* Variables holding some state of redisplay if GLYPH_DEBUG is defined.
13396 This is sometimes handy to have in a debugger session. */
13398 #ifdef GLYPH_DEBUG
13400 /* First and last unchanged row for try_window_id. */
13402 static int debug_first_unchanged_at_end_vpos;
13403 static int debug_last_unchanged_at_beg_vpos;
13405 /* Delta vpos and y. */
13407 static int debug_dvpos, debug_dy;
13409 /* Delta in characters and bytes for try_window_id. */
13411 static ptrdiff_t debug_delta, debug_delta_bytes;
13413 /* Values of window_end_pos and window_end_vpos at the end of
13414 try_window_id. */
13416 static ptrdiff_t debug_end_vpos;
13418 /* Append a string to W->desired_matrix->method. FMT is a printf
13419 format string. If trace_redisplay_p is true also printf the
13420 resulting string to stderr. */
13422 static void debug_method_add (struct window *, char const *, ...)
13423 ATTRIBUTE_FORMAT_PRINTF (2, 3);
13425 static void
13426 debug_method_add (struct window *w, char const *fmt, ...)
13428 void *ptr = w;
13429 char *method = w->desired_matrix->method;
13430 int len = strlen (method);
13431 int size = sizeof w->desired_matrix->method;
13432 int remaining = size - len - 1;
13433 va_list ap;
13435 if (len && remaining)
13437 method[len] = '|';
13438 --remaining, ++len;
13441 va_start (ap, fmt);
13442 vsnprintf (method + len, remaining + 1, fmt, ap);
13443 va_end (ap);
13445 if (trace_redisplay_p)
13446 fprintf (stderr, "%p (%s): %s\n",
13447 ptr,
13448 ((BUFFERP (w->contents)
13449 && STRINGP (BVAR (XBUFFER (w->contents), name)))
13450 ? SSDATA (BVAR (XBUFFER (w->contents), name))
13451 : "no buffer"),
13452 method + len);
13455 #endif /* GLYPH_DEBUG */
13458 /* Value is true if all changes in window W, which displays
13459 current_buffer, are in the text between START and END. START is a
13460 buffer position, END is given as a distance from Z. Used in
13461 redisplay_internal for display optimization. */
13463 static bool
13464 text_outside_line_unchanged_p (struct window *w,
13465 ptrdiff_t start, ptrdiff_t end)
13467 bool unchanged_p = true;
13469 /* If text or overlays have changed, see where. */
13470 if (window_outdated (w))
13472 /* Gap in the line? */
13473 if (GPT < start || Z - GPT < end)
13474 unchanged_p = false;
13476 /* Changes start in front of the line, or end after it? */
13477 if (unchanged_p
13478 && (BEG_UNCHANGED < start - 1
13479 || END_UNCHANGED < end))
13480 unchanged_p = false;
13482 /* If selective display, can't optimize if changes start at the
13483 beginning of the line. */
13484 if (unchanged_p
13485 && INTEGERP (BVAR (current_buffer, selective_display))
13486 && XINT (BVAR (current_buffer, selective_display)) > 0
13487 && (BEG_UNCHANGED < start || GPT <= start))
13488 unchanged_p = false;
13490 /* If there are overlays at the start or end of the line, these
13491 may have overlay strings with newlines in them. A change at
13492 START, for instance, may actually concern the display of such
13493 overlay strings as well, and they are displayed on different
13494 lines. So, quickly rule out this case. (For the future, it
13495 might be desirable to implement something more telling than
13496 just BEG/END_UNCHANGED.) */
13497 if (unchanged_p)
13499 if (BEG + BEG_UNCHANGED == start
13500 && overlay_touches_p (start))
13501 unchanged_p = false;
13502 if (END_UNCHANGED == end
13503 && overlay_touches_p (Z - end))
13504 unchanged_p = false;
13507 /* Under bidi reordering, adding or deleting a character in the
13508 beginning of a paragraph, before the first strong directional
13509 character, can change the base direction of the paragraph (unless
13510 the buffer specifies a fixed paragraph direction), which will
13511 require redisplaying the whole paragraph. It might be worthwhile
13512 to find the paragraph limits and widen the range of redisplayed
13513 lines to that, but for now just give up this optimization. */
13514 if (!NILP (BVAR (XBUFFER (w->contents), bidi_display_reordering))
13515 && NILP (BVAR (XBUFFER (w->contents), bidi_paragraph_direction)))
13516 unchanged_p = false;
13519 return unchanged_p;
13523 /* Do a frame update, taking possible shortcuts into account. This is
13524 the main external entry point for redisplay.
13526 If the last redisplay displayed an echo area message and that message
13527 is no longer requested, we clear the echo area or bring back the
13528 mini-buffer if that is in use. */
13530 void
13531 redisplay (void)
13533 redisplay_internal ();
13537 static Lisp_Object
13538 overlay_arrow_string_or_property (Lisp_Object var)
13540 Lisp_Object val;
13542 if (val = Fget (var, Qoverlay_arrow_string), STRINGP (val))
13543 return val;
13545 return Voverlay_arrow_string;
13548 /* Return true if there are any overlay-arrows in current_buffer. */
13549 static bool
13550 overlay_arrow_in_current_buffer_p (void)
13552 Lisp_Object vlist;
13554 for (vlist = Voverlay_arrow_variable_list;
13555 CONSP (vlist);
13556 vlist = XCDR (vlist))
13558 Lisp_Object var = XCAR (vlist);
13559 Lisp_Object val;
13561 if (!SYMBOLP (var))
13562 continue;
13563 val = find_symbol_value (var);
13564 if (MARKERP (val)
13565 && current_buffer == XMARKER (val)->buffer)
13566 return true;
13568 return false;
13572 /* Return true if any overlay_arrows have moved or overlay-arrow-string
13573 has changed.
13574 If SET_REDISPLAY is true, additionally, set the `redisplay' bit in those
13575 buffers that are affected. */
13577 static bool
13578 overlay_arrows_changed_p (bool set_redisplay)
13580 Lisp_Object vlist;
13581 bool changed = false;
13583 for (vlist = Voverlay_arrow_variable_list;
13584 CONSP (vlist);
13585 vlist = XCDR (vlist))
13587 Lisp_Object var = XCAR (vlist);
13588 Lisp_Object val, pstr;
13590 if (!SYMBOLP (var))
13591 continue;
13592 val = find_symbol_value (var);
13593 if (!MARKERP (val))
13594 continue;
13595 if (! EQ (COERCE_MARKER (val),
13596 /* FIXME: Don't we have a problem, using such a global
13597 * "last-position" if the variable is buffer-local? */
13598 Fget (var, Qlast_arrow_position))
13599 || ! (pstr = overlay_arrow_string_or_property (var),
13600 EQ (pstr, Fget (var, Qlast_arrow_string))))
13602 struct buffer *buf = XMARKER (val)->buffer;
13604 if (set_redisplay)
13606 if (buf)
13607 bset_redisplay (buf);
13608 changed = true;
13610 else
13611 return true;
13614 return changed;
13617 /* Mark overlay arrows to be updated on next redisplay. */
13619 static void
13620 update_overlay_arrows (int up_to_date)
13622 Lisp_Object vlist;
13624 for (vlist = Voverlay_arrow_variable_list;
13625 CONSP (vlist);
13626 vlist = XCDR (vlist))
13628 Lisp_Object var = XCAR (vlist);
13630 if (!SYMBOLP (var))
13631 continue;
13633 if (up_to_date > 0)
13635 Lisp_Object val = find_symbol_value (var);
13636 if (!MARKERP (val))
13637 continue;
13638 Fput (var, Qlast_arrow_position,
13639 COERCE_MARKER (val));
13640 Fput (var, Qlast_arrow_string,
13641 overlay_arrow_string_or_property (var));
13643 else if (up_to_date < 0
13644 || !NILP (Fget (var, Qlast_arrow_position)))
13646 Fput (var, Qlast_arrow_position, Qt);
13647 Fput (var, Qlast_arrow_string, Qt);
13653 /* Return overlay arrow string to display at row.
13654 Return integer (bitmap number) for arrow bitmap in left fringe.
13655 Return nil if no overlay arrow. */
13657 static Lisp_Object
13658 overlay_arrow_at_row (struct it *it, struct glyph_row *row)
13660 Lisp_Object vlist;
13662 for (vlist = Voverlay_arrow_variable_list;
13663 CONSP (vlist);
13664 vlist = XCDR (vlist))
13666 Lisp_Object var = XCAR (vlist);
13667 Lisp_Object val;
13669 if (!SYMBOLP (var))
13670 continue;
13672 val = find_symbol_value (var);
13674 if (MARKERP (val)
13675 && current_buffer == XMARKER (val)->buffer
13676 && (MATRIX_ROW_START_CHARPOS (row) == marker_position (val)))
13678 if (FRAME_WINDOW_P (it->f)
13679 /* FIXME: if ROW->reversed_p is set, this should test
13680 the right fringe, not the left one. */
13681 && WINDOW_LEFT_FRINGE_WIDTH (it->w) > 0)
13683 #ifdef HAVE_WINDOW_SYSTEM
13684 if (val = Fget (var, Qoverlay_arrow_bitmap), SYMBOLP (val))
13686 int fringe_bitmap = lookup_fringe_bitmap (val);
13687 if (fringe_bitmap != 0)
13688 return make_number (fringe_bitmap);
13690 #endif
13691 return make_number (-1); /* Use default arrow bitmap. */
13693 return overlay_arrow_string_or_property (var);
13697 return Qnil;
13700 /* Return true if point moved out of or into a composition. Otherwise
13701 return false. PREV_BUF and PREV_PT are the last point buffer and
13702 position. BUF and PT are the current point buffer and position. */
13704 static bool
13705 check_point_in_composition (struct buffer *prev_buf, ptrdiff_t prev_pt,
13706 struct buffer *buf, ptrdiff_t pt)
13708 ptrdiff_t start, end;
13709 Lisp_Object prop;
13710 Lisp_Object buffer;
13712 XSETBUFFER (buffer, buf);
13713 /* Check a composition at the last point if point moved within the
13714 same buffer. */
13715 if (prev_buf == buf)
13717 if (prev_pt == pt)
13718 /* Point didn't move. */
13719 return false;
13721 if (prev_pt > BUF_BEGV (buf) && prev_pt < BUF_ZV (buf)
13722 && find_composition (prev_pt, -1, &start, &end, &prop, buffer)
13723 && composition_valid_p (start, end, prop)
13724 && start < prev_pt && end > prev_pt)
13725 /* The last point was within the composition. Return true iff
13726 point moved out of the composition. */
13727 return (pt <= start || pt >= end);
13730 /* Check a composition at the current point. */
13731 return (pt > BUF_BEGV (buf) && pt < BUF_ZV (buf)
13732 && find_composition (pt, -1, &start, &end, &prop, buffer)
13733 && composition_valid_p (start, end, prop)
13734 && start < pt && end > pt);
13737 /* Reconsider the clip changes of buffer which is displayed in W. */
13739 static void
13740 reconsider_clip_changes (struct window *w)
13742 struct buffer *b = XBUFFER (w->contents);
13744 if (b->clip_changed
13745 && w->window_end_valid
13746 && w->current_matrix->buffer == b
13747 && w->current_matrix->zv == BUF_ZV (b)
13748 && w->current_matrix->begv == BUF_BEGV (b))
13749 b->clip_changed = false;
13751 /* If display wasn't paused, and W is not a tool bar window, see if
13752 point has been moved into or out of a composition. In that case,
13753 set b->clip_changed to force updating the screen. If
13754 b->clip_changed has already been set, skip this check. */
13755 if (!b->clip_changed && w->window_end_valid)
13757 ptrdiff_t pt = (w == XWINDOW (selected_window)
13758 ? PT : marker_position (w->pointm));
13760 if ((w->current_matrix->buffer != b || pt != w->last_point)
13761 && check_point_in_composition (w->current_matrix->buffer,
13762 w->last_point, b, pt))
13763 b->clip_changed = true;
13767 static void
13768 propagate_buffer_redisplay (void)
13769 { /* Resetting b->text->redisplay is problematic!
13770 We can't just reset it in the case that some window that displays
13771 it has not been redisplayed; and such a window can stay
13772 unredisplayed for a long time if it's currently invisible.
13773 But we do want to reset it at the end of redisplay otherwise
13774 its displayed windows will keep being redisplayed over and over
13775 again.
13776 So we copy all b->text->redisplay flags up to their windows here,
13777 such that mark_window_display_accurate can safely reset
13778 b->text->redisplay. */
13779 Lisp_Object ws = window_list ();
13780 for (; CONSP (ws); ws = XCDR (ws))
13782 struct window *thisw = XWINDOW (XCAR (ws));
13783 struct buffer *thisb = XBUFFER (thisw->contents);
13784 if (thisb->text->redisplay)
13785 thisw->redisplay = true;
13789 #define STOP_POLLING \
13790 do { if (! polling_stopped_here) stop_polling (); \
13791 polling_stopped_here = true; } while (false)
13793 #define RESUME_POLLING \
13794 do { if (polling_stopped_here) start_polling (); \
13795 polling_stopped_here = false; } while (false)
13798 /* Perhaps in the future avoid recentering windows if it
13799 is not necessary; currently that causes some problems. */
13801 static void
13802 redisplay_internal (void)
13804 struct window *w = XWINDOW (selected_window);
13805 struct window *sw;
13806 struct frame *fr;
13807 bool pending;
13808 bool must_finish = false, match_p;
13809 struct text_pos tlbufpos, tlendpos;
13810 int number_of_visible_frames;
13811 ptrdiff_t count;
13812 struct frame *sf;
13813 bool polling_stopped_here = false;
13814 Lisp_Object tail, frame;
13816 /* Set a limit to the number of retries we perform due to horizontal
13817 scrolling, this avoids getting stuck in an uninterruptible
13818 infinite loop (Bug #24633). */
13819 enum { MAX_HSCROLL_RETRIES = 16 };
13820 int hscroll_retries = 0;
13822 /* Limit the number of retries for when frame(s) become garbaged as
13823 result of redisplaying them. Some packages set various redisplay
13824 hooks, such as window-scroll-functions, to run Lisp that always
13825 calls APIs which cause the frame's garbaged flag to become set,
13826 so we loop indefinitely. */
13827 enum {MAX_GARBAGED_FRAME_RETRIES = 2 };
13828 int garbaged_frame_retries = 0;
13830 /* True means redisplay has to consider all windows on all
13831 frames. False, only selected_window is considered. */
13832 bool consider_all_windows_p;
13834 /* True means redisplay has to redisplay the miniwindow. */
13835 bool update_miniwindow_p = false;
13837 TRACE ((stderr, "redisplay_internal %d\n", redisplaying_p));
13839 /* No redisplay if running in batch mode or frame is not yet fully
13840 initialized, or redisplay is explicitly turned off by setting
13841 Vinhibit_redisplay. */
13842 if (FRAME_INITIAL_P (SELECTED_FRAME ())
13843 || !NILP (Vinhibit_redisplay))
13844 return;
13846 /* Don't examine these until after testing Vinhibit_redisplay.
13847 When Emacs is shutting down, perhaps because its connection to
13848 X has dropped, we should not look at them at all. */
13849 fr = XFRAME (w->frame);
13850 sf = SELECTED_FRAME ();
13852 if (!fr->glyphs_initialized_p)
13853 return;
13855 #if defined (USE_X_TOOLKIT) || defined (USE_GTK) || defined (HAVE_NS)
13856 if (popup_activated ())
13857 return;
13858 #endif
13860 /* I don't think this happens but let's be paranoid. */
13861 if (redisplaying_p)
13862 return;
13864 /* Record a function that clears redisplaying_p
13865 when we leave this function. */
13866 count = SPECPDL_INDEX ();
13867 record_unwind_protect_void (unwind_redisplay);
13868 redisplaying_p = true;
13869 block_buffer_flips ();
13870 specbind (Qinhibit_free_realized_faces, Qnil);
13872 /* Record this function, so it appears on the profiler's backtraces. */
13873 record_in_backtrace (Qredisplay_internal_xC_functionx, 0, 0);
13875 FOR_EACH_FRAME (tail, frame)
13876 XFRAME (frame)->already_hscrolled_p = false;
13878 retry:
13879 /* Remember the currently selected window. */
13880 sw = w;
13882 pending = false;
13883 forget_escape_and_glyphless_faces ();
13885 inhibit_free_realized_faces = false;
13887 /* If face_change, init_iterator will free all realized faces, which
13888 includes the faces referenced from current matrices. So, we
13889 can't reuse current matrices in this case. */
13890 if (face_change)
13891 windows_or_buffers_changed = 47;
13893 if ((FRAME_TERMCAP_P (sf) || FRAME_MSDOS_P (sf))
13894 && FRAME_TTY (sf)->previous_frame != sf)
13896 /* Since frames on a single ASCII terminal share the same
13897 display area, displaying a different frame means redisplay
13898 the whole thing. */
13899 SET_FRAME_GARBAGED (sf);
13900 #ifndef DOS_NT
13901 set_tty_color_mode (FRAME_TTY (sf), sf);
13902 #endif
13903 FRAME_TTY (sf)->previous_frame = sf;
13906 /* Set the visible flags for all frames. Do this before checking for
13907 resized or garbaged frames; they want to know if their frames are
13908 visible. See the comment in frame.h for FRAME_SAMPLE_VISIBILITY. */
13909 number_of_visible_frames = 0;
13911 FOR_EACH_FRAME (tail, frame)
13913 struct frame *f = XFRAME (frame);
13915 if (FRAME_VISIBLE_P (f))
13917 ++number_of_visible_frames;
13918 /* Adjust matrices for visible frames only. */
13919 if (f->fonts_changed)
13921 adjust_frame_glyphs (f);
13922 /* Disable all redisplay optimizations for this frame.
13923 This is because adjust_frame_glyphs resets the
13924 enabled_p flag for all glyph rows of all windows, so
13925 many optimizations will fail anyway, and some might
13926 fail to test that flag and do bogus things as
13927 result. */
13928 SET_FRAME_GARBAGED (f);
13929 f->fonts_changed = false;
13931 /* If cursor type has been changed on the frame
13932 other than selected, consider all frames. */
13933 if (f != sf && f->cursor_type_changed)
13934 fset_redisplay (f);
13936 clear_desired_matrices (f);
13939 /* Notice any pending interrupt request to change frame size. */
13940 do_pending_window_change (true);
13942 /* do_pending_window_change could change the selected_window due to
13943 frame resizing which makes the selected window too small. */
13944 if (WINDOWP (selected_window) && (w = XWINDOW (selected_window)) != sw)
13945 sw = w;
13947 /* Clear frames marked as garbaged. */
13948 clear_garbaged_frames ();
13950 /* Build menubar and tool-bar items. */
13951 if (NILP (Vmemory_full))
13952 prepare_menu_bars ();
13954 reconsider_clip_changes (w);
13956 /* In most cases selected window displays current buffer. */
13957 match_p = XBUFFER (w->contents) == current_buffer;
13958 if (match_p)
13960 /* Detect case that we need to write or remove a star in the mode line. */
13961 if ((SAVE_MODIFF < MODIFF) != w->last_had_star)
13962 w->update_mode_line = true;
13964 if (mode_line_update_needed (w))
13965 w->update_mode_line = true;
13967 /* If reconsider_clip_changes above decided that the narrowing
13968 in the current buffer changed, make sure all other windows
13969 showing that buffer will be redisplayed. */
13970 if (current_buffer->clip_changed)
13971 bset_update_mode_line (current_buffer);
13974 /* Normally the message* functions will have already displayed and
13975 updated the echo area, but the frame may have been trashed, or
13976 the update may have been preempted, so display the echo area
13977 again here. Checking message_cleared_p captures the case that
13978 the echo area should be cleared. */
13979 if ((!NILP (echo_area_buffer[0]) && !display_last_displayed_message_p)
13980 || (!NILP (echo_area_buffer[1]) && display_last_displayed_message_p)
13981 || (message_cleared_p
13982 && minibuf_level == 0
13983 /* If the mini-window is currently selected, this means the
13984 echo-area doesn't show through. */
13985 && !MINI_WINDOW_P (XWINDOW (selected_window))))
13987 echo_area_display (false);
13989 /* If echo_area_display resizes the mini-window, the redisplay and
13990 window_sizes_changed flags of the selected frame are set, but
13991 it's too late for the hooks in window-size-change-functions,
13992 which have been examined already in prepare_menu_bars. So in
13993 that case we call the hooks here only for the selected frame. */
13994 if (sf->redisplay)
13996 ptrdiff_t count1 = SPECPDL_INDEX ();
13998 record_unwind_save_match_data ();
13999 run_window_size_change_functions (selected_frame);
14000 unbind_to (count1, Qnil);
14003 if (message_cleared_p)
14004 update_miniwindow_p = true;
14006 must_finish = true;
14008 /* If we don't display the current message, don't clear the
14009 message_cleared_p flag, because, if we did, we wouldn't clear
14010 the echo area in the next redisplay which doesn't preserve
14011 the echo area. */
14012 if (!display_last_displayed_message_p)
14013 message_cleared_p = false;
14015 else if (EQ (selected_window, minibuf_window)
14016 && (current_buffer->clip_changed || window_outdated (w))
14017 && resize_mini_window (w, false))
14019 if (sf->redisplay)
14021 ptrdiff_t count1 = SPECPDL_INDEX ();
14023 record_unwind_save_match_data ();
14024 run_window_size_change_functions (selected_frame);
14025 unbind_to (count1, Qnil);
14028 /* Resized active mini-window to fit the size of what it is
14029 showing if its contents might have changed. */
14030 must_finish = true;
14032 /* If window configuration was changed, frames may have been
14033 marked garbaged. Clear them or we will experience
14034 surprises wrt scrolling. */
14035 clear_garbaged_frames ();
14038 if (windows_or_buffers_changed && !update_mode_lines)
14039 /* Code that sets windows_or_buffers_changed doesn't distinguish whether
14040 only the windows's contents needs to be refreshed, or whether the
14041 mode-lines also need a refresh. */
14042 update_mode_lines = (windows_or_buffers_changed == REDISPLAY_SOME
14043 ? REDISPLAY_SOME : 32);
14045 /* If specs for an arrow have changed, do thorough redisplay
14046 to ensure we remove any arrow that should no longer exist. */
14047 /* Apparently, this is the only case where we update other windows,
14048 without updating other mode-lines. */
14049 overlay_arrows_changed_p (true);
14051 consider_all_windows_p = (update_mode_lines
14052 || windows_or_buffers_changed);
14054 #define AINC(a,i) \
14056 Lisp_Object entry = Fgethash (make_number (i), a, make_number (0)); \
14057 if (INTEGERP (entry)) \
14058 Fputhash (make_number (i), make_number (1 + XINT (entry)), a); \
14061 AINC (Vredisplay__all_windows_cause, windows_or_buffers_changed);
14062 AINC (Vredisplay__mode_lines_cause, update_mode_lines);
14064 /* Optimize the case that only the line containing the cursor in the
14065 selected window has changed. Variables starting with this_ are
14066 set in display_line and record information about the line
14067 containing the cursor. */
14068 tlbufpos = this_line_start_pos;
14069 tlendpos = this_line_end_pos;
14070 if (!consider_all_windows_p
14071 && CHARPOS (tlbufpos) > 0
14072 && !w->update_mode_line
14073 && !current_buffer->clip_changed
14074 && !current_buffer->prevent_redisplay_optimizations_p
14075 && FRAME_VISIBLE_P (XFRAME (w->frame))
14076 && !FRAME_OBSCURED_P (XFRAME (w->frame))
14077 && !XFRAME (w->frame)->cursor_type_changed
14078 && !XFRAME (w->frame)->face_change
14079 /* Make sure recorded data applies to current buffer, etc. */
14080 && this_line_buffer == current_buffer
14081 && match_p
14082 && !w->force_start
14083 && !w->optional_new_start
14084 /* Point must be on the line that we have info recorded about. */
14085 && PT >= CHARPOS (tlbufpos)
14086 && PT <= Z - CHARPOS (tlendpos)
14087 /* All text outside that line, including its final newline,
14088 must be unchanged. */
14089 && text_outside_line_unchanged_p (w, CHARPOS (tlbufpos),
14090 CHARPOS (tlendpos)))
14092 if (CHARPOS (tlbufpos) > BEGV
14093 && FETCH_BYTE (BYTEPOS (tlbufpos) - 1) != '\n'
14094 && (CHARPOS (tlbufpos) == ZV
14095 || FETCH_BYTE (BYTEPOS (tlbufpos)) == '\n'))
14096 /* Former continuation line has disappeared by becoming empty. */
14097 goto cancel;
14098 else if (window_outdated (w) || MINI_WINDOW_P (w))
14100 /* We have to handle the case of continuation around a
14101 wide-column character (see the comment in indent.c around
14102 line 1340).
14104 For instance, in the following case:
14106 -------- Insert --------
14107 K_A_N_\\ `a' K_A_N_a\ `X_' are wide-column chars.
14108 J_I_ ==> J_I_ `^^' are cursors.
14109 ^^ ^^
14110 -------- --------
14112 As we have to redraw the line above, we cannot use this
14113 optimization. */
14115 struct it it;
14116 int line_height_before = this_line_pixel_height;
14118 /* Note that start_display will handle the case that the
14119 line starting at tlbufpos is a continuation line. */
14120 start_display (&it, w, tlbufpos);
14122 /* Implementation note: It this still necessary? */
14123 if (it.current_x != this_line_start_x)
14124 goto cancel;
14126 TRACE ((stderr, "trying display optimization 1\n"));
14127 w->cursor.vpos = -1;
14128 overlay_arrow_seen = false;
14129 it.vpos = this_line_vpos;
14130 it.current_y = this_line_y;
14131 it.glyph_row = MATRIX_ROW (w->desired_matrix, this_line_vpos);
14132 display_line (&it, -1);
14134 /* If line contains point, is not continued,
14135 and ends at same distance from eob as before, we win. */
14136 if (w->cursor.vpos >= 0
14137 /* Line is not continued, otherwise this_line_start_pos
14138 would have been set to 0 in display_line. */
14139 && CHARPOS (this_line_start_pos)
14140 /* Line ends as before. */
14141 && CHARPOS (this_line_end_pos) == CHARPOS (tlendpos)
14142 /* Line has same height as before. Otherwise other lines
14143 would have to be shifted up or down. */
14144 && this_line_pixel_height == line_height_before)
14146 /* If this is not the window's last line, we must adjust
14147 the charstarts of the lines below. */
14148 if (it.current_y < it.last_visible_y)
14150 struct glyph_row *row
14151 = MATRIX_ROW (w->current_matrix, this_line_vpos + 1);
14152 ptrdiff_t delta, delta_bytes;
14154 /* We used to distinguish between two cases here,
14155 conditioned by Z - CHARPOS (tlendpos) == ZV, for
14156 when the line ends in a newline or the end of the
14157 buffer's accessible portion. But both cases did
14158 the same, so they were collapsed. */
14159 delta = (Z
14160 - CHARPOS (tlendpos)
14161 - MATRIX_ROW_START_CHARPOS (row));
14162 delta_bytes = (Z_BYTE
14163 - BYTEPOS (tlendpos)
14164 - MATRIX_ROW_START_BYTEPOS (row));
14166 increment_matrix_positions (w->current_matrix,
14167 this_line_vpos + 1,
14168 w->current_matrix->nrows,
14169 delta, delta_bytes);
14172 /* If this row displays text now but previously didn't,
14173 or vice versa, w->window_end_vpos may have to be
14174 adjusted. */
14175 if (MATRIX_ROW_DISPLAYS_TEXT_P (it.glyph_row - 1))
14177 if (w->window_end_vpos < this_line_vpos)
14178 w->window_end_vpos = this_line_vpos;
14180 else if (w->window_end_vpos == this_line_vpos
14181 && this_line_vpos > 0)
14182 w->window_end_vpos = this_line_vpos - 1;
14183 w->window_end_valid = false;
14185 /* Update hint: No need to try to scroll in update_window. */
14186 w->desired_matrix->no_scrolling_p = true;
14188 #ifdef GLYPH_DEBUG
14189 *w->desired_matrix->method = 0;
14190 debug_method_add (w, "optimization 1");
14191 #endif
14192 #ifdef HAVE_WINDOW_SYSTEM
14193 update_window_fringes (w, false);
14194 #endif
14195 goto update;
14197 else
14198 goto cancel;
14200 else if (/* Cursor position hasn't changed. */
14201 PT == w->last_point
14202 /* Make sure the cursor was last displayed
14203 in this window. Otherwise we have to reposition it. */
14205 /* PXW: Must be converted to pixels, probably. */
14206 && 0 <= w->cursor.vpos
14207 && w->cursor.vpos < WINDOW_TOTAL_LINES (w))
14209 if (!must_finish)
14211 do_pending_window_change (true);
14212 /* If selected_window changed, redisplay again. */
14213 if (WINDOWP (selected_window)
14214 && (w = XWINDOW (selected_window)) != sw)
14215 goto retry;
14217 /* We used to always goto end_of_redisplay here, but this
14218 isn't enough if we have a blinking cursor. */
14219 if (w->cursor_off_p == w->last_cursor_off_p)
14220 goto end_of_redisplay;
14222 goto update;
14224 /* If highlighting the region, or if the cursor is in the echo area,
14225 then we can't just move the cursor. */
14226 else if (NILP (Vshow_trailing_whitespace)
14227 && !cursor_in_echo_area)
14229 struct it it;
14230 struct glyph_row *row;
14232 /* Skip from tlbufpos to PT and see where it is. Note that
14233 PT may be in invisible text. If so, we will end at the
14234 next visible position. */
14235 init_iterator (&it, w, CHARPOS (tlbufpos), BYTEPOS (tlbufpos),
14236 NULL, DEFAULT_FACE_ID);
14237 it.current_x = this_line_start_x;
14238 it.current_y = this_line_y;
14239 it.vpos = this_line_vpos;
14241 /* The call to move_it_to stops in front of PT, but
14242 moves over before-strings. */
14243 move_it_to (&it, PT, -1, -1, -1, MOVE_TO_POS);
14245 if (it.vpos == this_line_vpos
14246 && (row = MATRIX_ROW (w->current_matrix, this_line_vpos),
14247 row->enabled_p))
14249 eassert (this_line_vpos == it.vpos);
14250 eassert (this_line_y == it.current_y);
14251 set_cursor_from_row (w, row, w->current_matrix, 0, 0, 0, 0);
14252 if (cursor_row_fully_visible_p (w, false, true))
14254 #ifdef GLYPH_DEBUG
14255 *w->desired_matrix->method = 0;
14256 debug_method_add (w, "optimization 3");
14257 #endif
14258 goto update;
14260 else
14261 goto cancel;
14263 else
14264 goto cancel;
14267 cancel:
14268 /* Text changed drastically or point moved off of line. */
14269 SET_MATRIX_ROW_ENABLED_P (w->desired_matrix, this_line_vpos, false);
14272 CHARPOS (this_line_start_pos) = 0;
14273 ++clear_face_cache_count;
14274 #ifdef HAVE_WINDOW_SYSTEM
14275 ++clear_image_cache_count;
14276 #endif
14278 /* Build desired matrices, and update the display. If
14279 consider_all_windows_p, do it for all windows on all frames that
14280 require redisplay, as specified by their 'redisplay' flag.
14281 Otherwise do it for selected_window, only. */
14283 if (consider_all_windows_p)
14285 FOR_EACH_FRAME (tail, frame)
14286 XFRAME (frame)->updated_p = false;
14288 propagate_buffer_redisplay ();
14290 FOR_EACH_FRAME (tail, frame)
14292 struct frame *f = XFRAME (frame);
14294 /* We don't have to do anything for unselected terminal
14295 frames. */
14296 if ((FRAME_TERMCAP_P (f) || FRAME_MSDOS_P (f))
14297 && !EQ (FRAME_TTY (f)->top_frame, frame))
14298 continue;
14300 retry_frame:
14301 if (FRAME_WINDOW_P (f) || FRAME_TERMCAP_P (f) || f == sf)
14303 bool gcscrollbars
14304 /* Only GC scrollbars when we redisplay the whole frame. */
14305 = f->redisplay || !REDISPLAY_SOME_P ();
14306 bool f_redisplay_flag = f->redisplay;
14307 /* Mark all the scroll bars to be removed; we'll redeem
14308 the ones we want when we redisplay their windows. */
14309 if (gcscrollbars && FRAME_TERMINAL (f)->condemn_scroll_bars_hook)
14310 FRAME_TERMINAL (f)->condemn_scroll_bars_hook (f);
14312 if (FRAME_VISIBLE_P (f) && !FRAME_OBSCURED_P (f))
14313 redisplay_windows (FRAME_ROOT_WINDOW (f));
14314 /* Remember that the invisible frames need to be redisplayed next
14315 time they're visible. */
14316 else if (!REDISPLAY_SOME_P ())
14317 f->redisplay = true;
14319 /* The X error handler may have deleted that frame. */
14320 if (!FRAME_LIVE_P (f))
14321 continue;
14323 /* Any scroll bars which redisplay_windows should have
14324 nuked should now go away. */
14325 if (gcscrollbars && FRAME_TERMINAL (f)->judge_scroll_bars_hook)
14326 FRAME_TERMINAL (f)->judge_scroll_bars_hook (f);
14328 if (FRAME_VISIBLE_P (f) && !FRAME_OBSCURED_P (f))
14330 /* If fonts changed on visible frame, display again. */
14331 if (f->fonts_changed)
14333 adjust_frame_glyphs (f);
14334 /* Disable all redisplay optimizations for this
14335 frame. For the reasons, see the comment near
14336 the previous call to adjust_frame_glyphs above. */
14337 SET_FRAME_GARBAGED (f);
14338 f->fonts_changed = false;
14339 goto retry_frame;
14342 /* See if we have to hscroll. */
14343 if (!f->already_hscrolled_p)
14345 f->already_hscrolled_p = true;
14346 if (hscroll_retries <= MAX_HSCROLL_RETRIES
14347 && hscroll_windows (f->root_window))
14349 hscroll_retries++;
14350 goto retry_frame;
14354 /* If the frame's redisplay flag was not set before
14355 we went about redisplaying its windows, but it is
14356 set now, that means we employed some redisplay
14357 optimizations inside redisplay_windows, and
14358 bypassed producing some screen lines. But if
14359 f->redisplay is now set, it might mean the old
14360 faces are no longer valid (e.g., if redisplaying
14361 some window called some Lisp which defined a new
14362 face or redefined an existing face), so trying to
14363 use them in update_frame will segfault.
14364 Therefore, we must redisplay this frame. */
14365 if (!f_redisplay_flag && f->redisplay)
14366 goto retry_frame;
14367 /* In some case (e.g., window resize), we notice
14368 only during window updating that the window
14369 content changed unpredictably (e.g., a GTK
14370 scrollbar moved, or some Lisp hook that winds up
14371 calling adjust_frame_glyphs) and that our
14372 previous estimation of the frame content was
14373 garbage. We have to start over. These cases
14374 should be rare, so going all the way back to the
14375 top of redisplay should be good enough. */
14376 if (FRAME_GARBAGED_P (f)
14377 && garbaged_frame_retries++ < MAX_GARBAGED_FRAME_RETRIES)
14378 goto retry;
14380 #if defined (HAVE_WINDOW_SYSTEM) && !defined (HAVE_NS)
14381 x_clear_under_internal_border (f);
14382 #endif /* HAVE_WINDOW_SYSTEM && !HAVE_NS */
14384 /* Prevent various kinds of signals during display
14385 update. stdio is not robust about handling
14386 signals, which can cause an apparent I/O error. */
14387 if (interrupt_input)
14388 unrequest_sigio ();
14389 STOP_POLLING;
14391 pending |= update_frame (f, false, false);
14392 f->cursor_type_changed = false;
14393 f->updated_p = true;
14398 eassert (EQ (XFRAME (selected_frame)->selected_window, selected_window));
14400 if (!pending)
14402 /* Do the mark_window_display_accurate after all windows have
14403 been redisplayed because this call resets flags in buffers
14404 which are needed for proper redisplay. */
14405 FOR_EACH_FRAME (tail, frame)
14407 struct frame *f = XFRAME (frame);
14408 if (f->updated_p)
14410 f->redisplay = false;
14411 f->garbaged = false;
14412 mark_window_display_accurate (f->root_window, true);
14413 if (FRAME_TERMINAL (f)->frame_up_to_date_hook)
14414 FRAME_TERMINAL (f)->frame_up_to_date_hook (f);
14419 else if (FRAME_VISIBLE_P (sf) && !FRAME_OBSCURED_P (sf))
14421 displayed_buffer = XBUFFER (XWINDOW (selected_window)->contents);
14422 /* Use list_of_error, not Qerror, so that
14423 we catch only errors and don't run the debugger. */
14424 internal_condition_case_1 (redisplay_window_1, selected_window,
14425 list_of_error,
14426 redisplay_window_error);
14427 if (update_miniwindow_p)
14428 internal_condition_case_1 (redisplay_window_1,
14429 FRAME_MINIBUF_WINDOW (sf), list_of_error,
14430 redisplay_window_error);
14432 /* Compare desired and current matrices, perform output. */
14434 update:
14435 /* If fonts changed, display again. Likewise if redisplay_window_1
14436 above caused some change (e.g., a change in faces) that requires
14437 considering the entire frame again. */
14438 if (sf->fonts_changed || sf->redisplay)
14440 if (sf->redisplay)
14442 /* Set this to force a more thorough redisplay.
14443 Otherwise, we might immediately loop back to the
14444 above "else-if" clause (since all the conditions that
14445 led here might still be true), and we will then
14446 infloop, because the selected-frame's redisplay flag
14447 is not (and cannot be) reset. */
14448 windows_or_buffers_changed = 50;
14450 goto retry;
14453 /* Prevent freeing of realized faces, since desired matrices are
14454 pending that reference the faces we computed and cached. */
14455 inhibit_free_realized_faces = true;
14457 /* Prevent various kinds of signals during display update.
14458 stdio is not robust about handling signals,
14459 which can cause an apparent I/O error. */
14460 if (interrupt_input)
14461 unrequest_sigio ();
14462 STOP_POLLING;
14464 if (FRAME_VISIBLE_P (sf) && !FRAME_OBSCURED_P (sf))
14466 if (hscroll_retries <= MAX_HSCROLL_RETRIES
14467 && hscroll_windows (selected_window))
14469 hscroll_retries++;
14470 goto retry;
14473 XWINDOW (selected_window)->must_be_updated_p = true;
14474 pending = update_frame (sf, false, false);
14475 sf->cursor_type_changed = false;
14478 /* We may have called echo_area_display at the top of this
14479 function. If the echo area is on another frame, that may
14480 have put text on a frame other than the selected one, so the
14481 above call to update_frame would not have caught it. Catch
14482 it here. */
14483 Lisp_Object mini_window = FRAME_MINIBUF_WINDOW (sf);
14484 struct frame *mini_frame = XFRAME (WINDOW_FRAME (XWINDOW (mini_window)));
14486 if (mini_frame != sf && FRAME_WINDOW_P (mini_frame))
14488 XWINDOW (mini_window)->must_be_updated_p = true;
14489 pending |= update_frame (mini_frame, false, false);
14490 mini_frame->cursor_type_changed = false;
14491 if (!pending && hscroll_retries <= MAX_HSCROLL_RETRIES
14492 && hscroll_windows (mini_window))
14494 hscroll_retries++;
14495 goto retry;
14500 /* If display was paused because of pending input, make sure we do a
14501 thorough update the next time. */
14502 if (pending)
14504 /* Prevent the optimization at the beginning of
14505 redisplay_internal that tries a single-line update of the
14506 line containing the cursor in the selected window. */
14507 CHARPOS (this_line_start_pos) = 0;
14509 /* Let the overlay arrow be updated the next time. */
14510 update_overlay_arrows (0);
14512 /* If we pause after scrolling, some rows in the current
14513 matrices of some windows are not valid. */
14514 if (!WINDOW_FULL_WIDTH_P (w)
14515 && !FRAME_WINDOW_P (XFRAME (w->frame)))
14516 update_mode_lines = 36;
14518 else
14520 if (!consider_all_windows_p)
14522 /* This has already been done above if
14523 consider_all_windows_p is set. */
14524 if (XBUFFER (w->contents)->text->redisplay
14525 && buffer_window_count (XBUFFER (w->contents)) > 1)
14526 /* This can happen if b->text->redisplay was set during
14527 jit-lock. */
14528 propagate_buffer_redisplay ();
14529 mark_window_display_accurate_1 (w, true);
14531 /* Say overlay arrows are up to date. */
14532 update_overlay_arrows (1);
14534 if (FRAME_TERMINAL (sf)->frame_up_to_date_hook != 0)
14535 FRAME_TERMINAL (sf)->frame_up_to_date_hook (sf);
14538 update_mode_lines = 0;
14539 windows_or_buffers_changed = 0;
14542 /* Start SIGIO interrupts coming again. Having them off during the
14543 code above makes it less likely one will discard output, but not
14544 impossible, since there might be stuff in the system buffer here.
14545 But it is much hairier to try to do anything about that. */
14546 if (interrupt_input)
14547 request_sigio ();
14548 RESUME_POLLING;
14550 /* If a frame has become visible which was not before, redisplay
14551 again, so that we display it. Expose events for such a frame
14552 (which it gets when becoming visible) don't call the parts of
14553 redisplay constructing glyphs, so simply exposing a frame won't
14554 display anything in this case. So, we have to display these
14555 frames here explicitly. */
14556 if (!pending)
14558 int new_count = 0;
14560 FOR_EACH_FRAME (tail, frame)
14562 if (XFRAME (frame)->visible)
14563 new_count++;
14566 if (new_count != number_of_visible_frames)
14567 windows_or_buffers_changed = 52;
14570 /* Change frame size now if a change is pending. */
14571 do_pending_window_change (true);
14573 /* If we just did a pending size change, or have additional
14574 visible frames, or selected_window changed, redisplay again. */
14575 if ((windows_or_buffers_changed && !pending)
14576 || (WINDOWP (selected_window) && (w = XWINDOW (selected_window)) != sw))
14577 goto retry;
14579 /* Clear the face and image caches.
14581 We used to do this only if consider_all_windows_p. But the cache
14582 needs to be cleared if a timer creates images in the current
14583 buffer (e.g. the test case in Bug#6230). */
14585 if (clear_face_cache_count > CLEAR_FACE_CACHE_COUNT)
14587 clear_face_cache (false);
14588 clear_face_cache_count = 0;
14591 #ifdef HAVE_WINDOW_SYSTEM
14592 if (clear_image_cache_count > CLEAR_IMAGE_CACHE_COUNT)
14594 clear_image_caches (Qnil);
14595 clear_image_cache_count = 0;
14597 #endif /* HAVE_WINDOW_SYSTEM */
14599 end_of_redisplay:
14600 #ifdef HAVE_NS
14601 ns_set_doc_edited ();
14602 #endif
14603 if (interrupt_input && interrupts_deferred)
14604 request_sigio ();
14606 unbind_to (count, Qnil);
14607 RESUME_POLLING;
14610 static void
14611 unwind_redisplay_preserve_echo_area (void)
14613 unblock_buffer_flips ();
14616 /* Redisplay, but leave alone any recent echo area message unless
14617 another message has been requested in its place.
14619 This is useful in situations where you need to redisplay but no
14620 user action has occurred, making it inappropriate for the message
14621 area to be cleared. See tracking_off and
14622 wait_reading_process_output for examples of these situations.
14624 FROM_WHERE is an integer saying from where this function was
14625 called. This is useful for debugging. */
14627 void
14628 redisplay_preserve_echo_area (int from_where)
14630 TRACE ((stderr, "redisplay_preserve_echo_area (%d)\n", from_where));
14632 block_input ();
14633 ptrdiff_t count = SPECPDL_INDEX ();
14634 record_unwind_protect_void (unwind_redisplay_preserve_echo_area);
14635 block_buffer_flips ();
14636 unblock_input ();
14638 if (!NILP (echo_area_buffer[1]))
14640 /* We have a previously displayed message, but no current
14641 message. Redisplay the previous message. */
14642 display_last_displayed_message_p = true;
14643 redisplay_internal ();
14644 display_last_displayed_message_p = false;
14646 else
14647 redisplay_internal ();
14649 flush_frame (SELECTED_FRAME ());
14650 unbind_to (count, Qnil);
14654 /* Function registered with record_unwind_protect in redisplay_internal. */
14656 static void
14657 unwind_redisplay (void)
14659 redisplaying_p = false;
14660 unblock_buffer_flips ();
14664 /* Mark the display of leaf window W as accurate or inaccurate.
14665 If ACCURATE_P, mark display of W as accurate.
14666 If !ACCURATE_P, arrange for W to be redisplayed the next
14667 time redisplay_internal is called. */
14669 static void
14670 mark_window_display_accurate_1 (struct window *w, bool accurate_p)
14672 struct buffer *b = XBUFFER (w->contents);
14674 w->last_modified = accurate_p ? BUF_MODIFF (b) : 0;
14675 w->last_overlay_modified = accurate_p ? BUF_OVERLAY_MODIFF (b) : 0;
14676 w->last_had_star = BUF_MODIFF (b) > BUF_SAVE_MODIFF (b);
14678 if (accurate_p)
14680 b->clip_changed = false;
14681 b->prevent_redisplay_optimizations_p = false;
14682 eassert (buffer_window_count (b) > 0);
14683 /* Resetting b->text->redisplay is problematic!
14684 In order to make it safer to do it here, redisplay_internal must
14685 have copied all b->text->redisplay to their respective windows. */
14686 b->text->redisplay = false;
14688 BUF_UNCHANGED_MODIFIED (b) = BUF_MODIFF (b);
14689 BUF_OVERLAY_UNCHANGED_MODIFIED (b) = BUF_OVERLAY_MODIFF (b);
14690 BUF_BEG_UNCHANGED (b) = BUF_GPT (b) - BUF_BEG (b);
14691 BUF_END_UNCHANGED (b) = BUF_Z (b) - BUF_GPT (b);
14693 w->current_matrix->buffer = b;
14694 w->current_matrix->begv = BUF_BEGV (b);
14695 w->current_matrix->zv = BUF_ZV (b);
14697 w->last_cursor_vpos = w->cursor.vpos;
14698 w->last_cursor_off_p = w->cursor_off_p;
14700 if (w == XWINDOW (selected_window))
14701 w->last_point = BUF_PT (b);
14702 else
14703 w->last_point = marker_position (w->pointm);
14705 w->window_end_valid = true;
14706 w->update_mode_line = false;
14709 w->redisplay = !accurate_p;
14713 /* Mark the display of windows in the window tree rooted at WINDOW as
14714 accurate or inaccurate. If ACCURATE_P, mark display of
14715 windows as accurate. If !ACCURATE_P, arrange for windows to
14716 be redisplayed the next time redisplay_internal is called. */
14718 void
14719 mark_window_display_accurate (Lisp_Object window, bool accurate_p)
14721 struct window *w;
14723 for (; !NILP (window); window = w->next)
14725 w = XWINDOW (window);
14726 if (WINDOWP (w->contents))
14727 mark_window_display_accurate (w->contents, accurate_p);
14728 else
14729 mark_window_display_accurate_1 (w, accurate_p);
14732 if (accurate_p)
14733 update_overlay_arrows (1);
14734 else
14735 /* Force a thorough redisplay the next time by setting
14736 last_arrow_position and last_arrow_string to t, which is
14737 unequal to any useful value of Voverlay_arrow_... */
14738 update_overlay_arrows (-1);
14742 /* Return value in display table DP (Lisp_Char_Table *) for character
14743 C. Since a display table doesn't have any parent, we don't have to
14744 follow parent. Do not call this function directly but use the
14745 macro DISP_CHAR_VECTOR. */
14747 Lisp_Object
14748 disp_char_vector (struct Lisp_Char_Table *dp, int c)
14750 Lisp_Object val;
14752 if (ASCII_CHAR_P (c))
14754 val = dp->ascii;
14755 if (SUB_CHAR_TABLE_P (val))
14756 val = XSUB_CHAR_TABLE (val)->contents[c];
14758 else
14760 Lisp_Object table;
14762 XSETCHAR_TABLE (table, dp);
14763 val = char_table_ref (table, c);
14765 if (NILP (val))
14766 val = dp->defalt;
14767 return val;
14770 static int buffer_flip_blocked_depth;
14772 static void
14773 block_buffer_flips (void)
14775 eassert (buffer_flip_blocked_depth >= 0);
14776 buffer_flip_blocked_depth++;
14779 static void
14780 unblock_buffer_flips (void)
14782 eassert (buffer_flip_blocked_depth > 0);
14783 if (--buffer_flip_blocked_depth == 0)
14785 Lisp_Object tail, frame;
14786 block_input ();
14787 FOR_EACH_FRAME (tail, frame)
14789 struct frame *f = XFRAME (frame);
14790 if (FRAME_TERMINAL (f)->buffer_flipping_unblocked_hook)
14791 (*FRAME_TERMINAL (f)->buffer_flipping_unblocked_hook) (f);
14793 unblock_input ();
14797 bool
14798 buffer_flipping_blocked_p (void)
14800 return buffer_flip_blocked_depth > 0;
14804 /***********************************************************************
14805 Window Redisplay
14806 ***********************************************************************/
14808 /* Redisplay all leaf windows in the window tree rooted at WINDOW. */
14810 static void
14811 redisplay_windows (Lisp_Object window)
14813 while (!NILP (window))
14815 struct window *w = XWINDOW (window);
14817 if (WINDOWP (w->contents))
14818 redisplay_windows (w->contents);
14819 else if (BUFFERP (w->contents))
14821 displayed_buffer = XBUFFER (w->contents);
14822 /* Use list_of_error, not Qerror, so that
14823 we catch only errors and don't run the debugger. */
14824 internal_condition_case_1 (redisplay_window_0, window,
14825 list_of_error,
14826 redisplay_window_error);
14829 window = w->next;
14833 static Lisp_Object
14834 redisplay_window_error (Lisp_Object ignore)
14836 displayed_buffer->display_error_modiff = BUF_MODIFF (displayed_buffer);
14837 return Qnil;
14840 static Lisp_Object
14841 redisplay_window_0 (Lisp_Object window)
14843 if (displayed_buffer->display_error_modiff < BUF_MODIFF (displayed_buffer))
14844 redisplay_window (window, false);
14845 return Qnil;
14848 static Lisp_Object
14849 redisplay_window_1 (Lisp_Object window)
14851 if (displayed_buffer->display_error_modiff < BUF_MODIFF (displayed_buffer))
14852 redisplay_window (window, true);
14853 return Qnil;
14857 /* Set cursor position of W. PT is assumed to be displayed in ROW.
14858 DELTA and DELTA_BYTES are the numbers of characters and bytes by
14859 which positions recorded in ROW differ from current buffer
14860 positions.
14862 Return true iff cursor is on this row. */
14864 static bool
14865 set_cursor_from_row (struct window *w, struct glyph_row *row,
14866 struct glyph_matrix *matrix,
14867 ptrdiff_t delta, ptrdiff_t delta_bytes,
14868 int dy, int dvpos)
14870 struct glyph *glyph = row->glyphs[TEXT_AREA];
14871 struct glyph *end = glyph + row->used[TEXT_AREA];
14872 struct glyph *cursor = NULL;
14873 /* The last known character position in row. */
14874 ptrdiff_t last_pos = MATRIX_ROW_START_CHARPOS (row) + delta;
14875 int x = row->x;
14876 ptrdiff_t pt_old = PT - delta;
14877 ptrdiff_t pos_before = MATRIX_ROW_START_CHARPOS (row) + delta;
14878 ptrdiff_t pos_after = MATRIX_ROW_END_CHARPOS (row) + delta;
14879 struct glyph *glyph_before = glyph - 1, *glyph_after = end;
14880 /* A glyph beyond the edge of TEXT_AREA which we should never
14881 touch. */
14882 struct glyph *glyphs_end = end;
14883 /* True means we've found a match for cursor position, but that
14884 glyph has the avoid_cursor_p flag set. */
14885 bool match_with_avoid_cursor = false;
14886 /* True means we've seen at least one glyph that came from a
14887 display string. */
14888 bool string_seen = false;
14889 /* Largest and smallest buffer positions seen so far during scan of
14890 glyph row. */
14891 ptrdiff_t bpos_max = pos_before;
14892 ptrdiff_t bpos_min = pos_after;
14893 /* Last buffer position covered by an overlay string with an integer
14894 `cursor' property. */
14895 ptrdiff_t bpos_covered = 0;
14896 /* True means the display string on which to display the cursor
14897 comes from a text property, not from an overlay. */
14898 bool string_from_text_prop = false;
14900 /* Don't even try doing anything if called for a mode-line or
14901 header-line row, since the rest of the code isn't prepared to
14902 deal with such calamities. */
14903 eassert (!row->mode_line_p);
14904 if (row->mode_line_p)
14905 return false;
14907 /* Skip over glyphs not having an object at the start and the end of
14908 the row. These are special glyphs like truncation marks on
14909 terminal frames. */
14910 if (MATRIX_ROW_DISPLAYS_TEXT_P (row))
14912 if (!row->reversed_p)
14914 while (glyph < end
14915 && NILP (glyph->object)
14916 && glyph->charpos < 0)
14918 x += glyph->pixel_width;
14919 ++glyph;
14921 while (end > glyph
14922 && NILP ((end - 1)->object)
14923 /* CHARPOS is zero for blanks and stretch glyphs
14924 inserted by extend_face_to_end_of_line. */
14925 && (end - 1)->charpos <= 0)
14926 --end;
14927 glyph_before = glyph - 1;
14928 glyph_after = end;
14930 else
14932 struct glyph *g;
14934 /* If the glyph row is reversed, we need to process it from back
14935 to front, so swap the edge pointers. */
14936 glyphs_end = end = glyph - 1;
14937 glyph += row->used[TEXT_AREA] - 1;
14939 while (glyph > end + 1
14940 && NILP (glyph->object)
14941 && glyph->charpos < 0)
14942 --glyph;
14943 if (NILP (glyph->object) && glyph->charpos < 0)
14944 --glyph;
14945 /* By default, in reversed rows we put the cursor on the
14946 rightmost (first in the reading order) glyph. */
14947 for (x = 0, g = end + 1; g < glyph; g++)
14948 x += g->pixel_width;
14949 while (end < glyph
14950 && NILP ((end + 1)->object)
14951 && (end + 1)->charpos <= 0)
14952 ++end;
14953 glyph_before = glyph + 1;
14954 glyph_after = end;
14957 else if (row->reversed_p)
14959 /* In R2L rows that don't display text, put the cursor on the
14960 rightmost glyph. Case in point: an empty last line that is
14961 part of an R2L paragraph. */
14962 cursor = end - 1;
14963 /* Avoid placing the cursor on the last glyph of the row, where
14964 on terminal frames we hold the vertical border between
14965 adjacent windows. */
14966 if (!FRAME_WINDOW_P (WINDOW_XFRAME (w))
14967 && !WINDOW_RIGHTMOST_P (w)
14968 && cursor == row->glyphs[LAST_AREA] - 1)
14969 cursor--;
14970 x = -1; /* will be computed below, at label compute_x */
14973 /* Step 1: Try to find the glyph whose character position
14974 corresponds to point. If that's not possible, find 2 glyphs
14975 whose character positions are the closest to point, one before
14976 point, the other after it. */
14977 if (!row->reversed_p)
14978 while (/* not marched to end of glyph row */
14979 glyph < end
14980 /* glyph was not inserted by redisplay for internal purposes */
14981 && !NILP (glyph->object))
14983 if (BUFFERP (glyph->object))
14985 ptrdiff_t dpos = glyph->charpos - pt_old;
14987 if (glyph->charpos > bpos_max)
14988 bpos_max = glyph->charpos;
14989 if (glyph->charpos < bpos_min)
14990 bpos_min = glyph->charpos;
14991 if (!glyph->avoid_cursor_p)
14993 /* If we hit point, we've found the glyph on which to
14994 display the cursor. */
14995 if (dpos == 0)
14997 match_with_avoid_cursor = false;
14998 break;
15000 /* See if we've found a better approximation to
15001 POS_BEFORE or to POS_AFTER. */
15002 if (0 > dpos && dpos > pos_before - pt_old)
15004 pos_before = glyph->charpos;
15005 glyph_before = glyph;
15007 else if (0 < dpos && dpos < pos_after - pt_old)
15009 pos_after = glyph->charpos;
15010 glyph_after = glyph;
15013 else if (dpos == 0)
15014 match_with_avoid_cursor = true;
15016 else if (STRINGP (glyph->object))
15018 Lisp_Object chprop;
15019 ptrdiff_t glyph_pos = glyph->charpos;
15021 chprop = Fget_char_property (make_number (glyph_pos), Qcursor,
15022 glyph->object);
15023 if (!NILP (chprop))
15025 /* If the string came from a `display' text property,
15026 look up the buffer position of that property and
15027 use that position to update bpos_max, as if we
15028 actually saw such a position in one of the row's
15029 glyphs. This helps with supporting integer values
15030 of `cursor' property on the display string in
15031 situations where most or all of the row's buffer
15032 text is completely covered by display properties,
15033 so that no glyph with valid buffer positions is
15034 ever seen in the row. */
15035 ptrdiff_t prop_pos =
15036 string_buffer_position_lim (glyph->object, pos_before,
15037 pos_after, false);
15039 if (prop_pos >= pos_before)
15040 bpos_max = prop_pos;
15042 if (INTEGERP (chprop))
15044 bpos_covered = bpos_max + XINT (chprop);
15045 /* If the `cursor' property covers buffer positions up
15046 to and including point, we should display cursor on
15047 this glyph. Note that, if a `cursor' property on one
15048 of the string's characters has an integer value, we
15049 will break out of the loop below _before_ we get to
15050 the position match above. IOW, integer values of
15051 the `cursor' property override the "exact match for
15052 point" strategy of positioning the cursor. */
15053 /* Implementation note: bpos_max == pt_old when, e.g.,
15054 we are in an empty line, where bpos_max is set to
15055 MATRIX_ROW_START_CHARPOS, see above. */
15056 if (bpos_max <= pt_old && bpos_covered >= pt_old)
15058 cursor = glyph;
15059 break;
15063 string_seen = true;
15065 x += glyph->pixel_width;
15066 ++glyph;
15068 else if (glyph > end) /* row is reversed */
15069 while (!NILP (glyph->object))
15071 if (BUFFERP (glyph->object))
15073 ptrdiff_t dpos = glyph->charpos - pt_old;
15075 if (glyph->charpos > bpos_max)
15076 bpos_max = glyph->charpos;
15077 if (glyph->charpos < bpos_min)
15078 bpos_min = glyph->charpos;
15079 if (!glyph->avoid_cursor_p)
15081 if (dpos == 0)
15083 match_with_avoid_cursor = false;
15084 break;
15086 if (0 > dpos && dpos > pos_before - pt_old)
15088 pos_before = glyph->charpos;
15089 glyph_before = glyph;
15091 else if (0 < dpos && dpos < pos_after - pt_old)
15093 pos_after = glyph->charpos;
15094 glyph_after = glyph;
15097 else if (dpos == 0)
15098 match_with_avoid_cursor = true;
15100 else if (STRINGP (glyph->object))
15102 Lisp_Object chprop;
15103 ptrdiff_t glyph_pos = glyph->charpos;
15105 chprop = Fget_char_property (make_number (glyph_pos), Qcursor,
15106 glyph->object);
15107 if (!NILP (chprop))
15109 ptrdiff_t prop_pos =
15110 string_buffer_position_lim (glyph->object, pos_before,
15111 pos_after, false);
15113 if (prop_pos >= pos_before)
15114 bpos_max = prop_pos;
15116 if (INTEGERP (chprop))
15118 bpos_covered = bpos_max + XINT (chprop);
15119 /* If the `cursor' property covers buffer positions up
15120 to and including point, we should display cursor on
15121 this glyph. */
15122 if (bpos_max <= pt_old && bpos_covered >= pt_old)
15124 cursor = glyph;
15125 break;
15128 string_seen = true;
15130 --glyph;
15131 if (glyph == glyphs_end) /* don't dereference outside TEXT_AREA */
15133 x--; /* can't use any pixel_width */
15134 break;
15136 x -= glyph->pixel_width;
15139 /* Step 2: If we didn't find an exact match for point, we need to
15140 look for a proper place to put the cursor among glyphs between
15141 GLYPH_BEFORE and GLYPH_AFTER. */
15142 if (!((row->reversed_p ? glyph > glyphs_end : glyph < glyphs_end)
15143 && BUFFERP (glyph->object) && glyph->charpos == pt_old)
15144 && !(bpos_max <= pt_old && pt_old <= bpos_covered))
15146 /* An empty line has a single glyph whose OBJECT is nil and
15147 whose CHARPOS is the position of a newline on that line.
15148 Note that on a TTY, there are more glyphs after that, which
15149 were produced by extend_face_to_end_of_line, but their
15150 CHARPOS is zero or negative. */
15151 bool empty_line_p =
15152 ((row->reversed_p ? glyph > glyphs_end : glyph < glyphs_end)
15153 && NILP (glyph->object) && glyph->charpos > 0
15154 /* On a TTY, continued and truncated rows also have a glyph at
15155 their end whose OBJECT is nil and whose CHARPOS is
15156 positive (the continuation and truncation glyphs), but such
15157 rows are obviously not "empty". */
15158 && !(row->continued_p || row->truncated_on_right_p));
15160 if (row->ends_in_ellipsis_p && pos_after == last_pos)
15162 ptrdiff_t ellipsis_pos;
15164 /* Scan back over the ellipsis glyphs. */
15165 if (!row->reversed_p)
15167 ellipsis_pos = (glyph - 1)->charpos;
15168 while (glyph > row->glyphs[TEXT_AREA]
15169 && (glyph - 1)->charpos == ellipsis_pos)
15170 glyph--, x -= glyph->pixel_width;
15171 /* That loop always goes one position too far, including
15172 the glyph before the ellipsis. So scan forward over
15173 that one. */
15174 x += glyph->pixel_width;
15175 glyph++;
15177 else /* row is reversed */
15179 ellipsis_pos = (glyph + 1)->charpos;
15180 while (glyph < row->glyphs[TEXT_AREA] + row->used[TEXT_AREA] - 1
15181 && (glyph + 1)->charpos == ellipsis_pos)
15182 glyph++, x += glyph->pixel_width;
15183 x -= glyph->pixel_width;
15184 glyph--;
15187 else if (match_with_avoid_cursor)
15189 cursor = glyph_after;
15190 x = -1;
15192 else if (string_seen)
15194 int incr = row->reversed_p ? -1 : +1;
15196 /* Need to find the glyph that came out of a string which is
15197 present at point. That glyph is somewhere between
15198 GLYPH_BEFORE and GLYPH_AFTER, and it came from a string
15199 positioned between POS_BEFORE and POS_AFTER in the
15200 buffer. */
15201 struct glyph *start, *stop;
15202 ptrdiff_t pos = pos_before;
15204 x = -1;
15206 /* If the row ends in a newline from a display string,
15207 reordering could have moved the glyphs belonging to the
15208 string out of the [GLYPH_BEFORE..GLYPH_AFTER] range. So
15209 in this case we extend the search to the last glyph in
15210 the row that was not inserted by redisplay. */
15211 if (row->ends_in_newline_from_string_p)
15213 glyph_after = end;
15214 pos_after = MATRIX_ROW_END_CHARPOS (row) + delta;
15217 /* GLYPH_BEFORE and GLYPH_AFTER are the glyphs that
15218 correspond to POS_BEFORE and POS_AFTER, respectively. We
15219 need START and STOP in the order that corresponds to the
15220 row's direction as given by its reversed_p flag. If the
15221 directionality of characters between POS_BEFORE and
15222 POS_AFTER is the opposite of the row's base direction,
15223 these characters will have been reordered for display,
15224 and we need to reverse START and STOP. */
15225 if (!row->reversed_p)
15227 start = min (glyph_before, glyph_after);
15228 stop = max (glyph_before, glyph_after);
15230 else
15232 start = max (glyph_before, glyph_after);
15233 stop = min (glyph_before, glyph_after);
15235 for (glyph = start + incr;
15236 row->reversed_p ? glyph > stop : glyph < stop; )
15239 /* Any glyphs that come from the buffer are here because
15240 of bidi reordering. Skip them, and only pay
15241 attention to glyphs that came from some string. */
15242 if (STRINGP (glyph->object))
15244 Lisp_Object str;
15245 ptrdiff_t tem;
15246 /* If the display property covers the newline, we
15247 need to search for it one position farther. */
15248 ptrdiff_t lim = pos_after
15249 + (pos_after == MATRIX_ROW_END_CHARPOS (row) + delta);
15251 string_from_text_prop = false;
15252 str = glyph->object;
15253 tem = string_buffer_position_lim (str, pos, lim, false);
15254 if (tem == 0 /* from overlay */
15255 || pos <= tem)
15257 /* If the string from which this glyph came is
15258 found in the buffer at point, or at position
15259 that is closer to point than pos_after, then
15260 we've found the glyph we've been looking for.
15261 If it comes from an overlay (tem == 0), and
15262 it has the `cursor' property on one of its
15263 glyphs, record that glyph as a candidate for
15264 displaying the cursor. (As in the
15265 unidirectional version, we will display the
15266 cursor on the last candidate we find.) */
15267 if (tem == 0
15268 || tem == pt_old
15269 || (tem - pt_old > 0 && tem < pos_after))
15271 /* The glyphs from this string could have
15272 been reordered. Find the one with the
15273 smallest string position. Or there could
15274 be a character in the string with the
15275 `cursor' property, which means display
15276 cursor on that character's glyph. */
15277 ptrdiff_t strpos = glyph->charpos;
15279 if (tem)
15281 cursor = glyph;
15282 string_from_text_prop = true;
15284 for ( ;
15285 (row->reversed_p ? glyph > stop : glyph < stop)
15286 && EQ (glyph->object, str);
15287 glyph += incr)
15289 Lisp_Object cprop;
15290 ptrdiff_t gpos = glyph->charpos;
15292 cprop = Fget_char_property (make_number (gpos),
15293 Qcursor,
15294 glyph->object);
15295 if (!NILP (cprop))
15297 cursor = glyph;
15298 break;
15300 if (tem && glyph->charpos < strpos)
15302 strpos = glyph->charpos;
15303 cursor = glyph;
15307 if (tem == pt_old
15308 || (tem - pt_old > 0 && tem < pos_after))
15309 goto compute_x;
15311 if (tem)
15312 pos = tem + 1; /* don't find previous instances */
15314 /* This string is not what we want; skip all of the
15315 glyphs that came from it. */
15316 while ((row->reversed_p ? glyph > stop : glyph < stop)
15317 && EQ (glyph->object, str))
15318 glyph += incr;
15320 else
15321 glyph += incr;
15324 /* If we reached the end of the line, and END was from a string,
15325 the cursor is not on this line. */
15326 if (cursor == NULL
15327 && (row->reversed_p ? glyph <= end : glyph >= end)
15328 && (row->reversed_p ? end > glyphs_end : end < glyphs_end)
15329 && STRINGP (end->object)
15330 && row->continued_p)
15331 return false;
15333 /* A truncated row may not include PT among its character positions.
15334 Setting the cursor inside the scroll margin will trigger
15335 recalculation of hscroll in hscroll_window_tree. But if a
15336 display string covers point, defer to the string-handling
15337 code below to figure this out. */
15338 else if (row->truncated_on_left_p && pt_old < bpos_min)
15340 cursor = glyph_before;
15341 x = -1;
15343 else if ((row->truncated_on_right_p && pt_old > bpos_max)
15344 /* Zero-width characters produce no glyphs. */
15345 || (!empty_line_p
15346 && (row->reversed_p
15347 ? glyph_after > glyphs_end
15348 : glyph_after < glyphs_end)))
15350 cursor = glyph_after;
15351 x = -1;
15355 compute_x:
15356 if (cursor != NULL)
15357 glyph = cursor;
15358 else if (glyph == glyphs_end
15359 && pos_before == pos_after
15360 && STRINGP ((row->reversed_p
15361 ? row->glyphs[TEXT_AREA] + row->used[TEXT_AREA] - 1
15362 : row->glyphs[TEXT_AREA])->object))
15364 /* If all the glyphs of this row came from strings, put the
15365 cursor on the first glyph of the row. This avoids having the
15366 cursor outside of the text area in this very rare and hard
15367 use case. */
15368 glyph =
15369 row->reversed_p
15370 ? row->glyphs[TEXT_AREA] + row->used[TEXT_AREA] - 1
15371 : row->glyphs[TEXT_AREA];
15373 if (x < 0)
15375 struct glyph *g;
15377 /* Need to compute x that corresponds to GLYPH. */
15378 for (g = row->glyphs[TEXT_AREA], x = row->x; g < glyph; g++)
15380 if (g >= row->glyphs[TEXT_AREA] + row->used[TEXT_AREA])
15381 emacs_abort ();
15382 x += g->pixel_width;
15386 /* ROW could be part of a continued line, which, under bidi
15387 reordering, might have other rows whose start and end charpos
15388 occlude point. Only set w->cursor if we found a better
15389 approximation to the cursor position than we have from previously
15390 examined candidate rows belonging to the same continued line. */
15391 if (/* We already have a candidate row. */
15392 w->cursor.vpos >= 0
15393 /* That candidate is not the row we are processing. */
15394 && MATRIX_ROW (matrix, w->cursor.vpos) != row
15395 /* Make sure cursor.vpos specifies a row whose start and end
15396 charpos occlude point, and it is valid candidate for being a
15397 cursor-row. This is because some callers of this function
15398 leave cursor.vpos at the row where the cursor was displayed
15399 during the last redisplay cycle. */
15400 && MATRIX_ROW_START_CHARPOS (MATRIX_ROW (matrix, w->cursor.vpos)) <= pt_old
15401 && pt_old <= MATRIX_ROW_END_CHARPOS (MATRIX_ROW (matrix, w->cursor.vpos))
15402 && cursor_row_p (MATRIX_ROW (matrix, w->cursor.vpos)))
15404 struct glyph *g1
15405 = MATRIX_ROW_GLYPH_START (matrix, w->cursor.vpos) + w->cursor.hpos;
15407 /* Don't consider glyphs that are outside TEXT_AREA. */
15408 if (!(row->reversed_p ? glyph > glyphs_end : glyph < glyphs_end))
15409 return false;
15410 /* Keep the candidate whose buffer position is the closest to
15411 point or has the `cursor' property. */
15412 if (/* Previous candidate is a glyph in TEXT_AREA of that row. */
15413 w->cursor.hpos >= 0
15414 && w->cursor.hpos < MATRIX_ROW_USED (matrix, w->cursor.vpos)
15415 && ((BUFFERP (g1->object)
15416 && (g1->charpos == pt_old /* An exact match always wins. */
15417 || (BUFFERP (glyph->object)
15418 && eabs (g1->charpos - pt_old)
15419 < eabs (glyph->charpos - pt_old))))
15420 /* Previous candidate is a glyph from a string that has
15421 a non-nil `cursor' property. */
15422 || (STRINGP (g1->object)
15423 && (!NILP (Fget_char_property (make_number (g1->charpos),
15424 Qcursor, g1->object))
15425 /* Previous candidate is from the same display
15426 string as this one, and the display string
15427 came from a text property. */
15428 || (EQ (g1->object, glyph->object)
15429 && string_from_text_prop)
15430 /* this candidate is from newline and its
15431 position is not an exact match */
15432 || (NILP (glyph->object)
15433 && glyph->charpos != pt_old)))))
15434 return false;
15435 /* If this candidate gives an exact match, use that. */
15436 if (!((BUFFERP (glyph->object) && glyph->charpos == pt_old)
15437 /* If this candidate is a glyph created for the
15438 terminating newline of a line, and point is on that
15439 newline, it wins because it's an exact match. */
15440 || (!row->continued_p
15441 && NILP (glyph->object)
15442 && glyph->charpos == 0
15443 && pt_old == MATRIX_ROW_END_CHARPOS (row) - 1))
15444 /* Otherwise, keep the candidate that comes from a row
15445 spanning less buffer positions. This may win when one or
15446 both candidate positions are on glyphs that came from
15447 display strings, for which we cannot compare buffer
15448 positions. */
15449 && MATRIX_ROW_END_CHARPOS (MATRIX_ROW (matrix, w->cursor.vpos))
15450 - MATRIX_ROW_START_CHARPOS (MATRIX_ROW (matrix, w->cursor.vpos))
15451 < MATRIX_ROW_END_CHARPOS (row) - MATRIX_ROW_START_CHARPOS (row))
15452 return false;
15454 w->cursor.hpos = glyph - row->glyphs[TEXT_AREA];
15455 w->cursor.x = x;
15456 w->cursor.vpos = MATRIX_ROW_VPOS (row, matrix) + dvpos;
15457 w->cursor.y = row->y + dy;
15459 if (w == XWINDOW (selected_window))
15461 if (!row->continued_p
15462 && !MATRIX_ROW_CONTINUATION_LINE_P (row)
15463 && row->x == 0)
15465 this_line_buffer = XBUFFER (w->contents);
15467 CHARPOS (this_line_start_pos)
15468 = MATRIX_ROW_START_CHARPOS (row) + delta;
15469 BYTEPOS (this_line_start_pos)
15470 = MATRIX_ROW_START_BYTEPOS (row) + delta_bytes;
15472 CHARPOS (this_line_end_pos)
15473 = Z - (MATRIX_ROW_END_CHARPOS (row) + delta);
15474 BYTEPOS (this_line_end_pos)
15475 = Z_BYTE - (MATRIX_ROW_END_BYTEPOS (row) + delta_bytes);
15477 this_line_y = w->cursor.y;
15478 this_line_pixel_height = row->height;
15479 this_line_vpos = w->cursor.vpos;
15480 this_line_start_x = row->x;
15482 else
15483 CHARPOS (this_line_start_pos) = 0;
15486 return true;
15490 /* Run window scroll functions, if any, for WINDOW with new window
15491 start STARTP. Sets the window start of WINDOW to that position.
15493 We assume that the window's buffer is really current. */
15495 static struct text_pos
15496 run_window_scroll_functions (Lisp_Object window, struct text_pos startp)
15498 struct window *w = XWINDOW (window);
15499 SET_MARKER_FROM_TEXT_POS (w->start, startp);
15501 eassert (current_buffer == XBUFFER (w->contents));
15503 if (!NILP (Vwindow_scroll_functions))
15505 run_hook_with_args_2 (Qwindow_scroll_functions, window,
15506 make_number (CHARPOS (startp)));
15507 SET_TEXT_POS_FROM_MARKER (startp, w->start);
15508 /* In case the hook functions switch buffers. */
15509 set_buffer_internal (XBUFFER (w->contents));
15512 return startp;
15516 /* Make sure the line containing the cursor is fully visible.
15517 A value of true means there is nothing to be done.
15518 (Either the line is fully visible, or it cannot be made so,
15519 or we cannot tell.)
15521 If FORCE_P, return false even if partial visible cursor row
15522 is higher than window.
15524 If CURRENT_MATRIX_P, use the information from the
15525 window's current glyph matrix; otherwise use the desired glyph
15526 matrix.
15528 A value of false means the caller should do scrolling
15529 as if point had gone off the screen. */
15531 static bool
15532 cursor_row_fully_visible_p (struct window *w, bool force_p,
15533 bool current_matrix_p)
15535 struct glyph_matrix *matrix;
15536 struct glyph_row *row;
15537 int window_height;
15539 if (!make_cursor_line_fully_visible_p)
15540 return true;
15542 /* It's not always possible to find the cursor, e.g, when a window
15543 is full of overlay strings. Don't do anything in that case. */
15544 if (w->cursor.vpos < 0)
15545 return true;
15547 matrix = current_matrix_p ? w->current_matrix : w->desired_matrix;
15548 row = MATRIX_ROW (matrix, w->cursor.vpos);
15550 /* If the cursor row is not partially visible, there's nothing to do. */
15551 if (!MATRIX_ROW_PARTIALLY_VISIBLE_P (w, row))
15552 return true;
15554 /* If the row the cursor is in is taller than the window's height,
15555 it's not clear what to do, so do nothing. */
15556 window_height = window_box_height (w);
15557 if (row->height >= window_height)
15559 if (!force_p || MINI_WINDOW_P (w)
15560 || w->vscroll || w->cursor.vpos == 0)
15561 return true;
15563 return false;
15567 /* Try scrolling PT into view in window WINDOW. JUST_THIS_ONE_P
15568 means only WINDOW is redisplayed in redisplay_internal.
15569 TEMP_SCROLL_STEP has the same meaning as emacs_scroll_step, and is used
15570 in redisplay_window to bring a partially visible line into view in
15571 the case that only the cursor has moved.
15573 LAST_LINE_MISFIT should be true if we're scrolling because the
15574 last screen line's vertical height extends past the end of the screen.
15576 Value is
15578 1 if scrolling succeeded
15580 0 if scrolling didn't find point.
15582 -1 if new fonts have been loaded so that we must interrupt
15583 redisplay, adjust glyph matrices, and try again. */
15585 enum
15587 SCROLLING_SUCCESS,
15588 SCROLLING_FAILED,
15589 SCROLLING_NEED_LARGER_MATRICES
15592 /* If scroll-conservatively is more than this, never recenter.
15594 If you change this, don't forget to update the doc string of
15595 `scroll-conservatively' and the Emacs manual. */
15596 #define SCROLL_LIMIT 100
15598 static int
15599 try_scrolling (Lisp_Object window, bool just_this_one_p,
15600 ptrdiff_t arg_scroll_conservatively, ptrdiff_t scroll_step,
15601 bool temp_scroll_step, bool last_line_misfit)
15603 struct window *w = XWINDOW (window);
15604 struct text_pos pos, startp;
15605 struct it it;
15606 int this_scroll_margin, scroll_max, rc, height;
15607 int dy = 0, amount_to_scroll = 0;
15608 bool scroll_down_p = false;
15609 int extra_scroll_margin_lines = last_line_misfit;
15610 Lisp_Object aggressive;
15611 /* We will never try scrolling more than this number of lines. */
15612 int scroll_limit = SCROLL_LIMIT;
15613 int frame_line_height = default_line_pixel_height (w);
15615 #ifdef GLYPH_DEBUG
15616 debug_method_add (w, "try_scrolling");
15617 #endif
15619 SET_TEXT_POS_FROM_MARKER (startp, w->start);
15621 this_scroll_margin = window_scroll_margin (w, MARGIN_IN_PIXELS);
15623 /* Force arg_scroll_conservatively to have a reasonable value, to
15624 avoid scrolling too far away with slow move_it_* functions. Note
15625 that the user can supply scroll-conservatively equal to
15626 `most-positive-fixnum', which can be larger than INT_MAX. */
15627 if (arg_scroll_conservatively > scroll_limit)
15629 arg_scroll_conservatively = scroll_limit + 1;
15630 scroll_max = scroll_limit * frame_line_height;
15632 else if (scroll_step || arg_scroll_conservatively || temp_scroll_step)
15633 /* Compute how much we should try to scroll maximally to bring
15634 point into view. */
15635 scroll_max = (max (scroll_step,
15636 max (arg_scroll_conservatively, temp_scroll_step))
15637 * frame_line_height);
15638 else if (NUMBERP (BVAR (current_buffer, scroll_down_aggressively))
15639 || NUMBERP (BVAR (current_buffer, scroll_up_aggressively)))
15640 /* We're trying to scroll because of aggressive scrolling but no
15641 scroll_step is set. Choose an arbitrary one. */
15642 scroll_max = 10 * frame_line_height;
15643 else
15644 scroll_max = 0;
15646 too_near_end:
15648 /* Decide whether to scroll down. */
15649 if (PT > CHARPOS (startp))
15651 int scroll_margin_y;
15653 /* Compute the pixel ypos of the scroll margin, then move IT to
15654 either that ypos or PT, whichever comes first. */
15655 start_display (&it, w, startp);
15656 scroll_margin_y = it.last_visible_y - partial_line_height (&it)
15657 - this_scroll_margin
15658 - frame_line_height * extra_scroll_margin_lines;
15659 move_it_to (&it, PT, -1, scroll_margin_y - 1, -1,
15660 (MOVE_TO_POS | MOVE_TO_Y));
15662 if (PT > CHARPOS (it.current.pos))
15664 int y0 = line_bottom_y (&it);
15665 /* Compute how many pixels below window bottom to stop searching
15666 for PT. This avoids costly search for PT that is far away if
15667 the user limited scrolling by a small number of lines, but
15668 always finds PT if scroll_conservatively is set to a large
15669 number, such as most-positive-fixnum. */
15670 int slack = max (scroll_max, 10 * frame_line_height);
15671 int y_to_move = it.last_visible_y + slack;
15673 /* Compute the distance from the scroll margin to PT or to
15674 the scroll limit, whichever comes first. This should
15675 include the height of the cursor line, to make that line
15676 fully visible. */
15677 move_it_to (&it, PT, -1, y_to_move,
15678 -1, MOVE_TO_POS | MOVE_TO_Y);
15679 dy = line_bottom_y (&it) - y0;
15681 if (dy > scroll_max)
15682 return SCROLLING_FAILED;
15684 if (dy > 0)
15685 scroll_down_p = true;
15687 else if (PT == IT_CHARPOS (it)
15688 && IT_CHARPOS (it) < ZV
15689 && it.method == GET_FROM_STRING
15690 && arg_scroll_conservatively > scroll_limit
15691 && it.current_x == 0)
15693 enum move_it_result skip;
15694 int y1 = it.current_y;
15695 int vpos;
15697 /* A before-string that includes newlines and is displayed
15698 on the last visible screen line could fail us under
15699 scroll-conservatively > 100, because we will be unable to
15700 position the cursor on that last visible line. Try to
15701 recover by finding the first screen line that has some
15702 glyphs coming from the buffer text. */
15703 do {
15704 skip = move_it_in_display_line_to (&it, ZV, -1, MOVE_TO_POS);
15705 if (skip != MOVE_NEWLINE_OR_CR
15706 || IT_CHARPOS (it) != PT
15707 || it.method == GET_FROM_BUFFER)
15708 break;
15709 vpos = it.vpos;
15710 move_it_to (&it, -1, -1, -1, vpos + 1, MOVE_TO_VPOS);
15711 } while (it.vpos > vpos);
15713 dy = it.current_y - y1;
15715 if (dy > scroll_max)
15716 return SCROLLING_FAILED;
15718 if (dy > 0)
15719 scroll_down_p = true;
15723 if (scroll_down_p)
15725 /* Point is in or below the bottom scroll margin, so move the
15726 window start down. If scrolling conservatively, move it just
15727 enough down to make point visible. If scroll_step is set,
15728 move it down by scroll_step. */
15729 if (arg_scroll_conservatively)
15730 amount_to_scroll
15731 = min (max (dy, frame_line_height),
15732 frame_line_height * arg_scroll_conservatively);
15733 else if (scroll_step || temp_scroll_step)
15734 amount_to_scroll = scroll_max;
15735 else
15737 aggressive = BVAR (current_buffer, scroll_up_aggressively);
15738 height = WINDOW_BOX_TEXT_HEIGHT (w);
15739 if (NUMBERP (aggressive))
15741 double float_amount = XFLOATINT (aggressive) * height;
15742 int aggressive_scroll = float_amount;
15743 if (aggressive_scroll == 0 && float_amount > 0)
15744 aggressive_scroll = 1;
15745 /* Don't let point enter the scroll margin near top of
15746 the window. This could happen if the value of
15747 scroll_up_aggressively is too large and there are
15748 non-zero margins, because scroll_up_aggressively
15749 means put point that fraction of window height
15750 _from_the_bottom_margin_. */
15751 if (aggressive_scroll + 2 * this_scroll_margin > height)
15752 aggressive_scroll = height - 2 * this_scroll_margin;
15753 amount_to_scroll = dy + aggressive_scroll;
15757 if (amount_to_scroll <= 0)
15758 return SCROLLING_FAILED;
15760 start_display (&it, w, startp);
15761 if (arg_scroll_conservatively <= scroll_limit)
15762 move_it_vertically (&it, amount_to_scroll);
15763 else
15765 /* Extra precision for users who set scroll-conservatively
15766 to a large number: make sure the amount we scroll
15767 the window start is never less than amount_to_scroll,
15768 which was computed as distance from window bottom to
15769 point. This matters when lines at window top and lines
15770 below window bottom have different height. */
15771 struct it it1;
15772 void *it1data = NULL;
15773 /* We use a temporary it1 because line_bottom_y can modify
15774 its argument, if it moves one line down; see there. */
15775 int start_y;
15777 SAVE_IT (it1, it, it1data);
15778 start_y = line_bottom_y (&it1);
15779 do {
15780 RESTORE_IT (&it, &it, it1data);
15781 move_it_by_lines (&it, 1);
15782 SAVE_IT (it1, it, it1data);
15783 } while (IT_CHARPOS (it) < ZV
15784 && line_bottom_y (&it1) - start_y < amount_to_scroll);
15785 bidi_unshelve_cache (it1data, true);
15788 /* If STARTP is unchanged, move it down another screen line. */
15789 if (IT_CHARPOS (it) == CHARPOS (startp))
15790 move_it_by_lines (&it, 1);
15791 startp = it.current.pos;
15793 else
15795 struct text_pos scroll_margin_pos = startp;
15796 int y_offset = 0;
15798 /* See if point is inside the scroll margin at the top of the
15799 window. */
15800 if (this_scroll_margin)
15802 int y_start;
15804 start_display (&it, w, startp);
15805 y_start = it.current_y;
15806 move_it_vertically (&it, this_scroll_margin);
15807 scroll_margin_pos = it.current.pos;
15808 /* If we didn't move enough before hitting ZV, request
15809 additional amount of scroll, to move point out of the
15810 scroll margin. */
15811 if (IT_CHARPOS (it) == ZV
15812 && it.current_y - y_start < this_scroll_margin)
15813 y_offset = this_scroll_margin - (it.current_y - y_start);
15816 if (PT < CHARPOS (scroll_margin_pos))
15818 /* Point is in the scroll margin at the top of the window or
15819 above what is displayed in the window. */
15820 int y0, y_to_move;
15822 /* Compute the vertical distance from PT to the scroll
15823 margin position. Move as far as scroll_max allows, or
15824 one screenful, or 10 screen lines, whichever is largest.
15825 Give up if distance is greater than scroll_max or if we
15826 didn't reach the scroll margin position. */
15827 SET_TEXT_POS (pos, PT, PT_BYTE);
15828 start_display (&it, w, pos);
15829 y0 = it.current_y;
15830 y_to_move = max (it.last_visible_y,
15831 max (scroll_max, 10 * frame_line_height));
15832 move_it_to (&it, CHARPOS (scroll_margin_pos), 0,
15833 y_to_move, -1,
15834 MOVE_TO_POS | MOVE_TO_X | MOVE_TO_Y);
15835 dy = it.current_y - y0;
15836 if (dy > scroll_max
15837 || IT_CHARPOS (it) < CHARPOS (scroll_margin_pos))
15838 return SCROLLING_FAILED;
15840 /* Additional scroll for when ZV was too close to point. */
15841 dy += y_offset;
15843 /* Compute new window start. */
15844 start_display (&it, w, startp);
15846 if (arg_scroll_conservatively)
15847 amount_to_scroll = max (dy, frame_line_height
15848 * max (scroll_step, temp_scroll_step));
15849 else if (scroll_step || temp_scroll_step)
15850 amount_to_scroll = scroll_max;
15851 else
15853 aggressive = BVAR (current_buffer, scroll_down_aggressively);
15854 height = WINDOW_BOX_TEXT_HEIGHT (w);
15855 if (NUMBERP (aggressive))
15857 double float_amount = XFLOATINT (aggressive) * height;
15858 int aggressive_scroll = float_amount;
15859 if (aggressive_scroll == 0 && float_amount > 0)
15860 aggressive_scroll = 1;
15861 /* Don't let point enter the scroll margin near
15862 bottom of the window, if the value of
15863 scroll_down_aggressively happens to be too
15864 large. */
15865 if (aggressive_scroll + 2 * this_scroll_margin > height)
15866 aggressive_scroll = height - 2 * this_scroll_margin;
15867 amount_to_scroll = dy + aggressive_scroll;
15871 if (amount_to_scroll <= 0)
15872 return SCROLLING_FAILED;
15874 move_it_vertically_backward (&it, amount_to_scroll);
15875 startp = it.current.pos;
15879 /* Run window scroll functions. */
15880 startp = run_window_scroll_functions (window, startp);
15882 /* Display the window. Give up if new fonts are loaded, or if point
15883 doesn't appear. */
15884 if (!try_window (window, startp, 0))
15885 rc = SCROLLING_NEED_LARGER_MATRICES;
15886 else if (w->cursor.vpos < 0)
15888 clear_glyph_matrix (w->desired_matrix);
15889 rc = SCROLLING_FAILED;
15891 else
15893 /* Maybe forget recorded base line for line number display. */
15894 if (!just_this_one_p
15895 || current_buffer->clip_changed
15896 || BEG_UNCHANGED < CHARPOS (startp))
15897 w->base_line_number = 0;
15899 /* If cursor ends up on a partially visible line,
15900 treat that as being off the bottom of the screen. */
15901 if (! cursor_row_fully_visible_p (w, extra_scroll_margin_lines <= 1,
15902 false)
15903 /* It's possible that the cursor is on the first line of the
15904 buffer, which is partially obscured due to a vscroll
15905 (Bug#7537). In that case, avoid looping forever. */
15906 && extra_scroll_margin_lines < w->desired_matrix->nrows - 1)
15908 clear_glyph_matrix (w->desired_matrix);
15909 ++extra_scroll_margin_lines;
15910 goto too_near_end;
15912 rc = SCROLLING_SUCCESS;
15915 return rc;
15919 /* Compute a suitable window start for window W if display of W starts
15920 on a continuation line. Value is true if a new window start
15921 was computed.
15923 The new window start will be computed, based on W's width, starting
15924 from the start of the continued line. It is the start of the
15925 screen line with the minimum distance from the old start W->start,
15926 which is still before point (otherwise point will definitely not
15927 be visible in the window). */
15929 static bool
15930 compute_window_start_on_continuation_line (struct window *w)
15932 struct text_pos pos, start_pos, pos_before_pt;
15933 bool window_start_changed_p = false;
15935 SET_TEXT_POS_FROM_MARKER (start_pos, w->start);
15937 /* If window start is on a continuation line... Window start may be
15938 < BEGV in case there's invisible text at the start of the
15939 buffer (M-x rmail, for example). */
15940 if (CHARPOS (start_pos) > BEGV
15941 && FETCH_BYTE (BYTEPOS (start_pos) - 1) != '\n')
15943 struct it it;
15944 struct glyph_row *row;
15946 /* Handle the case that the window start is out of range. */
15947 if (CHARPOS (start_pos) < BEGV)
15948 SET_TEXT_POS (start_pos, BEGV, BEGV_BYTE);
15949 else if (CHARPOS (start_pos) > ZV)
15950 SET_TEXT_POS (start_pos, ZV, ZV_BYTE);
15952 /* Find the start of the continued line. This should be fast
15953 because find_newline is fast (newline cache). */
15954 row = w->desired_matrix->rows + window_wants_header_line (w);
15955 init_iterator (&it, w, CHARPOS (start_pos), BYTEPOS (start_pos),
15956 row, DEFAULT_FACE_ID);
15957 reseat_at_previous_visible_line_start (&it);
15959 /* If the line start is "too far" away from the window start,
15960 say it takes too much time to compute a new window start.
15961 Also, give up if the line start is after point, as in that
15962 case point will not be visible with any window start we
15963 compute. */
15964 if (IT_CHARPOS (it) <= PT
15965 || (CHARPOS (start_pos) - IT_CHARPOS (it)
15966 /* PXW: Do we need upper bounds here? */
15967 < WINDOW_TOTAL_LINES (w) * WINDOW_TOTAL_COLS (w)))
15969 int min_distance, distance;
15971 /* Move forward by display lines to find the new window
15972 start. If window width was enlarged, the new start can
15973 be expected to be > the old start. If window width was
15974 decreased, the new window start will be < the old start.
15975 So, we're looking for the display line start with the
15976 minimum distance from the old window start. */
15977 pos_before_pt = pos = it.current.pos;
15978 min_distance = DISP_INFINITY;
15979 while ((distance = eabs (CHARPOS (start_pos) - IT_CHARPOS (it))),
15980 distance < min_distance)
15982 min_distance = distance;
15983 if (CHARPOS (pos) <= PT)
15984 pos_before_pt = pos;
15985 pos = it.current.pos;
15986 if (it.line_wrap == WORD_WRAP)
15988 /* Under WORD_WRAP, move_it_by_lines is likely to
15989 overshoot and stop not at the first, but the
15990 second character from the left margin. So in
15991 that case, we need a more tight control on the X
15992 coordinate of the iterator than move_it_by_lines
15993 promises in its contract. The method is to first
15994 go to the last (rightmost) visible character of a
15995 line, then move to the leftmost character on the
15996 next line in a separate call. */
15997 move_it_to (&it, ZV, it.last_visible_x, it.current_y, -1,
15998 MOVE_TO_POS | MOVE_TO_X | MOVE_TO_Y);
15999 move_it_to (&it, ZV, 0,
16000 it.current_y + it.max_ascent + it.max_descent, -1,
16001 MOVE_TO_POS | MOVE_TO_X | MOVE_TO_Y);
16003 else
16004 move_it_by_lines (&it, 1);
16007 /* It makes very little sense to make the new window start
16008 after point, as point won't be visible. If that's what
16009 the loop above finds, fall back on the candidate before
16010 or at point that is closest to the old window start. */
16011 if (CHARPOS (pos) > PT)
16012 pos = pos_before_pt;
16014 /* Set the window start there. */
16015 SET_MARKER_FROM_TEXT_POS (w->start, pos);
16016 window_start_changed_p = true;
16020 return window_start_changed_p;
16024 /* Try cursor movement in case text has not changed in window WINDOW,
16025 with window start STARTP. Value is
16027 CURSOR_MOVEMENT_SUCCESS if successful
16029 CURSOR_MOVEMENT_CANNOT_BE_USED if this method cannot be used
16031 CURSOR_MOVEMENT_MUST_SCROLL if we know we have to scroll the
16032 display. *SCROLL_STEP is set to true, under certain circumstances, if
16033 we want to scroll as if scroll-step were set to 1. See the code.
16035 CURSOR_MOVEMENT_NEED_LARGER_MATRICES if we need larger matrices, in
16036 which case we have to abort this redisplay, and adjust matrices
16037 first. */
16039 enum
16041 CURSOR_MOVEMENT_SUCCESS,
16042 CURSOR_MOVEMENT_CANNOT_BE_USED,
16043 CURSOR_MOVEMENT_MUST_SCROLL,
16044 CURSOR_MOVEMENT_NEED_LARGER_MATRICES
16047 static int
16048 try_cursor_movement (Lisp_Object window, struct text_pos startp,
16049 bool *scroll_step)
16051 struct window *w = XWINDOW (window);
16052 struct frame *f = XFRAME (w->frame);
16053 int rc = CURSOR_MOVEMENT_CANNOT_BE_USED;
16055 #ifdef GLYPH_DEBUG
16056 if (inhibit_try_cursor_movement)
16057 return rc;
16058 #endif
16060 /* Previously, there was a check for Lisp integer in the
16061 if-statement below. Now, this field is converted to
16062 ptrdiff_t, thus zero means invalid position in a buffer. */
16063 eassert (w->last_point > 0);
16064 /* Likewise there was a check whether window_end_vpos is nil or larger
16065 than the window. Now window_end_vpos is int and so never nil, but
16066 let's leave eassert to check whether it fits in the window. */
16067 eassert (!w->window_end_valid
16068 || w->window_end_vpos < w->current_matrix->nrows);
16070 /* Handle case where text has not changed, only point, and it has
16071 not moved off the frame. */
16072 if (/* Point may be in this window. */
16073 PT >= CHARPOS (startp)
16074 /* Selective display hasn't changed. */
16075 && !current_buffer->clip_changed
16076 /* Function force-mode-line-update is used to force a thorough
16077 redisplay. It sets either windows_or_buffers_changed or
16078 update_mode_lines. So don't take a shortcut here for these
16079 cases. */
16080 && !update_mode_lines
16081 && !windows_or_buffers_changed
16082 && !f->cursor_type_changed
16083 && NILP (Vshow_trailing_whitespace)
16084 /* When display-line-numbers is in relative mode, moving point
16085 requires to redraw the entire window. */
16086 && !EQ (Vdisplay_line_numbers, Qrelative)
16087 && !EQ (Vdisplay_line_numbers, Qvisual)
16088 /* When the current line number should be displayed in a
16089 distinct face, moving point cannot be handled in optimized
16090 way as below. */
16091 && !(!NILP (Vdisplay_line_numbers)
16092 && NILP (Finternal_lisp_face_equal_p (Qline_number,
16093 Qline_number_current_line,
16094 w->frame)))
16095 /* This code is not used for mini-buffer for the sake of the case
16096 of redisplaying to replace an echo area message; since in
16097 that case the mini-buffer contents per se are usually
16098 unchanged. This code is of no real use in the mini-buffer
16099 since the handling of this_line_start_pos, etc., in redisplay
16100 handles the same cases. */
16101 && !EQ (window, minibuf_window)
16102 /* When overlay arrow is shown in current buffer, point movement
16103 is no longer "simple", as it typically causes the overlay
16104 arrow to move as well. */
16105 && !overlay_arrow_in_current_buffer_p ())
16107 int this_scroll_margin, top_scroll_margin;
16108 struct glyph_row *row = NULL;
16110 #ifdef GLYPH_DEBUG
16111 debug_method_add (w, "cursor movement");
16112 #endif
16114 this_scroll_margin = window_scroll_margin (w, MARGIN_IN_PIXELS);
16116 top_scroll_margin = this_scroll_margin;
16117 if (window_wants_header_line (w))
16118 top_scroll_margin += CURRENT_HEADER_LINE_HEIGHT (w);
16120 /* Start with the row the cursor was displayed during the last
16121 not paused redisplay. Give up if that row is not valid. */
16122 if (w->last_cursor_vpos < 0
16123 || w->last_cursor_vpos >= w->current_matrix->nrows)
16124 rc = CURSOR_MOVEMENT_MUST_SCROLL;
16125 else
16127 row = MATRIX_ROW (w->current_matrix, w->last_cursor_vpos);
16128 if (row->mode_line_p)
16129 ++row;
16130 if (!row->enabled_p)
16131 rc = CURSOR_MOVEMENT_MUST_SCROLL;
16134 if (rc == CURSOR_MOVEMENT_CANNOT_BE_USED)
16136 bool scroll_p = false, must_scroll = false;
16137 int last_y = window_text_bottom_y (w) - this_scroll_margin;
16139 if (PT > w->last_point)
16141 /* Point has moved forward. */
16142 while (MATRIX_ROW_END_CHARPOS (row) < PT
16143 && MATRIX_ROW_BOTTOM_Y (row) < last_y)
16145 eassert (row->enabled_p);
16146 ++row;
16149 /* If the end position of a row equals the start
16150 position of the next row, and PT is at that position,
16151 we would rather display cursor in the next line. */
16152 while (MATRIX_ROW_BOTTOM_Y (row) < last_y
16153 && MATRIX_ROW_END_CHARPOS (row) == PT
16154 && row < MATRIX_MODE_LINE_ROW (w->current_matrix)
16155 && MATRIX_ROW_START_CHARPOS (row+1) == PT
16156 && !cursor_row_p (row))
16157 ++row;
16159 /* If within the scroll margin, scroll. Note that
16160 MATRIX_ROW_BOTTOM_Y gives the pixel position at which
16161 the next line would be drawn, and that
16162 this_scroll_margin can be zero. */
16163 if (MATRIX_ROW_BOTTOM_Y (row) > last_y
16164 || PT > MATRIX_ROW_END_CHARPOS (row)
16165 /* Line is completely visible last line in window
16166 and PT is to be set in the next line. */
16167 || (MATRIX_ROW_BOTTOM_Y (row) == last_y
16168 && PT == MATRIX_ROW_END_CHARPOS (row)
16169 && !row->ends_at_zv_p
16170 && !MATRIX_ROW_ENDS_IN_MIDDLE_OF_CHAR_P (row)))
16171 scroll_p = true;
16173 else if (PT < w->last_point)
16175 /* Cursor has to be moved backward. Note that PT >=
16176 CHARPOS (startp) because of the outer if-statement. */
16177 while (!row->mode_line_p
16178 && (MATRIX_ROW_START_CHARPOS (row) > PT
16179 || (MATRIX_ROW_START_CHARPOS (row) == PT
16180 && (MATRIX_ROW_STARTS_IN_MIDDLE_OF_CHAR_P (row)
16181 || (/* STARTS_IN_MIDDLE_OF_STRING_P (row) */
16182 row > w->current_matrix->rows
16183 && (row-1)->ends_in_newline_from_string_p))))
16184 && (row->y > top_scroll_margin
16185 || CHARPOS (startp) == BEGV))
16187 eassert (row->enabled_p);
16188 --row;
16191 /* Consider the following case: Window starts at BEGV,
16192 there is invisible, intangible text at BEGV, so that
16193 display starts at some point START > BEGV. It can
16194 happen that we are called with PT somewhere between
16195 BEGV and START. Try to handle that case. */
16196 if (row < w->current_matrix->rows
16197 || row->mode_line_p)
16199 row = w->current_matrix->rows;
16200 if (row->mode_line_p)
16201 ++row;
16204 /* Due to newlines in overlay strings, we may have to
16205 skip forward over overlay strings. */
16206 while (MATRIX_ROW_BOTTOM_Y (row) < last_y
16207 && MATRIX_ROW_END_CHARPOS (row) == PT
16208 && !cursor_row_p (row))
16209 ++row;
16211 /* If within the scroll margin, scroll. */
16212 if (row->y < top_scroll_margin
16213 && CHARPOS (startp) != BEGV)
16214 scroll_p = true;
16216 else
16218 /* Cursor did not move. So don't scroll even if cursor line
16219 is partially visible, as it was so before. */
16220 rc = CURSOR_MOVEMENT_SUCCESS;
16223 if (PT < MATRIX_ROW_START_CHARPOS (row)
16224 || PT > MATRIX_ROW_END_CHARPOS (row))
16226 /* if PT is not in the glyph row, give up. */
16227 rc = CURSOR_MOVEMENT_MUST_SCROLL;
16228 must_scroll = true;
16230 else if (rc != CURSOR_MOVEMENT_SUCCESS
16231 && !NILP (BVAR (XBUFFER (w->contents), bidi_display_reordering)))
16233 struct glyph_row *row1;
16235 /* If rows are bidi-reordered and point moved, back up
16236 until we find a row that does not belong to a
16237 continuation line. This is because we must consider
16238 all rows of a continued line as candidates for the
16239 new cursor positioning, since row start and end
16240 positions change non-linearly with vertical position
16241 in such rows. */
16242 /* FIXME: Revisit this when glyph ``spilling'' in
16243 continuation lines' rows is implemented for
16244 bidi-reordered rows. */
16245 for (row1 = MATRIX_FIRST_TEXT_ROW (w->current_matrix);
16246 MATRIX_ROW_CONTINUATION_LINE_P (row);
16247 --row)
16249 /* If we hit the beginning of the displayed portion
16250 without finding the first row of a continued
16251 line, give up. */
16252 if (row <= row1)
16254 rc = CURSOR_MOVEMENT_MUST_SCROLL;
16255 break;
16257 eassert (row->enabled_p);
16260 if (must_scroll)
16262 else if (rc != CURSOR_MOVEMENT_SUCCESS
16263 && MATRIX_ROW_PARTIALLY_VISIBLE_P (w, row)
16264 /* Make sure this isn't a header line by any chance, since
16265 then MATRIX_ROW_PARTIALLY_VISIBLE_P might yield true. */
16266 && !row->mode_line_p
16267 && make_cursor_line_fully_visible_p)
16269 if (PT == MATRIX_ROW_END_CHARPOS (row)
16270 && !row->ends_at_zv_p
16271 && !MATRIX_ROW_ENDS_IN_MIDDLE_OF_CHAR_P (row))
16272 rc = CURSOR_MOVEMENT_MUST_SCROLL;
16273 else if (row->height > window_box_height (w))
16275 /* If we end up in a partially visible line, let's
16276 make it fully visible, except when it's taller
16277 than the window, in which case we can't do much
16278 about it. */
16279 *scroll_step = true;
16280 rc = CURSOR_MOVEMENT_MUST_SCROLL;
16282 else
16284 set_cursor_from_row (w, row, w->current_matrix, 0, 0, 0, 0);
16285 if (!cursor_row_fully_visible_p (w, false, true))
16286 rc = CURSOR_MOVEMENT_MUST_SCROLL;
16287 else
16288 rc = CURSOR_MOVEMENT_SUCCESS;
16291 else if (scroll_p)
16292 rc = CURSOR_MOVEMENT_MUST_SCROLL;
16293 else if (rc != CURSOR_MOVEMENT_SUCCESS
16294 && !NILP (BVAR (XBUFFER (w->contents), bidi_display_reordering)))
16296 /* With bidi-reordered rows, there could be more than
16297 one candidate row whose start and end positions
16298 occlude point. We need to let set_cursor_from_row
16299 find the best candidate. */
16300 /* FIXME: Revisit this when glyph ``spilling'' in
16301 continuation lines' rows is implemented for
16302 bidi-reordered rows. */
16303 bool rv = false;
16307 bool at_zv_p = false, exact_match_p = false;
16309 if (MATRIX_ROW_START_CHARPOS (row) <= PT
16310 && PT <= MATRIX_ROW_END_CHARPOS (row)
16311 && cursor_row_p (row))
16312 rv |= set_cursor_from_row (w, row, w->current_matrix,
16313 0, 0, 0, 0);
16314 /* As soon as we've found the exact match for point,
16315 or the first suitable row whose ends_at_zv_p flag
16316 is set, we are done. */
16317 if (rv)
16319 at_zv_p = MATRIX_ROW (w->current_matrix,
16320 w->cursor.vpos)->ends_at_zv_p;
16321 if (!at_zv_p
16322 && w->cursor.hpos >= 0
16323 && w->cursor.hpos < MATRIX_ROW_USED (w->current_matrix,
16324 w->cursor.vpos))
16326 struct glyph_row *candidate =
16327 MATRIX_ROW (w->current_matrix, w->cursor.vpos);
16328 struct glyph *g =
16329 candidate->glyphs[TEXT_AREA] + w->cursor.hpos;
16330 ptrdiff_t endpos = MATRIX_ROW_END_CHARPOS (candidate);
16332 exact_match_p =
16333 (BUFFERP (g->object) && g->charpos == PT)
16334 || (NILP (g->object)
16335 && (g->charpos == PT
16336 || (g->charpos == 0 && endpos - 1 == PT)));
16338 if (at_zv_p || exact_match_p)
16340 rc = CURSOR_MOVEMENT_SUCCESS;
16341 break;
16344 if (MATRIX_ROW_BOTTOM_Y (row) == last_y)
16345 break;
16346 ++row;
16348 while (((MATRIX_ROW_CONTINUATION_LINE_P (row)
16349 || row->continued_p)
16350 && MATRIX_ROW_BOTTOM_Y (row) <= last_y)
16351 || (MATRIX_ROW_START_CHARPOS (row) == PT
16352 && MATRIX_ROW_BOTTOM_Y (row) < last_y));
16353 /* If we didn't find any candidate rows, or exited the
16354 loop before all the candidates were examined, signal
16355 to the caller that this method failed. */
16356 if (rc != CURSOR_MOVEMENT_SUCCESS
16357 && !(rv
16358 && !MATRIX_ROW_CONTINUATION_LINE_P (row)
16359 && !row->continued_p))
16360 rc = CURSOR_MOVEMENT_MUST_SCROLL;
16361 else if (rv)
16362 rc = CURSOR_MOVEMENT_SUCCESS;
16364 else
16368 if (set_cursor_from_row (w, row, w->current_matrix, 0, 0, 0, 0))
16370 rc = CURSOR_MOVEMENT_SUCCESS;
16371 break;
16373 ++row;
16375 while (MATRIX_ROW_BOTTOM_Y (row) < last_y
16376 && MATRIX_ROW_START_CHARPOS (row) == PT
16377 && cursor_row_p (row));
16382 return rc;
16386 void
16387 set_vertical_scroll_bar (struct window *w)
16389 ptrdiff_t start, end, whole;
16391 /* Calculate the start and end positions for the current window.
16392 At some point, it would be nice to choose between scrollbars
16393 which reflect the whole buffer size, with special markers
16394 indicating narrowing, and scrollbars which reflect only the
16395 visible region.
16397 Note that mini-buffers sometimes aren't displaying any text. */
16398 if (!MINI_WINDOW_P (w)
16399 || (w == XWINDOW (minibuf_window)
16400 && NILP (echo_area_buffer[0])))
16402 struct buffer *buf = XBUFFER (w->contents);
16403 whole = BUF_ZV (buf) - BUF_BEGV (buf);
16404 start = marker_position (w->start) - BUF_BEGV (buf);
16405 /* I don't think this is guaranteed to be right. For the
16406 moment, we'll pretend it is. */
16407 end = BUF_Z (buf) - w->window_end_pos - BUF_BEGV (buf);
16409 if (end < start)
16410 end = start;
16411 if (whole < (end - start))
16412 whole = end - start;
16414 else
16415 start = end = whole = 0;
16417 /* Indicate what this scroll bar ought to be displaying now. */
16418 if (FRAME_TERMINAL (XFRAME (w->frame))->set_vertical_scroll_bar_hook)
16419 (*FRAME_TERMINAL (XFRAME (w->frame))->set_vertical_scroll_bar_hook)
16420 (w, end - start, whole, start);
16424 void
16425 set_horizontal_scroll_bar (struct window *w)
16427 int start, end, whole, portion;
16429 if (!MINI_WINDOW_P (w)
16430 || (w == XWINDOW (minibuf_window)
16431 && NILP (echo_area_buffer[0])))
16433 struct buffer *b = XBUFFER (w->contents);
16434 struct buffer *old_buffer = NULL;
16435 struct it it;
16436 struct text_pos startp;
16438 if (b != current_buffer)
16440 old_buffer = current_buffer;
16441 set_buffer_internal (b);
16444 SET_TEXT_POS_FROM_MARKER (startp, w->start);
16445 start_display (&it, w, startp);
16446 it.last_visible_x = INT_MAX;
16447 whole = move_it_to (&it, -1, INT_MAX, window_box_height (w), -1,
16448 MOVE_TO_X | MOVE_TO_Y);
16449 /* whole = move_it_to (&it, w->window_end_pos, INT_MAX,
16450 window_box_height (w), -1,
16451 MOVE_TO_POS | MOVE_TO_X | MOVE_TO_Y); */
16453 start = w->hscroll * FRAME_COLUMN_WIDTH (WINDOW_XFRAME (w));
16454 end = start + window_box_width (w, TEXT_AREA);
16455 portion = end - start;
16456 /* After enlarging a horizontally scrolled window such that it
16457 gets at least as wide as the text it contains, make sure that
16458 the thumb doesn't fill the entire scroll bar so we can still
16459 drag it back to see the entire text. */
16460 whole = max (whole, end);
16462 if (it.bidi_p)
16464 Lisp_Object pdir;
16466 pdir = Fcurrent_bidi_paragraph_direction (Qnil);
16467 if (EQ (pdir, Qright_to_left))
16469 start = whole - end;
16470 end = start + portion;
16474 if (old_buffer)
16475 set_buffer_internal (old_buffer);
16477 else
16478 start = end = whole = portion = 0;
16480 w->hscroll_whole = whole;
16482 /* Indicate what this scroll bar ought to be displaying now. */
16483 if (FRAME_TERMINAL (XFRAME (w->frame))->set_horizontal_scroll_bar_hook)
16484 (*FRAME_TERMINAL (XFRAME (w->frame))->set_horizontal_scroll_bar_hook)
16485 (w, portion, whole, start);
16489 /* Redisplay leaf window WINDOW. JUST_THIS_ONE_P means only
16490 selected_window is redisplayed.
16492 We can return without actually redisplaying the window if fonts has been
16493 changed on window's frame. In that case, redisplay_internal will retry.
16495 As one of the important parts of redisplaying a window, we need to
16496 decide whether the previous window-start position (stored in the
16497 window's w->start marker position) is still valid, and if it isn't,
16498 recompute it. Some details about that:
16500 . The previous window-start could be in a continuation line, in
16501 which case we need to recompute it when the window width
16502 changes. See compute_window_start_on_continuation_line and its
16503 call below.
16505 . The text that changed since last redisplay could include the
16506 previous window-start position. In that case, we try to salvage
16507 what we can from the current glyph matrix by calling
16508 try_scrolling, which see.
16510 . Some Emacs command could force us to use a specific window-start
16511 position by setting the window's force_start flag, or gently
16512 propose doing that by setting the window's optional_new_start
16513 flag. In these cases, we try using the specified start point if
16514 that succeeds (i.e. the window desired matrix is successfully
16515 recomputed, and point location is within the window). In case
16516 of optional_new_start, we first check if the specified start
16517 position is feasible, i.e. if it will allow point to be
16518 displayed in the window. If using the specified start point
16519 fails, e.g., if new fonts are needed to be loaded, we abort the
16520 redisplay cycle and leave it up to the next cycle to figure out
16521 things.
16523 . Note that the window's force_start flag is sometimes set by
16524 redisplay itself, when it decides that the previous window start
16525 point is fine and should be kept. Search for "goto force_start"
16526 below to see the details. Like the values of window-start
16527 specified outside of redisplay, these internally-deduced values
16528 are tested for feasibility, and ignored if found to be
16529 unfeasible.
16531 . Note that the function try_window, used to completely redisplay
16532 a window, accepts the window's start point as its argument.
16533 This is used several times in the redisplay code to control
16534 where the window start will be, according to user options such
16535 as scroll-conservatively, and also to ensure the screen line
16536 showing point will be fully (as opposed to partially) visible on
16537 display. */
16539 static void
16540 redisplay_window (Lisp_Object window, bool just_this_one_p)
16542 struct window *w = XWINDOW (window);
16543 struct frame *f = XFRAME (w->frame);
16544 struct buffer *buffer = XBUFFER (w->contents);
16545 struct buffer *old = current_buffer;
16546 struct text_pos lpoint, opoint, startp;
16547 bool update_mode_line;
16548 int tem;
16549 struct it it;
16550 /* Record it now because it's overwritten. */
16551 bool current_matrix_up_to_date_p = false;
16552 bool used_current_matrix_p = false;
16553 /* This is less strict than current_matrix_up_to_date_p.
16554 It indicates that the buffer contents and narrowing are unchanged. */
16555 bool buffer_unchanged_p = false;
16556 bool temp_scroll_step = false;
16557 ptrdiff_t count = SPECPDL_INDEX ();
16558 int rc;
16559 int centering_position = -1;
16560 bool last_line_misfit = false;
16561 ptrdiff_t beg_unchanged, end_unchanged;
16562 int frame_line_height, margin;
16563 bool use_desired_matrix;
16564 void *itdata = NULL;
16566 SET_TEXT_POS (lpoint, PT, PT_BYTE);
16567 opoint = lpoint;
16569 #ifdef GLYPH_DEBUG
16570 *w->desired_matrix->method = 0;
16571 #endif
16573 if (!just_this_one_p
16574 && REDISPLAY_SOME_P ()
16575 && !w->redisplay
16576 && !w->update_mode_line
16577 && !f->face_change
16578 && !f->redisplay
16579 && !buffer->text->redisplay
16580 && BUF_PT (buffer) == w->last_point)
16581 return;
16583 /* Make sure that both W's markers are valid. */
16584 eassert (XMARKER (w->start)->buffer == buffer);
16585 eassert (XMARKER (w->pointm)->buffer == buffer);
16587 reconsider_clip_changes (w);
16588 frame_line_height = default_line_pixel_height (w);
16589 margin = window_scroll_margin (w, MARGIN_IN_LINES);
16592 /* Has the mode line to be updated? */
16593 update_mode_line = (w->update_mode_line
16594 || update_mode_lines
16595 || buffer->clip_changed
16596 || buffer->prevent_redisplay_optimizations_p);
16598 if (!just_this_one_p)
16599 /* If `just_this_one_p' is set, we apparently set must_be_updated_p more
16600 cleverly elsewhere. */
16601 w->must_be_updated_p = true;
16603 if (MINI_WINDOW_P (w))
16605 if (w == XWINDOW (echo_area_window)
16606 && !NILP (echo_area_buffer[0]))
16608 if (update_mode_line)
16609 /* We may have to update a tty frame's menu bar or a
16610 tool-bar. Example `M-x C-h C-h C-g'. */
16611 goto finish_menu_bars;
16612 else
16613 /* We've already displayed the echo area glyphs in this window. */
16614 goto finish_scroll_bars;
16616 else if ((w != XWINDOW (minibuf_window)
16617 || minibuf_level == 0)
16618 /* When buffer is nonempty, redisplay window normally. */
16619 && BUF_Z (XBUFFER (w->contents)) == BUF_BEG (XBUFFER (w->contents))
16620 /* Quail displays non-mini buffers in minibuffer window.
16621 In that case, redisplay the window normally. */
16622 && !NILP (Fmemq (w->contents, Vminibuffer_list)))
16624 /* W is a mini-buffer window, but it's not active, so clear
16625 it. */
16626 int yb = window_text_bottom_y (w);
16627 struct glyph_row *row;
16628 int y;
16630 for (y = 0, row = w->desired_matrix->rows;
16631 y < yb;
16632 y += row->height, ++row)
16633 blank_row (w, row, y);
16634 goto finish_scroll_bars;
16637 clear_glyph_matrix (w->desired_matrix);
16640 /* Otherwise set up data on this window; select its buffer and point
16641 value. */
16642 /* Really select the buffer, for the sake of buffer-local
16643 variables. */
16644 set_buffer_internal_1 (XBUFFER (w->contents));
16646 current_matrix_up_to_date_p
16647 = (w->window_end_valid
16648 && !current_buffer->clip_changed
16649 && !current_buffer->prevent_redisplay_optimizations_p
16650 && !window_outdated (w)
16651 && !hscrolling_current_line_p (w));
16653 beg_unchanged = BEG_UNCHANGED;
16654 end_unchanged = END_UNCHANGED;
16656 SET_TEXT_POS (opoint, PT, PT_BYTE);
16658 specbind (Qinhibit_point_motion_hooks, Qt);
16660 buffer_unchanged_p
16661 = (w->window_end_valid
16662 && !current_buffer->clip_changed
16663 && !window_outdated (w));
16665 /* When windows_or_buffers_changed is non-zero, we can't rely
16666 on the window end being valid, so set it to zero there. */
16667 if (windows_or_buffers_changed)
16669 /* If window starts on a continuation line, maybe adjust the
16670 window start in case the window's width changed. */
16671 if (XMARKER (w->start)->buffer == current_buffer)
16672 compute_window_start_on_continuation_line (w);
16674 w->window_end_valid = false;
16675 /* If so, we also can't rely on current matrix
16676 and should not fool try_cursor_movement below. */
16677 current_matrix_up_to_date_p = false;
16680 /* Some sanity checks. */
16681 CHECK_WINDOW_END (w);
16682 if (Z == Z_BYTE && CHARPOS (opoint) != BYTEPOS (opoint))
16683 emacs_abort ();
16684 if (BYTEPOS (opoint) < CHARPOS (opoint))
16685 emacs_abort ();
16687 if (mode_line_update_needed (w))
16688 update_mode_line = true;
16690 /* Point refers normally to the selected window. For any other
16691 window, set up appropriate value. */
16692 if (!EQ (window, selected_window))
16694 ptrdiff_t new_pt = marker_position (w->pointm);
16695 ptrdiff_t new_pt_byte = marker_byte_position (w->pointm);
16697 if (new_pt < BEGV)
16699 new_pt = BEGV;
16700 new_pt_byte = BEGV_BYTE;
16701 set_marker_both (w->pointm, Qnil, BEGV, BEGV_BYTE);
16703 else if (new_pt > (ZV - 1))
16705 new_pt = ZV;
16706 new_pt_byte = ZV_BYTE;
16707 set_marker_both (w->pointm, Qnil, ZV, ZV_BYTE);
16710 /* We don't use SET_PT so that the point-motion hooks don't run. */
16711 TEMP_SET_PT_BOTH (new_pt, new_pt_byte);
16714 /* If any of the character widths specified in the display table
16715 have changed, invalidate the width run cache. It's true that
16716 this may be a bit late to catch such changes, but the rest of
16717 redisplay goes (non-fatally) haywire when the display table is
16718 changed, so why should we worry about doing any better? */
16719 if (current_buffer->width_run_cache
16720 || (current_buffer->base_buffer
16721 && current_buffer->base_buffer->width_run_cache))
16723 struct Lisp_Char_Table *disptab = buffer_display_table ();
16725 if (! disptab_matches_widthtab
16726 (disptab, XVECTOR (BVAR (current_buffer, width_table))))
16728 struct buffer *buf = current_buffer;
16730 if (buf->base_buffer)
16731 buf = buf->base_buffer;
16732 invalidate_region_cache (buf, buf->width_run_cache, BEG, Z);
16733 recompute_width_table (current_buffer, disptab);
16737 /* If window-start is screwed up, choose a new one. */
16738 if (XMARKER (w->start)->buffer != current_buffer)
16739 goto recenter;
16741 SET_TEXT_POS_FROM_MARKER (startp, w->start);
16743 /* If someone specified a new starting point but did not insist,
16744 check whether it can be used. */
16745 if ((w->optional_new_start || window_frozen_p (w))
16746 && CHARPOS (startp) >= BEGV
16747 && CHARPOS (startp) <= ZV)
16749 ptrdiff_t it_charpos;
16751 w->optional_new_start = false;
16752 start_display (&it, w, startp);
16753 move_it_to (&it, PT, 0, it.last_visible_y, -1,
16754 MOVE_TO_POS | MOVE_TO_X | MOVE_TO_Y);
16755 /* Record IT's position now, since line_bottom_y might change
16756 that. */
16757 it_charpos = IT_CHARPOS (it);
16758 /* Make sure we set the force_start flag only if the cursor row
16759 will be fully visible. Otherwise, the code under force_start
16760 label below will try to move point back into view, which is
16761 not what the code which sets optional_new_start wants. */
16762 if ((it.current_y == 0 || line_bottom_y (&it) < it.last_visible_y)
16763 && !w->force_start)
16765 if (it_charpos == PT)
16766 w->force_start = true;
16767 /* IT may overshoot PT if text at PT is invisible. */
16768 else if (it_charpos > PT && CHARPOS (startp) <= PT)
16769 w->force_start = true;
16770 #ifdef GLYPH_DEBUG
16771 if (w->force_start)
16773 if (window_frozen_p (w))
16774 debug_method_add (w, "set force_start from frozen window start");
16775 else
16776 debug_method_add (w, "set force_start from optional_new_start");
16778 #endif
16782 force_start:
16784 /* Handle case where place to start displaying has been specified,
16785 unless the specified location is outside the accessible range. */
16786 if (w->force_start)
16788 /* We set this later on if we have to adjust point. */
16789 int new_vpos = -1;
16791 w->force_start = false;
16792 w->vscroll = 0;
16793 w->window_end_valid = false;
16795 /* Forget any recorded base line for line number display. */
16796 if (!buffer_unchanged_p)
16797 w->base_line_number = 0;
16799 /* Redisplay the mode line. Select the buffer properly for that.
16800 Also, run the hook window-scroll-functions
16801 because we have scrolled. */
16802 /* Note, we do this after clearing force_start because
16803 if there's an error, it is better to forget about force_start
16804 than to get into an infinite loop calling the hook functions
16805 and having them get more errors. */
16806 if (!update_mode_line
16807 || ! NILP (Vwindow_scroll_functions))
16809 update_mode_line = true;
16810 w->update_mode_line = true;
16811 startp = run_window_scroll_functions (window, startp);
16814 if (CHARPOS (startp) < BEGV)
16815 SET_TEXT_POS (startp, BEGV, BEGV_BYTE);
16816 else if (CHARPOS (startp) > ZV)
16817 SET_TEXT_POS (startp, ZV, ZV_BYTE);
16819 /* Redisplay, then check if cursor has been set during the
16820 redisplay. Give up if new fonts were loaded. */
16821 /* We used to issue a CHECK_MARGINS argument to try_window here,
16822 but this causes scrolling to fail when point begins inside
16823 the scroll margin (bug#148) -- cyd */
16824 if (!try_window (window, startp, 0))
16826 w->force_start = true;
16827 clear_glyph_matrix (w->desired_matrix);
16828 goto need_larger_matrices;
16831 if (w->cursor.vpos < 0)
16833 /* If point does not appear, try to move point so it does
16834 appear. The desired matrix has been built above, so we
16835 can use it here. First see if point is in invisible
16836 text, and if so, move it to the first visible buffer
16837 position past that. */
16838 struct glyph_row *r = NULL;
16839 Lisp_Object invprop =
16840 get_char_property_and_overlay (make_number (PT), Qinvisible,
16841 Qnil, NULL);
16843 if (TEXT_PROP_MEANS_INVISIBLE (invprop) != 0)
16845 ptrdiff_t alt_pt;
16846 Lisp_Object invprop_end =
16847 Fnext_single_char_property_change (make_number (PT), Qinvisible,
16848 Qnil, Qnil);
16850 if (NATNUMP (invprop_end))
16851 alt_pt = XFASTINT (invprop_end);
16852 else
16853 alt_pt = ZV;
16854 r = row_containing_pos (w, alt_pt, w->desired_matrix->rows,
16855 NULL, 0);
16857 if (r)
16858 new_vpos = MATRIX_ROW_BOTTOM_Y (r);
16859 else /* Give up and just move to the middle of the window. */
16860 new_vpos = window_box_height (w) / 2;
16863 if (!cursor_row_fully_visible_p (w, false, false))
16865 /* Point does appear, but on a line partly visible at end of window.
16866 Move it back to a fully-visible line. */
16867 new_vpos = window_box_height (w);
16868 /* But if window_box_height suggests a Y coordinate that is
16869 not less than we already have, that line will clearly not
16870 be fully visible, so give up and scroll the display.
16871 This can happen when the default face uses a font whose
16872 dimensions are different from the frame's default
16873 font. */
16874 if (new_vpos >= w->cursor.y)
16876 w->cursor.vpos = -1;
16877 clear_glyph_matrix (w->desired_matrix);
16878 goto try_to_scroll;
16881 else if (w->cursor.vpos >= 0)
16883 /* Some people insist on not letting point enter the scroll
16884 margin, even though this part handles windows that didn't
16885 scroll at all. */
16886 int pixel_margin = margin * frame_line_height;
16887 bool header_line = window_wants_header_line (w);
16889 /* Note: We add an extra FRAME_LINE_HEIGHT, because the loop
16890 below, which finds the row to move point to, advances by
16891 the Y coordinate of the _next_ row, see the definition of
16892 MATRIX_ROW_BOTTOM_Y. */
16893 if (w->cursor.vpos < margin + header_line)
16895 w->cursor.vpos = -1;
16896 clear_glyph_matrix (w->desired_matrix);
16897 goto try_to_scroll;
16899 else
16901 int window_height = window_box_height (w);
16903 if (header_line)
16904 window_height += CURRENT_HEADER_LINE_HEIGHT (w);
16905 if (w->cursor.y >= window_height - pixel_margin)
16907 w->cursor.vpos = -1;
16908 clear_glyph_matrix (w->desired_matrix);
16909 goto try_to_scroll;
16914 /* If we need to move point for either of the above reasons,
16915 now actually do it. */
16916 if (new_vpos >= 0)
16918 struct glyph_row *row;
16920 row = MATRIX_FIRST_TEXT_ROW (w->desired_matrix);
16921 while (MATRIX_ROW_BOTTOM_Y (row) < new_vpos)
16922 ++row;
16924 TEMP_SET_PT_BOTH (MATRIX_ROW_START_CHARPOS (row),
16925 MATRIX_ROW_START_BYTEPOS (row));
16927 if (w != XWINDOW (selected_window))
16928 set_marker_both (w->pointm, Qnil, PT, PT_BYTE);
16929 else if (current_buffer == old)
16930 SET_TEXT_POS (lpoint, PT, PT_BYTE);
16932 set_cursor_from_row (w, row, w->desired_matrix, 0, 0, 0, 0);
16934 /* Re-run pre-redisplay-function so it can update the region
16935 according to the new position of point. */
16936 /* Other than the cursor, w's redisplay is done so we can set its
16937 redisplay to false. Also the buffer's redisplay can be set to
16938 false, since propagate_buffer_redisplay should have already
16939 propagated its info to `w' anyway. */
16940 w->redisplay = false;
16941 XBUFFER (w->contents)->text->redisplay = false;
16942 safe__call1 (true, Vpre_redisplay_function, Fcons (window, Qnil));
16944 if (w->redisplay || XBUFFER (w->contents)->text->redisplay
16945 || ((EQ (Vdisplay_line_numbers, Qrelative)
16946 || EQ (Vdisplay_line_numbers, Qvisual))
16947 && row != MATRIX_FIRST_TEXT_ROW (w->desired_matrix)))
16949 /* Either pre-redisplay-function made changes (e.g. move
16950 the region), or we moved point in a window that is
16951 under display-line-numbers = relative mode. We need
16952 another round of redisplay. */
16953 clear_glyph_matrix (w->desired_matrix);
16954 if (!try_window (window, startp, 0))
16955 goto need_larger_matrices;
16958 if (w->cursor.vpos < 0 || !cursor_row_fully_visible_p (w, false, false))
16960 clear_glyph_matrix (w->desired_matrix);
16961 goto try_to_scroll;
16964 #ifdef GLYPH_DEBUG
16965 debug_method_add (w, "forced window start");
16966 #endif
16967 goto done;
16970 /* Handle case where text has not changed, only point, and it has
16971 not moved off the frame, and we are not retrying after hscroll.
16972 (current_matrix_up_to_date_p is true when retrying.) */
16973 if (current_matrix_up_to_date_p
16974 && (rc = try_cursor_movement (window, startp, &temp_scroll_step),
16975 rc != CURSOR_MOVEMENT_CANNOT_BE_USED))
16977 switch (rc)
16979 case CURSOR_MOVEMENT_SUCCESS:
16980 used_current_matrix_p = true;
16981 goto done;
16983 case CURSOR_MOVEMENT_MUST_SCROLL:
16984 goto try_to_scroll;
16986 default:
16987 emacs_abort ();
16990 /* If current starting point was originally the beginning of a line
16991 but no longer is, find a new starting point. */
16992 else if (w->start_at_line_beg
16993 && !(CHARPOS (startp) <= BEGV
16994 || FETCH_BYTE (BYTEPOS (startp) - 1) == '\n'))
16996 #ifdef GLYPH_DEBUG
16997 debug_method_add (w, "recenter 1");
16998 #endif
16999 goto recenter;
17002 /* Try scrolling with try_window_id. Value is > 0 if update has
17003 been done, it is -1 if we know that the same window start will
17004 not work. It is 0 if unsuccessful for some other reason. */
17005 else if ((tem = try_window_id (w)) != 0)
17007 #ifdef GLYPH_DEBUG
17008 debug_method_add (w, "try_window_id %d", tem);
17009 #endif
17011 if (f->fonts_changed)
17012 goto need_larger_matrices;
17013 if (tem > 0)
17014 goto done;
17016 /* Otherwise try_window_id has returned -1 which means that we
17017 don't want the alternative below this comment to execute. */
17019 else if (CHARPOS (startp) >= BEGV
17020 && CHARPOS (startp) <= ZV
17021 && PT >= CHARPOS (startp)
17022 && (CHARPOS (startp) < ZV
17023 /* Avoid starting at end of buffer. */
17024 || CHARPOS (startp) == BEGV
17025 || !window_outdated (w)))
17027 int d1, d2, d5, d6;
17028 int rtop, rbot;
17030 /* If first window line is a continuation line, and window start
17031 is inside the modified region, but the first change is before
17032 current window start, we must select a new window start.
17034 However, if this is the result of a down-mouse event (e.g. by
17035 extending the mouse-drag-overlay), we don't want to select a
17036 new window start, since that would change the position under
17037 the mouse, resulting in an unwanted mouse-movement rather
17038 than a simple mouse-click. */
17039 if (!w->start_at_line_beg
17040 && NILP (do_mouse_tracking)
17041 && CHARPOS (startp) > BEGV
17042 && CHARPOS (startp) > BEG + beg_unchanged
17043 && CHARPOS (startp) <= Z - end_unchanged
17044 /* Even if w->start_at_line_beg is nil, a new window may
17045 start at a line_beg, since that's how set_buffer_window
17046 sets it. So, we need to check the return value of
17047 compute_window_start_on_continuation_line. (See also
17048 bug#197). */
17049 && XMARKER (w->start)->buffer == current_buffer
17050 && compute_window_start_on_continuation_line (w)
17051 /* It doesn't make sense to force the window start like we
17052 do at label force_start if it is already known that point
17053 will not be fully visible in the resulting window, because
17054 doing so will move point from its correct position
17055 instead of scrolling the window to bring point into view.
17056 See bug#9324. */
17057 && pos_visible_p (w, PT, &d1, &d2, &rtop, &rbot, &d5, &d6)
17058 /* A very tall row could need more than the window height,
17059 in which case we accept that it is partially visible. */
17060 && (rtop != 0) == (rbot != 0))
17062 w->force_start = true;
17063 SET_TEXT_POS_FROM_MARKER (startp, w->start);
17064 #ifdef GLYPH_DEBUG
17065 debug_method_add (w, "recomputed window start in continuation line");
17066 #endif
17067 goto force_start;
17070 #ifdef GLYPH_DEBUG
17071 debug_method_add (w, "same window start");
17072 #endif
17074 /* Try to redisplay starting at same place as before.
17075 If point has not moved off frame, accept the results. */
17076 if (!current_matrix_up_to_date_p
17077 /* Don't use try_window_reusing_current_matrix in this case
17078 because a window scroll function can have changed the
17079 buffer. */
17080 || !NILP (Vwindow_scroll_functions)
17081 || MINI_WINDOW_P (w)
17082 || !(used_current_matrix_p
17083 = try_window_reusing_current_matrix (w)))
17085 IF_DEBUG (debug_method_add (w, "1"));
17086 clear_glyph_matrix (w->desired_matrix);
17087 if (try_window (window, startp, TRY_WINDOW_CHECK_MARGINS) < 0)
17088 /* -1 means we need to scroll.
17089 0 means we need new matrices, but fonts_changed
17090 is set in that case, so we will detect it below. */
17091 goto try_to_scroll;
17094 if (f->fonts_changed)
17095 goto need_larger_matrices;
17097 if (w->cursor.vpos >= 0)
17099 if (!just_this_one_p
17100 || current_buffer->clip_changed
17101 || BEG_UNCHANGED < CHARPOS (startp))
17102 /* Forget any recorded base line for line number display. */
17103 w->base_line_number = 0;
17105 if (!cursor_row_fully_visible_p (w, true, false))
17107 clear_glyph_matrix (w->desired_matrix);
17108 last_line_misfit = true;
17110 /* Drop through and scroll. */
17111 else
17112 goto done;
17114 else
17115 clear_glyph_matrix (w->desired_matrix);
17118 try_to_scroll:
17120 /* Redisplay the mode line. Select the buffer properly for that. */
17121 if (!update_mode_line)
17123 update_mode_line = true;
17124 w->update_mode_line = true;
17127 /* Try to scroll by specified few lines. */
17128 if ((scroll_conservatively
17129 || emacs_scroll_step
17130 || temp_scroll_step
17131 || NUMBERP (BVAR (current_buffer, scroll_up_aggressively))
17132 || NUMBERP (BVAR (current_buffer, scroll_down_aggressively)))
17133 && CHARPOS (startp) >= BEGV
17134 && CHARPOS (startp) <= ZV)
17136 /* The function returns -1 if new fonts were loaded, 1 if
17137 successful, 0 if not successful. */
17138 int ss = try_scrolling (window, just_this_one_p,
17139 scroll_conservatively,
17140 emacs_scroll_step,
17141 temp_scroll_step, last_line_misfit);
17142 switch (ss)
17144 case SCROLLING_SUCCESS:
17145 goto done;
17147 case SCROLLING_NEED_LARGER_MATRICES:
17148 goto need_larger_matrices;
17150 case SCROLLING_FAILED:
17151 break;
17153 default:
17154 emacs_abort ();
17158 /* Finally, just choose a place to start which positions point
17159 according to user preferences. */
17161 recenter:
17163 #ifdef GLYPH_DEBUG
17164 debug_method_add (w, "recenter");
17165 #endif
17167 /* Forget any previously recorded base line for line number display. */
17168 if (!buffer_unchanged_p)
17169 w->base_line_number = 0;
17171 /* Determine the window start relative to point. */
17172 init_iterator (&it, w, PT, PT_BYTE, NULL, DEFAULT_FACE_ID);
17173 it.current_y = it.last_visible_y;
17174 if (centering_position < 0)
17176 ptrdiff_t margin_pos = CHARPOS (startp);
17177 Lisp_Object aggressive;
17178 bool scrolling_up;
17180 /* If there is a scroll margin at the top of the window, find
17181 its character position. */
17182 if (margin
17183 /* Cannot call start_display if startp is not in the
17184 accessible region of the buffer. This can happen when we
17185 have just switched to a different buffer and/or changed
17186 its restriction. In that case, startp is initialized to
17187 the character position 1 (BEGV) because we did not yet
17188 have chance to display the buffer even once. */
17189 && BEGV <= CHARPOS (startp) && CHARPOS (startp) <= ZV)
17191 struct it it1;
17192 void *it1data = NULL;
17194 SAVE_IT (it1, it, it1data);
17195 start_display (&it1, w, startp);
17196 move_it_vertically (&it1, margin * frame_line_height);
17197 margin_pos = IT_CHARPOS (it1);
17198 RESTORE_IT (&it, &it, it1data);
17200 scrolling_up = PT > margin_pos;
17201 aggressive =
17202 scrolling_up
17203 ? BVAR (current_buffer, scroll_up_aggressively)
17204 : BVAR (current_buffer, scroll_down_aggressively);
17206 if (!MINI_WINDOW_P (w)
17207 && (scroll_conservatively > SCROLL_LIMIT || NUMBERP (aggressive)))
17209 int pt_offset = 0;
17211 /* Setting scroll-conservatively overrides
17212 scroll-*-aggressively. */
17213 if (!scroll_conservatively && NUMBERP (aggressive))
17215 double float_amount = XFLOATINT (aggressive);
17217 pt_offset = float_amount * WINDOW_BOX_TEXT_HEIGHT (w);
17218 if (pt_offset == 0 && float_amount > 0)
17219 pt_offset = 1;
17220 if (pt_offset && margin > 0)
17221 margin -= 1;
17223 /* Compute how much to move the window start backward from
17224 point so that point will be displayed where the user
17225 wants it. */
17226 if (scrolling_up)
17228 centering_position = it.last_visible_y;
17229 if (pt_offset)
17230 centering_position -= pt_offset;
17231 centering_position -=
17232 (frame_line_height * (1 + margin + last_line_misfit)
17233 + WINDOW_HEADER_LINE_HEIGHT (w));
17234 /* Don't let point enter the scroll margin near top of
17235 the window. */
17236 if (centering_position < margin * frame_line_height)
17237 centering_position = margin * frame_line_height;
17239 else
17240 centering_position = margin * frame_line_height + pt_offset;
17242 else
17243 /* Set the window start half the height of the window backward
17244 from point. */
17245 centering_position = window_box_height (w) / 2;
17247 move_it_vertically_backward (&it, centering_position);
17249 eassert (IT_CHARPOS (it) >= BEGV);
17251 /* The function move_it_vertically_backward may move over more
17252 than the specified y-distance. If it->w is small, e.g. a
17253 mini-buffer window, we may end up in front of the window's
17254 display area. Start displaying at the start of the line
17255 containing PT in this case. */
17256 if (it.current_y <= 0)
17258 init_iterator (&it, w, PT, PT_BYTE, NULL, DEFAULT_FACE_ID);
17259 move_it_vertically_backward (&it, 0);
17260 it.current_y = 0;
17263 it.current_x = it.hpos = 0;
17265 /* Set the window start position here explicitly, to avoid an
17266 infinite loop in case the functions in window-scroll-functions
17267 get errors. */
17268 set_marker_both (w->start, Qnil, IT_CHARPOS (it), IT_BYTEPOS (it));
17270 /* Run scroll hooks. */
17271 startp = run_window_scroll_functions (window, it.current.pos);
17273 /* We invoke try_window and try_window_reusing_current_matrix below,
17274 and they manipulate the bidi cache. Save and restore the cache
17275 state of our iterator, so we could continue using it after that. */
17276 itdata = bidi_shelve_cache ();
17278 /* Redisplay the window. */
17279 use_desired_matrix = false;
17280 if (!current_matrix_up_to_date_p
17281 || windows_or_buffers_changed
17282 || f->cursor_type_changed
17283 /* Don't use try_window_reusing_current_matrix in this case
17284 because it can have changed the buffer. */
17285 || !NILP (Vwindow_scroll_functions)
17286 || !just_this_one_p
17287 || MINI_WINDOW_P (w)
17288 || !(used_current_matrix_p
17289 = try_window_reusing_current_matrix (w)))
17290 use_desired_matrix = (try_window (window, startp, 0) == 1);
17292 bidi_unshelve_cache (itdata, false);
17294 /* If new fonts have been loaded (due to fontsets), give up. We
17295 have to start a new redisplay since we need to re-adjust glyph
17296 matrices. */
17297 if (f->fonts_changed)
17298 goto need_larger_matrices;
17300 /* If cursor did not appear assume that the middle of the window is
17301 in the first line of the window. Do it again with the next line.
17302 (Imagine a window of height 100, displaying two lines of height
17303 60. Moving back 50 from it->last_visible_y will end in the first
17304 line.) */
17305 if (w->cursor.vpos < 0)
17307 if (w->window_end_valid && PT >= Z - w->window_end_pos)
17309 clear_glyph_matrix (w->desired_matrix);
17310 move_it_by_lines (&it, 1);
17311 try_window (window, it.current.pos, 0);
17313 else if (PT < IT_CHARPOS (it))
17315 clear_glyph_matrix (w->desired_matrix);
17316 move_it_by_lines (&it, -1);
17317 try_window (window, it.current.pos, 0);
17319 else if (scroll_conservatively > SCROLL_LIMIT
17320 && (it.method == GET_FROM_STRING
17321 || overlay_touches_p (IT_CHARPOS (it)))
17322 && IT_CHARPOS (it) < ZV)
17324 /* If the window starts with a before-string that spans more
17325 than one screen line, using that position to display the
17326 window might fail to bring point into the view, because
17327 start_display will always start by displaying the string,
17328 whereas the code above determines where to set w->start
17329 by the buffer position of the place where it takes screen
17330 coordinates. Try to recover by finding the next screen
17331 line that displays buffer text. */
17332 ptrdiff_t pos0 = IT_CHARPOS (it);
17334 clear_glyph_matrix (w->desired_matrix);
17335 do {
17336 move_it_by_lines (&it, 1);
17337 } while (IT_CHARPOS (it) == pos0);
17338 try_window (window, it.current.pos, 0);
17340 else
17342 /* Not much we can do about it. */
17346 /* Consider the following case: Window starts at BEGV, there is
17347 invisible, intangible text at BEGV, so that display starts at
17348 some point START > BEGV. It can happen that we are called with
17349 PT somewhere between BEGV and START. Try to handle that case,
17350 and similar ones. */
17351 if (w->cursor.vpos < 0)
17353 /* Prefer the desired matrix to the current matrix, if possible,
17354 in the fallback calculations below. This is because using
17355 the current matrix might completely goof, e.g. if its first
17356 row is after point. */
17357 struct glyph_matrix *matrix =
17358 use_desired_matrix ? w->desired_matrix : w->current_matrix;
17359 /* First, try locating the proper glyph row for PT. */
17360 struct glyph_row *row =
17361 row_containing_pos (w, PT, matrix->rows, NULL, 0);
17363 /* Sometimes point is at the beginning of invisible text that is
17364 before the 1st character displayed in the row. In that case,
17365 row_containing_pos fails to find the row, because no glyphs
17366 with appropriate buffer positions are present in the row.
17367 Therefore, we next try to find the row which shows the 1st
17368 position after the invisible text. */
17369 if (!row)
17371 Lisp_Object val =
17372 get_char_property_and_overlay (make_number (PT), Qinvisible,
17373 Qnil, NULL);
17375 if (TEXT_PROP_MEANS_INVISIBLE (val) != 0)
17377 ptrdiff_t alt_pos;
17378 Lisp_Object invis_end =
17379 Fnext_single_char_property_change (make_number (PT), Qinvisible,
17380 Qnil, Qnil);
17382 if (NATNUMP (invis_end))
17383 alt_pos = XFASTINT (invis_end);
17384 else
17385 alt_pos = ZV;
17386 row = row_containing_pos (w, alt_pos, matrix->rows, NULL, 0);
17389 /* Finally, fall back on the first row of the window after the
17390 header line (if any). This is slightly better than not
17391 displaying the cursor at all. */
17392 if (!row)
17394 row = matrix->rows;
17395 if (row->mode_line_p)
17396 ++row;
17398 set_cursor_from_row (w, row, matrix, 0, 0, 0, 0);
17401 if (!cursor_row_fully_visible_p (w, false, false))
17403 /* If vscroll is enabled, disable it and try again. */
17404 if (w->vscroll)
17406 w->vscroll = 0;
17407 clear_glyph_matrix (w->desired_matrix);
17408 goto recenter;
17411 /* Users who set scroll-conservatively to a large number want
17412 point just above/below the scroll margin. If we ended up
17413 with point's row partially visible, move the window start to
17414 make that row fully visible and out of the margin. */
17415 if (scroll_conservatively > SCROLL_LIMIT)
17417 int window_total_lines
17418 = WINDOW_TOTAL_LINES (w) * FRAME_LINE_HEIGHT (f) / frame_line_height;
17419 bool move_down = w->cursor.vpos >= window_total_lines / 2;
17421 move_it_by_lines (&it, move_down ? margin + 1 : -(margin + 1));
17422 clear_glyph_matrix (w->desired_matrix);
17423 if (1 == try_window (window, it.current.pos,
17424 TRY_WINDOW_CHECK_MARGINS))
17425 goto done;
17428 /* If centering point failed to make the whole line visible,
17429 put point at the top instead. That has to make the whole line
17430 visible, if it can be done. */
17431 if (centering_position == 0)
17432 goto done;
17434 clear_glyph_matrix (w->desired_matrix);
17435 centering_position = 0;
17436 goto recenter;
17439 done:
17441 SET_TEXT_POS_FROM_MARKER (startp, w->start);
17442 w->start_at_line_beg = (CHARPOS (startp) == BEGV
17443 || FETCH_BYTE (BYTEPOS (startp) - 1) == '\n');
17445 /* Display the mode line, if we must. */
17446 if ((update_mode_line
17447 /* If window not full width, must redo its mode line
17448 if (a) the window to its side is being redone and
17449 (b) we do a frame-based redisplay. This is a consequence
17450 of how inverted lines are drawn in frame-based redisplay. */
17451 || (!just_this_one_p
17452 && !FRAME_WINDOW_P (f)
17453 && !WINDOW_FULL_WIDTH_P (w))
17454 /* Line number to display. */
17455 || w->base_line_pos > 0
17456 /* Column number is displayed and different from the one displayed. */
17457 || (w->column_number_displayed != -1
17458 && (w->column_number_displayed != current_column ())))
17459 /* This means that the window has a mode line. */
17460 && (window_wants_mode_line (w)
17461 || window_wants_header_line (w)))
17464 display_mode_lines (w);
17466 /* If mode line height has changed, arrange for a thorough
17467 immediate redisplay using the correct mode line height. */
17468 if (window_wants_mode_line (w)
17469 && CURRENT_MODE_LINE_HEIGHT (w) != DESIRED_MODE_LINE_HEIGHT (w))
17471 f->fonts_changed = true;
17472 w->mode_line_height = -1;
17473 MATRIX_MODE_LINE_ROW (w->current_matrix)->height
17474 = DESIRED_MODE_LINE_HEIGHT (w);
17477 /* If header line height has changed, arrange for a thorough
17478 immediate redisplay using the correct header line height. */
17479 if (window_wants_header_line (w)
17480 && CURRENT_HEADER_LINE_HEIGHT (w) != DESIRED_HEADER_LINE_HEIGHT (w))
17482 f->fonts_changed = true;
17483 w->header_line_height = -1;
17484 MATRIX_HEADER_LINE_ROW (w->current_matrix)->height
17485 = DESIRED_HEADER_LINE_HEIGHT (w);
17488 if (f->fonts_changed)
17489 goto need_larger_matrices;
17492 if (!line_number_displayed && w->base_line_pos != -1)
17494 w->base_line_pos = 0;
17495 w->base_line_number = 0;
17498 finish_menu_bars:
17500 /* When we reach a frame's selected window, redo the frame's menu
17501 bar and the frame's title. */
17502 if (update_mode_line
17503 && EQ (FRAME_SELECTED_WINDOW (f), window))
17505 bool redisplay_menu_p;
17507 if (FRAME_WINDOW_P (f))
17509 #if defined (USE_X_TOOLKIT) || defined (HAVE_NTGUI) \
17510 || defined (HAVE_NS) || defined (USE_GTK)
17511 redisplay_menu_p = FRAME_EXTERNAL_MENU_BAR (f);
17512 #else
17513 redisplay_menu_p = FRAME_MENU_BAR_LINES (f) > 0;
17514 #endif
17516 else
17517 redisplay_menu_p = FRAME_MENU_BAR_LINES (f) > 0;
17519 if (redisplay_menu_p)
17520 display_menu_bar (w);
17522 #ifdef HAVE_WINDOW_SYSTEM
17523 if (FRAME_WINDOW_P (f))
17525 #if defined (USE_GTK) || defined (HAVE_NS)
17526 if (FRAME_EXTERNAL_TOOL_BAR (f))
17527 redisplay_tool_bar (f);
17528 #else
17529 if (WINDOWP (f->tool_bar_window)
17530 && (FRAME_TOOL_BAR_LINES (f) > 0
17531 || !NILP (Vauto_resize_tool_bars))
17532 && redisplay_tool_bar (f))
17533 ignore_mouse_drag_p = true;
17534 #endif
17536 x_consider_frame_title (w->frame);
17537 #endif
17540 #ifdef HAVE_WINDOW_SYSTEM
17541 if (FRAME_WINDOW_P (f)
17542 && update_window_fringes (w, (just_this_one_p
17543 || (!used_current_matrix_p && !overlay_arrow_seen)
17544 || w->pseudo_window_p)))
17546 update_begin (f);
17547 block_input ();
17548 if (draw_window_fringes (w, true))
17550 if (WINDOW_RIGHT_DIVIDER_WIDTH (w))
17551 x_draw_right_divider (w);
17552 else
17553 x_draw_vertical_border (w);
17555 unblock_input ();
17556 update_end (f);
17559 if (WINDOW_BOTTOM_DIVIDER_WIDTH (w))
17560 x_draw_bottom_divider (w);
17561 #endif /* HAVE_WINDOW_SYSTEM */
17563 /* We go to this label, with fonts_changed set, if it is
17564 necessary to try again using larger glyph matrices.
17565 We have to redeem the scroll bar even in this case,
17566 because the loop in redisplay_internal expects that. */
17567 need_larger_matrices:
17569 finish_scroll_bars:
17571 if (WINDOW_HAS_VERTICAL_SCROLL_BAR (w) || WINDOW_HAS_HORIZONTAL_SCROLL_BAR (w))
17573 if (WINDOW_HAS_VERTICAL_SCROLL_BAR (w))
17574 /* Set the thumb's position and size. */
17575 set_vertical_scroll_bar (w);
17577 if (WINDOW_HAS_HORIZONTAL_SCROLL_BAR (w))
17578 /* Set the thumb's position and size. */
17579 set_horizontal_scroll_bar (w);
17581 /* Note that we actually used the scroll bar attached to this
17582 window, so it shouldn't be deleted at the end of redisplay. */
17583 if (FRAME_TERMINAL (f)->redeem_scroll_bar_hook)
17584 (*FRAME_TERMINAL (f)->redeem_scroll_bar_hook) (w);
17587 /* Restore current_buffer and value of point in it. The window
17588 update may have changed the buffer, so first make sure `opoint'
17589 is still valid (Bug#6177). */
17590 if (CHARPOS (opoint) < BEGV)
17591 TEMP_SET_PT_BOTH (BEGV, BEGV_BYTE);
17592 else if (CHARPOS (opoint) > ZV)
17593 TEMP_SET_PT_BOTH (Z, Z_BYTE);
17594 else
17595 TEMP_SET_PT_BOTH (CHARPOS (opoint), BYTEPOS (opoint));
17597 set_buffer_internal_1 (old);
17598 /* Avoid an abort in TEMP_SET_PT_BOTH if the buffer has become
17599 shorter. This can be caused by log truncation in *Messages*. */
17600 if (CHARPOS (lpoint) <= ZV)
17601 TEMP_SET_PT_BOTH (CHARPOS (lpoint), BYTEPOS (lpoint));
17603 unbind_to (count, Qnil);
17607 /* Build the complete desired matrix of WINDOW with a window start
17608 buffer position POS.
17610 Value is 1 if successful. It is zero if fonts were loaded during
17611 redisplay which makes re-adjusting glyph matrices necessary, and -1
17612 if point would appear in the scroll margins.
17613 (We check the former only if TRY_WINDOW_IGNORE_FONTS_CHANGE is
17614 unset in FLAGS, and the latter only if TRY_WINDOW_CHECK_MARGINS is
17615 set in FLAGS.) */
17618 try_window (Lisp_Object window, struct text_pos pos, int flags)
17620 struct window *w = XWINDOW (window);
17621 struct it it;
17622 struct glyph_row *last_text_row = NULL;
17623 struct frame *f = XFRAME (w->frame);
17624 int cursor_vpos = w->cursor.vpos;
17626 /* Make POS the new window start. */
17627 set_marker_both (w->start, Qnil, CHARPOS (pos), BYTEPOS (pos));
17629 /* Mark cursor position as unknown. No overlay arrow seen. */
17630 w->cursor.vpos = -1;
17631 overlay_arrow_seen = false;
17633 /* Initialize iterator and info to start at POS. */
17634 start_display (&it, w, pos);
17635 it.glyph_row->reversed_p = false;
17637 /* Display all lines of W. */
17638 while (it.current_y < it.last_visible_y)
17640 if (display_line (&it, cursor_vpos))
17641 last_text_row = it.glyph_row - 1;
17642 if (f->fonts_changed && !(flags & TRY_WINDOW_IGNORE_FONTS_CHANGE))
17643 return 0;
17646 /* Save the character position of 'it' before we call
17647 'start_display' again. */
17648 ptrdiff_t it_charpos = IT_CHARPOS (it);
17650 /* Don't let the cursor end in the scroll margins. */
17651 if ((flags & TRY_WINDOW_CHECK_MARGINS)
17652 && !MINI_WINDOW_P (w))
17654 int this_scroll_margin = window_scroll_margin (w, MARGIN_IN_PIXELS);
17655 start_display (&it, w, pos);
17657 if ((w->cursor.y >= 0 /* not vscrolled */
17658 && w->cursor.y < this_scroll_margin
17659 && CHARPOS (pos) > BEGV
17660 && it_charpos < ZV)
17661 /* rms: considering make_cursor_line_fully_visible_p here
17662 seems to give wrong results. We don't want to recenter
17663 when the last line is partly visible, we want to allow
17664 that case to be handled in the usual way. */
17665 || w->cursor.y > (it.last_visible_y - partial_line_height (&it)
17666 - this_scroll_margin - 1))
17668 w->cursor.vpos = -1;
17669 clear_glyph_matrix (w->desired_matrix);
17670 return -1;
17674 /* If bottom moved off end of frame, change mode line percentage. */
17675 if (w->window_end_pos <= 0 && Z != it_charpos)
17676 w->update_mode_line = true;
17678 /* Set window_end_pos to the offset of the last character displayed
17679 on the window from the end of current_buffer. Set
17680 window_end_vpos to its row number. */
17681 if (last_text_row)
17683 eassert (MATRIX_ROW_DISPLAYS_TEXT_P (last_text_row));
17684 adjust_window_ends (w, last_text_row, false);
17685 eassert
17686 (MATRIX_ROW_DISPLAYS_TEXT_P (MATRIX_ROW (w->desired_matrix,
17687 w->window_end_vpos)));
17689 else
17691 w->window_end_bytepos = Z_BYTE - ZV_BYTE;
17692 w->window_end_pos = Z - ZV;
17693 w->window_end_vpos = 0;
17696 /* But that is not valid info until redisplay finishes. */
17697 w->window_end_valid = false;
17698 return 1;
17703 /************************************************************************
17704 Window redisplay reusing current matrix when buffer has not changed
17705 ************************************************************************/
17707 /* Try redisplay of window W showing an unchanged buffer with a
17708 different window start than the last time it was displayed by
17709 reusing its current matrix. Value is true if successful.
17710 W->start is the new window start. */
17712 static bool
17713 try_window_reusing_current_matrix (struct window *w)
17715 struct frame *f = XFRAME (w->frame);
17716 struct glyph_row *bottom_row;
17717 struct it it;
17718 struct run run;
17719 struct text_pos start, new_start;
17720 int nrows_scrolled, i;
17721 struct glyph_row *last_text_row;
17722 struct glyph_row *last_reused_text_row;
17723 struct glyph_row *start_row;
17724 int start_vpos, min_y, max_y;
17726 #ifdef GLYPH_DEBUG
17727 if (inhibit_try_window_reusing)
17728 return false;
17729 #endif
17731 if (/* This function doesn't handle terminal frames. */
17732 !FRAME_WINDOW_P (f)
17733 /* Don't try to reuse the display if windows have been split
17734 or such. */
17735 || windows_or_buffers_changed
17736 || f->cursor_type_changed
17737 /* This function cannot handle buffers where the overlay arrow
17738 is shown on the fringes, because if the arrow position
17739 changes, we cannot just reuse the current matrix. */
17740 || overlay_arrow_in_current_buffer_p ())
17741 return false;
17743 /* Can't do this if showing trailing whitespace. */
17744 if (!NILP (Vshow_trailing_whitespace))
17745 return false;
17747 /* If top-line visibility has changed, give up. */
17748 if (window_wants_header_line (w)
17749 != MATRIX_HEADER_LINE_ROW (w->current_matrix)->mode_line_p)
17750 return false;
17752 /* Give up if old or new display is scrolled vertically. We could
17753 make this function handle this, but right now it doesn't. */
17754 start_row = MATRIX_FIRST_TEXT_ROW (w->current_matrix);
17755 if (w->vscroll || MATRIX_ROW_PARTIALLY_VISIBLE_P (w, start_row))
17756 return false;
17758 /* Clear the desired matrix for the display below. */
17759 clear_glyph_matrix (w->desired_matrix);
17761 /* Give up if line numbers are being displayed, because reusing the
17762 current matrix might use the wrong width for line-number
17763 display. */
17764 if (!NILP (Vdisplay_line_numbers))
17765 return false;
17767 /* The variable new_start now holds the new window start. The old
17768 start `start' can be determined from the current matrix. */
17769 SET_TEXT_POS_FROM_MARKER (new_start, w->start);
17770 start = start_row->minpos;
17771 start_vpos = MATRIX_ROW_VPOS (start_row, w->current_matrix);
17773 if (CHARPOS (new_start) <= CHARPOS (start))
17775 /* Don't use this method if the display starts with an ellipsis
17776 displayed for invisible text. It's not easy to handle that case
17777 below, and it's certainly not worth the effort since this is
17778 not a frequent case. */
17779 if (in_ellipses_for_invisible_text_p (&start_row->start, w))
17780 return false;
17782 IF_DEBUG (debug_method_add (w, "twu1"));
17784 /* Display up to a row that can be reused. The variable
17785 last_text_row is set to the last row displayed that displays
17786 text. Note that it.vpos == 0 if or if not there is a
17787 header-line; it's not the same as the MATRIX_ROW_VPOS! */
17788 start_display (&it, w, new_start);
17789 w->cursor.vpos = -1;
17790 last_text_row = last_reused_text_row = NULL;
17792 while (it.current_y < it.last_visible_y && !f->fonts_changed)
17794 /* If we have reached into the characters in the START row,
17795 that means the line boundaries have changed. So we
17796 can't start copying with the row START. Maybe it will
17797 work to start copying with the following row. */
17798 while (IT_CHARPOS (it) > CHARPOS (start))
17800 /* Advance to the next row as the "start". */
17801 start_row++;
17802 start = start_row->minpos;
17803 /* If there are no more rows to try, or just one, give up. */
17804 if (start_row == MATRIX_MODE_LINE_ROW (w->current_matrix) - 1
17805 || w->vscroll || MATRIX_ROW_PARTIALLY_VISIBLE_P (w, start_row)
17806 || CHARPOS (start) == ZV)
17808 clear_glyph_matrix (w->desired_matrix);
17809 return false;
17812 start_vpos = MATRIX_ROW_VPOS (start_row, w->current_matrix);
17814 /* If we have reached alignment, we can copy the rest of the
17815 rows. */
17816 if (IT_CHARPOS (it) == CHARPOS (start)
17817 /* Don't accept "alignment" inside a display vector,
17818 since start_row could have started in the middle of
17819 that same display vector (thus their character
17820 positions match), and we have no way of telling if
17821 that is the case. */
17822 && it.current.dpvec_index < 0)
17823 break;
17825 it.glyph_row->reversed_p = false;
17826 if (display_line (&it, -1))
17827 last_text_row = it.glyph_row - 1;
17831 /* A value of current_y < last_visible_y means that we stopped
17832 at the previous window start, which in turn means that we
17833 have at least one reusable row. */
17834 if (it.current_y < it.last_visible_y)
17836 struct glyph_row *row;
17838 /* IT.vpos always starts from 0; it counts text lines. */
17839 nrows_scrolled = it.vpos - (start_row - MATRIX_FIRST_TEXT_ROW (w->current_matrix));
17841 /* Find PT if not already found in the lines displayed. */
17842 if (w->cursor.vpos < 0)
17844 int dy = it.current_y - start_row->y;
17846 row = MATRIX_FIRST_TEXT_ROW (w->current_matrix);
17847 row = row_containing_pos (w, PT, row, NULL, dy);
17848 if (row)
17849 set_cursor_from_row (w, row, w->current_matrix, 0, 0,
17850 dy, nrows_scrolled);
17851 else
17853 clear_glyph_matrix (w->desired_matrix);
17854 return false;
17858 /* Scroll the display. Do it before the current matrix is
17859 changed. The problem here is that update has not yet
17860 run, i.e. part of the current matrix is not up to date.
17861 scroll_run_hook will clear the cursor, and use the
17862 current matrix to get the height of the row the cursor is
17863 in. */
17864 run.current_y = start_row->y;
17865 run.desired_y = it.current_y;
17866 run.height = it.last_visible_y - it.current_y;
17868 if (run.height > 0 && run.current_y != run.desired_y)
17870 update_begin (f);
17871 FRAME_RIF (f)->update_window_begin_hook (w);
17872 FRAME_RIF (f)->clear_window_mouse_face (w);
17873 FRAME_RIF (f)->scroll_run_hook (w, &run);
17874 FRAME_RIF (f)->update_window_end_hook (w, false, false);
17875 update_end (f);
17878 /* Shift current matrix down by nrows_scrolled lines. */
17879 bottom_row = MATRIX_BOTTOM_TEXT_ROW (w->current_matrix, w);
17880 rotate_matrix (w->current_matrix,
17881 start_vpos,
17882 MATRIX_ROW_VPOS (bottom_row, w->current_matrix),
17883 nrows_scrolled);
17885 /* Disable lines that must be updated. */
17886 for (i = 0; i < nrows_scrolled; ++i)
17887 (start_row + i)->enabled_p = false;
17889 /* Re-compute Y positions. */
17890 min_y = WINDOW_HEADER_LINE_HEIGHT (w);
17891 max_y = it.last_visible_y;
17892 for (row = start_row + nrows_scrolled;
17893 row < bottom_row;
17894 ++row)
17896 row->y = it.current_y;
17897 row->visible_height = row->height;
17899 if (row->y < min_y)
17900 row->visible_height -= min_y - row->y;
17901 if (row->y + row->height > max_y)
17902 row->visible_height -= row->y + row->height - max_y;
17903 if (row->fringe_bitmap_periodic_p)
17904 row->redraw_fringe_bitmaps_p = true;
17906 it.current_y += row->height;
17908 if (MATRIX_ROW_DISPLAYS_TEXT_P (row))
17909 last_reused_text_row = row;
17910 if (MATRIX_ROW_BOTTOM_Y (row) >= it.last_visible_y)
17911 break;
17914 /* Disable lines in the current matrix which are now
17915 below the window. */
17916 for (++row; row < bottom_row; ++row)
17917 row->enabled_p = row->mode_line_p = false;
17920 /* Update window_end_pos etc.; last_reused_text_row is the last
17921 reused row from the current matrix containing text, if any.
17922 The value of last_text_row is the last displayed line
17923 containing text. */
17924 if (last_reused_text_row)
17925 adjust_window_ends (w, last_reused_text_row, true);
17926 else if (last_text_row)
17927 adjust_window_ends (w, last_text_row, false);
17928 else
17930 /* This window must be completely empty. */
17931 w->window_end_bytepos = Z_BYTE - ZV_BYTE;
17932 w->window_end_pos = Z - ZV;
17933 w->window_end_vpos = 0;
17935 w->window_end_valid = false;
17937 /* Update hint: don't try scrolling again in update_window. */
17938 w->desired_matrix->no_scrolling_p = true;
17940 #ifdef GLYPH_DEBUG
17941 debug_method_add (w, "try_window_reusing_current_matrix 1");
17942 #endif
17943 return true;
17945 else if (CHARPOS (new_start) > CHARPOS (start))
17947 struct glyph_row *pt_row, *row;
17948 struct glyph_row *first_reusable_row;
17949 struct glyph_row *first_row_to_display;
17950 int dy;
17951 int yb = window_text_bottom_y (w);
17953 /* Find the row starting at new_start, if there is one. Don't
17954 reuse a partially visible line at the end. */
17955 first_reusable_row = start_row;
17956 while (first_reusable_row->enabled_p
17957 && MATRIX_ROW_BOTTOM_Y (first_reusable_row) < yb
17958 && (MATRIX_ROW_START_CHARPOS (first_reusable_row)
17959 < CHARPOS (new_start)))
17960 ++first_reusable_row;
17962 /* Give up if there is no row to reuse. */
17963 if (MATRIX_ROW_BOTTOM_Y (first_reusable_row) >= yb
17964 || !first_reusable_row->enabled_p
17965 || (MATRIX_ROW_START_CHARPOS (first_reusable_row)
17966 != CHARPOS (new_start)))
17967 return false;
17969 /* We can reuse fully visible rows beginning with
17970 first_reusable_row to the end of the window. Set
17971 first_row_to_display to the first row that cannot be reused.
17972 Set pt_row to the row containing point, if there is any. */
17973 pt_row = NULL;
17974 for (first_row_to_display = first_reusable_row;
17975 MATRIX_ROW_BOTTOM_Y (first_row_to_display) < yb;
17976 ++first_row_to_display)
17978 if (PT >= MATRIX_ROW_START_CHARPOS (first_row_to_display)
17979 && (PT < MATRIX_ROW_END_CHARPOS (first_row_to_display)
17980 || (PT == MATRIX_ROW_END_CHARPOS (first_row_to_display)
17981 && first_row_to_display->ends_at_zv_p
17982 && pt_row == NULL)))
17983 pt_row = first_row_to_display;
17986 /* Start displaying at the start of first_row_to_display. */
17987 eassert (first_row_to_display->y < yb);
17988 init_to_row_start (&it, w, first_row_to_display);
17990 nrows_scrolled = (MATRIX_ROW_VPOS (first_reusable_row, w->current_matrix)
17991 - start_vpos);
17992 it.vpos = (MATRIX_ROW_VPOS (first_row_to_display, w->current_matrix)
17993 - nrows_scrolled);
17994 it.current_y = (first_row_to_display->y - first_reusable_row->y
17995 + WINDOW_HEADER_LINE_HEIGHT (w));
17997 /* Display lines beginning with first_row_to_display in the
17998 desired matrix. Set last_text_row to the last row displayed
17999 that displays text. */
18000 it.glyph_row = MATRIX_ROW (w->desired_matrix, it.vpos);
18001 if (pt_row == NULL)
18002 w->cursor.vpos = -1;
18003 last_text_row = NULL;
18004 while (it.current_y < it.last_visible_y && !f->fonts_changed)
18005 if (display_line (&it, w->cursor.vpos))
18006 last_text_row = it.glyph_row - 1;
18008 /* If point is in a reused row, adjust y and vpos of the cursor
18009 position. */
18010 if (pt_row)
18012 w->cursor.vpos -= nrows_scrolled;
18013 w->cursor.y -= first_reusable_row->y - start_row->y;
18016 /* Give up if point isn't in a row displayed or reused. (This
18017 also handles the case where w->cursor.vpos < nrows_scrolled
18018 after the calls to display_line, which can happen with scroll
18019 margins. See bug#1295.) */
18020 if (w->cursor.vpos < 0)
18022 clear_glyph_matrix (w->desired_matrix);
18023 return false;
18026 /* Scroll the display. */
18027 run.current_y = first_reusable_row->y;
18028 run.desired_y = WINDOW_HEADER_LINE_HEIGHT (w);
18029 run.height = it.last_visible_y - run.current_y;
18030 dy = run.current_y - run.desired_y;
18032 if (run.height)
18034 update_begin (f);
18035 FRAME_RIF (f)->update_window_begin_hook (w);
18036 FRAME_RIF (f)->clear_window_mouse_face (w);
18037 FRAME_RIF (f)->scroll_run_hook (w, &run);
18038 FRAME_RIF (f)->update_window_end_hook (w, false, false);
18039 update_end (f);
18042 /* Adjust Y positions of reused rows. */
18043 bottom_row = MATRIX_BOTTOM_TEXT_ROW (w->current_matrix, w);
18044 min_y = WINDOW_HEADER_LINE_HEIGHT (w);
18045 max_y = it.last_visible_y;
18046 for (row = first_reusable_row; row < first_row_to_display; ++row)
18048 row->y -= dy;
18049 row->visible_height = row->height;
18050 if (row->y < min_y)
18051 row->visible_height -= min_y - row->y;
18052 if (row->y + row->height > max_y)
18053 row->visible_height -= row->y + row->height - max_y;
18054 if (row->fringe_bitmap_periodic_p)
18055 row->redraw_fringe_bitmaps_p = true;
18058 /* Scroll the current matrix. */
18059 eassert (nrows_scrolled > 0);
18060 rotate_matrix (w->current_matrix,
18061 start_vpos,
18062 MATRIX_ROW_VPOS (bottom_row, w->current_matrix),
18063 -nrows_scrolled);
18065 /* Disable rows not reused. */
18066 for (row -= nrows_scrolled; row < bottom_row; ++row)
18067 row->enabled_p = false;
18069 /* Point may have moved to a different line, so we cannot assume that
18070 the previous cursor position is valid; locate the correct row. */
18071 if (pt_row)
18073 for (row = MATRIX_ROW (w->current_matrix, w->cursor.vpos);
18074 row < bottom_row
18075 && PT >= MATRIX_ROW_END_CHARPOS (row)
18076 && !row->ends_at_zv_p;
18077 row++)
18079 w->cursor.vpos++;
18080 w->cursor.y = row->y;
18082 if (row < bottom_row)
18084 /* Can't simply scan the row for point with
18085 bidi-reordered glyph rows. Let set_cursor_from_row
18086 figure out where to put the cursor, and if it fails,
18087 give up. */
18088 if (!NILP (BVAR (XBUFFER (w->contents), bidi_display_reordering)))
18090 if (!set_cursor_from_row (w, row, w->current_matrix,
18091 0, 0, 0, 0))
18093 clear_glyph_matrix (w->desired_matrix);
18094 return false;
18097 else
18099 struct glyph *glyph = row->glyphs[TEXT_AREA] + w->cursor.hpos;
18100 struct glyph *end = row->glyphs[TEXT_AREA] + row->used[TEXT_AREA];
18102 for (; glyph < end
18103 && (!BUFFERP (glyph->object)
18104 || glyph->charpos < PT);
18105 glyph++)
18107 w->cursor.hpos++;
18108 w->cursor.x += glyph->pixel_width;
18114 /* Adjust window end. A null value of last_text_row means that
18115 the window end is in reused rows which in turn means that
18116 only its vpos can have changed. */
18117 if (last_text_row)
18118 adjust_window_ends (w, last_text_row, false);
18119 else
18120 w->window_end_vpos -= nrows_scrolled;
18122 w->window_end_valid = false;
18123 w->desired_matrix->no_scrolling_p = true;
18125 #ifdef GLYPH_DEBUG
18126 debug_method_add (w, "try_window_reusing_current_matrix 2");
18127 #endif
18128 return true;
18131 return false;
18136 /************************************************************************
18137 Window redisplay reusing current matrix when buffer has changed
18138 ************************************************************************/
18140 static struct glyph_row *find_last_unchanged_at_beg_row (struct window *);
18141 static struct glyph_row *find_first_unchanged_at_end_row (struct window *,
18142 ptrdiff_t *, ptrdiff_t *);
18143 static struct glyph_row *
18144 find_last_row_displaying_text (struct glyph_matrix *, struct it *,
18145 struct glyph_row *);
18148 /* Return the last row in MATRIX displaying text. If row START is
18149 non-null, start searching with that row. IT gives the dimensions
18150 of the display. Value is null if matrix is empty; otherwise it is
18151 a pointer to the row found. */
18153 static struct glyph_row *
18154 find_last_row_displaying_text (struct glyph_matrix *matrix, struct it *it,
18155 struct glyph_row *start)
18157 struct glyph_row *row, *row_found;
18159 /* Set row_found to the last row in IT->w's current matrix
18160 displaying text. The loop looks funny but think of partially
18161 visible lines. */
18162 row_found = NULL;
18163 row = start ? start : MATRIX_FIRST_TEXT_ROW (matrix);
18164 while (MATRIX_ROW_DISPLAYS_TEXT_P (row))
18166 eassert (row->enabled_p);
18167 row_found = row;
18168 if (MATRIX_ROW_BOTTOM_Y (row) >= it->last_visible_y)
18169 break;
18170 ++row;
18173 return row_found;
18177 /* Return the last row in the current matrix of W that is not affected
18178 by changes at the start of current_buffer that occurred since W's
18179 current matrix was built. Value is null if no such row exists.
18181 BEG_UNCHANGED us the number of characters unchanged at the start of
18182 current_buffer. BEG + BEG_UNCHANGED is the buffer position of the
18183 first changed character in current_buffer. Characters at positions <
18184 BEG + BEG_UNCHANGED are at the same buffer positions as they were
18185 when the current matrix was built. */
18187 static struct glyph_row *
18188 find_last_unchanged_at_beg_row (struct window *w)
18190 ptrdiff_t first_changed_pos = BEG + BEG_UNCHANGED;
18191 struct glyph_row *row;
18192 struct glyph_row *row_found = NULL;
18193 int yb = window_text_bottom_y (w);
18195 /* Find the last row displaying unchanged text. */
18196 for (row = MATRIX_FIRST_TEXT_ROW (w->current_matrix);
18197 MATRIX_ROW_DISPLAYS_TEXT_P (row)
18198 && MATRIX_ROW_START_CHARPOS (row) < first_changed_pos;
18199 ++row)
18201 if (/* If row ends before first_changed_pos, it is unchanged,
18202 except in some case. */
18203 MATRIX_ROW_END_CHARPOS (row) <= first_changed_pos
18204 /* When row ends in ZV and we write at ZV it is not
18205 unchanged. */
18206 && !row->ends_at_zv_p
18207 /* When first_changed_pos is the end of a continued line,
18208 row is not unchanged because it may be no longer
18209 continued. */
18210 && !(MATRIX_ROW_END_CHARPOS (row) == first_changed_pos
18211 && (row->continued_p
18212 || row->exact_window_width_line_p))
18213 /* If ROW->end is beyond ZV, then ROW->end is outdated and
18214 needs to be recomputed, so don't consider this row as
18215 unchanged. This happens when the last line was
18216 bidi-reordered and was killed immediately before this
18217 redisplay cycle. In that case, ROW->end stores the
18218 buffer position of the first visual-order character of
18219 the killed text, which is now beyond ZV. */
18220 && CHARPOS (row->end.pos) <= ZV)
18221 row_found = row;
18223 /* Stop if last visible row. */
18224 if (MATRIX_ROW_BOTTOM_Y (row) >= yb)
18225 break;
18228 return row_found;
18232 /* Find the first glyph row in the current matrix of W that is not
18233 affected by changes at the end of current_buffer since the
18234 time W's current matrix was built.
18236 Return in *DELTA the number of chars by which buffer positions in
18237 unchanged text at the end of current_buffer must be adjusted.
18239 Return in *DELTA_BYTES the corresponding number of bytes.
18241 Value is null if no such row exists, i.e. all rows are affected by
18242 changes. */
18244 static struct glyph_row *
18245 find_first_unchanged_at_end_row (struct window *w,
18246 ptrdiff_t *delta, ptrdiff_t *delta_bytes)
18248 struct glyph_row *row;
18249 struct glyph_row *row_found = NULL;
18251 *delta = *delta_bytes = 0;
18253 /* Display must not have been paused, otherwise the current matrix
18254 is not up to date. */
18255 eassert (w->window_end_valid);
18257 /* A value of window_end_pos >= END_UNCHANGED means that the window
18258 end is in the range of changed text. If so, there is no
18259 unchanged row at the end of W's current matrix. */
18260 if (w->window_end_pos >= END_UNCHANGED)
18261 return NULL;
18263 /* Set row to the last row in W's current matrix displaying text. */
18264 row = MATRIX_ROW (w->current_matrix, w->window_end_vpos);
18266 /* If matrix is entirely empty, no unchanged row exists. */
18267 if (MATRIX_ROW_DISPLAYS_TEXT_P (row))
18269 /* The value of row is the last glyph row in the matrix having a
18270 meaningful buffer position in it. The end position of row
18271 corresponds to window_end_pos. This allows us to translate
18272 buffer positions in the current matrix to current buffer
18273 positions for characters not in changed text. */
18274 ptrdiff_t Z_old =
18275 MATRIX_ROW_END_CHARPOS (row) + w->window_end_pos;
18276 ptrdiff_t Z_BYTE_old =
18277 MATRIX_ROW_END_BYTEPOS (row) + w->window_end_bytepos;
18278 ptrdiff_t last_unchanged_pos, last_unchanged_pos_old;
18279 struct glyph_row *first_text_row
18280 = MATRIX_FIRST_TEXT_ROW (w->current_matrix);
18282 *delta = Z - Z_old;
18283 *delta_bytes = Z_BYTE - Z_BYTE_old;
18285 /* Set last_unchanged_pos to the buffer position of the last
18286 character in the buffer that has not been changed. Z is the
18287 index + 1 of the last character in current_buffer, i.e. by
18288 subtracting END_UNCHANGED we get the index of the last
18289 unchanged character, and we have to add BEG to get its buffer
18290 position. */
18291 last_unchanged_pos = Z - END_UNCHANGED + BEG;
18292 last_unchanged_pos_old = last_unchanged_pos - *delta;
18294 /* Search backward from ROW for a row displaying a line that
18295 starts at a minimum position >= last_unchanged_pos_old. */
18296 for (; row > first_text_row; --row)
18298 /* This used to abort, but it can happen.
18299 It is ok to just stop the search instead here. KFS. */
18300 if (!row->enabled_p || !MATRIX_ROW_DISPLAYS_TEXT_P (row))
18301 break;
18303 if (MATRIX_ROW_START_CHARPOS (row) >= last_unchanged_pos_old)
18304 row_found = row;
18308 eassert (!row_found || MATRIX_ROW_DISPLAYS_TEXT_P (row_found));
18310 return row_found;
18314 /* Make sure that glyph rows in the current matrix of window W
18315 reference the same glyph memory as corresponding rows in the
18316 frame's frame matrix. This function is called after scrolling W's
18317 current matrix on a terminal frame in try_window_id and
18318 try_window_reusing_current_matrix. */
18320 static void
18321 sync_frame_with_window_matrix_rows (struct window *w)
18323 struct frame *f = XFRAME (w->frame);
18324 struct glyph_row *window_row, *window_row_end, *frame_row;
18326 /* Preconditions: W must be a leaf window and full-width. Its frame
18327 must have a frame matrix. */
18328 eassert (BUFFERP (w->contents));
18329 eassert (WINDOW_FULL_WIDTH_P (w));
18330 eassert (!FRAME_WINDOW_P (f));
18332 /* If W is a full-width window, glyph pointers in W's current matrix
18333 have, by definition, to be the same as glyph pointers in the
18334 corresponding frame matrix. Note that frame matrices have no
18335 marginal areas (see build_frame_matrix). */
18336 window_row = w->current_matrix->rows;
18337 window_row_end = window_row + w->current_matrix->nrows;
18338 frame_row = f->current_matrix->rows + WINDOW_TOP_EDGE_LINE (w);
18339 while (window_row < window_row_end)
18341 struct glyph *start = window_row->glyphs[LEFT_MARGIN_AREA];
18342 struct glyph *end = window_row->glyphs[LAST_AREA];
18344 frame_row->glyphs[LEFT_MARGIN_AREA] = start;
18345 frame_row->glyphs[TEXT_AREA] = start;
18346 frame_row->glyphs[RIGHT_MARGIN_AREA] = end;
18347 frame_row->glyphs[LAST_AREA] = end;
18349 /* Disable frame rows whose corresponding window rows have
18350 been disabled in try_window_id. */
18351 if (!window_row->enabled_p)
18352 frame_row->enabled_p = false;
18354 ++window_row, ++frame_row;
18359 /* Find the glyph row in window W containing CHARPOS. Consider all
18360 rows between START and END (not inclusive). END null means search
18361 all rows to the end of the display area of W. Value is the row
18362 containing CHARPOS or null. */
18364 struct glyph_row *
18365 row_containing_pos (struct window *w, ptrdiff_t charpos,
18366 struct glyph_row *start, struct glyph_row *end, int dy)
18368 struct glyph_row *row = start;
18369 struct glyph_row *best_row = NULL;
18370 ptrdiff_t mindif = BUF_ZV (XBUFFER (w->contents)) + 1;
18371 int last_y;
18373 /* If we happen to start on a header-line, skip that. */
18374 if (row->mode_line_p)
18375 ++row;
18377 if ((end && row >= end) || !row->enabled_p)
18378 return NULL;
18380 last_y = window_text_bottom_y (w) - dy;
18382 while (true)
18384 /* Give up if we have gone too far. */
18385 if ((end && row >= end) || !row->enabled_p)
18386 return NULL;
18387 /* This formerly returned if they were equal.
18388 I think that both quantities are of a "last plus one" type;
18389 if so, when they are equal, the row is within the screen. -- rms. */
18390 if (MATRIX_ROW_BOTTOM_Y (row) > last_y)
18391 return NULL;
18393 /* If it is in this row, return this row. */
18394 if (! (MATRIX_ROW_END_CHARPOS (row) < charpos
18395 || (MATRIX_ROW_END_CHARPOS (row) == charpos
18396 /* The end position of a row equals the start
18397 position of the next row. If CHARPOS is there, we
18398 would rather consider it displayed in the next
18399 line, except when this line ends in ZV. */
18400 && !row_for_charpos_p (row, charpos)))
18401 && charpos >= MATRIX_ROW_START_CHARPOS (row))
18403 struct glyph *g;
18405 if (NILP (BVAR (XBUFFER (w->contents), bidi_display_reordering))
18406 || (!best_row && !row->continued_p))
18407 return row;
18408 /* In bidi-reordered rows, there could be several rows whose
18409 edges surround CHARPOS, all of these rows belonging to
18410 the same continued line. We need to find the row which
18411 fits CHARPOS the best. */
18412 for (g = row->glyphs[TEXT_AREA];
18413 g < row->glyphs[TEXT_AREA] + row->used[TEXT_AREA];
18414 g++)
18416 if (!STRINGP (g->object))
18418 if (g->charpos > 0 && eabs (g->charpos - charpos) < mindif)
18420 mindif = eabs (g->charpos - charpos);
18421 best_row = row;
18422 /* Exact match always wins. */
18423 if (mindif == 0)
18424 return best_row;
18429 else if (best_row && !row->continued_p)
18430 return best_row;
18431 ++row;
18436 /* Try to redisplay window W by reusing its existing display. W's
18437 current matrix must be up to date when this function is called,
18438 i.e., window_end_valid must be true.
18440 Value is
18442 >= 1 if successful, i.e. display has been updated
18443 specifically:
18444 1 means the changes were in front of a newline that precedes
18445 the window start, and the whole current matrix was reused
18446 2 means the changes were after the last position displayed
18447 in the window, and the whole current matrix was reused
18448 3 means portions of the current matrix were reused, while
18449 some of the screen lines were redrawn
18450 -1 if redisplay with same window start is known not to succeed
18451 0 if otherwise unsuccessful
18453 The following steps are performed:
18455 1. Find the last row in the current matrix of W that is not
18456 affected by changes at the start of current_buffer. If no such row
18457 is found, give up.
18459 2. Find the first row in W's current matrix that is not affected by
18460 changes at the end of current_buffer. Maybe there is no such row.
18462 3. Display lines beginning with the row + 1 found in step 1 to the
18463 row found in step 2 or, if step 2 didn't find a row, to the end of
18464 the window.
18466 4. If cursor is not known to appear on the window, give up.
18468 5. If display stopped at the row found in step 2, scroll the
18469 display and current matrix as needed.
18471 6. Maybe display some lines at the end of W, if we must. This can
18472 happen under various circumstances, like a partially visible line
18473 becoming fully visible, or because newly displayed lines are displayed
18474 in smaller font sizes.
18476 7. Update W's window end information. */
18478 static int
18479 try_window_id (struct window *w)
18481 struct frame *f = XFRAME (w->frame);
18482 struct glyph_matrix *current_matrix = w->current_matrix;
18483 struct glyph_matrix *desired_matrix = w->desired_matrix;
18484 struct glyph_row *last_unchanged_at_beg_row;
18485 struct glyph_row *first_unchanged_at_end_row;
18486 struct glyph_row *row;
18487 struct glyph_row *bottom_row;
18488 int bottom_vpos;
18489 struct it it;
18490 ptrdiff_t delta = 0, delta_bytes = 0, stop_pos;
18491 int dvpos, dy;
18492 struct text_pos start_pos;
18493 struct run run;
18494 int first_unchanged_at_end_vpos = 0;
18495 struct glyph_row *last_text_row, *last_text_row_at_end;
18496 struct text_pos start;
18497 ptrdiff_t first_changed_charpos, last_changed_charpos;
18499 #ifdef GLYPH_DEBUG
18500 if (inhibit_try_window_id)
18501 return 0;
18502 #endif
18504 /* This is handy for debugging. */
18505 #if false
18506 #define GIVE_UP(X) \
18507 do { \
18508 TRACE ((stderr, "try_window_id give up %d\n", (X))); \
18509 return 0; \
18510 } while (false)
18511 #else
18512 #define GIVE_UP(X) return 0
18513 #endif
18515 SET_TEXT_POS_FROM_MARKER (start, w->start);
18517 /* Don't use this for mini-windows because these can show
18518 messages and mini-buffers, and we don't handle that here. */
18519 if (MINI_WINDOW_P (w))
18520 GIVE_UP (1);
18522 /* This flag is used to prevent redisplay optimizations. */
18523 if (windows_or_buffers_changed || f->cursor_type_changed)
18524 GIVE_UP (2);
18526 /* This function's optimizations cannot be used if overlays have
18527 changed in the buffer displayed by the window, so give up if they
18528 have. */
18529 if (w->last_overlay_modified != OVERLAY_MODIFF)
18530 GIVE_UP (200);
18532 /* Verify that narrowing has not changed.
18533 Also verify that we were not told to prevent redisplay optimizations.
18534 It would be nice to further
18535 reduce the number of cases where this prevents try_window_id. */
18536 if (current_buffer->clip_changed
18537 || current_buffer->prevent_redisplay_optimizations_p)
18538 GIVE_UP (3);
18540 /* Window must either use window-based redisplay or be full width. */
18541 if (!FRAME_WINDOW_P (f)
18542 && (!FRAME_LINE_INS_DEL_OK (f)
18543 || !WINDOW_FULL_WIDTH_P (w)))
18544 GIVE_UP (4);
18546 /* Give up if point is known NOT to appear in W. */
18547 if (PT < CHARPOS (start))
18548 GIVE_UP (5);
18550 /* Another way to prevent redisplay optimizations. */
18551 if (w->last_modified == 0)
18552 GIVE_UP (6);
18554 /* Verify that window is not hscrolled. */
18555 if (w->hscroll != 0)
18556 GIVE_UP (7);
18558 /* Verify that display wasn't paused. */
18559 if (!w->window_end_valid)
18560 GIVE_UP (8);
18562 /* Likewise if highlighting trailing whitespace. */
18563 if (!NILP (Vshow_trailing_whitespace))
18564 GIVE_UP (11);
18566 /* Can't use this if overlay arrow position and/or string have
18567 changed. */
18568 if (overlay_arrows_changed_p (false))
18569 GIVE_UP (12);
18571 /* When word-wrap is on, adding a space to the first word of a
18572 wrapped line can change the wrap position, altering the line
18573 above it. It might be worthwhile to handle this more
18574 intelligently, but for now just redisplay from scratch. */
18575 if (!NILP (BVAR (XBUFFER (w->contents), word_wrap)))
18576 GIVE_UP (21);
18578 /* Under bidi reordering, adding or deleting a character in the
18579 beginning of a paragraph, before the first strong directional
18580 character, can change the base direction of the paragraph (unless
18581 the buffer specifies a fixed paragraph direction), which will
18582 require redisplaying the whole paragraph. It might be worthwhile
18583 to find the paragraph limits and widen the range of redisplayed
18584 lines to that, but for now just give up this optimization and
18585 redisplay from scratch. */
18586 if (!NILP (BVAR (XBUFFER (w->contents), bidi_display_reordering))
18587 && NILP (BVAR (XBUFFER (w->contents), bidi_paragraph_direction)))
18588 GIVE_UP (22);
18590 /* Give up if the buffer has line-spacing set, as Lisp-level changes
18591 to that variable require thorough redisplay. */
18592 if (!NILP (BVAR (XBUFFER (w->contents), extra_line_spacing)))
18593 GIVE_UP (23);
18595 /* Give up if display-line-numbers is in relative mode, or when the
18596 current line's number needs to be displayed in a distinct face. */
18597 if (EQ (Vdisplay_line_numbers, Qrelative)
18598 || EQ (Vdisplay_line_numbers, Qvisual)
18599 || (!NILP (Vdisplay_line_numbers)
18600 && NILP (Finternal_lisp_face_equal_p (Qline_number,
18601 Qline_number_current_line,
18602 w->frame))))
18603 GIVE_UP (24);
18605 /* Make sure beg_unchanged and end_unchanged are up to date. Do it
18606 only if buffer has really changed. The reason is that the gap is
18607 initially at Z for freshly visited files. The code below would
18608 set end_unchanged to 0 in that case. */
18609 if (MODIFF > SAVE_MODIFF
18610 /* This seems to happen sometimes after saving a buffer. */
18611 || BEG_UNCHANGED + END_UNCHANGED > Z_BYTE)
18613 if (GPT - BEG < BEG_UNCHANGED)
18614 BEG_UNCHANGED = GPT - BEG;
18615 if (Z - GPT < END_UNCHANGED)
18616 END_UNCHANGED = Z - GPT;
18619 /* The position of the first and last character that has been changed. */
18620 first_changed_charpos = BEG + BEG_UNCHANGED;
18621 last_changed_charpos = Z - END_UNCHANGED;
18623 /* If window starts after a line end, and the last change is in
18624 front of that newline, then changes don't affect the display.
18625 This case happens with stealth-fontification. Note that although
18626 the display is unchanged, glyph positions in the matrix have to
18627 be adjusted, of course. */
18628 row = MATRIX_ROW (w->current_matrix, w->window_end_vpos);
18629 if (MATRIX_ROW_DISPLAYS_TEXT_P (row)
18630 && ((last_changed_charpos < CHARPOS (start)
18631 && CHARPOS (start) == BEGV)
18632 || (last_changed_charpos < CHARPOS (start) - 1
18633 && FETCH_BYTE (BYTEPOS (start) - 1) == '\n')))
18635 ptrdiff_t Z_old, Z_delta, Z_BYTE_old, Z_delta_bytes;
18636 struct glyph_row *r0;
18638 /* Compute how many chars/bytes have been added to or removed
18639 from the buffer. */
18640 Z_old = MATRIX_ROW_END_CHARPOS (row) + w->window_end_pos;
18641 Z_BYTE_old = MATRIX_ROW_END_BYTEPOS (row) + w->window_end_bytepos;
18642 Z_delta = Z - Z_old;
18643 Z_delta_bytes = Z_BYTE - Z_BYTE_old;
18645 /* Give up if PT is not in the window. Note that it already has
18646 been checked at the start of try_window_id that PT is not in
18647 front of the window start. */
18648 if (PT >= MATRIX_ROW_END_CHARPOS (row) + Z_delta)
18649 GIVE_UP (13);
18651 /* If window start is unchanged, we can reuse the whole matrix
18652 as is, after adjusting glyph positions. No need to compute
18653 the window end again, since its offset from Z hasn't changed. */
18654 r0 = MATRIX_FIRST_TEXT_ROW (current_matrix);
18655 if (CHARPOS (start) == MATRIX_ROW_START_CHARPOS (r0) + Z_delta
18656 && BYTEPOS (start) == MATRIX_ROW_START_BYTEPOS (r0) + Z_delta_bytes
18657 /* PT must not be in a partially visible line. */
18658 && !(PT >= MATRIX_ROW_START_CHARPOS (row) + Z_delta
18659 && MATRIX_ROW_BOTTOM_Y (row) > window_text_bottom_y (w)))
18661 /* Adjust positions in the glyph matrix. */
18662 if (Z_delta || Z_delta_bytes)
18664 struct glyph_row *r1
18665 = MATRIX_BOTTOM_TEXT_ROW (current_matrix, w);
18666 increment_matrix_positions (w->current_matrix,
18667 MATRIX_ROW_VPOS (r0, current_matrix),
18668 MATRIX_ROW_VPOS (r1, current_matrix),
18669 Z_delta, Z_delta_bytes);
18672 /* Set the cursor. */
18673 row = row_containing_pos (w, PT, r0, NULL, 0);
18674 if (row)
18675 set_cursor_from_row (w, row, current_matrix, 0, 0, 0, 0);
18676 return 1;
18680 /* Handle the case that changes are all below what is displayed in
18681 the window, and that PT is in the window. This shortcut cannot
18682 be taken if ZV is visible in the window, and text has been added
18683 there that is visible in the window. */
18684 if (first_changed_charpos >= MATRIX_ROW_END_CHARPOS (row)
18685 /* ZV is not visible in the window, or there are no
18686 changes at ZV, actually. */
18687 && (current_matrix->zv > MATRIX_ROW_END_CHARPOS (row)
18688 || first_changed_charpos == last_changed_charpos))
18690 struct glyph_row *r0;
18692 /* Give up if PT is not in the window. Note that it already has
18693 been checked at the start of try_window_id that PT is not in
18694 front of the window start. */
18695 if (PT >= MATRIX_ROW_END_CHARPOS (row))
18696 GIVE_UP (14);
18698 /* If window start is unchanged, we can reuse the whole matrix
18699 as is, without changing glyph positions since no text has
18700 been added/removed in front of the window end. */
18701 r0 = MATRIX_FIRST_TEXT_ROW (current_matrix);
18702 if (TEXT_POS_EQUAL_P (start, r0->minpos)
18703 /* PT must not be in a partially visible line. */
18704 && !(PT >= MATRIX_ROW_START_CHARPOS (row)
18705 && MATRIX_ROW_BOTTOM_Y (row) > window_text_bottom_y (w)))
18707 /* We have to compute the window end anew since text
18708 could have been added/removed after it. */
18709 w->window_end_pos = Z - MATRIX_ROW_END_CHARPOS (row);
18710 w->window_end_bytepos = Z_BYTE - MATRIX_ROW_END_BYTEPOS (row);
18712 /* Set the cursor. */
18713 row = row_containing_pos (w, PT, r0, NULL, 0);
18714 if (row)
18715 set_cursor_from_row (w, row, current_matrix, 0, 0, 0, 0);
18716 return 2;
18720 /* Give up if window start is in the changed area.
18722 The condition used to read
18724 (BEG_UNCHANGED + END_UNCHANGED != Z - BEG && ...)
18726 but why that was tested escapes me at the moment. */
18727 if (CHARPOS (start) >= first_changed_charpos
18728 && CHARPOS (start) <= last_changed_charpos)
18729 GIVE_UP (15);
18731 /* Check that window start agrees with the start of the first glyph
18732 row in its current matrix. Check this after we know the window
18733 start is not in changed text, otherwise positions would not be
18734 comparable. */
18735 row = MATRIX_FIRST_TEXT_ROW (current_matrix);
18736 if (!TEXT_POS_EQUAL_P (start, row->minpos))
18737 GIVE_UP (16);
18739 /* Give up if the window ends in strings. Overlay strings
18740 at the end are difficult to handle, so don't try. */
18741 row = MATRIX_ROW (current_matrix, w->window_end_vpos);
18742 if (MATRIX_ROW_START_CHARPOS (row) == MATRIX_ROW_END_CHARPOS (row))
18743 GIVE_UP (20);
18745 /* Compute the position at which we have to start displaying new
18746 lines. Some of the lines at the top of the window might be
18747 reusable because they are not displaying changed text. Find the
18748 last row in W's current matrix not affected by changes at the
18749 start of current_buffer. Value is null if changes start in the
18750 first line of window. */
18751 last_unchanged_at_beg_row = find_last_unchanged_at_beg_row (w);
18752 if (last_unchanged_at_beg_row)
18754 /* Avoid starting to display in the middle of a character, a TAB
18755 for instance. This is easier than to set up the iterator
18756 exactly, and it's not a frequent case, so the additional
18757 effort wouldn't really pay off. */
18758 while ((MATRIX_ROW_ENDS_IN_MIDDLE_OF_CHAR_P (last_unchanged_at_beg_row)
18759 || last_unchanged_at_beg_row->ends_in_newline_from_string_p)
18760 && last_unchanged_at_beg_row > w->current_matrix->rows)
18761 --last_unchanged_at_beg_row;
18763 if (MATRIX_ROW_ENDS_IN_MIDDLE_OF_CHAR_P (last_unchanged_at_beg_row))
18764 GIVE_UP (17);
18766 if (! init_to_row_end (&it, w, last_unchanged_at_beg_row))
18767 GIVE_UP (18);
18768 start_pos = it.current.pos;
18770 /* Start displaying new lines in the desired matrix at the same
18771 vpos we would use in the current matrix, i.e. below
18772 last_unchanged_at_beg_row. */
18773 it.vpos = 1 + MATRIX_ROW_VPOS (last_unchanged_at_beg_row,
18774 current_matrix);
18775 it.glyph_row = MATRIX_ROW (desired_matrix, it.vpos);
18776 it.current_y = MATRIX_ROW_BOTTOM_Y (last_unchanged_at_beg_row);
18778 eassert (it.hpos == 0 && it.current_x == 0);
18780 else
18782 /* There are no reusable lines at the start of the window.
18783 Start displaying in the first text line. */
18784 start_display (&it, w, start);
18785 it.vpos = it.first_vpos;
18786 start_pos = it.current.pos;
18789 /* Find the first row that is not affected by changes at the end of
18790 the buffer. Value will be null if there is no unchanged row, in
18791 which case we must redisplay to the end of the window. delta
18792 will be set to the value by which buffer positions beginning with
18793 first_unchanged_at_end_row have to be adjusted due to text
18794 changes. */
18795 first_unchanged_at_end_row
18796 = find_first_unchanged_at_end_row (w, &delta, &delta_bytes);
18797 IF_DEBUG (debug_delta = delta);
18798 IF_DEBUG (debug_delta_bytes = delta_bytes);
18800 /* Set stop_pos to the buffer position up to which we will have to
18801 display new lines. If first_unchanged_at_end_row != NULL, this
18802 is the buffer position of the start of the line displayed in that
18803 row. For first_unchanged_at_end_row == NULL, use 0 to indicate
18804 that we don't stop at a buffer position. */
18805 stop_pos = 0;
18806 if (first_unchanged_at_end_row)
18808 eassert (last_unchanged_at_beg_row == NULL
18809 || first_unchanged_at_end_row >= last_unchanged_at_beg_row);
18811 /* If this is a continuation line, move forward to the next one
18812 that isn't. Changes in lines above affect this line.
18813 Caution: this may move first_unchanged_at_end_row to a row
18814 not displaying text. */
18815 while (MATRIX_ROW_CONTINUATION_LINE_P (first_unchanged_at_end_row)
18816 && MATRIX_ROW_DISPLAYS_TEXT_P (first_unchanged_at_end_row)
18817 && (MATRIX_ROW_BOTTOM_Y (first_unchanged_at_end_row)
18818 < it.last_visible_y))
18819 ++first_unchanged_at_end_row;
18821 if (!MATRIX_ROW_DISPLAYS_TEXT_P (first_unchanged_at_end_row)
18822 || (MATRIX_ROW_BOTTOM_Y (first_unchanged_at_end_row)
18823 >= it.last_visible_y))
18824 first_unchanged_at_end_row = NULL;
18825 else
18827 stop_pos = (MATRIX_ROW_START_CHARPOS (first_unchanged_at_end_row)
18828 + delta);
18829 first_unchanged_at_end_vpos
18830 = MATRIX_ROW_VPOS (first_unchanged_at_end_row, current_matrix);
18831 eassert (stop_pos >= Z - END_UNCHANGED);
18834 else if (last_unchanged_at_beg_row == NULL)
18835 GIVE_UP (19);
18838 #ifdef GLYPH_DEBUG
18840 /* Either there is no unchanged row at the end, or the one we have
18841 now displays text. This is a necessary condition for the window
18842 end pos calculation at the end of this function. */
18843 eassert (first_unchanged_at_end_row == NULL
18844 || MATRIX_ROW_DISPLAYS_TEXT_P (first_unchanged_at_end_row));
18846 debug_last_unchanged_at_beg_vpos
18847 = (last_unchanged_at_beg_row
18848 ? MATRIX_ROW_VPOS (last_unchanged_at_beg_row, current_matrix)
18849 : -1);
18850 debug_first_unchanged_at_end_vpos = first_unchanged_at_end_vpos;
18852 #endif /* GLYPH_DEBUG */
18855 /* Display new lines. Set last_text_row to the last new line
18856 displayed which has text on it, i.e. might end up as being the
18857 line where the window_end_vpos is. */
18858 w->cursor.vpos = -1;
18859 last_text_row = NULL;
18860 overlay_arrow_seen = false;
18861 if (it.current_y < it.last_visible_y
18862 && !f->fonts_changed
18863 && (first_unchanged_at_end_row == NULL
18864 || IT_CHARPOS (it) < stop_pos))
18865 it.glyph_row->reversed_p = false;
18866 while (it.current_y < it.last_visible_y
18867 && !f->fonts_changed
18868 && (first_unchanged_at_end_row == NULL
18869 || IT_CHARPOS (it) < stop_pos))
18871 if (display_line (&it, -1))
18872 last_text_row = it.glyph_row - 1;
18875 if (f->fonts_changed)
18876 return -1;
18878 /* The redisplay iterations in display_line above could have
18879 triggered font-lock, which could have done something that
18880 invalidates IT->w window's end-point information, on which we
18881 rely below. E.g., one package, which will remain unnamed, used
18882 to install a font-lock-fontify-region-function that called
18883 bury-buffer, whose side effect is to switch the buffer displayed
18884 by IT->w, and that predictably resets IT->w's window_end_valid
18885 flag, which we already tested at the entry to this function.
18886 Amply punish such packages/modes by giving up on this
18887 optimization in those cases. */
18888 if (!w->window_end_valid)
18890 clear_glyph_matrix (w->desired_matrix);
18891 return -1;
18894 /* Compute differences in buffer positions, y-positions etc. for
18895 lines reused at the bottom of the window. Compute what we can
18896 scroll. */
18897 if (first_unchanged_at_end_row
18898 /* No lines reused because we displayed everything up to the
18899 bottom of the window. */
18900 && it.current_y < it.last_visible_y)
18902 dvpos = (it.vpos
18903 - MATRIX_ROW_VPOS (first_unchanged_at_end_row,
18904 current_matrix));
18905 dy = it.current_y - first_unchanged_at_end_row->y;
18906 run.current_y = first_unchanged_at_end_row->y;
18907 run.desired_y = run.current_y + dy;
18908 run.height = it.last_visible_y - max (run.current_y, run.desired_y);
18910 else
18912 delta = delta_bytes = dvpos = dy
18913 = run.current_y = run.desired_y = run.height = 0;
18914 first_unchanged_at_end_row = NULL;
18916 IF_DEBUG ((debug_dvpos = dvpos, debug_dy = dy));
18919 /* Find the cursor if not already found. We have to decide whether
18920 PT will appear on this window (it sometimes doesn't, but this is
18921 not a very frequent case.) This decision has to be made before
18922 the current matrix is altered. A value of cursor.vpos < 0 means
18923 that PT is either in one of the lines beginning at
18924 first_unchanged_at_end_row or below the window. Don't care for
18925 lines that might be displayed later at the window end; as
18926 mentioned, this is not a frequent case. */
18927 if (w->cursor.vpos < 0)
18929 /* Cursor in unchanged rows at the top? */
18930 if (PT < CHARPOS (start_pos)
18931 && last_unchanged_at_beg_row)
18933 row = row_containing_pos (w, PT,
18934 MATRIX_FIRST_TEXT_ROW (w->current_matrix),
18935 last_unchanged_at_beg_row + 1, 0);
18936 if (row)
18937 set_cursor_from_row (w, row, w->current_matrix, 0, 0, 0, 0);
18940 /* Start from first_unchanged_at_end_row looking for PT. */
18941 else if (first_unchanged_at_end_row)
18943 row = row_containing_pos (w, PT - delta,
18944 first_unchanged_at_end_row, NULL, 0);
18945 if (row)
18946 set_cursor_from_row (w, row, w->current_matrix, delta,
18947 delta_bytes, dy, dvpos);
18950 /* Give up if cursor was not found. */
18951 if (w->cursor.vpos < 0)
18953 clear_glyph_matrix (w->desired_matrix);
18954 return -1;
18958 /* Don't let the cursor end in the scroll margins. */
18960 int this_scroll_margin = window_scroll_margin (w, MARGIN_IN_PIXELS);
18961 int cursor_height = MATRIX_ROW (w->desired_matrix, w->cursor.vpos)->height;
18963 if ((w->cursor.y < this_scroll_margin
18964 && CHARPOS (start) > BEGV)
18965 /* Old redisplay didn't take scroll margin into account at the bottom,
18966 but then global-hl-line-mode doesn't scroll. KFS 2004-06-14 */
18967 || (w->cursor.y + (make_cursor_line_fully_visible_p
18968 ? cursor_height + this_scroll_margin
18969 : 1)) > it.last_visible_y)
18971 w->cursor.vpos = -1;
18972 clear_glyph_matrix (w->desired_matrix);
18973 return -1;
18977 /* Scroll the display. Do it before changing the current matrix so
18978 that xterm.c doesn't get confused about where the cursor glyph is
18979 found. */
18980 if (dy && run.height)
18982 update_begin (f);
18984 if (FRAME_WINDOW_P (f))
18986 FRAME_RIF (f)->update_window_begin_hook (w);
18987 FRAME_RIF (f)->clear_window_mouse_face (w);
18988 FRAME_RIF (f)->scroll_run_hook (w, &run);
18989 FRAME_RIF (f)->update_window_end_hook (w, false, false);
18991 else
18993 /* Terminal frame. In this case, dvpos gives the number of
18994 lines to scroll by; dvpos < 0 means scroll up. */
18995 int from_vpos
18996 = MATRIX_ROW_VPOS (first_unchanged_at_end_row, w->current_matrix);
18997 int from = WINDOW_TOP_EDGE_LINE (w) + from_vpos;
18998 int end = (WINDOW_TOP_EDGE_LINE (w)
18999 + window_wants_header_line (w)
19000 + window_internal_height (w));
19002 #if defined (HAVE_GPM) || defined (MSDOS)
19003 x_clear_window_mouse_face (w);
19004 #endif
19005 /* Perform the operation on the screen. */
19006 if (dvpos > 0)
19008 /* Scroll last_unchanged_at_beg_row to the end of the
19009 window down dvpos lines. */
19010 set_terminal_window (f, end);
19012 /* On dumb terminals delete dvpos lines at the end
19013 before inserting dvpos empty lines. */
19014 if (!FRAME_SCROLL_REGION_OK (f))
19015 ins_del_lines (f, end - dvpos, -dvpos);
19017 /* Insert dvpos empty lines in front of
19018 last_unchanged_at_beg_row. */
19019 ins_del_lines (f, from, dvpos);
19021 else if (dvpos < 0)
19023 /* Scroll up last_unchanged_at_beg_vpos to the end of
19024 the window to last_unchanged_at_beg_vpos - |dvpos|. */
19025 set_terminal_window (f, end);
19027 /* Delete dvpos lines in front of
19028 last_unchanged_at_beg_vpos. ins_del_lines will set
19029 the cursor to the given vpos and emit |dvpos| delete
19030 line sequences. */
19031 ins_del_lines (f, from + dvpos, dvpos);
19033 /* On a dumb terminal insert dvpos empty lines at the
19034 end. */
19035 if (!FRAME_SCROLL_REGION_OK (f))
19036 ins_del_lines (f, end + dvpos, -dvpos);
19039 set_terminal_window (f, 0);
19042 update_end (f);
19045 /* Shift reused rows of the current matrix to the right position.
19046 BOTTOM_ROW is the last + 1 row in the current matrix reserved for
19047 text. */
19048 bottom_row = MATRIX_BOTTOM_TEXT_ROW (current_matrix, w);
19049 bottom_vpos = MATRIX_ROW_VPOS (bottom_row, current_matrix);
19050 if (dvpos < 0)
19052 rotate_matrix (current_matrix, first_unchanged_at_end_vpos + dvpos,
19053 bottom_vpos, dvpos);
19054 clear_glyph_matrix_rows (current_matrix, bottom_vpos + dvpos,
19055 bottom_vpos);
19057 else if (dvpos > 0)
19059 rotate_matrix (current_matrix, first_unchanged_at_end_vpos,
19060 bottom_vpos, dvpos);
19061 clear_glyph_matrix_rows (current_matrix, first_unchanged_at_end_vpos,
19062 first_unchanged_at_end_vpos + dvpos);
19065 /* For frame-based redisplay, make sure that current frame and window
19066 matrix are in sync with respect to glyph memory. */
19067 if (!FRAME_WINDOW_P (f))
19068 sync_frame_with_window_matrix_rows (w);
19070 /* Adjust buffer positions in reused rows. */
19071 if (delta || delta_bytes)
19072 increment_matrix_positions (current_matrix,
19073 first_unchanged_at_end_vpos + dvpos,
19074 bottom_vpos, delta, delta_bytes);
19076 /* Adjust Y positions. */
19077 if (dy)
19078 shift_glyph_matrix (w, current_matrix,
19079 first_unchanged_at_end_vpos + dvpos,
19080 bottom_vpos, dy);
19082 if (first_unchanged_at_end_row)
19084 first_unchanged_at_end_row += dvpos;
19085 if (first_unchanged_at_end_row->y >= it.last_visible_y
19086 || !MATRIX_ROW_DISPLAYS_TEXT_P (first_unchanged_at_end_row))
19087 first_unchanged_at_end_row = NULL;
19090 /* If scrolling up, there may be some lines to display at the end of
19091 the window. */
19092 last_text_row_at_end = NULL;
19093 if (dy < 0)
19095 /* Scrolling up can leave for example a partially visible line
19096 at the end of the window to be redisplayed. */
19097 /* Set last_row to the glyph row in the current matrix where the
19098 window end line is found. It has been moved up or down in
19099 the matrix by dvpos. */
19100 int last_vpos = w->window_end_vpos + dvpos;
19101 struct glyph_row *last_row = MATRIX_ROW (current_matrix, last_vpos);
19103 /* If last_row is the window end line, it should display text. */
19104 eassert (MATRIX_ROW_DISPLAYS_TEXT_P (last_row));
19106 /* If window end line was partially visible before, begin
19107 displaying at that line. Otherwise begin displaying with the
19108 line following it. */
19109 if (MATRIX_ROW_BOTTOM_Y (last_row) - dy >= it.last_visible_y)
19111 init_to_row_start (&it, w, last_row);
19112 it.vpos = last_vpos;
19113 it.current_y = last_row->y;
19115 else
19117 init_to_row_end (&it, w, last_row);
19118 it.vpos = 1 + last_vpos;
19119 it.current_y = MATRIX_ROW_BOTTOM_Y (last_row);
19120 ++last_row;
19123 /* We may start in a continuation line. If so, we have to
19124 get the right continuation_lines_width and current_x. */
19125 it.continuation_lines_width = last_row->continuation_lines_width;
19126 it.hpos = it.current_x = 0;
19128 /* Display the rest of the lines at the window end. */
19129 it.glyph_row = MATRIX_ROW (desired_matrix, it.vpos);
19130 while (it.current_y < it.last_visible_y && !f->fonts_changed)
19132 /* Is it always sure that the display agrees with lines in
19133 the current matrix? I don't think so, so we mark rows
19134 displayed invalid in the current matrix by setting their
19135 enabled_p flag to false. */
19136 SET_MATRIX_ROW_ENABLED_P (w->current_matrix, it.vpos, false);
19137 if (display_line (&it, w->cursor.vpos))
19138 last_text_row_at_end = it.glyph_row - 1;
19142 /* Update window_end_pos and window_end_vpos. */
19143 if (first_unchanged_at_end_row && !last_text_row_at_end)
19145 /* Window end line if one of the preserved rows from the current
19146 matrix. Set row to the last row displaying text in current
19147 matrix starting at first_unchanged_at_end_row, after
19148 scrolling. */
19149 eassert (MATRIX_ROW_DISPLAYS_TEXT_P (first_unchanged_at_end_row));
19150 row = find_last_row_displaying_text (w->current_matrix, &it,
19151 first_unchanged_at_end_row);
19152 eassume (row && MATRIX_ROW_DISPLAYS_TEXT_P (row));
19153 adjust_window_ends (w, row, true);
19154 eassert (w->window_end_bytepos >= 0);
19155 IF_DEBUG (debug_method_add (w, "A"));
19157 else if (last_text_row_at_end)
19159 adjust_window_ends (w, last_text_row_at_end, false);
19160 eassert (w->window_end_bytepos >= 0);
19161 IF_DEBUG (debug_method_add (w, "B"));
19163 else if (last_text_row)
19165 /* We have displayed either to the end of the window or at the
19166 end of the window, i.e. the last row with text is to be found
19167 in the desired matrix. */
19168 adjust_window_ends (w, last_text_row, false);
19169 eassert (w->window_end_bytepos >= 0);
19171 else if (first_unchanged_at_end_row == NULL
19172 && last_text_row == NULL
19173 && last_text_row_at_end == NULL)
19175 /* Displayed to end of window, but no line containing text was
19176 displayed. Lines were deleted at the end of the window. */
19177 bool first_vpos = window_wants_header_line (w);
19178 int vpos = w->window_end_vpos;
19179 struct glyph_row *current_row = current_matrix->rows + vpos;
19180 struct glyph_row *desired_row = desired_matrix->rows + vpos;
19182 for (row = NULL; !row; --vpos, --current_row, --desired_row)
19184 eassert (first_vpos <= vpos);
19185 if (desired_row->enabled_p)
19187 if (MATRIX_ROW_DISPLAYS_TEXT_P (desired_row))
19188 row = desired_row;
19190 else if (MATRIX_ROW_DISPLAYS_TEXT_P (current_row))
19191 row = current_row;
19194 w->window_end_vpos = vpos + 1;
19195 w->window_end_pos = Z - MATRIX_ROW_END_CHARPOS (row);
19196 w->window_end_bytepos = Z_BYTE - MATRIX_ROW_END_BYTEPOS (row);
19197 eassert (w->window_end_bytepos >= 0);
19198 IF_DEBUG (debug_method_add (w, "C"));
19200 else
19201 emacs_abort ();
19203 IF_DEBUG ((debug_end_pos = w->window_end_pos,
19204 debug_end_vpos = w->window_end_vpos));
19206 /* Record that display has not been completed. */
19207 w->window_end_valid = false;
19208 w->desired_matrix->no_scrolling_p = true;
19209 return 3;
19211 #undef GIVE_UP
19216 /***********************************************************************
19217 More debugging support
19218 ***********************************************************************/
19220 #ifdef GLYPH_DEBUG
19222 void dump_glyph_row (struct glyph_row *, int, int) EXTERNALLY_VISIBLE;
19223 void dump_glyph_matrix (struct glyph_matrix *, int) EXTERNALLY_VISIBLE;
19224 void dump_glyph (struct glyph_row *, struct glyph *, int) EXTERNALLY_VISIBLE;
19227 /* Dump the contents of glyph matrix MATRIX on stderr.
19229 GLYPHS 0 means don't show glyph contents.
19230 GLYPHS 1 means show glyphs in short form
19231 GLYPHS > 1 means show glyphs in long form. */
19233 void
19234 dump_glyph_matrix (struct glyph_matrix *matrix, int glyphs)
19236 int i;
19237 for (i = 0; i < matrix->nrows; ++i)
19238 dump_glyph_row (MATRIX_ROW (matrix, i), i, glyphs);
19242 /* Dump contents of glyph GLYPH to stderr. ROW and AREA are
19243 the glyph row and area where the glyph comes from. */
19245 void
19246 dump_glyph (struct glyph_row *row, struct glyph *glyph, int area)
19248 if (glyph->type == CHAR_GLYPH
19249 || glyph->type == GLYPHLESS_GLYPH)
19251 fprintf (stderr,
19252 " %5"pD"d %c %9"pD"d %c %3d 0x%06x %c %4d %1.1d%1.1d\n",
19253 glyph - row->glyphs[TEXT_AREA],
19254 (glyph->type == CHAR_GLYPH
19255 ? 'C'
19256 : 'G'),
19257 glyph->charpos,
19258 (BUFFERP (glyph->object)
19259 ? 'B'
19260 : (STRINGP (glyph->object)
19261 ? 'S'
19262 : (NILP (glyph->object)
19263 ? '0'
19264 : '-'))),
19265 glyph->pixel_width,
19266 glyph->u.ch,
19267 (glyph->u.ch < 0x80 && glyph->u.ch >= ' '
19268 ? (int) glyph->u.ch
19269 : '.'),
19270 glyph->face_id,
19271 glyph->left_box_line_p,
19272 glyph->right_box_line_p);
19274 else if (glyph->type == STRETCH_GLYPH)
19276 fprintf (stderr,
19277 " %5"pD"d %c %9"pD"d %c %3d 0x%06x %c %4d %1.1d%1.1d\n",
19278 glyph - row->glyphs[TEXT_AREA],
19279 'S',
19280 glyph->charpos,
19281 (BUFFERP (glyph->object)
19282 ? 'B'
19283 : (STRINGP (glyph->object)
19284 ? 'S'
19285 : (NILP (glyph->object)
19286 ? '0'
19287 : '-'))),
19288 glyph->pixel_width,
19290 ' ',
19291 glyph->face_id,
19292 glyph->left_box_line_p,
19293 glyph->right_box_line_p);
19295 else if (glyph->type == IMAGE_GLYPH)
19297 fprintf (stderr,
19298 " %5"pD"d %c %9"pD"d %c %3d 0x%06x %c %4d %1.1d%1.1d\n",
19299 glyph - row->glyphs[TEXT_AREA],
19300 'I',
19301 glyph->charpos,
19302 (BUFFERP (glyph->object)
19303 ? 'B'
19304 : (STRINGP (glyph->object)
19305 ? 'S'
19306 : (NILP (glyph->object)
19307 ? '0'
19308 : '-'))),
19309 glyph->pixel_width,
19310 (unsigned int) glyph->u.img_id,
19311 '.',
19312 glyph->face_id,
19313 glyph->left_box_line_p,
19314 glyph->right_box_line_p);
19316 else if (glyph->type == COMPOSITE_GLYPH)
19318 fprintf (stderr,
19319 " %5"pD"d %c %9"pD"d %c %3d 0x%06x",
19320 glyph - row->glyphs[TEXT_AREA],
19321 '+',
19322 glyph->charpos,
19323 (BUFFERP (glyph->object)
19324 ? 'B'
19325 : (STRINGP (glyph->object)
19326 ? 'S'
19327 : (NILP (glyph->object)
19328 ? '0'
19329 : '-'))),
19330 glyph->pixel_width,
19331 (unsigned int) glyph->u.cmp.id);
19332 if (glyph->u.cmp.automatic)
19333 fprintf (stderr,
19334 "[%d-%d]",
19335 glyph->slice.cmp.from, glyph->slice.cmp.to);
19336 fprintf (stderr, " . %4d %1.1d%1.1d\n",
19337 glyph->face_id,
19338 glyph->left_box_line_p,
19339 glyph->right_box_line_p);
19341 else if (glyph->type == XWIDGET_GLYPH)
19343 #ifndef HAVE_XWIDGETS
19344 eassume (false);
19345 #else
19346 fprintf (stderr,
19347 " %5d %4c %6d %c %3d 0x%05x %c %4d %1.1d%1.1d\n",
19348 glyph - row->glyphs[TEXT_AREA],
19349 'X',
19350 glyph->charpos,
19351 (BUFFERP (glyph->object)
19352 ? 'B'
19353 : (STRINGP (glyph->object)
19354 ? 'S'
19355 : '-')),
19356 glyph->pixel_width,
19357 glyph->u.xwidget,
19358 '.',
19359 glyph->face_id,
19360 glyph->left_box_line_p,
19361 glyph->right_box_line_p);
19362 #endif
19367 /* Dump the contents of glyph row at VPOS in MATRIX to stderr.
19368 GLYPHS 0 means don't show glyph contents.
19369 GLYPHS 1 means show glyphs in short form
19370 GLYPHS > 1 means show glyphs in long form. */
19372 void
19373 dump_glyph_row (struct glyph_row *row, int vpos, int glyphs)
19375 if (glyphs != 1)
19377 fprintf (stderr, "Row Start End Used oE><\\CTZFesm X Y W H V A P\n");
19378 fprintf (stderr, "==============================================================================\n");
19380 fprintf (stderr, "%3d %9"pD"d %9"pD"d %4d %1.1d%1.1d%1.1d%1.1d\
19381 %1.1d%1.1d%1.1d%1.1d%1.1d%1.1d%1.1d%1.1d %4d %4d %4d %4d %4d %4d %4d\n",
19382 vpos,
19383 MATRIX_ROW_START_CHARPOS (row),
19384 MATRIX_ROW_END_CHARPOS (row),
19385 row->used[TEXT_AREA],
19386 row->contains_overlapping_glyphs_p,
19387 row->enabled_p,
19388 row->truncated_on_left_p,
19389 row->truncated_on_right_p,
19390 row->continued_p,
19391 MATRIX_ROW_CONTINUATION_LINE_P (row),
19392 MATRIX_ROW_DISPLAYS_TEXT_P (row),
19393 row->ends_at_zv_p,
19394 row->fill_line_p,
19395 row->ends_in_middle_of_char_p,
19396 row->starts_in_middle_of_char_p,
19397 row->mouse_face_p,
19398 row->x,
19399 row->y,
19400 row->pixel_width,
19401 row->height,
19402 row->visible_height,
19403 row->ascent,
19404 row->phys_ascent);
19405 /* The next 3 lines should align to "Start" in the header. */
19406 fprintf (stderr, " %9"pD"d %9"pD"d\t%5d\n", row->start.overlay_string_index,
19407 row->end.overlay_string_index,
19408 row->continuation_lines_width);
19409 fprintf (stderr, " %9"pD"d %9"pD"d\n",
19410 CHARPOS (row->start.string_pos),
19411 CHARPOS (row->end.string_pos));
19412 fprintf (stderr, " %9d %9d\n", row->start.dpvec_index,
19413 row->end.dpvec_index);
19416 if (glyphs > 1)
19418 int area;
19420 for (area = LEFT_MARGIN_AREA; area < LAST_AREA; ++area)
19422 struct glyph *glyph = row->glyphs[area];
19423 struct glyph *glyph_end = glyph + row->used[area];
19425 /* Glyph for a line end in text. */
19426 if (area == TEXT_AREA && glyph == glyph_end && glyph->charpos > 0)
19427 ++glyph_end;
19429 if (glyph < glyph_end)
19430 fprintf (stderr, " Glyph# Type Pos O W Code C Face LR\n");
19432 for (; glyph < glyph_end; ++glyph)
19433 dump_glyph (row, glyph, area);
19436 else if (glyphs == 1)
19438 int area;
19439 char s[SHRT_MAX + 4];
19441 for (area = LEFT_MARGIN_AREA; area < LAST_AREA; ++area)
19443 int i;
19445 for (i = 0; i < row->used[area]; ++i)
19447 struct glyph *glyph = row->glyphs[area] + i;
19448 if (i == row->used[area] - 1
19449 && area == TEXT_AREA
19450 && NILP (glyph->object)
19451 && glyph->type == CHAR_GLYPH
19452 && glyph->u.ch == ' ')
19454 strcpy (&s[i], "[\\n]");
19455 i += 4;
19457 else if (glyph->type == CHAR_GLYPH
19458 && glyph->u.ch < 0x80
19459 && glyph->u.ch >= ' ')
19460 s[i] = glyph->u.ch;
19461 else
19462 s[i] = '.';
19465 s[i] = '\0';
19466 fprintf (stderr, "%3d: (%d) '%s'\n", vpos, row->enabled_p, s);
19472 DEFUN ("dump-glyph-matrix", Fdump_glyph_matrix,
19473 Sdump_glyph_matrix, 0, 1, "p",
19474 doc: /* Dump the current matrix of the selected window to stderr.
19475 Shows contents of glyph row structures. With non-nil
19476 parameter GLYPHS, dump glyphs as well. If GLYPHS is 1 show
19477 glyphs in short form, otherwise show glyphs in long form.
19479 Interactively, no argument means show glyphs in short form;
19480 with numeric argument, its value is passed as the GLYPHS flag. */)
19481 (Lisp_Object glyphs)
19483 struct window *w = XWINDOW (selected_window);
19484 struct buffer *buffer = XBUFFER (w->contents);
19486 fprintf (stderr, "PT = %"pD"d, BEGV = %"pD"d. ZV = %"pD"d\n",
19487 BUF_PT (buffer), BUF_BEGV (buffer), BUF_ZV (buffer));
19488 fprintf (stderr, "Cursor x = %d, y = %d, hpos = %d, vpos = %d\n",
19489 w->cursor.x, w->cursor.y, w->cursor.hpos, w->cursor.vpos);
19490 fprintf (stderr, "=============================================\n");
19491 dump_glyph_matrix (w->current_matrix,
19492 TYPE_RANGED_INTEGERP (int, glyphs) ? XINT (glyphs) : 0);
19493 return Qnil;
19497 DEFUN ("dump-frame-glyph-matrix", Fdump_frame_glyph_matrix,
19498 Sdump_frame_glyph_matrix, 0, 0, "", doc: /* Dump the current glyph matrix of the selected frame to stderr.
19499 Only text-mode frames have frame glyph matrices. */)
19500 (void)
19502 struct frame *f = XFRAME (selected_frame);
19504 if (f->current_matrix)
19505 dump_glyph_matrix (f->current_matrix, 1);
19506 else
19507 fprintf (stderr, "*** This frame doesn't have a frame glyph matrix ***\n");
19508 return Qnil;
19512 DEFUN ("dump-glyph-row", Fdump_glyph_row, Sdump_glyph_row, 1, 2, "P",
19513 doc: /* Dump glyph row ROW to stderr.
19514 Interactively, ROW is the prefix numeric argument and defaults to
19515 the row which displays point.
19516 Optional argument GLYPHS 0 means don't dump glyphs.
19517 GLYPHS 1 means dump glyphs in short form.
19518 GLYPHS > 1 or omitted means dump glyphs in long form. */)
19519 (Lisp_Object row, Lisp_Object glyphs)
19521 struct glyph_matrix *matrix;
19522 EMACS_INT vpos;
19524 if (NILP (row))
19526 int d1, d2, d3, d4, d5, ypos;
19527 bool visible_p = pos_visible_p (XWINDOW (selected_window), PT,
19528 &d1, &d2, &d3, &d4, &d5, &ypos);
19529 if (visible_p)
19530 vpos = ypos;
19531 else
19532 vpos = 0;
19534 else
19536 CHECK_NUMBER (row);
19537 vpos = XINT (row);
19539 matrix = XWINDOW (selected_window)->current_matrix;
19540 if (vpos >= 0 && vpos < matrix->nrows)
19541 dump_glyph_row (MATRIX_ROW (matrix, vpos),
19542 vpos,
19543 TYPE_RANGED_INTEGERP (int, glyphs) ? XINT (glyphs) : 2);
19544 return Qnil;
19548 DEFUN ("dump-tool-bar-row", Fdump_tool_bar_row, Sdump_tool_bar_row, 1, 2, "P",
19549 doc: /* Dump glyph row ROW of the tool-bar of the current frame to stderr.
19550 Interactively, ROW is the prefix numeric argument and defaults to zero.
19551 GLYPHS 0 means don't dump glyphs.
19552 GLYPHS 1 means dump glyphs in short form.
19553 GLYPHS > 1 or omitted means dump glyphs in long form.
19555 If there's no tool-bar, or if the tool-bar is not drawn by Emacs,
19556 do nothing. */)
19557 (Lisp_Object row, Lisp_Object glyphs)
19559 #if defined (HAVE_WINDOW_SYSTEM) && ! defined (USE_GTK) && ! defined (HAVE_NS)
19560 struct frame *sf = SELECTED_FRAME ();
19561 struct glyph_matrix *m = XWINDOW (sf->tool_bar_window)->current_matrix;
19562 EMACS_INT vpos;
19564 if (NILP (row))
19565 vpos = 0;
19566 else
19568 CHECK_NUMBER (row);
19569 vpos = XINT (row);
19571 if (vpos >= 0 && vpos < m->nrows)
19572 dump_glyph_row (MATRIX_ROW (m, vpos), vpos,
19573 TYPE_RANGED_INTEGERP (int, glyphs) ? XINT (glyphs) : 2);
19574 #endif
19575 return Qnil;
19579 DEFUN ("trace-redisplay", Ftrace_redisplay, Strace_redisplay, 0, 1, "P",
19580 doc: /* Toggle tracing of redisplay.
19581 With ARG, turn tracing on if and only if ARG is positive. */)
19582 (Lisp_Object arg)
19584 if (NILP (arg))
19585 trace_redisplay_p = !trace_redisplay_p;
19586 else
19588 arg = Fprefix_numeric_value (arg);
19589 trace_redisplay_p = XINT (arg) > 0;
19592 return Qnil;
19596 DEFUN ("trace-to-stderr", Ftrace_to_stderr, Strace_to_stderr, 1, MANY, "",
19597 doc: /* Like `format', but print result to stderr.
19598 usage: (trace-to-stderr STRING &rest OBJECTS) */)
19599 (ptrdiff_t nargs, Lisp_Object *args)
19601 Lisp_Object s = Fformat (nargs, args);
19602 fwrite (SDATA (s), 1, SBYTES (s), stderr);
19603 return Qnil;
19606 #endif /* GLYPH_DEBUG */
19610 /***********************************************************************
19611 Building Desired Matrix Rows
19612 ***********************************************************************/
19614 /* Return a temporary glyph row holding the glyphs of an overlay arrow.
19615 Used for non-window-redisplay windows, and for windows w/o left fringe. */
19617 static struct glyph_row *
19618 get_overlay_arrow_glyph_row (struct window *w, Lisp_Object overlay_arrow_string)
19620 struct frame *f = XFRAME (WINDOW_FRAME (w));
19621 struct buffer *buffer = XBUFFER (w->contents);
19622 struct buffer *old = current_buffer;
19623 const unsigned char *arrow_string = SDATA (overlay_arrow_string);
19624 ptrdiff_t arrow_len = SCHARS (overlay_arrow_string);
19625 const unsigned char *arrow_end = arrow_string + arrow_len;
19626 const unsigned char *p;
19627 struct it it;
19628 bool multibyte_p;
19629 int n_glyphs_before;
19631 set_buffer_temp (buffer);
19632 init_iterator (&it, w, -1, -1, &scratch_glyph_row, DEFAULT_FACE_ID);
19633 scratch_glyph_row.reversed_p = false;
19634 it.glyph_row->used[TEXT_AREA] = 0;
19635 SET_TEXT_POS (it.position, 0, 0);
19637 multibyte_p = !NILP (BVAR (buffer, enable_multibyte_characters));
19638 p = arrow_string;
19639 while (p < arrow_end)
19641 Lisp_Object face, ilisp;
19643 /* Get the next character. */
19644 if (multibyte_p)
19645 it.c = it.char_to_display = string_char_and_length (p, &it.len);
19646 else
19648 it.c = it.char_to_display = *p, it.len = 1;
19649 if (! ASCII_CHAR_P (it.c))
19650 it.char_to_display = BYTE8_TO_CHAR (it.c);
19652 p += it.len;
19654 /* Get its face. */
19655 ilisp = make_number (p - arrow_string);
19656 face = Fget_text_property (ilisp, Qface, overlay_arrow_string);
19657 it.face_id = compute_char_face (f, it.char_to_display, face);
19659 /* Compute its width, get its glyphs. */
19660 n_glyphs_before = it.glyph_row->used[TEXT_AREA];
19661 SET_TEXT_POS (it.position, -1, -1);
19662 PRODUCE_GLYPHS (&it);
19664 /* If this character doesn't fit any more in the line, we have
19665 to remove some glyphs. */
19666 if (it.current_x > it.last_visible_x)
19668 it.glyph_row->used[TEXT_AREA] = n_glyphs_before;
19669 break;
19673 set_buffer_temp (old);
19674 return it.glyph_row;
19678 /* Insert truncation glyphs at the start of IT->glyph_row. Which
19679 glyphs to insert is determined by produce_special_glyphs. */
19681 static void
19682 insert_left_trunc_glyphs (struct it *it)
19684 struct it truncate_it;
19685 struct glyph *from, *end, *to, *toend;
19687 eassert (!FRAME_WINDOW_P (it->f)
19688 || (!it->glyph_row->reversed_p
19689 && WINDOW_LEFT_FRINGE_WIDTH (it->w) == 0)
19690 || (it->glyph_row->reversed_p
19691 && WINDOW_RIGHT_FRINGE_WIDTH (it->w) == 0));
19693 /* Get the truncation glyphs. */
19694 truncate_it = *it;
19695 truncate_it.current_x = 0;
19696 truncate_it.face_id = DEFAULT_FACE_ID;
19697 truncate_it.glyph_row = &scratch_glyph_row;
19698 truncate_it.area = TEXT_AREA;
19699 truncate_it.glyph_row->used[TEXT_AREA] = 0;
19700 CHARPOS (truncate_it.position) = BYTEPOS (truncate_it.position) = -1;
19701 truncate_it.object = Qnil;
19702 produce_special_glyphs (&truncate_it, IT_TRUNCATION);
19704 /* Overwrite glyphs from IT with truncation glyphs. */
19705 if (!it->glyph_row->reversed_p)
19707 short tused = truncate_it.glyph_row->used[TEXT_AREA];
19709 from = truncate_it.glyph_row->glyphs[TEXT_AREA];
19710 end = from + tused;
19711 to = it->glyph_row->glyphs[TEXT_AREA];
19712 toend = to + it->glyph_row->used[TEXT_AREA];
19713 if (FRAME_WINDOW_P (it->f))
19715 /* On GUI frames, when variable-size fonts are displayed,
19716 the truncation glyphs may need more pixels than the row's
19717 glyphs they overwrite. We overwrite more glyphs to free
19718 enough screen real estate, and enlarge the stretch glyph
19719 on the right (see display_line), if there is one, to
19720 preserve the screen position of the truncation glyphs on
19721 the right. */
19722 int w = 0;
19723 struct glyph *g = to;
19724 short used;
19726 /* The first glyph could be partially visible, in which case
19727 it->glyph_row->x will be negative. But we want the left
19728 truncation glyphs to be aligned at the left margin of the
19729 window, so we override the x coordinate at which the row
19730 will begin. */
19731 it->glyph_row->x = 0;
19732 while (g < toend && w < it->truncation_pixel_width)
19734 w += g->pixel_width;
19735 ++g;
19737 if (g - to - tused > 0)
19739 memmove (to + tused, g, (toend - g) * sizeof(*g));
19740 it->glyph_row->used[TEXT_AREA] -= g - to - tused;
19742 used = it->glyph_row->used[TEXT_AREA];
19743 if (it->glyph_row->truncated_on_right_p
19744 && WINDOW_RIGHT_FRINGE_WIDTH (it->w) == 0
19745 && it->glyph_row->glyphs[TEXT_AREA][used - 2].type
19746 == STRETCH_GLYPH)
19748 int extra = w - it->truncation_pixel_width;
19750 it->glyph_row->glyphs[TEXT_AREA][used - 2].pixel_width += extra;
19754 while (from < end)
19755 *to++ = *from++;
19757 /* There may be padding glyphs left over. Overwrite them too. */
19758 if (!FRAME_WINDOW_P (it->f))
19760 while (to < toend && CHAR_GLYPH_PADDING_P (*to))
19762 from = truncate_it.glyph_row->glyphs[TEXT_AREA];
19763 while (from < end)
19764 *to++ = *from++;
19768 if (to > toend)
19769 it->glyph_row->used[TEXT_AREA] = to - it->glyph_row->glyphs[TEXT_AREA];
19771 else
19773 short tused = truncate_it.glyph_row->used[TEXT_AREA];
19775 /* In R2L rows, overwrite the last (rightmost) glyphs, and do
19776 that back to front. */
19777 end = truncate_it.glyph_row->glyphs[TEXT_AREA];
19778 from = end + truncate_it.glyph_row->used[TEXT_AREA] - 1;
19779 toend = it->glyph_row->glyphs[TEXT_AREA];
19780 to = toend + it->glyph_row->used[TEXT_AREA] - 1;
19781 if (FRAME_WINDOW_P (it->f))
19783 int w = 0;
19784 struct glyph *g = to;
19786 while (g >= toend && w < it->truncation_pixel_width)
19788 w += g->pixel_width;
19789 --g;
19791 if (to - g - tused > 0)
19792 to = g + tused;
19793 if (it->glyph_row->truncated_on_right_p
19794 && WINDOW_LEFT_FRINGE_WIDTH (it->w) == 0
19795 && it->glyph_row->glyphs[TEXT_AREA][1].type == STRETCH_GLYPH)
19797 int extra = w - it->truncation_pixel_width;
19799 it->glyph_row->glyphs[TEXT_AREA][1].pixel_width += extra;
19803 while (from >= end && to >= toend)
19804 *to-- = *from--;
19805 if (!FRAME_WINDOW_P (it->f))
19807 while (to >= toend && CHAR_GLYPH_PADDING_P (*to))
19809 from =
19810 truncate_it.glyph_row->glyphs[TEXT_AREA]
19811 + truncate_it.glyph_row->used[TEXT_AREA] - 1;
19812 while (from >= end && to >= toend)
19813 *to-- = *from--;
19816 if (from >= end)
19818 /* Need to free some room before prepending additional
19819 glyphs. */
19820 int move_by = from - end + 1;
19821 struct glyph *g0 = it->glyph_row->glyphs[TEXT_AREA];
19822 struct glyph *g = g0 + it->glyph_row->used[TEXT_AREA] - 1;
19824 for ( ; g >= g0; g--)
19825 g[move_by] = *g;
19826 while (from >= end)
19827 *to-- = *from--;
19828 it->glyph_row->used[TEXT_AREA] += move_by;
19833 /* Compute the hash code for ROW. */
19834 unsigned
19835 row_hash (struct glyph_row *row)
19837 int area, k;
19838 unsigned hashval = 0;
19840 for (area = LEFT_MARGIN_AREA; area < LAST_AREA; ++area)
19841 for (k = 0; k < row->used[area]; ++k)
19842 hashval = ((((hashval << 4) + (hashval >> 24)) & 0x0fffffff)
19843 + row->glyphs[area][k].u.val
19844 + row->glyphs[area][k].face_id
19845 + row->glyphs[area][k].padding_p
19846 + (row->glyphs[area][k].type << 2));
19848 return hashval;
19851 /* Compute the pixel height and width of IT->glyph_row.
19853 Most of the time, ascent and height of a display line will be equal
19854 to the max_ascent and max_height values of the display iterator
19855 structure. This is not the case if
19857 1. We hit ZV without displaying anything. In this case, max_ascent
19858 and max_height will be zero.
19860 2. We have some glyphs that don't contribute to the line height.
19861 (The glyph row flag contributes_to_line_height_p is for future
19862 pixmap extensions).
19864 The first case is easily covered by using default values because in
19865 these cases, the line height does not really matter, except that it
19866 must not be zero. */
19868 static void
19869 compute_line_metrics (struct it *it)
19871 struct glyph_row *row = it->glyph_row;
19873 if (FRAME_WINDOW_P (it->f))
19875 int i, min_y, max_y;
19877 /* The line may consist of one space only, that was added to
19878 place the cursor on it. If so, the row's height hasn't been
19879 computed yet. */
19880 if (row->height == 0)
19882 if (it->max_ascent + it->max_descent == 0)
19883 it->max_descent = it->max_phys_descent = FRAME_LINE_HEIGHT (it->f);
19884 row->ascent = it->max_ascent;
19885 row->height = it->max_ascent + it->max_descent;
19886 row->phys_ascent = it->max_phys_ascent;
19887 row->phys_height = it->max_phys_ascent + it->max_phys_descent;
19888 row->extra_line_spacing = it->max_extra_line_spacing;
19891 /* Compute the width of this line. */
19892 row->pixel_width = row->x;
19893 for (i = 0; i < row->used[TEXT_AREA]; ++i)
19894 row->pixel_width += row->glyphs[TEXT_AREA][i].pixel_width;
19896 eassert (row->pixel_width >= 0);
19897 eassert (row->ascent >= 0 && row->height > 0);
19899 row->overlapping_p = (MATRIX_ROW_OVERLAPS_SUCC_P (row)
19900 || MATRIX_ROW_OVERLAPS_PRED_P (row));
19902 /* If first line's physical ascent is larger than its logical
19903 ascent, use the physical ascent, and make the row taller.
19904 This makes accented characters fully visible. */
19905 if (row == MATRIX_FIRST_TEXT_ROW (it->w->desired_matrix)
19906 && row->phys_ascent > row->ascent)
19908 row->height += row->phys_ascent - row->ascent;
19909 row->ascent = row->phys_ascent;
19912 /* Compute how much of the line is visible. */
19913 row->visible_height = row->height;
19915 min_y = WINDOW_HEADER_LINE_HEIGHT (it->w);
19916 max_y = WINDOW_BOX_HEIGHT_NO_MODE_LINE (it->w);
19918 if (row->y < min_y)
19919 row->visible_height -= min_y - row->y;
19920 if (row->y + row->height > max_y)
19921 row->visible_height -= row->y + row->height - max_y;
19923 else
19925 row->pixel_width = row->used[TEXT_AREA];
19926 if (row->continued_p)
19927 row->pixel_width -= it->continuation_pixel_width;
19928 else if (row->truncated_on_right_p)
19929 row->pixel_width -= it->truncation_pixel_width;
19930 row->ascent = row->phys_ascent = 0;
19931 row->height = row->phys_height = row->visible_height = 1;
19932 row->extra_line_spacing = 0;
19935 /* Compute a hash code for this row. */
19936 row->hash = row_hash (row);
19938 it->max_ascent = it->max_descent = 0;
19939 it->max_phys_ascent = it->max_phys_descent = 0;
19943 /* Append one space to the glyph row of iterator IT if doing a
19944 window-based redisplay. The space has the same face as
19945 IT->face_id. Value is true if a space was added.
19947 This function is called to make sure that there is always one glyph
19948 at the end of a glyph row that the cursor can be set on under
19949 window-systems. (If there weren't such a glyph we would not know
19950 how wide and tall a box cursor should be displayed).
19952 At the same time this space let's a nicely handle clearing to the
19953 end of the line if the row ends in italic text. */
19955 static bool
19956 append_space_for_newline (struct it *it, bool default_face_p)
19958 if (FRAME_WINDOW_P (it->f))
19960 int n = it->glyph_row->used[TEXT_AREA];
19962 if (it->glyph_row->glyphs[TEXT_AREA] + n
19963 < it->glyph_row->glyphs[1 + TEXT_AREA])
19965 /* Save some values that must not be changed.
19966 Must save IT->c and IT->len because otherwise
19967 ITERATOR_AT_END_P wouldn't work anymore after
19968 append_space_for_newline has been called. */
19969 enum display_element_type saved_what = it->what;
19970 int saved_c = it->c, saved_len = it->len;
19971 int saved_char_to_display = it->char_to_display;
19972 int saved_x = it->current_x;
19973 int saved_face_id = it->face_id;
19974 bool saved_box_end = it->end_of_box_run_p;
19975 struct text_pos saved_pos;
19976 Lisp_Object saved_object;
19977 struct face *face;
19979 saved_object = it->object;
19980 saved_pos = it->position;
19982 it->what = IT_CHARACTER;
19983 memset (&it->position, 0, sizeof it->position);
19984 it->object = Qnil;
19985 it->c = it->char_to_display = ' ';
19986 it->len = 1;
19988 /* If the default face was remapped, be sure to use the
19989 remapped face for the appended newline. */
19990 if (default_face_p)
19991 it->face_id = lookup_basic_face (it->f, DEFAULT_FACE_ID);
19992 else if (it->face_before_selective_p)
19993 it->face_id = it->saved_face_id;
19994 face = FACE_FROM_ID (it->f, it->face_id);
19995 it->face_id = FACE_FOR_CHAR (it->f, face, 0, -1, Qnil);
19996 /* In R2L rows, we will prepend a stretch glyph that will
19997 have the end_of_box_run_p flag set for it, so there's no
19998 need for the appended newline glyph to have that flag
19999 set. */
20000 if (it->glyph_row->reversed_p
20001 /* But if the appended newline glyph goes all the way to
20002 the end of the row, there will be no stretch glyph,
20003 so leave the box flag set. */
20004 && saved_x + FRAME_COLUMN_WIDTH (it->f) < it->last_visible_x)
20005 it->end_of_box_run_p = false;
20007 PRODUCE_GLYPHS (it);
20009 #ifdef HAVE_WINDOW_SYSTEM
20010 /* Make sure this space glyph has the right ascent and
20011 descent values, or else cursor at end of line will look
20012 funny, and height of empty lines will be incorrect. */
20013 struct glyph *g = it->glyph_row->glyphs[TEXT_AREA] + n;
20014 struct font *font = face->font ? face->font : FRAME_FONT (it->f);
20015 if (n == 0)
20017 Lisp_Object height, total_height;
20018 int extra_line_spacing = it->extra_line_spacing;
20019 int boff = font->baseline_offset;
20021 if (font->vertical_centering)
20022 boff = VCENTER_BASELINE_OFFSET (font, it->f) - boff;
20024 it->object = saved_object; /* get_it_property needs this */
20025 normal_char_ascent_descent (font, -1, &it->ascent, &it->descent);
20026 /* Must do a subset of line height processing from
20027 x_produce_glyph for newline characters. */
20028 height = get_it_property (it, Qline_height);
20029 if (CONSP (height)
20030 && CONSP (XCDR (height))
20031 && NILP (XCDR (XCDR (height))))
20033 total_height = XCAR (XCDR (height));
20034 height = XCAR (height);
20036 else
20037 total_height = Qnil;
20038 height = calc_line_height_property (it, height, font, boff, true);
20040 if (it->override_ascent >= 0)
20042 it->ascent = it->override_ascent;
20043 it->descent = it->override_descent;
20044 boff = it->override_boff;
20046 if (EQ (height, Qt))
20047 extra_line_spacing = 0;
20048 else
20050 Lisp_Object spacing;
20052 it->phys_ascent = it->ascent;
20053 it->phys_descent = it->descent;
20054 if (!NILP (height)
20055 && XINT (height) > it->ascent + it->descent)
20056 it->ascent = XINT (height) - it->descent;
20058 if (!NILP (total_height))
20059 spacing = calc_line_height_property (it, total_height, font,
20060 boff, false);
20061 else
20063 spacing = get_it_property (it, Qline_spacing);
20064 spacing = calc_line_height_property (it, spacing, font,
20065 boff, false);
20067 if (INTEGERP (spacing))
20069 extra_line_spacing = XINT (spacing);
20070 if (!NILP (total_height))
20071 extra_line_spacing -= (it->phys_ascent + it->phys_descent);
20074 if (extra_line_spacing > 0)
20076 it->descent += extra_line_spacing;
20077 if (extra_line_spacing > it->max_extra_line_spacing)
20078 it->max_extra_line_spacing = extra_line_spacing;
20080 it->max_ascent = it->ascent;
20081 it->max_descent = it->descent;
20082 /* Make sure compute_line_metrics recomputes the row height. */
20083 it->glyph_row->height = 0;
20086 g->ascent = it->max_ascent;
20087 g->descent = it->max_descent;
20088 #endif
20090 it->override_ascent = -1;
20091 it->constrain_row_ascent_descent_p = false;
20092 it->current_x = saved_x;
20093 it->object = saved_object;
20094 it->position = saved_pos;
20095 it->what = saved_what;
20096 it->face_id = saved_face_id;
20097 it->len = saved_len;
20098 it->c = saved_c;
20099 it->char_to_display = saved_char_to_display;
20100 it->end_of_box_run_p = saved_box_end;
20101 return true;
20105 return false;
20109 /* Extend the face of the last glyph in the text area of IT->glyph_row
20110 to the end of the display line. Called from display_line. If the
20111 glyph row is empty, add a space glyph to it so that we know the
20112 face to draw. Set the glyph row flag fill_line_p. If the glyph
20113 row is R2L, prepend a stretch glyph to cover the empty space to the
20114 left of the leftmost glyph. */
20116 static void
20117 extend_face_to_end_of_line (struct it *it)
20119 struct face *face, *default_face;
20120 struct frame *f = it->f;
20122 /* If line is already filled, do nothing. Non window-system frames
20123 get a grace of one more ``pixel'' because their characters are
20124 1-``pixel'' wide, so they hit the equality too early. This grace
20125 is needed only for R2L rows that are not continued, to produce
20126 one extra blank where we could display the cursor. */
20127 if ((it->current_x >= it->last_visible_x
20128 + (!FRAME_WINDOW_P (f)
20129 && it->glyph_row->reversed_p
20130 && !it->glyph_row->continued_p))
20131 /* If the window has display margins, we will need to extend
20132 their face even if the text area is filled. */
20133 && !(WINDOW_LEFT_MARGIN_WIDTH (it->w) > 0
20134 || WINDOW_RIGHT_MARGIN_WIDTH (it->w) > 0))
20135 return;
20137 /* The default face, possibly remapped. */
20138 default_face = FACE_FROM_ID_OR_NULL (f,
20139 lookup_basic_face (f, DEFAULT_FACE_ID));
20141 /* Face extension extends the background and box of IT->face_id
20142 to the end of the line. If the background equals the background
20143 of the frame, we don't have to do anything. */
20144 face = FACE_FROM_ID (f, (it->face_before_selective_p
20145 ? it->saved_face_id
20146 : it->face_id));
20148 if (FRAME_WINDOW_P (f)
20149 && MATRIX_ROW_DISPLAYS_TEXT_P (it->glyph_row)
20150 && face->box == FACE_NO_BOX
20151 && face->background == FRAME_BACKGROUND_PIXEL (f)
20152 #ifdef HAVE_WINDOW_SYSTEM
20153 && !face->stipple
20154 #endif
20155 && !it->glyph_row->reversed_p)
20156 return;
20158 /* Set the glyph row flag indicating that the face of the last glyph
20159 in the text area has to be drawn to the end of the text area. */
20160 it->glyph_row->fill_line_p = true;
20162 /* If current character of IT is not ASCII, make sure we have the
20163 ASCII face. This will be automatically undone the next time
20164 get_next_display_element returns a multibyte character. Note
20165 that the character will always be single byte in unibyte
20166 text. */
20167 if (!ASCII_CHAR_P (it->c))
20169 it->face_id = FACE_FOR_CHAR (f, face, 0, -1, Qnil);
20172 if (FRAME_WINDOW_P (f))
20174 /* If the row is empty, add a space with the current face of IT,
20175 so that we know which face to draw. */
20176 if (it->glyph_row->used[TEXT_AREA] == 0)
20178 it->glyph_row->glyphs[TEXT_AREA][0] = space_glyph;
20179 it->glyph_row->glyphs[TEXT_AREA][0].face_id = face->id;
20180 it->glyph_row->used[TEXT_AREA] = 1;
20182 /* Mode line and the header line don't have margins, and
20183 likewise the frame's tool-bar window, if there is any. */
20184 if (!(it->glyph_row->mode_line_p
20185 #if defined (HAVE_WINDOW_SYSTEM) && ! defined (USE_GTK) && ! defined (HAVE_NS)
20186 || (WINDOWP (f->tool_bar_window)
20187 && it->w == XWINDOW (f->tool_bar_window))
20188 #endif
20191 if (WINDOW_LEFT_MARGIN_WIDTH (it->w) > 0
20192 && it->glyph_row->used[LEFT_MARGIN_AREA] == 0)
20194 it->glyph_row->glyphs[LEFT_MARGIN_AREA][0] = space_glyph;
20195 it->glyph_row->glyphs[LEFT_MARGIN_AREA][0].face_id =
20196 default_face->id;
20197 it->glyph_row->used[LEFT_MARGIN_AREA] = 1;
20199 if (WINDOW_RIGHT_MARGIN_WIDTH (it->w) > 0
20200 && it->glyph_row->used[RIGHT_MARGIN_AREA] == 0)
20202 it->glyph_row->glyphs[RIGHT_MARGIN_AREA][0] = space_glyph;
20203 it->glyph_row->glyphs[RIGHT_MARGIN_AREA][0].face_id =
20204 default_face->id;
20205 it->glyph_row->used[RIGHT_MARGIN_AREA] = 1;
20208 #ifdef HAVE_WINDOW_SYSTEM
20209 if (it->glyph_row->reversed_p)
20211 /* Prepend a stretch glyph to the row, such that the
20212 rightmost glyph will be drawn flushed all the way to the
20213 right margin of the window. The stretch glyph that will
20214 occupy the empty space, if any, to the left of the
20215 glyphs. */
20216 struct font *font = face->font ? face->font : FRAME_FONT (f);
20217 struct glyph *row_start = it->glyph_row->glyphs[TEXT_AREA];
20218 struct glyph *row_end = row_start + it->glyph_row->used[TEXT_AREA];
20219 struct glyph *g;
20220 int row_width, stretch_ascent, stretch_width;
20221 struct text_pos saved_pos;
20222 int saved_face_id;
20223 bool saved_avoid_cursor, saved_box_start;
20225 for (row_width = 0, g = row_start; g < row_end; g++)
20226 row_width += g->pixel_width;
20228 /* FIXME: There are various minor display glitches in R2L
20229 rows when only one of the fringes is missing. The
20230 strange condition below produces the least bad effect. */
20231 if ((WINDOW_LEFT_FRINGE_WIDTH (it->w) == 0)
20232 == (WINDOW_RIGHT_FRINGE_WIDTH (it->w) == 0)
20233 || WINDOW_RIGHT_FRINGE_WIDTH (it->w) != 0)
20234 stretch_width = window_box_width (it->w, TEXT_AREA);
20235 else
20236 stretch_width = it->last_visible_x - it->first_visible_x;
20237 stretch_width -= row_width;
20239 if (stretch_width > 0)
20241 stretch_ascent =
20242 (((it->ascent + it->descent)
20243 * FONT_BASE (font)) / FONT_HEIGHT (font));
20244 saved_pos = it->position;
20245 memset (&it->position, 0, sizeof it->position);
20246 saved_avoid_cursor = it->avoid_cursor_p;
20247 it->avoid_cursor_p = true;
20248 saved_face_id = it->face_id;
20249 saved_box_start = it->start_of_box_run_p;
20250 /* The last row's stretch glyph should get the default
20251 face, to avoid painting the rest of the window with
20252 the region face, if the region ends at ZV. */
20253 if (it->glyph_row->ends_at_zv_p)
20254 it->face_id = default_face->id;
20255 else
20256 it->face_id = face->id;
20257 it->start_of_box_run_p = false;
20258 append_stretch_glyph (it, Qnil, stretch_width,
20259 it->ascent + it->descent, stretch_ascent);
20260 it->position = saved_pos;
20261 it->avoid_cursor_p = saved_avoid_cursor;
20262 it->face_id = saved_face_id;
20263 it->start_of_box_run_p = saved_box_start;
20265 /* If stretch_width comes out negative, it means that the
20266 last glyph is only partially visible. In R2L rows, we
20267 want the leftmost glyph to be partially visible, so we
20268 need to give the row the corresponding left offset. */
20269 if (stretch_width < 0)
20270 it->glyph_row->x = stretch_width;
20272 #endif /* HAVE_WINDOW_SYSTEM */
20274 else
20276 /* Save some values that must not be changed. */
20277 int saved_x = it->current_x;
20278 struct text_pos saved_pos;
20279 Lisp_Object saved_object;
20280 enum display_element_type saved_what = it->what;
20281 int saved_face_id = it->face_id;
20283 saved_object = it->object;
20284 saved_pos = it->position;
20286 it->what = IT_CHARACTER;
20287 memset (&it->position, 0, sizeof it->position);
20288 it->object = Qnil;
20289 it->c = it->char_to_display = ' ';
20290 it->len = 1;
20292 if (WINDOW_LEFT_MARGIN_WIDTH (it->w) > 0
20293 && (it->glyph_row->used[LEFT_MARGIN_AREA]
20294 < WINDOW_LEFT_MARGIN_WIDTH (it->w))
20295 && !it->glyph_row->mode_line_p
20296 && default_face->background != FRAME_BACKGROUND_PIXEL (f))
20298 struct glyph *g = it->glyph_row->glyphs[LEFT_MARGIN_AREA];
20299 struct glyph *e = g + it->glyph_row->used[LEFT_MARGIN_AREA];
20301 for (it->current_x = 0; g < e; g++)
20302 it->current_x += g->pixel_width;
20304 it->area = LEFT_MARGIN_AREA;
20305 it->face_id = default_face->id;
20306 while (it->glyph_row->used[LEFT_MARGIN_AREA]
20307 < WINDOW_LEFT_MARGIN_WIDTH (it->w)
20308 && g < it->glyph_row->glyphs[TEXT_AREA])
20310 PRODUCE_GLYPHS (it);
20311 /* term.c:produce_glyphs advances it->current_x only for
20312 TEXT_AREA. */
20313 it->current_x += it->pixel_width;
20314 g++;
20317 it->current_x = saved_x;
20318 it->area = TEXT_AREA;
20321 /* The last row's blank glyphs should get the default face, to
20322 avoid painting the rest of the window with the region face,
20323 if the region ends at ZV. */
20324 if (it->glyph_row->ends_at_zv_p)
20325 it->face_id = default_face->id;
20326 else
20327 it->face_id = face->id;
20328 PRODUCE_GLYPHS (it);
20330 while (it->current_x <= it->last_visible_x)
20331 PRODUCE_GLYPHS (it);
20333 if (WINDOW_RIGHT_MARGIN_WIDTH (it->w) > 0
20334 && (it->glyph_row->used[RIGHT_MARGIN_AREA]
20335 < WINDOW_RIGHT_MARGIN_WIDTH (it->w))
20336 && !it->glyph_row->mode_line_p
20337 && default_face->background != FRAME_BACKGROUND_PIXEL (f))
20339 struct glyph *g = it->glyph_row->glyphs[RIGHT_MARGIN_AREA];
20340 struct glyph *e = g + it->glyph_row->used[RIGHT_MARGIN_AREA];
20342 for ( ; g < e; g++)
20343 it->current_x += g->pixel_width;
20345 it->area = RIGHT_MARGIN_AREA;
20346 it->face_id = default_face->id;
20347 while (it->glyph_row->used[RIGHT_MARGIN_AREA]
20348 < WINDOW_RIGHT_MARGIN_WIDTH (it->w)
20349 && g < it->glyph_row->glyphs[LAST_AREA])
20351 PRODUCE_GLYPHS (it);
20352 it->current_x += it->pixel_width;
20353 g++;
20356 it->area = TEXT_AREA;
20359 /* Don't count these blanks really. It would let us insert a left
20360 truncation glyph below and make us set the cursor on them, maybe. */
20361 it->current_x = saved_x;
20362 it->object = saved_object;
20363 it->position = saved_pos;
20364 it->what = saved_what;
20365 it->face_id = saved_face_id;
20370 /* Value is true if text starting at CHARPOS in current_buffer is
20371 trailing whitespace. */
20373 static bool
20374 trailing_whitespace_p (ptrdiff_t charpos)
20376 ptrdiff_t bytepos = CHAR_TO_BYTE (charpos);
20377 int c = 0;
20379 while (bytepos < ZV_BYTE
20380 && (c = FETCH_CHAR (bytepos),
20381 c == ' ' || c == '\t'))
20382 ++bytepos;
20384 if (bytepos >= ZV_BYTE || c == '\n' || c == '\r')
20386 if (bytepos != PT_BYTE)
20387 return true;
20389 return false;
20393 /* Highlight trailing whitespace, if any, in ROW. */
20395 static void
20396 highlight_trailing_whitespace (struct frame *f, struct glyph_row *row)
20398 int used = row->used[TEXT_AREA];
20400 if (used)
20402 struct glyph *start = row->glyphs[TEXT_AREA];
20403 struct glyph *glyph = start + used - 1;
20405 if (row->reversed_p)
20407 /* Right-to-left rows need to be processed in the opposite
20408 direction, so swap the edge pointers. */
20409 glyph = start;
20410 start = row->glyphs[TEXT_AREA] + used - 1;
20413 /* Skip over glyphs inserted to display the cursor at the
20414 end of a line, for extending the face of the last glyph
20415 to the end of the line on terminals, and for truncation
20416 and continuation glyphs. */
20417 if (!row->reversed_p)
20419 while (glyph >= start
20420 && glyph->type == CHAR_GLYPH
20421 && NILP (glyph->object))
20422 --glyph;
20424 else
20426 while (glyph <= start
20427 && glyph->type == CHAR_GLYPH
20428 && NILP (glyph->object))
20429 ++glyph;
20432 /* If last glyph is a space or stretch, and it's trailing
20433 whitespace, set the face of all trailing whitespace glyphs in
20434 IT->glyph_row to `trailing-whitespace'. */
20435 if ((row->reversed_p ? glyph <= start : glyph >= start)
20436 && BUFFERP (glyph->object)
20437 && (glyph->type == STRETCH_GLYPH
20438 || (glyph->type == CHAR_GLYPH
20439 && glyph->u.ch == ' '))
20440 && trailing_whitespace_p (glyph->charpos))
20442 int face_id = lookup_named_face (f, Qtrailing_whitespace, false);
20443 if (face_id < 0)
20444 return;
20446 if (!row->reversed_p)
20448 while (glyph >= start
20449 && BUFFERP (glyph->object)
20450 && (glyph->type == STRETCH_GLYPH
20451 || (glyph->type == CHAR_GLYPH
20452 && glyph->u.ch == ' ')))
20453 (glyph--)->face_id = face_id;
20455 else
20457 while (glyph <= start
20458 && BUFFERP (glyph->object)
20459 && (glyph->type == STRETCH_GLYPH
20460 || (glyph->type == CHAR_GLYPH
20461 && glyph->u.ch == ' ')))
20462 (glyph++)->face_id = face_id;
20469 /* Value is true if glyph row ROW should be
20470 considered to hold the buffer position CHARPOS. */
20472 static bool
20473 row_for_charpos_p (struct glyph_row *row, ptrdiff_t charpos)
20475 bool result = true;
20477 if (charpos == CHARPOS (row->end.pos)
20478 || charpos == MATRIX_ROW_END_CHARPOS (row))
20480 /* Suppose the row ends on a string.
20481 Unless the row is continued, that means it ends on a newline
20482 in the string. If it's anything other than a display string
20483 (e.g., a before-string from an overlay), we don't want the
20484 cursor there. (This heuristic seems to give the optimal
20485 behavior for the various types of multi-line strings.)
20486 One exception: if the string has `cursor' property on one of
20487 its characters, we _do_ want the cursor there. */
20488 if (CHARPOS (row->end.string_pos) >= 0)
20490 if (row->continued_p)
20491 result = true;
20492 else
20494 /* Check for `display' property. */
20495 struct glyph *beg = row->glyphs[TEXT_AREA];
20496 struct glyph *end = beg + row->used[TEXT_AREA] - 1;
20497 struct glyph *glyph;
20499 result = false;
20500 for (glyph = end; glyph >= beg; --glyph)
20501 if (STRINGP (glyph->object))
20503 Lisp_Object prop
20504 = Fget_char_property (make_number (charpos),
20505 Qdisplay, Qnil);
20506 result =
20507 (!NILP (prop)
20508 && display_prop_string_p (prop, glyph->object));
20509 /* If there's a `cursor' property on one of the
20510 string's characters, this row is a cursor row,
20511 even though this is not a display string. */
20512 if (!result)
20514 Lisp_Object s = glyph->object;
20516 for ( ; glyph >= beg && EQ (glyph->object, s); --glyph)
20518 ptrdiff_t gpos = glyph->charpos;
20520 if (!NILP (Fget_char_property (make_number (gpos),
20521 Qcursor, s)))
20523 result = true;
20524 break;
20528 break;
20532 else if (MATRIX_ROW_ENDS_IN_MIDDLE_OF_CHAR_P (row))
20534 /* If the row ends in middle of a real character,
20535 and the line is continued, we want the cursor here.
20536 That's because CHARPOS (ROW->end.pos) would equal
20537 PT if PT is before the character. */
20538 if (!row->ends_in_ellipsis_p)
20539 result = row->continued_p;
20540 else
20541 /* If the row ends in an ellipsis, then
20542 CHARPOS (ROW->end.pos) will equal point after the
20543 invisible text. We want that position to be displayed
20544 after the ellipsis. */
20545 result = false;
20547 /* If the row ends at ZV, display the cursor at the end of that
20548 row instead of at the start of the row below. */
20549 else
20550 result = row->ends_at_zv_p;
20553 return result;
20556 /* Value is true if glyph row ROW should be
20557 used to hold the cursor. */
20559 static bool
20560 cursor_row_p (struct glyph_row *row)
20562 return row_for_charpos_p (row, PT);
20567 /* Push the property PROP so that it will be rendered at the current
20568 position in IT. Return true if PROP was successfully pushed, false
20569 otherwise. Called from handle_line_prefix to handle the
20570 `line-prefix' and `wrap-prefix' properties. */
20572 static bool
20573 push_prefix_prop (struct it *it, Lisp_Object prop)
20575 struct text_pos pos =
20576 STRINGP (it->string) ? it->current.string_pos : it->current.pos;
20578 eassert (it->method == GET_FROM_BUFFER
20579 || it->method == GET_FROM_DISPLAY_VECTOR
20580 || it->method == GET_FROM_STRING
20581 || it->method == GET_FROM_IMAGE);
20583 /* We need to save the current buffer/string position, so it will be
20584 restored by pop_it, because iterate_out_of_display_property
20585 depends on that being set correctly, but some situations leave
20586 it->position not yet set when this function is called. */
20587 push_it (it, &pos);
20589 if (STRINGP (prop))
20591 if (SCHARS (prop) == 0)
20593 pop_it (it);
20594 return false;
20597 it->string = prop;
20598 it->string_from_prefix_prop_p = true;
20599 it->multibyte_p = STRING_MULTIBYTE (it->string);
20600 it->current.overlay_string_index = -1;
20601 IT_STRING_CHARPOS (*it) = IT_STRING_BYTEPOS (*it) = 0;
20602 it->end_charpos = it->string_nchars = SCHARS (it->string);
20603 it->method = GET_FROM_STRING;
20604 it->stop_charpos = 0;
20605 it->prev_stop = 0;
20606 it->base_level_stop = 0;
20607 it->cmp_it.id = -1;
20609 /* Force paragraph direction to be that of the parent
20610 buffer/string. */
20611 if (it->bidi_p && it->bidi_it.paragraph_dir == R2L)
20612 it->paragraph_embedding = it->bidi_it.paragraph_dir;
20613 else
20614 it->paragraph_embedding = L2R;
20616 /* Set up the bidi iterator for this display string. */
20617 if (it->bidi_p)
20619 it->bidi_it.string.lstring = it->string;
20620 it->bidi_it.string.s = NULL;
20621 it->bidi_it.string.schars = it->end_charpos;
20622 it->bidi_it.string.bufpos = IT_CHARPOS (*it);
20623 it->bidi_it.string.from_disp_str = it->string_from_display_prop_p;
20624 it->bidi_it.string.unibyte = !it->multibyte_p;
20625 it->bidi_it.w = it->w;
20626 bidi_init_it (0, 0, FRAME_WINDOW_P (it->f), &it->bidi_it);
20629 else if (CONSP (prop) && EQ (XCAR (prop), Qspace))
20631 it->method = GET_FROM_STRETCH;
20632 it->object = prop;
20634 #ifdef HAVE_WINDOW_SYSTEM
20635 else if (IMAGEP (prop))
20637 it->what = IT_IMAGE;
20638 it->image_id = lookup_image (it->f, prop);
20639 it->method = GET_FROM_IMAGE;
20641 #endif /* HAVE_WINDOW_SYSTEM */
20642 else
20644 pop_it (it); /* bogus display property, give up */
20645 return false;
20648 return true;
20651 /* Return the character-property PROP at the current position in IT. */
20653 static Lisp_Object
20654 get_it_property (struct it *it, Lisp_Object prop)
20656 Lisp_Object position, object = it->object;
20658 if (STRINGP (object))
20659 position = make_number (IT_STRING_CHARPOS (*it));
20660 else if (BUFFERP (object))
20662 position = make_number (IT_CHARPOS (*it));
20663 object = it->window;
20665 else
20666 return Qnil;
20668 return Fget_char_property (position, prop, object);
20671 /* See if there's a line- or wrap-prefix, and if so, push it on IT. */
20673 static void
20674 handle_line_prefix (struct it *it)
20676 Lisp_Object prefix;
20678 if (it->continuation_lines_width > 0)
20680 prefix = get_it_property (it, Qwrap_prefix);
20681 if (NILP (prefix))
20682 prefix = Vwrap_prefix;
20684 else
20686 prefix = get_it_property (it, Qline_prefix);
20687 if (NILP (prefix))
20688 prefix = Vline_prefix;
20690 if (! NILP (prefix) && push_prefix_prop (it, prefix))
20692 /* If the prefix is wider than the window, and we try to wrap
20693 it, it would acquire its own wrap prefix, and so on till the
20694 iterator stack overflows. So, don't wrap the prefix. */
20695 it->line_wrap = TRUNCATE;
20696 it->avoid_cursor_p = true;
20702 /* Remove N glyphs at the start of a reversed IT->glyph_row. Called
20703 only for R2L lines from display_line and display_string, when they
20704 decide that too many glyphs were produced by PRODUCE_GLYPHS, and
20705 the line/string needs to be continued on the next glyph row. */
20706 static void
20707 unproduce_glyphs (struct it *it, int n)
20709 struct glyph *glyph, *end;
20711 eassert (it->glyph_row);
20712 eassert (it->glyph_row->reversed_p);
20713 eassert (it->area == TEXT_AREA);
20714 eassert (n <= it->glyph_row->used[TEXT_AREA]);
20716 if (n > it->glyph_row->used[TEXT_AREA])
20717 n = it->glyph_row->used[TEXT_AREA];
20718 glyph = it->glyph_row->glyphs[TEXT_AREA] + n;
20719 end = it->glyph_row->glyphs[TEXT_AREA] + it->glyph_row->used[TEXT_AREA];
20720 for ( ; glyph < end; glyph++)
20721 glyph[-n] = *glyph;
20724 /* Find the positions in a bidi-reordered ROW to serve as ROW->minpos
20725 and ROW->maxpos. */
20726 static void
20727 find_row_edges (struct it *it, struct glyph_row *row,
20728 ptrdiff_t min_pos, ptrdiff_t min_bpos,
20729 ptrdiff_t max_pos, ptrdiff_t max_bpos)
20731 /* FIXME: Revisit this when glyph ``spilling'' in continuation
20732 lines' rows is implemented for bidi-reordered rows. */
20734 /* ROW->minpos is the value of min_pos, the minimal buffer position
20735 we have in ROW, or ROW->start.pos if that is smaller. */
20736 if (min_pos <= ZV && min_pos < row->start.pos.charpos)
20737 SET_TEXT_POS (row->minpos, min_pos, min_bpos);
20738 else
20739 /* We didn't find buffer positions smaller than ROW->start, or
20740 didn't find _any_ valid buffer positions in any of the glyphs,
20741 so we must trust the iterator's computed positions. */
20742 row->minpos = row->start.pos;
20743 if (max_pos <= 0)
20745 max_pos = CHARPOS (it->current.pos);
20746 max_bpos = BYTEPOS (it->current.pos);
20749 /* Here are the various use-cases for ending the row, and the
20750 corresponding values for ROW->maxpos:
20752 Line ends in a newline from buffer eol_pos + 1
20753 Line is continued from buffer max_pos + 1
20754 Line is truncated on right it->current.pos
20755 Line ends in a newline from string max_pos + 1(*)
20756 (*) + 1 only when line ends in a forward scan
20757 Line is continued from string max_pos
20758 Line is continued from display vector max_pos
20759 Line is entirely from a string min_pos == max_pos
20760 Line is entirely from a display vector min_pos == max_pos
20761 Line that ends at ZV ZV
20763 If you discover other use-cases, please add them here as
20764 appropriate. */
20765 if (row->ends_at_zv_p)
20766 row->maxpos = it->current.pos;
20767 else if (row->used[TEXT_AREA])
20769 bool seen_this_string = false;
20770 struct glyph_row *r1 = row - 1;
20772 /* Did we see the same display string on the previous row? */
20773 if (STRINGP (it->object)
20774 /* this is not the first row */
20775 && row > it->w->desired_matrix->rows
20776 /* previous row is not the header line */
20777 && !r1->mode_line_p
20778 /* previous row also ends in a newline from a string */
20779 && r1->ends_in_newline_from_string_p)
20781 struct glyph *start, *end;
20783 /* Search for the last glyph of the previous row that came
20784 from buffer or string. Depending on whether the row is
20785 L2R or R2L, we need to process it front to back or the
20786 other way round. */
20787 if (!r1->reversed_p)
20789 start = r1->glyphs[TEXT_AREA];
20790 end = start + r1->used[TEXT_AREA];
20791 /* Glyphs inserted by redisplay have nil as their object. */
20792 while (end > start
20793 && NILP ((end - 1)->object)
20794 && (end - 1)->charpos <= 0)
20795 --end;
20796 if (end > start)
20798 if (EQ ((end - 1)->object, it->object))
20799 seen_this_string = true;
20801 else
20802 /* If all the glyphs of the previous row were inserted
20803 by redisplay, it means the previous row was
20804 produced from a single newline, which is only
20805 possible if that newline came from the same string
20806 as the one which produced this ROW. */
20807 seen_this_string = true;
20809 else
20811 end = r1->glyphs[TEXT_AREA] - 1;
20812 start = end + r1->used[TEXT_AREA];
20813 while (end < start
20814 && NILP ((end + 1)->object)
20815 && (end + 1)->charpos <= 0)
20816 ++end;
20817 if (end < start)
20819 if (EQ ((end + 1)->object, it->object))
20820 seen_this_string = true;
20822 else
20823 seen_this_string = true;
20826 /* Take note of each display string that covers a newline only
20827 once, the first time we see it. This is for when a display
20828 string includes more than one newline in it. */
20829 if (row->ends_in_newline_from_string_p && !seen_this_string)
20831 /* If we were scanning the buffer forward when we displayed
20832 the string, we want to account for at least one buffer
20833 position that belongs to this row (position covered by
20834 the display string), so that cursor positioning will
20835 consider this row as a candidate when point is at the end
20836 of the visual line represented by this row. This is not
20837 required when scanning back, because max_pos will already
20838 have a much larger value. */
20839 if (CHARPOS (row->end.pos) > max_pos)
20840 INC_BOTH (max_pos, max_bpos);
20841 SET_TEXT_POS (row->maxpos, max_pos, max_bpos);
20843 else if (CHARPOS (it->eol_pos) > 0)
20844 SET_TEXT_POS (row->maxpos,
20845 CHARPOS (it->eol_pos) + 1, BYTEPOS (it->eol_pos) + 1);
20846 else if (row->continued_p)
20848 /* If max_pos is different from IT's current position, it
20849 means IT->method does not belong to the display element
20850 at max_pos. However, it also means that the display
20851 element at max_pos was displayed in its entirety on this
20852 line, which is equivalent to saying that the next line
20853 starts at the next buffer position. */
20854 if (IT_CHARPOS (*it) == max_pos && it->method != GET_FROM_BUFFER)
20855 SET_TEXT_POS (row->maxpos, max_pos, max_bpos);
20856 else
20858 INC_BOTH (max_pos, max_bpos);
20859 SET_TEXT_POS (row->maxpos, max_pos, max_bpos);
20862 else if (row->truncated_on_right_p)
20863 /* display_line already called reseat_at_next_visible_line_start,
20864 which puts the iterator at the beginning of the next line, in
20865 the logical order. */
20866 row->maxpos = it->current.pos;
20867 else if (max_pos == min_pos && it->method != GET_FROM_BUFFER)
20868 /* A line that is entirely from a string/image/stretch... */
20869 row->maxpos = row->minpos;
20870 else
20871 emacs_abort ();
20873 else
20874 row->maxpos = it->current.pos;
20877 /* Like display_count_lines, but capable of counting outside of the
20878 current narrowed region. */
20879 static ptrdiff_t
20880 display_count_lines_logically (ptrdiff_t start_byte, ptrdiff_t limit_byte,
20881 ptrdiff_t count, ptrdiff_t *byte_pos_ptr)
20883 if (!display_line_numbers_widen || (BEGV == BEG && ZV == Z))
20884 return display_count_lines (start_byte, limit_byte, count, byte_pos_ptr);
20886 ptrdiff_t val;
20887 ptrdiff_t pdl_count = SPECPDL_INDEX ();
20888 record_unwind_protect (save_restriction_restore, save_restriction_save ());
20889 Fwiden ();
20890 val = display_count_lines (start_byte, limit_byte, count, byte_pos_ptr);
20891 unbind_to (pdl_count, Qnil);
20892 return val;
20895 /* Count the number of screen lines in window IT->w between character
20896 position IT_CHARPOS(*IT) and the line showing that window's point. */
20897 static ptrdiff_t
20898 display_count_lines_visually (struct it *it)
20900 struct it tem_it;
20901 ptrdiff_t to;
20902 struct text_pos from;
20904 /* If we already calculated a relative line number, use that. This
20905 trick relies on the fact that visual lines (a.k.a. "glyph rows")
20906 are laid out sequentially, one by one, for each sequence of calls
20907 to display_line or other similar function that follows a call to
20908 init_iterator. */
20909 if (it->lnum_bytepos > 0)
20910 return it->lnum + 1;
20911 else
20913 ptrdiff_t count = SPECPDL_INDEX ();
20915 if (IT_CHARPOS (*it) <= PT)
20917 from = it->current.pos;
20918 to = PT;
20920 else
20922 SET_TEXT_POS (from, PT, PT_BYTE);
20923 to = IT_CHARPOS (*it);
20925 start_display (&tem_it, it->w, from);
20926 /* Need to disable visual mode temporarily, since otherwise the
20927 call to move_it_to will cause infinite recursion. */
20928 specbind (Qdisplay_line_numbers, Qrelative);
20929 /* Some redisplay optimizations could invoke us very far from
20930 PT, which will make the caller painfully slow. There should
20931 be no need to go too far beyond the window's bottom, as any
20932 such optimization will fail to show point anyway. */
20933 move_it_to (&tem_it, to, -1,
20934 tem_it.last_visible_y
20935 + (SCROLL_LIMIT + 10) * FRAME_LINE_HEIGHT (tem_it.f),
20936 -1, MOVE_TO_POS | MOVE_TO_Y);
20937 unbind_to (count, Qnil);
20938 return IT_CHARPOS (*it) <= PT ? -tem_it.vpos : tem_it.vpos;
20942 /* Produce the line-number glyphs for the current glyph_row. If
20943 IT->glyph_row is non-NULL, populate the row with the produced
20944 glyphs. */
20945 static void
20946 maybe_produce_line_number (struct it *it)
20948 ptrdiff_t last_line = it->lnum;
20949 ptrdiff_t start_from, bytepos;
20950 ptrdiff_t this_line;
20951 bool first_time = false;
20952 ptrdiff_t beg_byte = display_line_numbers_widen ? BEG_BYTE : BEGV_BYTE;
20953 ptrdiff_t z_byte = display_line_numbers_widen ? Z_BYTE : ZV_BYTE;
20954 void *itdata = bidi_shelve_cache ();
20956 if (EQ (Vdisplay_line_numbers, Qvisual))
20957 this_line = display_count_lines_visually (it);
20958 else
20960 if (!last_line)
20962 /* If possible, reuse data cached by line-number-mode. */
20963 if (it->w->base_line_number > 0
20964 && it->w->base_line_pos > 0
20965 && it->w->base_line_pos <= IT_CHARPOS (*it)
20966 /* line-number-mode always displays narrowed line
20967 numbers, so we cannot use its data if the user wants
20968 line numbers that disregard narrowing, or if the
20969 buffer's narrowing has just changed. */
20970 && !(display_line_numbers_widen
20971 && (BEG_BYTE != BEGV_BYTE || Z_BYTE != ZV_BYTE))
20972 && !current_buffer->clip_changed)
20974 start_from = CHAR_TO_BYTE (it->w->base_line_pos);
20975 last_line = it->w->base_line_number - 1;
20977 else
20978 start_from = beg_byte;
20979 if (!it->lnum_bytepos)
20980 first_time = true;
20982 else
20983 start_from = it->lnum_bytepos;
20985 /* Paranoia: what if someone changes the narrowing since the
20986 last time display_line was called? Shouldn't really happen,
20987 but who knows what some crazy Lisp invoked by :eval could do? */
20988 if (!(beg_byte <= start_from && start_from <= z_byte))
20990 last_line = 0;
20991 start_from = beg_byte;
20994 this_line =
20995 last_line + display_count_lines_logically (start_from,
20996 IT_BYTEPOS (*it),
20997 IT_CHARPOS (*it), &bytepos);
20998 eassert (this_line > 0 || (this_line == 0 && start_from == beg_byte));
20999 eassert (bytepos == IT_BYTEPOS (*it));
21002 /* Record the line number information. */
21003 if (this_line != last_line || !it->lnum_bytepos)
21005 it->lnum = this_line;
21006 it->lnum_bytepos = IT_BYTEPOS (*it);
21009 /* Produce the glyphs for the line number. */
21010 struct it tem_it;
21011 char lnum_buf[INT_STRLEN_BOUND (ptrdiff_t) + 1];
21012 bool beyond_zv = IT_BYTEPOS (*it) >= ZV_BYTE ? true : false;
21013 ptrdiff_t lnum_offset = -1; /* to produce 1-based line numbers */
21014 int lnum_face_id = merge_faces (it->f, Qline_number, 0, DEFAULT_FACE_ID);
21015 int current_lnum_face_id
21016 = merge_faces (it->f, Qline_number_current_line, 0, DEFAULT_FACE_ID);
21017 /* Compute point's line number if needed. */
21018 if ((EQ (Vdisplay_line_numbers, Qrelative)
21019 || EQ (Vdisplay_line_numbers, Qvisual)
21020 || lnum_face_id != current_lnum_face_id)
21021 && !it->pt_lnum)
21023 ptrdiff_t ignored;
21024 if (PT_BYTE > it->lnum_bytepos && !EQ (Vdisplay_line_numbers, Qvisual))
21025 it->pt_lnum =
21026 this_line + display_count_lines_logically (it->lnum_bytepos, PT_BYTE,
21027 PT, &ignored);
21028 else
21029 it->pt_lnum = display_count_lines_logically (beg_byte, PT_BYTE, PT,
21030 &ignored);
21032 /* Compute the required width if needed. */
21033 if (!it->lnum_width)
21035 if (NATNUMP (Vdisplay_line_numbers_width))
21036 it->lnum_width = XFASTINT (Vdisplay_line_numbers_width);
21038 /* Max line number to be displayed cannot be more than the one
21039 corresponding to the last row of the desired matrix. */
21040 ptrdiff_t max_lnum;
21042 if (NILP (Vdisplay_line_numbers_current_absolute)
21043 && (EQ (Vdisplay_line_numbers, Qrelative)
21044 || EQ (Vdisplay_line_numbers, Qvisual)))
21045 /* We subtract one more because the current line is always
21046 zero in this mode. */
21047 max_lnum = it->w->desired_matrix->nrows - 2;
21048 else if (EQ (Vdisplay_line_numbers, Qvisual))
21049 max_lnum = it->pt_lnum + it->w->desired_matrix->nrows - 1;
21050 else
21051 max_lnum = this_line + it->w->desired_matrix->nrows - 1 - it->vpos;
21052 max_lnum = max (1, max_lnum);
21053 it->lnum_width = max (it->lnum_width, log10 (max_lnum) + 1);
21054 eassert (it->lnum_width > 0);
21056 if (EQ (Vdisplay_line_numbers, Qrelative))
21057 lnum_offset = it->pt_lnum;
21058 else if (EQ (Vdisplay_line_numbers, Qvisual))
21059 lnum_offset = 0;
21061 /* Under 'relative', display the absolute line number for the
21062 current line, unless the user requests otherwise. */
21063 ptrdiff_t lnum_to_display = eabs (this_line - lnum_offset);
21064 if ((EQ (Vdisplay_line_numbers, Qrelative)
21065 || EQ (Vdisplay_line_numbers, Qvisual))
21066 && lnum_to_display == 0
21067 && !NILP (Vdisplay_line_numbers_current_absolute))
21068 lnum_to_display = it->pt_lnum + 1;
21069 /* In L2R rows we need to append the blank separator, in R2L
21070 rows we need to prepend it. But this function is usually
21071 called when no display elements were produced from the
21072 following line, so the paragraph direction might be unknown.
21073 Therefore we cheat and add 2 blanks, one on either side. */
21074 pint2str (lnum_buf, it->lnum_width + 1, lnum_to_display);
21075 strcat (lnum_buf, " ");
21077 /* Setup for producing the glyphs. */
21078 init_iterator (&tem_it, it->w, -1, -1, &scratch_glyph_row,
21079 /* FIXME: Use specialized face. */
21080 DEFAULT_FACE_ID);
21081 scratch_glyph_row.reversed_p = false;
21082 scratch_glyph_row.used[TEXT_AREA] = 0;
21083 SET_TEXT_POS (tem_it.position, 0, 0);
21084 tem_it.avoid_cursor_p = true;
21085 tem_it.bidi_p = true;
21086 tem_it.bidi_it.type = WEAK_EN;
21087 /* According to UAX#9, EN goes up 2 levels in L2R paragraph and
21088 1 level in R2L paragraphs. Emulate that, assuming we are in
21089 an L2R paragraph. */
21090 tem_it.bidi_it.resolved_level = 2;
21092 /* Produce glyphs for the line number in a scratch glyph_row. */
21093 int n_glyphs_before;
21094 for (const char *p = lnum_buf; *p; p++)
21096 /* For continuation lines and lines after ZV, instead of a line
21097 number, produce a blank prefix of the same width. Use the
21098 default face for the blank field beyond ZV. */
21099 if (beyond_zv)
21100 tem_it.face_id = it->base_face_id;
21101 else if (lnum_face_id != current_lnum_face_id
21102 && (EQ (Vdisplay_line_numbers, Qvisual)
21103 ? this_line == 0
21104 : this_line == it->pt_lnum))
21105 tem_it.face_id = current_lnum_face_id;
21106 else
21107 tem_it.face_id = lnum_face_id;
21108 if (beyond_zv
21109 /* Don't display the same line number more than once. */
21110 || (!EQ (Vdisplay_line_numbers, Qvisual)
21111 && (it->continuation_lines_width > 0
21112 || (this_line == last_line && !first_time))))
21113 tem_it.c = tem_it.char_to_display = ' ';
21114 else
21115 tem_it.c = tem_it.char_to_display = *p;
21116 tem_it.len = 1;
21117 n_glyphs_before = scratch_glyph_row.used[TEXT_AREA];
21118 /* Make sure these glyphs will have a "position" of -1. */
21119 SET_TEXT_POS (tem_it.position, -1, -1);
21120 PRODUCE_GLYPHS (&tem_it);
21122 /* Stop producing glyphs if we don't have enough space on
21123 this line. FIXME: should we refrain from producing the
21124 line number at all in that case? */
21125 if (tem_it.current_x > tem_it.last_visible_x)
21127 scratch_glyph_row.used[TEXT_AREA] = n_glyphs_before;
21128 break;
21132 /* Record the width in pixels we need for the line number display. */
21133 it->lnum_pixel_width = tem_it.current_x;
21134 /* Copy the produced glyphs into IT's glyph_row. */
21135 struct glyph *g = scratch_glyph_row.glyphs[TEXT_AREA];
21136 struct glyph *e = g + scratch_glyph_row.used[TEXT_AREA];
21137 struct glyph *p = it->glyph_row ? it->glyph_row->glyphs[TEXT_AREA] : NULL;
21138 short *u = it->glyph_row ? &it->glyph_row->used[TEXT_AREA] : NULL;
21140 eassert (it->glyph_row == NULL || it->glyph_row->used[TEXT_AREA] == 0);
21142 for ( ; g < e; g++)
21144 it->current_x += g->pixel_width;
21145 /* The following is important when this function is called
21146 from move_it_in_display_line_to: HPOS is incremented only
21147 when we are in the visible portion of the glyph row. */
21148 if (it->current_x > it->first_visible_x)
21149 it->hpos++;
21150 if (p)
21152 *p++ = *g;
21153 (*u)++;
21157 /* Update IT's metrics due to glyphs produced for line numbers. */
21158 if (it->glyph_row)
21160 struct glyph_row *row = it->glyph_row;
21162 it->max_ascent = max (row->ascent, tem_it.max_ascent);
21163 it->max_descent = max (row->height - row->ascent, tem_it.max_descent);
21164 it->max_phys_ascent = max (row->phys_ascent, tem_it.max_phys_ascent);
21165 it->max_phys_descent = max (row->phys_height - row->phys_ascent,
21166 tem_it.max_phys_descent);
21168 else
21170 it->max_ascent = max (it->max_ascent, tem_it.max_ascent);
21171 it->max_descent = max (it->max_descent, tem_it.max_descent);
21172 it->max_phys_ascent = max (it->max_phys_ascent, tem_it.max_phys_ascent);
21173 it->max_phys_descent = max (it->max_phys_descent, tem_it.max_phys_descent);
21176 bidi_unshelve_cache (itdata, false);
21179 /* Return true if this glyph row needs a line number to be produced
21180 for it. */
21181 static bool
21182 should_produce_line_number (struct it *it)
21184 if (NILP (Vdisplay_line_numbers))
21185 return false;
21187 /* Don't display line numbers in minibuffer windows. */
21188 if (MINI_WINDOW_P (it->w))
21189 return false;
21191 #ifdef HAVE_WINDOW_SYSTEM
21192 /* Don't display line number in tooltip frames. */
21193 if (FRAME_TOOLTIP_P (XFRAME (WINDOW_FRAME (it->w))))
21194 return false;
21195 #endif
21197 /* If the character at current position has a non-nil special
21198 property, disable line numbers for this row. This is for
21199 packages such as company-mode, which need this for their tricky
21200 layout, where line numbers get in the way. */
21201 Lisp_Object val = Fget_char_property (make_number (IT_CHARPOS (*it)),
21202 Qdisplay_line_numbers_disable,
21203 it->window);
21204 /* For ZV, we need to also look in empty overlays at that point,
21205 because get-char-property always returns nil for ZV, except if
21206 the property is in 'default-text-properties'. */
21207 if (NILP (val) && IT_CHARPOS (*it) >= ZV)
21208 val = disable_line_numbers_overlay_at_eob ();
21209 return NILP (val) ? true : false;
21212 /* Return true if ROW has no glyphs except those inserted by the
21213 display engine. This is needed for indicate-empty-lines and
21214 similar features when the glyph row starts with glyphs which didn't
21215 come from buffer or string. */
21216 static bool
21217 row_text_area_empty (struct glyph_row *row)
21219 if (!row->reversed_p)
21221 for (struct glyph *g = row->glyphs[TEXT_AREA];
21222 g < row->glyphs[TEXT_AREA] + row->used[TEXT_AREA];
21223 g++)
21224 if (!NILP (g->object) || g->charpos > 0)
21225 return false;
21227 else
21229 for (struct glyph *g = row->glyphs[TEXT_AREA] + row->used[TEXT_AREA] - 1;
21230 g > row->glyphs[TEXT_AREA];
21231 g--)
21232 if (!NILP ((g - 1)->object) || (g - 1)->charpos > 0)
21233 return false;
21236 return true;
21239 /* Construct the glyph row IT->glyph_row in the desired matrix of
21240 IT->w from text at the current position of IT. See dispextern.h
21241 for an overview of struct it. Value is true if
21242 IT->glyph_row displays text, as opposed to a line displaying ZV
21243 only. CURSOR_VPOS is the window-relative vertical position of
21244 the glyph row displaying the cursor, or -1 if unknown. */
21246 static bool
21247 display_line (struct it *it, int cursor_vpos)
21249 struct glyph_row *row = it->glyph_row;
21250 Lisp_Object overlay_arrow_string;
21251 struct it wrap_it;
21252 void *wrap_data = NULL;
21253 bool may_wrap = false;
21254 int wrap_x UNINIT;
21255 int wrap_row_used = -1;
21256 int wrap_row_ascent UNINIT, wrap_row_height UNINIT;
21257 int wrap_row_phys_ascent UNINIT, wrap_row_phys_height UNINIT;
21258 int wrap_row_extra_line_spacing UNINIT;
21259 ptrdiff_t wrap_row_min_pos UNINIT, wrap_row_min_bpos UNINIT;
21260 ptrdiff_t wrap_row_max_pos UNINIT, wrap_row_max_bpos UNINIT;
21261 int cvpos;
21262 ptrdiff_t min_pos = ZV + 1, max_pos = 0;
21263 ptrdiff_t min_bpos UNINIT, max_bpos UNINIT;
21264 bool pending_handle_line_prefix = false;
21265 int header_line = window_wants_header_line (it->w);
21266 bool hscroll_this_line = (cursor_vpos >= 0
21267 && it->vpos == cursor_vpos - header_line
21268 && hscrolling_current_line_p (it->w));
21269 int first_visible_x = it->first_visible_x;
21270 int last_visible_x = it->last_visible_x;
21271 int x_incr = 0;
21273 /* We always start displaying at hpos zero even if hscrolled. */
21274 eassert (it->hpos == 0 && it->current_x == 0);
21276 if (MATRIX_ROW_VPOS (row, it->w->desired_matrix)
21277 >= it->w->desired_matrix->nrows)
21279 it->w->nrows_scale_factor++;
21280 it->f->fonts_changed = true;
21281 return false;
21284 /* Clear the result glyph row and enable it. */
21285 prepare_desired_row (it->w, row, false);
21287 row->y = it->current_y;
21288 row->start = it->start;
21289 row->continuation_lines_width = it->continuation_lines_width;
21290 row->displays_text_p = true;
21291 row->starts_in_middle_of_char_p = it->starts_in_middle_of_char_p;
21292 it->starts_in_middle_of_char_p = false;
21294 /* Arrange the overlays nicely for our purposes. Usually, we call
21295 display_line on only one line at a time, in which case this
21296 can't really hurt too much, or we call it on lines which appear
21297 one after another in the buffer, in which case all calls to
21298 recenter_overlay_lists but the first will be pretty cheap. */
21299 recenter_overlay_lists (current_buffer, IT_CHARPOS (*it));
21301 /* If we are going to display the cursor's line, account for the
21302 hscroll of that line. We subtract the window's min_hscroll,
21303 because that was already accounted for in init_iterator. */
21304 if (hscroll_this_line)
21305 x_incr =
21306 (window_hscroll_limited (it->w, it->f) - it->w->min_hscroll)
21307 * FRAME_COLUMN_WIDTH (it->f);
21309 bool line_number_needed = should_produce_line_number (it);
21311 /* Move over display elements that are not visible because we are
21312 hscrolled. This may stop at an x-position < first_visible_x
21313 if the first glyph is partially visible or if we hit a line end. */
21314 if (it->current_x < it->first_visible_x + x_incr)
21316 enum move_it_result move_result;
21318 this_line_min_pos = row->start.pos;
21319 if (hscroll_this_line)
21321 it->first_visible_x += x_incr;
21322 it->last_visible_x += x_incr;
21324 move_result = move_it_in_display_line_to (it, ZV, it->first_visible_x,
21325 MOVE_TO_POS | MOVE_TO_X);
21326 /* If we are under a large hscroll, move_it_in_display_line_to
21327 could hit the end of the line without reaching
21328 first_visible_x. Pretend that we did reach it. This is
21329 especially important on a TTY, where we will call
21330 extend_face_to_end_of_line, which needs to know how many
21331 blank glyphs to produce. */
21332 if (it->current_x < it->first_visible_x
21333 && (move_result == MOVE_NEWLINE_OR_CR
21334 || move_result == MOVE_POS_MATCH_OR_ZV))
21335 it->current_x = it->first_visible_x;
21337 /* Record the smallest positions seen while we moved over
21338 display elements that are not visible. This is needed by
21339 redisplay_internal for optimizing the case where the cursor
21340 stays inside the same line. The rest of this function only
21341 considers positions that are actually displayed, so
21342 RECORD_MAX_MIN_POS will not otherwise record positions that
21343 are hscrolled to the left of the left edge of the window. */
21344 min_pos = CHARPOS (this_line_min_pos);
21345 min_bpos = BYTEPOS (this_line_min_pos);
21347 /* Produce line number, if needed. */
21348 if (line_number_needed)
21349 maybe_produce_line_number (it);
21351 else if (it->area == TEXT_AREA)
21353 /* Line numbers should precede the line-prefix or wrap-prefix. */
21354 if (line_number_needed)
21355 maybe_produce_line_number (it);
21357 /* We only do this when not calling move_it_in_display_line_to
21358 above, because that function calls itself handle_line_prefix. */
21359 handle_line_prefix (it);
21361 else
21363 /* Line-prefix and wrap-prefix are always displayed in the text
21364 area. But if this is the first call to display_line after
21365 init_iterator, the iterator might have been set up to write
21366 into a marginal area, e.g. if the line begins with some
21367 display property that writes to the margins. So we need to
21368 wait with the call to handle_line_prefix until whatever
21369 writes to the margin has done its job. */
21370 pending_handle_line_prefix = true;
21373 /* Get the initial row height. This is either the height of the
21374 text hscrolled, if there is any, or zero. */
21375 row->ascent = it->max_ascent;
21376 row->height = it->max_ascent + it->max_descent;
21377 row->phys_ascent = it->max_phys_ascent;
21378 row->phys_height = it->max_phys_ascent + it->max_phys_descent;
21379 row->extra_line_spacing = it->max_extra_line_spacing;
21381 /* Utility macro to record max and min buffer positions seen until now. */
21382 #define RECORD_MAX_MIN_POS(IT) \
21383 do \
21385 bool composition_p \
21386 = !STRINGP ((IT)->string) && ((IT)->what == IT_COMPOSITION); \
21387 ptrdiff_t current_pos = \
21388 composition_p ? (IT)->cmp_it.charpos \
21389 : IT_CHARPOS (*(IT)); \
21390 ptrdiff_t current_bpos = \
21391 composition_p ? CHAR_TO_BYTE (current_pos) \
21392 : IT_BYTEPOS (*(IT)); \
21393 if (current_pos < min_pos) \
21395 min_pos = current_pos; \
21396 min_bpos = current_bpos; \
21398 if (IT_CHARPOS (*it) > max_pos) \
21400 max_pos = IT_CHARPOS (*it); \
21401 max_bpos = IT_BYTEPOS (*it); \
21404 while (false)
21406 /* Loop generating characters. The loop is left with IT on the next
21407 character to display. */
21408 while (true)
21410 int n_glyphs_before, hpos_before, x_before;
21411 int x, nglyphs;
21412 int ascent = 0, descent = 0, phys_ascent = 0, phys_descent = 0;
21414 /* Retrieve the next thing to display. Value is false if end of
21415 buffer reached. */
21416 if (!get_next_display_element (it))
21418 bool row_has_glyphs = false;
21419 /* Maybe add a space at the end of this line that is used to
21420 display the cursor there under X. Set the charpos of the
21421 first glyph of blank lines not corresponding to any text
21422 to -1. */
21423 if (IT_OVERFLOW_NEWLINE_INTO_FRINGE (it))
21424 row->exact_window_width_line_p = true;
21425 else if ((append_space_for_newline (it, true)
21426 && row->used[TEXT_AREA] == 1)
21427 || row->used[TEXT_AREA] == 0
21428 || (row_has_glyphs = row_text_area_empty (row)))
21430 row->glyphs[TEXT_AREA]->charpos = -1;
21431 /* Don't reset the displays_text_p flag if we are
21432 displaying line numbers or line-prefix. */
21433 if (!row_has_glyphs)
21434 row->displays_text_p = false;
21436 if (!NILP (BVAR (XBUFFER (it->w->contents), indicate_empty_lines))
21437 && (!MINI_WINDOW_P (it->w)))
21438 row->indicate_empty_line_p = true;
21441 it->continuation_lines_width = 0;
21442 /* Reset those iterator values set from display property
21443 values. This is for the case when the display property
21444 ends at ZV, and is not a replacing property, so pop_it is
21445 not called. */
21446 it->font_height = Qnil;
21447 it->voffset = 0;
21448 row->ends_at_zv_p = true;
21449 /* A row that displays right-to-left text must always have
21450 its last face extended all the way to the end of line,
21451 even if this row ends in ZV, because we still write to
21452 the screen left to right. We also need to extend the
21453 last face if the default face is remapped to some
21454 different face, otherwise the functions that clear
21455 portions of the screen will clear with the default face's
21456 background color. */
21457 if (row->reversed_p
21458 || lookup_basic_face (it->f, DEFAULT_FACE_ID) != DEFAULT_FACE_ID)
21459 extend_face_to_end_of_line (it);
21460 break;
21463 /* Now, get the metrics of what we want to display. This also
21464 generates glyphs in `row' (which is IT->glyph_row). */
21465 n_glyphs_before = row->used[TEXT_AREA];
21466 x = it->current_x;
21468 /* Remember the line height so far in case the next element doesn't
21469 fit on the line. */
21470 if (it->line_wrap != TRUNCATE)
21472 ascent = it->max_ascent;
21473 descent = it->max_descent;
21474 phys_ascent = it->max_phys_ascent;
21475 phys_descent = it->max_phys_descent;
21477 if (it->line_wrap == WORD_WRAP && it->area == TEXT_AREA)
21479 if (IT_DISPLAYING_WHITESPACE (it))
21480 may_wrap = true;
21481 else if (may_wrap)
21483 SAVE_IT (wrap_it, *it, wrap_data);
21484 wrap_x = x;
21485 wrap_row_used = row->used[TEXT_AREA];
21486 wrap_row_ascent = row->ascent;
21487 wrap_row_height = row->height;
21488 wrap_row_phys_ascent = row->phys_ascent;
21489 wrap_row_phys_height = row->phys_height;
21490 wrap_row_extra_line_spacing = row->extra_line_spacing;
21491 wrap_row_min_pos = min_pos;
21492 wrap_row_min_bpos = min_bpos;
21493 wrap_row_max_pos = max_pos;
21494 wrap_row_max_bpos = max_bpos;
21495 may_wrap = false;
21500 PRODUCE_GLYPHS (it);
21502 /* If this display element was in marginal areas, continue with
21503 the next one. */
21504 if (it->area != TEXT_AREA)
21506 row->ascent = max (row->ascent, it->max_ascent);
21507 row->height = max (row->height, it->max_ascent + it->max_descent);
21508 row->phys_ascent = max (row->phys_ascent, it->max_phys_ascent);
21509 row->phys_height = max (row->phys_height,
21510 it->max_phys_ascent + it->max_phys_descent);
21511 row->extra_line_spacing = max (row->extra_line_spacing,
21512 it->max_extra_line_spacing);
21513 set_iterator_to_next (it, true);
21514 /* If we didn't handle the line/wrap prefix above, and the
21515 call to set_iterator_to_next just switched to TEXT_AREA,
21516 process the prefix now. */
21517 if (it->area == TEXT_AREA && pending_handle_line_prefix)
21519 /* Line numbers should precede the line-prefix or wrap-prefix. */
21520 if (line_number_needed)
21521 maybe_produce_line_number (it);
21523 pending_handle_line_prefix = false;
21524 handle_line_prefix (it);
21526 continue;
21529 /* Does the display element fit on the line? If we truncate
21530 lines, we should draw past the right edge of the window. If
21531 we don't truncate, we want to stop so that we can display the
21532 continuation glyph before the right margin. If lines are
21533 continued, there are two possible strategies for characters
21534 resulting in more than 1 glyph (e.g. tabs): Display as many
21535 glyphs as possible in this line and leave the rest for the
21536 continuation line, or display the whole element in the next
21537 line. Original redisplay did the former, so we do it also. */
21538 nglyphs = row->used[TEXT_AREA] - n_glyphs_before;
21539 hpos_before = it->hpos;
21540 x_before = x;
21542 if (/* Not a newline. */
21543 nglyphs > 0
21544 /* Glyphs produced fit entirely in the line. */
21545 && it->current_x < it->last_visible_x)
21547 it->hpos += nglyphs;
21548 row->ascent = max (row->ascent, it->max_ascent);
21549 row->height = max (row->height, it->max_ascent + it->max_descent);
21550 row->phys_ascent = max (row->phys_ascent, it->max_phys_ascent);
21551 row->phys_height = max (row->phys_height,
21552 it->max_phys_ascent + it->max_phys_descent);
21553 row->extra_line_spacing = max (row->extra_line_spacing,
21554 it->max_extra_line_spacing);
21555 if (it->current_x - it->pixel_width < it->first_visible_x
21556 /* In R2L rows, we arrange in extend_face_to_end_of_line
21557 to add a right offset to the line, by a suitable
21558 change to the stretch glyph that is the leftmost
21559 glyph of the line. */
21560 && !row->reversed_p)
21561 row->x = x - it->first_visible_x;
21562 /* Record the maximum and minimum buffer positions seen so
21563 far in glyphs that will be displayed by this row. */
21564 if (it->bidi_p)
21565 RECORD_MAX_MIN_POS (it);
21567 else
21569 int i, new_x;
21570 struct glyph *glyph;
21572 for (i = 0; i < nglyphs; ++i, x = new_x)
21574 /* Identify the glyphs added by the last call to
21575 PRODUCE_GLYPHS. In R2L rows, they are prepended to
21576 the previous glyphs. */
21577 if (!row->reversed_p)
21578 glyph = row->glyphs[TEXT_AREA] + n_glyphs_before + i;
21579 else
21580 glyph = row->glyphs[TEXT_AREA] + nglyphs - 1 - i;
21581 new_x = x + glyph->pixel_width;
21583 if (/* Lines are continued. */
21584 it->line_wrap != TRUNCATE
21585 && (/* Glyph doesn't fit on the line. */
21586 new_x > it->last_visible_x
21587 /* Or it fits exactly on a window system frame. */
21588 || (new_x == it->last_visible_x
21589 && FRAME_WINDOW_P (it->f)
21590 && (row->reversed_p
21591 ? WINDOW_LEFT_FRINGE_WIDTH (it->w)
21592 : WINDOW_RIGHT_FRINGE_WIDTH (it->w)))))
21594 /* End of a continued line. */
21596 if (it->hpos == 0
21597 || (new_x == it->last_visible_x
21598 && FRAME_WINDOW_P (it->f)
21599 && (row->reversed_p
21600 ? WINDOW_LEFT_FRINGE_WIDTH (it->w)
21601 : WINDOW_RIGHT_FRINGE_WIDTH (it->w))))
21603 /* Current glyph is the only one on the line or
21604 fits exactly on the line. We must continue
21605 the line because we can't draw the cursor
21606 after the glyph. */
21607 row->continued_p = true;
21608 it->current_x = new_x;
21609 it->continuation_lines_width += new_x;
21610 ++it->hpos;
21611 if (i == nglyphs - 1)
21613 /* If line-wrap is on, check if a previous
21614 wrap point was found. */
21615 if (!IT_OVERFLOW_NEWLINE_INTO_FRINGE (it)
21616 && wrap_row_used > 0
21617 /* Even if there is a previous wrap
21618 point, continue the line here as
21619 usual, if (i) the previous character
21620 was a space or tab AND (ii) the
21621 current character is not. */
21622 && (!may_wrap
21623 || IT_DISPLAYING_WHITESPACE (it)))
21624 goto back_to_wrap;
21626 /* Record the maximum and minimum buffer
21627 positions seen so far in glyphs that will be
21628 displayed by this row. */
21629 if (it->bidi_p)
21630 RECORD_MAX_MIN_POS (it);
21631 set_iterator_to_next (it, true);
21632 if (IT_OVERFLOW_NEWLINE_INTO_FRINGE (it))
21634 if (!get_next_display_element (it))
21636 row->exact_window_width_line_p = true;
21637 it->continuation_lines_width = 0;
21638 it->font_height = Qnil;
21639 it->voffset = 0;
21640 row->continued_p = false;
21641 row->ends_at_zv_p = true;
21643 else if (ITERATOR_AT_END_OF_LINE_P (it))
21645 row->continued_p = false;
21646 row->exact_window_width_line_p = true;
21648 /* If line-wrap is on, check if a
21649 previous wrap point was found. */
21650 else if (wrap_row_used > 0
21651 /* Even if there is a previous wrap
21652 point, continue the line here as
21653 usual, if (i) the previous character
21654 was a space or tab AND (ii) the
21655 current character is not. */
21656 && (!may_wrap
21657 || IT_DISPLAYING_WHITESPACE (it)))
21658 goto back_to_wrap;
21662 else if (it->bidi_p)
21663 RECORD_MAX_MIN_POS (it);
21664 if (WINDOW_LEFT_MARGIN_WIDTH (it->w) > 0
21665 || WINDOW_RIGHT_MARGIN_WIDTH (it->w) > 0)
21666 extend_face_to_end_of_line (it);
21668 else if (CHAR_GLYPH_PADDING_P (*glyph)
21669 && !FRAME_WINDOW_P (it->f))
21671 /* A padding glyph that doesn't fit on this line.
21672 This means the whole character doesn't fit
21673 on the line. */
21674 if (row->reversed_p)
21675 unproduce_glyphs (it, row->used[TEXT_AREA]
21676 - n_glyphs_before);
21677 row->used[TEXT_AREA] = n_glyphs_before;
21679 /* Fill the rest of the row with continuation
21680 glyphs like in 20.x. */
21681 while (row->glyphs[TEXT_AREA] + row->used[TEXT_AREA]
21682 < row->glyphs[1 + TEXT_AREA])
21683 produce_special_glyphs (it, IT_CONTINUATION);
21685 row->continued_p = true;
21686 it->current_x = x_before;
21687 it->continuation_lines_width += x_before;
21689 /* Restore the height to what it was before the
21690 element not fitting on the line. */
21691 it->max_ascent = ascent;
21692 it->max_descent = descent;
21693 it->max_phys_ascent = phys_ascent;
21694 it->max_phys_descent = phys_descent;
21695 if (WINDOW_LEFT_MARGIN_WIDTH (it->w) > 0
21696 || WINDOW_RIGHT_MARGIN_WIDTH (it->w) > 0)
21697 extend_face_to_end_of_line (it);
21699 else if (wrap_row_used > 0)
21701 back_to_wrap:
21702 if (row->reversed_p)
21703 unproduce_glyphs (it,
21704 row->used[TEXT_AREA] - wrap_row_used);
21705 RESTORE_IT (it, &wrap_it, wrap_data);
21706 it->continuation_lines_width += wrap_x;
21707 row->used[TEXT_AREA] = wrap_row_used;
21708 row->ascent = wrap_row_ascent;
21709 row->height = wrap_row_height;
21710 row->phys_ascent = wrap_row_phys_ascent;
21711 row->phys_height = wrap_row_phys_height;
21712 row->extra_line_spacing = wrap_row_extra_line_spacing;
21713 min_pos = wrap_row_min_pos;
21714 min_bpos = wrap_row_min_bpos;
21715 max_pos = wrap_row_max_pos;
21716 max_bpos = wrap_row_max_bpos;
21717 row->continued_p = true;
21718 row->ends_at_zv_p = false;
21719 row->exact_window_width_line_p = false;
21721 /* Make sure that a non-default face is extended
21722 up to the right margin of the window. */
21723 extend_face_to_end_of_line (it);
21725 else if ((it->what == IT_CHARACTER
21726 || it->what == IT_STRETCH
21727 || it->what == IT_COMPOSITION)
21728 && it->c == '\t' && FRAME_WINDOW_P (it->f))
21730 /* A TAB that extends past the right edge of the
21731 window. This produces a single glyph on
21732 window system frames. We leave the glyph in
21733 this row and let it fill the row, but don't
21734 consume the TAB. */
21735 if ((row->reversed_p
21736 ? WINDOW_LEFT_FRINGE_WIDTH (it->w)
21737 : WINDOW_RIGHT_FRINGE_WIDTH (it->w)) == 0)
21738 produce_special_glyphs (it, IT_CONTINUATION);
21739 it->continuation_lines_width += it->last_visible_x;
21740 row->ends_in_middle_of_char_p = true;
21741 row->continued_p = true;
21742 glyph->pixel_width = it->last_visible_x - x;
21743 it->starts_in_middle_of_char_p = true;
21744 if (WINDOW_LEFT_MARGIN_WIDTH (it->w) > 0
21745 || WINDOW_RIGHT_MARGIN_WIDTH (it->w) > 0)
21746 extend_face_to_end_of_line (it);
21748 else
21750 /* Something other than a TAB that draws past
21751 the right edge of the window. Restore
21752 positions to values before the element. */
21753 if (row->reversed_p)
21754 unproduce_glyphs (it, row->used[TEXT_AREA]
21755 - (n_glyphs_before + i));
21756 row->used[TEXT_AREA] = n_glyphs_before + i;
21758 /* Display continuation glyphs. */
21759 it->current_x = x_before;
21760 it->continuation_lines_width += x;
21761 if (!FRAME_WINDOW_P (it->f)
21762 || (row->reversed_p
21763 ? WINDOW_LEFT_FRINGE_WIDTH (it->w)
21764 : WINDOW_RIGHT_FRINGE_WIDTH (it->w)) == 0)
21765 produce_special_glyphs (it, IT_CONTINUATION);
21766 row->continued_p = true;
21768 extend_face_to_end_of_line (it);
21770 if (nglyphs > 1 && i > 0)
21772 row->ends_in_middle_of_char_p = true;
21773 it->starts_in_middle_of_char_p = true;
21776 /* Restore the height to what it was before the
21777 element not fitting on the line. */
21778 it->max_ascent = ascent;
21779 it->max_descent = descent;
21780 it->max_phys_ascent = phys_ascent;
21781 it->max_phys_descent = phys_descent;
21784 break;
21786 else if (new_x > it->first_visible_x)
21788 /* Increment number of glyphs actually displayed. */
21789 ++it->hpos;
21791 /* Record the maximum and minimum buffer positions
21792 seen so far in glyphs that will be displayed by
21793 this row. */
21794 if (it->bidi_p)
21795 RECORD_MAX_MIN_POS (it);
21797 if (x < it->first_visible_x && !row->reversed_p)
21798 /* Glyph is partially visible, i.e. row starts at
21799 negative X position. Don't do that in R2L
21800 rows, where we arrange to add a right offset to
21801 the line in extend_face_to_end_of_line, by a
21802 suitable change to the stretch glyph that is
21803 the leftmost glyph of the line. */
21804 row->x = x - it->first_visible_x;
21805 /* When the last glyph of an R2L row only fits
21806 partially on the line, we need to set row->x to a
21807 negative offset, so that the leftmost glyph is
21808 the one that is partially visible. But if we are
21809 going to produce the truncation glyph, this will
21810 be taken care of in produce_special_glyphs. */
21811 if (row->reversed_p
21812 && new_x > it->last_visible_x
21813 && !(it->line_wrap == TRUNCATE
21814 && WINDOW_LEFT_FRINGE_WIDTH (it->w) == 0))
21816 eassert (FRAME_WINDOW_P (it->f));
21817 row->x = it->last_visible_x - new_x;
21820 else
21822 /* Glyph is completely off the left margin of the
21823 window. This should not happen because of the
21824 move_it_in_display_line at the start of this
21825 function, unless the text display area of the
21826 window is empty. */
21827 eassert (it->first_visible_x <= it->last_visible_x);
21830 /* Even if this display element produced no glyphs at all,
21831 we want to record its position. */
21832 if (it->bidi_p && nglyphs == 0)
21833 RECORD_MAX_MIN_POS (it);
21835 row->ascent = max (row->ascent, it->max_ascent);
21836 row->height = max (row->height, it->max_ascent + it->max_descent);
21837 row->phys_ascent = max (row->phys_ascent, it->max_phys_ascent);
21838 row->phys_height = max (row->phys_height,
21839 it->max_phys_ascent + it->max_phys_descent);
21840 row->extra_line_spacing = max (row->extra_line_spacing,
21841 it->max_extra_line_spacing);
21843 /* End of this display line if row is continued. */
21844 if (row->continued_p || row->ends_at_zv_p)
21845 break;
21848 at_end_of_line:
21849 /* Is this a line end? If yes, we're also done, after making
21850 sure that a non-default face is extended up to the right
21851 margin of the window. */
21852 if (ITERATOR_AT_END_OF_LINE_P (it))
21854 int used_before = row->used[TEXT_AREA];
21856 row->ends_in_newline_from_string_p = STRINGP (it->object);
21858 /* Add a space at the end of the line that is used to
21859 display the cursor there. */
21860 if (!IT_OVERFLOW_NEWLINE_INTO_FRINGE (it))
21861 append_space_for_newline (it, false);
21863 /* Extend the face to the end of the line. */
21864 extend_face_to_end_of_line (it);
21866 /* Make sure we have the position. */
21867 if (used_before == 0)
21868 row->glyphs[TEXT_AREA]->charpos = CHARPOS (it->position);
21870 /* Record the position of the newline, for use in
21871 find_row_edges. */
21872 it->eol_pos = it->current.pos;
21874 /* Consume the line end. This skips over invisible lines. */
21875 set_iterator_to_next (it, true);
21876 it->continuation_lines_width = 0;
21877 break;
21880 /* Proceed with next display element. Note that this skips
21881 over lines invisible because of selective display. */
21882 set_iterator_to_next (it, true);
21884 /* If we truncate lines, we are done when the last displayed
21885 glyphs reach past the right margin of the window. */
21886 if (it->line_wrap == TRUNCATE
21887 && ((FRAME_WINDOW_P (it->f)
21888 /* Images are preprocessed in produce_image_glyph such
21889 that they are cropped at the right edge of the
21890 window, so an image glyph will always end exactly at
21891 last_visible_x, even if there's no right fringe. */
21892 && ((row->reversed_p
21893 ? WINDOW_LEFT_FRINGE_WIDTH (it->w)
21894 : WINDOW_RIGHT_FRINGE_WIDTH (it->w))
21895 || it->what == IT_IMAGE))
21896 ? (it->current_x >= it->last_visible_x)
21897 : (it->current_x > it->last_visible_x)))
21899 /* Maybe add truncation glyphs. */
21900 if (!FRAME_WINDOW_P (it->f)
21901 || (row->reversed_p
21902 ? WINDOW_LEFT_FRINGE_WIDTH (it->w)
21903 : WINDOW_RIGHT_FRINGE_WIDTH (it->w)) == 0)
21905 int i, n;
21907 if (!row->reversed_p)
21909 for (i = row->used[TEXT_AREA] - 1; i > 0; --i)
21910 if (!CHAR_GLYPH_PADDING_P (row->glyphs[TEXT_AREA][i]))
21911 break;
21913 else
21915 for (i = 0; i < row->used[TEXT_AREA]; i++)
21916 if (!CHAR_GLYPH_PADDING_P (row->glyphs[TEXT_AREA][i]))
21917 break;
21918 /* Remove any padding glyphs at the front of ROW, to
21919 make room for the truncation glyphs we will be
21920 adding below. The loop below always inserts at
21921 least one truncation glyph, so also remove the
21922 last glyph added to ROW. */
21923 unproduce_glyphs (it, i + 1);
21924 /* Adjust i for the loop below. */
21925 i = row->used[TEXT_AREA] - (i + 1);
21928 /* produce_special_glyphs overwrites the last glyph, so
21929 we don't want that if we want to keep that last
21930 glyph, which means it's an image. */
21931 if (it->current_x > it->last_visible_x)
21933 it->current_x = x_before;
21934 if (!FRAME_WINDOW_P (it->f))
21936 for (n = row->used[TEXT_AREA]; i < n; ++i)
21938 row->used[TEXT_AREA] = i;
21939 produce_special_glyphs (it, IT_TRUNCATION);
21942 else
21944 row->used[TEXT_AREA] = i;
21945 produce_special_glyphs (it, IT_TRUNCATION);
21947 it->hpos = hpos_before;
21950 else if (IT_OVERFLOW_NEWLINE_INTO_FRINGE (it))
21952 /* Don't truncate if we can overflow newline into fringe. */
21953 if (!get_next_display_element (it))
21955 it->continuation_lines_width = 0;
21956 it->font_height = Qnil;
21957 it->voffset = 0;
21958 row->ends_at_zv_p = true;
21959 row->exact_window_width_line_p = true;
21960 break;
21962 if (ITERATOR_AT_END_OF_LINE_P (it))
21964 row->exact_window_width_line_p = true;
21965 goto at_end_of_line;
21967 it->current_x = x_before;
21968 it->hpos = hpos_before;
21971 row->truncated_on_right_p = true;
21972 it->continuation_lines_width = 0;
21973 reseat_at_next_visible_line_start (it, false);
21974 /* We insist below that IT's position be at ZV because in
21975 bidi-reordered lines the character at visible line start
21976 might not be the character that follows the newline in
21977 the logical order. */
21978 if (IT_BYTEPOS (*it) > BEG_BYTE)
21979 row->ends_at_zv_p =
21980 IT_BYTEPOS (*it) >= ZV_BYTE && FETCH_BYTE (ZV_BYTE - 1) != '\n';
21981 else
21982 row->ends_at_zv_p = false;
21983 break;
21987 if (wrap_data)
21988 bidi_unshelve_cache (wrap_data, true);
21990 /* If line is not empty and hscrolled, maybe insert truncation glyphs
21991 at the left window margin. */
21992 if (it->first_visible_x
21993 && IT_CHARPOS (*it) != CHARPOS (row->start.pos))
21995 if (!FRAME_WINDOW_P (it->f)
21996 || (((row->reversed_p
21997 ? WINDOW_RIGHT_FRINGE_WIDTH (it->w)
21998 : WINDOW_LEFT_FRINGE_WIDTH (it->w)) == 0)
21999 /* Don't let insert_left_trunc_glyphs overwrite the
22000 first glyph of the row if it is an image. */
22001 && row->glyphs[TEXT_AREA]->type != IMAGE_GLYPH))
22002 insert_left_trunc_glyphs (it);
22003 row->truncated_on_left_p = true;
22006 /* Remember the position at which this line ends.
22008 BIDI Note: any code that needs MATRIX_ROW_START/END_CHARPOS
22009 cannot be before the call to find_row_edges below, since that is
22010 where these positions are determined. */
22011 row->end = it->current;
22012 if (!it->bidi_p)
22014 row->minpos = row->start.pos;
22015 row->maxpos = row->end.pos;
22017 else
22019 /* ROW->minpos and ROW->maxpos must be the smallest and
22020 `1 + the largest' buffer positions in ROW. But if ROW was
22021 bidi-reordered, these two positions can be anywhere in the
22022 row, so we must determine them now. */
22023 find_row_edges (it, row, min_pos, min_bpos, max_pos, max_bpos);
22026 /* If the start of this line is the overlay arrow-position, then
22027 mark this glyph row as the one containing the overlay arrow.
22028 This is clearly a mess with variable size fonts. It would be
22029 better to let it be displayed like cursors under X. */
22030 if ((MATRIX_ROW_DISPLAYS_TEXT_P (row) || !overlay_arrow_seen)
22031 && (overlay_arrow_string = overlay_arrow_at_row (it, row),
22032 !NILP (overlay_arrow_string)))
22034 /* Overlay arrow in window redisplay is a fringe bitmap. */
22035 if (STRINGP (overlay_arrow_string))
22037 struct glyph_row *arrow_row
22038 = get_overlay_arrow_glyph_row (it->w, overlay_arrow_string);
22039 struct glyph *glyph = arrow_row->glyphs[TEXT_AREA];
22040 struct glyph *arrow_end = glyph + arrow_row->used[TEXT_AREA];
22041 struct glyph *p = row->glyphs[TEXT_AREA];
22042 struct glyph *p2, *end;
22044 /* Copy the arrow glyphs. */
22045 while (glyph < arrow_end)
22046 *p++ = *glyph++;
22048 /* Throw away padding glyphs. */
22049 p2 = p;
22050 end = row->glyphs[TEXT_AREA] + row->used[TEXT_AREA];
22051 while (p2 < end && CHAR_GLYPH_PADDING_P (*p2))
22052 ++p2;
22053 if (p2 > p)
22055 while (p2 < end)
22056 *p++ = *p2++;
22057 row->used[TEXT_AREA] = p2 - row->glyphs[TEXT_AREA];
22060 else
22062 eassert (INTEGERP (overlay_arrow_string));
22063 row->overlay_arrow_bitmap = XINT (overlay_arrow_string);
22065 overlay_arrow_seen = true;
22068 /* Highlight trailing whitespace. */
22069 if (!NILP (Vshow_trailing_whitespace))
22070 highlight_trailing_whitespace (it->f, it->glyph_row);
22072 /* Compute pixel dimensions of this line. */
22073 compute_line_metrics (it);
22075 /* Implementation note: No changes in the glyphs of ROW or in their
22076 faces can be done past this point, because compute_line_metrics
22077 computes ROW's hash value and stores it within the glyph_row
22078 structure. */
22080 /* Record whether this row ends inside an ellipsis. */
22081 row->ends_in_ellipsis_p
22082 = (it->method == GET_FROM_DISPLAY_VECTOR
22083 && it->ellipsis_p);
22085 /* Save fringe bitmaps in this row. */
22086 row->left_user_fringe_bitmap = it->left_user_fringe_bitmap;
22087 row->left_user_fringe_face_id = it->left_user_fringe_face_id;
22088 row->right_user_fringe_bitmap = it->right_user_fringe_bitmap;
22089 row->right_user_fringe_face_id = it->right_user_fringe_face_id;
22091 it->left_user_fringe_bitmap = 0;
22092 it->left_user_fringe_face_id = 0;
22093 it->right_user_fringe_bitmap = 0;
22094 it->right_user_fringe_face_id = 0;
22096 /* Maybe set the cursor. */
22097 cvpos = it->w->cursor.vpos;
22098 if ((cvpos < 0
22099 /* In bidi-reordered rows, keep checking for proper cursor
22100 position even if one has been found already, because buffer
22101 positions in such rows change non-linearly with ROW->VPOS,
22102 when a line is continued. One exception: when we are at ZV,
22103 display cursor on the first suitable glyph row, since all
22104 the empty rows after that also have their position set to ZV. */
22105 /* FIXME: Revisit this when glyph ``spilling'' in continuation
22106 lines' rows is implemented for bidi-reordered rows. */
22107 || (it->bidi_p
22108 && !MATRIX_ROW (it->w->desired_matrix, cvpos)->ends_at_zv_p))
22109 && PT >= MATRIX_ROW_START_CHARPOS (row)
22110 && PT <= MATRIX_ROW_END_CHARPOS (row)
22111 && cursor_row_p (row))
22112 set_cursor_from_row (it->w, row, it->w->desired_matrix, 0, 0, 0, 0);
22114 /* Prepare for the next line. This line starts horizontally at (X
22115 HPOS) = (0 0). Vertical positions are incremented. As a
22116 convenience for the caller, IT->glyph_row is set to the next
22117 row to be used. */
22118 it->current_x = it->hpos = 0;
22119 it->current_y += row->height;
22120 /* Restore the first and last visible X if we adjusted them for
22121 current-line hscrolling. */
22122 if (hscroll_this_line)
22124 it->first_visible_x = first_visible_x;
22125 it->last_visible_x = last_visible_x;
22127 SET_TEXT_POS (it->eol_pos, 0, 0);
22128 ++it->vpos;
22129 ++it->glyph_row;
22130 /* The next row should by default use the same value of the
22131 reversed_p flag as this one. set_iterator_to_next decides when
22132 it's a new paragraph, and PRODUCE_GLYPHS recomputes the value of
22133 the flag accordingly. */
22134 if (it->glyph_row < MATRIX_BOTTOM_TEXT_ROW (it->w->desired_matrix, it->w))
22135 it->glyph_row->reversed_p = row->reversed_p;
22136 it->start = row->end;
22137 return MATRIX_ROW_DISPLAYS_TEXT_P (row);
22139 #undef RECORD_MAX_MIN_POS
22142 DEFUN ("current-bidi-paragraph-direction", Fcurrent_bidi_paragraph_direction,
22143 Scurrent_bidi_paragraph_direction, 0, 1, 0,
22144 doc: /* Return paragraph direction at point in BUFFER.
22145 Value is either `left-to-right' or `right-to-left'.
22146 If BUFFER is omitted or nil, it defaults to the current buffer.
22148 Paragraph direction determines how the text in the paragraph is displayed.
22149 In left-to-right paragraphs, text begins at the left margin of the window
22150 and the reading direction is generally left to right. In right-to-left
22151 paragraphs, text begins at the right margin and is read from right to left.
22153 See also `bidi-paragraph-direction'. */)
22154 (Lisp_Object buffer)
22156 struct buffer *buf = current_buffer;
22157 struct buffer *old = buf;
22159 if (! NILP (buffer))
22161 CHECK_BUFFER (buffer);
22162 buf = XBUFFER (buffer);
22165 if (NILP (BVAR (buf, bidi_display_reordering))
22166 || NILP (BVAR (buf, enable_multibyte_characters))
22167 /* When we are loading loadup.el, the character property tables
22168 needed for bidi iteration are not yet available. */
22169 || redisplay__inhibit_bidi)
22170 return Qleft_to_right;
22171 else if (!NILP (BVAR (buf, bidi_paragraph_direction)))
22172 return BVAR (buf, bidi_paragraph_direction);
22173 else
22175 /* Determine the direction from buffer text. We could try to
22176 use current_matrix if it is up to date, but this seems fast
22177 enough as it is. */
22178 struct bidi_it itb;
22179 ptrdiff_t pos = BUF_PT (buf);
22180 ptrdiff_t bytepos = BUF_PT_BYTE (buf);
22181 int c;
22182 void *itb_data = bidi_shelve_cache ();
22184 set_buffer_temp (buf);
22185 /* bidi_paragraph_init finds the base direction of the paragraph
22186 by searching forward from paragraph start. We need the base
22187 direction of the current or _previous_ paragraph, so we need
22188 to make sure we are within that paragraph. To that end, find
22189 the previous non-empty line. */
22190 if (pos >= ZV && pos > BEGV)
22191 DEC_BOTH (pos, bytepos);
22192 AUTO_STRING (trailing_white_space, "[\f\t ]*\n");
22193 if (fast_looking_at (trailing_white_space,
22194 pos, bytepos, ZV, ZV_BYTE, Qnil) > 0)
22196 while ((c = FETCH_BYTE (bytepos)) == '\n'
22197 || c == ' ' || c == '\t' || c == '\f')
22199 if (bytepos <= BEGV_BYTE)
22200 break;
22201 bytepos--;
22202 pos--;
22204 while (!CHAR_HEAD_P (FETCH_BYTE (bytepos)))
22205 bytepos--;
22207 bidi_init_it (pos, bytepos, FRAME_WINDOW_P (SELECTED_FRAME ()), &itb);
22208 itb.paragraph_dir = NEUTRAL_DIR;
22209 itb.string.s = NULL;
22210 itb.string.lstring = Qnil;
22211 itb.string.bufpos = 0;
22212 itb.string.from_disp_str = false;
22213 itb.string.unibyte = false;
22214 /* We have no window to use here for ignoring window-specific
22215 overlays. Using NULL for window pointer will cause
22216 compute_display_string_pos to use the current buffer. */
22217 itb.w = NULL;
22218 bidi_paragraph_init (NEUTRAL_DIR, &itb, true);
22219 bidi_unshelve_cache (itb_data, false);
22220 set_buffer_temp (old);
22221 switch (itb.paragraph_dir)
22223 case L2R:
22224 return Qleft_to_right;
22225 break;
22226 case R2L:
22227 return Qright_to_left;
22228 break;
22229 default:
22230 emacs_abort ();
22235 DEFUN ("bidi-find-overridden-directionality",
22236 Fbidi_find_overridden_directionality,
22237 Sbidi_find_overridden_directionality, 2, 3, 0,
22238 doc: /* Return position between FROM and TO where directionality was overridden.
22240 This function returns the first character position in the specified
22241 region of OBJECT where there is a character whose `bidi-class' property
22242 is `L', but which was forced to display as `R' by a directional
22243 override, and likewise with characters whose `bidi-class' is `R'
22244 or `AL' that were forced to display as `L'.
22246 If no such character is found, the function returns nil.
22248 OBJECT is a Lisp string or buffer to search for overridden
22249 directionality, and defaults to the current buffer if nil or omitted.
22250 OBJECT can also be a window, in which case the function will search
22251 the buffer displayed in that window. Passing the window instead of
22252 a buffer is preferable when the buffer is displayed in some window,
22253 because this function will then be able to correctly account for
22254 window-specific overlays, which can affect the results.
22256 Strong directional characters `L', `R', and `AL' can have their
22257 intrinsic directionality overridden by directional override
22258 control characters RLO (u+202e) and LRO (u+202d). See the
22259 function `get-char-code-property' for a way to inquire about
22260 the `bidi-class' property of a character. */)
22261 (Lisp_Object from, Lisp_Object to, Lisp_Object object)
22263 struct buffer *buf = current_buffer;
22264 struct buffer *old = buf;
22265 struct window *w = NULL;
22266 bool frame_window_p = FRAME_WINDOW_P (SELECTED_FRAME ());
22267 struct bidi_it itb;
22268 ptrdiff_t from_pos, to_pos, from_bpos;
22269 void *itb_data;
22271 if (!NILP (object))
22273 if (BUFFERP (object))
22274 buf = XBUFFER (object);
22275 else if (WINDOWP (object))
22277 w = decode_live_window (object);
22278 buf = XBUFFER (w->contents);
22279 frame_window_p = FRAME_WINDOW_P (XFRAME (w->frame));
22281 else
22282 CHECK_STRING (object);
22285 if (STRINGP (object))
22287 /* Characters in unibyte strings are always treated by bidi.c as
22288 strong LTR. */
22289 if (!STRING_MULTIBYTE (object)
22290 /* When we are loading loadup.el, the character property
22291 tables needed for bidi iteration are not yet
22292 available. */
22293 || redisplay__inhibit_bidi)
22294 return Qnil;
22296 validate_subarray (object, from, to, SCHARS (object), &from_pos, &to_pos);
22297 if (from_pos >= SCHARS (object))
22298 return Qnil;
22300 /* Set up the bidi iterator. */
22301 itb_data = bidi_shelve_cache ();
22302 itb.paragraph_dir = NEUTRAL_DIR;
22303 itb.string.lstring = object;
22304 itb.string.s = NULL;
22305 itb.string.schars = SCHARS (object);
22306 itb.string.bufpos = 0;
22307 itb.string.from_disp_str = false;
22308 itb.string.unibyte = false;
22309 itb.w = w;
22310 bidi_init_it (0, 0, frame_window_p, &itb);
22312 else
22314 /* Nothing this fancy can happen in unibyte buffers, or in a
22315 buffer that disabled reordering, or if FROM is at EOB. */
22316 if (NILP (BVAR (buf, bidi_display_reordering))
22317 || NILP (BVAR (buf, enable_multibyte_characters))
22318 /* When we are loading loadup.el, the character property
22319 tables needed for bidi iteration are not yet
22320 available. */
22321 || redisplay__inhibit_bidi)
22322 return Qnil;
22324 set_buffer_temp (buf);
22325 validate_region (&from, &to);
22326 from_pos = XINT (from);
22327 to_pos = XINT (to);
22328 if (from_pos >= ZV)
22329 return Qnil;
22331 /* Set up the bidi iterator. */
22332 itb_data = bidi_shelve_cache ();
22333 from_bpos = CHAR_TO_BYTE (from_pos);
22334 if (from_pos == BEGV)
22336 itb.charpos = BEGV;
22337 itb.bytepos = BEGV_BYTE;
22339 else if (FETCH_CHAR (from_bpos - 1) == '\n')
22341 itb.charpos = from_pos;
22342 itb.bytepos = from_bpos;
22344 else
22345 itb.charpos = find_newline_no_quit (from_pos, CHAR_TO_BYTE (from_pos),
22346 -1, &itb.bytepos);
22347 itb.paragraph_dir = NEUTRAL_DIR;
22348 itb.string.s = NULL;
22349 itb.string.lstring = Qnil;
22350 itb.string.bufpos = 0;
22351 itb.string.from_disp_str = false;
22352 itb.string.unibyte = false;
22353 itb.w = w;
22354 bidi_init_it (itb.charpos, itb.bytepos, frame_window_p, &itb);
22357 ptrdiff_t found;
22358 do {
22359 /* For the purposes of this function, the actual base direction of
22360 the paragraph doesn't matter, so just set it to L2R. */
22361 bidi_paragraph_init (L2R, &itb, false);
22362 while ((found = bidi_find_first_overridden (&itb)) < from_pos)
22364 } while (found == ZV && itb.ch == '\n' && itb.charpos < to_pos);
22366 bidi_unshelve_cache (itb_data, false);
22367 set_buffer_temp (old);
22369 return (from_pos <= found && found < to_pos) ? make_number (found) : Qnil;
22372 DEFUN ("move-point-visually", Fmove_point_visually,
22373 Smove_point_visually, 1, 1, 0,
22374 doc: /* Move point in the visual order in the specified DIRECTION.
22375 DIRECTION can be 1, meaning move to the right, or -1, which moves to the
22376 left.
22378 Value is the new character position of point. */)
22379 (Lisp_Object direction)
22381 struct window *w = XWINDOW (selected_window);
22382 struct buffer *b = XBUFFER (w->contents);
22383 struct glyph_row *row;
22384 int dir;
22385 Lisp_Object paragraph_dir;
22387 #define ROW_GLYPH_NEWLINE_P(ROW,GLYPH) \
22388 (!(ROW)->continued_p \
22389 && NILP ((GLYPH)->object) \
22390 && (GLYPH)->type == CHAR_GLYPH \
22391 && (GLYPH)->u.ch == ' ' \
22392 && (GLYPH)->charpos >= 0 \
22393 && !(GLYPH)->avoid_cursor_p)
22395 CHECK_NUMBER (direction);
22396 dir = XINT (direction);
22397 if (dir > 0)
22398 dir = 1;
22399 else
22400 dir = -1;
22402 /* If current matrix is up-to-date, we can use the information
22403 recorded in the glyphs, at least as long as the goal is on the
22404 screen. */
22405 if (w->window_end_valid
22406 && !windows_or_buffers_changed
22407 && b
22408 && !b->clip_changed
22409 && !b->prevent_redisplay_optimizations_p
22410 && !window_outdated (w)
22411 /* We rely below on the cursor coordinates to be up to date, but
22412 we cannot trust them if some command moved point since the
22413 last complete redisplay. */
22414 && w->last_point == BUF_PT (b)
22415 && w->cursor.vpos >= 0
22416 && w->cursor.vpos < w->current_matrix->nrows
22417 && (row = MATRIX_ROW (w->current_matrix, w->cursor.vpos))->enabled_p)
22419 struct glyph *g = row->glyphs[TEXT_AREA];
22420 struct glyph *e = dir > 0 ? g + row->used[TEXT_AREA] : g - 1;
22421 struct glyph *gpt = g + w->cursor.hpos;
22423 for (g = gpt + dir; (dir > 0 ? g < e : g > e); g += dir)
22425 if (BUFFERP (g->object) && g->charpos != PT)
22427 SET_PT (g->charpos);
22428 w->cursor.vpos = -1;
22429 return make_number (PT);
22431 else if (!NILP (g->object) && !EQ (g->object, gpt->object))
22433 ptrdiff_t new_pos;
22435 if (BUFFERP (gpt->object))
22437 new_pos = PT;
22438 if ((gpt->resolved_level - row->reversed_p) % 2 == 0)
22439 new_pos += (row->reversed_p ? -dir : dir);
22440 else
22441 new_pos -= (row->reversed_p ? -dir : dir);
22443 else if (BUFFERP (g->object))
22444 new_pos = g->charpos;
22445 else
22446 break;
22447 SET_PT (new_pos);
22448 w->cursor.vpos = -1;
22449 return make_number (PT);
22451 else if (ROW_GLYPH_NEWLINE_P (row, g))
22453 /* Glyphs inserted at the end of a non-empty line for
22454 positioning the cursor have zero charpos, so we must
22455 deduce the value of point by other means. */
22456 if (g->charpos > 0)
22457 SET_PT (g->charpos);
22458 else if (row->ends_at_zv_p && PT != ZV)
22459 SET_PT (ZV);
22460 else if (PT != MATRIX_ROW_END_CHARPOS (row) - 1)
22461 SET_PT (MATRIX_ROW_END_CHARPOS (row) - 1);
22462 else
22463 break;
22464 w->cursor.vpos = -1;
22465 return make_number (PT);
22468 if (g == e || NILP (g->object))
22470 if (row->truncated_on_left_p || row->truncated_on_right_p)
22471 goto simulate_display;
22472 if (!row->reversed_p)
22473 row += dir;
22474 else
22475 row -= dir;
22476 if (!(MATRIX_FIRST_TEXT_ROW (w->current_matrix) <= row
22477 && row < MATRIX_BOTTOM_TEXT_ROW (w->current_matrix, w)))
22478 goto simulate_display;
22480 if (dir > 0)
22482 if (row->reversed_p && !row->continued_p)
22484 SET_PT (MATRIX_ROW_END_CHARPOS (row) - 1);
22485 w->cursor.vpos = -1;
22486 return make_number (PT);
22488 g = row->glyphs[TEXT_AREA];
22489 e = g + row->used[TEXT_AREA];
22490 for ( ; g < e; g++)
22492 if (BUFFERP (g->object)
22493 /* Empty lines have only one glyph, which stands
22494 for the newline, and whose charpos is the
22495 buffer position of the newline. */
22496 || ROW_GLYPH_NEWLINE_P (row, g)
22497 /* When the buffer ends in a newline, the line at
22498 EOB also has one glyph, but its charpos is -1. */
22499 || (row->ends_at_zv_p
22500 && !row->reversed_p
22501 && NILP (g->object)
22502 && g->type == CHAR_GLYPH
22503 && g->u.ch == ' '))
22505 if (g->charpos > 0)
22506 SET_PT (g->charpos);
22507 else if (!row->reversed_p
22508 && row->ends_at_zv_p
22509 && PT != ZV)
22510 SET_PT (ZV);
22511 else
22512 continue;
22513 w->cursor.vpos = -1;
22514 return make_number (PT);
22518 else
22520 if (!row->reversed_p && !row->continued_p)
22522 SET_PT (MATRIX_ROW_END_CHARPOS (row) - 1);
22523 w->cursor.vpos = -1;
22524 return make_number (PT);
22526 e = row->glyphs[TEXT_AREA];
22527 g = e + row->used[TEXT_AREA] - 1;
22528 for ( ; g >= e; g--)
22530 if (BUFFERP (g->object)
22531 || (ROW_GLYPH_NEWLINE_P (row, g)
22532 && g->charpos > 0)
22533 /* Empty R2L lines on GUI frames have the buffer
22534 position of the newline stored in the stretch
22535 glyph. */
22536 || g->type == STRETCH_GLYPH
22537 || (row->ends_at_zv_p
22538 && row->reversed_p
22539 && NILP (g->object)
22540 && g->type == CHAR_GLYPH
22541 && g->u.ch == ' '))
22543 if (g->charpos > 0)
22544 SET_PT (g->charpos);
22545 else if (row->reversed_p
22546 && row->ends_at_zv_p
22547 && PT != ZV)
22548 SET_PT (ZV);
22549 else
22550 continue;
22551 w->cursor.vpos = -1;
22552 return make_number (PT);
22559 simulate_display:
22561 /* If we wind up here, we failed to move by using the glyphs, so we
22562 need to simulate display instead. */
22564 if (b)
22565 paragraph_dir = Fcurrent_bidi_paragraph_direction (w->contents);
22566 else
22567 paragraph_dir = Qleft_to_right;
22568 if (EQ (paragraph_dir, Qright_to_left))
22569 dir = -dir;
22570 if (PT <= BEGV && dir < 0)
22571 xsignal0 (Qbeginning_of_buffer);
22572 else if (PT >= ZV && dir > 0)
22573 xsignal0 (Qend_of_buffer);
22574 else
22576 struct text_pos pt;
22577 struct it it;
22578 int pt_x, target_x, pixel_width, pt_vpos;
22579 bool at_eol_p;
22580 bool overshoot_expected = false;
22581 bool target_is_eol_p = false;
22583 /* Setup the arena. */
22584 SET_TEXT_POS (pt, PT, PT_BYTE);
22585 start_display (&it, w, pt);
22586 /* When lines are truncated, we could be called with point
22587 outside of the windows edges, in which case move_it_*
22588 functions either prematurely stop at window's edge or jump to
22589 the next screen line, whereas we rely below on our ability to
22590 reach point, in order to start from its X coordinate. So we
22591 need to disregard the window's horizontal extent in that case. */
22592 if (it.line_wrap == TRUNCATE)
22593 it.last_visible_x = DISP_INFINITY;
22595 if (it.cmp_it.id < 0
22596 && it.method == GET_FROM_STRING
22597 && it.area == TEXT_AREA
22598 && it.string_from_display_prop_p
22599 && (it.sp > 0 && it.stack[it.sp - 1].method == GET_FROM_BUFFER))
22600 overshoot_expected = true;
22602 /* Find the X coordinate of point. We start from the beginning
22603 of this or previous line to make sure we are before point in
22604 the logical order (since the move_it_* functions can only
22605 move forward). */
22606 reseat:
22607 reseat_at_previous_visible_line_start (&it);
22608 it.current_x = it.hpos = it.current_y = it.vpos = 0;
22609 if (IT_CHARPOS (it) != PT)
22611 move_it_to (&it, overshoot_expected ? PT - 1 : PT,
22612 -1, -1, -1, MOVE_TO_POS);
22613 /* If we missed point because the character there is
22614 displayed out of a display vector that has more than one
22615 glyph, retry expecting overshoot. */
22616 if (it.method == GET_FROM_DISPLAY_VECTOR
22617 && it.current.dpvec_index > 0
22618 && !overshoot_expected)
22620 overshoot_expected = true;
22621 goto reseat;
22623 else if (IT_CHARPOS (it) != PT && !overshoot_expected)
22624 move_it_in_display_line (&it, PT, -1, MOVE_TO_POS);
22626 pt_x = it.current_x;
22627 pt_vpos = it.vpos;
22628 if (dir > 0 || overshoot_expected)
22630 struct glyph_row *row = it.glyph_row;
22632 /* When point is at beginning of line, we don't have
22633 information about the glyph there loaded into struct
22634 it. Calling get_next_display_element fixes that. */
22635 if (pt_x == 0)
22636 get_next_display_element (&it);
22637 at_eol_p = ITERATOR_AT_END_OF_LINE_P (&it);
22638 it.glyph_row = NULL;
22639 PRODUCE_GLYPHS (&it); /* compute it.pixel_width */
22640 it.glyph_row = row;
22641 /* PRODUCE_GLYPHS advances it.current_x, so we must restore
22642 it, lest it will become out of sync with it's buffer
22643 position. */
22644 it.current_x = pt_x;
22646 else
22647 at_eol_p = ITERATOR_AT_END_OF_LINE_P (&it);
22648 pixel_width = it.pixel_width;
22649 if (overshoot_expected && at_eol_p)
22650 pixel_width = 0;
22651 else if (pixel_width <= 0)
22652 pixel_width = 1;
22654 /* If there's a display string (or something similar) at point,
22655 we are actually at the glyph to the left of point, so we need
22656 to correct the X coordinate. */
22657 if (overshoot_expected)
22659 if (it.bidi_p)
22660 pt_x += pixel_width * it.bidi_it.scan_dir;
22661 else
22662 pt_x += pixel_width;
22665 /* Compute target X coordinate, either to the left or to the
22666 right of point. On TTY frames, all characters have the same
22667 pixel width of 1, so we can use that. On GUI frames we don't
22668 have an easy way of getting at the pixel width of the
22669 character to the left of point, so we use a different method
22670 of getting to that place. */
22671 if (dir > 0)
22672 target_x = pt_x + pixel_width;
22673 else
22674 target_x = pt_x - (!FRAME_WINDOW_P (it.f)) * pixel_width;
22676 /* Target X coordinate could be one line above or below the line
22677 of point, in which case we need to adjust the target X
22678 coordinate. Also, if moving to the left, we need to begin at
22679 the left edge of the point's screen line. */
22680 if (dir < 0)
22682 if (pt_x > 0)
22684 start_display (&it, w, pt);
22685 if (it.line_wrap == TRUNCATE)
22686 it.last_visible_x = DISP_INFINITY;
22687 reseat_at_previous_visible_line_start (&it);
22688 it.current_x = it.current_y = it.hpos = 0;
22689 if (pt_vpos != 0)
22690 move_it_by_lines (&it, pt_vpos);
22692 else
22694 move_it_by_lines (&it, -1);
22695 target_x = it.last_visible_x - !FRAME_WINDOW_P (it.f);
22696 target_is_eol_p = true;
22697 /* Under word-wrap, we don't know the x coordinate of
22698 the last character displayed on the previous line,
22699 which immediately precedes the wrap point. To find
22700 out its x coordinate, we try moving to the right
22701 margin of the window, which will stop at the wrap
22702 point, and then reset target_x to point at the
22703 character that precedes the wrap point. This is not
22704 needed on GUI frames, because (see below) there we
22705 move from the left margin one grapheme cluster at a
22706 time, and stop when we hit the wrap point. */
22707 if (!FRAME_WINDOW_P (it.f) && it.line_wrap == WORD_WRAP)
22709 void *it_data = NULL;
22710 struct it it2;
22712 SAVE_IT (it2, it, it_data);
22713 move_it_in_display_line_to (&it, ZV, target_x,
22714 MOVE_TO_POS | MOVE_TO_X);
22715 /* If we arrived at target_x, that _is_ the last
22716 character on the previous line. */
22717 if (it.current_x != target_x)
22718 target_x = it.current_x - 1;
22719 RESTORE_IT (&it, &it2, it_data);
22723 else
22725 if (at_eol_p
22726 || (target_x >= it.last_visible_x
22727 && it.line_wrap != TRUNCATE))
22729 if (pt_x > 0)
22730 move_it_by_lines (&it, 0);
22731 move_it_by_lines (&it, 1);
22732 target_x = 0;
22736 /* Move to the target X coordinate. */
22737 /* On GUI frames, as we don't know the X coordinate of the
22738 character to the left of point, moving point to the left
22739 requires walking, one grapheme cluster at a time, until we
22740 find ourself at a place immediately to the left of the
22741 character at point. */
22742 if (FRAME_WINDOW_P (it.f) && dir < 0)
22744 struct text_pos new_pos;
22745 enum move_it_result rc = MOVE_X_REACHED;
22747 if (it.current_x == 0)
22748 get_next_display_element (&it);
22749 if (it.what == IT_COMPOSITION)
22751 new_pos.charpos = it.cmp_it.charpos;
22752 new_pos.bytepos = -1;
22754 else
22755 new_pos = it.current.pos;
22757 while (it.current_x + it.pixel_width <= target_x
22758 && (rc == MOVE_X_REACHED
22759 /* Under word-wrap, move_it_in_display_line_to
22760 stops at correct coordinates, but sometimes
22761 returns MOVE_POS_MATCH_OR_ZV. */
22762 || (it.line_wrap == WORD_WRAP
22763 && rc == MOVE_POS_MATCH_OR_ZV)))
22765 int new_x = it.current_x + it.pixel_width;
22767 /* For composed characters, we want the position of the
22768 first character in the grapheme cluster (usually, the
22769 composition's base character), whereas it.current
22770 might give us the position of the _last_ one, e.g. if
22771 the composition is rendered in reverse due to bidi
22772 reordering. */
22773 if (it.what == IT_COMPOSITION)
22775 new_pos.charpos = it.cmp_it.charpos;
22776 new_pos.bytepos = -1;
22778 else
22779 new_pos = it.current.pos;
22780 if (new_x == it.current_x)
22781 new_x++;
22782 rc = move_it_in_display_line_to (&it, ZV, new_x,
22783 MOVE_TO_POS | MOVE_TO_X);
22784 if (ITERATOR_AT_END_OF_LINE_P (&it) && !target_is_eol_p)
22785 break;
22787 /* The previous position we saw in the loop is the one we
22788 want. */
22789 if (new_pos.bytepos == -1)
22790 new_pos.bytepos = CHAR_TO_BYTE (new_pos.charpos);
22791 it.current.pos = new_pos;
22793 else if (it.current_x != target_x)
22794 move_it_in_display_line_to (&it, ZV, target_x, MOVE_TO_POS | MOVE_TO_X);
22796 /* If we ended up in a display string that covers point, move to
22797 buffer position to the right in the visual order. */
22798 if (dir > 0)
22800 while (IT_CHARPOS (it) == PT)
22802 set_iterator_to_next (&it, false);
22803 if (!get_next_display_element (&it))
22804 break;
22808 /* Move point to that position. */
22809 SET_PT_BOTH (IT_CHARPOS (it), IT_BYTEPOS (it));
22812 return make_number (PT);
22814 #undef ROW_GLYPH_NEWLINE_P
22817 DEFUN ("bidi-resolved-levels", Fbidi_resolved_levels,
22818 Sbidi_resolved_levels, 0, 1, 0,
22819 doc: /* Return the resolved bidirectional levels of characters at VPOS.
22821 The resolved levels are produced by the Emacs bidi reordering engine
22822 that implements the UBA, the Unicode Bidirectional Algorithm. Please
22823 read the Unicode Standard Annex 9 (UAX#9) for background information
22824 about these levels.
22826 VPOS is the zero-based number of the current window's screen line
22827 for which to produce the resolved levels. If VPOS is nil or omitted,
22828 it defaults to the screen line of point. If the window displays a
22829 header line, VPOS of zero will report on the header line, and first
22830 line of text in the window will have VPOS of 1.
22832 Value is an array of resolved levels, indexed by glyph number.
22833 Glyphs are numbered from zero starting from the beginning of the
22834 screen line, i.e. the left edge of the window for left-to-right lines
22835 and from the right edge for right-to-left lines. The resolved levels
22836 are produced only for the window's text area; text in display margins
22837 is not included.
22839 If the selected window's display is not up-to-date, or if the specified
22840 screen line does not display text, this function returns nil. It is
22841 highly recommended to bind this function to some simple key, like F8,
22842 in order to avoid these problems.
22844 This function exists mainly for testing the correctness of the
22845 Emacs UBA implementation, in particular with the test suite. */)
22846 (Lisp_Object vpos)
22848 struct window *w = XWINDOW (selected_window);
22849 struct buffer *b = XBUFFER (w->contents);
22850 int nrow;
22851 struct glyph_row *row;
22853 if (NILP (vpos))
22855 int d1, d2, d3, d4, d5;
22857 pos_visible_p (w, PT, &d1, &d2, &d3, &d4, &d5, &nrow);
22859 else
22861 CHECK_NUMBER_COERCE_MARKER (vpos);
22862 nrow = XINT (vpos);
22865 /* We require up-to-date glyph matrix for this window. */
22866 if (w->window_end_valid
22867 && !windows_or_buffers_changed
22868 && b
22869 && !b->clip_changed
22870 && !b->prevent_redisplay_optimizations_p
22871 && !window_outdated (w)
22872 && nrow >= 0
22873 && nrow < w->current_matrix->nrows
22874 && (row = MATRIX_ROW (w->current_matrix, nrow))->enabled_p
22875 && MATRIX_ROW_DISPLAYS_TEXT_P (row))
22877 struct glyph *g, *e, *g1;
22878 int nglyphs, i;
22879 Lisp_Object levels;
22881 if (!row->reversed_p) /* Left-to-right glyph row. */
22883 g = g1 = row->glyphs[TEXT_AREA];
22884 e = g + row->used[TEXT_AREA];
22886 /* Skip over glyphs at the start of the row that was
22887 generated by redisplay for its own needs. */
22888 while (g < e
22889 && NILP (g->object)
22890 && g->charpos < 0)
22891 g++;
22892 g1 = g;
22894 /* Count the "interesting" glyphs in this row. */
22895 for (nglyphs = 0; g < e && !NILP (g->object); g++)
22896 nglyphs++;
22898 /* Create and fill the array. */
22899 levels = make_uninit_vector (nglyphs);
22900 for (i = 0; g1 < g; i++, g1++)
22901 ASET (levels, i, make_number (g1->resolved_level));
22903 else /* Right-to-left glyph row. */
22905 g = row->glyphs[TEXT_AREA] + row->used[TEXT_AREA] - 1;
22906 e = row->glyphs[TEXT_AREA] - 1;
22907 while (g > e
22908 && NILP (g->object)
22909 && g->charpos < 0)
22910 g--;
22911 g1 = g;
22912 for (nglyphs = 0; g > e && !NILP (g->object); g--)
22913 nglyphs++;
22914 levels = make_uninit_vector (nglyphs);
22915 for (i = 0; g1 > g; i++, g1--)
22916 ASET (levels, i, make_number (g1->resolved_level));
22918 return levels;
22920 else
22921 return Qnil;
22926 /***********************************************************************
22927 Menu Bar
22928 ***********************************************************************/
22930 /* Redisplay the menu bar in the frame for window W.
22932 The menu bar of X frames that don't have X toolkit support is
22933 displayed in a special window W->frame->menu_bar_window.
22935 The menu bar of terminal frames is treated specially as far as
22936 glyph matrices are concerned. Menu bar lines are not part of
22937 windows, so the update is done directly on the frame matrix rows
22938 for the menu bar. */
22940 static void
22941 display_menu_bar (struct window *w)
22943 struct frame *f = XFRAME (WINDOW_FRAME (w));
22944 struct it it;
22945 Lisp_Object items;
22946 int i;
22948 /* Don't do all this for graphical frames. */
22949 #ifdef HAVE_NTGUI
22950 if (FRAME_W32_P (f))
22951 return;
22952 #endif
22953 #if defined (USE_X_TOOLKIT) || defined (USE_GTK)
22954 if (FRAME_X_P (f))
22955 return;
22956 #endif
22958 #ifdef HAVE_NS
22959 if (FRAME_NS_P (f))
22960 return;
22961 #endif /* HAVE_NS */
22963 #if defined (USE_X_TOOLKIT) || defined (USE_GTK)
22964 eassert (!FRAME_WINDOW_P (f));
22965 init_iterator (&it, w, -1, -1, f->desired_matrix->rows, MENU_FACE_ID);
22966 it.first_visible_x = 0;
22967 it.last_visible_x = FRAME_PIXEL_WIDTH (f);
22968 #elif defined (HAVE_X_WINDOWS) /* X without toolkit. */
22969 if (FRAME_WINDOW_P (f))
22971 /* Menu bar lines are displayed in the desired matrix of the
22972 dummy window menu_bar_window. */
22973 struct window *menu_w;
22974 menu_w = XWINDOW (f->menu_bar_window);
22975 init_iterator (&it, menu_w, -1, -1, menu_w->desired_matrix->rows,
22976 MENU_FACE_ID);
22977 it.first_visible_x = 0;
22978 it.last_visible_x = FRAME_PIXEL_WIDTH (f);
22980 else
22981 #endif /* not USE_X_TOOLKIT and not USE_GTK */
22983 /* This is a TTY frame, i.e. character hpos/vpos are used as
22984 pixel x/y. */
22985 init_iterator (&it, w, -1, -1, f->desired_matrix->rows,
22986 MENU_FACE_ID);
22987 it.first_visible_x = 0;
22988 it.last_visible_x = FRAME_COLS (f);
22991 /* FIXME: This should be controlled by a user option. See the
22992 comments in redisplay_tool_bar and display_mode_line about
22993 this. */
22994 it.paragraph_embedding = L2R;
22996 /* Clear all rows of the menu bar. */
22997 for (i = 0; i < FRAME_MENU_BAR_LINES (f); ++i)
22999 struct glyph_row *row = it.glyph_row + i;
23000 clear_glyph_row (row);
23001 row->enabled_p = true;
23002 row->full_width_p = true;
23003 row->reversed_p = false;
23006 /* Display all items of the menu bar. */
23007 items = FRAME_MENU_BAR_ITEMS (it.f);
23008 for (i = 0; i < ASIZE (items); i += 4)
23010 Lisp_Object string;
23012 /* Stop at nil string. */
23013 string = AREF (items, i + 1);
23014 if (NILP (string))
23015 break;
23017 /* Remember where item was displayed. */
23018 ASET (items, i + 3, make_number (it.hpos));
23020 /* Display the item, pad with one space. */
23021 if (it.current_x < it.last_visible_x)
23022 display_string (NULL, string, Qnil, 0, 0, &it,
23023 SCHARS (string) + 1, 0, 0, -1);
23026 /* Fill out the line with spaces. */
23027 if (it.current_x < it.last_visible_x)
23028 display_string ("", Qnil, Qnil, 0, 0, &it, -1, 0, 0, -1);
23030 /* Compute the total height of the lines. */
23031 compute_line_metrics (&it);
23034 /* Deep copy of a glyph row, including the glyphs. */
23035 static void
23036 deep_copy_glyph_row (struct glyph_row *to, struct glyph_row *from)
23038 struct glyph *pointers[1 + LAST_AREA];
23039 int to_used = to->used[TEXT_AREA];
23041 /* Save glyph pointers of TO. */
23042 memcpy (pointers, to->glyphs, sizeof to->glyphs);
23044 /* Do a structure assignment. */
23045 *to = *from;
23047 /* Restore original glyph pointers of TO. */
23048 memcpy (to->glyphs, pointers, sizeof to->glyphs);
23050 /* Copy the glyphs. */
23051 memcpy (to->glyphs[TEXT_AREA], from->glyphs[TEXT_AREA],
23052 min (from->used[TEXT_AREA], to_used) * sizeof (struct glyph));
23054 /* If we filled only part of the TO row, fill the rest with
23055 space_glyph (which will display as empty space). */
23056 if (to_used > from->used[TEXT_AREA])
23057 fill_up_frame_row_with_spaces (to, to_used);
23060 /* Display one menu item on a TTY, by overwriting the glyphs in the
23061 frame F's desired glyph matrix with glyphs produced from the menu
23062 item text. Called from term.c to display TTY drop-down menus one
23063 item at a time.
23065 ITEM_TEXT is the menu item text as a C string.
23067 FACE_ID is the face ID to be used for this menu item. FACE_ID
23068 could specify one of 3 faces: a face for an enabled item, a face
23069 for a disabled item, or a face for a selected item.
23071 X and Y are coordinates of the first glyph in the frame's desired
23072 matrix to be overwritten by the menu item. Since this is a TTY, Y
23073 is the zero-based number of the glyph row and X is the zero-based
23074 glyph number in the row, starting from left, where to start
23075 displaying the item.
23077 SUBMENU means this menu item drops down a submenu, which
23078 should be indicated by displaying a proper visual cue after the
23079 item text. */
23081 void
23082 display_tty_menu_item (const char *item_text, int width, int face_id,
23083 int x, int y, bool submenu)
23085 struct it it;
23086 struct frame *f = SELECTED_FRAME ();
23087 struct window *w = XWINDOW (f->selected_window);
23088 struct glyph_row *row;
23089 size_t item_len = strlen (item_text);
23091 eassert (FRAME_TERMCAP_P (f));
23093 /* Don't write beyond the matrix's last row. This can happen for
23094 TTY screens that are not high enough to show the entire menu.
23095 (This is actually a bit of defensive programming, as
23096 tty_menu_display already limits the number of menu items to one
23097 less than the number of screen lines.) */
23098 if (y >= f->desired_matrix->nrows)
23099 return;
23101 init_iterator (&it, w, -1, -1, f->desired_matrix->rows + y, MENU_FACE_ID);
23102 it.first_visible_x = 0;
23103 it.last_visible_x = FRAME_COLS (f) - 1;
23104 row = it.glyph_row;
23105 /* Start with the row contents from the current matrix. */
23106 deep_copy_glyph_row (row, f->current_matrix->rows + y);
23107 bool saved_width = row->full_width_p;
23108 row->full_width_p = true;
23109 bool saved_reversed = row->reversed_p;
23110 row->reversed_p = false;
23111 row->enabled_p = true;
23113 /* Arrange for the menu item glyphs to start at (X,Y) and have the
23114 desired face. */
23115 eassert (x < f->desired_matrix->matrix_w);
23116 it.current_x = it.hpos = x;
23117 it.current_y = it.vpos = y;
23118 int saved_used = row->used[TEXT_AREA];
23119 bool saved_truncated = row->truncated_on_right_p;
23120 row->used[TEXT_AREA] = x;
23121 it.face_id = face_id;
23122 it.line_wrap = TRUNCATE;
23124 /* FIXME: This should be controlled by a user option. See the
23125 comments in redisplay_tool_bar and display_mode_line about this.
23126 Also, if paragraph_embedding could ever be R2L, changes will be
23127 needed to avoid shifting to the right the row characters in
23128 term.c:append_glyph. */
23129 it.paragraph_embedding = L2R;
23131 /* Pad with a space on the left. */
23132 display_string (" ", Qnil, Qnil, 0, 0, &it, 1, 0, FRAME_COLS (f) - 1, -1);
23133 width--;
23134 /* Display the menu item, pad with spaces to WIDTH. */
23135 if (submenu)
23137 display_string (item_text, Qnil, Qnil, 0, 0, &it,
23138 item_len, 0, FRAME_COLS (f) - 1, -1);
23139 width -= item_len;
23140 /* Indicate with " >" that there's a submenu. */
23141 display_string (" >", Qnil, Qnil, 0, 0, &it, width, 0,
23142 FRAME_COLS (f) - 1, -1);
23144 else
23145 display_string (item_text, Qnil, Qnil, 0, 0, &it,
23146 width, 0, FRAME_COLS (f) - 1, -1);
23148 row->used[TEXT_AREA] = max (saved_used, row->used[TEXT_AREA]);
23149 row->truncated_on_right_p = saved_truncated;
23150 row->hash = row_hash (row);
23151 row->full_width_p = saved_width;
23152 row->reversed_p = saved_reversed;
23155 /***********************************************************************
23156 Mode Line
23157 ***********************************************************************/
23159 /* Redisplay mode lines in the window tree whose root is WINDOW.
23160 If FORCE, redisplay mode lines unconditionally.
23161 Otherwise, redisplay only mode lines that are garbaged. Value is
23162 the number of windows whose mode lines were redisplayed. */
23164 static int
23165 redisplay_mode_lines (Lisp_Object window, bool force)
23167 int nwindows = 0;
23169 while (!NILP (window))
23171 struct window *w = XWINDOW (window);
23173 if (WINDOWP (w->contents))
23174 nwindows += redisplay_mode_lines (w->contents, force);
23175 else if (force
23176 || FRAME_GARBAGED_P (XFRAME (w->frame))
23177 || !MATRIX_MODE_LINE_ROW (w->current_matrix)->enabled_p)
23179 struct text_pos lpoint;
23180 struct buffer *old = current_buffer;
23182 /* Set the window's buffer for the mode line display. */
23183 SET_TEXT_POS (lpoint, PT, PT_BYTE);
23184 set_buffer_internal_1 (XBUFFER (w->contents));
23186 /* Point refers normally to the selected window. For any
23187 other window, set up appropriate value. */
23188 if (!EQ (window, selected_window))
23190 struct text_pos pt;
23192 CLIP_TEXT_POS_FROM_MARKER (pt, w->pointm);
23193 TEMP_SET_PT_BOTH (CHARPOS (pt), BYTEPOS (pt));
23196 /* Display mode lines. */
23197 clear_glyph_matrix (w->desired_matrix);
23198 if (display_mode_lines (w))
23199 ++nwindows;
23201 /* Restore old settings. */
23202 set_buffer_internal_1 (old);
23203 TEMP_SET_PT_BOTH (CHARPOS (lpoint), BYTEPOS (lpoint));
23206 window = w->next;
23209 return nwindows;
23213 /* Display the mode and/or header line of window W. Value is the
23214 sum number of mode lines and header lines displayed. */
23216 static int
23217 display_mode_lines (struct window *w)
23219 Lisp_Object old_selected_window = selected_window;
23220 Lisp_Object old_selected_frame = selected_frame;
23221 Lisp_Object new_frame = w->frame;
23222 Lisp_Object old_frame_selected_window = XFRAME (new_frame)->selected_window;
23223 int n = 0;
23225 if (window_wants_mode_line (w))
23227 Lisp_Object window;
23228 Lisp_Object default_help
23229 = buffer_local_value (Qmode_line_default_help_echo, w->contents);
23231 /* Set up mode line help echo. Do this before selecting w so it
23232 can reasonably tell whether a mouse click will select w. */
23233 XSETWINDOW (window, w);
23234 if (FUNCTIONP (default_help))
23235 wset_mode_line_help_echo (w, safe_call1 (default_help, window));
23236 else if (STRINGP (default_help))
23237 wset_mode_line_help_echo (w, default_help);
23238 else
23239 wset_mode_line_help_echo (w, Qnil);
23242 selected_frame = new_frame;
23243 /* FIXME: If we were to allow the mode-line's computation changing the buffer
23244 or window's point, then we'd need select_window_1 here as well. */
23245 XSETWINDOW (selected_window, w);
23246 XFRAME (new_frame)->selected_window = selected_window;
23248 /* These will be set while the mode line specs are processed. */
23249 line_number_displayed = false;
23250 w->column_number_displayed = -1;
23252 if (window_wants_mode_line (w))
23254 Lisp_Object window_mode_line_format
23255 = window_parameter (w, Qmode_line_format);
23256 struct window *sel_w = XWINDOW (old_selected_window);
23258 /* Select mode line face based on the real selected window. */
23259 display_mode_line (w, CURRENT_MODE_LINE_FACE_ID_3 (sel_w, sel_w, w),
23260 NILP (window_mode_line_format)
23261 ? BVAR (current_buffer, mode_line_format)
23262 : window_mode_line_format);
23263 ++n;
23266 if (window_wants_header_line (w))
23268 Lisp_Object window_header_line_format
23269 = window_parameter (w, Qheader_line_format);
23271 display_mode_line (w, HEADER_LINE_FACE_ID,
23272 NILP (window_header_line_format)
23273 ? BVAR (current_buffer, header_line_format)
23274 : window_header_line_format);
23275 ++n;
23278 XFRAME (new_frame)->selected_window = old_frame_selected_window;
23279 selected_frame = old_selected_frame;
23280 selected_window = old_selected_window;
23281 if (n > 0)
23282 w->must_be_updated_p = true;
23283 return n;
23287 /* Display mode or header line of window W. FACE_ID specifies which
23288 line to display; it is either MODE_LINE_FACE_ID or
23289 HEADER_LINE_FACE_ID. FORMAT is the mode/header line format to
23290 display. Value is the pixel height of the mode/header line
23291 displayed. */
23293 static int
23294 display_mode_line (struct window *w, enum face_id face_id, Lisp_Object format)
23296 struct it it;
23297 struct face *face;
23298 ptrdiff_t count = SPECPDL_INDEX ();
23300 init_iterator (&it, w, -1, -1, NULL, face_id);
23301 /* Don't extend on a previously drawn mode-line.
23302 This may happen if called from pos_visible_p. */
23303 it.glyph_row->enabled_p = false;
23304 prepare_desired_row (w, it.glyph_row, true);
23306 it.glyph_row->mode_line_p = true;
23308 /* FIXME: This should be controlled by a user option. But
23309 supporting such an option is not trivial, since the mode line is
23310 made up of many separate strings. */
23311 it.paragraph_embedding = L2R;
23313 record_unwind_protect (unwind_format_mode_line,
23314 format_mode_line_unwind_data (NULL, NULL,
23315 Qnil, false));
23317 mode_line_target = MODE_LINE_DISPLAY;
23319 /* Temporarily make frame's keyboard the current kboard so that
23320 kboard-local variables in the mode_line_format will get the right
23321 values. */
23322 push_kboard (FRAME_KBOARD (it.f));
23323 record_unwind_save_match_data ();
23324 display_mode_element (&it, 0, 0, 0, format, Qnil, false);
23325 pop_kboard ();
23327 unbind_to (count, Qnil);
23329 /* Fill up with spaces. */
23330 display_string (" ", Qnil, Qnil, 0, 0, &it, 10000, -1, -1, 0);
23332 compute_line_metrics (&it);
23333 it.glyph_row->full_width_p = true;
23334 it.glyph_row->continued_p = false;
23335 it.glyph_row->truncated_on_left_p = false;
23336 it.glyph_row->truncated_on_right_p = false;
23338 /* Make a 3D mode-line have a shadow at its right end. */
23339 face = FACE_FROM_ID (it.f, face_id);
23340 extend_face_to_end_of_line (&it);
23341 if (face->box != FACE_NO_BOX)
23343 struct glyph *last = (it.glyph_row->glyphs[TEXT_AREA]
23344 + it.glyph_row->used[TEXT_AREA] - 1);
23345 last->right_box_line_p = true;
23348 return it.glyph_row->height;
23351 /* Move element ELT in LIST to the front of LIST.
23352 Return the updated list. */
23354 static Lisp_Object
23355 move_elt_to_front (Lisp_Object elt, Lisp_Object list)
23357 register Lisp_Object tail, prev;
23358 register Lisp_Object tem;
23360 tail = list;
23361 prev = Qnil;
23362 while (CONSP (tail))
23364 tem = XCAR (tail);
23366 if (EQ (elt, tem))
23368 /* Splice out the link TAIL. */
23369 if (NILP (prev))
23370 list = XCDR (tail);
23371 else
23372 Fsetcdr (prev, XCDR (tail));
23374 /* Now make it the first. */
23375 Fsetcdr (tail, list);
23376 return tail;
23378 else
23379 prev = tail;
23380 tail = XCDR (tail);
23381 maybe_quit ();
23384 /* Not found--return unchanged LIST. */
23385 return list;
23388 /* Contribute ELT to the mode line for window IT->w. How it
23389 translates into text depends on its data type.
23391 IT describes the display environment in which we display, as usual.
23393 DEPTH is the depth in recursion. It is used to prevent
23394 infinite recursion here.
23396 FIELD_WIDTH is the number of characters the display of ELT should
23397 occupy in the mode line, and PRECISION is the maximum number of
23398 characters to display from ELT's representation. See
23399 display_string for details.
23401 Returns the hpos of the end of the text generated by ELT.
23403 PROPS is a property list to add to any string we encounter.
23405 If RISKY, remove (disregard) any properties in any string
23406 we encounter, and ignore :eval and :propertize.
23408 The global variable `mode_line_target' determines whether the
23409 output is passed to `store_mode_line_noprop',
23410 `store_mode_line_string', or `display_string'. */
23412 static int
23413 display_mode_element (struct it *it, int depth, int field_width, int precision,
23414 Lisp_Object elt, Lisp_Object props, bool risky)
23416 int n = 0, field, prec;
23417 bool literal = false;
23419 tail_recurse:
23420 if (depth > 100)
23421 elt = build_string ("*too-deep*");
23423 depth++;
23425 switch (XTYPE (elt))
23427 case Lisp_String:
23429 /* A string: output it and check for %-constructs within it. */
23430 unsigned char c;
23431 ptrdiff_t offset = 0;
23433 if (SCHARS (elt) > 0
23434 && (!NILP (props) || risky))
23436 Lisp_Object oprops, aelt;
23437 oprops = Ftext_properties_at (make_number (0), elt);
23439 /* If the starting string's properties are not what
23440 we want, translate the string. Also, if the string
23441 is risky, do that anyway. */
23443 if (NILP (Fequal (props, oprops)) || risky)
23445 /* If the starting string has properties,
23446 merge the specified ones onto the existing ones. */
23447 if (! NILP (oprops) && !risky)
23449 Lisp_Object tem;
23451 oprops = Fcopy_sequence (oprops);
23452 tem = props;
23453 while (CONSP (tem))
23455 oprops = Fplist_put (oprops, XCAR (tem),
23456 XCAR (XCDR (tem)));
23457 tem = XCDR (XCDR (tem));
23459 props = oprops;
23462 aelt = Fassoc (elt, mode_line_proptrans_alist, Qnil);
23463 if (! NILP (aelt) && !NILP (Fequal (props, XCDR (aelt))))
23465 /* AELT is what we want. Move it to the front
23466 without consing. */
23467 elt = XCAR (aelt);
23468 mode_line_proptrans_alist
23469 = move_elt_to_front (aelt, mode_line_proptrans_alist);
23471 else
23473 Lisp_Object tem;
23475 /* If AELT has the wrong props, it is useless.
23476 so get rid of it. */
23477 if (! NILP (aelt))
23478 mode_line_proptrans_alist
23479 = Fdelq (aelt, mode_line_proptrans_alist);
23481 elt = Fcopy_sequence (elt);
23482 Fset_text_properties (make_number (0), Flength (elt),
23483 props, elt);
23484 /* Add this item to mode_line_proptrans_alist. */
23485 mode_line_proptrans_alist
23486 = Fcons (Fcons (elt, props),
23487 mode_line_proptrans_alist);
23488 /* Truncate mode_line_proptrans_alist
23489 to at most 50 elements. */
23490 tem = Fnthcdr (make_number (50),
23491 mode_line_proptrans_alist);
23492 if (! NILP (tem))
23493 XSETCDR (tem, Qnil);
23498 offset = 0;
23500 if (literal)
23502 prec = precision - n;
23503 switch (mode_line_target)
23505 case MODE_LINE_NOPROP:
23506 case MODE_LINE_TITLE:
23507 n += store_mode_line_noprop (SSDATA (elt), -1, prec);
23508 break;
23509 case MODE_LINE_STRING:
23510 n += store_mode_line_string (NULL, elt, true, 0, prec, Qnil);
23511 break;
23512 case MODE_LINE_DISPLAY:
23513 n += display_string (NULL, elt, Qnil, 0, 0, it,
23514 0, prec, 0, STRING_MULTIBYTE (elt));
23515 break;
23518 break;
23521 /* Handle the non-literal case. */
23523 while ((precision <= 0 || n < precision)
23524 && SREF (elt, offset) != 0
23525 && (mode_line_target != MODE_LINE_DISPLAY
23526 || it->current_x < it->last_visible_x))
23528 ptrdiff_t last_offset = offset;
23530 /* Advance to end of string or next format specifier. */
23531 while ((c = SREF (elt, offset++)) != '\0' && c != '%')
23534 if (offset - 1 != last_offset)
23536 ptrdiff_t nchars, nbytes;
23538 /* Output to end of string or up to '%'. Field width
23539 is length of string. Don't output more than
23540 PRECISION allows us. */
23541 offset--;
23543 prec = c_string_width (SDATA (elt) + last_offset,
23544 offset - last_offset, precision - n,
23545 &nchars, &nbytes);
23547 switch (mode_line_target)
23549 case MODE_LINE_NOPROP:
23550 case MODE_LINE_TITLE:
23551 n += store_mode_line_noprop (SSDATA (elt) + last_offset, 0, prec);
23552 break;
23553 case MODE_LINE_STRING:
23555 ptrdiff_t bytepos = last_offset;
23556 ptrdiff_t charpos = string_byte_to_char (elt, bytepos);
23557 ptrdiff_t endpos = (precision <= 0
23558 ? string_byte_to_char (elt, offset)
23559 : charpos + nchars);
23560 Lisp_Object mode_string
23561 = Fsubstring (elt, make_number (charpos),
23562 make_number (endpos));
23563 n += store_mode_line_string (NULL, mode_string, false,
23564 0, 0, Qnil);
23566 break;
23567 case MODE_LINE_DISPLAY:
23569 ptrdiff_t bytepos = last_offset;
23570 ptrdiff_t charpos = string_byte_to_char (elt, bytepos);
23572 if (precision <= 0)
23573 nchars = string_byte_to_char (elt, offset) - charpos;
23574 n += display_string (NULL, elt, Qnil, 0, charpos,
23575 it, 0, nchars, 0,
23576 STRING_MULTIBYTE (elt));
23578 break;
23581 else /* c == '%' */
23583 ptrdiff_t percent_position = offset;
23585 /* Get the specified minimum width. Zero means
23586 don't pad. */
23587 field = 0;
23588 while ((c = SREF (elt, offset++)) >= '0' && c <= '9')
23589 field = field * 10 + c - '0';
23591 /* Don't pad beyond the total padding allowed. */
23592 if (field_width - n > 0 && field > field_width - n)
23593 field = field_width - n;
23595 /* Note that either PRECISION <= 0 or N < PRECISION. */
23596 prec = precision - n;
23598 if (c == 'M')
23599 n += display_mode_element (it, depth, field, prec,
23600 Vglobal_mode_string, props,
23601 risky);
23602 else if (c != 0)
23604 bool multibyte;
23605 ptrdiff_t bytepos, charpos;
23606 const char *spec;
23607 Lisp_Object string;
23609 bytepos = percent_position;
23610 charpos = (STRING_MULTIBYTE (elt)
23611 ? string_byte_to_char (elt, bytepos)
23612 : bytepos);
23613 spec = decode_mode_spec (it->w, c, field, &string);
23614 multibyte = STRINGP (string) && STRING_MULTIBYTE (string);
23616 switch (mode_line_target)
23618 case MODE_LINE_NOPROP:
23619 case MODE_LINE_TITLE:
23620 n += store_mode_line_noprop (spec, field, prec);
23621 break;
23622 case MODE_LINE_STRING:
23624 Lisp_Object tem = build_string (spec);
23625 props = Ftext_properties_at (make_number (charpos), elt);
23626 /* Should only keep face property in props */
23627 n += store_mode_line_string (NULL, tem, false,
23628 field, prec, props);
23630 break;
23631 case MODE_LINE_DISPLAY:
23633 int nglyphs_before, nwritten;
23635 nglyphs_before = it->glyph_row->used[TEXT_AREA];
23636 nwritten = display_string (spec, string, elt,
23637 charpos, 0, it,
23638 field, prec, 0,
23639 multibyte);
23641 /* Assign to the glyphs written above the
23642 string where the `%x' came from, position
23643 of the `%'. */
23644 if (nwritten > 0)
23646 struct glyph *glyph
23647 = (it->glyph_row->glyphs[TEXT_AREA]
23648 + nglyphs_before);
23649 int i;
23651 for (i = 0; i < nwritten; ++i)
23653 glyph[i].object = elt;
23654 glyph[i].charpos = charpos;
23657 n += nwritten;
23660 break;
23663 else /* c == 0 */
23664 break;
23668 break;
23670 case Lisp_Symbol:
23671 /* A symbol: process the value of the symbol recursively
23672 as if it appeared here directly. Avoid error if symbol void.
23673 Special case: if value of symbol is a string, output the string
23674 literally. */
23676 register Lisp_Object tem;
23678 /* If the variable is not marked as risky to set
23679 then its contents are risky to use. */
23680 if (NILP (Fget (elt, Qrisky_local_variable)))
23681 risky = true;
23683 tem = Fboundp (elt);
23684 if (!NILP (tem))
23686 tem = Fsymbol_value (elt);
23687 /* If value is a string, output that string literally:
23688 don't check for % within it. */
23689 if (STRINGP (tem))
23690 literal = true;
23692 if (!EQ (tem, elt))
23694 /* Give up right away for nil or t. */
23695 elt = tem;
23696 goto tail_recurse;
23700 break;
23702 case Lisp_Cons:
23704 register Lisp_Object car, tem;
23706 /* A cons cell: five distinct cases.
23707 If first element is :eval or :propertize, do something special.
23708 If first element is a string or a cons, process all the elements
23709 and effectively concatenate them.
23710 If first element is a negative number, truncate displaying cdr to
23711 at most that many characters. If positive, pad (with spaces)
23712 to at least that many characters.
23713 If first element is a symbol, process the cadr or caddr recursively
23714 according to whether the symbol's value is non-nil or nil. */
23715 car = XCAR (elt);
23716 if (EQ (car, QCeval))
23718 /* An element of the form (:eval FORM) means evaluate FORM
23719 and use the result as mode line elements. */
23721 if (risky)
23722 break;
23724 if (CONSP (XCDR (elt)))
23726 Lisp_Object spec;
23727 spec = safe__eval (true, XCAR (XCDR (elt)));
23728 /* The :eval form could delete the frame stored in the
23729 iterator, which will cause a crash if we try to
23730 access faces and other fields (e.g., FRAME_KBOARD)
23731 on that frame. This is a nonsensical thing to do,
23732 and signaling an error from redisplay might be
23733 dangerous, but we cannot continue with an invalid frame. */
23734 if (!FRAME_LIVE_P (it->f))
23735 signal_error (":eval deleted the frame being displayed", elt);
23736 n += display_mode_element (it, depth, field_width - n,
23737 precision - n, spec, props,
23738 risky);
23741 else if (EQ (car, QCpropertize))
23743 /* An element of the form (:propertize ELT PROPS...)
23744 means display ELT but applying properties PROPS. */
23746 if (risky)
23747 break;
23749 if (CONSP (XCDR (elt)))
23750 n += display_mode_element (it, depth, field_width - n,
23751 precision - n, XCAR (XCDR (elt)),
23752 XCDR (XCDR (elt)), risky);
23754 else if (SYMBOLP (car))
23756 tem = Fboundp (car);
23757 elt = XCDR (elt);
23758 if (!CONSP (elt))
23759 goto invalid;
23760 /* elt is now the cdr, and we know it is a cons cell.
23761 Use its car if CAR has a non-nil value. */
23762 if (!NILP (tem))
23764 tem = Fsymbol_value (car);
23765 if (!NILP (tem))
23767 elt = XCAR (elt);
23768 goto tail_recurse;
23771 /* Symbol's value is nil (or symbol is unbound)
23772 Get the cddr of the original list
23773 and if possible find the caddr and use that. */
23774 elt = XCDR (elt);
23775 if (NILP (elt))
23776 break;
23777 else if (!CONSP (elt))
23778 goto invalid;
23779 elt = XCAR (elt);
23780 goto tail_recurse;
23782 else if (INTEGERP (car))
23784 register int lim = XINT (car);
23785 elt = XCDR (elt);
23786 if (lim < 0)
23788 /* Negative int means reduce maximum width. */
23789 if (precision <= 0)
23790 precision = -lim;
23791 else
23792 precision = min (precision, -lim);
23794 else if (lim > 0)
23796 /* Padding specified. Don't let it be more than
23797 current maximum. */
23798 if (precision > 0)
23799 lim = min (precision, lim);
23801 /* If that's more padding than already wanted, queue it.
23802 But don't reduce padding already specified even if
23803 that is beyond the current truncation point. */
23804 field_width = max (lim, field_width);
23806 goto tail_recurse;
23808 else if (STRINGP (car) || CONSP (car))
23809 FOR_EACH_TAIL_SAFE (elt)
23811 if (0 < precision && precision <= n)
23812 break;
23813 n += display_mode_element (it, depth,
23814 /* Pad after only the last
23815 list element. */
23816 (! CONSP (XCDR (elt))
23817 ? field_width - n
23818 : 0),
23819 precision - n, XCAR (elt),
23820 props, risky);
23823 break;
23825 default:
23826 invalid:
23827 elt = build_string ("*invalid*");
23828 goto tail_recurse;
23831 /* Pad to FIELD_WIDTH. */
23832 if (field_width > 0 && n < field_width)
23834 switch (mode_line_target)
23836 case MODE_LINE_NOPROP:
23837 case MODE_LINE_TITLE:
23838 n += store_mode_line_noprop ("", field_width - n, 0);
23839 break;
23840 case MODE_LINE_STRING:
23841 n += store_mode_line_string ("", Qnil, false, field_width - n, 0,
23842 Qnil);
23843 break;
23844 case MODE_LINE_DISPLAY:
23845 n += display_string ("", Qnil, Qnil, 0, 0, it, field_width - n,
23846 0, 0, 0);
23847 break;
23851 return n;
23854 /* Store a mode-line string element in mode_line_string_list.
23856 If STRING is non-null, display that C string. Otherwise, the Lisp
23857 string LISP_STRING is displayed.
23859 FIELD_WIDTH is the minimum number of output glyphs to produce.
23860 If STRING has fewer characters than FIELD_WIDTH, pad to the right
23861 with spaces. FIELD_WIDTH <= 0 means don't pad.
23863 PRECISION is the maximum number of characters to output from
23864 STRING. PRECISION <= 0 means don't truncate the string.
23866 If COPY_STRING, make a copy of LISP_STRING before adding
23867 properties to the string.
23869 PROPS are the properties to add to the string.
23870 The mode_line_string_face face property is always added to the string.
23873 static int
23874 store_mode_line_string (const char *string, Lisp_Object lisp_string,
23875 bool copy_string,
23876 int field_width, int precision, Lisp_Object props)
23878 ptrdiff_t len;
23879 int n = 0;
23881 if (string != NULL)
23883 len = strlen (string);
23884 if (precision > 0 && len > precision)
23885 len = precision;
23886 lisp_string = make_string (string, len);
23887 if (NILP (props))
23888 props = mode_line_string_face_prop;
23889 else if (!NILP (mode_line_string_face))
23891 Lisp_Object face = Fplist_get (props, Qface);
23892 props = Fcopy_sequence (props);
23893 if (NILP (face))
23894 face = mode_line_string_face;
23895 else
23896 face = list2 (face, mode_line_string_face);
23897 props = Fplist_put (props, Qface, face);
23899 Fadd_text_properties (make_number (0), make_number (len),
23900 props, lisp_string);
23902 else
23904 len = XFASTINT (Flength (lisp_string));
23905 if (precision > 0 && len > precision)
23907 len = precision;
23908 lisp_string = Fsubstring (lisp_string, make_number (0), make_number (len));
23909 precision = -1;
23911 if (!NILP (mode_line_string_face))
23913 Lisp_Object face;
23914 if (NILP (props))
23915 props = Ftext_properties_at (make_number (0), lisp_string);
23916 face = Fplist_get (props, Qface);
23917 if (NILP (face))
23918 face = mode_line_string_face;
23919 else
23920 face = list2 (face, mode_line_string_face);
23921 props = list2 (Qface, face);
23922 if (copy_string)
23923 lisp_string = Fcopy_sequence (lisp_string);
23925 if (!NILP (props))
23926 Fadd_text_properties (make_number (0), make_number (len),
23927 props, lisp_string);
23930 if (len > 0)
23932 mode_line_string_list = Fcons (lisp_string, mode_line_string_list);
23933 n += len;
23936 if (field_width > len)
23938 field_width -= len;
23939 lisp_string = Fmake_string (make_number (field_width), make_number (' '),
23940 Qnil);
23941 if (!NILP (props))
23942 Fadd_text_properties (make_number (0), make_number (field_width),
23943 props, lisp_string);
23944 mode_line_string_list = Fcons (lisp_string, mode_line_string_list);
23945 n += field_width;
23948 return n;
23952 DEFUN ("format-mode-line", Fformat_mode_line, Sformat_mode_line,
23953 1, 4, 0,
23954 doc: /* Format a string out of a mode line format specification.
23955 First arg FORMAT specifies the mode line format (see `mode-line-format'
23956 for details) to use.
23958 By default, the format is evaluated for the currently selected window.
23960 Optional second arg FACE specifies the face property to put on all
23961 characters for which no face is specified. The value nil means the
23962 default face. The value t means whatever face the window's mode line
23963 currently uses (either `mode-line' or `mode-line-inactive',
23964 depending on whether the window is the selected window or not).
23965 An integer value means the value string has no text
23966 properties.
23968 Optional third and fourth args WINDOW and BUFFER specify the window
23969 and buffer to use as the context for the formatting (defaults
23970 are the selected window and the WINDOW's buffer). */)
23971 (Lisp_Object format, Lisp_Object face,
23972 Lisp_Object window, Lisp_Object buffer)
23974 struct it it;
23975 int len;
23976 struct window *w;
23977 struct buffer *old_buffer = NULL;
23978 int face_id;
23979 bool no_props = INTEGERP (face);
23980 ptrdiff_t count = SPECPDL_INDEX ();
23981 Lisp_Object str;
23982 int string_start = 0;
23984 w = decode_any_window (window);
23985 XSETWINDOW (window, w);
23987 if (NILP (buffer))
23988 buffer = w->contents;
23989 CHECK_BUFFER (buffer);
23991 /* Make formatting the modeline a non-op when noninteractive, otherwise
23992 there will be problems later caused by a partially initialized frame. */
23993 if (NILP (format) || noninteractive)
23994 return empty_unibyte_string;
23996 if (no_props)
23997 face = Qnil;
23999 face_id = (NILP (face) || EQ (face, Qdefault)) ? DEFAULT_FACE_ID
24000 : EQ (face, Qt) ? (EQ (window, selected_window)
24001 ? MODE_LINE_FACE_ID : MODE_LINE_INACTIVE_FACE_ID)
24002 : EQ (face, Qmode_line) ? MODE_LINE_FACE_ID
24003 : EQ (face, Qmode_line_inactive) ? MODE_LINE_INACTIVE_FACE_ID
24004 : EQ (face, Qheader_line) ? HEADER_LINE_FACE_ID
24005 : EQ (face, Qtool_bar) ? TOOL_BAR_FACE_ID
24006 : DEFAULT_FACE_ID;
24008 old_buffer = current_buffer;
24010 /* Save things including mode_line_proptrans_alist,
24011 and set that to nil so that we don't alter the outer value. */
24012 record_unwind_protect (unwind_format_mode_line,
24013 format_mode_line_unwind_data
24014 (XFRAME (WINDOW_FRAME (w)),
24015 old_buffer, selected_window, true));
24016 mode_line_proptrans_alist = Qnil;
24018 Fselect_window (window, Qt);
24019 set_buffer_internal_1 (XBUFFER (buffer));
24021 init_iterator (&it, w, -1, -1, NULL, face_id);
24023 if (no_props)
24025 mode_line_target = MODE_LINE_NOPROP;
24026 mode_line_string_face_prop = Qnil;
24027 mode_line_string_list = Qnil;
24028 string_start = MODE_LINE_NOPROP_LEN (0);
24030 else
24032 mode_line_target = MODE_LINE_STRING;
24033 mode_line_string_list = Qnil;
24034 mode_line_string_face = face;
24035 mode_line_string_face_prop
24036 = NILP (face) ? Qnil : list2 (Qface, face);
24039 push_kboard (FRAME_KBOARD (it.f));
24040 display_mode_element (&it, 0, 0, 0, format, Qnil, false);
24041 pop_kboard ();
24043 if (no_props)
24045 len = MODE_LINE_NOPROP_LEN (string_start);
24046 str = make_string (mode_line_noprop_buf + string_start, len);
24048 else
24050 mode_line_string_list = Fnreverse (mode_line_string_list);
24051 str = Fmapconcat (Qidentity, mode_line_string_list,
24052 empty_unibyte_string);
24055 unbind_to (count, Qnil);
24056 return str;
24059 /* Write a null-terminated, right justified decimal representation of
24060 the positive integer D to BUF using a minimal field width WIDTH. */
24062 static void
24063 pint2str (register char *buf, register int width, register ptrdiff_t d)
24065 register char *p = buf;
24067 if (d <= 0)
24068 *p++ = '0';
24069 else
24071 while (d > 0)
24073 *p++ = d % 10 + '0';
24074 d /= 10;
24078 for (width -= (int) (p - buf); width > 0; --width)
24079 *p++ = ' ';
24080 *p-- = '\0';
24081 while (p > buf)
24083 d = *buf;
24084 *buf++ = *p;
24085 *p-- = d;
24089 /* Write a null-terminated, right justified decimal and "human
24090 readable" representation of the nonnegative integer D to BUF using
24091 a minimal field width WIDTH. D should be smaller than 999.5e24. */
24093 static const char power_letter[] =
24095 0, /* no letter */
24096 'k', /* kilo */
24097 'M', /* mega */
24098 'G', /* giga */
24099 'T', /* tera */
24100 'P', /* peta */
24101 'E', /* exa */
24102 'Z', /* zetta */
24103 'Y' /* yotta */
24106 static void
24107 pint2hrstr (char *buf, int width, ptrdiff_t d)
24109 /* We aim to represent the nonnegative integer D as
24110 QUOTIENT.TENTHS * 10 ^ (3 * EXPONENT). */
24111 ptrdiff_t quotient = d;
24112 int remainder = 0;
24113 /* -1 means: do not use TENTHS. */
24114 int tenths = -1;
24115 int exponent = 0;
24117 /* Length of QUOTIENT.TENTHS as a string. */
24118 int length;
24120 char * psuffix;
24121 char * p;
24123 if (quotient >= 1000)
24125 /* Scale to the appropriate EXPONENT. */
24128 remainder = quotient % 1000;
24129 quotient /= 1000;
24130 exponent++;
24132 while (quotient >= 1000);
24134 /* Round to nearest and decide whether to use TENTHS or not. */
24135 if (quotient <= 9)
24137 tenths = remainder / 100;
24138 if (remainder % 100 >= 50)
24140 if (tenths < 9)
24141 tenths++;
24142 else
24144 quotient++;
24145 if (quotient == 10)
24146 tenths = -1;
24147 else
24148 tenths = 0;
24152 else
24153 if (remainder >= 500)
24155 if (quotient < 999)
24156 quotient++;
24157 else
24159 quotient = 1;
24160 exponent++;
24161 tenths = 0;
24166 /* Calculate the LENGTH of QUOTIENT.TENTHS as a string. */
24167 if (tenths == -1 && quotient <= 99)
24168 if (quotient <= 9)
24169 length = 1;
24170 else
24171 length = 2;
24172 else
24173 length = 3;
24174 p = psuffix = buf + max (width, length);
24176 /* Print EXPONENT. */
24177 *psuffix++ = power_letter[exponent];
24178 *psuffix = '\0';
24180 /* Print TENTHS. */
24181 if (tenths >= 0)
24183 *--p = '0' + tenths;
24184 *--p = '.';
24187 /* Print QUOTIENT. */
24190 int digit = quotient % 10;
24191 *--p = '0' + digit;
24193 while ((quotient /= 10) != 0);
24195 /* Print leading spaces. */
24196 while (buf < p)
24197 *--p = ' ';
24200 /* Set a mnemonic character for coding_system (Lisp symbol) in BUF.
24201 If EOL_FLAG, set also a mnemonic character for end-of-line
24202 type of CODING_SYSTEM. Return updated pointer into BUF. */
24204 static unsigned char invalid_eol_type[] = "(*invalid*)";
24206 static char *
24207 decode_mode_spec_coding (Lisp_Object coding_system, char *buf, bool eol_flag)
24209 Lisp_Object val;
24210 bool multibyte = !NILP (BVAR (current_buffer, enable_multibyte_characters));
24211 const unsigned char *eol_str;
24212 int eol_str_len;
24213 /* The EOL conversion we are using. */
24214 Lisp_Object eoltype;
24216 val = CODING_SYSTEM_SPEC (coding_system);
24217 eoltype = Qnil;
24219 if (!VECTORP (val)) /* Not yet decided. */
24221 *buf++ = multibyte ? '-' : ' ';
24222 if (eol_flag)
24223 eoltype = eol_mnemonic_undecided;
24224 /* Don't mention EOL conversion if it isn't decided. */
24226 else
24228 Lisp_Object attrs;
24229 Lisp_Object eolvalue;
24231 attrs = AREF (val, 0);
24232 eolvalue = AREF (val, 2);
24234 *buf++ = multibyte
24235 ? XFASTINT (CODING_ATTR_MNEMONIC (attrs))
24236 : ' ';
24238 if (eol_flag)
24240 /* The EOL conversion that is normal on this system. */
24242 if (NILP (eolvalue)) /* Not yet decided. */
24243 eoltype = eol_mnemonic_undecided;
24244 else if (VECTORP (eolvalue)) /* Not yet decided. */
24245 eoltype = eol_mnemonic_undecided;
24246 else /* eolvalue is Qunix, Qdos, or Qmac. */
24247 eoltype = (EQ (eolvalue, Qunix)
24248 ? eol_mnemonic_unix
24249 : EQ (eolvalue, Qdos)
24250 ? eol_mnemonic_dos : eol_mnemonic_mac);
24254 if (eol_flag)
24256 /* Mention the EOL conversion if it is not the usual one. */
24257 if (STRINGP (eoltype))
24259 eol_str = SDATA (eoltype);
24260 eol_str_len = SBYTES (eoltype);
24262 else if (CHARACTERP (eoltype))
24264 int c = XFASTINT (eoltype);
24265 return buf + CHAR_STRING (c, (unsigned char *) buf);
24267 else
24269 eol_str = invalid_eol_type;
24270 eol_str_len = sizeof (invalid_eol_type) - 1;
24272 memcpy (buf, eol_str, eol_str_len);
24273 buf += eol_str_len;
24276 return buf;
24279 /* Return the approximate percentage N is of D (rounding upward), or 99,
24280 whichever is less. Assume 0 < D and 0 <= N <= D * INT_MAX / 100. */
24282 static int
24283 percent99 (ptrdiff_t n, ptrdiff_t d)
24285 int percent = (d - 1 + 100.0 * n) / d;
24286 return min (percent, 99);
24289 /* Return a string for the output of a mode line %-spec for window W,
24290 generated by character C. FIELD_WIDTH > 0 means pad the string
24291 returned with spaces to that value. Return a Lisp string in
24292 *STRING if the resulting string is taken from that Lisp string.
24294 Note we operate on the current buffer for most purposes. */
24296 static char lots_of_dashes[] = "--------------------------------------------------------------------------------------------------------------------------------------------";
24298 static const char *
24299 decode_mode_spec (struct window *w, register int c, int field_width,
24300 Lisp_Object *string)
24302 Lisp_Object obj;
24303 struct frame *f = XFRAME (WINDOW_FRAME (w));
24304 char *decode_mode_spec_buf = f->decode_mode_spec_buffer;
24305 /* We are going to use f->decode_mode_spec_buffer as the buffer to
24306 produce strings from numerical values, so limit preposterously
24307 large values of FIELD_WIDTH to avoid overrunning the buffer's
24308 end. The size of the buffer is enough for FRAME_MESSAGE_BUF_SIZE
24309 bytes plus the terminating null. */
24310 int width = min (field_width, FRAME_MESSAGE_BUF_SIZE (f));
24311 struct buffer *b = current_buffer;
24313 obj = Qnil;
24314 *string = Qnil;
24316 switch (c)
24318 case '*':
24319 if (!NILP (BVAR (b, read_only)))
24320 return "%";
24321 if (BUF_MODIFF (b) > BUF_SAVE_MODIFF (b))
24322 return "*";
24323 return "-";
24325 case '+':
24326 /* This differs from %* only for a modified read-only buffer. */
24327 if (BUF_MODIFF (b) > BUF_SAVE_MODIFF (b))
24328 return "*";
24329 if (!NILP (BVAR (b, read_only)))
24330 return "%";
24331 return "-";
24333 case '&':
24334 /* This differs from %* in ignoring read-only-ness. */
24335 if (BUF_MODIFF (b) > BUF_SAVE_MODIFF (b))
24336 return "*";
24337 return "-";
24339 case '%':
24340 return "%";
24342 case '[':
24344 int i;
24345 char *p;
24347 if (command_loop_level > 5)
24348 return "[[[... ";
24349 p = decode_mode_spec_buf;
24350 for (i = 0; i < command_loop_level; i++)
24351 *p++ = '[';
24352 *p = 0;
24353 return decode_mode_spec_buf;
24356 case ']':
24358 int i;
24359 char *p;
24361 if (command_loop_level > 5)
24362 return " ...]]]";
24363 p = decode_mode_spec_buf;
24364 for (i = 0; i < command_loop_level; i++)
24365 *p++ = ']';
24366 *p = 0;
24367 return decode_mode_spec_buf;
24370 case '-':
24372 register int i;
24374 /* Let lots_of_dashes be a string of infinite length. */
24375 if (mode_line_target == MODE_LINE_NOPROP
24376 || mode_line_target == MODE_LINE_STRING)
24377 return "--";
24378 if (field_width <= 0
24379 || field_width > sizeof (lots_of_dashes))
24381 for (i = 0; i < FRAME_MESSAGE_BUF_SIZE (f) - 1; ++i)
24382 decode_mode_spec_buf[i] = '-';
24383 decode_mode_spec_buf[i] = '\0';
24384 return decode_mode_spec_buf;
24386 else
24387 return lots_of_dashes;
24390 case 'b':
24391 obj = BVAR (b, name);
24392 break;
24394 case 'c':
24395 case 'C':
24396 /* %c, %C, and %l are ignored in `frame-title-format'.
24397 (In redisplay_internal, the frame title is drawn _before_ the
24398 windows are updated, so the stuff which depends on actual
24399 window contents (such as %l) may fail to render properly, or
24400 even crash emacs.) */
24401 if (mode_line_target == MODE_LINE_TITLE)
24402 return "";
24403 else
24405 ptrdiff_t col = current_column ();
24406 int disp_col = (c == 'C') ? col + 1 : col;
24407 w->column_number_displayed = col;
24408 pint2str (decode_mode_spec_buf, width, disp_col);
24409 return decode_mode_spec_buf;
24412 case 'e':
24413 #if !defined SYSTEM_MALLOC && !defined HYBRID_MALLOC
24415 if (NILP (Vmemory_full))
24416 return "";
24417 else
24418 return "!MEM FULL! ";
24420 #else
24421 return "";
24422 #endif
24424 case 'F':
24425 /* %F displays the frame name. */
24426 if (!NILP (f->title))
24427 return SSDATA (f->title);
24428 if (f->explicit_name || ! FRAME_WINDOW_P (f))
24429 return SSDATA (f->name);
24430 return "Emacs";
24432 case 'f':
24433 obj = BVAR (b, filename);
24434 break;
24436 case 'i':
24438 ptrdiff_t size = ZV - BEGV;
24439 pint2str (decode_mode_spec_buf, width, size);
24440 return decode_mode_spec_buf;
24443 case 'I':
24445 ptrdiff_t size = ZV - BEGV;
24446 pint2hrstr (decode_mode_spec_buf, width, size);
24447 return decode_mode_spec_buf;
24450 case 'l':
24452 ptrdiff_t startpos, startpos_byte, line, linepos, linepos_byte;
24453 ptrdiff_t topline, nlines, height;
24454 ptrdiff_t junk;
24456 /* %c, %C, and %l are ignored in `frame-title-format'. */
24457 if (mode_line_target == MODE_LINE_TITLE)
24458 return "";
24460 startpos = marker_position (w->start);
24461 startpos_byte = marker_byte_position (w->start);
24462 height = WINDOW_TOTAL_LINES (w);
24464 /* If we decided that this buffer isn't suitable for line numbers,
24465 don't forget that too fast. */
24466 if (w->base_line_pos == -1)
24467 goto no_value;
24469 /* If the buffer is very big, don't waste time. */
24470 if (INTEGERP (Vline_number_display_limit)
24471 && BUF_ZV (b) - BUF_BEGV (b) > XINT (Vline_number_display_limit))
24473 w->base_line_pos = 0;
24474 w->base_line_number = 0;
24475 goto no_value;
24478 if (w->base_line_number > 0
24479 && w->base_line_pos > 0
24480 && w->base_line_pos <= startpos)
24482 line = w->base_line_number;
24483 linepos = w->base_line_pos;
24484 linepos_byte = buf_charpos_to_bytepos (b, linepos);
24486 else
24488 line = 1;
24489 linepos = BUF_BEGV (b);
24490 linepos_byte = BUF_BEGV_BYTE (b);
24493 /* Count lines from base line to window start position. */
24494 nlines = display_count_lines (linepos_byte,
24495 startpos_byte,
24496 startpos, &junk);
24498 topline = nlines + line;
24500 /* Determine a new base line, if the old one is too close
24501 or too far away, or if we did not have one.
24502 "Too close" means it's plausible a scroll-down would
24503 go back past it. */
24504 if (startpos == BUF_BEGV (b))
24506 w->base_line_number = topline;
24507 w->base_line_pos = BUF_BEGV (b);
24509 else if (nlines < height + 25 || nlines > height * 3 + 50
24510 || linepos == BUF_BEGV (b))
24512 ptrdiff_t limit = BUF_BEGV (b);
24513 ptrdiff_t limit_byte = BUF_BEGV_BYTE (b);
24514 ptrdiff_t position;
24515 ptrdiff_t distance =
24516 (height * 2 + 30) * line_number_display_limit_width;
24518 if (startpos - distance > limit)
24520 limit = startpos - distance;
24521 limit_byte = CHAR_TO_BYTE (limit);
24524 nlines = display_count_lines (startpos_byte,
24525 limit_byte,
24526 - (height * 2 + 30),
24527 &position);
24528 /* If we couldn't find the lines we wanted within
24529 line_number_display_limit_width chars per line,
24530 give up on line numbers for this window. */
24531 if (position == limit_byte && limit == startpos - distance)
24533 w->base_line_pos = -1;
24534 w->base_line_number = 0;
24535 goto no_value;
24538 w->base_line_number = topline - nlines;
24539 w->base_line_pos = BYTE_TO_CHAR (position);
24542 /* Now count lines from the start pos to point. */
24543 nlines = display_count_lines (startpos_byte,
24544 PT_BYTE, PT, &junk);
24546 /* Record that we did display the line number. */
24547 line_number_displayed = true;
24549 /* Make the string to show. */
24550 pint2str (decode_mode_spec_buf, width, topline + nlines);
24551 return decode_mode_spec_buf;
24552 no_value:
24554 char *p = decode_mode_spec_buf;
24555 int pad = width - 2;
24556 while (pad-- > 0)
24557 *p++ = ' ';
24558 *p++ = '?';
24559 *p++ = '?';
24560 *p = '\0';
24561 return decode_mode_spec_buf;
24564 break;
24566 case 'm':
24567 obj = BVAR (b, mode_name);
24568 break;
24570 case 'n':
24571 if (BUF_BEGV (b) > BUF_BEG (b) || BUF_ZV (b) < BUF_Z (b))
24572 return " Narrow";
24573 break;
24575 /* Display the "degree of travel" of the window through the buffer. */
24576 case 'o':
24578 ptrdiff_t toppos = marker_position (w->start);
24579 ptrdiff_t botpos = BUF_Z (b) - w->window_end_pos;
24580 ptrdiff_t begv = BUF_BEGV (b);
24581 ptrdiff_t zv = BUF_ZV (b);
24583 if (zv <= botpos)
24584 return toppos <= begv ? "All" : "Bottom";
24585 else if (toppos <= begv)
24586 return "Top";
24587 else
24589 sprintf (decode_mode_spec_buf, "%2d%%",
24590 percent99 (toppos - begv, (toppos - begv) + (zv - botpos)));
24591 return decode_mode_spec_buf;
24595 /* Display percentage of buffer above the top of the screen. */
24596 case 'p':
24598 ptrdiff_t pos = marker_position (w->start);
24599 ptrdiff_t begv = BUF_BEGV (b);
24600 ptrdiff_t zv = BUF_ZV (b);
24602 if (w->window_end_pos <= BUF_Z (b) - zv)
24603 return pos <= begv ? "All" : "Bottom";
24604 else if (pos <= begv)
24605 return "Top";
24606 else
24608 sprintf (decode_mode_spec_buf, "%2d%%",
24609 percent99 (pos - begv, zv - begv));
24610 return decode_mode_spec_buf;
24614 /* Display percentage of size above the bottom of the screen. */
24615 case 'P':
24617 ptrdiff_t toppos = marker_position (w->start);
24618 ptrdiff_t botpos = BUF_Z (b) - w->window_end_pos;
24619 ptrdiff_t begv = BUF_BEGV (b);
24620 ptrdiff_t zv = BUF_ZV (b);
24622 if (zv <= botpos)
24623 return toppos <= begv ? "All" : "Bottom";
24624 else
24626 sprintf (decode_mode_spec_buf,
24627 &"Top%2d%%"[begv < toppos ? sizeof "Top" - 1 : 0],
24628 percent99 (botpos - begv, zv - begv));
24629 return decode_mode_spec_buf;
24633 /* Display percentage offsets of top and bottom of the window,
24634 using "All" (but not "Top" or "Bottom") where appropriate. */
24635 case 'q':
24637 ptrdiff_t toppos = marker_position (w->start);
24638 ptrdiff_t botpos = BUF_Z (b) - w->window_end_pos;
24639 ptrdiff_t begv = BUF_BEGV (b);
24640 ptrdiff_t zv = BUF_ZV (b);
24641 int top_perc, bot_perc;
24643 if ((toppos <= begv) && (zv <= botpos))
24644 return "All ";
24646 top_perc = toppos <= begv ? 0 : percent99 (toppos - begv, zv - begv);
24647 bot_perc = zv <= botpos ? 100 : percent99 (botpos - begv, zv - begv);
24649 if (top_perc == bot_perc)
24650 sprintf (decode_mode_spec_buf, "%d%%", top_perc);
24651 else
24652 sprintf (decode_mode_spec_buf, "%d-%d%%", top_perc, bot_perc);
24654 return decode_mode_spec_buf;
24657 case 's':
24658 /* status of process */
24659 obj = Fget_buffer_process (Fcurrent_buffer ());
24660 if (NILP (obj))
24661 return "no process";
24662 #ifndef MSDOS
24663 obj = Fsymbol_name (Fprocess_status (obj));
24664 #endif
24665 break;
24667 case '@':
24669 ptrdiff_t count = inhibit_garbage_collection ();
24670 Lisp_Object curdir = BVAR (current_buffer, directory);
24671 Lisp_Object val = Qnil;
24673 if (STRINGP (curdir))
24674 val = call1 (intern ("file-remote-p"), curdir);
24676 unbind_to (count, Qnil);
24678 if (NILP (val))
24679 return "-";
24680 else
24681 return "@";
24684 case 'z':
24685 /* coding-system (not including end-of-line format) */
24686 case 'Z':
24687 /* coding-system (including end-of-line type) */
24689 bool eol_flag = (c == 'Z');
24690 char *p = decode_mode_spec_buf;
24692 if (! FRAME_WINDOW_P (f))
24694 /* No need to mention EOL here--the terminal never needs
24695 to do EOL conversion. */
24696 p = decode_mode_spec_coding (CODING_ID_NAME
24697 (FRAME_KEYBOARD_CODING (f)->id),
24698 p, false);
24699 p = decode_mode_spec_coding (CODING_ID_NAME
24700 (FRAME_TERMINAL_CODING (f)->id),
24701 p, false);
24703 p = decode_mode_spec_coding (BVAR (b, buffer_file_coding_system),
24704 p, eol_flag);
24706 #if false /* This proves to be annoying; I think we can do without. -- rms. */
24707 #ifdef subprocesses
24708 obj = Fget_buffer_process (Fcurrent_buffer ());
24709 if (PROCESSP (obj))
24711 p = decode_mode_spec_coding
24712 (XPROCESS (obj)->decode_coding_system, p, eol_flag);
24713 p = decode_mode_spec_coding
24714 (XPROCESS (obj)->encode_coding_system, p, eol_flag);
24716 #endif /* subprocesses */
24717 #endif /* false */
24718 *p = 0;
24719 return decode_mode_spec_buf;
24723 if (STRINGP (obj))
24725 *string = obj;
24726 return SSDATA (obj);
24728 else
24729 return "";
24733 /* Count up to COUNT lines starting from START_BYTE. COUNT negative
24734 means count lines back from START_BYTE. But don't go beyond
24735 LIMIT_BYTE. Return the number of lines thus found (always
24736 nonnegative).
24738 Set *BYTE_POS_PTR to the byte position where we stopped. This is
24739 either the position COUNT lines after/before START_BYTE, if we
24740 found COUNT lines, or LIMIT_BYTE if we hit the limit before finding
24741 COUNT lines. */
24743 static ptrdiff_t
24744 display_count_lines (ptrdiff_t start_byte,
24745 ptrdiff_t limit_byte, ptrdiff_t count,
24746 ptrdiff_t *byte_pos_ptr)
24748 register unsigned char *cursor;
24749 unsigned char *base;
24751 register ptrdiff_t ceiling;
24752 register unsigned char *ceiling_addr;
24753 ptrdiff_t orig_count = count;
24755 /* If we are not in selective display mode,
24756 check only for newlines. */
24757 bool selective_display
24758 = (!NILP (BVAR (current_buffer, selective_display))
24759 && !INTEGERP (BVAR (current_buffer, selective_display)));
24761 if (count > 0)
24763 while (start_byte < limit_byte)
24765 ceiling = BUFFER_CEILING_OF (start_byte);
24766 ceiling = min (limit_byte - 1, ceiling);
24767 ceiling_addr = BYTE_POS_ADDR (ceiling) + 1;
24768 base = (cursor = BYTE_POS_ADDR (start_byte));
24772 if (selective_display)
24774 while (*cursor != '\n' && *cursor != 015
24775 && ++cursor != ceiling_addr)
24776 continue;
24777 if (cursor == ceiling_addr)
24778 break;
24780 else
24782 cursor = memchr (cursor, '\n', ceiling_addr - cursor);
24783 if (! cursor)
24784 break;
24787 cursor++;
24789 if (--count == 0)
24791 start_byte += cursor - base;
24792 *byte_pos_ptr = start_byte;
24793 return orig_count;
24796 while (cursor < ceiling_addr);
24798 start_byte += ceiling_addr - base;
24801 else
24803 while (start_byte > limit_byte)
24805 ceiling = BUFFER_FLOOR_OF (start_byte - 1);
24806 ceiling = max (limit_byte, ceiling);
24807 ceiling_addr = BYTE_POS_ADDR (ceiling);
24808 base = (cursor = BYTE_POS_ADDR (start_byte - 1) + 1);
24809 while (true)
24811 if (selective_display)
24813 while (--cursor >= ceiling_addr
24814 && *cursor != '\n' && *cursor != 015)
24815 continue;
24816 if (cursor < ceiling_addr)
24817 break;
24819 else
24821 cursor = memrchr (ceiling_addr, '\n', cursor - ceiling_addr);
24822 if (! cursor)
24823 break;
24826 if (++count == 0)
24828 start_byte += cursor - base + 1;
24829 *byte_pos_ptr = start_byte;
24830 /* When scanning backwards, we should
24831 not count the newline posterior to which we stop. */
24832 return - orig_count - 1;
24835 start_byte += ceiling_addr - base;
24839 *byte_pos_ptr = limit_byte;
24841 if (count < 0)
24842 return - orig_count + count;
24843 return orig_count - count;
24849 /***********************************************************************
24850 Displaying strings
24851 ***********************************************************************/
24853 /* Display a NUL-terminated string, starting with index START.
24855 If STRING is non-null, display that C string. Otherwise, the Lisp
24856 string LISP_STRING is displayed. There's a case that STRING is
24857 non-null and LISP_STRING is not nil. It means STRING is a string
24858 data of LISP_STRING. In that case, we display LISP_STRING while
24859 ignoring its text properties.
24861 If FACE_STRING is not nil, FACE_STRING_POS is a position in
24862 FACE_STRING. Display STRING or LISP_STRING with the face at
24863 FACE_STRING_POS in FACE_STRING:
24865 Display the string in the environment given by IT, but use the
24866 standard display table, temporarily.
24868 FIELD_WIDTH is the minimum number of output glyphs to produce.
24869 If STRING has fewer characters than FIELD_WIDTH, pad to the right
24870 with spaces. If STRING has more characters, more than FIELD_WIDTH
24871 glyphs will be produced. FIELD_WIDTH <= 0 means don't pad.
24873 PRECISION is the maximum number of characters to output from
24874 STRING. PRECISION < 0 means don't truncate the string.
24876 This is roughly equivalent to printf format specifiers:
24878 FIELD_WIDTH PRECISION PRINTF
24879 ----------------------------------------
24880 -1 -1 %s
24881 -1 10 %.10s
24882 10 -1 %10s
24883 20 10 %20.10s
24885 MULTIBYTE zero means do not display multibyte chars, > 0 means do
24886 display them, and < 0 means obey the current buffer's value of
24887 enable_multibyte_characters.
24889 Value is the number of columns displayed. */
24891 static int
24892 display_string (const char *string, Lisp_Object lisp_string, Lisp_Object face_string,
24893 ptrdiff_t face_string_pos, ptrdiff_t start, struct it *it,
24894 int field_width, int precision, int max_x, int multibyte)
24896 int hpos_at_start = it->hpos;
24897 int saved_face_id = it->face_id;
24898 struct glyph_row *row = it->glyph_row;
24899 ptrdiff_t it_charpos;
24901 /* Initialize the iterator IT for iteration over STRING beginning
24902 with index START. */
24903 reseat_to_string (it, NILP (lisp_string) ? string : NULL, lisp_string, start,
24904 precision, field_width, multibyte);
24905 if (string && STRINGP (lisp_string))
24906 /* LISP_STRING is the one returned by decode_mode_spec. We should
24907 ignore its text properties. */
24908 it->stop_charpos = it->end_charpos;
24910 /* If displaying STRING, set up the face of the iterator from
24911 FACE_STRING, if that's given. */
24912 if (STRINGP (face_string))
24914 ptrdiff_t endptr;
24915 struct face *face;
24917 it->face_id
24918 = face_at_string_position (it->w, face_string, face_string_pos,
24919 0, &endptr, it->base_face_id, false);
24920 face = FACE_FROM_ID (it->f, it->face_id);
24921 it->face_box_p = face->box != FACE_NO_BOX;
24924 /* Set max_x to the maximum allowed X position. Don't let it go
24925 beyond the right edge of the window. */
24926 if (max_x <= 0)
24927 max_x = it->last_visible_x;
24928 else
24929 max_x = min (max_x, it->last_visible_x);
24931 /* Skip over display elements that are not visible. because IT->w is
24932 hscrolled. */
24933 if (it->current_x < it->first_visible_x)
24934 move_it_in_display_line_to (it, 100000, it->first_visible_x,
24935 MOVE_TO_POS | MOVE_TO_X);
24937 row->ascent = it->max_ascent;
24938 row->height = it->max_ascent + it->max_descent;
24939 row->phys_ascent = it->max_phys_ascent;
24940 row->phys_height = it->max_phys_ascent + it->max_phys_descent;
24941 row->extra_line_spacing = it->max_extra_line_spacing;
24943 if (STRINGP (it->string))
24944 it_charpos = IT_STRING_CHARPOS (*it);
24945 else
24946 it_charpos = IT_CHARPOS (*it);
24948 /* This condition is for the case that we are called with current_x
24949 past last_visible_x. */
24950 while (it->current_x < max_x)
24952 int x_before, x, n_glyphs_before, i, nglyphs;
24954 /* Get the next display element. */
24955 if (!get_next_display_element (it))
24956 break;
24958 /* Produce glyphs. */
24959 x_before = it->current_x;
24960 n_glyphs_before = row->used[TEXT_AREA];
24961 PRODUCE_GLYPHS (it);
24963 nglyphs = row->used[TEXT_AREA] - n_glyphs_before;
24964 i = 0;
24965 x = x_before;
24966 while (i < nglyphs)
24968 struct glyph *glyph = row->glyphs[TEXT_AREA] + n_glyphs_before + i;
24970 if (it->line_wrap != TRUNCATE
24971 && x + glyph->pixel_width > max_x)
24973 /* End of continued line or max_x reached. */
24974 if (CHAR_GLYPH_PADDING_P (*glyph))
24976 /* A wide character is unbreakable. */
24977 if (row->reversed_p)
24978 unproduce_glyphs (it, row->used[TEXT_AREA]
24979 - n_glyphs_before);
24980 row->used[TEXT_AREA] = n_glyphs_before;
24981 it->current_x = x_before;
24983 else
24985 if (row->reversed_p)
24986 unproduce_glyphs (it, row->used[TEXT_AREA]
24987 - (n_glyphs_before + i));
24988 row->used[TEXT_AREA] = n_glyphs_before + i;
24989 it->current_x = x;
24991 break;
24993 else if (x + glyph->pixel_width >= it->first_visible_x)
24995 /* Glyph is at least partially visible. */
24996 ++it->hpos;
24997 if (x < it->first_visible_x)
24998 row->x = x - it->first_visible_x;
25000 else
25002 /* Glyph is off the left margin of the display area.
25003 Should not happen. */
25004 emacs_abort ();
25007 row->ascent = max (row->ascent, it->max_ascent);
25008 row->height = max (row->height, it->max_ascent + it->max_descent);
25009 row->phys_ascent = max (row->phys_ascent, it->max_phys_ascent);
25010 row->phys_height = max (row->phys_height,
25011 it->max_phys_ascent + it->max_phys_descent);
25012 row->extra_line_spacing = max (row->extra_line_spacing,
25013 it->max_extra_line_spacing);
25014 x += glyph->pixel_width;
25015 ++i;
25018 /* Stop if max_x reached. */
25019 if (i < nglyphs)
25020 break;
25022 /* Stop at line ends. */
25023 if (ITERATOR_AT_END_OF_LINE_P (it))
25025 it->continuation_lines_width = 0;
25026 break;
25029 set_iterator_to_next (it, true);
25030 if (STRINGP (it->string))
25031 it_charpos = IT_STRING_CHARPOS (*it);
25032 else
25033 it_charpos = IT_CHARPOS (*it);
25035 /* Stop if truncating at the right edge. */
25036 if (it->line_wrap == TRUNCATE
25037 && it->current_x >= it->last_visible_x)
25039 /* Add truncation mark, but don't do it if the line is
25040 truncated at a padding space. */
25041 if (it_charpos < it->string_nchars)
25043 if (!FRAME_WINDOW_P (it->f))
25045 int ii, n;
25047 if (it->current_x > it->last_visible_x)
25049 if (!row->reversed_p)
25051 for (ii = row->used[TEXT_AREA] - 1; ii > 0; --ii)
25052 if (!CHAR_GLYPH_PADDING_P (row->glyphs[TEXT_AREA][ii]))
25053 break;
25055 else
25057 for (ii = 0; ii < row->used[TEXT_AREA]; ii++)
25058 if (!CHAR_GLYPH_PADDING_P (row->glyphs[TEXT_AREA][ii]))
25059 break;
25060 unproduce_glyphs (it, ii + 1);
25061 ii = row->used[TEXT_AREA] - (ii + 1);
25063 for (n = row->used[TEXT_AREA]; ii < n; ++ii)
25065 row->used[TEXT_AREA] = ii;
25066 produce_special_glyphs (it, IT_TRUNCATION);
25069 produce_special_glyphs (it, IT_TRUNCATION);
25071 row->truncated_on_right_p = true;
25073 break;
25077 /* Maybe insert a truncation at the left. */
25078 if (it->first_visible_x
25079 && it_charpos > 0)
25081 if (!FRAME_WINDOW_P (it->f)
25082 || (row->reversed_p
25083 ? WINDOW_RIGHT_FRINGE_WIDTH (it->w)
25084 : WINDOW_LEFT_FRINGE_WIDTH (it->w)) == 0)
25085 insert_left_trunc_glyphs (it);
25086 row->truncated_on_left_p = true;
25089 it->face_id = saved_face_id;
25091 /* Value is number of columns displayed. */
25092 return it->hpos - hpos_at_start;
25097 /* This is like a combination of memq and assq. Return 1/2 if PROPVAL
25098 appears as an element of LIST or as the car of an element of LIST.
25099 If PROPVAL is a list, compare each element against LIST in that
25100 way, and return 1/2 if any element of PROPVAL is found in LIST.
25101 Otherwise return 0. This function cannot quit.
25102 The return value is 2 if the text is invisible but with an ellipsis
25103 and 1 if it's invisible and without an ellipsis. */
25106 invisible_prop (Lisp_Object propval, Lisp_Object list)
25108 Lisp_Object tail, proptail;
25110 for (tail = list; CONSP (tail); tail = XCDR (tail))
25112 register Lisp_Object tem;
25113 tem = XCAR (tail);
25114 if (EQ (propval, tem))
25115 return 1;
25116 if (CONSP (tem) && EQ (propval, XCAR (tem)))
25117 return NILP (XCDR (tem)) ? 1 : 2;
25120 if (CONSP (propval))
25122 for (proptail = propval; CONSP (proptail); proptail = XCDR (proptail))
25124 Lisp_Object propelt;
25125 propelt = XCAR (proptail);
25126 for (tail = list; CONSP (tail); tail = XCDR (tail))
25128 register Lisp_Object tem;
25129 tem = XCAR (tail);
25130 if (EQ (propelt, tem))
25131 return 1;
25132 if (CONSP (tem) && EQ (propelt, XCAR (tem)))
25133 return NILP (XCDR (tem)) ? 1 : 2;
25138 return 0;
25141 DEFUN ("invisible-p", Finvisible_p, Sinvisible_p, 1, 1, 0,
25142 doc: /* Non-nil if text properties at POS cause text there to be currently invisible.
25143 POS should be a marker or a buffer position; the value of the `invisible'
25144 property at that position in the current buffer is examined.
25145 POS can also be the actual value of the `invisible' text or overlay
25146 property of the text of interest, in which case the value itself is
25147 examined.
25149 The non-nil value returned can be t for currently invisible text that is
25150 entirely hidden on display, or some other non-nil, non-t value if the
25151 text is replaced by an ellipsis.
25153 Note that whether text with `invisible' property is actually hidden on
25154 display may depend on `buffer-invisibility-spec', which see. */)
25155 (Lisp_Object pos)
25157 Lisp_Object prop
25158 = (NATNUMP (pos) || MARKERP (pos)
25159 ? Fget_char_property (pos, Qinvisible, Qnil)
25160 : pos);
25161 int invis = TEXT_PROP_MEANS_INVISIBLE (prop);
25162 return (invis == 0 ? Qnil
25163 : invis == 1 ? Qt
25164 : make_number (invis));
25167 /* Calculate a width or height in pixels from a specification using
25168 the following elements:
25170 SPEC ::=
25171 NUM - a (fractional) multiple of the default font width/height
25172 (NUM) - specifies exactly NUM pixels
25173 UNIT - a fixed number of pixels, see below.
25174 ELEMENT - size of a display element in pixels, see below.
25175 (NUM . SPEC) - equals NUM * SPEC
25176 (+ SPEC SPEC ...) - add pixel values
25177 (- SPEC SPEC ...) - subtract pixel values
25178 (- SPEC) - negate pixel value
25180 NUM ::=
25181 INT or FLOAT - a number constant
25182 SYMBOL - use symbol's (buffer local) variable binding.
25184 UNIT ::=
25185 in - pixels per inch *)
25186 mm - pixels per 1/1000 meter *)
25187 cm - pixels per 1/100 meter *)
25188 width - width of current font in pixels.
25189 height - height of current font in pixels.
25191 *) using the ratio(s) defined in display-pixels-per-inch.
25193 ELEMENT ::=
25195 left-fringe - left fringe width in pixels
25196 right-fringe - right fringe width in pixels
25198 left-margin - left margin width in pixels
25199 right-margin - right margin width in pixels
25201 scroll-bar - scroll-bar area width in pixels
25203 Examples:
25205 Pixels corresponding to 5 inches:
25206 (5 . in)
25208 Total width of non-text areas on left side of window (if scroll-bar is on left):
25209 '(space :width (+ left-fringe left-margin scroll-bar))
25211 Align to first text column (in header line):
25212 '(space :align-to 0)
25214 Align to middle of text area minus half the width of variable `my-image'
25215 containing a loaded image:
25216 '(space :align-to (0.5 . (- text my-image)))
25218 Width of left margin minus width of 1 character in the default font:
25219 '(space :width (- left-margin 1))
25221 Width of left margin minus width of 2 characters in the current font:
25222 '(space :width (- left-margin (2 . width)))
25224 Center 1 character over left-margin (in header line):
25225 '(space :align-to (+ left-margin (0.5 . left-margin) -0.5))
25227 Different ways to express width of left fringe plus left margin minus one pixel:
25228 '(space :width (- (+ left-fringe left-margin) (1)))
25229 '(space :width (+ left-fringe left-margin (- (1))))
25230 '(space :width (+ left-fringe left-margin (-1)))
25232 If ALIGN_TO is NULL, returns the result in *RES. If ALIGN_TO is
25233 non-NULL, the value of *ALIGN_TO is a window-relative pixel
25234 coordinate, and *RES is the additional pixel width from that point
25235 till the end of the stretch glyph.
25237 WIDTH_P non-zero means take the width dimension or X coordinate of
25238 the object specified by PROP, WIDTH_P zero means take the height
25239 dimension or the Y coordinate. (Therefore, if ALIGN_TO is
25240 non-NULL, WIDTH_P should be non-zero.)
25242 FONT is the font of the face of the surrounding text.
25244 The return value is non-zero if width or height were successfully
25245 calculated, i.e. if PROP is a valid spec. */
25247 static bool
25248 calc_pixel_width_or_height (double *res, struct it *it, Lisp_Object prop,
25249 struct font *font, bool width_p, int *align_to)
25251 double pixels;
25253 # define OK_PIXELS(val) (*res = (val), true)
25254 # define OK_ALIGN_TO(val) (*align_to = (val), true)
25256 if (NILP (prop))
25257 return OK_PIXELS (0);
25259 eassert (FRAME_LIVE_P (it->f));
25261 if (SYMBOLP (prop))
25263 if (SCHARS (SYMBOL_NAME (prop)) == 2)
25265 char *unit = SSDATA (SYMBOL_NAME (prop));
25267 /* The UNIT expression, e.g. as part of (NUM . UNIT). */
25268 if (unit[0] == 'i' && unit[1] == 'n')
25269 pixels = 1.0;
25270 else if (unit[0] == 'm' && unit[1] == 'm')
25271 pixels = 25.4;
25272 else if (unit[0] == 'c' && unit[1] == 'm')
25273 pixels = 2.54;
25274 else
25275 pixels = 0;
25276 if (pixels > 0)
25278 double ppi = (width_p ? FRAME_RES_X (it->f)
25279 : FRAME_RES_Y (it->f));
25281 if (ppi > 0)
25282 return OK_PIXELS (ppi / pixels);
25283 return false;
25287 #ifdef HAVE_WINDOW_SYSTEM
25288 /* 'height': the height of FONT. */
25289 if (EQ (prop, Qheight))
25290 return OK_PIXELS (font
25291 ? normal_char_height (font, -1)
25292 : FRAME_LINE_HEIGHT (it->f));
25293 /* 'width': the width of FONT. */
25294 if (EQ (prop, Qwidth))
25295 return OK_PIXELS (font
25296 ? FONT_WIDTH (font)
25297 : FRAME_COLUMN_WIDTH (it->f));
25298 #else
25299 if (EQ (prop, Qheight) || EQ (prop, Qwidth))
25300 return OK_PIXELS (1);
25301 #endif
25303 /* 'text': the width or height of the text area. */
25304 if (EQ (prop, Qtext))
25305 return OK_PIXELS (width_p
25306 ? (window_box_width (it->w, TEXT_AREA)
25307 - it->lnum_pixel_width)
25308 : WINDOW_BOX_HEIGHT_NO_MODE_LINE (it->w));
25310 /* ':align_to'. First time we compute the value, window
25311 elements are interpreted as the position of the element's
25312 left edge. */
25313 if (align_to && *align_to < 0)
25315 *res = 0;
25316 /* 'left': left edge of the text area. */
25317 if (EQ (prop, Qleft))
25318 return OK_ALIGN_TO (window_box_left_offset (it->w, TEXT_AREA)
25319 + it->lnum_pixel_width);
25320 /* 'right': right edge of the text area. */
25321 if (EQ (prop, Qright))
25322 return OK_ALIGN_TO (window_box_right_offset (it->w, TEXT_AREA));
25323 /* 'center': the center of the text area. */
25324 if (EQ (prop, Qcenter))
25325 return OK_ALIGN_TO (window_box_left_offset (it->w, TEXT_AREA)
25326 + it->lnum_pixel_width
25327 + window_box_width (it->w, TEXT_AREA) / 2);
25328 /* 'left-fringe': left edge of the left fringe. */
25329 if (EQ (prop, Qleft_fringe))
25330 return OK_ALIGN_TO (WINDOW_HAS_FRINGES_OUTSIDE_MARGINS (it->w)
25331 ? WINDOW_LEFT_SCROLL_BAR_AREA_WIDTH (it->w)
25332 : window_box_right_offset (it->w, LEFT_MARGIN_AREA));
25333 /* 'right-fringe': left edge of the right fringe. */
25334 if (EQ (prop, Qright_fringe))
25335 return OK_ALIGN_TO (WINDOW_HAS_FRINGES_OUTSIDE_MARGINS (it->w)
25336 ? window_box_right_offset (it->w, RIGHT_MARGIN_AREA)
25337 : window_box_right_offset (it->w, TEXT_AREA));
25338 /* 'left-margin': left edge of the left display margin. */
25339 if (EQ (prop, Qleft_margin))
25340 return OK_ALIGN_TO (window_box_left_offset (it->w, LEFT_MARGIN_AREA));
25341 /* 'right-margin': left edge of the right display margin. */
25342 if (EQ (prop, Qright_margin))
25343 return OK_ALIGN_TO (window_box_left_offset (it->w, RIGHT_MARGIN_AREA));
25344 /* 'scroll-bar': left edge of the vertical scroll bar. */
25345 if (EQ (prop, Qscroll_bar))
25346 return OK_ALIGN_TO (WINDOW_HAS_VERTICAL_SCROLL_BAR_ON_LEFT (it->w)
25348 : (window_box_right_offset (it->w, RIGHT_MARGIN_AREA)
25349 + (WINDOW_HAS_FRINGES_OUTSIDE_MARGINS (it->w)
25350 ? WINDOW_RIGHT_FRINGE_WIDTH (it->w)
25351 : 0)));
25353 else
25355 /* Otherwise, the elements stand for their width. */
25356 if (EQ (prop, Qleft_fringe))
25357 return OK_PIXELS (WINDOW_LEFT_FRINGE_WIDTH (it->w));
25358 if (EQ (prop, Qright_fringe))
25359 return OK_PIXELS (WINDOW_RIGHT_FRINGE_WIDTH (it->w));
25360 if (EQ (prop, Qleft_margin))
25361 return OK_PIXELS (WINDOW_LEFT_MARGIN_WIDTH (it->w));
25362 if (EQ (prop, Qright_margin))
25363 return OK_PIXELS (WINDOW_RIGHT_MARGIN_WIDTH (it->w));
25364 if (EQ (prop, Qscroll_bar))
25365 return OK_PIXELS (WINDOW_SCROLL_BAR_AREA_WIDTH (it->w));
25368 prop = buffer_local_value (prop, it->w->contents);
25369 if (EQ (prop, Qunbound))
25370 prop = Qnil;
25373 if (NUMBERP (prop))
25375 int base_unit = (width_p
25376 ? FRAME_COLUMN_WIDTH (it->f)
25377 : FRAME_LINE_HEIGHT (it->f));
25378 if (width_p && align_to && *align_to < 0)
25379 return OK_PIXELS (XFLOATINT (prop) * base_unit + it->lnum_pixel_width);
25380 return OK_PIXELS (XFLOATINT (prop) * base_unit);
25383 if (CONSP (prop))
25385 Lisp_Object car = XCAR (prop);
25386 Lisp_Object cdr = XCDR (prop);
25388 if (SYMBOLP (car))
25390 #ifdef HAVE_WINDOW_SYSTEM
25391 /* '(image PROPS...)': width or height of the specified image. */
25392 if (FRAME_WINDOW_P (it->f)
25393 && valid_image_p (prop))
25395 ptrdiff_t id = lookup_image (it->f, prop);
25396 struct image *img = IMAGE_FROM_ID (it->f, id);
25398 return OK_PIXELS (width_p ? img->width : img->height);
25400 /* '(xwidget PROPS...)': dimensions of the specified xwidget. */
25401 if (FRAME_WINDOW_P (it->f) && valid_xwidget_spec_p (prop))
25403 /* TODO: Don't return dummy size. */
25404 return OK_PIXELS (100);
25406 #endif
25407 /* '(+ EXPR...)' or '(- EXPR...)' add or subtract
25408 recursively calculated values. */
25409 if (EQ (car, Qplus) || EQ (car, Qminus))
25411 bool first = true;
25412 double px;
25414 pixels = 0;
25415 while (CONSP (cdr))
25417 if (!calc_pixel_width_or_height (&px, it, XCAR (cdr),
25418 font, width_p, align_to))
25419 return false;
25420 if (first)
25421 pixels = (EQ (car, Qplus) ? px : -px), first = false;
25422 else
25423 pixels += px;
25424 cdr = XCDR (cdr);
25426 if (EQ (car, Qminus))
25427 pixels = -pixels;
25428 return OK_PIXELS (pixels);
25431 car = buffer_local_value (car, it->w->contents);
25432 if (EQ (car, Qunbound))
25433 car = Qnil;
25436 /* '(NUM)': absolute number of pixels. */
25437 if (NUMBERP (car))
25439 double fact;
25440 int offset =
25441 width_p && align_to && *align_to < 0 ? it->lnum_pixel_width : 0;
25442 pixels = XFLOATINT (car);
25443 if (NILP (cdr))
25444 return OK_PIXELS (pixels + offset);
25445 if (calc_pixel_width_or_height (&fact, it, cdr,
25446 font, width_p, align_to))
25447 return OK_PIXELS (pixels * fact + offset);
25448 return false;
25451 return false;
25454 return false;
25457 void
25458 get_font_ascent_descent (struct font *font, int *ascent, int *descent)
25460 #ifdef HAVE_WINDOW_SYSTEM
25461 normal_char_ascent_descent (font, -1, ascent, descent);
25462 #else
25463 *ascent = 1;
25464 *descent = 0;
25465 #endif
25469 /***********************************************************************
25470 Glyph Display
25471 ***********************************************************************/
25473 #ifdef HAVE_WINDOW_SYSTEM
25475 #ifdef GLYPH_DEBUG
25477 void
25478 dump_glyph_string (struct glyph_string *s)
25480 fprintf (stderr, "glyph string\n");
25481 fprintf (stderr, " x, y, w, h = %d, %d, %d, %d\n",
25482 s->x, s->y, s->width, s->height);
25483 fprintf (stderr, " ybase = %d\n", s->ybase);
25484 fprintf (stderr, " hl = %u\n", s->hl);
25485 fprintf (stderr, " left overhang = %d, right = %d\n",
25486 s->left_overhang, s->right_overhang);
25487 fprintf (stderr, " nchars = %d\n", s->nchars);
25488 fprintf (stderr, " extends to end of line = %d\n",
25489 s->extends_to_end_of_line_p);
25490 fprintf (stderr, " font height = %d\n", FONT_HEIGHT (s->font));
25491 fprintf (stderr, " bg width = %d\n", s->background_width);
25494 #endif /* GLYPH_DEBUG */
25496 /* Initialize glyph string S. CHAR2B is a suitably allocated vector
25497 of XChar2b structures for S; it can't be allocated in
25498 init_glyph_string because it must be allocated via `alloca'. W
25499 is the window on which S is drawn. ROW and AREA are the glyph row
25500 and area within the row from which S is constructed. START is the
25501 index of the first glyph structure covered by S. HL is a
25502 face-override for drawing S. */
25504 #ifdef HAVE_NTGUI
25505 #define OPTIONAL_HDC(hdc) HDC hdc,
25506 #define DECLARE_HDC(hdc) HDC hdc;
25507 #define ALLOCATE_HDC(hdc, f) hdc = get_frame_dc ((f))
25508 #define RELEASE_HDC(hdc, f) release_frame_dc ((f), (hdc))
25509 #endif
25511 #ifndef OPTIONAL_HDC
25512 #define OPTIONAL_HDC(hdc)
25513 #define DECLARE_HDC(hdc)
25514 #define ALLOCATE_HDC(hdc, f)
25515 #define RELEASE_HDC(hdc, f)
25516 #endif
25518 static void
25519 init_glyph_string (struct glyph_string *s,
25520 OPTIONAL_HDC (hdc)
25521 XChar2b *char2b, struct window *w, struct glyph_row *row,
25522 enum glyph_row_area area, int start, enum draw_glyphs_face hl)
25524 memset (s, 0, sizeof *s);
25525 s->w = w;
25526 s->f = XFRAME (w->frame);
25527 #ifdef HAVE_NTGUI
25528 s->hdc = hdc;
25529 #endif
25530 s->display = FRAME_X_DISPLAY (s->f);
25531 s->char2b = char2b;
25532 s->hl = hl;
25533 s->row = row;
25534 s->area = area;
25535 s->first_glyph = row->glyphs[area] + start;
25536 s->height = row->height;
25537 s->y = WINDOW_TO_FRAME_PIXEL_Y (w, row->y);
25538 s->ybase = s->y + row->ascent;
25542 /* Append the list of glyph strings with head H and tail T to the list
25543 with head *HEAD and tail *TAIL. Set *HEAD and *TAIL to the result. */
25545 static void
25546 append_glyph_string_lists (struct glyph_string **head, struct glyph_string **tail,
25547 struct glyph_string *h, struct glyph_string *t)
25549 if (h)
25551 if (*head)
25552 (*tail)->next = h;
25553 else
25554 *head = h;
25555 h->prev = *tail;
25556 *tail = t;
25561 /* Prepend the list of glyph strings with head H and tail T to the
25562 list with head *HEAD and tail *TAIL. Set *HEAD and *TAIL to the
25563 result. */
25565 static void
25566 prepend_glyph_string_lists (struct glyph_string **head, struct glyph_string **tail,
25567 struct glyph_string *h, struct glyph_string *t)
25569 if (h)
25571 if (*head)
25572 (*head)->prev = t;
25573 else
25574 *tail = t;
25575 t->next = *head;
25576 *head = h;
25581 /* Append glyph string S to the list with head *HEAD and tail *TAIL.
25582 Set *HEAD and *TAIL to the resulting list. */
25584 static void
25585 append_glyph_string (struct glyph_string **head, struct glyph_string **tail,
25586 struct glyph_string *s)
25588 s->next = s->prev = NULL;
25589 append_glyph_string_lists (head, tail, s, s);
25593 /* Get face and two-byte form of character C in face FACE_ID on frame F.
25594 The encoding of C is returned in *CHAR2B. DISPLAY_P means
25595 make sure that X resources for the face returned are allocated.
25596 Value is a pointer to a realized face that is ready for display if
25597 DISPLAY_P. */
25599 static struct face *
25600 get_char_face_and_encoding (struct frame *f, int c, int face_id,
25601 XChar2b *char2b, bool display_p)
25603 struct face *face = FACE_FROM_ID (f, face_id);
25604 unsigned code = 0;
25606 if (face->font)
25608 code = face->font->driver->encode_char (face->font, c);
25610 if (code == FONT_INVALID_CODE)
25611 code = 0;
25613 STORE_XCHAR2B (char2b, (code >> 8), (code & 0xFF));
25615 /* Make sure X resources of the face are allocated. */
25616 #ifdef HAVE_X_WINDOWS
25617 if (display_p)
25618 #endif
25620 eassert (face != NULL);
25621 prepare_face_for_display (f, face);
25624 return face;
25628 /* Get face and two-byte form of character glyph GLYPH on frame F.
25629 The encoding of GLYPH->u.ch is returned in *CHAR2B. Value is
25630 a pointer to a realized face that is ready for display. */
25632 static struct face *
25633 get_glyph_face_and_encoding (struct frame *f, struct glyph *glyph,
25634 XChar2b *char2b)
25636 struct face *face;
25637 unsigned code = 0;
25639 eassert (glyph->type == CHAR_GLYPH);
25640 face = FACE_FROM_ID (f, glyph->face_id);
25642 /* Make sure X resources of the face are allocated. */
25643 prepare_face_for_display (f, face);
25645 if (face->font)
25647 if (CHAR_BYTE8_P (glyph->u.ch))
25648 code = CHAR_TO_BYTE8 (glyph->u.ch);
25649 else
25650 code = face->font->driver->encode_char (face->font, glyph->u.ch);
25652 if (code == FONT_INVALID_CODE)
25653 code = 0;
25656 STORE_XCHAR2B (char2b, (code >> 8), (code & 0xFF));
25657 return face;
25661 /* Get glyph code of character C in FONT in the two-byte form CHAR2B.
25662 Return true iff FONT has a glyph for C. */
25664 static bool
25665 get_char_glyph_code (int c, struct font *font, XChar2b *char2b)
25667 unsigned code;
25669 if (CHAR_BYTE8_P (c))
25670 code = CHAR_TO_BYTE8 (c);
25671 else
25672 code = font->driver->encode_char (font, c);
25674 if (code == FONT_INVALID_CODE)
25675 return false;
25676 STORE_XCHAR2B (char2b, (code >> 8), (code & 0xFF));
25677 return true;
25681 /* Fill glyph string S with composition components specified by S->cmp.
25683 BASE_FACE is the base face of the composition.
25684 S->cmp_from is the index of the first component for S.
25686 OVERLAPS non-zero means S should draw the foreground only, and use
25687 its physical height for clipping. See also draw_glyphs.
25689 Value is the index of a component not in S. */
25691 static int
25692 fill_composite_glyph_string (struct glyph_string *s, struct face *base_face,
25693 int overlaps)
25695 int i;
25696 /* For all glyphs of this composition, starting at the offset
25697 S->cmp_from, until we reach the end of the definition or encounter a
25698 glyph that requires the different face, add it to S. */
25699 struct face *face;
25701 eassert (s);
25703 s->for_overlaps = overlaps;
25704 s->face = NULL;
25705 s->font = NULL;
25706 for (i = s->cmp_from; i < s->cmp->glyph_len; i++)
25708 int c = COMPOSITION_GLYPH (s->cmp, i);
25710 /* TAB in a composition means display glyphs with padding space
25711 on the left or right. */
25712 if (c != '\t')
25714 int face_id = FACE_FOR_CHAR (s->f, base_face->ascii_face, c,
25715 -1, Qnil);
25717 face = get_char_face_and_encoding (s->f, c, face_id,
25718 s->char2b + i, true);
25719 if (face)
25721 if (! s->face)
25723 s->face = face;
25724 s->font = s->face->font;
25726 else if (s->face != face)
25727 break;
25730 ++s->nchars;
25732 s->cmp_to = i;
25734 if (s->face == NULL)
25736 s->face = base_face->ascii_face;
25737 s->font = s->face->font;
25740 /* All glyph strings for the same composition has the same width,
25741 i.e. the width set for the first component of the composition. */
25742 s->width = s->first_glyph->pixel_width;
25744 /* If the specified font could not be loaded, use the frame's
25745 default font, but record the fact that we couldn't load it in
25746 the glyph string so that we can draw rectangles for the
25747 characters of the glyph string. */
25748 if (s->font == NULL)
25750 s->font_not_found_p = true;
25751 s->font = FRAME_FONT (s->f);
25754 /* Adjust base line for subscript/superscript text. */
25755 s->ybase += s->first_glyph->voffset;
25757 return s->cmp_to;
25760 static int
25761 fill_gstring_glyph_string (struct glyph_string *s, int face_id,
25762 int start, int end, int overlaps)
25764 struct glyph *glyph, *last;
25765 Lisp_Object lgstring;
25766 int i;
25768 s->for_overlaps = overlaps;
25769 glyph = s->row->glyphs[s->area] + start;
25770 last = s->row->glyphs[s->area] + end;
25771 s->cmp_id = glyph->u.cmp.id;
25772 s->cmp_from = glyph->slice.cmp.from;
25773 s->cmp_to = glyph->slice.cmp.to + 1;
25774 s->face = FACE_FROM_ID (s->f, face_id);
25775 lgstring = composition_gstring_from_id (s->cmp_id);
25776 s->font = XFONT_OBJECT (LGSTRING_FONT (lgstring));
25777 glyph++;
25778 while (glyph < last
25779 && glyph->u.cmp.automatic
25780 && glyph->u.cmp.id == s->cmp_id
25781 && s->cmp_to == glyph->slice.cmp.from)
25782 s->cmp_to = (glyph++)->slice.cmp.to + 1;
25784 for (i = s->cmp_from; i < s->cmp_to; i++)
25786 Lisp_Object lglyph = LGSTRING_GLYPH (lgstring, i);
25787 unsigned code = LGLYPH_CODE (lglyph);
25789 STORE_XCHAR2B ((s->char2b + i), code >> 8, code & 0xFF);
25791 s->width = composition_gstring_width (lgstring, s->cmp_from, s->cmp_to, NULL);
25792 return glyph - s->row->glyphs[s->area];
25796 /* Fill glyph string S from a sequence glyphs for glyphless characters.
25797 See the comment of fill_glyph_string for arguments.
25798 Value is the index of the first glyph not in S. */
25801 static int
25802 fill_glyphless_glyph_string (struct glyph_string *s, int face_id,
25803 int start, int end, int overlaps)
25805 struct glyph *glyph, *last;
25806 int voffset;
25808 eassert (s->first_glyph->type == GLYPHLESS_GLYPH);
25809 s->for_overlaps = overlaps;
25810 glyph = s->row->glyphs[s->area] + start;
25811 last = s->row->glyphs[s->area] + end;
25812 voffset = glyph->voffset;
25813 s->face = FACE_FROM_ID (s->f, face_id);
25814 s->font = s->face->font ? s->face->font : FRAME_FONT (s->f);
25815 s->nchars = 1;
25816 s->width = glyph->pixel_width;
25817 glyph++;
25818 while (glyph < last
25819 && glyph->type == GLYPHLESS_GLYPH
25820 && glyph->voffset == voffset
25821 && glyph->face_id == face_id)
25823 s->nchars++;
25824 s->width += glyph->pixel_width;
25825 glyph++;
25827 s->ybase += voffset;
25828 return glyph - s->row->glyphs[s->area];
25832 /* Fill glyph string S from a sequence of character glyphs.
25834 FACE_ID is the face id of the string. START is the index of the
25835 first glyph to consider, END is the index of the last + 1.
25836 OVERLAPS non-zero means S should draw the foreground only, and use
25837 its physical height for clipping. See also draw_glyphs.
25839 Value is the index of the first glyph not in S. */
25841 static int
25842 fill_glyph_string (struct glyph_string *s, int face_id,
25843 int start, int end, int overlaps)
25845 struct glyph *glyph, *last;
25846 int voffset;
25847 bool glyph_not_available_p;
25849 eassert (s->f == XFRAME (s->w->frame));
25850 eassert (s->nchars == 0);
25851 eassert (start >= 0 && end > start);
25853 s->for_overlaps = overlaps;
25854 glyph = s->row->glyphs[s->area] + start;
25855 last = s->row->glyphs[s->area] + end;
25856 voffset = glyph->voffset;
25857 s->padding_p = glyph->padding_p;
25858 glyph_not_available_p = glyph->glyph_not_available_p;
25860 while (glyph < last
25861 && glyph->type == CHAR_GLYPH
25862 && glyph->voffset == voffset
25863 /* Same face id implies same font, nowadays. */
25864 && glyph->face_id == face_id
25865 && glyph->glyph_not_available_p == glyph_not_available_p)
25867 s->face = get_glyph_face_and_encoding (s->f, glyph,
25868 s->char2b + s->nchars);
25869 ++s->nchars;
25870 eassert (s->nchars <= end - start);
25871 s->width += glyph->pixel_width;
25872 if (glyph++->padding_p != s->padding_p)
25873 break;
25876 s->font = s->face->font;
25878 /* If the specified font could not be loaded, use the frame's font,
25879 but record the fact that we couldn't load it in
25880 S->font_not_found_p so that we can draw rectangles for the
25881 characters of the glyph string. */
25882 if (s->font == NULL || glyph_not_available_p)
25884 s->font_not_found_p = true;
25885 s->font = FRAME_FONT (s->f);
25888 /* Adjust base line for subscript/superscript text. */
25889 s->ybase += voffset;
25891 eassert (s->face && s->face->gc);
25892 return glyph - s->row->glyphs[s->area];
25896 /* Fill glyph string S from image glyph S->first_glyph. */
25898 static void
25899 fill_image_glyph_string (struct glyph_string *s)
25901 eassert (s->first_glyph->type == IMAGE_GLYPH);
25902 s->img = IMAGE_FROM_ID (s->f, s->first_glyph->u.img_id);
25903 eassert (s->img);
25904 s->slice = s->first_glyph->slice.img;
25905 s->face = FACE_FROM_ID (s->f, s->first_glyph->face_id);
25906 s->font = s->face->font;
25907 s->width = s->first_glyph->pixel_width;
25909 /* Adjust base line for subscript/superscript text. */
25910 s->ybase += s->first_glyph->voffset;
25914 #ifdef HAVE_XWIDGETS
25915 static void
25916 fill_xwidget_glyph_string (struct glyph_string *s)
25918 eassert (s->first_glyph->type == XWIDGET_GLYPH);
25919 s->face = FACE_FROM_ID (s->f, s->first_glyph->face_id);
25920 s->font = s->face->font;
25921 s->width = s->first_glyph->pixel_width;
25922 s->ybase += s->first_glyph->voffset;
25923 s->xwidget = s->first_glyph->u.xwidget;
25925 #endif
25926 /* Fill glyph string S from a sequence of stretch glyphs.
25928 START is the index of the first glyph to consider,
25929 END is the index of the last + 1.
25931 Value is the index of the first glyph not in S. */
25933 static int
25934 fill_stretch_glyph_string (struct glyph_string *s, int start, int end)
25936 struct glyph *glyph, *last;
25937 int voffset, face_id;
25939 eassert (s->first_glyph->type == STRETCH_GLYPH);
25941 glyph = s->row->glyphs[s->area] + start;
25942 last = s->row->glyphs[s->area] + end;
25943 face_id = glyph->face_id;
25944 s->face = FACE_FROM_ID (s->f, face_id);
25945 s->font = s->face->font;
25946 s->width = glyph->pixel_width;
25947 s->nchars = 1;
25948 voffset = glyph->voffset;
25950 for (++glyph;
25951 (glyph < last
25952 && glyph->type == STRETCH_GLYPH
25953 && glyph->voffset == voffset
25954 && glyph->face_id == face_id);
25955 ++glyph)
25956 s->width += glyph->pixel_width;
25958 /* Adjust base line for subscript/superscript text. */
25959 s->ybase += voffset;
25961 /* The case that face->gc == 0 is handled when drawing the glyph
25962 string by calling prepare_face_for_display. */
25963 eassert (s->face);
25964 return glyph - s->row->glyphs[s->area];
25967 static struct font_metrics *
25968 get_per_char_metric (struct font *font, XChar2b *char2b)
25970 static struct font_metrics metrics;
25971 unsigned code;
25973 if (! font)
25974 return NULL;
25975 code = (XCHAR2B_BYTE1 (char2b) << 8) | XCHAR2B_BYTE2 (char2b);
25976 if (code == FONT_INVALID_CODE)
25977 return NULL;
25978 font->driver->text_extents (font, &code, 1, &metrics);
25979 return &metrics;
25982 /* A subroutine that computes "normal" values of ASCENT and DESCENT
25983 for FONT. Values are taken from font-global ones, except for fonts
25984 that claim preposterously large values, but whose glyphs actually
25985 have reasonable dimensions. C is the character to use for metrics
25986 if the font-global values are too large; if C is negative, the
25987 function selects a default character. */
25988 static void
25989 normal_char_ascent_descent (struct font *font, int c, int *ascent, int *descent)
25991 *ascent = FONT_BASE (font);
25992 *descent = FONT_DESCENT (font);
25994 if (FONT_TOO_HIGH (font))
25996 XChar2b char2b;
25998 /* Get metrics of C, defaulting to a reasonably sized ASCII
25999 character. */
26000 if (get_char_glyph_code (c >= 0 ? c : '{', font, &char2b))
26002 struct font_metrics *pcm = get_per_char_metric (font, &char2b);
26004 if (!(pcm->width == 0 && pcm->rbearing == 0 && pcm->lbearing == 0))
26006 /* We add 1 pixel to character dimensions as heuristics
26007 that produces nicer display, e.g. when the face has
26008 the box attribute. */
26009 *ascent = pcm->ascent + 1;
26010 *descent = pcm->descent + 1;
26016 /* A subroutine that computes a reasonable "normal character height"
26017 for fonts that claim preposterously large vertical dimensions, but
26018 whose glyphs are actually reasonably sized. C is the character
26019 whose metrics to use for those fonts, or -1 for default
26020 character. */
26021 static int
26022 normal_char_height (struct font *font, int c)
26024 int ascent, descent;
26026 normal_char_ascent_descent (font, c, &ascent, &descent);
26028 return ascent + descent;
26031 /* EXPORT for RIF:
26032 Set *LEFT and *RIGHT to the left and right overhang of GLYPH on
26033 frame F. Overhangs of glyphs other than type CHAR_GLYPH are
26034 assumed to be zero. */
26036 void
26037 x_get_glyph_overhangs (struct glyph *glyph, struct frame *f, int *left, int *right)
26039 *left = *right = 0;
26041 if (glyph->type == CHAR_GLYPH)
26043 XChar2b char2b;
26044 struct face *face = get_glyph_face_and_encoding (f, glyph, &char2b);
26045 if (face->font)
26047 struct font_metrics *pcm = get_per_char_metric (face->font, &char2b);
26048 if (pcm)
26050 if (pcm->rbearing > pcm->width)
26051 *right = pcm->rbearing - pcm->width;
26052 if (pcm->lbearing < 0)
26053 *left = -pcm->lbearing;
26057 else if (glyph->type == COMPOSITE_GLYPH)
26059 if (! glyph->u.cmp.automatic)
26061 struct composition *cmp = composition_table[glyph->u.cmp.id];
26063 if (cmp->rbearing > cmp->pixel_width)
26064 *right = cmp->rbearing - cmp->pixel_width;
26065 if (cmp->lbearing < 0)
26066 *left = - cmp->lbearing;
26068 else
26070 Lisp_Object gstring = composition_gstring_from_id (glyph->u.cmp.id);
26071 struct font_metrics metrics;
26073 composition_gstring_width (gstring, glyph->slice.cmp.from,
26074 glyph->slice.cmp.to + 1, &metrics);
26075 if (metrics.rbearing > metrics.width)
26076 *right = metrics.rbearing - metrics.width;
26077 if (metrics.lbearing < 0)
26078 *left = - metrics.lbearing;
26084 /* Return the index of the first glyph preceding glyph string S that
26085 is overwritten by S because of S's left overhang. Value is -1
26086 if no glyphs are overwritten. */
26088 static int
26089 left_overwritten (struct glyph_string *s)
26091 int k;
26093 if (s->left_overhang)
26095 int x = 0, i;
26096 struct glyph *glyphs = s->row->glyphs[s->area];
26097 int first = s->first_glyph - glyphs;
26099 for (i = first - 1; i >= 0 && x > -s->left_overhang; --i)
26100 x -= glyphs[i].pixel_width;
26102 k = i + 1;
26104 else
26105 k = -1;
26107 return k;
26111 /* Return the index of the first glyph preceding glyph string S that
26112 is overwriting S because of its right overhang. Value is -1 if no
26113 glyph in front of S overwrites S. */
26115 static int
26116 left_overwriting (struct glyph_string *s)
26118 int i, k, x;
26119 struct glyph *glyphs = s->row->glyphs[s->area];
26120 int first = s->first_glyph - glyphs;
26122 k = -1;
26123 x = 0;
26124 for (i = first - 1; i >= 0; --i)
26126 int left, right;
26127 x_get_glyph_overhangs (glyphs + i, s->f, &left, &right);
26128 if (x + right > 0)
26129 k = i;
26130 x -= glyphs[i].pixel_width;
26133 return k;
26137 /* Return the index of the last glyph following glyph string S that is
26138 overwritten by S because of S's right overhang. Value is -1 if
26139 no such glyph is found. */
26141 static int
26142 right_overwritten (struct glyph_string *s)
26144 int k = -1;
26146 if (s->right_overhang)
26148 int x = 0, i;
26149 struct glyph *glyphs = s->row->glyphs[s->area];
26150 int first = (s->first_glyph - glyphs
26151 + (s->first_glyph->type == COMPOSITE_GLYPH ? 1 : s->nchars));
26152 int end = s->row->used[s->area];
26154 for (i = first; i < end && s->right_overhang > x; ++i)
26155 x += glyphs[i].pixel_width;
26157 k = i;
26160 return k;
26164 /* Return the index of the last glyph following glyph string S that
26165 overwrites S because of its left overhang. Value is negative
26166 if no such glyph is found. */
26168 static int
26169 right_overwriting (struct glyph_string *s)
26171 int i, k, x;
26172 int end = s->row->used[s->area];
26173 struct glyph *glyphs = s->row->glyphs[s->area];
26174 int first = (s->first_glyph - glyphs
26175 + (s->first_glyph->type == COMPOSITE_GLYPH ? 1 : s->nchars));
26177 k = -1;
26178 x = 0;
26179 for (i = first; i < end; ++i)
26181 int left, right;
26182 x_get_glyph_overhangs (glyphs + i, s->f, &left, &right);
26183 if (x - left < 0)
26184 k = i;
26185 x += glyphs[i].pixel_width;
26188 return k;
26192 /* Set background width of glyph string S. START is the index of the
26193 first glyph following S. LAST_X is the right-most x-position + 1
26194 in the drawing area. */
26196 static void
26197 set_glyph_string_background_width (struct glyph_string *s, int start, int last_x)
26199 /* If the face of this glyph string has to be drawn to the end of
26200 the drawing area, set S->extends_to_end_of_line_p. */
26202 if (start == s->row->used[s->area]
26203 && ((s->row->fill_line_p
26204 && (s->hl == DRAW_NORMAL_TEXT
26205 || s->hl == DRAW_IMAGE_RAISED
26206 || s->hl == DRAW_IMAGE_SUNKEN))
26207 || s->hl == DRAW_MOUSE_FACE))
26208 s->extends_to_end_of_line_p = true;
26210 /* If S extends its face to the end of the line, set its
26211 background_width to the distance to the right edge of the drawing
26212 area. */
26213 if (s->extends_to_end_of_line_p)
26214 s->background_width = last_x - s->x + 1;
26215 else
26216 s->background_width = s->width;
26220 /* Return glyph string that shares background with glyph string S and
26221 whose `background_width' member has been set. */
26223 static struct glyph_string *
26224 glyph_string_containing_background_width (struct glyph_string *s)
26226 if (s->cmp)
26227 while (s->cmp_from)
26228 s = s->prev;
26230 return s;
26234 /* Compute overhangs and x-positions for glyph string S and its
26235 predecessors, or successors. X is the starting x-position for S.
26236 BACKWARD_P means process predecessors. */
26238 static void
26239 compute_overhangs_and_x (struct glyph_string *s, int x, bool backward_p)
26241 if (backward_p)
26243 while (s)
26245 if (FRAME_RIF (s->f)->compute_glyph_string_overhangs)
26246 FRAME_RIF (s->f)->compute_glyph_string_overhangs (s);
26247 if (!s->cmp || s->cmp_to == s->cmp->glyph_len)
26248 x -= s->width;
26249 s->x = x;
26250 s = s->prev;
26253 else
26255 while (s)
26257 if (FRAME_RIF (s->f)->compute_glyph_string_overhangs)
26258 FRAME_RIF (s->f)->compute_glyph_string_overhangs (s);
26259 s->x = x;
26260 if (!s->cmp || s->cmp_to == s->cmp->glyph_len)
26261 x += s->width;
26262 s = s->next;
26269 /* The following macros are only called from draw_glyphs below.
26270 They reference the following parameters of that function directly:
26271 `w', `row', `area', and `overlap_p'
26272 as well as the following local variables:
26273 `s', `f', and `hdc' (in W32) */
26275 #ifdef HAVE_NTGUI
26276 /* On W32, silently add local `hdc' variable to argument list of
26277 init_glyph_string. */
26278 #define INIT_GLYPH_STRING(s, char2b, w, row, area, start, hl) \
26279 init_glyph_string (s, hdc, char2b, w, row, area, start, hl)
26280 #else
26281 #define INIT_GLYPH_STRING(s, char2b, w, row, area, start, hl) \
26282 init_glyph_string (s, char2b, w, row, area, start, hl)
26283 #endif
26285 /* Add a glyph string for a stretch glyph to the list of strings
26286 between HEAD and TAIL. START is the index of the stretch glyph in
26287 row area AREA of glyph row ROW. END is the index of the last glyph
26288 in that glyph row area. X is the current output position assigned
26289 to the new glyph string constructed. HL overrides that face of the
26290 glyph; e.g. it is DRAW_CURSOR if a cursor has to be drawn. LAST_X
26291 is the right-most x-position of the drawing area. */
26293 /* SunOS 4 bundled cc, barfed on continuations in the arg lists here
26294 and below -- keep them on one line. */
26295 #define BUILD_STRETCH_GLYPH_STRING(START, END, HEAD, TAIL, HL, X, LAST_X) \
26296 do \
26298 s = alloca (sizeof *s); \
26299 INIT_GLYPH_STRING (s, NULL, w, row, area, START, HL); \
26300 START = fill_stretch_glyph_string (s, START, END); \
26301 append_glyph_string (&HEAD, &TAIL, s); \
26302 s->x = (X); \
26304 while (false)
26307 /* Add a glyph string for an image glyph to the list of strings
26308 between HEAD and TAIL. START is the index of the image glyph in
26309 row area AREA of glyph row ROW. END is the index of the last glyph
26310 in that glyph row area. X is the current output position assigned
26311 to the new glyph string constructed. HL overrides that face of the
26312 glyph; e.g. it is DRAW_CURSOR if a cursor has to be drawn. LAST_X
26313 is the right-most x-position of the drawing area. */
26315 #define BUILD_IMAGE_GLYPH_STRING(START, END, HEAD, TAIL, HL, X, LAST_X) \
26316 do \
26318 s = alloca (sizeof *s); \
26319 INIT_GLYPH_STRING (s, NULL, w, row, area, START, HL); \
26320 fill_image_glyph_string (s); \
26321 append_glyph_string (&HEAD, &TAIL, s); \
26322 ++START; \
26323 s->x = (X); \
26325 while (false)
26327 #ifndef HAVE_XWIDGETS
26328 # define BUILD_XWIDGET_GLYPH_STRING(START, END, HEAD, TAIL, HL, X, LAST_X) \
26329 eassume (false)
26330 #else
26331 # define BUILD_XWIDGET_GLYPH_STRING(START, END, HEAD, TAIL, HL, X, LAST_X) \
26332 do \
26334 s = alloca (sizeof *s); \
26335 INIT_GLYPH_STRING (s, NULL, w, row, area, START, HL); \
26336 fill_xwidget_glyph_string (s); \
26337 append_glyph_string (&(HEAD), &(TAIL), s); \
26338 ++(START); \
26339 s->x = (X); \
26341 while (false)
26342 #endif
26344 /* Add a glyph string for a sequence of character glyphs to the list
26345 of strings between HEAD and TAIL. START is the index of the first
26346 glyph in row area AREA of glyph row ROW that is part of the new
26347 glyph string. END is the index of the last glyph in that glyph row
26348 area. X is the current output position assigned to the new glyph
26349 string constructed. HL overrides that face of the glyph; e.g. it
26350 is DRAW_CURSOR if a cursor has to be drawn. LAST_X is the
26351 right-most x-position of the drawing area. */
26353 #define BUILD_CHAR_GLYPH_STRINGS(START, END, HEAD, TAIL, HL, X, LAST_X) \
26354 do \
26356 int face_id; \
26357 XChar2b *char2b; \
26359 face_id = (row)->glyphs[area][START].face_id; \
26361 s = alloca (sizeof *s); \
26362 SAFE_NALLOCA (char2b, 1, (END) - (START)); \
26363 INIT_GLYPH_STRING (s, char2b, w, row, area, START, HL); \
26364 append_glyph_string (&HEAD, &TAIL, s); \
26365 s->x = (X); \
26366 START = fill_glyph_string (s, face_id, START, END, overlaps); \
26368 while (false)
26371 /* Add a glyph string for a composite sequence to the list of strings
26372 between HEAD and TAIL. START is the index of the first glyph in
26373 row area AREA of glyph row ROW that is part of the new glyph
26374 string. END is the index of the last glyph in that glyph row area.
26375 X is the current output position assigned to the new glyph string
26376 constructed. HL overrides that face of the glyph; e.g. it is
26377 DRAW_CURSOR if a cursor has to be drawn. LAST_X is the right-most
26378 x-position of the drawing area. */
26380 #define BUILD_COMPOSITE_GLYPH_STRING(START, END, HEAD, TAIL, HL, X, LAST_X) \
26381 do { \
26382 int face_id = (row)->glyphs[area][START].face_id; \
26383 struct face *base_face = FACE_FROM_ID (f, face_id); \
26384 ptrdiff_t cmp_id = (row)->glyphs[area][START].u.cmp.id; \
26385 struct composition *cmp = composition_table[cmp_id]; \
26386 XChar2b *char2b; \
26387 struct glyph_string *first_s = NULL; \
26388 int n; \
26390 SAFE_NALLOCA (char2b, 1, cmp->glyph_len); \
26392 /* Make glyph_strings for each glyph sequence that is drawable by \
26393 the same face, and append them to HEAD/TAIL. */ \
26394 for (n = 0; n < cmp->glyph_len;) \
26396 s = alloca (sizeof *s); \
26397 INIT_GLYPH_STRING (s, char2b, w, row, area, START, HL); \
26398 append_glyph_string (&(HEAD), &(TAIL), s); \
26399 s->cmp = cmp; \
26400 s->cmp_from = n; \
26401 s->x = (X); \
26402 if (n == 0) \
26403 first_s = s; \
26404 n = fill_composite_glyph_string (s, base_face, overlaps); \
26407 ++START; \
26408 s = first_s; \
26409 } while (false)
26412 /* Add a glyph string for a glyph-string sequence to the list of strings
26413 between HEAD and TAIL. */
26415 #define BUILD_GSTRING_GLYPH_STRING(START, END, HEAD, TAIL, HL, X, LAST_X) \
26416 do { \
26417 int face_id; \
26418 XChar2b *char2b; \
26419 Lisp_Object gstring; \
26421 face_id = (row)->glyphs[area][START].face_id; \
26422 gstring = (composition_gstring_from_id \
26423 ((row)->glyphs[area][START].u.cmp.id)); \
26424 s = alloca (sizeof *s); \
26425 SAFE_NALLOCA (char2b, 1, LGSTRING_GLYPH_LEN (gstring)); \
26426 INIT_GLYPH_STRING (s, char2b, w, row, area, START, HL); \
26427 append_glyph_string (&(HEAD), &(TAIL), s); \
26428 s->x = (X); \
26429 START = fill_gstring_glyph_string (s, face_id, START, END, overlaps); \
26430 } while (false)
26433 /* Add a glyph string for a sequence of glyphless character's glyphs
26434 to the list of strings between HEAD and TAIL. The meanings of
26435 arguments are the same as those of BUILD_CHAR_GLYPH_STRINGS. */
26437 #define BUILD_GLYPHLESS_GLYPH_STRING(START, END, HEAD, TAIL, HL, X, LAST_X) \
26438 do \
26440 int face_id; \
26442 face_id = (row)->glyphs[area][START].face_id; \
26444 s = alloca (sizeof *s); \
26445 INIT_GLYPH_STRING (s, NULL, w, row, area, START, HL); \
26446 append_glyph_string (&HEAD, &TAIL, s); \
26447 s->x = (X); \
26448 START = fill_glyphless_glyph_string (s, face_id, START, END, \
26449 overlaps); \
26451 while (false)
26454 /* Build a list of glyph strings between HEAD and TAIL for the glyphs
26455 of AREA of glyph row ROW on window W between indices START and END.
26456 HL overrides the face for drawing glyph strings, e.g. it is
26457 DRAW_CURSOR to draw a cursor. X and LAST_X are start and end
26458 x-positions of the drawing area.
26460 This is an ugly monster macro construct because we must use alloca
26461 to allocate glyph strings (because draw_glyphs can be called
26462 asynchronously). */
26464 #define BUILD_GLYPH_STRINGS_1(START, END, HEAD, TAIL, HL, X, LAST_X) \
26465 do \
26467 HEAD = TAIL = NULL; \
26468 while (START < END) \
26470 struct glyph *first_glyph = (row)->glyphs[area] + START; \
26471 switch (first_glyph->type) \
26473 case CHAR_GLYPH: \
26474 BUILD_CHAR_GLYPH_STRINGS (START, END, HEAD, TAIL, \
26475 HL, X, LAST_X); \
26476 break; \
26478 case COMPOSITE_GLYPH: \
26479 if (first_glyph->u.cmp.automatic) \
26480 BUILD_GSTRING_GLYPH_STRING (START, END, HEAD, TAIL, \
26481 HL, X, LAST_X); \
26482 else \
26483 BUILD_COMPOSITE_GLYPH_STRING (START, END, HEAD, TAIL, \
26484 HL, X, LAST_X); \
26485 break; \
26487 case STRETCH_GLYPH: \
26488 BUILD_STRETCH_GLYPH_STRING (START, END, HEAD, TAIL, \
26489 HL, X, LAST_X); \
26490 break; \
26492 case IMAGE_GLYPH: \
26493 BUILD_IMAGE_GLYPH_STRING (START, END, HEAD, TAIL, \
26494 HL, X, LAST_X); \
26495 break;
26497 #define BUILD_GLYPH_STRINGS_XW(START, END, HEAD, TAIL, HL, X, LAST_X) \
26498 case XWIDGET_GLYPH: \
26499 BUILD_XWIDGET_GLYPH_STRING (START, END, HEAD, TAIL, \
26500 HL, X, LAST_X); \
26501 break;
26503 #define BUILD_GLYPH_STRINGS_2(START, END, HEAD, TAIL, HL, X, LAST_X) \
26504 case GLYPHLESS_GLYPH: \
26505 BUILD_GLYPHLESS_GLYPH_STRING (START, END, HEAD, TAIL, \
26506 HL, X, LAST_X); \
26507 break; \
26509 default: \
26510 emacs_abort (); \
26513 if (s) \
26515 set_glyph_string_background_width (s, START, LAST_X); \
26516 (X) += s->width; \
26519 } while (false)
26522 #define BUILD_GLYPH_STRINGS(START, END, HEAD, TAIL, HL, X, LAST_X) \
26523 BUILD_GLYPH_STRINGS_1(START, END, HEAD, TAIL, HL, X, LAST_X) \
26524 BUILD_GLYPH_STRINGS_XW(START, END, HEAD, TAIL, HL, X, LAST_X) \
26525 BUILD_GLYPH_STRINGS_2(START, END, HEAD, TAIL, HL, X, LAST_X)
26528 /* Draw glyphs between START and END in AREA of ROW on window W,
26529 starting at x-position X. X is relative to AREA in W. HL is a
26530 face-override with the following meaning:
26532 DRAW_NORMAL_TEXT draw normally
26533 DRAW_CURSOR draw in cursor face
26534 DRAW_MOUSE_FACE draw in mouse face.
26535 DRAW_INVERSE_VIDEO draw in mode line face
26536 DRAW_IMAGE_SUNKEN draw an image with a sunken relief around it
26537 DRAW_IMAGE_RAISED draw an image with a raised relief around it
26539 If OVERLAPS is non-zero, draw only the foreground of characters and
26540 clip to the physical height of ROW. Non-zero value also defines
26541 the overlapping part to be drawn:
26543 OVERLAPS_PRED overlap with preceding rows
26544 OVERLAPS_SUCC overlap with succeeding rows
26545 OVERLAPS_BOTH overlap with both preceding/succeeding rows
26546 OVERLAPS_ERASED_CURSOR overlap with erased cursor area
26548 Value is the x-position reached, relative to AREA of W. */
26550 static int
26551 draw_glyphs (struct window *w, int x, struct glyph_row *row,
26552 enum glyph_row_area area, ptrdiff_t start, ptrdiff_t end,
26553 enum draw_glyphs_face hl, int overlaps)
26555 struct glyph_string *head, *tail;
26556 struct glyph_string *s;
26557 struct glyph_string *clip_head = NULL, *clip_tail = NULL;
26558 int i, j, x_reached, last_x, area_left = 0;
26559 struct frame *f = XFRAME (WINDOW_FRAME (w));
26560 DECLARE_HDC (hdc);
26562 ALLOCATE_HDC (hdc, f);
26564 /* Let's rather be paranoid than getting a SEGV. */
26565 end = min (end, row->used[area]);
26566 start = clip_to_bounds (0, start, end);
26568 /* Translate X to frame coordinates. Set last_x to the right
26569 end of the drawing area. */
26570 if (row->full_width_p)
26572 /* X is relative to the left edge of W, without scroll bars
26573 or fringes. */
26574 area_left = WINDOW_LEFT_EDGE_X (w);
26575 last_x = (WINDOW_LEFT_EDGE_X (w) + WINDOW_PIXEL_WIDTH (w)
26576 - (row->mode_line_p ? WINDOW_RIGHT_DIVIDER_WIDTH (w) : 0));
26578 else
26580 area_left = window_box_left (w, area);
26581 last_x = area_left + window_box_width (w, area);
26583 x += area_left;
26585 /* Build a doubly-linked list of glyph_string structures between
26586 head and tail from what we have to draw. Note that the macro
26587 BUILD_GLYPH_STRINGS will modify its start parameter. That's
26588 the reason we use a separate variable `i'. */
26589 i = start;
26590 USE_SAFE_ALLOCA;
26591 BUILD_GLYPH_STRINGS (i, end, head, tail, hl, x, last_x);
26592 if (tail)
26594 s = glyph_string_containing_background_width (tail);
26595 x_reached = s->x + s->background_width;
26597 else
26598 x_reached = x;
26600 /* If there are any glyphs with lbearing < 0 or rbearing > width in
26601 the row, redraw some glyphs in front or following the glyph
26602 strings built above. */
26603 if (head && !overlaps && row->contains_overlapping_glyphs_p)
26605 struct glyph_string *h, *t;
26606 Mouse_HLInfo *hlinfo = MOUSE_HL_INFO (f);
26607 int mouse_beg_col UNINIT, mouse_end_col UNINIT;
26608 bool check_mouse_face = false;
26609 int dummy_x = 0;
26611 /* If mouse highlighting is on, we may need to draw adjacent
26612 glyphs using mouse-face highlighting. */
26613 if (area == TEXT_AREA && row->mouse_face_p
26614 && hlinfo->mouse_face_beg_row >= 0
26615 && hlinfo->mouse_face_end_row >= 0)
26617 ptrdiff_t row_vpos = MATRIX_ROW_VPOS (row, w->current_matrix);
26619 if (row_vpos >= hlinfo->mouse_face_beg_row
26620 && row_vpos <= hlinfo->mouse_face_end_row)
26622 check_mouse_face = true;
26623 mouse_beg_col = (row_vpos == hlinfo->mouse_face_beg_row)
26624 ? hlinfo->mouse_face_beg_col : 0;
26625 mouse_end_col = (row_vpos == hlinfo->mouse_face_end_row)
26626 ? hlinfo->mouse_face_end_col
26627 : row->used[TEXT_AREA];
26631 /* Compute overhangs for all glyph strings. */
26632 if (FRAME_RIF (f)->compute_glyph_string_overhangs)
26633 for (s = head; s; s = s->next)
26634 FRAME_RIF (f)->compute_glyph_string_overhangs (s);
26636 /* Prepend glyph strings for glyphs in front of the first glyph
26637 string that are overwritten because of the first glyph
26638 string's left overhang. The background of all strings
26639 prepended must be drawn because the first glyph string
26640 draws over it. */
26641 i = left_overwritten (head);
26642 if (i >= 0)
26644 enum draw_glyphs_face overlap_hl;
26646 /* If this row contains mouse highlighting, attempt to draw
26647 the overlapped glyphs with the correct highlight. This
26648 code fails if the overlap encompasses more than one glyph
26649 and mouse-highlight spans only some of these glyphs.
26650 However, making it work perfectly involves a lot more
26651 code, and I don't know if the pathological case occurs in
26652 practice, so we'll stick to this for now. --- cyd */
26653 if (check_mouse_face
26654 && mouse_beg_col < start && mouse_end_col > i)
26655 overlap_hl = DRAW_MOUSE_FACE;
26656 else
26657 overlap_hl = DRAW_NORMAL_TEXT;
26659 if (hl != overlap_hl)
26660 clip_head = head;
26661 j = i;
26662 BUILD_GLYPH_STRINGS (j, start, h, t,
26663 overlap_hl, dummy_x, last_x);
26664 start = i;
26665 compute_overhangs_and_x (t, head->x, true);
26666 prepend_glyph_string_lists (&head, &tail, h, t);
26667 if (clip_head == NULL)
26668 clip_head = head;
26671 /* Prepend glyph strings for glyphs in front of the first glyph
26672 string that overwrite that glyph string because of their
26673 right overhang. For these strings, only the foreground must
26674 be drawn, because it draws over the glyph string at `head'.
26675 The background must not be drawn because this would overwrite
26676 right overhangs of preceding glyphs for which no glyph
26677 strings exist. */
26678 i = left_overwriting (head);
26679 if (i >= 0)
26681 enum draw_glyphs_face overlap_hl;
26683 if (check_mouse_face
26684 && mouse_beg_col < start && mouse_end_col > i)
26685 overlap_hl = DRAW_MOUSE_FACE;
26686 else
26687 overlap_hl = DRAW_NORMAL_TEXT;
26689 if (hl == overlap_hl || clip_head == NULL)
26690 clip_head = head;
26691 BUILD_GLYPH_STRINGS (i, start, h, t,
26692 overlap_hl, dummy_x, last_x);
26693 for (s = h; s; s = s->next)
26694 s->background_filled_p = true;
26695 compute_overhangs_and_x (t, head->x, true);
26696 prepend_glyph_string_lists (&head, &tail, h, t);
26699 /* Append glyphs strings for glyphs following the last glyph
26700 string tail that are overwritten by tail. The background of
26701 these strings has to be drawn because tail's foreground draws
26702 over it. */
26703 i = right_overwritten (tail);
26704 if (i >= 0)
26706 enum draw_glyphs_face overlap_hl;
26708 if (check_mouse_face
26709 && mouse_beg_col < i && mouse_end_col > end)
26710 overlap_hl = DRAW_MOUSE_FACE;
26711 else
26712 overlap_hl = DRAW_NORMAL_TEXT;
26714 if (hl != overlap_hl)
26715 clip_tail = tail;
26716 BUILD_GLYPH_STRINGS (end, i, h, t,
26717 overlap_hl, x, last_x);
26718 /* Because BUILD_GLYPH_STRINGS updates the first argument,
26719 we don't have `end = i;' here. */
26720 compute_overhangs_and_x (h, tail->x + tail->width, false);
26721 append_glyph_string_lists (&head, &tail, h, t);
26722 if (clip_tail == NULL)
26723 clip_tail = tail;
26726 /* Append glyph strings for glyphs following the last glyph
26727 string tail that overwrite tail. The foreground of such
26728 glyphs has to be drawn because it writes into the background
26729 of tail. The background must not be drawn because it could
26730 paint over the foreground of following glyphs. */
26731 i = right_overwriting (tail);
26732 if (i >= 0)
26734 enum draw_glyphs_face overlap_hl;
26735 if (check_mouse_face
26736 && mouse_beg_col < i && mouse_end_col > end)
26737 overlap_hl = DRAW_MOUSE_FACE;
26738 else
26739 overlap_hl = DRAW_NORMAL_TEXT;
26741 if (hl == overlap_hl || clip_tail == NULL)
26742 clip_tail = tail;
26743 i++; /* We must include the Ith glyph. */
26744 BUILD_GLYPH_STRINGS (end, i, h, t,
26745 overlap_hl, x, last_x);
26746 for (s = h; s; s = s->next)
26747 s->background_filled_p = true;
26748 compute_overhangs_and_x (h, tail->x + tail->width, false);
26749 append_glyph_string_lists (&head, &tail, h, t);
26751 tail = glyph_string_containing_background_width (tail);
26752 if (clip_tail)
26753 clip_tail = glyph_string_containing_background_width (clip_tail);
26754 if (clip_head || clip_tail)
26755 for (s = head; s; s = s->next)
26757 s->clip_head = clip_head;
26758 s->clip_tail = clip_tail;
26762 /* Draw all strings. */
26763 for (s = head; s; s = s->next)
26764 FRAME_RIF (f)->draw_glyph_string (s);
26766 #ifndef HAVE_NS
26767 /* When focus a sole frame and move horizontally, this clears on_p
26768 causing a failure to erase prev cursor position. */
26769 if (area == TEXT_AREA
26770 && !row->full_width_p
26771 /* When drawing overlapping rows, only the glyph strings'
26772 foreground is drawn, which doesn't erase a cursor
26773 completely. */
26774 && !overlaps)
26776 int x0 = clip_head ? clip_head->x : (head ? head->x : x);
26777 int x1 = (clip_tail ? clip_tail->x + clip_tail->background_width
26778 : (tail ? tail->x + tail->background_width : x));
26779 x0 -= area_left;
26780 x1 -= area_left;
26782 notice_overwritten_cursor (w, TEXT_AREA, x0, x1,
26783 row->y, MATRIX_ROW_BOTTOM_Y (row));
26785 #endif
26787 /* Value is the x-position up to which drawn, relative to AREA of W.
26788 This doesn't include parts drawn because of overhangs. */
26789 if (row->full_width_p)
26790 x_reached = FRAME_TO_WINDOW_PIXEL_X (w, x_reached);
26791 else
26792 x_reached -= area_left;
26794 RELEASE_HDC (hdc, f);
26796 SAFE_FREE ();
26797 return x_reached;
26800 /* Find the first glyph in the run of underlined glyphs preceding the
26801 beginning of glyph string S, and return its font (which could be
26802 NULL). This is needed because that font determines the underline
26803 position and thickness for the entire run of the underlined glyphs.
26804 This function is called from the draw_glyph_string method of GUI
26805 frame's redisplay interface (RIF) when it needs to draw in an
26806 underlined face. */
26807 struct font *
26808 font_for_underline_metrics (struct glyph_string *s)
26810 struct glyph *g0 = s->row->glyphs[s->area], *g;
26812 for (g = s->first_glyph - 1; g >= g0; g--)
26814 struct face *prev_face = FACE_FROM_ID (s->f, g->face_id);
26815 if (!(prev_face && prev_face->underline_p))
26816 break;
26819 /* If preceding glyphs are not underlined, use the font of S. */
26820 if (g == s->first_glyph - 1)
26821 return s->font;
26822 else
26824 /* Otherwise use the font of the last glyph we saw in the above
26825 loop whose face had the underline_p flag set. */
26826 return FACE_FROM_ID (s->f, g[1].face_id)->font;
26830 /* Expand row matrix if too narrow. Don't expand if area
26831 is not present. */
26833 #define IT_EXPAND_MATRIX_WIDTH(it, area) \
26835 if (!it->f->fonts_changed \
26836 && (it->glyph_row->glyphs[area] \
26837 < it->glyph_row->glyphs[area + 1])) \
26839 it->w->ncols_scale_factor++; \
26840 it->f->fonts_changed = true; \
26844 /* Store one glyph for IT->char_to_display in IT->glyph_row.
26845 Called from x_produce_glyphs when IT->glyph_row is non-null. */
26847 static void
26848 append_glyph (struct it *it)
26850 struct glyph *glyph;
26851 enum glyph_row_area area = it->area;
26853 eassert (it->glyph_row);
26854 eassert (it->char_to_display != '\n' && it->char_to_display != '\t');
26856 glyph = it->glyph_row->glyphs[area] + it->glyph_row->used[area];
26857 if (glyph < it->glyph_row->glyphs[area + 1])
26859 /* If the glyph row is reversed, we need to prepend the glyph
26860 rather than append it. */
26861 if (it->glyph_row->reversed_p && area == TEXT_AREA)
26863 struct glyph *g;
26865 /* Make room for the additional glyph. */
26866 for (g = glyph - 1; g >= it->glyph_row->glyphs[area]; g--)
26867 g[1] = *g;
26868 glyph = it->glyph_row->glyphs[area];
26870 glyph->charpos = CHARPOS (it->position);
26871 glyph->object = it->object;
26872 if (it->pixel_width > 0)
26874 eassert (it->pixel_width <= SHRT_MAX);
26875 glyph->pixel_width = it->pixel_width;
26876 glyph->padding_p = false;
26878 else
26880 /* Assure at least 1-pixel width. Otherwise, cursor can't
26881 be displayed correctly. */
26882 glyph->pixel_width = 1;
26883 glyph->padding_p = true;
26885 glyph->ascent = it->ascent;
26886 glyph->descent = it->descent;
26887 glyph->voffset = it->voffset;
26888 glyph->type = CHAR_GLYPH;
26889 glyph->avoid_cursor_p = it->avoid_cursor_p;
26890 glyph->multibyte_p = it->multibyte_p;
26891 if (it->glyph_row->reversed_p && area == TEXT_AREA)
26893 /* In R2L rows, the left and the right box edges need to be
26894 drawn in reverse direction. */
26895 glyph->right_box_line_p = it->start_of_box_run_p;
26896 glyph->left_box_line_p = it->end_of_box_run_p;
26898 else
26900 glyph->left_box_line_p = it->start_of_box_run_p;
26901 glyph->right_box_line_p = it->end_of_box_run_p;
26903 glyph->overlaps_vertically_p = (it->phys_ascent > it->ascent
26904 || it->phys_descent > it->descent);
26905 glyph->glyph_not_available_p = it->glyph_not_available_p;
26906 glyph->face_id = it->face_id;
26907 glyph->u.ch = it->char_to_display;
26908 glyph->slice.img = null_glyph_slice;
26909 glyph->font_type = FONT_TYPE_UNKNOWN;
26910 if (it->bidi_p)
26912 glyph->resolved_level = it->bidi_it.resolved_level;
26913 eassert ((it->bidi_it.type & 7) == it->bidi_it.type);
26914 glyph->bidi_type = it->bidi_it.type;
26916 else
26918 glyph->resolved_level = 0;
26919 glyph->bidi_type = UNKNOWN_BT;
26921 ++it->glyph_row->used[area];
26923 else
26924 IT_EXPAND_MATRIX_WIDTH (it, area);
26927 /* Store one glyph for the composition IT->cmp_it.id in
26928 IT->glyph_row. Called from x_produce_glyphs when IT->glyph_row is
26929 non-null. */
26931 static void
26932 append_composite_glyph (struct it *it)
26934 struct glyph *glyph;
26935 enum glyph_row_area area = it->area;
26937 eassert (it->glyph_row);
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 && it->area == TEXT_AREA)
26946 struct glyph *g;
26948 /* Make room for the new glyph. */
26949 for (g = glyph - 1; g >= it->glyph_row->glyphs[it->area]; g--)
26950 g[1] = *g;
26951 glyph = it->glyph_row->glyphs[it->area];
26953 glyph->charpos = it->cmp_it.charpos;
26954 glyph->object = it->object;
26955 eassert (it->pixel_width <= SHRT_MAX);
26956 glyph->pixel_width = it->pixel_width;
26957 glyph->ascent = it->ascent;
26958 glyph->descent = it->descent;
26959 glyph->voffset = it->voffset;
26960 glyph->type = COMPOSITE_GLYPH;
26961 if (it->cmp_it.ch < 0)
26963 glyph->u.cmp.automatic = false;
26964 glyph->u.cmp.id = it->cmp_it.id;
26965 glyph->slice.cmp.from = glyph->slice.cmp.to = 0;
26967 else
26969 glyph->u.cmp.automatic = true;
26970 glyph->u.cmp.id = it->cmp_it.id;
26971 glyph->slice.cmp.from = it->cmp_it.from;
26972 glyph->slice.cmp.to = it->cmp_it.to - 1;
26974 glyph->avoid_cursor_p = it->avoid_cursor_p;
26975 glyph->multibyte_p = it->multibyte_p;
26976 if (it->glyph_row->reversed_p && area == TEXT_AREA)
26978 /* In R2L rows, the left and the right box edges need to be
26979 drawn in reverse direction. */
26980 glyph->right_box_line_p = it->start_of_box_run_p;
26981 glyph->left_box_line_p = it->end_of_box_run_p;
26983 else
26985 glyph->left_box_line_p = it->start_of_box_run_p;
26986 glyph->right_box_line_p = it->end_of_box_run_p;
26988 glyph->overlaps_vertically_p = (it->phys_ascent > it->ascent
26989 || it->phys_descent > it->descent);
26990 glyph->padding_p = false;
26991 glyph->glyph_not_available_p = false;
26992 glyph->face_id = it->face_id;
26993 glyph->font_type = FONT_TYPE_UNKNOWN;
26994 if (it->bidi_p)
26996 glyph->resolved_level = it->bidi_it.resolved_level;
26997 eassert ((it->bidi_it.type & 7) == it->bidi_it.type);
26998 glyph->bidi_type = it->bidi_it.type;
27000 ++it->glyph_row->used[area];
27002 else
27003 IT_EXPAND_MATRIX_WIDTH (it, area);
27007 /* Change IT->ascent and IT->height according to the setting of
27008 IT->voffset. */
27010 static void
27011 take_vertical_position_into_account (struct it *it)
27013 if (it->voffset)
27015 if (it->voffset < 0)
27016 /* Increase the ascent so that we can display the text higher
27017 in the line. */
27018 it->ascent -= it->voffset;
27019 else
27020 /* Increase the descent so that we can display the text lower
27021 in the line. */
27022 it->descent += it->voffset;
27027 /* Produce glyphs/get display metrics for the image IT is loaded with.
27028 See the description of struct display_iterator in dispextern.h for
27029 an overview of struct display_iterator. */
27031 static void
27032 produce_image_glyph (struct it *it)
27034 struct image *img;
27035 struct face *face;
27036 int glyph_ascent, crop;
27037 struct glyph_slice slice;
27039 eassert (it->what == IT_IMAGE);
27041 face = FACE_FROM_ID (it->f, it->face_id);
27042 /* Make sure X resources of the face is loaded. */
27043 prepare_face_for_display (it->f, face);
27045 if (it->image_id < 0)
27047 /* Fringe bitmap. */
27048 it->ascent = it->phys_ascent = 0;
27049 it->descent = it->phys_descent = 0;
27050 it->pixel_width = 0;
27051 it->nglyphs = 0;
27052 return;
27055 img = IMAGE_FROM_ID (it->f, it->image_id);
27056 /* Make sure X resources of the image is loaded. */
27057 prepare_image_for_display (it->f, img);
27059 slice.x = slice.y = 0;
27060 slice.width = img->width;
27061 slice.height = img->height;
27063 if (INTEGERP (it->slice.x))
27064 slice.x = XINT (it->slice.x);
27065 else if (FLOATP (it->slice.x))
27066 slice.x = XFLOAT_DATA (it->slice.x) * img->width;
27068 if (INTEGERP (it->slice.y))
27069 slice.y = XINT (it->slice.y);
27070 else if (FLOATP (it->slice.y))
27071 slice.y = XFLOAT_DATA (it->slice.y) * img->height;
27073 if (INTEGERP (it->slice.width))
27074 slice.width = XINT (it->slice.width);
27075 else if (FLOATP (it->slice.width))
27076 slice.width = XFLOAT_DATA (it->slice.width) * img->width;
27078 if (INTEGERP (it->slice.height))
27079 slice.height = XINT (it->slice.height);
27080 else if (FLOATP (it->slice.height))
27081 slice.height = XFLOAT_DATA (it->slice.height) * img->height;
27083 if (slice.x >= img->width)
27084 slice.x = img->width;
27085 if (slice.y >= img->height)
27086 slice.y = img->height;
27087 if (slice.x + slice.width >= img->width)
27088 slice.width = img->width - slice.x;
27089 if (slice.y + slice.height > img->height)
27090 slice.height = img->height - slice.y;
27092 if (slice.width == 0 || slice.height == 0)
27093 return;
27095 it->ascent = it->phys_ascent = glyph_ascent = image_ascent (img, face, &slice);
27097 it->descent = slice.height - glyph_ascent;
27098 if (slice.y == 0)
27099 it->descent += img->vmargin;
27100 if (slice.y + slice.height == img->height)
27101 it->descent += img->vmargin;
27102 it->phys_descent = it->descent;
27104 it->pixel_width = slice.width;
27105 if (slice.x == 0)
27106 it->pixel_width += img->hmargin;
27107 if (slice.x + slice.width == img->width)
27108 it->pixel_width += img->hmargin;
27110 /* It's quite possible for images to have an ascent greater than
27111 their height, so don't get confused in that case. */
27112 if (it->descent < 0)
27113 it->descent = 0;
27115 it->nglyphs = 1;
27117 if (face->box != FACE_NO_BOX)
27119 if (face->box_line_width > 0)
27121 if (slice.y == 0)
27122 it->ascent += face->box_line_width;
27123 if (slice.y + slice.height == img->height)
27124 it->descent += face->box_line_width;
27127 if (it->start_of_box_run_p && slice.x == 0)
27128 it->pixel_width += eabs (face->box_line_width);
27129 if (it->end_of_box_run_p && slice.x + slice.width == img->width)
27130 it->pixel_width += eabs (face->box_line_width);
27133 take_vertical_position_into_account (it);
27135 /* Automatically crop wide image glyphs at right edge so we can
27136 draw the cursor on same display row. */
27137 if ((crop = it->pixel_width - (it->last_visible_x - it->current_x), crop > 0)
27138 && (it->hpos == 0 || it->pixel_width > it->last_visible_x / 4))
27140 it->pixel_width -= crop;
27141 slice.width -= crop;
27144 if (it->glyph_row)
27146 struct glyph *glyph;
27147 enum glyph_row_area area = it->area;
27149 glyph = it->glyph_row->glyphs[area] + it->glyph_row->used[area];
27150 if (it->glyph_row->reversed_p)
27152 struct glyph *g;
27154 /* Make room for the new glyph. */
27155 for (g = glyph - 1; g >= it->glyph_row->glyphs[it->area]; g--)
27156 g[1] = *g;
27157 glyph = it->glyph_row->glyphs[it->area];
27159 if (glyph < it->glyph_row->glyphs[area + 1])
27161 glyph->charpos = CHARPOS (it->position);
27162 glyph->object = it->object;
27163 glyph->pixel_width = clip_to_bounds (-1, it->pixel_width, SHRT_MAX);
27164 glyph->ascent = glyph_ascent;
27165 glyph->descent = it->descent;
27166 glyph->voffset = it->voffset;
27167 glyph->type = IMAGE_GLYPH;
27168 glyph->avoid_cursor_p = it->avoid_cursor_p;
27169 glyph->multibyte_p = it->multibyte_p;
27170 if (it->glyph_row->reversed_p && area == TEXT_AREA)
27172 /* In R2L rows, the left and the right box edges need to be
27173 drawn in reverse direction. */
27174 glyph->right_box_line_p = it->start_of_box_run_p;
27175 glyph->left_box_line_p = it->end_of_box_run_p;
27177 else
27179 glyph->left_box_line_p = it->start_of_box_run_p;
27180 glyph->right_box_line_p = it->end_of_box_run_p;
27182 glyph->overlaps_vertically_p = false;
27183 glyph->padding_p = false;
27184 glyph->glyph_not_available_p = false;
27185 glyph->face_id = it->face_id;
27186 glyph->u.img_id = img->id;
27187 glyph->slice.img = slice;
27188 glyph->font_type = FONT_TYPE_UNKNOWN;
27189 if (it->bidi_p)
27191 glyph->resolved_level = it->bidi_it.resolved_level;
27192 eassert ((it->bidi_it.type & 7) == it->bidi_it.type);
27193 glyph->bidi_type = it->bidi_it.type;
27195 ++it->glyph_row->used[area];
27197 else
27198 IT_EXPAND_MATRIX_WIDTH (it, area);
27202 static void
27203 produce_xwidget_glyph (struct it *it)
27205 #ifdef HAVE_XWIDGETS
27206 struct xwidget *xw;
27207 int glyph_ascent, crop;
27208 eassert (it->what == IT_XWIDGET);
27210 struct face *face = FACE_FROM_ID (it->f, it->face_id);
27211 /* Make sure X resources of the face is loaded. */
27212 prepare_face_for_display (it->f, face);
27214 xw = it->xwidget;
27215 it->ascent = it->phys_ascent = glyph_ascent = xw->height/2;
27216 it->descent = xw->height/2;
27217 it->phys_descent = it->descent;
27218 it->pixel_width = xw->width;
27219 /* It's quite possible for images to have an ascent greater than
27220 their height, so don't get confused in that case. */
27221 if (it->descent < 0)
27222 it->descent = 0;
27224 it->nglyphs = 1;
27226 if (face->box != FACE_NO_BOX)
27228 if (face->box_line_width > 0)
27230 it->ascent += face->box_line_width;
27231 it->descent += face->box_line_width;
27234 if (it->start_of_box_run_p)
27235 it->pixel_width += eabs (face->box_line_width);
27236 it->pixel_width += eabs (face->box_line_width);
27239 take_vertical_position_into_account (it);
27241 /* Automatically crop wide image glyphs at right edge so we can
27242 draw the cursor on same display row. */
27243 crop = it->pixel_width - (it->last_visible_x - it->current_x);
27244 if (crop > 0 && (it->hpos == 0 || it->pixel_width > it->last_visible_x / 4))
27245 it->pixel_width -= crop;
27247 if (it->glyph_row)
27249 enum glyph_row_area area = it->area;
27250 struct glyph *glyph
27251 = it->glyph_row->glyphs[area] + it->glyph_row->used[area];
27253 if (it->glyph_row->reversed_p)
27255 struct glyph *g;
27257 /* Make room for the new glyph. */
27258 for (g = glyph - 1; g >= it->glyph_row->glyphs[it->area]; g--)
27259 g[1] = *g;
27260 glyph = it->glyph_row->glyphs[it->area];
27262 if (glyph < it->glyph_row->glyphs[area + 1])
27264 glyph->charpos = CHARPOS (it->position);
27265 glyph->object = it->object;
27266 glyph->pixel_width = clip_to_bounds (-1, it->pixel_width, SHRT_MAX);
27267 glyph->ascent = glyph_ascent;
27268 glyph->descent = it->descent;
27269 glyph->voffset = it->voffset;
27270 glyph->type = XWIDGET_GLYPH;
27271 glyph->avoid_cursor_p = it->avoid_cursor_p;
27272 glyph->multibyte_p = it->multibyte_p;
27273 if (it->glyph_row->reversed_p && area == TEXT_AREA)
27275 /* In R2L rows, the left and the right box edges need to be
27276 drawn in reverse direction. */
27277 glyph->right_box_line_p = it->start_of_box_run_p;
27278 glyph->left_box_line_p = it->end_of_box_run_p;
27280 else
27282 glyph->left_box_line_p = it->start_of_box_run_p;
27283 glyph->right_box_line_p = it->end_of_box_run_p;
27285 glyph->overlaps_vertically_p = 0;
27286 glyph->padding_p = 0;
27287 glyph->glyph_not_available_p = 0;
27288 glyph->face_id = it->face_id;
27289 glyph->u.xwidget = it->xwidget;
27290 glyph->font_type = FONT_TYPE_UNKNOWN;
27291 if (it->bidi_p)
27293 glyph->resolved_level = it->bidi_it.resolved_level;
27294 eassert ((it->bidi_it.type & 7) == it->bidi_it.type);
27295 glyph->bidi_type = it->bidi_it.type;
27297 ++it->glyph_row->used[area];
27299 else
27300 IT_EXPAND_MATRIX_WIDTH (it, area);
27302 #endif
27305 /* Append a stretch glyph to IT->glyph_row. OBJECT is the source
27306 of the glyph, WIDTH and HEIGHT are the width and height of the
27307 stretch. ASCENT is the ascent of the glyph (0 <= ASCENT <= HEIGHT). */
27309 static void
27310 append_stretch_glyph (struct it *it, Lisp_Object object,
27311 int width, int height, int ascent)
27313 struct glyph *glyph;
27314 enum glyph_row_area area = it->area;
27316 eassert (ascent >= 0 && ascent <= height);
27318 glyph = it->glyph_row->glyphs[area] + it->glyph_row->used[area];
27319 if (glyph < it->glyph_row->glyphs[area + 1])
27321 /* If the glyph row is reversed, we need to prepend the glyph
27322 rather than append it. */
27323 if (it->glyph_row->reversed_p && area == TEXT_AREA)
27325 struct glyph *g;
27327 /* Make room for the additional glyph. */
27328 for (g = glyph - 1; g >= it->glyph_row->glyphs[area]; g--)
27329 g[1] = *g;
27330 glyph = it->glyph_row->glyphs[area];
27332 /* Decrease the width of the first glyph of the row that
27333 begins before first_visible_x (e.g., due to hscroll).
27334 This is so the overall width of the row becomes smaller
27335 by the scroll amount, and the stretch glyph appended by
27336 extend_face_to_end_of_line will be wider, to shift the
27337 row glyphs to the right. (In L2R rows, the corresponding
27338 left-shift effect is accomplished by setting row->x to a
27339 negative value, which won't work with R2L rows.)
27341 This must leave us with a positive value of WIDTH, since
27342 otherwise the call to move_it_in_display_line_to at the
27343 beginning of display_line would have got past the entire
27344 first glyph, and then it->current_x would have been
27345 greater or equal to it->first_visible_x. */
27346 if (it->current_x < it->first_visible_x)
27347 width -= it->first_visible_x - it->current_x;
27348 eassert (width > 0);
27350 glyph->charpos = CHARPOS (it->position);
27351 glyph->object = object;
27352 /* FIXME: It would be better to use TYPE_MAX here, but
27353 __typeof__ is not portable enough... */
27354 glyph->pixel_width = clip_to_bounds (-1, width, SHRT_MAX);
27355 glyph->ascent = ascent;
27356 glyph->descent = height - ascent;
27357 glyph->voffset = it->voffset;
27358 glyph->type = STRETCH_GLYPH;
27359 glyph->avoid_cursor_p = it->avoid_cursor_p;
27360 glyph->multibyte_p = it->multibyte_p;
27361 if (it->glyph_row->reversed_p && area == TEXT_AREA)
27363 /* In R2L rows, the left and the right box edges need to be
27364 drawn in reverse direction. */
27365 glyph->right_box_line_p = it->start_of_box_run_p;
27366 glyph->left_box_line_p = it->end_of_box_run_p;
27368 else
27370 glyph->left_box_line_p = it->start_of_box_run_p;
27371 glyph->right_box_line_p = it->end_of_box_run_p;
27373 glyph->overlaps_vertically_p = false;
27374 glyph->padding_p = false;
27375 glyph->glyph_not_available_p = false;
27376 glyph->face_id = it->face_id;
27377 glyph->u.stretch.ascent = ascent;
27378 glyph->u.stretch.height = height;
27379 glyph->slice.img = null_glyph_slice;
27380 glyph->font_type = FONT_TYPE_UNKNOWN;
27381 if (it->bidi_p)
27383 glyph->resolved_level = it->bidi_it.resolved_level;
27384 eassert ((it->bidi_it.type & 7) == it->bidi_it.type);
27385 glyph->bidi_type = it->bidi_it.type;
27387 else
27389 glyph->resolved_level = 0;
27390 glyph->bidi_type = UNKNOWN_BT;
27392 ++it->glyph_row->used[area];
27394 else
27395 IT_EXPAND_MATRIX_WIDTH (it, area);
27398 #endif /* HAVE_WINDOW_SYSTEM */
27400 /* Produce a stretch glyph for iterator IT. IT->object is the value
27401 of the glyph property displayed. The value must be a list
27402 `(space KEYWORD VALUE ...)' with the following KEYWORD/VALUE pairs
27403 being recognized:
27405 1. `:width WIDTH' specifies that the space should be WIDTH *
27406 canonical char width wide. WIDTH may be an integer or floating
27407 point number.
27409 2. `:relative-width FACTOR' specifies that the width of the stretch
27410 should be computed from the width of the first character having the
27411 `glyph' property, and should be FACTOR times that width.
27413 3. `:align-to HPOS' specifies that the space should be wide enough
27414 to reach HPOS, a value in canonical character units.
27416 Exactly one of the above pairs must be present.
27418 4. `:height HEIGHT' specifies that the height of the stretch produced
27419 should be HEIGHT, measured in canonical character units.
27421 5. `:relative-height FACTOR' specifies that the height of the
27422 stretch should be FACTOR times the height of the characters having
27423 the glyph property.
27425 Either none or exactly one of 4 or 5 must be present.
27427 6. `:ascent ASCENT' specifies that ASCENT percent of the height
27428 of the stretch should be used for the ascent of the stretch.
27429 ASCENT must be in the range 0 <= ASCENT <= 100. */
27431 void
27432 produce_stretch_glyph (struct it *it)
27434 /* (space :width WIDTH :height HEIGHT ...) */
27435 Lisp_Object prop, plist;
27436 int width = 0, height = 0, align_to = -1;
27437 bool zero_width_ok_p = false;
27438 double tem;
27439 struct font *font = NULL;
27441 #ifdef HAVE_WINDOW_SYSTEM
27442 int ascent = 0;
27443 bool zero_height_ok_p = false;
27445 if (FRAME_WINDOW_P (it->f))
27447 struct face *face = FACE_FROM_ID (it->f, it->face_id);
27448 font = face->font ? face->font : FRAME_FONT (it->f);
27449 prepare_face_for_display (it->f, face);
27451 #endif
27453 /* List should start with `space'. */
27454 eassert (CONSP (it->object) && EQ (XCAR (it->object), Qspace));
27455 plist = XCDR (it->object);
27457 /* Compute the width of the stretch. */
27458 if ((prop = Fplist_get (plist, QCwidth), !NILP (prop))
27459 && calc_pixel_width_or_height (&tem, it, prop, font, true, 0))
27461 /* Absolute width `:width WIDTH' specified and valid. */
27462 zero_width_ok_p = true;
27463 width = (int)tem;
27465 else if (prop = Fplist_get (plist, QCrelative_width), NUMVAL (prop) > 0)
27467 /* Relative width `:relative-width FACTOR' specified and valid.
27468 Compute the width of the characters having the `glyph'
27469 property. */
27470 struct it it2;
27471 unsigned char *p = BYTE_POS_ADDR (IT_BYTEPOS (*it));
27473 it2 = *it;
27474 if (it->multibyte_p)
27475 it2.c = it2.char_to_display = STRING_CHAR_AND_LENGTH (p, it2.len);
27476 else
27478 it2.c = it2.char_to_display = *p, it2.len = 1;
27479 if (! ASCII_CHAR_P (it2.c))
27480 it2.char_to_display = BYTE8_TO_CHAR (it2.c);
27483 it2.glyph_row = NULL;
27484 it2.what = IT_CHARACTER;
27485 PRODUCE_GLYPHS (&it2);
27486 width = NUMVAL (prop) * it2.pixel_width;
27488 else if ((prop = Fplist_get (plist, QCalign_to), !NILP (prop))
27489 && calc_pixel_width_or_height (&tem, it, prop, font, true,
27490 &align_to))
27492 if (it->glyph_row == NULL || !it->glyph_row->mode_line_p)
27493 align_to = (align_to < 0
27495 : align_to - window_box_left_offset (it->w, TEXT_AREA));
27496 else if (align_to < 0)
27497 align_to = window_box_left_offset (it->w, TEXT_AREA);
27498 width = max (0, (int)tem + align_to - it->current_x);
27499 zero_width_ok_p = true;
27501 else
27502 /* Nothing specified -> width defaults to canonical char width. */
27503 width = FRAME_COLUMN_WIDTH (it->f);
27505 if (width <= 0 && (width < 0 || !zero_width_ok_p))
27506 width = 1;
27508 #ifdef HAVE_WINDOW_SYSTEM
27509 /* Compute height. */
27510 if (FRAME_WINDOW_P (it->f))
27512 int default_height = normal_char_height (font, ' ');
27514 if ((prop = Fplist_get (plist, QCheight), !NILP (prop))
27515 && calc_pixel_width_or_height (&tem, it, prop, font, false, 0))
27517 height = (int)tem;
27518 zero_height_ok_p = true;
27520 else if (prop = Fplist_get (plist, QCrelative_height),
27521 NUMVAL (prop) > 0)
27522 height = default_height * NUMVAL (prop);
27523 else
27524 height = default_height;
27526 if (height <= 0 && (height < 0 || !zero_height_ok_p))
27527 height = 1;
27529 /* Compute percentage of height used for ascent. If
27530 `:ascent ASCENT' is present and valid, use that. Otherwise,
27531 derive the ascent from the font in use. */
27532 if (prop = Fplist_get (plist, QCascent),
27533 NUMVAL (prop) > 0 && NUMVAL (prop) <= 100)
27534 ascent = height * NUMVAL (prop) / 100.0;
27535 else if (!NILP (prop)
27536 && calc_pixel_width_or_height (&tem, it, prop, font, false, 0))
27537 ascent = min (max (0, (int)tem), height);
27538 else
27539 ascent = (height * FONT_BASE (font)) / FONT_HEIGHT (font);
27541 else
27542 #endif /* HAVE_WINDOW_SYSTEM */
27543 height = 1;
27545 if (width > 0 && it->line_wrap != TRUNCATE
27546 && it->current_x + width > it->last_visible_x)
27548 width = it->last_visible_x - it->current_x;
27549 #ifdef HAVE_WINDOW_SYSTEM
27550 /* Subtract one more pixel from the stretch width, but only on
27551 GUI frames, since on a TTY each glyph is one "pixel" wide. */
27552 width -= FRAME_WINDOW_P (it->f);
27553 #endif
27556 if (width > 0 && height > 0 && it->glyph_row)
27558 Lisp_Object o_object = it->object;
27559 Lisp_Object object = it->stack[it->sp - 1].string;
27560 int n = width;
27562 if (!STRINGP (object))
27563 object = it->w->contents;
27564 #ifdef HAVE_WINDOW_SYSTEM
27565 if (FRAME_WINDOW_P (it->f))
27566 append_stretch_glyph (it, object, width, height, ascent);
27567 else
27568 #endif
27570 it->object = object;
27571 it->char_to_display = ' ';
27572 it->pixel_width = it->len = 1;
27573 while (n--)
27574 tty_append_glyph (it);
27575 it->object = o_object;
27579 it->pixel_width = width;
27580 #ifdef HAVE_WINDOW_SYSTEM
27581 if (FRAME_WINDOW_P (it->f))
27583 it->ascent = it->phys_ascent = ascent;
27584 it->descent = it->phys_descent = height - it->ascent;
27585 it->nglyphs = width > 0 && height > 0;
27586 take_vertical_position_into_account (it);
27588 else
27589 #endif
27590 it->nglyphs = width;
27593 /* Get information about special display element WHAT in an
27594 environment described by IT. WHAT is one of IT_TRUNCATION or
27595 IT_CONTINUATION. Maybe produce glyphs for WHAT if IT has a
27596 non-null glyph_row member. This function ensures that fields like
27597 face_id, c, len of IT are left untouched. */
27599 static void
27600 produce_special_glyphs (struct it *it, enum display_element_type what)
27602 struct it temp_it;
27603 Lisp_Object gc;
27604 GLYPH glyph;
27606 temp_it = *it;
27607 temp_it.object = Qnil;
27608 memset (&temp_it.current, 0, sizeof temp_it.current);
27610 if (what == IT_CONTINUATION)
27612 /* Continuation glyph. For R2L lines, we mirror it by hand. */
27613 if (it->bidi_it.paragraph_dir == R2L)
27614 SET_GLYPH_FROM_CHAR (glyph, '/');
27615 else
27616 SET_GLYPH_FROM_CHAR (glyph, '\\');
27617 if (it->dp
27618 && (gc = DISP_CONTINUE_GLYPH (it->dp), GLYPH_CODE_P (gc)))
27620 /* FIXME: Should we mirror GC for R2L lines? */
27621 SET_GLYPH_FROM_GLYPH_CODE (glyph, gc);
27622 spec_glyph_lookup_face (XWINDOW (it->window), &glyph);
27625 else if (what == IT_TRUNCATION)
27627 /* Truncation glyph. */
27628 SET_GLYPH_FROM_CHAR (glyph, '$');
27629 if (it->dp
27630 && (gc = DISP_TRUNC_GLYPH (it->dp), GLYPH_CODE_P (gc)))
27632 /* FIXME: Should we mirror GC for R2L lines? */
27633 SET_GLYPH_FROM_GLYPH_CODE (glyph, gc);
27634 spec_glyph_lookup_face (XWINDOW (it->window), &glyph);
27637 else
27638 emacs_abort ();
27640 #ifdef HAVE_WINDOW_SYSTEM
27641 /* On a GUI frame, when the right fringe (left fringe for R2L rows)
27642 is turned off, we precede the truncation/continuation glyphs by a
27643 stretch glyph whose width is computed such that these special
27644 glyphs are aligned at the window margin, even when very different
27645 fonts are used in different glyph rows. */
27646 if (FRAME_WINDOW_P (temp_it.f)
27647 /* init_iterator calls this with it->glyph_row == NULL, and it
27648 wants only the pixel width of the truncation/continuation
27649 glyphs. */
27650 && temp_it.glyph_row
27651 /* insert_left_trunc_glyphs calls us at the beginning of the
27652 row, and it has its own calculation of the stretch glyph
27653 width. */
27654 && temp_it.glyph_row->used[TEXT_AREA] > 0
27655 && (temp_it.glyph_row->reversed_p
27656 ? WINDOW_LEFT_FRINGE_WIDTH (temp_it.w)
27657 : WINDOW_RIGHT_FRINGE_WIDTH (temp_it.w)) == 0)
27659 int stretch_width = temp_it.last_visible_x - temp_it.current_x;
27661 if (stretch_width > 0)
27663 struct face *face = FACE_FROM_ID (temp_it.f, temp_it.face_id);
27664 struct font *font =
27665 face->font ? face->font : FRAME_FONT (temp_it.f);
27666 int stretch_ascent =
27667 (((temp_it.ascent + temp_it.descent)
27668 * FONT_BASE (font)) / FONT_HEIGHT (font));
27670 append_stretch_glyph (&temp_it, Qnil, stretch_width,
27671 temp_it.ascent + temp_it.descent,
27672 stretch_ascent);
27675 #endif
27677 temp_it.dp = NULL;
27678 temp_it.what = IT_CHARACTER;
27679 temp_it.c = temp_it.char_to_display = GLYPH_CHAR (glyph);
27680 temp_it.face_id = GLYPH_FACE (glyph);
27681 temp_it.len = CHAR_BYTES (temp_it.c);
27683 PRODUCE_GLYPHS (&temp_it);
27684 it->pixel_width = temp_it.pixel_width;
27685 it->nglyphs = temp_it.nglyphs;
27688 #ifdef HAVE_WINDOW_SYSTEM
27690 /* Calculate line-height and line-spacing properties.
27691 An integer value specifies explicit pixel value.
27692 A float value specifies relative value to current face height.
27693 A cons (float . face-name) specifies relative value to
27694 height of specified face font.
27696 Returns height in pixels, or nil. */
27698 static Lisp_Object
27699 calc_line_height_property (struct it *it, Lisp_Object val, struct font *font,
27700 int boff, bool override)
27702 Lisp_Object face_name = Qnil;
27703 int ascent, descent, height;
27705 if (NILP (val) || INTEGERP (val) || (override && EQ (val, Qt)))
27706 return val;
27708 if (CONSP (val))
27710 face_name = XCAR (val);
27711 val = XCDR (val);
27712 if (!NUMBERP (val))
27713 val = make_number (1);
27714 if (NILP (face_name))
27716 height = it->ascent + it->descent;
27717 goto scale;
27721 if (NILP (face_name))
27723 font = FRAME_FONT (it->f);
27724 boff = FRAME_BASELINE_OFFSET (it->f);
27726 else if (EQ (face_name, Qt))
27728 override = false;
27730 else
27732 int face_id;
27733 struct face *face;
27735 face_id = lookup_named_face (it->f, face_name, false);
27736 face = FACE_FROM_ID_OR_NULL (it->f, face_id);
27737 if (face == NULL || ((font = face->font) == NULL))
27738 return make_number (-1);
27739 boff = font->baseline_offset;
27740 if (font->vertical_centering)
27741 boff = VCENTER_BASELINE_OFFSET (font, it->f) - boff;
27744 normal_char_ascent_descent (font, -1, &ascent, &descent);
27746 if (override)
27748 it->override_ascent = ascent;
27749 it->override_descent = descent;
27750 it->override_boff = boff;
27753 height = ascent + descent;
27755 scale:
27756 if (FLOATP (val))
27757 height = (int)(XFLOAT_DATA (val) * height);
27758 else if (INTEGERP (val))
27759 height *= XINT (val);
27761 return make_number (height);
27765 /* Append a glyph for a glyphless character to IT->glyph_row. FACE_ID
27766 is a face ID to be used for the glyph. FOR_NO_FONT is true if
27767 and only if this is for a character for which no font was found.
27769 If the display method (it->glyphless_method) is
27770 GLYPHLESS_DISPLAY_ACRONYM or GLYPHLESS_DISPLAY_HEX_CODE, LEN is a
27771 length of the acronym or the hexadecimal string, UPPER_XOFF and
27772 UPPER_YOFF are pixel offsets for the upper part of the string,
27773 LOWER_XOFF and LOWER_YOFF are for the lower part.
27775 For the other display methods, LEN through LOWER_YOFF are zero. */
27777 static void
27778 append_glyphless_glyph (struct it *it, int face_id, bool for_no_font, int len,
27779 short upper_xoff, short upper_yoff,
27780 short lower_xoff, short lower_yoff)
27782 struct glyph *glyph;
27783 enum glyph_row_area area = it->area;
27785 glyph = it->glyph_row->glyphs[area] + it->glyph_row->used[area];
27786 if (glyph < it->glyph_row->glyphs[area + 1])
27788 /* If the glyph row is reversed, we need to prepend the glyph
27789 rather than append it. */
27790 if (it->glyph_row->reversed_p && area == TEXT_AREA)
27792 struct glyph *g;
27794 /* Make room for the additional glyph. */
27795 for (g = glyph - 1; g >= it->glyph_row->glyphs[area]; g--)
27796 g[1] = *g;
27797 glyph = it->glyph_row->glyphs[area];
27799 glyph->charpos = CHARPOS (it->position);
27800 glyph->object = it->object;
27801 eassert (it->pixel_width <= SHRT_MAX);
27802 glyph->pixel_width = it->pixel_width;
27803 glyph->ascent = it->ascent;
27804 glyph->descent = it->descent;
27805 glyph->voffset = it->voffset;
27806 glyph->type = GLYPHLESS_GLYPH;
27807 glyph->u.glyphless.method = it->glyphless_method;
27808 glyph->u.glyphless.for_no_font = for_no_font;
27809 glyph->u.glyphless.len = len;
27810 glyph->u.glyphless.ch = it->c;
27811 glyph->slice.glyphless.upper_xoff = upper_xoff;
27812 glyph->slice.glyphless.upper_yoff = upper_yoff;
27813 glyph->slice.glyphless.lower_xoff = lower_xoff;
27814 glyph->slice.glyphless.lower_yoff = lower_yoff;
27815 glyph->avoid_cursor_p = it->avoid_cursor_p;
27816 glyph->multibyte_p = it->multibyte_p;
27817 if (it->glyph_row->reversed_p && area == TEXT_AREA)
27819 /* In R2L rows, the left and the right box edges need to be
27820 drawn in reverse direction. */
27821 glyph->right_box_line_p = it->start_of_box_run_p;
27822 glyph->left_box_line_p = it->end_of_box_run_p;
27824 else
27826 glyph->left_box_line_p = it->start_of_box_run_p;
27827 glyph->right_box_line_p = it->end_of_box_run_p;
27829 glyph->overlaps_vertically_p = (it->phys_ascent > it->ascent
27830 || it->phys_descent > it->descent);
27831 glyph->padding_p = false;
27832 glyph->glyph_not_available_p = false;
27833 glyph->face_id = face_id;
27834 glyph->font_type = FONT_TYPE_UNKNOWN;
27835 if (it->bidi_p)
27837 glyph->resolved_level = it->bidi_it.resolved_level;
27838 eassert ((it->bidi_it.type & 7) == it->bidi_it.type);
27839 glyph->bidi_type = it->bidi_it.type;
27841 ++it->glyph_row->used[area];
27843 else
27844 IT_EXPAND_MATRIX_WIDTH (it, area);
27848 /* Produce a glyph for a glyphless character for iterator IT.
27849 IT->glyphless_method specifies which method to use for displaying
27850 the character. See the description of enum
27851 glyphless_display_method in dispextern.h for the detail.
27853 FOR_NO_FONT is true if and only if this is for a character for
27854 which no font was found. ACRONYM, if non-nil, is an acronym string
27855 for the character. */
27857 static void
27858 produce_glyphless_glyph (struct it *it, bool for_no_font, Lisp_Object acronym)
27860 int face_id;
27861 struct face *face;
27862 struct font *font;
27863 int base_width, base_height, width, height;
27864 short upper_xoff, upper_yoff, lower_xoff, lower_yoff;
27865 int len;
27867 /* Get the metrics of the base font. We always refer to the current
27868 ASCII face. */
27869 face = FACE_FROM_ID (it->f, it->face_id)->ascii_face;
27870 font = face->font ? face->font : FRAME_FONT (it->f);
27871 normal_char_ascent_descent (font, -1, &it->ascent, &it->descent);
27872 it->ascent += font->baseline_offset;
27873 it->descent -= font->baseline_offset;
27874 base_height = it->ascent + it->descent;
27875 base_width = font->average_width;
27877 face_id = merge_glyphless_glyph_face (it);
27879 if (it->glyphless_method == GLYPHLESS_DISPLAY_THIN_SPACE)
27881 it->pixel_width = THIN_SPACE_WIDTH;
27882 len = 0;
27883 upper_xoff = upper_yoff = lower_xoff = lower_yoff = 0;
27885 else if (it->glyphless_method == GLYPHLESS_DISPLAY_EMPTY_BOX)
27887 width = CHARACTER_WIDTH (it->c);
27888 if (width == 0)
27889 width = 1;
27890 else if (width > 4)
27891 width = 4;
27892 it->pixel_width = base_width * width;
27893 len = 0;
27894 upper_xoff = upper_yoff = lower_xoff = lower_yoff = 0;
27896 else
27898 char buf[7];
27899 const char *str;
27900 unsigned int code[6];
27901 int upper_len;
27902 int ascent, descent;
27903 struct font_metrics metrics_upper, metrics_lower;
27905 face = FACE_FROM_ID (it->f, face_id);
27906 font = face->font ? face->font : FRAME_FONT (it->f);
27907 prepare_face_for_display (it->f, face);
27909 if (it->glyphless_method == GLYPHLESS_DISPLAY_ACRONYM)
27911 if (! STRINGP (acronym) && CHAR_TABLE_P (Vglyphless_char_display))
27912 acronym = CHAR_TABLE_REF (Vglyphless_char_display, it->c);
27913 if (CONSP (acronym))
27914 acronym = XCAR (acronym);
27915 str = STRINGP (acronym) ? SSDATA (acronym) : "";
27917 else
27919 eassert (it->glyphless_method == GLYPHLESS_DISPLAY_HEX_CODE);
27920 sprintf (buf, "%0*X", it->c < 0x10000 ? 4 : 6, it->c + 0u);
27921 str = buf;
27923 for (len = 0; str[len] && ASCII_CHAR_P (str[len]) && len < 6; len++)
27924 code[len] = font->driver->encode_char (font, str[len]);
27925 upper_len = (len + 1) / 2;
27926 font->driver->text_extents (font, code, upper_len,
27927 &metrics_upper);
27928 font->driver->text_extents (font, code + upper_len, len - upper_len,
27929 &metrics_lower);
27933 /* +4 is for vertical bars of a box plus 1-pixel spaces at both side. */
27934 width = max (metrics_upper.width, metrics_lower.width) + 4;
27935 upper_xoff = upper_yoff = 2; /* the typical case */
27936 if (base_width >= width)
27938 /* Align the upper to the left, the lower to the right. */
27939 it->pixel_width = base_width;
27940 lower_xoff = base_width - 2 - metrics_lower.width;
27942 else
27944 /* Center the shorter one. */
27945 it->pixel_width = width;
27946 if (metrics_upper.width >= metrics_lower.width)
27947 lower_xoff = (width - metrics_lower.width) / 2;
27948 else
27950 /* FIXME: This code doesn't look right. It formerly was
27951 missing the "lower_xoff = 0;", which couldn't have
27952 been right since it left lower_xoff uninitialized. */
27953 lower_xoff = 0;
27954 upper_xoff = (width - metrics_upper.width) / 2;
27958 /* +5 is for horizontal bars of a box plus 1-pixel spaces at
27959 top, bottom, and between upper and lower strings. */
27960 height = (metrics_upper.ascent + metrics_upper.descent
27961 + metrics_lower.ascent + metrics_lower.descent) + 5;
27962 /* Center vertically.
27963 H:base_height, D:base_descent
27964 h:height, ld:lower_descent, la:lower_ascent, ud:upper_descent
27966 ascent = - (D - H/2 - h/2 + 1); "+ 1" for rounding up
27967 descent = D - H/2 + h/2;
27968 lower_yoff = descent - 2 - ld;
27969 upper_yoff = lower_yoff - la - 1 - ud; */
27970 ascent = - (it->descent - (base_height + height + 1) / 2);
27971 descent = it->descent - (base_height - height) / 2;
27972 lower_yoff = descent - 2 - metrics_lower.descent;
27973 upper_yoff = (lower_yoff - metrics_lower.ascent - 1
27974 - metrics_upper.descent);
27975 /* Don't make the height shorter than the base height. */
27976 if (height > base_height)
27978 it->ascent = ascent;
27979 it->descent = descent;
27983 it->phys_ascent = it->ascent;
27984 it->phys_descent = it->descent;
27985 if (it->glyph_row)
27986 append_glyphless_glyph (it, face_id, for_no_font, len,
27987 upper_xoff, upper_yoff,
27988 lower_xoff, lower_yoff);
27989 it->nglyphs = 1;
27990 take_vertical_position_into_account (it);
27994 /* RIF:
27995 Produce glyphs/get display metrics for the display element IT is
27996 loaded with. See the description of struct it in dispextern.h
27997 for an overview of struct it. */
27999 void
28000 x_produce_glyphs (struct it *it)
28002 int extra_line_spacing = it->extra_line_spacing;
28004 it->glyph_not_available_p = false;
28006 if (it->what == IT_CHARACTER)
28008 XChar2b char2b;
28009 struct face *face = FACE_FROM_ID (it->f, it->face_id);
28010 struct font *font = face->font;
28011 struct font_metrics *pcm = NULL;
28012 int boff; /* Baseline offset. */
28014 if (font == NULL)
28016 /* When no suitable font is found, display this character by
28017 the method specified in the first extra slot of
28018 Vglyphless_char_display. */
28019 Lisp_Object acronym = lookup_glyphless_char_display (-1, it);
28021 eassert (it->what == IT_GLYPHLESS);
28022 produce_glyphless_glyph (it, true,
28023 STRINGP (acronym) ? acronym : Qnil);
28024 goto done;
28027 boff = font->baseline_offset;
28028 if (font->vertical_centering)
28029 boff = VCENTER_BASELINE_OFFSET (font, it->f) - boff;
28031 if (it->char_to_display != '\n' && it->char_to_display != '\t')
28033 it->nglyphs = 1;
28035 if (it->override_ascent >= 0)
28037 it->ascent = it->override_ascent;
28038 it->descent = it->override_descent;
28039 boff = it->override_boff;
28041 else
28043 it->ascent = FONT_BASE (font) + boff;
28044 it->descent = FONT_DESCENT (font) - boff;
28047 if (get_char_glyph_code (it->char_to_display, font, &char2b))
28049 pcm = get_per_char_metric (font, &char2b);
28050 if (pcm->width == 0
28051 && pcm->rbearing == 0 && pcm->lbearing == 0)
28052 pcm = NULL;
28055 if (pcm)
28057 it->phys_ascent = pcm->ascent + boff;
28058 it->phys_descent = pcm->descent - boff;
28059 it->pixel_width = pcm->width;
28060 /* Don't use font-global values for ascent and descent
28061 if they result in an exceedingly large line height. */
28062 if (it->override_ascent < 0)
28064 if (FONT_TOO_HIGH (font))
28066 it->ascent = it->phys_ascent;
28067 it->descent = it->phys_descent;
28068 /* These limitations are enforced by an
28069 assertion near the end of this function. */
28070 if (it->ascent < 0)
28071 it->ascent = 0;
28072 if (it->descent < 0)
28073 it->descent = 0;
28077 else
28079 it->glyph_not_available_p = true;
28080 it->phys_ascent = it->ascent;
28081 it->phys_descent = it->descent;
28082 it->pixel_width = font->space_width;
28085 if (it->constrain_row_ascent_descent_p)
28087 if (it->descent > it->max_descent)
28089 it->ascent += it->descent - it->max_descent;
28090 it->descent = it->max_descent;
28092 if (it->ascent > it->max_ascent)
28094 it->descent = min (it->max_descent, it->descent + it->ascent - it->max_ascent);
28095 it->ascent = it->max_ascent;
28097 it->phys_ascent = min (it->phys_ascent, it->ascent);
28098 it->phys_descent = min (it->phys_descent, it->descent);
28099 extra_line_spacing = 0;
28102 /* If this is a space inside a region of text with
28103 `space-width' property, change its width. */
28104 bool stretched_p
28105 = it->char_to_display == ' ' && !NILP (it->space_width);
28106 if (stretched_p)
28107 it->pixel_width *= XFLOATINT (it->space_width);
28109 /* If face has a box, add the box thickness to the character
28110 height. If character has a box line to the left and/or
28111 right, add the box line width to the character's width. */
28112 if (face->box != FACE_NO_BOX)
28114 int thick = face->box_line_width;
28116 if (thick > 0)
28118 it->ascent += thick;
28119 it->descent += thick;
28121 else
28122 thick = -thick;
28124 if (it->start_of_box_run_p)
28125 it->pixel_width += thick;
28126 if (it->end_of_box_run_p)
28127 it->pixel_width += thick;
28130 /* If face has an overline, add the height of the overline
28131 (1 pixel) and a 1 pixel margin to the character height. */
28132 if (face->overline_p)
28133 it->ascent += overline_margin;
28135 if (it->constrain_row_ascent_descent_p)
28137 if (it->ascent > it->max_ascent)
28138 it->ascent = it->max_ascent;
28139 if (it->descent > it->max_descent)
28140 it->descent = it->max_descent;
28143 take_vertical_position_into_account (it);
28145 /* If we have to actually produce glyphs, do it. */
28146 if (it->glyph_row)
28148 if (stretched_p)
28150 /* Translate a space with a `space-width' property
28151 into a stretch glyph. */
28152 int ascent = (((it->ascent + it->descent) * FONT_BASE (font))
28153 / FONT_HEIGHT (font));
28154 append_stretch_glyph (it, it->object, it->pixel_width,
28155 it->ascent + it->descent, ascent);
28157 else
28158 append_glyph (it);
28160 /* If characters with lbearing or rbearing are displayed
28161 in this line, record that fact in a flag of the
28162 glyph row. This is used to optimize X output code. */
28163 if (pcm && (pcm->lbearing < 0 || pcm->rbearing > pcm->width))
28164 it->glyph_row->contains_overlapping_glyphs_p = true;
28166 if (! stretched_p && it->pixel_width == 0)
28167 /* We assure that all visible glyphs have at least 1-pixel
28168 width. */
28169 it->pixel_width = 1;
28171 else if (it->char_to_display == '\n')
28173 /* A newline has no width, but we need the height of the
28174 line. But if previous part of the line sets a height,
28175 don't increase that height. */
28177 Lisp_Object height;
28178 Lisp_Object total_height = Qnil;
28180 it->override_ascent = -1;
28181 it->pixel_width = 0;
28182 it->nglyphs = 0;
28184 height = get_it_property (it, Qline_height);
28185 /* Split (line-height total-height) list. */
28186 if (CONSP (height)
28187 && CONSP (XCDR (height))
28188 && NILP (XCDR (XCDR (height))))
28190 total_height = XCAR (XCDR (height));
28191 height = XCAR (height);
28193 height = calc_line_height_property (it, height, font, boff, true);
28195 if (it->override_ascent >= 0)
28197 it->ascent = it->override_ascent;
28198 it->descent = it->override_descent;
28199 boff = it->override_boff;
28201 else
28203 if (FONT_TOO_HIGH (font))
28205 it->ascent = font->pixel_size + boff - 1;
28206 it->descent = -boff + 1;
28207 if (it->descent < 0)
28208 it->descent = 0;
28210 else
28212 it->ascent = FONT_BASE (font) + boff;
28213 it->descent = FONT_DESCENT (font) - boff;
28217 if (EQ (height, Qt))
28219 if (it->descent > it->max_descent)
28221 it->ascent += it->descent - it->max_descent;
28222 it->descent = it->max_descent;
28224 if (it->ascent > it->max_ascent)
28226 it->descent = min (it->max_descent, it->descent + it->ascent - it->max_ascent);
28227 it->ascent = it->max_ascent;
28229 it->phys_ascent = min (it->phys_ascent, it->ascent);
28230 it->phys_descent = min (it->phys_descent, it->descent);
28231 it->constrain_row_ascent_descent_p = true;
28232 extra_line_spacing = 0;
28234 else
28236 Lisp_Object spacing;
28238 it->phys_ascent = it->ascent;
28239 it->phys_descent = it->descent;
28241 if ((it->max_ascent > 0 || it->max_descent > 0)
28242 && face->box != FACE_NO_BOX
28243 && face->box_line_width > 0)
28245 it->ascent += face->box_line_width;
28246 it->descent += face->box_line_width;
28248 if (!NILP (height)
28249 && XINT (height) > it->ascent + it->descent)
28250 it->ascent = XINT (height) - it->descent;
28252 if (!NILP (total_height))
28253 spacing = calc_line_height_property (it, total_height, font,
28254 boff, false);
28255 else
28257 spacing = get_it_property (it, Qline_spacing);
28258 spacing = calc_line_height_property (it, spacing, font,
28259 boff, false);
28261 if (INTEGERP (spacing))
28263 extra_line_spacing = XINT (spacing);
28264 if (!NILP (total_height))
28265 extra_line_spacing -= (it->phys_ascent + it->phys_descent);
28269 else /* i.e. (it->char_to_display == '\t') */
28271 if (font->space_width > 0)
28273 int tab_width = it->tab_width * font->space_width;
28274 int x = it->current_x + it->continuation_lines_width;
28275 int x0 = x;
28276 /* Adjust for line numbers, if needed. */
28277 if (!NILP (Vdisplay_line_numbers) && x0 >= it->lnum_pixel_width)
28278 x -= it->lnum_pixel_width;
28279 int next_tab_x = ((1 + x + tab_width - 1) / tab_width) * tab_width;
28281 /* If the distance from the current position to the next tab
28282 stop is less than a space character width, use the
28283 tab stop after that. */
28284 if (next_tab_x - x < font->space_width)
28285 next_tab_x += tab_width;
28286 if (!NILP (Vdisplay_line_numbers) && x0 >= it->lnum_pixel_width)
28287 next_tab_x += (it->lnum_pixel_width
28288 - ((it->w->hscroll * font->space_width)
28289 % tab_width));
28291 it->pixel_width = next_tab_x - x0;
28292 it->nglyphs = 1;
28293 if (FONT_TOO_HIGH (font))
28295 if (get_char_glyph_code (' ', font, &char2b))
28297 pcm = get_per_char_metric (font, &char2b);
28298 if (pcm->width == 0
28299 && pcm->rbearing == 0 && pcm->lbearing == 0)
28300 pcm = NULL;
28303 if (pcm)
28305 it->ascent = pcm->ascent + boff;
28306 it->descent = pcm->descent - boff;
28308 else
28310 it->ascent = font->pixel_size + boff - 1;
28311 it->descent = -boff + 1;
28313 if (it->ascent < 0)
28314 it->ascent = 0;
28315 if (it->descent < 0)
28316 it->descent = 0;
28318 else
28320 it->ascent = FONT_BASE (font) + boff;
28321 it->descent = FONT_DESCENT (font) - boff;
28323 it->phys_ascent = it->ascent;
28324 it->phys_descent = it->descent;
28326 if (it->glyph_row)
28328 append_stretch_glyph (it, it->object, it->pixel_width,
28329 it->ascent + it->descent, it->ascent);
28332 else
28334 it->pixel_width = 0;
28335 it->nglyphs = 1;
28339 if (FONT_TOO_HIGH (font))
28341 int font_ascent, font_descent;
28343 /* For very large fonts, where we ignore the declared font
28344 dimensions, and go by per-character metrics instead,
28345 don't let the row ascent and descent values (and the row
28346 height computed from them) be smaller than the "normal"
28347 character metrics. This avoids unpleasant effects
28348 whereby lines on display would change their height
28349 depending on which characters are shown. */
28350 normal_char_ascent_descent (font, -1, &font_ascent, &font_descent);
28351 it->max_ascent = max (it->max_ascent, font_ascent);
28352 it->max_descent = max (it->max_descent, font_descent);
28355 else if (it->what == IT_COMPOSITION && it->cmp_it.ch < 0)
28357 /* A static composition.
28359 Note: A composition is represented as one glyph in the
28360 glyph matrix. There are no padding glyphs.
28362 Important note: pixel_width, ascent, and descent are the
28363 values of what is drawn by draw_glyphs (i.e. the values of
28364 the overall glyphs composed). */
28365 struct face *face = FACE_FROM_ID (it->f, it->face_id);
28366 int boff; /* baseline offset */
28367 struct composition *cmp = composition_table[it->cmp_it.id];
28368 int glyph_len = cmp->glyph_len;
28369 struct font *font = face->font;
28371 it->nglyphs = 1;
28373 /* If we have not yet calculated pixel size data of glyphs of
28374 the composition for the current face font, calculate them
28375 now. Theoretically, we have to check all fonts for the
28376 glyphs, but that requires much time and memory space. So,
28377 here we check only the font of the first glyph. This may
28378 lead to incorrect display, but it's very rare, and C-l
28379 (recenter-top-bottom) can correct the display anyway. */
28380 if (! cmp->font || cmp->font != font)
28382 /* Ascent and descent of the font of the first character
28383 of this composition (adjusted by baseline offset).
28384 Ascent and descent of overall glyphs should not be less
28385 than these, respectively. */
28386 int font_ascent, font_descent, font_height;
28387 /* Bounding box of the overall glyphs. */
28388 int leftmost, rightmost, lowest, highest;
28389 int lbearing, rbearing;
28390 int i, width, ascent, descent;
28391 int c;
28392 XChar2b char2b;
28393 struct font_metrics *pcm;
28394 ptrdiff_t pos;
28396 eassume (0 < glyph_len); /* See Bug#8512. */
28398 c = COMPOSITION_GLYPH (cmp, glyph_len - 1);
28399 while (c == '\t' && 0 < --glyph_len);
28401 bool right_padded = glyph_len < cmp->glyph_len;
28402 for (i = 0; i < glyph_len; i++)
28404 c = COMPOSITION_GLYPH (cmp, i);
28405 if (c != '\t')
28406 break;
28407 cmp->offsets[i * 2] = cmp->offsets[i * 2 + 1] = 0;
28409 bool left_padded = i > 0;
28411 pos = (STRINGP (it->string) ? IT_STRING_CHARPOS (*it)
28412 : IT_CHARPOS (*it));
28413 /* If no suitable font is found, use the default font. */
28414 bool font_not_found_p = font == NULL;
28415 if (font_not_found_p)
28417 face = face->ascii_face;
28418 font = face->font;
28420 boff = font->baseline_offset;
28421 if (font->vertical_centering)
28422 boff = VCENTER_BASELINE_OFFSET (font, it->f) - boff;
28423 normal_char_ascent_descent (font, -1, &font_ascent, &font_descent);
28424 font_ascent += boff;
28425 font_descent -= boff;
28426 font_height = font_ascent + font_descent;
28428 cmp->font = font;
28430 pcm = NULL;
28431 if (! font_not_found_p)
28433 get_char_face_and_encoding (it->f, c, it->face_id,
28434 &char2b, false);
28435 pcm = get_per_char_metric (font, &char2b);
28438 /* Initialize the bounding box. */
28439 if (pcm)
28441 width = cmp->glyph_len > 0 ? pcm->width : 0;
28442 ascent = pcm->ascent;
28443 descent = pcm->descent;
28444 lbearing = pcm->lbearing;
28445 rbearing = pcm->rbearing;
28447 else
28449 width = cmp->glyph_len > 0 ? font->space_width : 0;
28450 ascent = FONT_BASE (font);
28451 descent = FONT_DESCENT (font);
28452 lbearing = 0;
28453 rbearing = width;
28456 rightmost = width;
28457 leftmost = 0;
28458 lowest = - descent + boff;
28459 highest = ascent + boff;
28461 if (! font_not_found_p
28462 && font->default_ascent
28463 && CHAR_TABLE_P (Vuse_default_ascent)
28464 && !NILP (Faref (Vuse_default_ascent,
28465 make_number (it->char_to_display))))
28466 highest = font->default_ascent + boff;
28468 /* Draw the first glyph at the normal position. It may be
28469 shifted to right later if some other glyphs are drawn
28470 at the left. */
28471 cmp->offsets[i * 2] = 0;
28472 cmp->offsets[i * 2 + 1] = boff;
28473 cmp->lbearing = lbearing;
28474 cmp->rbearing = rbearing;
28476 /* Set cmp->offsets for the remaining glyphs. */
28477 for (i++; i < glyph_len; i++)
28479 int left, right, btm, top;
28480 int ch = COMPOSITION_GLYPH (cmp, i);
28481 int face_id;
28482 struct face *this_face;
28484 if (ch == '\t')
28485 ch = ' ';
28486 face_id = FACE_FOR_CHAR (it->f, face, ch, pos, it->string);
28487 this_face = FACE_FROM_ID (it->f, face_id);
28488 font = this_face->font;
28490 if (font == NULL)
28491 pcm = NULL;
28492 else
28494 get_char_face_and_encoding (it->f, ch, face_id,
28495 &char2b, false);
28496 pcm = get_per_char_metric (font, &char2b);
28498 if (! pcm)
28499 cmp->offsets[i * 2] = cmp->offsets[i * 2 + 1] = 0;
28500 else
28502 width = pcm->width;
28503 ascent = pcm->ascent;
28504 descent = pcm->descent;
28505 lbearing = pcm->lbearing;
28506 rbearing = pcm->rbearing;
28507 if (cmp->method != COMPOSITION_WITH_RULE_ALTCHARS)
28509 /* Relative composition with or without
28510 alternate chars. */
28511 left = (leftmost + rightmost - width) / 2;
28512 btm = - descent + boff;
28513 if (font->relative_compose
28514 && (! CHAR_TABLE_P (Vignore_relative_composition)
28515 || NILP (Faref (Vignore_relative_composition,
28516 make_number (ch)))))
28519 if (- descent >= font->relative_compose)
28520 /* One extra pixel between two glyphs. */
28521 btm = highest + 1;
28522 else if (ascent <= 0)
28523 /* One extra pixel between two glyphs. */
28524 btm = lowest - 1 - ascent - descent;
28527 else
28529 /* A composition rule is specified by an integer
28530 value that encodes global and new reference
28531 points (GREF and NREF). GREF and NREF are
28532 specified by numbers as below:
28534 0---1---2 -- ascent
28538 9--10--11 -- center
28540 ---3---4---5--- baseline
28542 6---7---8 -- descent
28544 int rule = COMPOSITION_RULE (cmp, i);
28545 int gref, nref, grefx, grefy, nrefx, nrefy, xoff, yoff;
28547 COMPOSITION_DECODE_RULE (rule, gref, nref, xoff, yoff);
28548 grefx = gref % 3, nrefx = nref % 3;
28549 grefy = gref / 3, nrefy = nref / 3;
28550 if (xoff)
28551 xoff = font_height * (xoff - 128) / 256;
28552 if (yoff)
28553 yoff = font_height * (yoff - 128) / 256;
28555 left = (leftmost
28556 + grefx * (rightmost - leftmost) / 2
28557 - nrefx * width / 2
28558 + xoff);
28560 btm = ((grefy == 0 ? highest
28561 : grefy == 1 ? 0
28562 : grefy == 2 ? lowest
28563 : (highest + lowest) / 2)
28564 - (nrefy == 0 ? ascent + descent
28565 : nrefy == 1 ? descent - boff
28566 : nrefy == 2 ? 0
28567 : (ascent + descent) / 2)
28568 + yoff);
28571 cmp->offsets[i * 2] = left;
28572 cmp->offsets[i * 2 + 1] = btm + descent;
28574 /* Update the bounding box of the overall glyphs. */
28575 if (width > 0)
28577 right = left + width;
28578 if (left < leftmost)
28579 leftmost = left;
28580 if (right > rightmost)
28581 rightmost = right;
28583 top = btm + descent + ascent;
28584 if (top > highest)
28585 highest = top;
28586 if (btm < lowest)
28587 lowest = btm;
28589 if (cmp->lbearing > left + lbearing)
28590 cmp->lbearing = left + lbearing;
28591 if (cmp->rbearing < left + rbearing)
28592 cmp->rbearing = left + rbearing;
28596 /* If there are glyphs whose x-offsets are negative,
28597 shift all glyphs to the right and make all x-offsets
28598 non-negative. */
28599 if (leftmost < 0)
28601 for (i = 0; i < cmp->glyph_len; i++)
28602 cmp->offsets[i * 2] -= leftmost;
28603 rightmost -= leftmost;
28604 cmp->lbearing -= leftmost;
28605 cmp->rbearing -= leftmost;
28608 if (left_padded && cmp->lbearing < 0)
28610 for (i = 0; i < cmp->glyph_len; i++)
28611 cmp->offsets[i * 2] -= cmp->lbearing;
28612 rightmost -= cmp->lbearing;
28613 cmp->rbearing -= cmp->lbearing;
28614 cmp->lbearing = 0;
28616 if (right_padded && rightmost < cmp->rbearing)
28618 rightmost = cmp->rbearing;
28621 cmp->pixel_width = rightmost;
28622 cmp->ascent = highest;
28623 cmp->descent = - lowest;
28624 if (cmp->ascent < font_ascent)
28625 cmp->ascent = font_ascent;
28626 if (cmp->descent < font_descent)
28627 cmp->descent = font_descent;
28630 if (it->glyph_row
28631 && (cmp->lbearing < 0
28632 || cmp->rbearing > cmp->pixel_width))
28633 it->glyph_row->contains_overlapping_glyphs_p = true;
28635 it->pixel_width = cmp->pixel_width;
28636 it->ascent = it->phys_ascent = cmp->ascent;
28637 it->descent = it->phys_descent = cmp->descent;
28638 if (face->box != FACE_NO_BOX)
28640 int thick = face->box_line_width;
28642 if (thick > 0)
28644 it->ascent += thick;
28645 it->descent += thick;
28647 else
28648 thick = - thick;
28650 if (it->start_of_box_run_p)
28651 it->pixel_width += thick;
28652 if (it->end_of_box_run_p)
28653 it->pixel_width += thick;
28656 /* If face has an overline, add the height of the overline
28657 (1 pixel) and a 1 pixel margin to the character height. */
28658 if (face->overline_p)
28659 it->ascent += overline_margin;
28661 take_vertical_position_into_account (it);
28662 if (it->ascent < 0)
28663 it->ascent = 0;
28664 if (it->descent < 0)
28665 it->descent = 0;
28667 if (it->glyph_row && cmp->glyph_len > 0)
28668 append_composite_glyph (it);
28670 else if (it->what == IT_COMPOSITION)
28672 /* A dynamic (automatic) composition. */
28673 struct face *face = FACE_FROM_ID (it->f, it->face_id);
28674 Lisp_Object gstring;
28675 struct font_metrics metrics;
28677 it->nglyphs = 1;
28679 gstring = composition_gstring_from_id (it->cmp_it.id);
28680 it->pixel_width
28681 = composition_gstring_width (gstring, it->cmp_it.from, it->cmp_it.to,
28682 &metrics);
28683 if (it->glyph_row
28684 && (metrics.lbearing < 0 || metrics.rbearing > metrics.width))
28685 it->glyph_row->contains_overlapping_glyphs_p = true;
28686 it->ascent = it->phys_ascent = metrics.ascent;
28687 it->descent = it->phys_descent = metrics.descent;
28688 if (face->box != FACE_NO_BOX)
28690 int thick = face->box_line_width;
28692 if (thick > 0)
28694 it->ascent += thick;
28695 it->descent += thick;
28697 else
28698 thick = - thick;
28700 if (it->start_of_box_run_p)
28701 it->pixel_width += thick;
28702 if (it->end_of_box_run_p)
28703 it->pixel_width += thick;
28705 /* If face has an overline, add the height of the overline
28706 (1 pixel) and a 1 pixel margin to the character height. */
28707 if (face->overline_p)
28708 it->ascent += overline_margin;
28709 take_vertical_position_into_account (it);
28710 if (it->ascent < 0)
28711 it->ascent = 0;
28712 if (it->descent < 0)
28713 it->descent = 0;
28715 if (it->glyph_row)
28716 append_composite_glyph (it);
28718 else if (it->what == IT_GLYPHLESS)
28719 produce_glyphless_glyph (it, false, Qnil);
28720 else if (it->what == IT_IMAGE)
28721 produce_image_glyph (it);
28722 else if (it->what == IT_STRETCH)
28723 produce_stretch_glyph (it);
28724 else if (it->what == IT_XWIDGET)
28725 produce_xwidget_glyph (it);
28727 done:
28728 /* Accumulate dimensions. Note: can't assume that it->descent > 0
28729 because this isn't true for images with `:ascent 100'. */
28730 eassert (it->ascent >= 0 && it->descent >= 0);
28731 if (it->area == TEXT_AREA)
28732 it->current_x += it->pixel_width;
28734 if (extra_line_spacing > 0)
28736 it->descent += extra_line_spacing;
28737 if (extra_line_spacing > it->max_extra_line_spacing)
28738 it->max_extra_line_spacing = extra_line_spacing;
28741 it->max_ascent = max (it->max_ascent, it->ascent);
28742 it->max_descent = max (it->max_descent, it->descent);
28743 it->max_phys_ascent = max (it->max_phys_ascent, it->phys_ascent);
28744 it->max_phys_descent = max (it->max_phys_descent, it->phys_descent);
28747 /* EXPORT for RIF:
28748 Output LEN glyphs starting at START at the nominal cursor position.
28749 Advance the nominal cursor over the text. UPDATED_ROW is the glyph row
28750 being updated, and UPDATED_AREA is the area of that row being updated. */
28752 void
28753 x_write_glyphs (struct window *w, struct glyph_row *updated_row,
28754 struct glyph *start, enum glyph_row_area updated_area, int len)
28756 int x, hpos, chpos = w->phys_cursor.hpos;
28758 eassert (updated_row);
28759 /* When the window is hscrolled, cursor hpos can legitimately be out
28760 of bounds, but we draw the cursor at the corresponding window
28761 margin in that case. */
28762 if (!updated_row->reversed_p && chpos < 0)
28763 chpos = 0;
28764 if (updated_row->reversed_p && chpos >= updated_row->used[TEXT_AREA])
28765 chpos = updated_row->used[TEXT_AREA] - 1;
28767 block_input ();
28769 /* Write glyphs. */
28771 hpos = start - updated_row->glyphs[updated_area];
28772 x = draw_glyphs (w, w->output_cursor.x,
28773 updated_row, updated_area,
28774 hpos, hpos + len,
28775 DRAW_NORMAL_TEXT, 0);
28777 /* Invalidate old phys cursor if the glyph at its hpos is redrawn. */
28778 if (updated_area == TEXT_AREA
28779 && w->phys_cursor_on_p
28780 && w->phys_cursor.vpos == w->output_cursor.vpos
28781 && chpos >= hpos
28782 && chpos < hpos + len)
28783 w->phys_cursor_on_p = false;
28785 unblock_input ();
28787 /* Advance the output cursor. */
28788 w->output_cursor.hpos += len;
28789 w->output_cursor.x = x;
28793 /* EXPORT for RIF:
28794 Insert LEN glyphs from START at the nominal cursor position. */
28796 void
28797 x_insert_glyphs (struct window *w, struct glyph_row *updated_row,
28798 struct glyph *start, enum glyph_row_area updated_area, int len)
28800 struct frame *f;
28801 int line_height, shift_by_width, shifted_region_width;
28802 struct glyph_row *row;
28803 struct glyph *glyph;
28804 int frame_x, frame_y;
28805 ptrdiff_t hpos;
28807 eassert (updated_row);
28808 block_input ();
28809 f = XFRAME (WINDOW_FRAME (w));
28811 /* Get the height of the line we are in. */
28812 row = updated_row;
28813 line_height = row->height;
28815 /* Get the width of the glyphs to insert. */
28816 shift_by_width = 0;
28817 for (glyph = start; glyph < start + len; ++glyph)
28818 shift_by_width += glyph->pixel_width;
28820 /* Get the width of the region to shift right. */
28821 shifted_region_width = (window_box_width (w, updated_area)
28822 - w->output_cursor.x
28823 - shift_by_width);
28825 /* Shift right. */
28826 frame_x = window_box_left (w, updated_area) + w->output_cursor.x;
28827 frame_y = WINDOW_TO_FRAME_PIXEL_Y (w, w->output_cursor.y);
28829 FRAME_RIF (f)->shift_glyphs_for_insert (f, frame_x, frame_y, shifted_region_width,
28830 line_height, shift_by_width);
28832 /* Write the glyphs. */
28833 hpos = start - row->glyphs[updated_area];
28834 draw_glyphs (w, w->output_cursor.x, row, updated_area,
28835 hpos, hpos + len,
28836 DRAW_NORMAL_TEXT, 0);
28838 /* Advance the output cursor. */
28839 w->output_cursor.hpos += len;
28840 w->output_cursor.x += shift_by_width;
28841 unblock_input ();
28845 /* EXPORT for RIF:
28846 Erase the current text line from the nominal cursor position
28847 (inclusive) to pixel column TO_X (exclusive). The idea is that
28848 everything from TO_X onward is already erased.
28850 TO_X is a pixel position relative to UPDATED_AREA of currently
28851 updated window W. TO_X == -1 means clear to the end of this area. */
28853 void
28854 x_clear_end_of_line (struct window *w, struct glyph_row *updated_row,
28855 enum glyph_row_area updated_area, int to_x)
28857 struct frame *f;
28858 int max_x, min_y, max_y;
28859 int from_x, from_y, to_y;
28861 eassert (updated_row);
28862 f = XFRAME (w->frame);
28864 if (updated_row->full_width_p)
28865 max_x = (WINDOW_PIXEL_WIDTH (w)
28866 - (updated_row->mode_line_p ? WINDOW_RIGHT_DIVIDER_WIDTH (w) : 0));
28867 else
28868 max_x = window_box_width (w, updated_area);
28869 max_y = window_text_bottom_y (w);
28871 /* TO_X == 0 means don't do anything. TO_X < 0 means clear to end
28872 of window. For TO_X > 0, truncate to end of drawing area. */
28873 if (to_x == 0)
28874 return;
28875 else if (to_x < 0)
28876 to_x = max_x;
28877 else
28878 to_x = min (to_x, max_x);
28880 to_y = min (max_y, w->output_cursor.y + updated_row->height);
28882 /* Notice if the cursor will be cleared by this operation. */
28883 if (!updated_row->full_width_p)
28884 notice_overwritten_cursor (w, updated_area,
28885 w->output_cursor.x, -1,
28886 updated_row->y,
28887 MATRIX_ROW_BOTTOM_Y (updated_row));
28889 from_x = w->output_cursor.x;
28891 /* Translate to frame coordinates. */
28892 if (updated_row->full_width_p)
28894 from_x = WINDOW_TO_FRAME_PIXEL_X (w, from_x);
28895 to_x = WINDOW_TO_FRAME_PIXEL_X (w, to_x);
28897 else
28899 int area_left = window_box_left (w, updated_area);
28900 from_x += area_left;
28901 to_x += area_left;
28904 min_y = WINDOW_HEADER_LINE_HEIGHT (w);
28905 from_y = WINDOW_TO_FRAME_PIXEL_Y (w, max (min_y, w->output_cursor.y));
28906 to_y = WINDOW_TO_FRAME_PIXEL_Y (w, to_y);
28908 /* Prevent inadvertently clearing to end of the X window. */
28909 if (to_x > from_x && to_y > from_y)
28911 block_input ();
28912 FRAME_RIF (f)->clear_frame_area (f, from_x, from_y,
28913 to_x - from_x, to_y - from_y);
28914 unblock_input ();
28918 #endif /* HAVE_WINDOW_SYSTEM */
28922 /***********************************************************************
28923 Cursor types
28924 ***********************************************************************/
28926 /* Value is the internal representation of the specified cursor type
28927 ARG. If type is BAR_CURSOR, return in *WIDTH the specified width
28928 of the bar cursor. */
28930 static enum text_cursor_kinds
28931 get_specified_cursor_type (Lisp_Object arg, int *width)
28933 enum text_cursor_kinds type;
28935 if (NILP (arg))
28936 return NO_CURSOR;
28938 if (EQ (arg, Qbox))
28939 return FILLED_BOX_CURSOR;
28941 if (EQ (arg, Qhollow))
28942 return HOLLOW_BOX_CURSOR;
28944 if (EQ (arg, Qbar))
28946 *width = 2;
28947 return BAR_CURSOR;
28950 if (CONSP (arg)
28951 && EQ (XCAR (arg), Qbar)
28952 && RANGED_INTEGERP (0, XCDR (arg), INT_MAX))
28954 *width = XINT (XCDR (arg));
28955 return BAR_CURSOR;
28958 if (EQ (arg, Qhbar))
28960 *width = 2;
28961 return HBAR_CURSOR;
28964 if (CONSP (arg)
28965 && EQ (XCAR (arg), Qhbar)
28966 && RANGED_INTEGERP (0, XCDR (arg), INT_MAX))
28968 *width = XINT (XCDR (arg));
28969 return HBAR_CURSOR;
28972 /* Treat anything unknown as "hollow box cursor".
28973 It was bad to signal an error; people have trouble fixing
28974 .Xdefaults with Emacs, when it has something bad in it. */
28975 type = HOLLOW_BOX_CURSOR;
28977 return type;
28980 /* Set the default cursor types for specified frame. */
28981 void
28982 set_frame_cursor_types (struct frame *f, Lisp_Object arg)
28984 int width = 1;
28985 Lisp_Object tem;
28987 FRAME_DESIRED_CURSOR (f) = get_specified_cursor_type (arg, &width);
28988 FRAME_CURSOR_WIDTH (f) = width;
28990 /* By default, set up the blink-off state depending on the on-state. */
28992 tem = Fassoc (arg, Vblink_cursor_alist, Qnil);
28993 if (!NILP (tem))
28995 FRAME_BLINK_OFF_CURSOR (f)
28996 = get_specified_cursor_type (XCDR (tem), &width);
28997 FRAME_BLINK_OFF_CURSOR_WIDTH (f) = width;
28999 else
29000 FRAME_BLINK_OFF_CURSOR (f) = DEFAULT_CURSOR;
29002 /* Make sure the cursor gets redrawn. */
29003 f->cursor_type_changed = true;
29007 #ifdef HAVE_WINDOW_SYSTEM
29009 /* Return the cursor we want to be displayed in window W. Return
29010 width of bar/hbar cursor through WIDTH arg. Return with
29011 ACTIVE_CURSOR arg set to true if cursor in window W is `active'
29012 (i.e. if the `system caret' should track this cursor).
29014 In a mini-buffer window, we want the cursor only to appear if we
29015 are reading input from this window. For the selected window, we
29016 want the cursor type given by the frame parameter or buffer local
29017 setting of cursor-type. If explicitly marked off, draw no cursor.
29018 In all other cases, we want a hollow box cursor. */
29020 static enum text_cursor_kinds
29021 get_window_cursor_type (struct window *w, struct glyph *glyph, int *width,
29022 bool *active_cursor)
29024 struct frame *f = XFRAME (w->frame);
29025 struct buffer *b = XBUFFER (w->contents);
29026 int cursor_type = DEFAULT_CURSOR;
29027 Lisp_Object alt_cursor;
29028 bool non_selected = false;
29030 *active_cursor = true;
29032 /* Echo area */
29033 if (cursor_in_echo_area
29034 && FRAME_HAS_MINIBUF_P (f)
29035 && EQ (FRAME_MINIBUF_WINDOW (f), echo_area_window))
29037 if (w == XWINDOW (echo_area_window))
29039 if (EQ (BVAR (b, cursor_type), Qt) || NILP (BVAR (b, cursor_type)))
29041 *width = FRAME_CURSOR_WIDTH (f);
29042 return FRAME_DESIRED_CURSOR (f);
29044 else
29045 return get_specified_cursor_type (BVAR (b, cursor_type), width);
29048 *active_cursor = false;
29049 non_selected = true;
29052 /* Detect a nonselected window or nonselected frame. */
29053 else if (w != XWINDOW (f->selected_window)
29054 || f != FRAME_DISPLAY_INFO (f)->x_highlight_frame)
29056 *active_cursor = false;
29058 if (MINI_WINDOW_P (w) && minibuf_level == 0)
29059 return NO_CURSOR;
29061 non_selected = true;
29064 /* Never display a cursor in a window in which cursor-type is nil. */
29065 if (NILP (BVAR (b, cursor_type)))
29066 return NO_CURSOR;
29068 /* Get the normal cursor type for this window. */
29069 if (EQ (BVAR (b, cursor_type), Qt))
29071 cursor_type = FRAME_DESIRED_CURSOR (f);
29072 *width = FRAME_CURSOR_WIDTH (f);
29074 else
29075 cursor_type = get_specified_cursor_type (BVAR (b, cursor_type), width);
29077 /* Use cursor-in-non-selected-windows instead
29078 for non-selected window or frame. */
29079 if (non_selected)
29081 alt_cursor = BVAR (b, cursor_in_non_selected_windows);
29082 if (!EQ (Qt, alt_cursor))
29083 return get_specified_cursor_type (alt_cursor, width);
29084 /* t means modify the normal cursor type. */
29085 if (cursor_type == FILLED_BOX_CURSOR)
29086 cursor_type = HOLLOW_BOX_CURSOR;
29087 else if (cursor_type == BAR_CURSOR && *width > 1)
29088 --*width;
29089 return cursor_type;
29092 /* Use normal cursor if not blinked off. */
29093 if (!w->cursor_off_p)
29095 if (glyph != NULL && glyph->type == XWIDGET_GLYPH)
29096 return NO_CURSOR;
29097 if (glyph != NULL && glyph->type == IMAGE_GLYPH)
29099 if (cursor_type == FILLED_BOX_CURSOR)
29101 /* Using a block cursor on large images can be very annoying.
29102 So use a hollow cursor for "large" images.
29103 If image is not transparent (no mask), also use hollow cursor. */
29104 struct image *img = IMAGE_OPT_FROM_ID (f, glyph->u.img_id);
29105 if (img != NULL && IMAGEP (img->spec))
29107 /* Arbitrarily, interpret "Large" as >32x32 and >NxN
29108 where N = size of default frame font size.
29109 This should cover most of the "tiny" icons people may use. */
29110 if (!img->mask
29111 || img->width > max (32, WINDOW_FRAME_COLUMN_WIDTH (w))
29112 || img->height > max (32, WINDOW_FRAME_LINE_HEIGHT (w)))
29113 cursor_type = HOLLOW_BOX_CURSOR;
29116 else if (cursor_type != NO_CURSOR)
29118 /* Display current only supports BOX and HOLLOW cursors for images.
29119 So for now, unconditionally use a HOLLOW cursor when cursor is
29120 not a solid box cursor. */
29121 cursor_type = HOLLOW_BOX_CURSOR;
29124 return cursor_type;
29127 /* Cursor is blinked off, so determine how to "toggle" it. */
29129 /* First look for an entry matching the buffer's cursor-type in blink-cursor-alist. */
29130 if ((alt_cursor = Fassoc (BVAR (b, cursor_type), Vblink_cursor_alist, Qnil), !NILP (alt_cursor)))
29131 return get_specified_cursor_type (XCDR (alt_cursor), width);
29133 /* Then see if frame has specified a specific blink off cursor type. */
29134 if (FRAME_BLINK_OFF_CURSOR (f) != DEFAULT_CURSOR)
29136 *width = FRAME_BLINK_OFF_CURSOR_WIDTH (f);
29137 return FRAME_BLINK_OFF_CURSOR (f);
29140 #if false
29141 /* Some people liked having a permanently visible blinking cursor,
29142 while others had very strong opinions against it. So it was
29143 decided to remove it. KFS 2003-09-03 */
29145 /* Finally perform built-in cursor blinking:
29146 filled box <-> hollow box
29147 wide [h]bar <-> narrow [h]bar
29148 narrow [h]bar <-> no cursor
29149 other type <-> no cursor */
29151 if (cursor_type == FILLED_BOX_CURSOR)
29152 return HOLLOW_BOX_CURSOR;
29154 if ((cursor_type == BAR_CURSOR || cursor_type == HBAR_CURSOR) && *width > 1)
29156 *width = 1;
29157 return cursor_type;
29159 #endif
29161 return NO_CURSOR;
29165 /* Notice when the text cursor of window W has been completely
29166 overwritten by a drawing operation that outputs glyphs in AREA
29167 starting at X0 and ending at X1 in the line starting at Y0 and
29168 ending at Y1. X coordinates are area-relative. X1 < 0 means all
29169 the rest of the line after X0 has been written. Y coordinates
29170 are window-relative. */
29172 static void
29173 notice_overwritten_cursor (struct window *w, enum glyph_row_area area,
29174 int x0, int x1, int y0, int y1)
29176 int cx0, cx1, cy0, cy1;
29177 struct glyph_row *row;
29179 if (!w->phys_cursor_on_p)
29180 return;
29181 if (area != TEXT_AREA)
29182 return;
29184 if (w->phys_cursor.vpos < 0
29185 || w->phys_cursor.vpos >= w->current_matrix->nrows
29186 || (row = w->current_matrix->rows + w->phys_cursor.vpos,
29187 !(row->enabled_p && MATRIX_ROW_DISPLAYS_TEXT_P (row))))
29188 return;
29190 if (row->cursor_in_fringe_p)
29192 row->cursor_in_fringe_p = false;
29193 draw_fringe_bitmap (w, row, row->reversed_p);
29194 w->phys_cursor_on_p = false;
29195 return;
29198 cx0 = w->phys_cursor.x;
29199 cx1 = cx0 + w->phys_cursor_width;
29200 if (x0 > cx0 || (x1 >= 0 && x1 < cx1))
29201 return;
29203 /* The cursor image will be completely removed from the
29204 screen if the output area intersects the cursor area in
29205 y-direction. When we draw in [y0 y1[, and some part of
29206 the cursor is at y < y0, that part must have been drawn
29207 before. When scrolling, the cursor is erased before
29208 actually scrolling, so we don't come here. When not
29209 scrolling, the rows above the old cursor row must have
29210 changed, and in this case these rows must have written
29211 over the cursor image.
29213 Likewise if part of the cursor is below y1, with the
29214 exception of the cursor being in the first blank row at
29215 the buffer and window end because update_text_area
29216 doesn't draw that row. (Except when it does, but
29217 that's handled in update_text_area.) */
29219 cy0 = w->phys_cursor.y;
29220 cy1 = cy0 + w->phys_cursor_height;
29221 if ((y0 < cy0 || y0 >= cy1) && (y1 <= cy0 || y1 >= cy1))
29222 return;
29224 w->phys_cursor_on_p = false;
29227 #endif /* HAVE_WINDOW_SYSTEM */
29230 /************************************************************************
29231 Mouse Face
29232 ************************************************************************/
29234 #ifdef HAVE_WINDOW_SYSTEM
29236 /* EXPORT for RIF:
29237 Fix the display of area AREA of overlapping row ROW in window W
29238 with respect to the overlapping part OVERLAPS. */
29240 void
29241 x_fix_overlapping_area (struct window *w, struct glyph_row *row,
29242 enum glyph_row_area area, int overlaps)
29244 int i, x;
29246 block_input ();
29248 x = 0;
29249 for (i = 0; i < row->used[area];)
29251 if (row->glyphs[area][i].overlaps_vertically_p)
29253 int start = i, start_x = x;
29257 x += row->glyphs[area][i].pixel_width;
29258 ++i;
29260 while (i < row->used[area]
29261 && row->glyphs[area][i].overlaps_vertically_p);
29263 draw_glyphs (w, start_x, row, area,
29264 start, i,
29265 DRAW_NORMAL_TEXT, overlaps);
29267 else
29269 x += row->glyphs[area][i].pixel_width;
29270 ++i;
29274 unblock_input ();
29278 /* EXPORT:
29279 Draw the cursor glyph of window W in glyph row ROW. See the
29280 comment of draw_glyphs for the meaning of HL. */
29282 void
29283 draw_phys_cursor_glyph (struct window *w, struct glyph_row *row,
29284 enum draw_glyphs_face hl)
29286 /* If cursor hpos is out of bounds, don't draw garbage. This can
29287 happen in mini-buffer windows when switching between echo area
29288 glyphs and mini-buffer. */
29289 if ((row->reversed_p
29290 ? (w->phys_cursor.hpos >= 0)
29291 : (w->phys_cursor.hpos < row->used[TEXT_AREA])))
29293 bool on_p = w->phys_cursor_on_p;
29294 int x1;
29295 int hpos = w->phys_cursor.hpos;
29297 /* When the window is hscrolled, cursor hpos can legitimately be
29298 out of bounds, but we draw the cursor at the corresponding
29299 window margin in that case. */
29300 if (!row->reversed_p && hpos < 0)
29301 hpos = 0;
29302 if (row->reversed_p && hpos >= row->used[TEXT_AREA])
29303 hpos = row->used[TEXT_AREA] - 1;
29305 x1 = draw_glyphs (w, w->phys_cursor.x, row, TEXT_AREA, hpos, hpos + 1,
29306 hl, 0);
29307 w->phys_cursor_on_p = on_p;
29309 if (hl == DRAW_CURSOR)
29310 w->phys_cursor_width = x1 - w->phys_cursor.x;
29311 /* When we erase the cursor, and ROW is overlapped by other
29312 rows, make sure that these overlapping parts of other rows
29313 are redrawn. */
29314 else if (hl == DRAW_NORMAL_TEXT && row->overlapped_p)
29316 w->phys_cursor_width = x1 - w->phys_cursor.x;
29318 if (row > w->current_matrix->rows
29319 && MATRIX_ROW_OVERLAPS_SUCC_P (row - 1))
29320 x_fix_overlapping_area (w, row - 1, TEXT_AREA,
29321 OVERLAPS_ERASED_CURSOR);
29323 if (MATRIX_ROW_BOTTOM_Y (row) < window_text_bottom_y (w)
29324 && MATRIX_ROW_OVERLAPS_PRED_P (row + 1))
29325 x_fix_overlapping_area (w, row + 1, TEXT_AREA,
29326 OVERLAPS_ERASED_CURSOR);
29332 /* Erase the image of a cursor of window W from the screen. */
29334 void
29335 erase_phys_cursor (struct window *w)
29337 struct frame *f = XFRAME (w->frame);
29338 Mouse_HLInfo *hlinfo = MOUSE_HL_INFO (f);
29339 int hpos = w->phys_cursor.hpos;
29340 int vpos = w->phys_cursor.vpos;
29341 bool mouse_face_here_p = false;
29342 struct glyph_matrix *active_glyphs = w->current_matrix;
29343 struct glyph_row *cursor_row;
29344 struct glyph *cursor_glyph;
29345 enum draw_glyphs_face hl;
29347 /* No cursor displayed or row invalidated => nothing to do on the
29348 screen. */
29349 if (w->phys_cursor_type == NO_CURSOR)
29350 goto mark_cursor_off;
29352 /* VPOS >= active_glyphs->nrows means that window has been resized.
29353 Don't bother to erase the cursor. */
29354 if (vpos >= active_glyphs->nrows)
29355 goto mark_cursor_off;
29357 /* If row containing cursor is marked invalid, there is nothing we
29358 can do. */
29359 cursor_row = MATRIX_ROW (active_glyphs, vpos);
29360 if (!cursor_row->enabled_p)
29361 goto mark_cursor_off;
29363 /* If line spacing is > 0, old cursor may only be partially visible in
29364 window after split-window. So adjust visible height. */
29365 cursor_row->visible_height = min (cursor_row->visible_height,
29366 window_text_bottom_y (w) - cursor_row->y);
29368 /* If row is completely invisible, don't attempt to delete a cursor which
29369 isn't there. This can happen if cursor is at top of a window, and
29370 we switch to a buffer with a header line in that window. */
29371 if (cursor_row->visible_height <= 0)
29372 goto mark_cursor_off;
29374 /* If cursor is in the fringe, erase by drawing actual bitmap there. */
29375 if (cursor_row->cursor_in_fringe_p)
29377 cursor_row->cursor_in_fringe_p = false;
29378 draw_fringe_bitmap (w, cursor_row, cursor_row->reversed_p);
29379 goto mark_cursor_off;
29382 /* This can happen when the new row is shorter than the old one.
29383 In this case, either draw_glyphs or clear_end_of_line
29384 should have cleared the cursor. Note that we wouldn't be
29385 able to erase the cursor in this case because we don't have a
29386 cursor glyph at hand. */
29387 if ((cursor_row->reversed_p
29388 ? (w->phys_cursor.hpos < 0)
29389 : (w->phys_cursor.hpos >= cursor_row->used[TEXT_AREA])))
29390 goto mark_cursor_off;
29392 /* When the window is hscrolled, cursor hpos can legitimately be out
29393 of bounds, but we draw the cursor at the corresponding window
29394 margin in that case. */
29395 if (!cursor_row->reversed_p && hpos < 0)
29396 hpos = 0;
29397 if (cursor_row->reversed_p && hpos >= cursor_row->used[TEXT_AREA])
29398 hpos = cursor_row->used[TEXT_AREA] - 1;
29400 /* If the cursor is in the mouse face area, redisplay that when
29401 we clear the cursor. */
29402 if (! NILP (hlinfo->mouse_face_window)
29403 && coords_in_mouse_face_p (w, hpos, vpos)
29404 /* Don't redraw the cursor's spot in mouse face if it is at the
29405 end of a line (on a newline). The cursor appears there, but
29406 mouse highlighting does not. */
29407 && cursor_row->used[TEXT_AREA] > hpos && hpos >= 0)
29408 mouse_face_here_p = true;
29410 /* Maybe clear the display under the cursor. */
29411 if (w->phys_cursor_type == HOLLOW_BOX_CURSOR)
29413 int x, y;
29414 int header_line_height = WINDOW_HEADER_LINE_HEIGHT (w);
29415 int width;
29417 cursor_glyph = get_phys_cursor_glyph (w);
29418 if (cursor_glyph == NULL)
29419 goto mark_cursor_off;
29421 width = cursor_glyph->pixel_width;
29422 x = w->phys_cursor.x;
29423 if (x < 0)
29425 width += x;
29426 x = 0;
29428 width = min (width, window_box_width (w, TEXT_AREA) - x);
29429 y = WINDOW_TO_FRAME_PIXEL_Y (w, max (header_line_height, cursor_row->y));
29430 x = WINDOW_TEXT_TO_FRAME_PIXEL_X (w, x);
29432 if (width > 0)
29433 FRAME_RIF (f)->clear_frame_area (f, x, y, width, cursor_row->visible_height);
29436 /* Erase the cursor by redrawing the character underneath it. */
29437 if (mouse_face_here_p)
29438 hl = DRAW_MOUSE_FACE;
29439 else
29440 hl = DRAW_NORMAL_TEXT;
29441 draw_phys_cursor_glyph (w, cursor_row, hl);
29443 mark_cursor_off:
29444 w->phys_cursor_on_p = false;
29445 w->phys_cursor_type = NO_CURSOR;
29449 /* Display or clear cursor of window W. If !ON, clear the cursor.
29450 If ON, display the cursor; where to put the cursor is specified by
29451 HPOS, VPOS, X and Y. */
29453 void
29454 display_and_set_cursor (struct window *w, bool on,
29455 int hpos, int vpos, int x, int y)
29457 struct frame *f = XFRAME (w->frame);
29458 int new_cursor_type;
29459 int new_cursor_width;
29460 bool active_cursor;
29461 struct glyph_row *glyph_row;
29462 struct glyph *glyph;
29464 /* This is pointless on invisible frames, and dangerous on garbaged
29465 windows and frames; in the latter case, the frame or window may
29466 be in the midst of changing its size, and x and y may be off the
29467 window. */
29468 if (! FRAME_VISIBLE_P (f)
29469 || vpos >= w->current_matrix->nrows
29470 || hpos >= w->current_matrix->matrix_w)
29471 return;
29473 /* If cursor is off and we want it off, return quickly. */
29474 if (!on && !w->phys_cursor_on_p)
29475 return;
29477 glyph_row = MATRIX_ROW (w->current_matrix, vpos);
29478 /* If cursor row is not enabled, we don't really know where to
29479 display the cursor. */
29480 if (!glyph_row->enabled_p)
29482 w->phys_cursor_on_p = false;
29483 return;
29486 /* A frame might be marked garbaged even though its cursor position
29487 is correct, and will not change upon subsequent redisplay. This
29488 happens in some rare situations, like toggling the sort order in
29489 Dired windows. We've already established that VPOS is valid, so
29490 it shouldn't do any harm to record the cursor position, as we are
29491 going to return without acting on it anyway. Otherwise, expose
29492 events might come in and call update_window_cursor, which will
29493 blindly use outdated values in w->phys_cursor. */
29494 if (FRAME_GARBAGED_P (f))
29496 if (on)
29498 w->phys_cursor.x = x;
29499 w->phys_cursor.y = glyph_row->y;
29500 w->phys_cursor.hpos = hpos;
29501 w->phys_cursor.vpos = vpos;
29503 return;
29506 glyph = NULL;
29507 if (0 <= hpos && hpos < glyph_row->used[TEXT_AREA])
29508 glyph = glyph_row->glyphs[TEXT_AREA] + hpos;
29510 eassert (input_blocked_p ());
29512 /* Set new_cursor_type to the cursor we want to be displayed. */
29513 new_cursor_type = get_window_cursor_type (w, glyph,
29514 &new_cursor_width, &active_cursor);
29516 /* If cursor is currently being shown and we don't want it to be or
29517 it is in the wrong place, or the cursor type is not what we want,
29518 erase it. */
29519 if (w->phys_cursor_on_p
29520 && (!on
29521 || w->phys_cursor.x != x
29522 || w->phys_cursor.y != y
29523 /* HPOS can be negative in R2L rows whose
29524 exact_window_width_line_p flag is set (i.e. their newline
29525 would "overflow into the fringe"). */
29526 || hpos < 0
29527 || new_cursor_type != w->phys_cursor_type
29528 || ((new_cursor_type == BAR_CURSOR || new_cursor_type == HBAR_CURSOR)
29529 && new_cursor_width != w->phys_cursor_width)))
29530 erase_phys_cursor (w);
29532 /* Don't check phys_cursor_on_p here because that flag is only set
29533 to false in some cases where we know that the cursor has been
29534 completely erased, to avoid the extra work of erasing the cursor
29535 twice. In other words, phys_cursor_on_p can be true and the cursor
29536 still not be visible, or it has only been partly erased. */
29537 if (on)
29539 w->phys_cursor_ascent = glyph_row->ascent;
29540 w->phys_cursor_height = glyph_row->height;
29542 /* Set phys_cursor_.* before x_draw_.* is called because some
29543 of them may need the information. */
29544 w->phys_cursor.x = x;
29545 w->phys_cursor.y = glyph_row->y;
29546 w->phys_cursor.hpos = hpos;
29547 w->phys_cursor.vpos = vpos;
29550 FRAME_RIF (f)->draw_window_cursor (w, glyph_row, x, y,
29551 new_cursor_type, new_cursor_width,
29552 on, active_cursor);
29556 /* Switch the display of W's cursor on or off, according to the value
29557 of ON. */
29559 static void
29560 update_window_cursor (struct window *w, bool on)
29562 /* Don't update cursor in windows whose frame is in the process
29563 of being deleted. */
29564 if (w->current_matrix)
29566 int hpos = w->phys_cursor.hpos;
29567 int vpos = w->phys_cursor.vpos;
29568 struct glyph_row *row;
29570 if (vpos >= w->current_matrix->nrows
29571 || hpos >= w->current_matrix->matrix_w)
29572 return;
29574 row = MATRIX_ROW (w->current_matrix, vpos);
29576 /* When the window is hscrolled, cursor hpos can legitimately be
29577 out of bounds, but we draw the cursor at the corresponding
29578 window margin in that case. */
29579 if (!row->reversed_p && hpos < 0)
29580 hpos = 0;
29581 if (row->reversed_p && hpos >= row->used[TEXT_AREA])
29582 hpos = row->used[TEXT_AREA] - 1;
29584 block_input ();
29585 display_and_set_cursor (w, on, hpos, vpos,
29586 w->phys_cursor.x, w->phys_cursor.y);
29587 unblock_input ();
29592 /* Call update_window_cursor with parameter ON_P on all leaf windows
29593 in the window tree rooted at W. */
29595 static void
29596 update_cursor_in_window_tree (struct window *w, bool on_p)
29598 while (w)
29600 if (WINDOWP (w->contents))
29601 update_cursor_in_window_tree (XWINDOW (w->contents), on_p);
29602 else
29603 update_window_cursor (w, on_p);
29605 w = NILP (w->next) ? 0 : XWINDOW (w->next);
29610 /* EXPORT:
29611 Display the cursor on window W, or clear it, according to ON_P.
29612 Don't change the cursor's position. */
29614 void
29615 x_update_cursor (struct frame *f, bool on_p)
29617 update_cursor_in_window_tree (XWINDOW (f->root_window), on_p);
29621 /* EXPORT:
29622 Clear the cursor of window W to background color, and mark the
29623 cursor as not shown. This is used when the text where the cursor
29624 is about to be rewritten. */
29626 void
29627 x_clear_cursor (struct window *w)
29629 if (FRAME_VISIBLE_P (XFRAME (w->frame)) && w->phys_cursor_on_p)
29630 update_window_cursor (w, false);
29633 #endif /* HAVE_WINDOW_SYSTEM */
29635 /* Implementation of draw_row_with_mouse_face for GUI sessions, GPM,
29636 and MSDOS. */
29637 static void
29638 draw_row_with_mouse_face (struct window *w, int start_x, struct glyph_row *row,
29639 int start_hpos, int end_hpos,
29640 enum draw_glyphs_face draw)
29642 #ifdef HAVE_WINDOW_SYSTEM
29643 if (FRAME_WINDOW_P (XFRAME (w->frame)))
29645 draw_glyphs (w, start_x, row, TEXT_AREA, start_hpos, end_hpos, draw, 0);
29646 return;
29648 #endif
29649 #if defined (HAVE_GPM) || defined (MSDOS) || defined (WINDOWSNT)
29650 tty_draw_row_with_mouse_face (w, row, start_hpos, end_hpos, draw);
29651 #endif
29654 /* Display the active region described by mouse_face_* according to DRAW. */
29656 static void
29657 show_mouse_face (Mouse_HLInfo *hlinfo, enum draw_glyphs_face draw)
29659 struct window *w = XWINDOW (hlinfo->mouse_face_window);
29660 struct frame *f = XFRAME (WINDOW_FRAME (w));
29662 if (/* If window is in the process of being destroyed, don't bother
29663 to do anything. */
29664 w->current_matrix != NULL
29665 /* Don't update mouse highlight if hidden. */
29666 && (draw != DRAW_MOUSE_FACE || !hlinfo->mouse_face_hidden)
29667 /* Recognize when we are called to operate on rows that don't exist
29668 anymore. This can happen when a window is split. */
29669 && hlinfo->mouse_face_end_row < w->current_matrix->nrows)
29671 bool phys_cursor_on_p = w->phys_cursor_on_p;
29672 struct glyph_row *row, *first, *last;
29674 first = MATRIX_ROW (w->current_matrix, hlinfo->mouse_face_beg_row);
29675 last = MATRIX_ROW (w->current_matrix, hlinfo->mouse_face_end_row);
29677 for (row = first; row <= last && row->enabled_p; ++row)
29679 int start_hpos, end_hpos, start_x;
29681 /* For all but the first row, the highlight starts at column 0. */
29682 if (row == first)
29684 /* R2L rows have BEG and END in reversed order, but the
29685 screen drawing geometry is always left to right. So
29686 we need to mirror the beginning and end of the
29687 highlighted area in R2L rows. */
29688 if (!row->reversed_p)
29690 start_hpos = hlinfo->mouse_face_beg_col;
29691 start_x = hlinfo->mouse_face_beg_x;
29693 else if (row == last)
29695 start_hpos = hlinfo->mouse_face_end_col;
29696 start_x = hlinfo->mouse_face_end_x;
29698 else
29700 start_hpos = 0;
29701 start_x = 0;
29704 else if (row->reversed_p && row == last)
29706 start_hpos = hlinfo->mouse_face_end_col;
29707 start_x = hlinfo->mouse_face_end_x;
29709 else
29711 start_hpos = 0;
29712 start_x = 0;
29715 if (row == last)
29717 if (!row->reversed_p)
29718 end_hpos = hlinfo->mouse_face_end_col;
29719 else if (row == first)
29720 end_hpos = hlinfo->mouse_face_beg_col;
29721 else
29723 end_hpos = row->used[TEXT_AREA];
29724 if (draw == DRAW_NORMAL_TEXT)
29725 row->fill_line_p = true; /* Clear to end of line. */
29728 else if (row->reversed_p && row == first)
29729 end_hpos = hlinfo->mouse_face_beg_col;
29730 else
29732 end_hpos = row->used[TEXT_AREA];
29733 if (draw == DRAW_NORMAL_TEXT)
29734 row->fill_line_p = true; /* Clear to end of line. */
29737 if (end_hpos > start_hpos)
29739 draw_row_with_mouse_face (w, start_x, row,
29740 start_hpos, end_hpos, draw);
29742 row->mouse_face_p
29743 = draw == DRAW_MOUSE_FACE || draw == DRAW_IMAGE_RAISED;
29747 /* When we've written over the cursor, arrange for it to
29748 be displayed again. */
29749 if (FRAME_WINDOW_P (f)
29750 && phys_cursor_on_p && !w->phys_cursor_on_p)
29752 #ifdef HAVE_WINDOW_SYSTEM
29753 int hpos = w->phys_cursor.hpos;
29755 /* When the window is hscrolled, cursor hpos can legitimately be
29756 out of bounds, but we draw the cursor at the corresponding
29757 window margin in that case. */
29758 if (!row->reversed_p && hpos < 0)
29759 hpos = 0;
29760 if (row->reversed_p && hpos >= row->used[TEXT_AREA])
29761 hpos = row->used[TEXT_AREA] - 1;
29763 block_input ();
29764 display_and_set_cursor (w, true, hpos, w->phys_cursor.vpos,
29765 w->phys_cursor.x, w->phys_cursor.y);
29766 unblock_input ();
29767 #endif /* HAVE_WINDOW_SYSTEM */
29771 #ifdef HAVE_WINDOW_SYSTEM
29772 /* Change the mouse cursor. */
29773 if (FRAME_WINDOW_P (f) && NILP (do_mouse_tracking))
29775 #if ! defined (USE_GTK) && ! defined (HAVE_NS)
29776 if (draw == DRAW_NORMAL_TEXT
29777 && !EQ (hlinfo->mouse_face_window, f->tool_bar_window))
29778 FRAME_RIF (f)->define_frame_cursor (f, FRAME_X_OUTPUT (f)->text_cursor);
29779 else
29780 #endif
29781 if (draw == DRAW_MOUSE_FACE)
29782 FRAME_RIF (f)->define_frame_cursor (f, FRAME_X_OUTPUT (f)->hand_cursor);
29783 else
29784 FRAME_RIF (f)->define_frame_cursor (f, FRAME_X_OUTPUT (f)->nontext_cursor);
29786 #endif /* HAVE_WINDOW_SYSTEM */
29789 /* EXPORT:
29790 Clear out the mouse-highlighted active region.
29791 Redraw it un-highlighted first. Value is true if mouse
29792 face was actually drawn unhighlighted. */
29794 bool
29795 clear_mouse_face (Mouse_HLInfo *hlinfo)
29797 bool cleared
29798 = !hlinfo->mouse_face_hidden && !NILP (hlinfo->mouse_face_window);
29799 if (cleared)
29800 show_mouse_face (hlinfo, DRAW_NORMAL_TEXT);
29801 hlinfo->mouse_face_beg_row = hlinfo->mouse_face_beg_col = -1;
29802 hlinfo->mouse_face_end_row = hlinfo->mouse_face_end_col = -1;
29803 hlinfo->mouse_face_window = Qnil;
29804 hlinfo->mouse_face_overlay = Qnil;
29805 return cleared;
29808 /* Return true if the coordinates HPOS and VPOS on windows W are
29809 within the mouse face on that window. */
29810 static bool
29811 coords_in_mouse_face_p (struct window *w, int hpos, int vpos)
29813 Mouse_HLInfo *hlinfo = MOUSE_HL_INFO (XFRAME (w->frame));
29815 /* Quickly resolve the easy cases. */
29816 if (!(WINDOWP (hlinfo->mouse_face_window)
29817 && XWINDOW (hlinfo->mouse_face_window) == w))
29818 return false;
29819 if (vpos < hlinfo->mouse_face_beg_row
29820 || vpos > hlinfo->mouse_face_end_row)
29821 return false;
29822 if (vpos > hlinfo->mouse_face_beg_row
29823 && vpos < hlinfo->mouse_face_end_row)
29824 return true;
29826 if (!MATRIX_ROW (w->current_matrix, vpos)->reversed_p)
29828 if (hlinfo->mouse_face_beg_row == hlinfo->mouse_face_end_row)
29830 if (hlinfo->mouse_face_beg_col <= hpos && hpos < hlinfo->mouse_face_end_col)
29831 return true;
29833 else if ((vpos == hlinfo->mouse_face_beg_row
29834 && hpos >= hlinfo->mouse_face_beg_col)
29835 || (vpos == hlinfo->mouse_face_end_row
29836 && hpos < hlinfo->mouse_face_end_col))
29837 return true;
29839 else
29841 if (hlinfo->mouse_face_beg_row == hlinfo->mouse_face_end_row)
29843 if (hlinfo->mouse_face_end_col < hpos && hpos <= hlinfo->mouse_face_beg_col)
29844 return true;
29846 else if ((vpos == hlinfo->mouse_face_beg_row
29847 && hpos <= hlinfo->mouse_face_beg_col)
29848 || (vpos == hlinfo->mouse_face_end_row
29849 && hpos > hlinfo->mouse_face_end_col))
29850 return true;
29852 return false;
29856 /* EXPORT:
29857 True if physical cursor of window W is within mouse face. */
29859 bool
29860 cursor_in_mouse_face_p (struct window *w)
29862 int hpos = w->phys_cursor.hpos;
29863 int vpos = w->phys_cursor.vpos;
29864 struct glyph_row *row = MATRIX_ROW (w->current_matrix, vpos);
29866 /* When the window is hscrolled, cursor hpos can legitimately be out
29867 of bounds, but we draw the cursor at the corresponding window
29868 margin in that case. */
29869 if (!row->reversed_p && hpos < 0)
29870 hpos = 0;
29871 if (row->reversed_p && hpos >= row->used[TEXT_AREA])
29872 hpos = row->used[TEXT_AREA] - 1;
29874 return coords_in_mouse_face_p (w, hpos, vpos);
29879 /* Find the glyph rows START_ROW and END_ROW of window W that display
29880 characters between buffer positions START_CHARPOS and END_CHARPOS
29881 (excluding END_CHARPOS). DISP_STRING is a display string that
29882 covers these buffer positions. This is similar to
29883 row_containing_pos, but is more accurate when bidi reordering makes
29884 buffer positions change non-linearly with glyph rows. */
29885 static void
29886 rows_from_pos_range (struct window *w,
29887 ptrdiff_t start_charpos, ptrdiff_t end_charpos,
29888 Lisp_Object disp_string,
29889 struct glyph_row **start, struct glyph_row **end)
29891 struct glyph_row *first = MATRIX_FIRST_TEXT_ROW (w->current_matrix);
29892 int last_y = window_text_bottom_y (w);
29893 struct glyph_row *row;
29895 *start = NULL;
29896 *end = NULL;
29898 while (!first->enabled_p
29899 && first < MATRIX_BOTTOM_TEXT_ROW (w->current_matrix, w))
29900 first++;
29902 /* Find the START row. */
29903 for (row = first;
29904 row->enabled_p && MATRIX_ROW_BOTTOM_Y (row) <= last_y;
29905 row++)
29907 /* A row can potentially be the START row if the range of the
29908 characters it displays intersects the range
29909 [START_CHARPOS..END_CHARPOS). */
29910 if (! ((start_charpos < MATRIX_ROW_START_CHARPOS (row)
29911 && end_charpos < MATRIX_ROW_START_CHARPOS (row))
29912 /* See the commentary in row_containing_pos, for the
29913 explanation of the complicated way to check whether
29914 some position is beyond the end of the characters
29915 displayed by a row. */
29916 || ((start_charpos > MATRIX_ROW_END_CHARPOS (row)
29917 || (start_charpos == MATRIX_ROW_END_CHARPOS (row)
29918 && !row->ends_at_zv_p
29919 && !MATRIX_ROW_ENDS_IN_MIDDLE_OF_CHAR_P (row)))
29920 && (end_charpos > MATRIX_ROW_END_CHARPOS (row)
29921 || (end_charpos == MATRIX_ROW_END_CHARPOS (row)
29922 && !row->ends_at_zv_p
29923 && !MATRIX_ROW_ENDS_IN_MIDDLE_OF_CHAR_P (row))))))
29925 /* Found a candidate row. Now make sure at least one of the
29926 glyphs it displays has a charpos from the range
29927 [START_CHARPOS..END_CHARPOS).
29929 This is not obvious because bidi reordering could make
29930 buffer positions of a row be 1,2,3,102,101,100, and if we
29931 want to highlight characters in [50..60), we don't want
29932 this row, even though [50..60) does intersect [1..103),
29933 the range of character positions given by the row's start
29934 and end positions. */
29935 struct glyph *g = row->glyphs[TEXT_AREA];
29936 struct glyph *e = g + row->used[TEXT_AREA];
29938 while (g < e)
29940 if (((BUFFERP (g->object) || NILP (g->object))
29941 && start_charpos <= g->charpos && g->charpos < end_charpos)
29942 /* A glyph that comes from DISP_STRING is by
29943 definition to be highlighted. */
29944 || EQ (g->object, disp_string))
29945 *start = row;
29946 g++;
29948 if (*start)
29949 break;
29953 /* Find the END row. */
29954 if (!*start
29955 /* If the last row is partially visible, start looking for END
29956 from that row, instead of starting from FIRST. */
29957 && !(row->enabled_p
29958 && row->y < last_y && MATRIX_ROW_BOTTOM_Y (row) > last_y))
29959 row = first;
29960 for ( ; row->enabled_p && MATRIX_ROW_BOTTOM_Y (row) <= last_y; row++)
29962 struct glyph_row *next = row + 1;
29963 ptrdiff_t next_start = MATRIX_ROW_START_CHARPOS (next);
29965 if (!next->enabled_p
29966 || next >= MATRIX_BOTTOM_TEXT_ROW (w->current_matrix, w)
29967 /* The first row >= START whose range of displayed characters
29968 does NOT intersect the range [START_CHARPOS..END_CHARPOS]
29969 is the row END + 1. */
29970 || (start_charpos < next_start
29971 && end_charpos < next_start)
29972 || ((start_charpos > MATRIX_ROW_END_CHARPOS (next)
29973 || (start_charpos == MATRIX_ROW_END_CHARPOS (next)
29974 && !next->ends_at_zv_p
29975 && !MATRIX_ROW_ENDS_IN_MIDDLE_OF_CHAR_P (next)))
29976 && (end_charpos > MATRIX_ROW_END_CHARPOS (next)
29977 || (end_charpos == MATRIX_ROW_END_CHARPOS (next)
29978 && !next->ends_at_zv_p
29979 && !MATRIX_ROW_ENDS_IN_MIDDLE_OF_CHAR_P (next)))))
29981 *end = row;
29982 break;
29984 else
29986 /* If the next row's edges intersect [START_CHARPOS..END_CHARPOS],
29987 but none of the characters it displays are in the range, it is
29988 also END + 1. */
29989 struct glyph *g = next->glyphs[TEXT_AREA];
29990 struct glyph *s = g;
29991 struct glyph *e = g + next->used[TEXT_AREA];
29993 while (g < e)
29995 if (((BUFFERP (g->object) || NILP (g->object))
29996 && ((start_charpos <= g->charpos && g->charpos < end_charpos)
29997 /* If the buffer position of the first glyph in
29998 the row is equal to END_CHARPOS, it means
29999 the last character to be highlighted is the
30000 newline of ROW, and we must consider NEXT as
30001 END, not END+1. */
30002 || (((!next->reversed_p && g == s)
30003 || (next->reversed_p && g == e - 1))
30004 && (g->charpos == end_charpos
30005 /* Special case for when NEXT is an
30006 empty line at ZV. */
30007 || (g->charpos == -1
30008 && !row->ends_at_zv_p
30009 && next_start == end_charpos)))))
30010 /* A glyph that comes from DISP_STRING is by
30011 definition to be highlighted. */
30012 || EQ (g->object, disp_string))
30013 break;
30014 g++;
30016 if (g == e)
30018 *end = row;
30019 break;
30021 /* The first row that ends at ZV must be the last to be
30022 highlighted. */
30023 else if (next->ends_at_zv_p)
30025 *end = next;
30026 break;
30032 /* This function sets the mouse_face_* elements of HLINFO, assuming
30033 the mouse cursor is on a glyph with buffer charpos MOUSE_CHARPOS in
30034 window WINDOW. START_CHARPOS and END_CHARPOS are buffer positions
30035 for the overlay or run of text properties specifying the mouse
30036 face. BEFORE_STRING and AFTER_STRING, if non-nil, are a
30037 before-string and after-string that must also be highlighted.
30038 DISP_STRING, if non-nil, is a display string that may cover some
30039 or all of the highlighted text. */
30041 static void
30042 mouse_face_from_buffer_pos (Lisp_Object window,
30043 Mouse_HLInfo *hlinfo,
30044 ptrdiff_t mouse_charpos,
30045 ptrdiff_t start_charpos,
30046 ptrdiff_t end_charpos,
30047 Lisp_Object before_string,
30048 Lisp_Object after_string,
30049 Lisp_Object disp_string)
30051 struct window *w = XWINDOW (window);
30052 struct glyph_row *first = MATRIX_FIRST_TEXT_ROW (w->current_matrix);
30053 struct glyph_row *r1, *r2;
30054 struct glyph *glyph, *end;
30055 ptrdiff_t ignore, pos;
30056 int x;
30058 eassert (NILP (disp_string) || STRINGP (disp_string));
30059 eassert (NILP (before_string) || STRINGP (before_string));
30060 eassert (NILP (after_string) || STRINGP (after_string));
30062 /* Find the rows corresponding to START_CHARPOS and END_CHARPOS. */
30063 rows_from_pos_range (w, start_charpos, end_charpos, disp_string, &r1, &r2);
30064 if (r1 == NULL)
30065 r1 = MATRIX_ROW (w->current_matrix, w->window_end_vpos);
30066 /* If the before-string or display-string contains newlines,
30067 rows_from_pos_range skips to its last row. Move back. */
30068 if (!NILP (before_string) || !NILP (disp_string))
30070 struct glyph_row *prev;
30071 while ((prev = r1 - 1, prev >= first)
30072 && MATRIX_ROW_END_CHARPOS (prev) == start_charpos
30073 && prev->used[TEXT_AREA] > 0)
30075 struct glyph *beg = prev->glyphs[TEXT_AREA];
30076 glyph = beg + prev->used[TEXT_AREA];
30077 while (--glyph >= beg && NILP (glyph->object));
30078 if (glyph < beg
30079 || !(EQ (glyph->object, before_string)
30080 || EQ (glyph->object, disp_string)))
30081 break;
30082 r1 = prev;
30085 if (r2 == NULL)
30087 r2 = MATRIX_ROW (w->current_matrix, w->window_end_vpos);
30088 hlinfo->mouse_face_past_end = true;
30090 else if (!NILP (after_string))
30092 /* If the after-string has newlines, advance to its last row. */
30093 struct glyph_row *next;
30094 struct glyph_row *last
30095 = MATRIX_ROW (w->current_matrix, w->window_end_vpos);
30097 for (next = r2 + 1;
30098 next <= last
30099 && next->used[TEXT_AREA] > 0
30100 && EQ (next->glyphs[TEXT_AREA]->object, after_string);
30101 ++next)
30102 r2 = next;
30104 /* The rest of the display engine assumes that mouse_face_beg_row is
30105 either above mouse_face_end_row or identical to it. But with
30106 bidi-reordered continued lines, the row for START_CHARPOS could
30107 be below the row for END_CHARPOS. If so, swap the rows and store
30108 them in correct order. */
30109 if (r1->y > r2->y)
30111 struct glyph_row *tem = r2;
30113 r2 = r1;
30114 r1 = tem;
30117 hlinfo->mouse_face_beg_row = MATRIX_ROW_VPOS (r1, w->current_matrix);
30118 hlinfo->mouse_face_end_row = MATRIX_ROW_VPOS (r2, w->current_matrix);
30120 /* For a bidi-reordered row, the positions of BEFORE_STRING,
30121 AFTER_STRING, DISP_STRING, START_CHARPOS, and END_CHARPOS
30122 could be anywhere in the row and in any order. The strategy
30123 below is to find the leftmost and the rightmost glyph that
30124 belongs to either of these 3 strings, or whose position is
30125 between START_CHARPOS and END_CHARPOS, and highlight all the
30126 glyphs between those two. This may cover more than just the text
30127 between START_CHARPOS and END_CHARPOS if the range of characters
30128 strides the bidi level boundary, e.g. if the beginning is in R2L
30129 text while the end is in L2R text or vice versa. */
30130 if (!r1->reversed_p)
30132 /* This row is in a left to right paragraph. Scan it left to
30133 right. */
30134 glyph = r1->glyphs[TEXT_AREA];
30135 end = glyph + r1->used[TEXT_AREA];
30136 x = r1->x;
30138 /* Skip truncation glyphs at the start of the glyph row. */
30139 if (MATRIX_ROW_DISPLAYS_TEXT_P (r1))
30140 for (; glyph < end
30141 && NILP (glyph->object)
30142 && glyph->charpos < 0;
30143 ++glyph)
30144 x += glyph->pixel_width;
30146 /* Scan the glyph row, looking for BEFORE_STRING, AFTER_STRING,
30147 or DISP_STRING, and the first glyph from buffer whose
30148 position is between START_CHARPOS and END_CHARPOS. */
30149 for (; glyph < end
30150 && !NILP (glyph->object)
30151 && !EQ (glyph->object, disp_string)
30152 && !(BUFFERP (glyph->object)
30153 && (glyph->charpos >= start_charpos
30154 && glyph->charpos < end_charpos));
30155 ++glyph)
30157 /* BEFORE_STRING or AFTER_STRING are only relevant if they
30158 are present at buffer positions between START_CHARPOS and
30159 END_CHARPOS, or if they come from an overlay. */
30160 if (EQ (glyph->object, before_string))
30162 pos = string_buffer_position (before_string,
30163 start_charpos);
30164 /* If pos == 0, it means before_string came from an
30165 overlay, not from a buffer position. */
30166 if (!pos || (pos >= start_charpos && pos < end_charpos))
30167 break;
30169 else if (EQ (glyph->object, after_string))
30171 pos = string_buffer_position (after_string, end_charpos);
30172 if (!pos || (pos >= start_charpos && pos < end_charpos))
30173 break;
30175 x += glyph->pixel_width;
30177 hlinfo->mouse_face_beg_x = x;
30178 hlinfo->mouse_face_beg_col = glyph - r1->glyphs[TEXT_AREA];
30180 else
30182 /* This row is in a right to left paragraph. Scan it right to
30183 left. */
30184 struct glyph *g;
30186 end = r1->glyphs[TEXT_AREA] - 1;
30187 glyph = end + r1->used[TEXT_AREA];
30189 /* Skip truncation glyphs at the start of the glyph row. */
30190 if (MATRIX_ROW_DISPLAYS_TEXT_P (r1))
30191 for (; glyph > end
30192 && NILP (glyph->object)
30193 && glyph->charpos < 0;
30194 --glyph)
30197 /* Scan the glyph row, looking for BEFORE_STRING, AFTER_STRING,
30198 or DISP_STRING, and the first glyph from buffer whose
30199 position is between START_CHARPOS and END_CHARPOS. */
30200 for (; glyph > end
30201 && !NILP (glyph->object)
30202 && !EQ (glyph->object, disp_string)
30203 && !(BUFFERP (glyph->object)
30204 && (glyph->charpos >= start_charpos
30205 && glyph->charpos < end_charpos));
30206 --glyph)
30208 /* BEFORE_STRING or AFTER_STRING are only relevant if they
30209 are present at buffer positions between START_CHARPOS and
30210 END_CHARPOS, or if they come from an overlay. */
30211 if (EQ (glyph->object, before_string))
30213 pos = string_buffer_position (before_string, start_charpos);
30214 /* If pos == 0, it means before_string came from an
30215 overlay, not from a buffer position. */
30216 if (!pos || (pos >= start_charpos && pos < end_charpos))
30217 break;
30219 else if (EQ (glyph->object, after_string))
30221 pos = string_buffer_position (after_string, end_charpos);
30222 if (!pos || (pos >= start_charpos && pos < end_charpos))
30223 break;
30227 glyph++; /* first glyph to the right of the highlighted area */
30228 for (g = r1->glyphs[TEXT_AREA], x = r1->x; g < glyph; g++)
30229 x += g->pixel_width;
30230 hlinfo->mouse_face_beg_x = x;
30231 hlinfo->mouse_face_beg_col = glyph - r1->glyphs[TEXT_AREA];
30234 /* If the highlight ends in a different row, compute GLYPH and END
30235 for the end row. Otherwise, reuse the values computed above for
30236 the row where the highlight begins. */
30237 if (r2 != r1)
30239 if (!r2->reversed_p)
30241 glyph = r2->glyphs[TEXT_AREA];
30242 end = glyph + r2->used[TEXT_AREA];
30243 x = r2->x;
30245 else
30247 end = r2->glyphs[TEXT_AREA] - 1;
30248 glyph = end + r2->used[TEXT_AREA];
30252 if (!r2->reversed_p)
30254 /* Skip truncation and continuation glyphs near the end of the
30255 row, and also blanks and stretch glyphs inserted by
30256 extend_face_to_end_of_line. */
30257 while (end > glyph
30258 && NILP ((end - 1)->object))
30259 --end;
30260 /* Scan the rest of the glyph row from the end, looking for the
30261 first glyph that comes from BEFORE_STRING, AFTER_STRING, or
30262 DISP_STRING, or whose position is between START_CHARPOS
30263 and END_CHARPOS */
30264 for (--end;
30265 end > glyph
30266 && !NILP (end->object)
30267 && !EQ (end->object, disp_string)
30268 && !(BUFFERP (end->object)
30269 && (end->charpos >= start_charpos
30270 && end->charpos < end_charpos));
30271 --end)
30273 /* BEFORE_STRING or AFTER_STRING are only relevant if they
30274 are present at buffer positions between START_CHARPOS and
30275 END_CHARPOS, or if they come from an overlay. */
30276 if (EQ (end->object, before_string))
30278 pos = string_buffer_position (before_string, start_charpos);
30279 if (!pos || (pos >= start_charpos && pos < end_charpos))
30280 break;
30282 else if (EQ (end->object, after_string))
30284 pos = string_buffer_position (after_string, end_charpos);
30285 if (!pos || (pos >= start_charpos && pos < end_charpos))
30286 break;
30289 /* Find the X coordinate of the last glyph to be highlighted. */
30290 for (; glyph <= end; ++glyph)
30291 x += glyph->pixel_width;
30293 hlinfo->mouse_face_end_x = x;
30294 hlinfo->mouse_face_end_col = glyph - r2->glyphs[TEXT_AREA];
30296 else
30298 /* Skip truncation and continuation glyphs near the end of the
30299 row, and also blanks and stretch glyphs inserted by
30300 extend_face_to_end_of_line. */
30301 x = r2->x;
30302 end++;
30303 while (end < glyph
30304 && NILP (end->object))
30306 x += end->pixel_width;
30307 ++end;
30309 /* Scan the rest of the glyph row from the end, looking for the
30310 first glyph that comes from BEFORE_STRING, AFTER_STRING, or
30311 DISP_STRING, or whose position is between START_CHARPOS
30312 and END_CHARPOS */
30313 for ( ;
30314 end < glyph
30315 && !NILP (end->object)
30316 && !EQ (end->object, disp_string)
30317 && !(BUFFERP (end->object)
30318 && (end->charpos >= start_charpos
30319 && end->charpos < end_charpos));
30320 ++end)
30322 /* BEFORE_STRING or AFTER_STRING are only relevant if they
30323 are present at buffer positions between START_CHARPOS and
30324 END_CHARPOS, or if they come from an overlay. */
30325 if (EQ (end->object, before_string))
30327 pos = string_buffer_position (before_string, start_charpos);
30328 if (!pos || (pos >= start_charpos && pos < end_charpos))
30329 break;
30331 else if (EQ (end->object, after_string))
30333 pos = string_buffer_position (after_string, end_charpos);
30334 if (!pos || (pos >= start_charpos && pos < end_charpos))
30335 break;
30337 x += end->pixel_width;
30339 /* If we exited the above loop because we arrived at the last
30340 glyph of the row, and its buffer position is still not in
30341 range, it means the last character in range is the preceding
30342 newline. Bump the end column and x values to get past the
30343 last glyph. */
30344 if (end == glyph
30345 && BUFFERP (end->object)
30346 && (end->charpos < start_charpos
30347 || end->charpos >= end_charpos))
30349 x += end->pixel_width;
30350 ++end;
30352 hlinfo->mouse_face_end_x = x;
30353 hlinfo->mouse_face_end_col = end - r2->glyphs[TEXT_AREA];
30356 hlinfo->mouse_face_window = window;
30357 hlinfo->mouse_face_face_id
30358 = face_at_buffer_position (w, mouse_charpos, &ignore,
30359 mouse_charpos + 1,
30360 !hlinfo->mouse_face_hidden, -1);
30361 show_mouse_face (hlinfo, DRAW_MOUSE_FACE);
30364 /* The following function is not used anymore (replaced with
30365 mouse_face_from_string_pos), but I leave it here for the time
30366 being, in case someone would. */
30368 #if false /* not used */
30370 /* Find the position of the glyph for position POS in OBJECT in
30371 window W's current matrix, and return in *X, *Y the pixel
30372 coordinates, and return in *HPOS, *VPOS the column/row of the glyph.
30374 RIGHT_P means return the position of the right edge of the glyph.
30375 !RIGHT_P means return the left edge position.
30377 If no glyph for POS exists in the matrix, return the position of
30378 the glyph with the next smaller position that is in the matrix, if
30379 RIGHT_P is false. If RIGHT_P, and no glyph for POS
30380 exists in the matrix, return the position of the glyph with the
30381 next larger position in OBJECT.
30383 Value is true if a glyph was found. */
30385 static bool
30386 fast_find_string_pos (struct window *w, ptrdiff_t pos, Lisp_Object object,
30387 int *hpos, int *vpos, int *x, int *y, bool right_p)
30389 int yb = window_text_bottom_y (w);
30390 struct glyph_row *r;
30391 struct glyph *best_glyph = NULL;
30392 struct glyph_row *best_row = NULL;
30393 int best_x = 0;
30395 for (r = MATRIX_FIRST_TEXT_ROW (w->current_matrix);
30396 r->enabled_p && r->y < yb;
30397 ++r)
30399 struct glyph *g = r->glyphs[TEXT_AREA];
30400 struct glyph *e = g + r->used[TEXT_AREA];
30401 int gx;
30403 for (gx = r->x; g < e; gx += g->pixel_width, ++g)
30404 if (EQ (g->object, object))
30406 if (g->charpos == pos)
30408 best_glyph = g;
30409 best_x = gx;
30410 best_row = r;
30411 goto found;
30413 else if (best_glyph == NULL
30414 || ((eabs (g->charpos - pos)
30415 < eabs (best_glyph->charpos - pos))
30416 && (right_p
30417 ? g->charpos < pos
30418 : g->charpos > pos)))
30420 best_glyph = g;
30421 best_x = gx;
30422 best_row = r;
30427 found:
30429 if (best_glyph)
30431 *x = best_x;
30432 *hpos = best_glyph - best_row->glyphs[TEXT_AREA];
30434 if (right_p)
30436 *x += best_glyph->pixel_width;
30437 ++*hpos;
30440 *y = best_row->y;
30441 *vpos = MATRIX_ROW_VPOS (best_row, w->current_matrix);
30444 return best_glyph != NULL;
30446 #endif /* not used */
30448 /* Find the positions of the first and the last glyphs in window W's
30449 current matrix that occlude positions [STARTPOS..ENDPOS) in OBJECT
30450 (assumed to be a string), and return in HLINFO's mouse_face_*
30451 members the pixel and column/row coordinates of those glyphs. */
30453 static void
30454 mouse_face_from_string_pos (struct window *w, Mouse_HLInfo *hlinfo,
30455 Lisp_Object object,
30456 ptrdiff_t startpos, ptrdiff_t endpos)
30458 int yb = window_text_bottom_y (w);
30459 struct glyph_row *r;
30460 struct glyph *g, *e;
30461 int gx;
30462 bool found = false;
30464 /* Find the glyph row with at least one position in the range
30465 [STARTPOS..ENDPOS), and the first glyph in that row whose
30466 position belongs to that range. */
30467 for (r = MATRIX_FIRST_TEXT_ROW (w->current_matrix);
30468 r->enabled_p && r->y < yb;
30469 ++r)
30471 if (!r->reversed_p)
30473 g = r->glyphs[TEXT_AREA];
30474 e = g + r->used[TEXT_AREA];
30475 for (gx = r->x; g < e; gx += g->pixel_width, ++g)
30476 if (EQ (g->object, object)
30477 && startpos <= g->charpos && g->charpos < endpos)
30479 hlinfo->mouse_face_beg_row
30480 = MATRIX_ROW_VPOS (r, w->current_matrix);
30481 hlinfo->mouse_face_beg_col = g - r->glyphs[TEXT_AREA];
30482 hlinfo->mouse_face_beg_x = gx;
30483 found = true;
30484 break;
30487 else
30489 struct glyph *g1;
30491 e = r->glyphs[TEXT_AREA];
30492 g = e + r->used[TEXT_AREA];
30493 for ( ; g > e; --g)
30494 if (EQ ((g-1)->object, object)
30495 && startpos <= (g-1)->charpos && (g-1)->charpos < endpos)
30497 hlinfo->mouse_face_beg_row
30498 = MATRIX_ROW_VPOS (r, w->current_matrix);
30499 hlinfo->mouse_face_beg_col = g - r->glyphs[TEXT_AREA];
30500 for (gx = r->x, g1 = r->glyphs[TEXT_AREA]; g1 < g; ++g1)
30501 gx += g1->pixel_width;
30502 hlinfo->mouse_face_beg_x = gx;
30503 found = true;
30504 break;
30507 if (found)
30508 break;
30511 if (!found)
30512 return;
30514 /* Starting with the next row, look for the first row which does NOT
30515 include any glyphs whose positions are in the range. */
30516 for (++r; r->enabled_p && r->y < yb; ++r)
30518 g = r->glyphs[TEXT_AREA];
30519 e = g + r->used[TEXT_AREA];
30520 found = false;
30521 for ( ; g < e; ++g)
30522 if (EQ (g->object, object)
30523 && startpos <= g->charpos && g->charpos < endpos)
30525 found = true;
30526 break;
30528 if (!found)
30529 break;
30532 /* The highlighted region ends on the previous row. */
30533 r--;
30535 /* Set the end row. */
30536 hlinfo->mouse_face_end_row = MATRIX_ROW_VPOS (r, w->current_matrix);
30538 /* Compute and set the end column and the end column's horizontal
30539 pixel coordinate. */
30540 if (!r->reversed_p)
30542 g = r->glyphs[TEXT_AREA];
30543 e = g + r->used[TEXT_AREA];
30544 for ( ; e > g; --e)
30545 if (EQ ((e-1)->object, object)
30546 && startpos <= (e-1)->charpos && (e-1)->charpos < endpos)
30547 break;
30548 hlinfo->mouse_face_end_col = e - g;
30550 for (gx = r->x; g < e; ++g)
30551 gx += g->pixel_width;
30552 hlinfo->mouse_face_end_x = gx;
30554 else
30556 e = r->glyphs[TEXT_AREA];
30557 g = e + r->used[TEXT_AREA];
30558 for (gx = r->x ; e < g; ++e)
30560 if (EQ (e->object, object)
30561 && startpos <= e->charpos && e->charpos < endpos)
30562 break;
30563 gx += e->pixel_width;
30565 hlinfo->mouse_face_end_col = e - r->glyphs[TEXT_AREA];
30566 hlinfo->mouse_face_end_x = gx;
30570 #ifdef HAVE_WINDOW_SYSTEM
30572 /* See if position X, Y is within a hot-spot of an image. */
30574 static bool
30575 on_hot_spot_p (Lisp_Object hot_spot, int x, int y)
30577 if (!CONSP (hot_spot))
30578 return false;
30580 if (EQ (XCAR (hot_spot), Qrect))
30582 /* CDR is (Top-Left . Bottom-Right) = ((x0 . y0) . (x1 . y1)) */
30583 Lisp_Object rect = XCDR (hot_spot);
30584 Lisp_Object tem;
30585 if (!CONSP (rect))
30586 return false;
30587 if (!CONSP (XCAR (rect)))
30588 return false;
30589 if (!CONSP (XCDR (rect)))
30590 return false;
30591 if (!(tem = XCAR (XCAR (rect)), INTEGERP (tem) && x >= XINT (tem)))
30592 return false;
30593 if (!(tem = XCDR (XCAR (rect)), INTEGERP (tem) && y >= XINT (tem)))
30594 return false;
30595 if (!(tem = XCAR (XCDR (rect)), INTEGERP (tem) && x <= XINT (tem)))
30596 return false;
30597 if (!(tem = XCDR (XCDR (rect)), INTEGERP (tem) && y <= XINT (tem)))
30598 return false;
30599 return true;
30601 else if (EQ (XCAR (hot_spot), Qcircle))
30603 /* CDR is (Center . Radius) = ((x0 . y0) . r) */
30604 Lisp_Object circ = XCDR (hot_spot);
30605 Lisp_Object lr, lx0, ly0;
30606 if (CONSP (circ)
30607 && CONSP (XCAR (circ))
30608 && (lr = XCDR (circ), NUMBERP (lr))
30609 && (lx0 = XCAR (XCAR (circ)), INTEGERP (lx0))
30610 && (ly0 = XCDR (XCAR (circ)), INTEGERP (ly0)))
30612 double r = XFLOATINT (lr);
30613 double dx = XINT (lx0) - x;
30614 double dy = XINT (ly0) - y;
30615 return (dx * dx + dy * dy <= r * r);
30618 else if (EQ (XCAR (hot_spot), Qpoly))
30620 /* CDR is [x0 y0 x1 y1 x2 y2 ...x(n-1) y(n-1)] */
30621 if (VECTORP (XCDR (hot_spot)))
30623 struct Lisp_Vector *v = XVECTOR (XCDR (hot_spot));
30624 Lisp_Object *poly = v->contents;
30625 ptrdiff_t n = v->header.size;
30626 ptrdiff_t i;
30627 bool inside = false;
30628 Lisp_Object lx, ly;
30629 int x0, y0;
30631 /* Need an even number of coordinates, and at least 3 edges. */
30632 if (n < 6 || n & 1)
30633 return false;
30635 /* Count edge segments intersecting line from (X,Y) to (X,infinity).
30636 If count is odd, we are inside polygon. Pixels on edges
30637 may or may not be included depending on actual geometry of the
30638 polygon. */
30639 if ((lx = poly[n-2], !INTEGERP (lx))
30640 || (ly = poly[n-1], !INTEGERP (lx)))
30641 return false;
30642 x0 = XINT (lx), y0 = XINT (ly);
30643 for (i = 0; i < n; i += 2)
30645 int x1 = x0, y1 = y0;
30646 if ((lx = poly[i], !INTEGERP (lx))
30647 || (ly = poly[i+1], !INTEGERP (ly)))
30648 return false;
30649 x0 = XINT (lx), y0 = XINT (ly);
30651 /* Does this segment cross the X line? */
30652 if (x0 >= x)
30654 if (x1 >= x)
30655 continue;
30657 else if (x1 < x)
30658 continue;
30659 if (y > y0 && y > y1)
30660 continue;
30661 if (y < y0 + ((y1 - y0) * (x - x0)) / (x1 - x0))
30662 inside = !inside;
30664 return inside;
30667 return false;
30670 Lisp_Object
30671 find_hot_spot (Lisp_Object map, int x, int y)
30673 while (CONSP (map))
30675 if (CONSP (XCAR (map))
30676 && on_hot_spot_p (XCAR (XCAR (map)), x, y))
30677 return XCAR (map);
30678 map = XCDR (map);
30681 return Qnil;
30684 DEFUN ("lookup-image-map", Flookup_image_map, Slookup_image_map,
30685 3, 3, 0,
30686 doc: /* Lookup in image map MAP coordinates X and Y.
30687 An image map is an alist where each element has the format (AREA ID PLIST).
30688 An AREA is specified as either a rectangle, a circle, or a polygon:
30689 A rectangle is a cons (rect . ((x0 . y0) . (x1 . y1))) specifying the
30690 pixel coordinates of the upper left and bottom right corners.
30691 A circle is a cons (circle . ((x0 . y0) . r)) specifying the center
30692 and the radius of the circle; r may be a float or integer.
30693 A polygon is a cons (poly . [x0 y0 x1 y1 ...]) where each pair in the
30694 vector describes one corner in the polygon.
30695 Returns the alist element for the first matching AREA in MAP. */)
30696 (Lisp_Object map, Lisp_Object x, Lisp_Object y)
30698 if (NILP (map))
30699 return Qnil;
30701 CHECK_NUMBER (x);
30702 CHECK_NUMBER (y);
30704 return find_hot_spot (map,
30705 clip_to_bounds (INT_MIN, XINT (x), INT_MAX),
30706 clip_to_bounds (INT_MIN, XINT (y), INT_MAX));
30708 #endif /* HAVE_WINDOW_SYSTEM */
30711 /* Display frame CURSOR, optionally using shape defined by POINTER. */
30712 static void
30713 define_frame_cursor1 (struct frame *f, Cursor cursor, Lisp_Object pointer)
30715 #ifdef HAVE_WINDOW_SYSTEM
30716 if (!FRAME_WINDOW_P (f))
30717 return;
30719 /* Do not change cursor shape while dragging mouse. */
30720 if (EQ (do_mouse_tracking, Qdragging))
30721 return;
30723 if (!NILP (pointer))
30725 if (EQ (pointer, Qarrow))
30726 cursor = FRAME_X_OUTPUT (f)->nontext_cursor;
30727 else if (EQ (pointer, Qhand))
30728 cursor = FRAME_X_OUTPUT (f)->hand_cursor;
30729 else if (EQ (pointer, Qtext))
30730 cursor = FRAME_X_OUTPUT (f)->text_cursor;
30731 else if (EQ (pointer, intern ("hdrag")))
30732 cursor = FRAME_X_OUTPUT (f)->horizontal_drag_cursor;
30733 else if (EQ (pointer, intern ("nhdrag")))
30734 cursor = FRAME_X_OUTPUT (f)->vertical_drag_cursor;
30735 # ifdef HAVE_X_WINDOWS
30736 else if (EQ (pointer, intern ("vdrag")))
30737 cursor = FRAME_DISPLAY_INFO (f)->vertical_scroll_bar_cursor;
30738 # endif
30739 else if (EQ (pointer, intern ("hourglass")))
30740 cursor = FRAME_X_OUTPUT (f)->hourglass_cursor;
30741 else if (EQ (pointer, Qmodeline))
30742 cursor = FRAME_X_OUTPUT (f)->modeline_cursor;
30743 else
30744 cursor = FRAME_X_OUTPUT (f)->nontext_cursor;
30747 if (cursor != No_Cursor)
30748 FRAME_RIF (f)->define_frame_cursor (f, cursor);
30749 #endif
30752 /* Take proper action when mouse has moved to the mode or header line
30753 or marginal area AREA of window W, x-position X and y-position Y.
30754 X is relative to the start of the text display area of W, so the
30755 width of bitmap areas and scroll bars must be subtracted to get a
30756 position relative to the start of the mode line. */
30758 static void
30759 note_mode_line_or_margin_highlight (Lisp_Object window, int x, int y,
30760 enum window_part area)
30762 struct window *w = XWINDOW (window);
30763 struct frame *f = XFRAME (w->frame);
30764 Mouse_HLInfo *hlinfo = MOUSE_HL_INFO (f);
30765 Cursor cursor = No_Cursor;
30766 Lisp_Object pointer = Qnil;
30767 int dx, dy, width, height;
30768 ptrdiff_t charpos;
30769 Lisp_Object string, object = Qnil;
30770 Lisp_Object pos UNINIT;
30771 Lisp_Object mouse_face;
30772 int original_x_pixel = x;
30773 struct glyph * glyph = NULL, * row_start_glyph = NULL;
30774 struct glyph_row *row UNINIT;
30776 if (area == ON_MODE_LINE || area == ON_HEADER_LINE)
30778 int x0;
30779 struct glyph *end;
30781 /* Kludge alert: mode_line_string takes X/Y in pixels, but
30782 returns them in row/column units! */
30783 string = mode_line_string (w, area, &x, &y, &charpos,
30784 &object, &dx, &dy, &width, &height);
30786 row = (area == ON_MODE_LINE
30787 ? MATRIX_MODE_LINE_ROW (w->current_matrix)
30788 : MATRIX_HEADER_LINE_ROW (w->current_matrix));
30790 /* Find the glyph under the mouse pointer. */
30791 if (row->mode_line_p && row->enabled_p)
30793 glyph = row_start_glyph = row->glyphs[TEXT_AREA];
30794 end = glyph + row->used[TEXT_AREA];
30796 for (x0 = original_x_pixel;
30797 glyph < end && x0 >= glyph->pixel_width;
30798 ++glyph)
30799 x0 -= glyph->pixel_width;
30801 if (glyph >= end)
30802 glyph = NULL;
30805 else
30807 x -= WINDOW_LEFT_SCROLL_BAR_AREA_WIDTH (w);
30808 /* Kludge alert: marginal_area_string takes X/Y in pixels, but
30809 returns them in row/column units! */
30810 string = marginal_area_string (w, area, &x, &y, &charpos,
30811 &object, &dx, &dy, &width, &height);
30814 Lisp_Object help = Qnil;
30816 #ifdef HAVE_WINDOW_SYSTEM
30817 if (IMAGEP (object))
30819 Lisp_Object image_map, hotspot;
30820 if ((image_map = Fplist_get (XCDR (object), QCmap),
30821 !NILP (image_map))
30822 && (hotspot = find_hot_spot (image_map, dx, dy),
30823 CONSP (hotspot))
30824 && (hotspot = XCDR (hotspot), CONSP (hotspot)))
30826 Lisp_Object plist;
30828 /* Could check XCAR (hotspot) to see if we enter/leave this hot-spot.
30829 If so, we could look for mouse-enter, mouse-leave
30830 properties in PLIST (and do something...). */
30831 hotspot = XCDR (hotspot);
30832 if (CONSP (hotspot)
30833 && (plist = XCAR (hotspot), CONSP (plist)))
30835 pointer = Fplist_get (plist, Qpointer);
30836 if (NILP (pointer))
30837 pointer = Qhand;
30838 help = Fplist_get (plist, Qhelp_echo);
30839 if (!NILP (help))
30841 help_echo_string = help;
30842 XSETWINDOW (help_echo_window, w);
30843 help_echo_object = w->contents;
30844 help_echo_pos = charpos;
30848 if (NILP (pointer))
30849 pointer = Fplist_get (XCDR (object), QCpointer);
30851 #endif /* HAVE_WINDOW_SYSTEM */
30853 if (STRINGP (string))
30854 pos = make_number (charpos);
30856 /* Set the help text and mouse pointer. If the mouse is on a part
30857 of the mode line without any text (e.g. past the right edge of
30858 the mode line text), use that windows's mode line help echo if it
30859 has been set. */
30860 if (STRINGP (string) || area == ON_MODE_LINE)
30862 /* Arrange to display the help by setting the global variables
30863 help_echo_string, help_echo_object, and help_echo_pos. */
30864 if (NILP (help))
30866 if (STRINGP (string))
30867 help = Fget_text_property (pos, Qhelp_echo, string);
30869 if (!NILP (help))
30871 help_echo_string = help;
30872 XSETWINDOW (help_echo_window, w);
30873 help_echo_object = string;
30874 help_echo_pos = charpos;
30876 else if (area == ON_MODE_LINE
30877 && !NILP (w->mode_line_help_echo))
30879 help_echo_string = w->mode_line_help_echo;
30880 XSETWINDOW (help_echo_window, w);
30881 help_echo_object = Qnil;
30882 help_echo_pos = -1;
30886 #ifdef HAVE_WINDOW_SYSTEM
30887 /* Change the mouse pointer according to what is under it. */
30888 if (FRAME_WINDOW_P (f))
30890 bool draggable = (! WINDOW_BOTTOMMOST_P (w)
30891 || minibuf_level
30892 || NILP (Vresize_mini_windows));
30894 if (STRINGP (string))
30896 cursor = FRAME_X_OUTPUT (f)->nontext_cursor;
30898 if (NILP (pointer))
30899 pointer = Fget_text_property (pos, Qpointer, string);
30901 /* Change the mouse pointer according to what is under X/Y. */
30902 if (NILP (pointer)
30903 && (area == ON_MODE_LINE || area == ON_HEADER_LINE))
30905 Lisp_Object map;
30907 map = Fget_text_property (pos, Qlocal_map, string);
30908 if (!KEYMAPP (map))
30909 map = Fget_text_property (pos, Qkeymap, string);
30910 if (!KEYMAPP (map) && draggable && area == ON_MODE_LINE)
30911 cursor = FRAME_X_OUTPUT (f)->vertical_drag_cursor;
30914 else if (draggable && area == ON_MODE_LINE)
30915 cursor = FRAME_X_OUTPUT (f)->vertical_drag_cursor;
30916 else
30917 cursor = FRAME_X_OUTPUT (f)->nontext_cursor;
30919 #endif
30922 /* Change the mouse face according to what is under X/Y. */
30923 bool mouse_face_shown = false;
30925 if (STRINGP (string))
30927 mouse_face = Fget_text_property (pos, Qmouse_face, string);
30928 if (!NILP (Vmouse_highlight) && !NILP (mouse_face)
30929 && ((area == ON_MODE_LINE) || (area == ON_HEADER_LINE))
30930 && glyph)
30932 Lisp_Object b, e;
30934 struct glyph * tmp_glyph;
30936 int gpos;
30937 int gseq_length;
30938 int total_pixel_width;
30939 ptrdiff_t begpos, endpos, ignore;
30941 int vpos, hpos;
30943 b = Fprevious_single_property_change (make_number (charpos + 1),
30944 Qmouse_face, string, Qnil);
30945 if (NILP (b))
30946 begpos = 0;
30947 else
30948 begpos = XINT (b);
30950 e = Fnext_single_property_change (pos, Qmouse_face, string, Qnil);
30951 if (NILP (e))
30952 endpos = SCHARS (string);
30953 else
30954 endpos = XINT (e);
30956 /* Calculate the glyph position GPOS of GLYPH in the
30957 displayed string, relative to the beginning of the
30958 highlighted part of the string.
30960 Note: GPOS is different from CHARPOS. CHARPOS is the
30961 position of GLYPH in the internal string object. A mode
30962 line string format has structures which are converted to
30963 a flattened string by the Emacs Lisp interpreter. The
30964 internal string is an element of those structures. The
30965 displayed string is the flattened string. */
30966 tmp_glyph = row_start_glyph;
30967 while (tmp_glyph < glyph
30968 && (!(EQ (tmp_glyph->object, glyph->object)
30969 && begpos <= tmp_glyph->charpos
30970 && tmp_glyph->charpos < endpos)))
30971 tmp_glyph++;
30972 gpos = glyph - tmp_glyph;
30974 /* Calculate the length GSEQ_LENGTH of the glyph sequence of
30975 the highlighted part of the displayed string to which
30976 GLYPH belongs. Note: GSEQ_LENGTH is different from
30977 SCHARS (STRING), because the latter returns the length of
30978 the internal string. */
30979 for (tmp_glyph = row->glyphs[TEXT_AREA] + row->used[TEXT_AREA] - 1;
30980 tmp_glyph > glyph
30981 && (!(EQ (tmp_glyph->object, glyph->object)
30982 && begpos <= tmp_glyph->charpos
30983 && tmp_glyph->charpos < endpos));
30984 tmp_glyph--)
30986 gseq_length = gpos + (tmp_glyph - glyph) + 1;
30988 /* Calculate the total pixel width of all the glyphs between
30989 the beginning of the highlighted area and GLYPH. */
30990 total_pixel_width = 0;
30991 for (tmp_glyph = glyph - gpos; tmp_glyph != glyph; tmp_glyph++)
30992 total_pixel_width += tmp_glyph->pixel_width;
30994 /* Pre calculation of re-rendering position. Note: X is in
30995 column units here, after the call to mode_line_string or
30996 marginal_area_string. */
30997 hpos = x - gpos;
30998 vpos = (area == ON_MODE_LINE
30999 ? (w->current_matrix)->nrows - 1
31000 : 0);
31002 /* If GLYPH's position is included in the region that is
31003 already drawn in mouse face, we have nothing to do. */
31004 if ( EQ (window, hlinfo->mouse_face_window)
31005 && (!row->reversed_p
31006 ? (hlinfo->mouse_face_beg_col <= hpos
31007 && hpos < hlinfo->mouse_face_end_col)
31008 /* In R2L rows we swap BEG and END, see below. */
31009 : (hlinfo->mouse_face_end_col <= hpos
31010 && hpos < hlinfo->mouse_face_beg_col))
31011 && hlinfo->mouse_face_beg_row == vpos )
31012 return;
31014 if (clear_mouse_face (hlinfo))
31015 cursor = No_Cursor;
31017 if (!row->reversed_p)
31019 hlinfo->mouse_face_beg_col = hpos;
31020 hlinfo->mouse_face_beg_x = original_x_pixel
31021 - (total_pixel_width + dx);
31022 hlinfo->mouse_face_end_col = hpos + gseq_length;
31023 hlinfo->mouse_face_end_x = 0;
31025 else
31027 /* In R2L rows, show_mouse_face expects BEG and END
31028 coordinates to be swapped. */
31029 hlinfo->mouse_face_end_col = hpos;
31030 hlinfo->mouse_face_end_x = original_x_pixel
31031 - (total_pixel_width + dx);
31032 hlinfo->mouse_face_beg_col = hpos + gseq_length;
31033 hlinfo->mouse_face_beg_x = 0;
31036 hlinfo->mouse_face_beg_row = vpos;
31037 hlinfo->mouse_face_end_row = hlinfo->mouse_face_beg_row;
31038 hlinfo->mouse_face_past_end = false;
31039 hlinfo->mouse_face_window = window;
31041 hlinfo->mouse_face_face_id = face_at_string_position (w, string,
31042 charpos,
31043 0, &ignore,
31044 glyph->face_id,
31045 true);
31046 show_mouse_face (hlinfo, DRAW_MOUSE_FACE);
31047 mouse_face_shown = true;
31049 if (NILP (pointer))
31050 pointer = Qhand;
31054 /* If mouse-face doesn't need to be shown, clear any existing
31055 mouse-face. */
31056 if ((area == ON_MODE_LINE || area == ON_HEADER_LINE) && !mouse_face_shown)
31057 clear_mouse_face (hlinfo);
31059 define_frame_cursor1 (f, cursor, pointer);
31063 /* EXPORT:
31064 Take proper action when the mouse has moved to position X, Y on
31065 frame F with regards to highlighting portions of display that have
31066 mouse-face properties. Also de-highlight portions of display where
31067 the mouse was before, set the mouse pointer shape as appropriate
31068 for the mouse coordinates, and activate help echo (tooltips).
31069 X and Y can be negative or out of range. */
31071 void
31072 note_mouse_highlight (struct frame *f, int x, int y)
31074 Mouse_HLInfo *hlinfo = MOUSE_HL_INFO (f);
31075 enum window_part part = ON_NOTHING;
31076 Lisp_Object window;
31077 struct window *w;
31078 Cursor cursor = No_Cursor;
31079 Lisp_Object pointer = Qnil; /* Takes precedence over cursor! */
31080 struct buffer *b;
31082 /* When a menu is active, don't highlight because this looks odd. */
31083 #if defined (USE_X_TOOLKIT) || defined (USE_GTK) || defined (HAVE_NS) || defined (MSDOS)
31084 if (popup_activated ())
31085 return;
31086 #endif
31088 if (!f->glyphs_initialized_p
31089 || f->pointer_invisible)
31090 return;
31092 hlinfo->mouse_face_mouse_x = x;
31093 hlinfo->mouse_face_mouse_y = y;
31094 hlinfo->mouse_face_mouse_frame = f;
31096 if (hlinfo->mouse_face_defer)
31097 return;
31099 /* Which window is that in? */
31100 window = window_from_coordinates (f, x, y, &part, true);
31102 /* If displaying active text in another window, clear that. */
31103 if (! EQ (window, hlinfo->mouse_face_window)
31104 /* Also clear if we move out of text area in same window. */
31105 || (!NILP (hlinfo->mouse_face_window)
31106 && !NILP (window)
31107 && part != ON_TEXT
31108 && part != ON_MODE_LINE
31109 && part != ON_HEADER_LINE))
31110 clear_mouse_face (hlinfo);
31112 /* Reset help_echo_string. It will get recomputed below. */
31113 help_echo_string = Qnil;
31115 #ifdef HAVE_WINDOW_SYSTEM
31116 /* If the cursor is on the internal border of FRAME and FRAME's
31117 internal border is draggable, provide some visual feedback. */
31118 if (FRAME_INTERNAL_BORDER_WIDTH (f) > 0
31119 && !NILP (get_frame_param (f, Qdrag_internal_border)))
31121 enum internal_border_part part = frame_internal_border_part (f, x, y);
31123 switch (part)
31125 case INTERNAL_BORDER_NONE:
31126 if (cursor != FRAME_X_OUTPUT (f)->nontext_cursor)
31127 /* Reset cursor. */
31128 cursor = FRAME_X_OUTPUT (f)->nontext_cursor;
31129 break;
31130 case INTERNAL_BORDER_LEFT_EDGE:
31131 cursor = FRAME_X_OUTPUT (f)->left_edge_cursor;
31132 break;
31133 case INTERNAL_BORDER_TOP_LEFT_CORNER:
31134 cursor = FRAME_X_OUTPUT (f)->top_left_corner_cursor;
31135 break;
31136 case INTERNAL_BORDER_TOP_EDGE:
31137 cursor = FRAME_X_OUTPUT (f)->top_edge_cursor;
31138 break;
31139 case INTERNAL_BORDER_TOP_RIGHT_CORNER:
31140 cursor = FRAME_X_OUTPUT (f)->top_right_corner_cursor;
31141 break;
31142 case INTERNAL_BORDER_RIGHT_EDGE:
31143 cursor = FRAME_X_OUTPUT (f)->right_edge_cursor;
31144 break;
31145 case INTERNAL_BORDER_BOTTOM_RIGHT_CORNER:
31146 cursor = FRAME_X_OUTPUT (f)->bottom_right_corner_cursor;
31147 break;
31148 case INTERNAL_BORDER_BOTTOM_EDGE:
31149 cursor = FRAME_X_OUTPUT (f)->bottom_edge_cursor;
31150 break;
31151 case INTERNAL_BORDER_BOTTOM_LEFT_CORNER:
31152 cursor = FRAME_X_OUTPUT (f)->bottom_left_corner_cursor;
31153 break;
31154 default:
31155 /* This should not happen. */
31156 if (cursor != FRAME_X_OUTPUT (f)->nontext_cursor)
31157 cursor = FRAME_X_OUTPUT (f)->nontext_cursor;
31160 if (cursor != FRAME_X_OUTPUT (f)->nontext_cursor)
31162 /* Do we really want a help echo here? */
31163 help_echo_string = build_string ("drag-mouse-1: resize frame");
31164 goto set_cursor;
31167 #endif /* HAVE_WINDOW_SYSTEM */
31169 /* Not on a window -> return. */
31170 if (!WINDOWP (window))
31171 return;
31173 /* Convert to window-relative pixel coordinates. */
31174 w = XWINDOW (window);
31175 frame_to_window_pixel_xy (w, &x, &y);
31177 #if defined (HAVE_WINDOW_SYSTEM) && ! defined (USE_GTK) && ! defined (HAVE_NS)
31178 /* Handle tool-bar window differently since it doesn't display a
31179 buffer. */
31180 if (EQ (window, f->tool_bar_window))
31182 note_tool_bar_highlight (f, x, y);
31183 return;
31185 #endif
31187 /* Mouse is on the mode, header line or margin? */
31188 if (part == ON_MODE_LINE || part == ON_HEADER_LINE
31189 || part == ON_LEFT_MARGIN || part == ON_RIGHT_MARGIN)
31191 note_mode_line_or_margin_highlight (window, x, y, part);
31193 #ifdef HAVE_WINDOW_SYSTEM
31194 if (part == ON_LEFT_MARGIN || part == ON_RIGHT_MARGIN)
31196 cursor = FRAME_X_OUTPUT (f)->nontext_cursor;
31197 /* Show non-text cursor (Bug#16647). */
31198 goto set_cursor;
31200 else
31201 #endif
31202 return;
31205 #ifdef HAVE_WINDOW_SYSTEM
31206 if (part == ON_VERTICAL_BORDER)
31208 cursor = FRAME_X_OUTPUT (f)->horizontal_drag_cursor;
31209 help_echo_string = build_string ("drag-mouse-1: resize");
31210 goto set_cursor;
31212 else if (part == ON_RIGHT_DIVIDER)
31214 cursor = FRAME_X_OUTPUT (f)->horizontal_drag_cursor;
31215 help_echo_string = build_string ("drag-mouse-1: resize");
31216 goto set_cursor;
31218 else if (part == ON_BOTTOM_DIVIDER)
31219 if (! WINDOW_BOTTOMMOST_P (w)
31220 || minibuf_level
31221 || NILP (Vresize_mini_windows))
31223 cursor = FRAME_X_OUTPUT (f)->vertical_drag_cursor;
31224 help_echo_string = build_string ("drag-mouse-1: resize");
31225 goto set_cursor;
31227 else
31228 cursor = FRAME_X_OUTPUT (f)->nontext_cursor;
31229 else if (part == ON_LEFT_FRINGE || part == ON_RIGHT_FRINGE
31230 || part == ON_VERTICAL_SCROLL_BAR
31231 || part == ON_HORIZONTAL_SCROLL_BAR)
31232 cursor = FRAME_X_OUTPUT (f)->nontext_cursor;
31233 else
31234 cursor = FRAME_X_OUTPUT (f)->text_cursor;
31235 #endif
31237 /* Are we in a window whose display is up to date?
31238 And verify the buffer's text has not changed. */
31239 b = XBUFFER (w->contents);
31240 if (part == ON_TEXT && w->window_end_valid && !window_outdated (w))
31242 int hpos, vpos, dx, dy, area = LAST_AREA;
31243 ptrdiff_t pos;
31244 struct glyph *glyph;
31245 Lisp_Object object;
31246 Lisp_Object mouse_face = Qnil, position;
31247 Lisp_Object *overlay_vec = NULL;
31248 ptrdiff_t i, noverlays;
31249 struct buffer *obuf;
31250 ptrdiff_t obegv, ozv;
31251 bool same_region;
31253 /* Find the glyph under X/Y. */
31254 glyph = x_y_to_hpos_vpos (w, x, y, &hpos, &vpos, &dx, &dy, &area);
31256 #ifdef HAVE_WINDOW_SYSTEM
31257 /* Look for :pointer property on image. */
31258 if (glyph != NULL && glyph->type == IMAGE_GLYPH)
31260 struct image *img = IMAGE_OPT_FROM_ID (f, glyph->u.img_id);
31261 if (img != NULL && IMAGEP (img->spec))
31263 Lisp_Object image_map, hotspot;
31264 if ((image_map = Fplist_get (XCDR (img->spec), QCmap),
31265 !NILP (image_map))
31266 && (hotspot = find_hot_spot (image_map,
31267 glyph->slice.img.x + dx,
31268 glyph->slice.img.y + dy),
31269 CONSP (hotspot))
31270 && (hotspot = XCDR (hotspot), CONSP (hotspot)))
31272 Lisp_Object plist;
31274 /* Could check XCAR (hotspot) to see if we enter/leave
31275 this hot-spot.
31276 If so, we could look for mouse-enter, mouse-leave
31277 properties in PLIST (and do something...). */
31278 hotspot = XCDR (hotspot);
31279 if (CONSP (hotspot)
31280 && (plist = XCAR (hotspot), CONSP (plist)))
31282 pointer = Fplist_get (plist, Qpointer);
31283 if (NILP (pointer))
31284 pointer = Qhand;
31285 help_echo_string = Fplist_get (plist, Qhelp_echo);
31286 if (!NILP (help_echo_string))
31288 help_echo_window = window;
31289 help_echo_object = glyph->object;
31290 help_echo_pos = glyph->charpos;
31294 if (NILP (pointer))
31295 pointer = Fplist_get (XCDR (img->spec), QCpointer);
31298 #endif /* HAVE_WINDOW_SYSTEM */
31300 /* Clear mouse face if X/Y not over text. */
31301 if (glyph == NULL
31302 || area != TEXT_AREA
31303 || !MATRIX_ROW_DISPLAYS_TEXT_P (MATRIX_ROW (w->current_matrix, vpos))
31304 /* Glyph's OBJECT is nil for glyphs inserted by the
31305 display engine for its internal purposes, like truncation
31306 and continuation glyphs and blanks beyond the end of
31307 line's text on text terminals. If we are over such a
31308 glyph, we are not over any text. */
31309 || NILP (glyph->object)
31310 /* R2L rows have a stretch glyph at their front, which
31311 stands for no text, whereas L2R rows have no glyphs at
31312 all beyond the end of text. Treat such stretch glyphs
31313 like we do with NULL glyphs in L2R rows. */
31314 || (MATRIX_ROW (w->current_matrix, vpos)->reversed_p
31315 && glyph == MATRIX_ROW_GLYPH_START (w->current_matrix, vpos)
31316 && glyph->type == STRETCH_GLYPH
31317 && glyph->avoid_cursor_p))
31319 if (clear_mouse_face (hlinfo))
31320 cursor = No_Cursor;
31321 if (FRAME_WINDOW_P (f) && NILP (pointer))
31323 #ifdef HAVE_WINDOW_SYSTEM
31324 if (area != TEXT_AREA)
31325 cursor = FRAME_X_OUTPUT (f)->nontext_cursor;
31326 else
31327 pointer = Vvoid_text_area_pointer;
31328 #endif
31330 goto set_cursor;
31333 pos = glyph->charpos;
31334 object = glyph->object;
31335 if (!STRINGP (object) && !BUFFERP (object))
31336 goto set_cursor;
31338 /* If we get an out-of-range value, return now; avoid an error. */
31339 if (BUFFERP (object) && pos > BUF_Z (b))
31340 goto set_cursor;
31342 /* Make the window's buffer temporarily current for
31343 overlays_at and compute_char_face. */
31344 obuf = current_buffer;
31345 current_buffer = b;
31346 obegv = BEGV;
31347 ozv = ZV;
31348 BEGV = BEG;
31349 ZV = Z;
31351 /* Is this char mouse-active or does it have help-echo? */
31352 position = make_number (pos);
31354 USE_SAFE_ALLOCA;
31356 if (BUFFERP (object))
31358 /* Put all the overlays we want in a vector in overlay_vec. */
31359 GET_OVERLAYS_AT (pos, overlay_vec, noverlays, NULL, false);
31360 /* Sort overlays into increasing priority order. */
31361 noverlays = sort_overlays (overlay_vec, noverlays, w);
31363 else
31364 noverlays = 0;
31366 if (NILP (Vmouse_highlight))
31368 clear_mouse_face (hlinfo);
31369 goto check_help_echo;
31372 same_region = coords_in_mouse_face_p (w, hpos, vpos);
31374 if (same_region)
31375 cursor = No_Cursor;
31377 /* Check mouse-face highlighting. */
31378 if (! same_region
31379 /* If there exists an overlay with mouse-face overlapping
31380 the one we are currently highlighting, we have to check
31381 if we enter the overlapping overlay, and then highlight
31382 only that. Skip the check when mouse-face highlighting
31383 is currently hidden to avoid Bug#30519. */
31384 || (!hlinfo->mouse_face_hidden
31385 && OVERLAYP (hlinfo->mouse_face_overlay)
31386 && mouse_face_overlay_overlaps (hlinfo->mouse_face_overlay)))
31388 /* Find the highest priority overlay with a mouse-face. */
31389 Lisp_Object overlay = Qnil;
31390 for (i = noverlays - 1; i >= 0 && NILP (overlay); --i)
31392 mouse_face = Foverlay_get (overlay_vec[i], Qmouse_face);
31393 if (!NILP (mouse_face))
31394 overlay = overlay_vec[i];
31397 /* If we're highlighting the same overlay as before, there's
31398 no need to do that again. */
31399 if (!NILP (overlay) && EQ (overlay, hlinfo->mouse_face_overlay))
31400 goto check_help_echo;
31402 /* Clear the display of the old active region, if any. */
31403 if (clear_mouse_face (hlinfo))
31404 cursor = No_Cursor;
31406 /* Record the overlay, if any, to be highlighted. */
31407 hlinfo->mouse_face_overlay = overlay;
31409 /* If no overlay applies, get a text property. */
31410 if (NILP (overlay))
31411 mouse_face = Fget_text_property (position, Qmouse_face, object);
31413 /* Next, compute the bounds of the mouse highlighting and
31414 display it. */
31415 if (!NILP (mouse_face) && STRINGP (object))
31417 /* The mouse-highlighting comes from a display string
31418 with a mouse-face. */
31419 Lisp_Object s, e;
31420 ptrdiff_t ignore;
31422 s = Fprevious_single_property_change
31423 (make_number (pos + 1), Qmouse_face, object, Qnil);
31424 e = Fnext_single_property_change
31425 (position, Qmouse_face, object, Qnil);
31426 if (NILP (s))
31427 s = make_number (0);
31428 if (NILP (e))
31429 e = make_number (SCHARS (object));
31430 mouse_face_from_string_pos (w, hlinfo, object,
31431 XINT (s), XINT (e));
31432 hlinfo->mouse_face_past_end = false;
31433 hlinfo->mouse_face_window = window;
31434 hlinfo->mouse_face_face_id
31435 = face_at_string_position (w, object, pos, 0, &ignore,
31436 glyph->face_id, true);
31437 show_mouse_face (hlinfo, DRAW_MOUSE_FACE);
31438 cursor = No_Cursor;
31440 else
31442 /* The mouse-highlighting, if any, comes from an overlay
31443 or text property in the buffer. */
31444 Lisp_Object buffer UNINIT;
31445 Lisp_Object disp_string UNINIT;
31447 if (STRINGP (object))
31449 /* If we are on a display string with no mouse-face,
31450 check if the text under it has one. */
31451 struct glyph_row *r = MATRIX_ROW (w->current_matrix, vpos);
31452 ptrdiff_t start = MATRIX_ROW_START_CHARPOS (r);
31453 pos = string_buffer_position (object, start);
31454 if (pos > 0)
31456 mouse_face = get_char_property_and_overlay
31457 (make_number (pos), Qmouse_face, w->contents, &overlay);
31458 buffer = w->contents;
31459 disp_string = object;
31462 else
31464 buffer = object;
31465 disp_string = Qnil;
31468 if (!NILP (mouse_face))
31470 Lisp_Object before, after;
31471 Lisp_Object before_string, after_string;
31472 /* To correctly find the limits of mouse highlight
31473 in a bidi-reordered buffer, we must not use the
31474 optimization of limiting the search in
31475 previous-single-property-change and
31476 next-single-property-change, because
31477 rows_from_pos_range needs the real start and end
31478 positions to DTRT in this case. That's because
31479 the first row visible in a window does not
31480 necessarily display the character whose position
31481 is the smallest. */
31482 Lisp_Object lim1
31483 = NILP (BVAR (XBUFFER (buffer), bidi_display_reordering))
31484 ? Fmarker_position (w->start)
31485 : Qnil;
31486 Lisp_Object lim2
31487 = NILP (BVAR (XBUFFER (buffer), bidi_display_reordering))
31488 ? make_number (BUF_Z (XBUFFER (buffer))
31489 - w->window_end_pos)
31490 : Qnil;
31492 if (NILP (overlay))
31494 /* Handle the text property case. */
31495 before = Fprevious_single_property_change
31496 (make_number (pos + 1), Qmouse_face, buffer, lim1);
31497 after = Fnext_single_property_change
31498 (make_number (pos), Qmouse_face, buffer, lim2);
31499 before_string = after_string = Qnil;
31501 else
31503 /* Handle the overlay case. */
31504 before = Foverlay_start (overlay);
31505 after = Foverlay_end (overlay);
31506 before_string = Foverlay_get (overlay, Qbefore_string);
31507 after_string = Foverlay_get (overlay, Qafter_string);
31509 if (!STRINGP (before_string)) before_string = Qnil;
31510 if (!STRINGP (after_string)) after_string = Qnil;
31513 mouse_face_from_buffer_pos (window, hlinfo, pos,
31514 NILP (before)
31516 : XFASTINT (before),
31517 NILP (after)
31518 ? BUF_Z (XBUFFER (buffer))
31519 : XFASTINT (after),
31520 before_string, after_string,
31521 disp_string);
31522 cursor = No_Cursor;
31527 check_help_echo:
31529 /* Look for a `help-echo' property. */
31530 if (NILP (help_echo_string)) {
31531 Lisp_Object help, overlay;
31533 /* Check overlays first. */
31534 help = overlay = Qnil;
31535 for (i = noverlays - 1; i >= 0 && NILP (help); --i)
31537 overlay = overlay_vec[i];
31538 help = Foverlay_get (overlay, Qhelp_echo);
31541 if (!NILP (help))
31543 help_echo_string = help;
31544 help_echo_window = window;
31545 help_echo_object = overlay;
31546 help_echo_pos = pos;
31548 else
31550 Lisp_Object obj = glyph->object;
31551 ptrdiff_t charpos = glyph->charpos;
31553 /* Try text properties. */
31554 if (STRINGP (obj)
31555 && charpos >= 0
31556 && charpos < SCHARS (obj))
31558 help = Fget_text_property (make_number (charpos),
31559 Qhelp_echo, obj);
31560 if (NILP (help))
31562 /* If the string itself doesn't specify a help-echo,
31563 see if the buffer text ``under'' it does. */
31564 struct glyph_row *r
31565 = MATRIX_ROW (w->current_matrix, vpos);
31566 ptrdiff_t start = MATRIX_ROW_START_CHARPOS (r);
31567 ptrdiff_t p = string_buffer_position (obj, start);
31568 if (p > 0)
31570 help = Fget_char_property (make_number (p),
31571 Qhelp_echo, w->contents);
31572 if (!NILP (help))
31574 charpos = p;
31575 obj = w->contents;
31580 else if (BUFFERP (obj)
31581 && charpos >= BEGV
31582 && charpos < ZV)
31583 help = Fget_text_property (make_number (charpos), Qhelp_echo,
31584 obj);
31586 if (!NILP (help))
31588 help_echo_string = help;
31589 help_echo_window = window;
31590 help_echo_object = obj;
31591 help_echo_pos = charpos;
31596 #ifdef HAVE_WINDOW_SYSTEM
31597 /* Look for a `pointer' property. */
31598 if (FRAME_WINDOW_P (f) && NILP (pointer))
31600 /* Check overlays first. */
31601 for (i = noverlays - 1; i >= 0 && NILP (pointer); --i)
31602 pointer = Foverlay_get (overlay_vec[i], Qpointer);
31604 if (NILP (pointer))
31606 Lisp_Object obj = glyph->object;
31607 ptrdiff_t charpos = glyph->charpos;
31609 /* Try text properties. */
31610 if (STRINGP (obj)
31611 && charpos >= 0
31612 && charpos < SCHARS (obj))
31614 pointer = Fget_text_property (make_number (charpos),
31615 Qpointer, obj);
31616 if (NILP (pointer))
31618 /* If the string itself doesn't specify a pointer,
31619 see if the buffer text ``under'' it does. */
31620 struct glyph_row *r
31621 = MATRIX_ROW (w->current_matrix, vpos);
31622 ptrdiff_t start = MATRIX_ROW_START_CHARPOS (r);
31623 ptrdiff_t p = string_buffer_position (obj, start);
31624 if (p > 0)
31625 pointer = Fget_char_property (make_number (p),
31626 Qpointer, w->contents);
31629 else if (BUFFERP (obj)
31630 && charpos >= BEGV
31631 && charpos < ZV)
31632 pointer = Fget_text_property (make_number (charpos),
31633 Qpointer, obj);
31636 #endif /* HAVE_WINDOW_SYSTEM */
31638 BEGV = obegv;
31639 ZV = ozv;
31640 current_buffer = obuf;
31641 SAFE_FREE ();
31644 set_cursor:
31645 define_frame_cursor1 (f, cursor, pointer);
31649 /* EXPORT for RIF:
31650 Clear any mouse-face on window W. This function is part of the
31651 redisplay interface, and is called from try_window_id and similar
31652 functions to ensure the mouse-highlight is off. */
31654 void
31655 x_clear_window_mouse_face (struct window *w)
31657 Mouse_HLInfo *hlinfo = MOUSE_HL_INFO (XFRAME (w->frame));
31658 Lisp_Object window;
31660 block_input ();
31661 XSETWINDOW (window, w);
31662 if (EQ (window, hlinfo->mouse_face_window))
31663 clear_mouse_face (hlinfo);
31664 unblock_input ();
31668 /* EXPORT:
31669 Just discard the mouse face information for frame F, if any.
31670 This is used when the size of F is changed. */
31672 void
31673 cancel_mouse_face (struct frame *f)
31675 Lisp_Object window;
31676 Mouse_HLInfo *hlinfo = MOUSE_HL_INFO (f);
31678 window = hlinfo->mouse_face_window;
31679 if (! NILP (window) && XFRAME (XWINDOW (window)->frame) == f)
31680 reset_mouse_highlight (hlinfo);
31685 /***********************************************************************
31686 Exposure Events
31687 ***********************************************************************/
31689 #ifdef HAVE_WINDOW_SYSTEM
31691 /* Redraw the part of glyph row area AREA of glyph row ROW on window W
31692 which intersects rectangle R. R is in window-relative coordinates. */
31694 static void
31695 expose_area (struct window *w, struct glyph_row *row, XRectangle *r,
31696 enum glyph_row_area area)
31698 struct glyph *first = row->glyphs[area];
31699 struct glyph *end = row->glyphs[area] + row->used[area];
31700 struct glyph *last;
31701 int first_x, start_x, x;
31703 if (area == TEXT_AREA && row->fill_line_p)
31704 /* If row extends face to end of line write the whole line. */
31705 draw_glyphs (w, 0, row, area,
31706 0, row->used[area],
31707 DRAW_NORMAL_TEXT, 0);
31708 else
31710 /* Set START_X to the window-relative start position for drawing glyphs of
31711 AREA. The first glyph of the text area can be partially visible.
31712 The first glyphs of other areas cannot. */
31713 start_x = window_box_left_offset (w, area);
31714 x = start_x;
31715 if (area == TEXT_AREA)
31716 x += row->x;
31718 /* Find the first glyph that must be redrawn. */
31719 while (first < end
31720 && x + first->pixel_width < r->x)
31722 x += first->pixel_width;
31723 ++first;
31726 /* Find the last one. */
31727 last = first;
31728 first_x = x;
31729 /* Use a signed int intermediate value to avoid catastrophic
31730 failures due to comparison between signed and unsigned, when
31731 x is negative (can happen for wide images that are hscrolled). */
31732 int r_end = r->x + r->width;
31733 while (last < end && x < r_end)
31735 x += last->pixel_width;
31736 ++last;
31739 /* Repaint. */
31740 if (last > first)
31741 draw_glyphs (w, first_x - start_x, row, area,
31742 first - row->glyphs[area], last - row->glyphs[area],
31743 DRAW_NORMAL_TEXT, 0);
31748 /* Redraw the parts of the glyph row ROW on window W intersecting
31749 rectangle R. R is in window-relative coordinates. Value is
31750 true if mouse-face was overwritten. */
31752 static bool
31753 expose_line (struct window *w, struct glyph_row *row, XRectangle *r)
31755 eassert (row->enabled_p);
31757 if (row->mode_line_p || w->pseudo_window_p)
31758 draw_glyphs (w, 0, row, TEXT_AREA,
31759 0, row->used[TEXT_AREA],
31760 DRAW_NORMAL_TEXT, 0);
31761 else
31763 if (row->used[LEFT_MARGIN_AREA])
31764 expose_area (w, row, r, LEFT_MARGIN_AREA);
31765 if (row->used[TEXT_AREA])
31766 expose_area (w, row, r, TEXT_AREA);
31767 if (row->used[RIGHT_MARGIN_AREA])
31768 expose_area (w, row, r, RIGHT_MARGIN_AREA);
31769 draw_row_fringe_bitmaps (w, row);
31772 return row->mouse_face_p;
31776 /* Redraw those parts of glyphs rows during expose event handling that
31777 overlap other rows. Redrawing of an exposed line writes over parts
31778 of lines overlapping that exposed line; this function fixes that.
31780 W is the window being exposed. FIRST_OVERLAPPING_ROW is the first
31781 row in W's current matrix that is exposed and overlaps other rows.
31782 LAST_OVERLAPPING_ROW is the last such row. */
31784 static void
31785 expose_overlaps (struct window *w,
31786 struct glyph_row *first_overlapping_row,
31787 struct glyph_row *last_overlapping_row,
31788 XRectangle *r)
31790 struct glyph_row *row;
31792 for (row = first_overlapping_row; row <= last_overlapping_row; ++row)
31793 if (row->overlapping_p)
31795 eassert (row->enabled_p && !row->mode_line_p);
31797 row->clip = r;
31798 if (row->used[LEFT_MARGIN_AREA])
31799 x_fix_overlapping_area (w, row, LEFT_MARGIN_AREA, OVERLAPS_BOTH);
31801 if (row->used[TEXT_AREA])
31802 x_fix_overlapping_area (w, row, TEXT_AREA, OVERLAPS_BOTH);
31804 if (row->used[RIGHT_MARGIN_AREA])
31805 x_fix_overlapping_area (w, row, RIGHT_MARGIN_AREA, OVERLAPS_BOTH);
31806 row->clip = NULL;
31811 /* Return true if W's cursor intersects rectangle R. */
31813 static bool
31814 phys_cursor_in_rect_p (struct window *w, XRectangle *r)
31816 XRectangle cr, result;
31817 struct glyph *cursor_glyph;
31818 struct glyph_row *row;
31820 if (w->phys_cursor.vpos >= 0
31821 && w->phys_cursor.vpos < w->current_matrix->nrows
31822 && (row = MATRIX_ROW (w->current_matrix, w->phys_cursor.vpos),
31823 row->enabled_p)
31824 && row->cursor_in_fringe_p)
31826 /* Cursor is in the fringe. */
31827 cr.x = window_box_right_offset (w,
31828 (WINDOW_HAS_FRINGES_OUTSIDE_MARGINS (w)
31829 ? RIGHT_MARGIN_AREA
31830 : TEXT_AREA));
31831 cr.y = row->y;
31832 cr.width = WINDOW_RIGHT_FRINGE_WIDTH (w);
31833 cr.height = row->height;
31834 return x_intersect_rectangles (&cr, r, &result);
31837 cursor_glyph = get_phys_cursor_glyph (w);
31838 if (cursor_glyph)
31840 /* r is relative to W's box, but w->phys_cursor.x is relative
31841 to left edge of W's TEXT area. Adjust it. */
31842 cr.x = window_box_left_offset (w, TEXT_AREA) + w->phys_cursor.x;
31843 cr.y = w->phys_cursor.y;
31844 cr.width = cursor_glyph->pixel_width;
31845 cr.height = w->phys_cursor_height;
31846 /* ++KFS: W32 version used W32-specific IntersectRect here, but
31847 I assume the effect is the same -- and this is portable. */
31848 return x_intersect_rectangles (&cr, r, &result);
31850 /* If we don't understand the format, pretend we're not in the hot-spot. */
31851 return false;
31855 /* EXPORT:
31856 Draw a vertical window border to the right of window W if W doesn't
31857 have vertical scroll bars. */
31859 void
31860 x_draw_vertical_border (struct window *w)
31862 struct frame *f = XFRAME (WINDOW_FRAME (w));
31864 /* We could do better, if we knew what type of scroll-bar the adjacent
31865 windows (on either side) have... But we don't :-(
31866 However, I think this works ok. ++KFS 2003-04-25 */
31868 /* Redraw borders between horizontally adjacent windows. Don't
31869 do it for frames with vertical scroll bars because either the
31870 right scroll bar of a window, or the left scroll bar of its
31871 neighbor will suffice as a border. */
31872 if (FRAME_HAS_VERTICAL_SCROLL_BARS (f) || FRAME_RIGHT_DIVIDER_WIDTH (f))
31873 return;
31875 /* Note: It is necessary to redraw both the left and the right
31876 borders, for when only this single window W is being
31877 redisplayed. */
31878 if (!WINDOW_RIGHTMOST_P (w)
31879 && !WINDOW_HAS_VERTICAL_SCROLL_BAR_ON_RIGHT (w))
31881 int x0, x1, y0, y1;
31883 window_box_edges (w, &x0, &y0, &x1, &y1);
31884 y1 -= 1;
31886 if (WINDOW_LEFT_FRINGE_WIDTH (w) == 0)
31887 x1 -= 1;
31889 FRAME_RIF (f)->draw_vertical_window_border (w, x1, y0, y1);
31892 if (!WINDOW_LEFTMOST_P (w)
31893 && !WINDOW_HAS_VERTICAL_SCROLL_BAR_ON_LEFT (w))
31895 int x0, x1, y0, y1;
31897 window_box_edges (w, &x0, &y0, &x1, &y1);
31898 y1 -= 1;
31900 if (WINDOW_LEFT_FRINGE_WIDTH (w) == 0)
31901 x0 -= 1;
31903 FRAME_RIF (f)->draw_vertical_window_border (w, x0, y0, y1);
31908 /* Draw window dividers for window W. */
31910 void
31911 x_draw_right_divider (struct window *w)
31913 struct frame *f = WINDOW_XFRAME (w);
31915 if (w->mini || w->pseudo_window_p)
31916 return;
31917 else if (WINDOW_RIGHT_DIVIDER_WIDTH (w))
31919 int x0 = WINDOW_RIGHT_EDGE_X (w) - WINDOW_RIGHT_DIVIDER_WIDTH (w);
31920 int x1 = WINDOW_RIGHT_EDGE_X (w);
31921 int y0 = WINDOW_TOP_EDGE_Y (w);
31922 int y1 = WINDOW_BOTTOM_EDGE_Y (w);
31924 /* If W is horizontally combined and has a right sibling, don't
31925 draw over any bottom divider. */
31926 if (WINDOW_BOTTOM_DIVIDER_WIDTH (w)
31927 && !NILP (w->parent)
31928 && WINDOW_HORIZONTAL_COMBINATION_P (XWINDOW (w->parent))
31929 && !NILP (w->next))
31930 y1 -= WINDOW_BOTTOM_DIVIDER_WIDTH (w);
31932 FRAME_RIF (f)->draw_window_divider (w, x0, x1, y0, y1);
31936 static void
31937 x_draw_bottom_divider (struct window *w)
31939 struct frame *f = XFRAME (WINDOW_FRAME (w));
31941 if (w->mini || w->pseudo_window_p)
31942 return;
31943 else if (WINDOW_BOTTOM_DIVIDER_WIDTH (w))
31945 int x0 = WINDOW_LEFT_EDGE_X (w);
31946 int x1 = WINDOW_RIGHT_EDGE_X (w);
31947 int y0 = WINDOW_BOTTOM_EDGE_Y (w) - WINDOW_BOTTOM_DIVIDER_WIDTH (w);
31948 int y1 = WINDOW_BOTTOM_EDGE_Y (w);
31949 struct window *p = !NILP (w->parent) ? XWINDOW (w->parent) : NULL;
31951 /* If W is vertically combined and has a sibling below, don't draw
31952 over any right divider. */
31953 if (WINDOW_RIGHT_DIVIDER_WIDTH (w)
31954 && p
31955 && ((WINDOW_VERTICAL_COMBINATION_P (p)
31956 && !NILP (w->next))
31957 || (WINDOW_HORIZONTAL_COMBINATION_P (p)
31958 && NILP (w->next)
31959 && !NILP (p->parent)
31960 && WINDOW_VERTICAL_COMBINATION_P (XWINDOW (p->parent))
31961 && !NILP (XWINDOW (p->parent)->next))))
31962 x1 -= WINDOW_RIGHT_DIVIDER_WIDTH (w);
31964 FRAME_RIF (f)->draw_window_divider (w, x0, x1, y0, y1);
31968 /* Redraw the part of window W intersection rectangle FR. Pixel
31969 coordinates in FR are frame-relative. Call this function with
31970 input blocked. Value is true if the exposure overwrites
31971 mouse-face. */
31973 static bool
31974 expose_window (struct window *w, XRectangle *fr)
31976 struct frame *f = XFRAME (w->frame);
31977 XRectangle wr, r;
31978 bool mouse_face_overwritten_p = false;
31980 /* If window is not yet fully initialized, do nothing. This can
31981 happen when toolkit scroll bars are used and a window is split.
31982 Reconfiguring the scroll bar will generate an expose for a newly
31983 created window. */
31984 if (w->current_matrix == NULL)
31985 return false;
31987 /* When we're currently updating the window, display and current
31988 matrix usually don't agree. Arrange for a thorough display
31989 later. */
31990 if (w->must_be_updated_p)
31992 SET_FRAME_GARBAGED (f);
31993 return false;
31996 /* Frame-relative pixel rectangle of W. */
31997 wr.x = WINDOW_LEFT_EDGE_X (w);
31998 wr.y = WINDOW_TOP_EDGE_Y (w);
31999 wr.width = WINDOW_PIXEL_WIDTH (w);
32000 wr.height = WINDOW_PIXEL_HEIGHT (w);
32002 if (x_intersect_rectangles (fr, &wr, &r))
32004 int yb = window_text_bottom_y (w);
32005 struct glyph_row *row;
32006 struct glyph_row *first_overlapping_row, *last_overlapping_row;
32008 TRACE ((stderr, "expose_window (%d, %d, %d, %d)\n",
32009 r.x, r.y, r.width, r.height));
32011 /* Convert to window coordinates. */
32012 r.x -= WINDOW_LEFT_EDGE_X (w);
32013 r.y -= WINDOW_TOP_EDGE_Y (w);
32015 /* Turn off the cursor. */
32016 bool cursor_cleared_p = (!w->pseudo_window_p
32017 && phys_cursor_in_rect_p (w, &r));
32018 if (cursor_cleared_p)
32019 x_clear_cursor (w);
32021 /* If the row containing the cursor extends face to end of line,
32022 then expose_area might overwrite the cursor outside the
32023 rectangle and thus notice_overwritten_cursor might clear
32024 w->phys_cursor_on_p. We remember the original value and
32025 check later if it is changed. */
32026 bool phys_cursor_on_p = w->phys_cursor_on_p;
32028 /* Use a signed int intermediate value to avoid catastrophic
32029 failures due to comparison between signed and unsigned, when
32030 y0 or y1 is negative (can happen for tall images). */
32031 int r_bottom = r.y + r.height;
32033 /* Update lines intersecting rectangle R. */
32034 first_overlapping_row = last_overlapping_row = NULL;
32035 for (row = w->current_matrix->rows;
32036 row->enabled_p;
32037 ++row)
32039 int y0 = row->y;
32040 int y1 = MATRIX_ROW_BOTTOM_Y (row);
32042 if ((y0 >= r.y && y0 < r_bottom)
32043 || (y1 > r.y && y1 < r_bottom)
32044 || (r.y >= y0 && r.y < y1)
32045 || (r_bottom > y0 && r_bottom < y1))
32047 /* A header line may be overlapping, but there is no need
32048 to fix overlapping areas for them. KFS 2005-02-12 */
32049 if (row->overlapping_p && !row->mode_line_p)
32051 if (first_overlapping_row == NULL)
32052 first_overlapping_row = row;
32053 last_overlapping_row = row;
32056 row->clip = fr;
32057 if (expose_line (w, row, &r))
32058 mouse_face_overwritten_p = true;
32059 row->clip = NULL;
32061 else if (row->overlapping_p)
32063 /* We must redraw a row overlapping the exposed area. */
32064 if (y0 < r.y
32065 ? y0 + row->phys_height > r.y
32066 : y0 + row->ascent - row->phys_ascent < r.y +r.height)
32068 if (first_overlapping_row == NULL)
32069 first_overlapping_row = row;
32070 last_overlapping_row = row;
32074 if (y1 >= yb)
32075 break;
32078 /* Display the mode line if there is one. */
32079 if (window_wants_mode_line (w)
32080 && (row = MATRIX_MODE_LINE_ROW (w->current_matrix),
32081 row->enabled_p)
32082 && row->y < r_bottom)
32084 if (expose_line (w, row, &r))
32085 mouse_face_overwritten_p = true;
32088 if (!w->pseudo_window_p)
32090 /* Fix the display of overlapping rows. */
32091 if (first_overlapping_row)
32092 expose_overlaps (w, first_overlapping_row, last_overlapping_row,
32093 fr);
32095 /* Draw border between windows. */
32096 if (WINDOW_RIGHT_DIVIDER_WIDTH (w))
32097 x_draw_right_divider (w);
32098 else
32099 x_draw_vertical_border (w);
32101 if (WINDOW_BOTTOM_DIVIDER_WIDTH (w))
32102 x_draw_bottom_divider (w);
32104 /* Turn the cursor on again. */
32105 if (cursor_cleared_p
32106 || (phys_cursor_on_p && !w->phys_cursor_on_p))
32107 update_window_cursor (w, true);
32111 return mouse_face_overwritten_p;
32116 /* Redraw (parts) of all windows in the window tree rooted at W that
32117 intersect R. R contains frame pixel coordinates. Value is
32118 true if the exposure overwrites mouse-face. */
32120 static bool
32121 expose_window_tree (struct window *w, XRectangle *r)
32123 struct frame *f = XFRAME (w->frame);
32124 bool mouse_face_overwritten_p = false;
32126 while (w && !FRAME_GARBAGED_P (f))
32128 mouse_face_overwritten_p
32129 |= (WINDOWP (w->contents)
32130 ? expose_window_tree (XWINDOW (w->contents), r)
32131 : expose_window (w, r));
32133 w = NILP (w->next) ? NULL : XWINDOW (w->next);
32136 return mouse_face_overwritten_p;
32140 /* EXPORT:
32141 Redisplay an exposed area of frame F. X and Y are the upper-left
32142 corner of the exposed rectangle. W and H are width and height of
32143 the exposed area. All are pixel values. W or H zero means redraw
32144 the entire frame. */
32146 void
32147 expose_frame (struct frame *f, int x, int y, int w, int h)
32149 XRectangle r;
32150 bool mouse_face_overwritten_p = false;
32152 TRACE ((stderr, "expose_frame "));
32154 /* No need to redraw if frame will be redrawn soon. */
32155 if (FRAME_GARBAGED_P (f))
32157 TRACE ((stderr, " garbaged\n"));
32158 return;
32161 /* If basic faces haven't been realized yet, there is no point in
32162 trying to redraw anything. This can happen when we get an expose
32163 event while Emacs is starting, e.g. by moving another window. */
32164 if (FRAME_FACE_CACHE (f) == NULL
32165 || FRAME_FACE_CACHE (f)->used < BASIC_FACE_ID_SENTINEL)
32167 TRACE ((stderr, " no faces\n"));
32168 return;
32171 if (w == 0 || h == 0)
32173 r.x = r.y = 0;
32174 r.width = FRAME_TEXT_WIDTH (f);
32175 r.height = FRAME_TEXT_HEIGHT (f);
32177 else
32179 r.x = x;
32180 r.y = y;
32181 r.width = w;
32182 r.height = h;
32185 TRACE ((stderr, "(%d, %d, %d, %d)\n", r.x, r.y, r.width, r.height));
32186 mouse_face_overwritten_p = expose_window_tree (XWINDOW (f->root_window), &r);
32188 #if ! defined (USE_GTK) && ! defined (HAVE_NS)
32189 if (WINDOWP (f->tool_bar_window))
32190 mouse_face_overwritten_p
32191 |= expose_window (XWINDOW (f->tool_bar_window), &r);
32192 #endif
32194 #ifdef HAVE_X_WINDOWS
32195 #ifndef MSDOS
32196 #if ! defined (USE_X_TOOLKIT) && ! defined (USE_GTK)
32197 if (WINDOWP (f->menu_bar_window))
32198 mouse_face_overwritten_p
32199 |= expose_window (XWINDOW (f->menu_bar_window), &r);
32200 #endif /* not USE_X_TOOLKIT and not USE_GTK */
32201 #endif
32202 #endif
32204 /* Some window managers support a focus-follows-mouse style with
32205 delayed raising of frames. Imagine a partially obscured frame,
32206 and moving the mouse into partially obscured mouse-face on that
32207 frame. The visible part of the mouse-face will be highlighted,
32208 then the WM raises the obscured frame. With at least one WM, KDE
32209 2.1, Emacs is not getting any event for the raising of the frame
32210 (even tried with SubstructureRedirectMask), only Expose events.
32211 These expose events will draw text normally, i.e. not
32212 highlighted. Which means we must redo the highlight here.
32213 Subsume it under ``we love X''. --gerd 2001-08-15 */
32214 /* Included in Windows version because Windows most likely does not
32215 do the right thing if any third party tool offers
32216 focus-follows-mouse with delayed raise. --jason 2001-10-12 */
32217 if (mouse_face_overwritten_p && !FRAME_GARBAGED_P (f))
32219 Mouse_HLInfo *hlinfo = MOUSE_HL_INFO (f);
32220 if (f == hlinfo->mouse_face_mouse_frame)
32222 int mouse_x = hlinfo->mouse_face_mouse_x;
32223 int mouse_y = hlinfo->mouse_face_mouse_y;
32224 clear_mouse_face (hlinfo);
32225 note_mouse_highlight (f, mouse_x, mouse_y);
32231 /* EXPORT:
32232 Determine the intersection of two rectangles R1 and R2. Return
32233 the intersection in *RESULT. Value is true if RESULT is not
32234 empty. */
32236 bool
32237 x_intersect_rectangles (XRectangle *r1, XRectangle *r2, XRectangle *result)
32239 XRectangle *left, *right;
32240 XRectangle *upper, *lower;
32241 bool intersection_p = false;
32243 /* Rearrange so that R1 is the left-most rectangle. */
32244 if (r1->x < r2->x)
32245 left = r1, right = r2;
32246 else
32247 left = r2, right = r1;
32249 /* X0 of the intersection is right.x0, if this is inside R1,
32250 otherwise there is no intersection. */
32251 if (right->x <= left->x + left->width)
32253 result->x = right->x;
32255 /* The right end of the intersection is the minimum of
32256 the right ends of left and right. */
32257 result->width = (min (left->x + left->width, right->x + right->width)
32258 - result->x);
32260 /* Same game for Y. */
32261 if (r1->y < r2->y)
32262 upper = r1, lower = r2;
32263 else
32264 upper = r2, lower = r1;
32266 /* The upper end of the intersection is lower.y0, if this is inside
32267 of upper. Otherwise, there is no intersection. */
32268 if (lower->y <= upper->y + upper->height)
32270 result->y = lower->y;
32272 /* The lower end of the intersection is the minimum of the lower
32273 ends of upper and lower. */
32274 result->height = (min (lower->y + lower->height,
32275 upper->y + upper->height)
32276 - result->y);
32277 intersection_p = true;
32281 return intersection_p;
32284 #endif /* HAVE_WINDOW_SYSTEM */
32287 /***********************************************************************
32288 Initialization
32289 ***********************************************************************/
32291 void
32292 syms_of_xdisp (void)
32294 Vwith_echo_area_save_vector = Qnil;
32295 staticpro (&Vwith_echo_area_save_vector);
32297 Vmessage_stack = Qnil;
32298 staticpro (&Vmessage_stack);
32300 /* Non-nil means don't actually do any redisplay. */
32301 DEFSYM (Qinhibit_redisplay, "inhibit-redisplay");
32303 DEFSYM (Qredisplay_internal_xC_functionx, "redisplay_internal (C function)");
32305 DEFVAR_BOOL("inhibit-message", inhibit_message,
32306 doc: /* Non-nil means calls to `message' are not displayed.
32307 They are still logged to the *Messages* buffer. */);
32308 inhibit_message = 0;
32310 message_dolog_marker1 = Fmake_marker ();
32311 staticpro (&message_dolog_marker1);
32312 message_dolog_marker2 = Fmake_marker ();
32313 staticpro (&message_dolog_marker2);
32314 message_dolog_marker3 = Fmake_marker ();
32315 staticpro (&message_dolog_marker3);
32317 defsubr (&Sset_buffer_redisplay);
32318 #ifdef GLYPH_DEBUG
32319 defsubr (&Sdump_frame_glyph_matrix);
32320 defsubr (&Sdump_glyph_matrix);
32321 defsubr (&Sdump_glyph_row);
32322 defsubr (&Sdump_tool_bar_row);
32323 defsubr (&Strace_redisplay);
32324 defsubr (&Strace_to_stderr);
32325 #endif
32326 #ifdef HAVE_WINDOW_SYSTEM
32327 defsubr (&Stool_bar_height);
32328 defsubr (&Slookup_image_map);
32329 #endif
32330 defsubr (&Sline_pixel_height);
32331 defsubr (&Sformat_mode_line);
32332 defsubr (&Sinvisible_p);
32333 defsubr (&Scurrent_bidi_paragraph_direction);
32334 defsubr (&Swindow_text_pixel_size);
32335 defsubr (&Smove_point_visually);
32336 defsubr (&Sbidi_find_overridden_directionality);
32338 DEFSYM (Qmenu_bar_update_hook, "menu-bar-update-hook");
32339 DEFSYM (Qoverriding_terminal_local_map, "overriding-terminal-local-map");
32340 DEFSYM (Qoverriding_local_map, "overriding-local-map");
32341 DEFSYM (Qwindow_scroll_functions, "window-scroll-functions");
32342 DEFSYM (Qredisplay_end_trigger_functions, "redisplay-end-trigger-functions");
32343 DEFSYM (Qinhibit_point_motion_hooks, "inhibit-point-motion-hooks");
32344 DEFSYM (Qeval, "eval");
32345 DEFSYM (QCdata, ":data");
32347 /* Names of text properties relevant for redisplay. */
32348 DEFSYM (Qdisplay, "display");
32349 DEFSYM (Qspace_width, "space-width");
32350 DEFSYM (Qraise, "raise");
32351 DEFSYM (Qslice, "slice");
32352 DEFSYM (Qspace, "space");
32353 DEFSYM (Qmargin, "margin");
32354 DEFSYM (Qpointer, "pointer");
32355 DEFSYM (Qleft_margin, "left-margin");
32356 DEFSYM (Qright_margin, "right-margin");
32357 DEFSYM (Qcenter, "center");
32358 DEFSYM (Qline_height, "line-height");
32359 DEFSYM (QCalign_to, ":align-to");
32360 DEFSYM (QCrelative_width, ":relative-width");
32361 DEFSYM (QCrelative_height, ":relative-height");
32362 DEFSYM (QCeval, ":eval");
32363 DEFSYM (QCpropertize, ":propertize");
32364 DEFSYM (QCfile, ":file");
32365 DEFSYM (Qfontified, "fontified");
32366 DEFSYM (Qfontification_functions, "fontification-functions");
32368 /* Name of the symbol which disables Lisp evaluation in 'display'
32369 properties. This is used by enriched.el. */
32370 DEFSYM (Qdisable_eval, "disable-eval");
32372 /* Name of the face used to highlight trailing whitespace. */
32373 DEFSYM (Qtrailing_whitespace, "trailing-whitespace");
32375 /* Names of the faces used to display line numbers. */
32376 DEFSYM (Qline_number, "line-number");
32377 DEFSYM (Qline_number_current_line, "line-number-current-line");
32378 /* Name of a text property which disables line-number display. */
32379 DEFSYM (Qdisplay_line_numbers_disable, "display-line-numbers-disable");
32381 /* Name and number of the face used to highlight escape glyphs. */
32382 DEFSYM (Qescape_glyph, "escape-glyph");
32384 /* Name and number of the face used to highlight non-breaking
32385 spaces/hyphens. */
32386 DEFSYM (Qnobreak_space, "nobreak-space");
32387 DEFSYM (Qnobreak_hyphen, "nobreak-hyphen");
32389 /* The symbol 'image' which is the car of the lists used to represent
32390 images in Lisp. Also a tool bar style. */
32391 DEFSYM (Qimage, "image");
32393 /* Tool bar styles. */
32394 DEFSYM (Qtext, "text");
32395 DEFSYM (Qboth, "both");
32396 DEFSYM (Qboth_horiz, "both-horiz");
32397 DEFSYM (Qtext_image_horiz, "text-image-horiz");
32399 /* The image map types. */
32400 DEFSYM (QCmap, ":map");
32401 DEFSYM (QCpointer, ":pointer");
32402 DEFSYM (Qrect, "rect");
32403 DEFSYM (Qcircle, "circle");
32404 DEFSYM (Qpoly, "poly");
32406 DEFSYM (Qinhibit_menubar_update, "inhibit-menubar-update");
32408 DEFSYM (Qgrow_only, "grow-only");
32409 DEFSYM (Qinhibit_eval_during_redisplay, "inhibit-eval-during-redisplay");
32410 DEFSYM (Qposition, "position");
32411 DEFSYM (Qbuffer_position, "buffer-position");
32412 DEFSYM (Qobject, "object");
32414 /* Cursor shapes. */
32415 DEFSYM (Qbar, "bar");
32416 DEFSYM (Qhbar, "hbar");
32417 DEFSYM (Qbox, "box");
32418 DEFSYM (Qhollow, "hollow");
32420 /* Pointer shapes. */
32421 DEFSYM (Qhand, "hand");
32422 DEFSYM (Qarrow, "arrow");
32423 /* also Qtext */
32425 DEFSYM (Qdragging, "dragging");
32427 DEFSYM (Qinhibit_free_realized_faces, "inhibit-free-realized-faces");
32429 list_of_error = list1 (list2 (Qerror, Qvoid_variable));
32430 staticpro (&list_of_error);
32432 /* Values of those variables at last redisplay are stored as
32433 properties on 'overlay-arrow-position' symbol. However, if
32434 Voverlay_arrow_position is a marker, last-arrow-position is its
32435 numerical position. */
32436 DEFSYM (Qlast_arrow_position, "last-arrow-position");
32437 DEFSYM (Qlast_arrow_string, "last-arrow-string");
32439 /* Alternative overlay-arrow-string and overlay-arrow-bitmap
32440 properties on a symbol in overlay-arrow-variable-list. */
32441 DEFSYM (Qoverlay_arrow_string, "overlay-arrow-string");
32442 DEFSYM (Qoverlay_arrow_bitmap, "overlay-arrow-bitmap");
32444 echo_buffer[0] = echo_buffer[1] = Qnil;
32445 staticpro (&echo_buffer[0]);
32446 staticpro (&echo_buffer[1]);
32448 echo_area_buffer[0] = echo_area_buffer[1] = Qnil;
32449 staticpro (&echo_area_buffer[0]);
32450 staticpro (&echo_area_buffer[1]);
32452 Vmessages_buffer_name = build_pure_c_string ("*Messages*");
32453 staticpro (&Vmessages_buffer_name);
32455 mode_line_proptrans_alist = Qnil;
32456 staticpro (&mode_line_proptrans_alist);
32457 mode_line_string_list = Qnil;
32458 staticpro (&mode_line_string_list);
32459 mode_line_string_face = Qnil;
32460 staticpro (&mode_line_string_face);
32461 mode_line_string_face_prop = Qnil;
32462 staticpro (&mode_line_string_face_prop);
32463 Vmode_line_unwind_vector = Qnil;
32464 staticpro (&Vmode_line_unwind_vector);
32466 DEFSYM (Qmode_line_default_help_echo, "mode-line-default-help-echo");
32468 help_echo_string = Qnil;
32469 staticpro (&help_echo_string);
32470 help_echo_object = Qnil;
32471 staticpro (&help_echo_object);
32472 help_echo_window = Qnil;
32473 staticpro (&help_echo_window);
32474 previous_help_echo_string = Qnil;
32475 staticpro (&previous_help_echo_string);
32476 help_echo_pos = -1;
32478 DEFSYM (Qright_to_left, "right-to-left");
32479 DEFSYM (Qleft_to_right, "left-to-right");
32480 defsubr (&Sbidi_resolved_levels);
32482 #ifdef HAVE_WINDOW_SYSTEM
32483 DEFVAR_BOOL ("x-stretch-cursor", x_stretch_cursor_p,
32484 doc: /* Non-nil means draw block cursor as wide as the glyph under it.
32485 For example, if a block cursor is over a tab, it will be drawn as
32486 wide as that tab on the display. */);
32487 x_stretch_cursor_p = 0;
32488 #endif
32490 DEFVAR_LISP ("show-trailing-whitespace", Vshow_trailing_whitespace,
32491 doc: /* Non-nil means highlight trailing whitespace.
32492 The face used for trailing whitespace is `trailing-whitespace'. */);
32493 Vshow_trailing_whitespace = Qnil;
32495 DEFVAR_LISP ("nobreak-char-display", Vnobreak_char_display,
32496 doc: /* Control highlighting of non-ASCII space and hyphen chars.
32497 If the value is t, Emacs highlights non-ASCII chars which have the
32498 same appearance as an ASCII space or hyphen, using the `nobreak-space'
32499 or `nobreak-hyphen' face respectively.
32501 U+00A0 (no-break space), U+00AD (soft hyphen), U+2010 (hyphen), and
32502 U+2011 (non-breaking hyphen) are affected.
32504 Any other non-nil value means to display these characters as an escape
32505 glyph followed by an ordinary space or hyphen.
32507 A value of nil means no special handling of these characters. */);
32508 Vnobreak_char_display = Qt;
32510 DEFVAR_LISP ("void-text-area-pointer", Vvoid_text_area_pointer,
32511 doc: /* The pointer shape to show in void text areas.
32512 A value of nil means to show the text pointer. Other options are
32513 `arrow', `text', `hand', `vdrag', `hdrag', `nhdrag', `modeline', and
32514 `hourglass'. */);
32515 Vvoid_text_area_pointer = Qarrow;
32517 DEFVAR_LISP ("inhibit-redisplay", Vinhibit_redisplay,
32518 doc: /* Non-nil means don't actually do any redisplay.
32519 This is used for internal purposes. */);
32520 Vinhibit_redisplay = Qnil;
32522 DEFVAR_LISP ("global-mode-string", Vglobal_mode_string,
32523 doc: /* String (or mode line construct) included (normally) in `mode-line-format'. */);
32524 Vglobal_mode_string = Qnil;
32526 DEFVAR_LISP ("overlay-arrow-position", Voverlay_arrow_position,
32527 doc: /* Marker for where to display an arrow on top of the buffer text.
32528 This must be the beginning of a line in order to work.
32529 See also `overlay-arrow-string'. */);
32530 Voverlay_arrow_position = Qnil;
32532 DEFVAR_LISP ("overlay-arrow-string", Voverlay_arrow_string,
32533 doc: /* String to display as an arrow in non-window frames.
32534 See also `overlay-arrow-position'. */);
32535 Voverlay_arrow_string = build_pure_c_string ("=>");
32537 DEFVAR_LISP ("overlay-arrow-variable-list", Voverlay_arrow_variable_list,
32538 doc: /* List of variables (symbols) which hold markers for overlay arrows.
32539 The symbols on this list are examined during redisplay to determine
32540 where to display overlay arrows. */);
32541 Voverlay_arrow_variable_list
32542 = list1 (intern_c_string ("overlay-arrow-position"));
32544 DEFVAR_INT ("scroll-step", emacs_scroll_step,
32545 doc: /* The number of lines to try scrolling a window by when point moves out.
32546 If that fails to bring point back on frame, point is centered instead.
32547 If this is zero, point is always centered after it moves off frame.
32548 If you want scrolling to always be a line at a time, you should set
32549 `scroll-conservatively' to a large value rather than set this to 1. */);
32551 DEFVAR_INT ("scroll-conservatively", scroll_conservatively,
32552 doc: /* Scroll up to this many lines, to bring point back on screen.
32553 If point moves off-screen, redisplay will scroll by up to
32554 `scroll-conservatively' lines in order to bring point just barely
32555 onto the screen again. If that cannot be done, then redisplay
32556 recenters point as usual.
32558 If the value is greater than 100, redisplay will never recenter point,
32559 but will always scroll just enough text to bring point into view, even
32560 if you move far away.
32562 A value of zero means always recenter point if it moves off screen. */);
32563 scroll_conservatively = 0;
32565 DEFVAR_INT ("scroll-margin", scroll_margin,
32566 doc: /* Number of lines of margin at the top and bottom of a window.
32567 Trigger automatic scrolling whenever point gets within this many lines
32568 of the top or bottom of the window (see info node `Auto Scrolling'). */);
32569 scroll_margin = 0;
32571 DEFVAR_LISP ("maximum-scroll-margin", Vmaximum_scroll_margin,
32572 doc: /* Maximum effective value of `scroll-margin'.
32573 Given as a fraction of the current window's lines. The value should
32574 be a floating point number between 0.0 and 0.5. The effective maximum
32575 is limited to (/ (1- window-lines) 2). Non-float values for this
32576 variable are ignored and the default 0.25 is used instead. */);
32577 Vmaximum_scroll_margin = make_float (0.25);
32579 DEFVAR_LISP ("display-pixels-per-inch", Vdisplay_pixels_per_inch,
32580 doc: /* Pixels per inch value for non-window system displays.
32581 Value is a number or a cons (WIDTH-DPI . HEIGHT-DPI). */);
32582 Vdisplay_pixels_per_inch = make_float (72.0);
32584 #ifdef GLYPH_DEBUG
32585 DEFVAR_INT ("debug-end-pos", debug_end_pos, doc: /* Don't ask. */);
32586 #endif
32588 DEFVAR_LISP ("truncate-partial-width-windows",
32589 Vtruncate_partial_width_windows,
32590 doc: /* Non-nil means truncate lines in windows narrower than the frame.
32591 For an integer value, truncate lines in each window narrower than the
32592 full frame width, provided the total window width in column units is less
32593 than that integer; otherwise, respect the value of `truncate-lines'.
32594 The total width of the window is as returned by `window-total-width', it
32595 includes the fringes, the continuation and truncation glyphs, the
32596 display margins (if any), and the scroll bar
32598 For any other non-nil value, truncate lines in all windows that do
32599 not span the full frame width.
32601 A value of nil means to respect the value of `truncate-lines'.
32603 If `word-wrap' is enabled, you might want to reduce this. */);
32604 Vtruncate_partial_width_windows = make_number (50);
32606 DEFVAR_LISP ("line-number-display-limit", Vline_number_display_limit,
32607 doc: /* Maximum buffer size for which line number should be displayed.
32608 If the buffer is bigger than this, the line number does not appear
32609 in the mode line. A value of nil means no limit. */);
32610 Vline_number_display_limit = Qnil;
32612 DEFVAR_INT ("line-number-display-limit-width",
32613 line_number_display_limit_width,
32614 doc: /* Maximum line width (in characters) for line number display.
32615 If the average length of the lines near point is bigger than this, then the
32616 line number may be omitted from the mode line. */);
32617 line_number_display_limit_width = 200;
32619 DEFVAR_BOOL ("highlight-nonselected-windows", highlight_nonselected_windows,
32620 doc: /* Non-nil means highlight region even in nonselected windows. */);
32621 highlight_nonselected_windows = false;
32623 DEFVAR_BOOL ("multiple-frames", multiple_frames,
32624 doc: /* Non-nil if more than one frame is visible on this display.
32625 Minibuffer-only frames don't count, but iconified frames do.
32626 This variable is not guaranteed to be accurate except while processing
32627 `frame-title-format' and `icon-title-format'. */);
32629 DEFVAR_LISP ("frame-title-format", Vframe_title_format,
32630 doc: /* Template for displaying the title bar of visible frames.
32631 \(Assuming the window manager supports this feature.)
32633 This variable has the same structure as `mode-line-format', except that
32634 the %c, %C, and %l constructs are ignored. It is used only on frames for
32635 which no explicit name has been set (see `modify-frame-parameters'). */);
32637 DEFVAR_LISP ("icon-title-format", Vicon_title_format,
32638 doc: /* Template for displaying the title bar of an iconified frame.
32639 \(Assuming the window manager supports this feature.)
32640 This variable has the same structure as `mode-line-format' (which see),
32641 and is used only on frames for which no explicit name has been set
32642 \(see `modify-frame-parameters'). */);
32643 Vicon_title_format
32644 = Vframe_title_format
32645 = listn (CONSTYPE_PURE, 3,
32646 intern_c_string ("multiple-frames"),
32647 build_pure_c_string ("%b"),
32648 listn (CONSTYPE_PURE, 4,
32649 empty_unibyte_string,
32650 intern_c_string ("invocation-name"),
32651 build_pure_c_string ("@"),
32652 intern_c_string ("system-name")));
32654 DEFVAR_LISP ("message-log-max", Vmessage_log_max,
32655 doc: /* Maximum number of lines to keep in the message log buffer.
32656 If nil, disable message logging. If t, log messages but don't truncate
32657 the buffer when it becomes large. */);
32658 Vmessage_log_max = make_number (1000);
32660 DEFVAR_LISP ("window-scroll-functions", Vwindow_scroll_functions,
32661 doc: /* List of functions to call before redisplaying a window with scrolling.
32662 Each function is called with two arguments, the window and its new
32663 display-start position.
32664 These functions are called whenever the `window-start' marker is modified,
32665 either to point into another buffer (e.g. via `set-window-buffer') or another
32666 place in the same buffer.
32667 When each function is called, the `window-start' marker of its window
32668 argument has been already set to the new value, and the buffer which that
32669 window will display is set to be the current buffer.
32670 Note that the value of `window-end' is not valid when these functions are
32671 called.
32673 Warning: Do not use this feature to alter the way the window
32674 is scrolled. It is not designed for that, and such use probably won't
32675 work. */);
32676 Vwindow_scroll_functions = Qnil;
32678 DEFVAR_LISP ("redisplay-end-trigger-functions", Vredisplay_end_trigger_functions,
32679 doc: /* Functions called when redisplay of a window reaches the end trigger.
32680 Each function is called with two arguments, the window and the end trigger value.
32681 See `set-window-redisplay-end-trigger'. */);
32682 Vredisplay_end_trigger_functions = Qnil;
32684 DEFVAR_LISP ("mouse-autoselect-window", Vmouse_autoselect_window,
32685 doc: /* Non-nil means autoselect window with mouse pointer.
32686 If nil, do not autoselect windows.
32687 A positive number means delay autoselection by that many seconds: a
32688 window is autoselected only after the mouse has remained in that
32689 window for the duration of the delay.
32690 A negative number has a similar effect, but causes windows to be
32691 autoselected only after the mouse has stopped moving. (Because of
32692 the way Emacs compares mouse events, you will occasionally wait twice
32693 that time before the window gets selected.)
32694 Any other value means to autoselect window instantaneously when the
32695 mouse pointer enters it.
32697 Autoselection selects the minibuffer only if it is active, and never
32698 unselects the minibuffer if it is active.
32700 When customizing this variable make sure that the actual value of
32701 `focus-follows-mouse' matches the behavior of your window manager. */);
32702 Vmouse_autoselect_window = Qnil;
32704 DEFVAR_LISP ("auto-resize-tool-bars", Vauto_resize_tool_bars,
32705 doc: /* Non-nil means automatically resize tool-bars.
32706 This dynamically changes the tool-bar's height to the minimum height
32707 that is needed to make all tool-bar items visible.
32708 If value is `grow-only', the tool-bar's height is only increased
32709 automatically; to decrease the tool-bar height, use \\[recenter]. */);
32710 Vauto_resize_tool_bars = Qt;
32712 DEFVAR_BOOL ("auto-raise-tool-bar-buttons", auto_raise_tool_bar_buttons_p,
32713 doc: /* Non-nil means raise tool-bar buttons when the mouse moves over them. */);
32714 auto_raise_tool_bar_buttons_p = true;
32716 DEFVAR_BOOL ("make-cursor-line-fully-visible", make_cursor_line_fully_visible_p,
32717 doc: /* Non-nil means to scroll (recenter) cursor line if it is not fully visible. */);
32718 make_cursor_line_fully_visible_p = true;
32720 DEFVAR_LISP ("tool-bar-border", Vtool_bar_border,
32721 doc: /* Border below tool-bar in pixels.
32722 If an integer, use it as the height of the border.
32723 If it is one of `internal-border-width' or `border-width', use the
32724 value of the corresponding frame parameter.
32725 Otherwise, no border is added below the tool-bar. */);
32726 Vtool_bar_border = Qinternal_border_width;
32728 DEFVAR_LISP ("tool-bar-button-margin", Vtool_bar_button_margin,
32729 doc: /* Margin around tool-bar buttons in pixels.
32730 If an integer, use that for both horizontal and vertical margins.
32731 Otherwise, value should be a pair of integers `(HORZ . VERT)' with
32732 HORZ specifying the horizontal margin, and VERT specifying the
32733 vertical margin. */);
32734 Vtool_bar_button_margin = make_number (DEFAULT_TOOL_BAR_BUTTON_MARGIN);
32736 DEFVAR_INT ("tool-bar-button-relief", tool_bar_button_relief,
32737 doc: /* Relief thickness of tool-bar buttons. */);
32738 tool_bar_button_relief = DEFAULT_TOOL_BAR_BUTTON_RELIEF;
32740 DEFVAR_LISP ("tool-bar-style", Vtool_bar_style,
32741 doc: /* Tool bar style to use.
32742 It can be one of
32743 image - show images only
32744 text - show text only
32745 both - show both, text below image
32746 both-horiz - show text to the right of the image
32747 text-image-horiz - show text to the left of the image
32748 any other - use system default or image if no system default.
32750 This variable only affects the GTK+ toolkit version of Emacs. */);
32751 Vtool_bar_style = Qnil;
32753 DEFVAR_INT ("tool-bar-max-label-size", tool_bar_max_label_size,
32754 doc: /* Maximum number of characters a label can have to be shown.
32755 The tool bar style must also show labels for this to have any effect, see
32756 `tool-bar-style'. */);
32757 tool_bar_max_label_size = DEFAULT_TOOL_BAR_LABEL_SIZE;
32759 DEFVAR_LISP ("fontification-functions", Vfontification_functions,
32760 doc: /* List of functions to call to fontify regions of text.
32761 Each function is called with one argument POS. Functions must
32762 fontify a region starting at POS in the current buffer, and give
32763 fontified regions the property `fontified'. */);
32764 Vfontification_functions = Qnil;
32765 Fmake_variable_buffer_local (Qfontification_functions);
32767 DEFVAR_BOOL ("unibyte-display-via-language-environment",
32768 unibyte_display_via_language_environment,
32769 doc: /* Non-nil means display unibyte text according to language environment.
32770 Specifically, this means that raw bytes in the range 160-255 decimal
32771 are displayed by converting them to the equivalent multibyte characters
32772 according to the current language environment. As a result, they are
32773 displayed according to the current fontset.
32775 Note that this variable affects only how these bytes are displayed,
32776 but does not change the fact they are interpreted as raw bytes. */);
32777 unibyte_display_via_language_environment = false;
32779 DEFVAR_LISP ("max-mini-window-height", Vmax_mini_window_height,
32780 doc: /* Maximum height for resizing mini-windows (the minibuffer and the echo area).
32781 If a float, it specifies a fraction of the mini-window frame's height.
32782 If an integer, it specifies a number of lines. */);
32783 Vmax_mini_window_height = make_float (0.25);
32785 DEFVAR_LISP ("resize-mini-windows", Vresize_mini_windows,
32786 doc: /* How to resize mini-windows (the minibuffer and the echo area).
32787 A value of nil means don't automatically resize mini-windows.
32788 A value of t means resize them to fit the text displayed in them.
32789 A value of `grow-only', the default, means let mini-windows grow only;
32790 they return to their normal size when the minibuffer is closed, or the
32791 echo area becomes empty. */);
32792 /* Contrary to the doc string, we initialize this to nil, so that
32793 loading loadup.el won't try to resize windows before loading
32794 window.el, where some functions we need to call for this live.
32795 We assign the 'grow-only' value right after loading window.el
32796 during loadup. */
32797 Vresize_mini_windows = Qnil;
32799 DEFVAR_LISP ("blink-cursor-alist", Vblink_cursor_alist,
32800 doc: /* Alist specifying how to blink the cursor off.
32801 Each element has the form (ON-STATE . OFF-STATE). Whenever the
32802 `cursor-type' frame-parameter or variable equals ON-STATE,
32803 comparing using `equal', Emacs uses OFF-STATE to specify
32804 how to blink it off. ON-STATE and OFF-STATE are values for
32805 the `cursor-type' frame parameter.
32807 If a frame's ON-STATE has no entry in this list,
32808 the frame's other specifications determine how to blink the cursor off. */);
32809 Vblink_cursor_alist = Qnil;
32811 DEFVAR_LISP ("auto-hscroll-mode", automatic_hscrolling,
32812 doc: /* Allow or disallow automatic horizontal scrolling of windows.
32813 The value `current-line' means the line displaying point in each window
32814 is automatically scrolled horizontally to make point visible.
32815 Any other non-nil value means all the lines in a window are automatically
32816 scrolled horizontally to make point visible. */);
32817 automatic_hscrolling = Qt;
32818 DEFSYM (Qauto_hscroll_mode, "auto-hscroll-mode");
32819 DEFSYM (Qcurrent_line, "current-line");
32821 DEFVAR_INT ("hscroll-margin", hscroll_margin,
32822 doc: /* How many columns away from the window edge point is allowed to get
32823 before automatic hscrolling will horizontally scroll the window. */);
32824 hscroll_margin = 5;
32826 DEFVAR_LISP ("hscroll-step", Vhscroll_step,
32827 doc: /* How many columns to scroll the window when point gets too close to the edge.
32828 When point is less than `hscroll-margin' columns from the window
32829 edge, automatic hscrolling will scroll the window by the amount of columns
32830 determined by this variable. If its value is a positive integer, scroll that
32831 many columns. If it's a positive floating-point number, it specifies the
32832 fraction of the window's width to scroll. If it's nil or zero, point will be
32833 centered horizontally after the scroll. Any other value, including negative
32834 numbers, are treated as if the value were zero.
32836 Automatic hscrolling always moves point outside the scroll margin, so if
32837 point was more than scroll step columns inside the margin, the window will
32838 scroll more than the value given by the scroll step.
32840 Note that the lower bound for automatic hscrolling specified by `scroll-left'
32841 and `scroll-right' overrides this variable's effect. */);
32842 Vhscroll_step = make_number (0);
32844 DEFVAR_BOOL ("message-truncate-lines", message_truncate_lines,
32845 doc: /* If non-nil, messages are truncated instead of resizing the echo area.
32846 Bind this around calls to `message' to let it take effect. */);
32847 message_truncate_lines = false;
32849 DEFVAR_LISP ("menu-bar-update-hook", Vmenu_bar_update_hook,
32850 doc: /* Normal hook run to update the menu bar definitions.
32851 Redisplay runs this hook before it redisplays the menu bar.
32852 This is used to update menus such as Buffers, whose contents depend on
32853 various data. */);
32854 Vmenu_bar_update_hook = Qnil;
32856 DEFVAR_LISP ("menu-updating-frame", Vmenu_updating_frame,
32857 doc: /* Frame for which we are updating a menu.
32858 The enable predicate for a menu binding should check this variable. */);
32859 Vmenu_updating_frame = Qnil;
32861 DEFVAR_BOOL ("inhibit-menubar-update", inhibit_menubar_update,
32862 doc: /* Non-nil means don't update menu bars. Internal use only. */);
32863 inhibit_menubar_update = false;
32865 DEFVAR_LISP ("wrap-prefix", Vwrap_prefix,
32866 doc: /* Prefix prepended to all continuation lines at display time.
32867 The value may be a string, an image, or a stretch-glyph; it is
32868 interpreted in the same way as the value of a `display' text property.
32870 This variable is overridden by any `wrap-prefix' text or overlay
32871 property.
32873 To add a prefix to non-continuation lines, use `line-prefix'. */);
32874 Vwrap_prefix = Qnil;
32875 DEFSYM (Qwrap_prefix, "wrap-prefix");
32876 Fmake_variable_buffer_local (Qwrap_prefix);
32878 DEFVAR_LISP ("line-prefix", Vline_prefix,
32879 doc: /* Prefix prepended to all non-continuation lines at display time.
32880 The value may be a string, an image, or a stretch-glyph; it is
32881 interpreted in the same way as the value of a `display' text property.
32883 This variable is overridden by any `line-prefix' text or overlay
32884 property.
32886 To add a prefix to continuation lines, use `wrap-prefix'. */);
32887 Vline_prefix = Qnil;
32888 DEFSYM (Qline_prefix, "line-prefix");
32889 Fmake_variable_buffer_local (Qline_prefix);
32891 DEFVAR_LISP ("display-line-numbers", Vdisplay_line_numbers,
32892 doc: /* Non-nil means display line numbers.
32893 If the value is t, display the absolute number of each line of a buffer
32894 shown in a window. Absolute line numbers count from the beginning of
32895 the current narrowing, or from buffer beginning. If the value is
32896 `relative', display for each line not containing the window's point its
32897 relative number instead, i.e. the number of the line relative to the
32898 line showing the window's point.
32900 In either case, line numbers are displayed at the beginning of each
32901 non-continuation line that displays buffer text, i.e. after each newline
32902 character that comes from the buffer. The value `visual' is like
32903 `relative' but counts screen lines instead of buffer lines. In practice
32904 this means that continuation lines count as well when calculating the
32905 relative number of a line.
32907 Lisp programs can disable display of a line number of a particular
32908 buffer line by putting the `display-line-numbers-disable' text property
32909 or overlay property on the first visible character of that line. */);
32910 Vdisplay_line_numbers = Qnil;
32911 DEFSYM (Qdisplay_line_numbers, "display-line-numbers");
32912 Fmake_variable_buffer_local (Qdisplay_line_numbers);
32913 DEFSYM (Qrelative, "relative");
32914 DEFSYM (Qvisual, "visual");
32916 DEFVAR_LISP ("display-line-numbers-width", Vdisplay_line_numbers_width,
32917 doc: /* Minimum width of space reserved for line number display.
32918 A positive number means reserve that many columns for line numbers,
32919 even if the actual number needs less space.
32920 The default value of nil means compute the space dynamically.
32921 Any other value is treated as nil. */);
32922 Vdisplay_line_numbers_width = Qnil;
32923 DEFSYM (Qdisplay_line_numbers_width, "display-line-numbers-width");
32924 Fmake_variable_buffer_local (Qdisplay_line_numbers_width);
32926 DEFVAR_LISP ("display-line-numbers-current-absolute",
32927 Vdisplay_line_numbers_current_absolute,
32928 doc: /* Non-nil means display absolute number of current line.
32929 This variable has effect only when `display-line-numbers' is
32930 either `relative' or `visual'. */);
32931 Vdisplay_line_numbers_current_absolute = Qt;
32933 DEFVAR_BOOL ("display-line-numbers-widen", display_line_numbers_widen,
32934 doc: /* Non-nil means display line numbers disregarding any narrowing. */);
32935 display_line_numbers_widen = false;
32936 DEFSYM (Qdisplay_line_numbers_widen, "display-line-numbers-widen");
32937 Fmake_variable_buffer_local (Qdisplay_line_numbers_widen);
32939 DEFVAR_BOOL ("inhibit-eval-during-redisplay", inhibit_eval_during_redisplay,
32940 doc: /* Non-nil means don't eval Lisp during redisplay. */);
32941 inhibit_eval_during_redisplay = false;
32943 DEFVAR_BOOL ("inhibit-free-realized-faces", inhibit_free_realized_faces,
32944 doc: /* Non-nil means don't free realized faces. Internal use only. */);
32945 inhibit_free_realized_faces = false;
32947 DEFVAR_BOOL ("inhibit-bidi-mirroring", inhibit_bidi_mirroring,
32948 doc: /* Non-nil means don't mirror characters even when bidi context requires that.
32949 Intended for use during debugging and for testing bidi display;
32950 see biditest.el in the test suite. */);
32951 inhibit_bidi_mirroring = false;
32953 #ifdef GLYPH_DEBUG
32954 DEFVAR_BOOL ("inhibit-try-window-id", inhibit_try_window_id,
32955 doc: /* Inhibit try_window_id display optimization. */);
32956 inhibit_try_window_id = false;
32958 DEFVAR_BOOL ("inhibit-try-window-reusing", inhibit_try_window_reusing,
32959 doc: /* Inhibit try_window_reusing display optimization. */);
32960 inhibit_try_window_reusing = false;
32962 DEFVAR_BOOL ("inhibit-try-cursor-movement", inhibit_try_cursor_movement,
32963 doc: /* Inhibit try_cursor_movement display optimization. */);
32964 inhibit_try_cursor_movement = false;
32965 #endif /* GLYPH_DEBUG */
32967 DEFVAR_INT ("overline-margin", overline_margin,
32968 doc: /* Space between overline and text, in pixels.
32969 The default value is 2: the height of the overline (1 pixel) plus 1 pixel
32970 margin to the character height. */);
32971 overline_margin = 2;
32973 DEFVAR_INT ("underline-minimum-offset",
32974 underline_minimum_offset,
32975 doc: /* Minimum distance between baseline and underline.
32976 This can improve legibility of underlined text at small font sizes,
32977 particularly when using variable `x-use-underline-position-properties'
32978 with fonts that specify an UNDERLINE_POSITION relatively close to the
32979 baseline. The default value is 1. */);
32980 underline_minimum_offset = 1;
32982 DEFVAR_BOOL ("display-hourglass", display_hourglass_p,
32983 doc: /* Non-nil means show an hourglass pointer, when Emacs is busy.
32984 This feature only works when on a window system that can change
32985 cursor shapes. */);
32986 display_hourglass_p = true;
32988 DEFVAR_LISP ("hourglass-delay", Vhourglass_delay,
32989 doc: /* Seconds to wait before displaying an hourglass pointer when Emacs is busy. */);
32990 Vhourglass_delay = make_number (DEFAULT_HOURGLASS_DELAY);
32992 #ifdef HAVE_WINDOW_SYSTEM
32993 hourglass_atimer = NULL;
32994 hourglass_shown_p = false;
32995 #endif /* HAVE_WINDOW_SYSTEM */
32997 /* Name of the face used to display glyphless characters. */
32998 DEFSYM (Qglyphless_char, "glyphless-char");
33000 /* Method symbols for Vglyphless_char_display. */
33001 DEFSYM (Qhex_code, "hex-code");
33002 DEFSYM (Qempty_box, "empty-box");
33003 DEFSYM (Qthin_space, "thin-space");
33004 DEFSYM (Qzero_width, "zero-width");
33006 DEFVAR_LISP ("pre-redisplay-function", Vpre_redisplay_function,
33007 doc: /* Function run just before redisplay.
33008 It is called with one argument, which is the set of windows that are to
33009 be redisplayed. This set can be nil (meaning, only the selected window),
33010 or t (meaning all windows). */);
33011 Vpre_redisplay_function = intern ("ignore");
33013 /* Symbol for the purpose of Vglyphless_char_display. */
33014 DEFSYM (Qglyphless_char_display, "glyphless-char-display");
33015 Fput (Qglyphless_char_display, Qchar_table_extra_slots, make_number (1));
33017 DEFVAR_LISP ("glyphless-char-display", Vglyphless_char_display,
33018 doc: /* Char-table defining glyphless characters.
33019 Each element, if non-nil, should be one of the following:
33020 an ASCII acronym string: display this string in a box
33021 `hex-code': display the hexadecimal code of a character in a box
33022 `empty-box': display as an empty box
33023 `thin-space': display as 1-pixel width space
33024 `zero-width': don't display
33025 An element may also be a cons cell (GRAPHICAL . TEXT), which specifies the
33026 display method for graphical terminals and text terminals respectively.
33027 GRAPHICAL and TEXT should each have one of the values listed above.
33029 The char-table has one extra slot to control the display of a character for
33030 which no font is found. This slot only takes effect on graphical terminals.
33031 Its value should be an ASCII acronym string, `hex-code', `empty-box', or
33032 `thin-space'. The default is `empty-box'.
33034 If a character has a non-nil entry in an active display table, the
33035 display table takes effect; in this case, Emacs does not consult
33036 `glyphless-char-display' at all. */);
33037 Vglyphless_char_display = Fmake_char_table (Qglyphless_char_display, Qnil);
33038 Fset_char_table_extra_slot (Vglyphless_char_display, make_number (0),
33039 Qempty_box);
33041 DEFVAR_LISP ("debug-on-message", Vdebug_on_message,
33042 doc: /* If non-nil, debug if a message matching this regexp is displayed. */);
33043 Vdebug_on_message = Qnil;
33045 DEFVAR_LISP ("redisplay--all-windows-cause", Vredisplay__all_windows_cause,
33046 doc: /* */);
33047 Vredisplay__all_windows_cause = Fmake_hash_table (0, NULL);
33049 DEFVAR_LISP ("redisplay--mode-lines-cause", Vredisplay__mode_lines_cause,
33050 doc: /* */);
33051 Vredisplay__mode_lines_cause = Fmake_hash_table (0, NULL);
33053 DEFVAR_BOOL ("redisplay--inhibit-bidi", redisplay__inhibit_bidi,
33054 doc: /* Non-nil means it is not safe to attempt bidi reordering for display. */);
33055 /* Initialize to t, since we need to disable reordering until
33056 loadup.el successfully loads charprop.el. */
33057 redisplay__inhibit_bidi = true;
33059 DEFVAR_BOOL ("display-raw-bytes-as-hex", display_raw_bytes_as_hex,
33060 doc: /* Non-nil means display raw bytes in hexadecimal format.
33061 The default is to use octal format (\200) whereas hexadecimal (\x80)
33062 may be more familiar to users. */);
33063 display_raw_bytes_as_hex = false;
33068 /* Initialize this module when Emacs starts. */
33070 void
33071 init_xdisp (void)
33073 CHARPOS (this_line_start_pos) = 0;
33075 if (!noninteractive)
33077 struct window *m = XWINDOW (minibuf_window);
33078 Lisp_Object frame = m->frame;
33079 struct frame *f = XFRAME (frame);
33080 Lisp_Object root = FRAME_ROOT_WINDOW (f);
33081 struct window *r = XWINDOW (root);
33082 int i;
33084 echo_area_window = minibuf_window;
33086 r->top_line = FRAME_TOP_MARGIN (f);
33087 r->pixel_top = r->top_line * FRAME_LINE_HEIGHT (f);
33088 r->total_cols = FRAME_COLS (f);
33089 r->pixel_width = r->total_cols * FRAME_COLUMN_WIDTH (f);
33090 r->total_lines = FRAME_TOTAL_LINES (f) - 1 - FRAME_TOP_MARGIN (f);
33091 r->pixel_height = r->total_lines * FRAME_LINE_HEIGHT (f);
33093 m->top_line = FRAME_TOTAL_LINES (f) - 1;
33094 m->pixel_top = m->top_line * FRAME_LINE_HEIGHT (f);
33095 m->total_cols = FRAME_COLS (f);
33096 m->pixel_width = m->total_cols * FRAME_COLUMN_WIDTH (f);
33097 m->total_lines = 1;
33098 m->pixel_height = m->total_lines * FRAME_LINE_HEIGHT (f);
33100 scratch_glyph_row.glyphs[TEXT_AREA] = scratch_glyphs;
33101 scratch_glyph_row.glyphs[TEXT_AREA + 1]
33102 = scratch_glyphs + MAX_SCRATCH_GLYPHS;
33104 /* The default ellipsis glyphs `...'. */
33105 for (i = 0; i < 3; ++i)
33106 default_invis_vector[i] = make_number ('.');
33110 /* Allocate the buffer for frame titles.
33111 Also used for `format-mode-line'. */
33112 int size = 100;
33113 mode_line_noprop_buf = xmalloc (size);
33114 mode_line_noprop_buf_end = mode_line_noprop_buf + size;
33115 mode_line_noprop_ptr = mode_line_noprop_buf;
33116 mode_line_target = MODE_LINE_DISPLAY;
33119 help_echo_showing_p = false;
33122 #ifdef HAVE_WINDOW_SYSTEM
33124 /* Platform-independent portion of hourglass implementation. */
33126 /* Timer function of hourglass_atimer. */
33128 static void
33129 show_hourglass (struct atimer *timer)
33131 /* The timer implementation will cancel this timer automatically
33132 after this function has run. Set hourglass_atimer to null
33133 so that we know the timer doesn't have to be canceled. */
33134 hourglass_atimer = NULL;
33136 if (!hourglass_shown_p)
33138 Lisp_Object tail, frame;
33140 block_input ();
33142 FOR_EACH_FRAME (tail, frame)
33144 struct frame *f = XFRAME (frame);
33146 if (FRAME_LIVE_P (f) && FRAME_WINDOW_P (f)
33147 && FRAME_RIF (f)->show_hourglass)
33148 FRAME_RIF (f)->show_hourglass (f);
33151 hourglass_shown_p = true;
33152 unblock_input ();
33156 /* Cancel a currently active hourglass timer, and start a new one. */
33158 void
33159 start_hourglass (void)
33161 struct timespec delay;
33163 cancel_hourglass ();
33165 if (INTEGERP (Vhourglass_delay)
33166 && XINT (Vhourglass_delay) > 0)
33167 delay = make_timespec (min (XINT (Vhourglass_delay),
33168 TYPE_MAXIMUM (time_t)),
33170 else if (FLOATP (Vhourglass_delay)
33171 && XFLOAT_DATA (Vhourglass_delay) > 0)
33172 delay = dtotimespec (XFLOAT_DATA (Vhourglass_delay));
33173 else
33174 delay = make_timespec (DEFAULT_HOURGLASS_DELAY, 0);
33176 hourglass_atimer = start_atimer (ATIMER_RELATIVE, delay,
33177 show_hourglass, NULL);
33180 /* Cancel the hourglass cursor timer if active, hide a busy cursor if
33181 shown. */
33183 void
33184 cancel_hourglass (void)
33186 if (hourglass_atimer)
33188 cancel_atimer (hourglass_atimer);
33189 hourglass_atimer = NULL;
33192 if (hourglass_shown_p)
33194 Lisp_Object tail, frame;
33196 block_input ();
33198 FOR_EACH_FRAME (tail, frame)
33200 struct frame *f = XFRAME (frame);
33202 if (FRAME_LIVE_P (f) && FRAME_WINDOW_P (f)
33203 && FRAME_RIF (f)->hide_hourglass)
33204 FRAME_RIF (f)->hide_hourglass (f);
33205 #ifdef HAVE_NTGUI
33206 /* No cursors on non GUI frames - restore to stock arrow cursor. */
33207 else if (!FRAME_W32_P (f))
33208 w32_arrow_cursor ();
33209 #endif
33212 hourglass_shown_p = false;
33213 unblock_input ();
33217 #endif /* HAVE_WINDOW_SYSTEM */