1 /* Display generation from window structure and buffer text.
3 Copyright (C) 1985-1988, 1993-1995, 1997-2018 Free Software Foundation,
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>.
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
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
57 +--------------+ redisplay +----------------+
58 | Lisp machine |---------------->| Redisplay code |<--+
59 +--------------+ (xdisp.c) +----------------+ |
61 +----------------------------------+ |
62 Block input to prevent this when |
63 called asynchronously! |
65 note_mouse_highlight (asynchronous) |
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
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
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
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
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.
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)
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
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).
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
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. */
312 #include "composite.h"
313 #include "keyboard.h"
317 #include "termchar.h"
318 #include "dispextern.h"
319 #include "character.h"
323 #include "commands.h"
326 #include "termhooks.h"
327 #include "termopts.h"
328 #include "intervals.h"
330 #include "region-cache.h"
333 #include "blockinput.h"
335 #ifdef HAVE_WINDOW_SYSTEM
337 #endif /* HAVE_WINDOW_SYSTEM */
339 #ifndef FRAME_X_OUTPUT
340 #define FRAME_X_OUTPUT(f) ((f)->output_data.x)
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')) \
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
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
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) \
576 bidi_unshelve_cache (CACHE, true); \
578 CACHE = bidi_shelve_cache (); \
581 #define RESTORE_IT(pITORIG, pITCOPY, CACHE) \
583 if (pITORIG != pITCOPY) \
584 *(pITORIG) = *(pITCOPY); \
585 bidi_unshelve_cache (CACHE, false); \
589 /* Functions to mark elements as needing redisplay. */
590 enum { REDISPLAY_SOME
= 2}; /* Arbitrary choice. */
593 redisplay_other_windows (void)
595 if (!windows_or_buffers_changed
)
596 windows_or_buffers_changed
= REDISPLAY_SOME
;
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 ();
609 fset_redisplay (struct frame
*f
)
611 redisplay_other_windows ();
616 bset_redisplay (struct buffer
*b
)
618 int count
= buffer_window_count (b
);
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
627 b
->text
->redisplay
= true;
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;
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
665 #define TRACE_MOVE(x) (void) 0
668 /* Buffer being redisplayed -- for redisplay_window_error. */
670 static struct buffer
*displayed_buffer
;
672 /* Value returned from text property handlers (see below). */
677 HANDLED_RECOMPUTE_PROPS
,
678 HANDLED_OVERLAY_STRING_CONSUMED
,
682 /* A description of text properties that redisplay is interested
687 /* The symbol index of the name of the property. */
690 /* A unique index for the property. */
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
},
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. */
728 /* Not used. Undefined value. */
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. */
737 /* Move within a line ended at the end of a line that must be
741 /* Move within a line ended at the end of a line that would
742 be displayed truncated. */
745 /* Move within a line ended at a line end. */
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
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 };
767 /* True while redisplay_internal is in progress. */
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
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,
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
,
856 static int store_mode_line_string (const char *, Lisp_Object
, bool, int, int,
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,
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
*,
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
,
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
);
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
)
1005 if (ml_row
&& ml_row
->mode_line_p
)
1006 height
-= ml_row
->height
;
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
)
1017 if (hl_row
&& hl_row
->mode_line_p
)
1018 height
-= hl_row
->height
;
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
)
1037 if (w
->pseudo_window_p
)
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. */
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
),
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
);
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
));
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. */
1111 window_box (struct window
*w
, enum glyph_row_area area
, int *box_x
,
1112 int *box_y
, int *box_width
, int *box_height
)
1115 *box_width
= window_box_width (w
, area
);
1117 *box_height
= window_box_height (w
);
1119 *box_x
= window_box_left (w
, area
);
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
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 /***********************************************************************
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)
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
1175 struct glyph_row
*row
= it
->glyph_row
;
1177 /* Use the default character height. */
1178 it
->glyph_row
= NULL
;
1179 it
->what
= IT_CHARACTER
;
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. */)
1200 struct window
*w
= XWINDOW (selected_window
);
1201 struct buffer
*old_buffer
= NULL
;
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
1214 move_it_by_lines (&it
, 0);
1215 it
.vpos
= it
.current_y
= 0;
1217 result
= make_number (line_bottom_y (&it
));
1219 set_buffer_internal_1 (old_buffer
);
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
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
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
);
1250 val
= BVAR (&buffer_defaults
, extra_line_spacing
);
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;
1264 height
+= f
->extra_line_spacing
;
1270 /* Subroutine of pos_visible_p below. Extracts a display string, if
1271 any, from the display spec given as its argument. */
1273 string_from_display_spec (Lisp_Object spec
)
1277 for (ptrdiff_t i
= 0; i
< ASIZE (spec
); i
++)
1278 if (STRINGP (AREF (spec
, i
)))
1279 return AREF (spec
, i
);
1283 for (; CONSP (spec
); spec
= XCDR (spec
))
1284 if (STRINGP (XCAR (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. */
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). */
1314 pos_visible_p (struct window
*w
, ptrdiff_t charpos
, int *x
, int *y
,
1315 int *rtop
, int *rbot
, int *rowh
, int *vpos
)
1318 void *itdata
= bidi_shelve_cache ();
1319 struct text_pos top
;
1320 bool visible_p
= false;
1321 struct buffer
*old_buffer
= NULL
;
1324 if (FRAME_INITIAL_P (XFRAME (WINDOW_FRAME (w
))))
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
1343 if (charpos
>= 0 && CHARPOS (top
) > charpos
)
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
);
1362 = display_mode_line (w
, CURRENT_MODE_LINE_FACE_ID (w
),
1363 NILP (window_mode_line_format
)
1364 ? BVAR (current_buffer
, mode_line_format
)
1365 : window_mode_line_format
);
1368 if (window_wants_header_line (w
))
1370 Lisp_Object window_header_line_format
1371 = window_parameter (w
, Qheader_line_format
);
1373 w
->header_line_height
1374 = display_mode_line (w
, HEADER_LINE_FACE_ID
,
1375 NILP (window_header_line_format
)
1376 ? BVAR (current_buffer
, header_line_format
)
1377 : window_header_line_format
);
1380 start_display (&it
, w
, top
);
1381 move_it_to (&it
, charpos
, -1, it
.last_visible_y
- 1, -1,
1382 (charpos
>= 0 ? MOVE_TO_POS
: 0) | MOVE_TO_Y
);
1384 /* Adjust for line numbers, if CHARPOS is at or beyond first_visible_x,
1385 but we didn't yet produce the line-number glyphs. */
1386 if (!NILP (Vdisplay_line_numbers
)
1387 && it
.current_x
>= it
.first_visible_x
1388 && IT_CHARPOS (it
) == charpos
1389 && !it
.line_number_produced_p
)
1391 /* If the pixel width of line numbers was not yet known, compute
1392 it now. This usually happens in the first display line of a
1394 if (!it
.lnum_pixel_width
)
1397 void *it2data
= NULL
;
1399 SAVE_IT (it2
, it
, it2data
);
1400 move_it_by_lines (&it
, 1);
1401 it2
.lnum_pixel_width
= it
.lnum_pixel_width
;
1402 RESTORE_IT (&it
, &it2
, it2data
);
1404 it
.current_x
+= it
.lnum_pixel_width
;
1408 && (((!it
.bidi_p
|| it
.bidi_it
.scan_dir
!= -1)
1409 && IT_CHARPOS (it
) >= charpos
)
1410 /* When scanning backwards under bidi iteration, move_it_to
1411 stops at or _before_ CHARPOS, because it stops at or to
1412 the _right_ of the character at CHARPOS. */
1413 || (it
.bidi_p
&& it
.bidi_it
.scan_dir
== -1
1414 && IT_CHARPOS (it
) <= charpos
)))
1416 /* We have reached CHARPOS, or passed it. How the call to
1417 move_it_to can overshoot: (i) If CHARPOS is on invisible text
1418 or covered by a display property, move_it_to stops at the end
1419 of the invisible text, to the right of CHARPOS. (ii) If
1420 CHARPOS is in a display vector, move_it_to stops on its last
1422 int top_x
= it
.current_x
;
1423 int top_y
= it
.current_y
;
1424 int window_top_y
= WINDOW_HEADER_LINE_HEIGHT (w
);
1427 void *save_it_data
= NULL
;
1429 /* Calling line_bottom_y may change it.method, it.position, etc. */
1430 SAVE_IT (save_it
, it
, save_it_data
);
1432 bottom_y
= line_bottom_y (&it
);
1433 if (top_y
< window_top_y
)
1434 visible_p
= bottom_y
> window_top_y
;
1435 else if (top_y
< it
.last_visible_y
)
1437 if (bottom_y
>= it
.last_visible_y
1438 && it
.bidi_p
&& it
.bidi_it
.scan_dir
== -1
1439 && IT_CHARPOS (it
) < charpos
)
1441 /* When the last line of the window is scanned backwards
1442 under bidi iteration, we could be duped into thinking
1443 that we have passed CHARPOS, when in fact move_it_to
1444 simply stopped short of CHARPOS because it reached
1445 last_visible_y. To see if that's what happened, we call
1446 move_it_to again with a slightly larger vertical limit,
1447 and see if it actually moved vertically; if it did, we
1448 didn't really reach CHARPOS, which is beyond window end. */
1449 /* Why 10? because we don't know how many canonical lines
1450 will the height of the next line(s) be. So we guess. */
1451 int ten_more_lines
= 10 * default_line_pixel_height (w
);
1453 move_it_to (&it
, charpos
, -1, bottom_y
+ ten_more_lines
, -1,
1454 MOVE_TO_POS
| MOVE_TO_Y
);
1455 if (it
.current_y
> top_y
)
1459 RESTORE_IT (&it
, &save_it
, save_it_data
);
1462 if (it
.method
== GET_FROM_DISPLAY_VECTOR
)
1464 /* We stopped on the last glyph of a display vector.
1465 Try and recompute. Hack alert! */
1466 if (charpos
< 2 || top
.charpos
>= charpos
)
1467 top_x
= it
.glyph_row
->x
;
1470 struct it it2
, it2_prev
;
1471 /* The idea is to get to the previous buffer
1472 position, consume the character there, and use
1473 the pixel coordinates we get after that. But if
1474 the previous buffer position is also displayed
1475 from a display vector, we need to consume all of
1476 the glyphs from that display vector. */
1477 start_display (&it2
, w
, top
);
1478 move_it_to (&it2
, charpos
- 1, -1, -1, -1, MOVE_TO_POS
);
1479 /* If we didn't get to CHARPOS - 1, there's some
1480 replacing display property at that position, and
1481 we stopped after it. That is exactly the place
1482 whose coordinates we want. */
1483 if (IT_CHARPOS (it2
) != charpos
- 1)
1487 /* Iterate until we get out of the display
1488 vector that displays the character at
1491 get_next_display_element (&it2
);
1492 PRODUCE_GLYPHS (&it2
);
1494 set_iterator_to_next (&it2
, true);
1495 } while (it2
.method
== GET_FROM_DISPLAY_VECTOR
1496 && IT_CHARPOS (it2
) < charpos
);
1498 if (ITERATOR_AT_END_OF_LINE_P (&it2_prev
)
1499 || it2_prev
.current_x
> it2_prev
.last_visible_x
)
1500 top_x
= it
.glyph_row
->x
;
1503 top_x
= it2_prev
.current_x
;
1504 top_y
= it2_prev
.current_y
;
1508 else if (IT_CHARPOS (it
) != charpos
)
1510 Lisp_Object cpos
= make_number (charpos
);
1511 Lisp_Object spec
= Fget_char_property (cpos
, Qdisplay
, Qnil
);
1512 Lisp_Object string
= string_from_display_spec (spec
);
1513 struct text_pos tpos
;
1514 bool newline_in_string
1516 && memchr (SDATA (string
), '\n', SBYTES (string
)));
1518 SET_TEXT_POS (tpos
, charpos
, CHAR_TO_BYTE (charpos
));
1519 bool replacing_spec_p
1521 && handle_display_spec (NULL
, spec
, Qnil
, Qnil
, &tpos
,
1522 charpos
, FRAME_WINDOW_P (it
.f
)));
1523 /* The tricky code below is needed because there's a
1524 discrepancy between move_it_to and how we set cursor
1525 when PT is at the beginning of a portion of text
1526 covered by a display property or an overlay with a
1527 display property, or the display line ends in a
1528 newline from a display string. move_it_to will stop
1529 _after_ such display strings, whereas
1530 set_cursor_from_row conspires with cursor_row_p to
1531 place the cursor on the first glyph produced from the
1534 /* We have overshoot PT because it is covered by a
1535 display property that replaces the text it covers.
1536 If the string includes embedded newlines, we are also
1537 in the wrong display line. Backtrack to the correct
1538 line, where the display property begins. */
1539 if (replacing_spec_p
)
1541 Lisp_Object startpos
, endpos
;
1542 EMACS_INT start
, end
;
1545 /* Find the first and the last buffer positions
1546 covered by the display string. */
1548 Fnext_single_char_property_change (cpos
, Qdisplay
,
1551 Fprevious_single_char_property_change (endpos
, Qdisplay
,
1553 start
= XFASTINT (startpos
);
1554 end
= XFASTINT (endpos
);
1555 /* Move to the last buffer position before the
1556 display property. */
1557 start_display (&it3
, w
, top
);
1558 if (start
> CHARPOS (top
))
1559 move_it_to (&it3
, start
- 1, -1, -1, -1, MOVE_TO_POS
);
1560 /* Move forward one more line if the position before
1561 the display string is a newline or if it is the
1562 rightmost character on a line that is
1563 continued or word-wrapped. */
1564 if (it3
.method
== GET_FROM_BUFFER
1566 || FETCH_BYTE (IT_BYTEPOS (it3
)) == '\n'))
1567 move_it_by_lines (&it3
, 1);
1568 else if (move_it_in_display_line_to (&it3
, -1,
1572 == MOVE_LINE_CONTINUED
)
1574 move_it_by_lines (&it3
, 1);
1575 /* When we are under word-wrap, the #$@%!
1576 move_it_by_lines moves 2 lines, so we need to
1578 if (it3
.line_wrap
== WORD_WRAP
)
1579 move_it_by_lines (&it3
, -1);
1582 /* Record the vertical coordinate of the display
1583 line where we wound up. */
1584 top_y
= it3
.current_y
;
1587 /* When characters are reordered for display,
1588 the character displayed to the left of the
1589 display string could be _after_ the display
1590 property in the logical order. Use the
1591 smallest vertical position of these two. */
1592 start_display (&it3
, w
, top
);
1593 move_it_to (&it3
, end
+ 1, -1, -1, -1, MOVE_TO_POS
);
1594 if (it3
.current_y
< top_y
)
1595 top_y
= it3
.current_y
;
1597 /* Move from the top of the window to the beginning
1598 of the display line where the display string
1600 start_display (&it3
, w
, top
);
1601 move_it_to (&it3
, -1, 0, top_y
, -1, MOVE_TO_X
| MOVE_TO_Y
);
1602 /* If it3_moved stays false after the 'while' loop
1603 below, that means we already were at a newline
1604 before the loop (e.g., the display string begins
1605 with a newline), so we don't need to (and cannot)
1606 inspect the glyphs of it3.glyph_row, because
1607 PRODUCE_GLYPHS will not produce anything for a
1608 newline, and thus it3.glyph_row stays at its
1609 stale content it got at top of the window. */
1610 bool it3_moved
= false;
1611 /* Finally, advance the iterator until we hit the
1612 first display element whose character position is
1613 CHARPOS, or until the first newline from the
1614 display string, which signals the end of the
1616 while (get_next_display_element (&it3
))
1618 PRODUCE_GLYPHS (&it3
);
1619 if (IT_CHARPOS (it3
) == charpos
1620 || ITERATOR_AT_END_OF_LINE_P (&it3
))
1623 set_iterator_to_next (&it3
, false);
1625 top_x
= it3
.current_x
- it3
.pixel_width
;
1626 /* Normally, we would exit the above loop because we
1627 found the display element whose character
1628 position is CHARPOS. For the contingency that we
1629 didn't, and stopped at the first newline from the
1630 display string, move back over the glyphs
1631 produced from the string, until we find the
1632 rightmost glyph not from the string. */
1634 && newline_in_string
1635 && IT_CHARPOS (it3
) != charpos
&& EQ (it3
.object
, string
))
1637 struct glyph
*g
= it3
.glyph_row
->glyphs
[TEXT_AREA
]
1638 + it3
.glyph_row
->used
[TEXT_AREA
];
1640 while (EQ ((g
- 1)->object
, string
))
1643 top_x
-= g
->pixel_width
;
1645 eassert (g
< it3
.glyph_row
->glyphs
[TEXT_AREA
]
1646 + it3
.glyph_row
->used
[TEXT_AREA
]);
1652 *y
= max (top_y
+ max (0, it
.max_ascent
- it
.ascent
), window_top_y
);
1653 *rtop
= max (0, window_top_y
- top_y
);
1654 *rbot
= max (0, bottom_y
- it
.last_visible_y
);
1655 *rowh
= max (0, (min (bottom_y
, it
.last_visible_y
)
1656 - max (top_y
, window_top_y
)));
1658 if (it
.bidi_it
.paragraph_dir
== R2L
)
1664 /* Either we were asked to provide info about WINDOW_END, or
1665 CHARPOS is in the partially visible glyph row at end of
1668 void *it2data
= NULL
;
1670 SAVE_IT (it2
, it
, it2data
);
1671 if (IT_CHARPOS (it
) < ZV
&& FETCH_BYTE (IT_BYTEPOS (it
)) != '\n')
1672 move_it_by_lines (&it
, 1);
1673 if (charpos
< IT_CHARPOS (it
)
1674 || (it
.what
== IT_EOB
&& charpos
== IT_CHARPOS (it
)))
1677 RESTORE_IT (&it2
, &it2
, it2data
);
1678 move_it_to (&it2
, charpos
, -1, -1, -1, MOVE_TO_POS
);
1680 *y
= it2
.current_y
+ it2
.max_ascent
- it2
.ascent
;
1681 *rtop
= max (0, -it2
.current_y
);
1682 *rbot
= max (0, ((it2
.current_y
+ it2
.max_ascent
+ it2
.max_descent
)
1683 - it
.last_visible_y
));
1684 *rowh
= max (0, (min (it2
.current_y
+ it2
.max_ascent
+ it2
.max_descent
,
1686 - max (it2
.current_y
,
1687 WINDOW_HEADER_LINE_HEIGHT (w
))));
1689 if (it2
.bidi_it
.paragraph_dir
== R2L
)
1693 bidi_unshelve_cache (it2data
, true);
1695 bidi_unshelve_cache (itdata
, false);
1698 set_buffer_internal_1 (old_buffer
);
1704 window_hscroll_limited (w
, WINDOW_XFRAME (w
))
1705 * WINDOW_FRAME_COLUMN_WIDTH (w
);
1706 /* For lines in an R2L paragraph, we need to mirror the X pixel
1707 coordinate wrt the text area. For the reasons, see the
1708 commentary in buffer_posn_from_coords and the explanation of
1709 the geometry used by the move_it_* functions at the end of
1710 the large commentary near the beginning of this file. */
1712 *x
= window_box_width (w
, TEXT_AREA
) - *x
- 1;
1716 /* Debugging code. */
1718 fprintf (stderr
, "+pv pt=%d vs=%d --> x=%d y=%d rt=%d rb=%d rh=%d vp=%d\n",
1719 charpos
, w
->vscroll
, *x
, *y
, *rtop
, *rbot
, *rowh
, *vpos
);
1721 fprintf (stderr
, "-pv pt=%d vs=%d\n", charpos
, w
->vscroll
);
1724 /* Restore potentially overwritten values. */
1725 w
->mode_line_height
= prev_mode_line_height
;
1726 w
->header_line_height
= prev_header_line_height
;
1732 /* Return the next character from STR. Return in *LEN the length of
1733 the character. This is like STRING_CHAR_AND_LENGTH but never
1734 returns an invalid character. If we find one, we return a `?', but
1735 with the length of the invalid character. */
1738 string_char_and_length (const unsigned char *str
, int *len
)
1742 c
= STRING_CHAR_AND_LENGTH (str
, *len
);
1743 if (!CHAR_VALID_P (c
))
1744 /* We may not change the length here because other places in Emacs
1745 don't use this function, i.e. they silently accept invalid
1754 /* Given a position POS containing a valid character and byte position
1755 in STRING, return the position NCHARS ahead (NCHARS >= 0). */
1757 static struct text_pos
1758 string_pos_nchars_ahead (struct text_pos pos
, Lisp_Object string
, ptrdiff_t nchars
)
1760 eassert (STRINGP (string
) && nchars
>= 0);
1762 if (STRING_MULTIBYTE (string
))
1764 const unsigned char *p
= SDATA (string
) + BYTEPOS (pos
);
1769 string_char_and_length (p
, &len
);
1772 BYTEPOS (pos
) += len
;
1776 SET_TEXT_POS (pos
, CHARPOS (pos
) + nchars
, BYTEPOS (pos
) + nchars
);
1782 /* Value is the text position, i.e. character and byte position,
1783 for character position CHARPOS in STRING. */
1785 static struct text_pos
1786 string_pos (ptrdiff_t charpos
, Lisp_Object string
)
1788 struct text_pos pos
;
1789 eassert (STRINGP (string
));
1790 eassert (charpos
>= 0);
1791 SET_TEXT_POS (pos
, charpos
, string_char_to_byte (string
, charpos
));
1796 /* Value is a text position, i.e. character and byte position, for
1797 character position CHARPOS in C string S. MULTIBYTE_P
1798 means recognize multibyte characters. */
1800 static struct text_pos
1801 c_string_pos (ptrdiff_t charpos
, const char *s
, bool multibyte_p
)
1803 struct text_pos pos
;
1805 eassert (s
!= NULL
);
1806 eassert (charpos
>= 0);
1812 SET_TEXT_POS (pos
, 0, 0);
1815 string_char_and_length ((const unsigned char *) s
, &len
);
1818 BYTEPOS (pos
) += len
;
1822 SET_TEXT_POS (pos
, charpos
, charpos
);
1828 /* Value is the number of characters in C string S. MULTIBYTE_P
1829 means recognize multibyte characters. */
1832 number_of_chars (const char *s
, bool multibyte_p
)
1838 ptrdiff_t rest
= strlen (s
);
1840 const unsigned char *p
= (const unsigned char *) s
;
1842 for (nchars
= 0; rest
> 0; ++nchars
)
1844 string_char_and_length (p
, &len
);
1845 rest
-= len
, p
+= len
;
1849 nchars
= strlen (s
);
1855 /* Compute byte position NEWPOS->bytepos corresponding to
1856 NEWPOS->charpos. POS is a known position in string STRING.
1857 NEWPOS->charpos must be >= POS.charpos. */
1860 compute_string_pos (struct text_pos
*newpos
, struct text_pos pos
, Lisp_Object string
)
1862 eassert (STRINGP (string
));
1863 eassert (CHARPOS (*newpos
) >= CHARPOS (pos
));
1865 if (STRING_MULTIBYTE (string
))
1866 *newpos
= string_pos_nchars_ahead (pos
, string
,
1867 CHARPOS (*newpos
) - CHARPOS (pos
));
1869 BYTEPOS (*newpos
) = CHARPOS (*newpos
);
1873 Return an estimation of the pixel height of mode or header lines on
1874 frame F. FACE_ID specifies what line's height to estimate. */
1877 estimate_mode_line_height (struct frame
*f
, enum face_id face_id
)
1879 #ifdef HAVE_WINDOW_SYSTEM
1880 if (FRAME_WINDOW_P (f
))
1882 int height
= FONT_HEIGHT (FRAME_FONT (f
));
1884 /* This function is called so early when Emacs starts that the face
1885 cache and mode line face are not yet initialized. */
1886 if (FRAME_FACE_CACHE (f
))
1888 struct face
*face
= FACE_FROM_ID_OR_NULL (f
, face_id
);
1892 height
= normal_char_height (face
->font
, -1);
1893 if (face
->box_line_width
> 0)
1894 height
+= 2 * face
->box_line_width
;
1905 /* Given a pixel position (PIX_X, PIX_Y) on frame F, return glyph
1906 co-ordinates in (*X, *Y). Set *BOUNDS to the rectangle that the
1907 glyph at X, Y occupies, if BOUNDS != 0. If NOCLIP, do
1908 not force the value into range. */
1911 pixel_to_glyph_coords (struct frame
*f
, int pix_x
, int pix_y
, int *x
, int *y
,
1912 NativeRectangle
*bounds
, bool noclip
)
1915 #ifdef HAVE_WINDOW_SYSTEM
1916 if (FRAME_WINDOW_P (f
))
1918 /* Arrange for the division in FRAME_PIXEL_X_TO_COL etc. to round down
1919 even for negative values. */
1921 pix_x
-= FRAME_COLUMN_WIDTH (f
) - 1;
1923 pix_y
-= FRAME_LINE_HEIGHT (f
) - 1;
1925 pix_x
= FRAME_PIXEL_X_TO_COL (f
, pix_x
);
1926 pix_y
= FRAME_PIXEL_Y_TO_LINE (f
, pix_y
);
1929 STORE_NATIVE_RECT (*bounds
,
1930 FRAME_COL_TO_PIXEL_X (f
, pix_x
),
1931 FRAME_LINE_TO_PIXEL_Y (f
, pix_y
),
1932 FRAME_COLUMN_WIDTH (f
) - 1,
1933 FRAME_LINE_HEIGHT (f
) - 1);
1935 /* PXW: Should we clip pixels before converting to columns/lines? */
1940 else if (pix_x
> FRAME_TOTAL_COLS (f
))
1941 pix_x
= FRAME_TOTAL_COLS (f
);
1945 else if (pix_y
> FRAME_TOTAL_LINES (f
))
1946 pix_y
= FRAME_TOTAL_LINES (f
);
1956 /* Find the glyph under window-relative coordinates X/Y in window W.
1957 Consider only glyphs from buffer text, i.e. no glyphs from overlay
1958 strings. Return in *HPOS and *VPOS the row and column number of
1959 the glyph found. Return in *AREA the glyph area containing X.
1960 Value is a pointer to the glyph found or null if X/Y is not on
1961 text, or we can't tell because W's current matrix is not up to
1964 static struct glyph
*
1965 x_y_to_hpos_vpos (struct window
*w
, int x
, int y
, int *hpos
, int *vpos
,
1966 int *dx
, int *dy
, int *area
)
1968 struct glyph
*glyph
, *end
;
1969 struct glyph_row
*row
= NULL
;
1972 /* Find row containing Y. Give up if some row is not enabled. */
1973 for (i
= 0; i
< w
->current_matrix
->nrows
; ++i
)
1975 row
= MATRIX_ROW (w
->current_matrix
, i
);
1976 if (!row
->enabled_p
)
1978 if (y
>= row
->y
&& y
< MATRIX_ROW_BOTTOM_Y (row
))
1985 /* Give up if Y is not in the window. */
1986 if (i
== w
->current_matrix
->nrows
)
1989 /* Get the glyph area containing X. */
1990 if (w
->pseudo_window_p
)
1997 if (x
< window_box_left_offset (w
, TEXT_AREA
))
1999 *area
= LEFT_MARGIN_AREA
;
2000 x0
= window_box_left_offset (w
, LEFT_MARGIN_AREA
);
2002 else if (x
< window_box_right_offset (w
, TEXT_AREA
))
2005 x0
= window_box_left_offset (w
, TEXT_AREA
) + min (row
->x
, 0);
2009 *area
= RIGHT_MARGIN_AREA
;
2010 x0
= window_box_left_offset (w
, RIGHT_MARGIN_AREA
);
2014 /* Find glyph containing X. */
2015 glyph
= row
->glyphs
[*area
];
2016 end
= glyph
+ row
->used
[*area
];
2018 while (glyph
< end
&& x
>= glyph
->pixel_width
)
2020 x
-= glyph
->pixel_width
;
2030 *dy
= y
- (row
->y
+ row
->ascent
- glyph
->ascent
);
2033 *hpos
= glyph
- row
->glyphs
[*area
];
2037 /* Convert frame-relative x/y to coordinates relative to window W.
2038 Takes pseudo-windows into account. */
2041 frame_to_window_pixel_xy (struct window
*w
, int *x
, int *y
)
2043 if (w
->pseudo_window_p
)
2045 /* A pseudo-window is always full-width, and starts at the
2046 left edge of the frame, plus a frame border. */
2047 struct frame
*f
= XFRAME (w
->frame
);
2048 *x
-= FRAME_INTERNAL_BORDER_WIDTH (f
);
2049 *y
= FRAME_TO_WINDOW_PIXEL_Y (w
, *y
);
2053 *x
-= WINDOW_LEFT_EDGE_X (w
);
2054 *y
= FRAME_TO_WINDOW_PIXEL_Y (w
, *y
);
2058 #ifdef HAVE_WINDOW_SYSTEM
2061 Return in RECTS[] at most N clipping rectangles for glyph string S.
2062 Return the number of stored rectangles. */
2065 get_glyph_string_clip_rects (struct glyph_string
*s
, NativeRectangle
*rects
, int n
)
2072 if (s
->row
->full_width_p
)
2074 /* Draw full-width. X coordinates are relative to S->w->left_col. */
2075 r
.x
= WINDOW_LEFT_EDGE_X (s
->w
);
2076 if (s
->row
->mode_line_p
)
2077 r
.width
= WINDOW_PIXEL_WIDTH (s
->w
) - WINDOW_RIGHT_DIVIDER_WIDTH (s
->w
);
2079 r
.width
= WINDOW_PIXEL_WIDTH (s
->w
);
2081 /* Unless displaying a mode or menu bar line, which are always
2082 fully visible, clip to the visible part of the row. */
2083 if (s
->w
->pseudo_window_p
)
2084 r
.height
= s
->row
->visible_height
;
2086 r
.height
= s
->height
;
2090 /* This is a text line that may be partially visible. */
2091 r
.x
= window_box_left (s
->w
, s
->area
);
2092 r
.width
= window_box_width (s
->w
, s
->area
);
2093 r
.height
= s
->row
->visible_height
;
2097 if (r
.x
< s
->clip_head
->x
)
2099 if (r
.width
>= s
->clip_head
->x
- r
.x
)
2100 r
.width
-= s
->clip_head
->x
- r
.x
;
2103 r
.x
= s
->clip_head
->x
;
2106 if (r
.x
+ r
.width
> s
->clip_tail
->x
+ s
->clip_tail
->background_width
)
2108 if (s
->clip_tail
->x
+ s
->clip_tail
->background_width
>= r
.x
)
2109 r
.width
= s
->clip_tail
->x
+ s
->clip_tail
->background_width
- r
.x
;
2114 /* If S draws overlapping rows, it's sufficient to use the top and
2115 bottom of the window for clipping because this glyph string
2116 intentionally draws over other lines. */
2117 if (s
->for_overlaps
)
2119 r
.y
= WINDOW_HEADER_LINE_HEIGHT (s
->w
);
2120 r
.height
= window_text_bottom_y (s
->w
) - r
.y
;
2122 /* Alas, the above simple strategy does not work for the
2123 environments with anti-aliased text: if the same text is
2124 drawn onto the same place multiple times, it gets thicker.
2125 If the overlap we are processing is for the erased cursor, we
2126 take the intersection with the rectangle of the cursor. */
2127 if (s
->for_overlaps
& OVERLAPS_ERASED_CURSOR
)
2129 XRectangle rc
, r_save
= r
;
2131 rc
.x
= WINDOW_TEXT_TO_FRAME_PIXEL_X (s
->w
, s
->w
->phys_cursor
.x
);
2132 rc
.y
= s
->w
->phys_cursor
.y
;
2133 rc
.width
= s
->w
->phys_cursor_width
;
2134 rc
.height
= s
->w
->phys_cursor_height
;
2136 x_intersect_rectangles (&r_save
, &rc
, &r
);
2141 /* Don't use S->y for clipping because it doesn't take partially
2142 visible lines into account. For example, it can be negative for
2143 partially visible lines at the top of a window. */
2144 if (!s
->row
->full_width_p
2145 && MATRIX_ROW_PARTIALLY_VISIBLE_AT_TOP_P (s
->w
, s
->row
))
2146 r
.y
= WINDOW_HEADER_LINE_HEIGHT (s
->w
);
2148 r
.y
= max (0, s
->row
->y
);
2151 r
.y
= WINDOW_TO_FRAME_PIXEL_Y (s
->w
, r
.y
);
2153 /* If drawing the cursor, don't let glyph draw outside its
2154 advertised boundaries. Cleartype does this under some circumstances. */
2155 if (s
->hl
== DRAW_CURSOR
)
2157 struct glyph
*glyph
= s
->first_glyph
;
2162 if (r
.width
>= s
->x
- r
.x
)
2163 r
.width
-= s
->x
- r
.x
;
2164 else /* R2L hscrolled row with cursor outside text area */
2168 r
.width
= min (r
.width
, glyph
->pixel_width
);
2170 /* If r.y is below window bottom, ensure that we still see a cursor. */
2171 height
= min (glyph
->ascent
+ glyph
->descent
,
2172 min (FRAME_LINE_HEIGHT (s
->f
), s
->row
->visible_height
));
2173 max_y
= window_text_bottom_y (s
->w
) - height
;
2174 max_y
= WINDOW_TO_FRAME_PIXEL_Y (s
->w
, max_y
);
2175 if (s
->ybase
- glyph
->ascent
> max_y
)
2182 /* Don't draw cursor glyph taller than our actual glyph. */
2183 height
= max (FRAME_LINE_HEIGHT (s
->f
), glyph
->ascent
+ glyph
->descent
);
2184 if (height
< r
.height
)
2186 max_y
= r
.y
+ r
.height
;
2187 r
.y
= min (max_y
, max (r
.y
, s
->ybase
+ glyph
->descent
- height
));
2188 r
.height
= min (max_y
- r
.y
, height
);
2195 XRectangle r_save
= r
;
2197 if (! x_intersect_rectangles (&r_save
, s
->row
->clip
, &r
))
2201 if ((s
->for_overlaps
& OVERLAPS_BOTH
) == 0
2202 || ((s
->for_overlaps
& OVERLAPS_BOTH
) == OVERLAPS_BOTH
&& n
== 1))
2204 #ifdef CONVERT_FROM_XRECT
2205 CONVERT_FROM_XRECT (r
, *rects
);
2213 /* If we are processing overlapping and allowed to return
2214 multiple clipping rectangles, we exclude the row of the glyph
2215 string from the clipping rectangle. This is to avoid drawing
2216 the same text on the environment with anti-aliasing. */
2217 #ifdef CONVERT_FROM_XRECT
2220 XRectangle
*rs
= rects
;
2222 int i
= 0, row_y
= WINDOW_TO_FRAME_PIXEL_Y (s
->w
, s
->row
->y
);
2224 if (s
->for_overlaps
& OVERLAPS_PRED
)
2227 if (r
.y
+ r
.height
> row_y
)
2230 rs
[i
].height
= row_y
- r
.y
;
2236 if (s
->for_overlaps
& OVERLAPS_SUCC
)
2239 if (r
.y
< row_y
+ s
->row
->visible_height
)
2241 if (r
.y
+ r
.height
> row_y
+ s
->row
->visible_height
)
2243 rs
[i
].y
= row_y
+ s
->row
->visible_height
;
2244 rs
[i
].height
= r
.y
+ r
.height
- rs
[i
].y
;
2253 #ifdef CONVERT_FROM_XRECT
2254 for (i
= 0; i
< n
; i
++)
2255 CONVERT_FROM_XRECT (rs
[i
], rects
[i
]);
2262 Return in *NR the clipping rectangle for glyph string S. */
2265 get_glyph_string_clip_rect (struct glyph_string
*s
, NativeRectangle
*nr
)
2267 get_glyph_string_clip_rects (s
, nr
, 1);
2272 Return the position and height of the phys cursor in window W.
2273 Set w->phys_cursor_width to width of phys cursor.
2277 get_phys_cursor_geometry (struct window
*w
, struct glyph_row
*row
,
2278 struct glyph
*glyph
, int *xp
, int *yp
, int *heightp
)
2280 struct frame
*f
= XFRAME (WINDOW_FRAME (w
));
2281 int x
, y
, wd
, h
, h0
, y0
, ascent
;
2283 /* Compute the width of the rectangle to draw. If on a stretch
2284 glyph, and `x-stretch-block-cursor' is nil, don't draw a
2285 rectangle as wide as the glyph, but use a canonical character
2287 wd
= glyph
->pixel_width
;
2289 x
= w
->phys_cursor
.x
;
2296 if (glyph
->type
== STRETCH_GLYPH
2297 && !x_stretch_cursor_p
)
2298 wd
= min (FRAME_COLUMN_WIDTH (f
), wd
);
2299 w
->phys_cursor_width
= wd
;
2301 /* Don't let the hollow cursor glyph descend below the glyph row's
2302 ascent value, lest the hollow cursor looks funny. */
2303 y
= w
->phys_cursor
.y
;
2304 ascent
= row
->ascent
;
2305 if (row
->ascent
< glyph
->ascent
)
2307 y
-= glyph
->ascent
- row
->ascent
;
2308 ascent
= glyph
->ascent
;
2311 /* If y is below window bottom, ensure that we still see a cursor. */
2312 h0
= min (FRAME_LINE_HEIGHT (f
), row
->visible_height
);
2314 h
= max (h0
, ascent
+ glyph
->descent
);
2315 h0
= min (h0
, ascent
+ glyph
->descent
);
2317 y0
= WINDOW_HEADER_LINE_HEIGHT (w
);
2320 h
= max (h
- (y0
- y
) + 1, h0
);
2325 y0
= window_text_bottom_y (w
) - h0
;
2333 *xp
= WINDOW_TEXT_TO_FRAME_PIXEL_X (w
, x
);
2334 *yp
= WINDOW_TO_FRAME_PIXEL_Y (w
, y
);
2339 * Remember which glyph the mouse is over.
2343 remember_mouse_glyph (struct frame
*f
, int gx
, int gy
, NativeRectangle
*rect
)
2347 struct glyph_row
*r
, *gr
, *end_row
;
2348 enum window_part part
;
2349 enum glyph_row_area area
;
2350 int x
, y
, width
, height
;
2352 /* Try to determine frame pixel position and size of the glyph under
2353 frame pixel coordinates X/Y on frame F. */
2355 if (window_resize_pixelwise
)
2360 else if (!f
->glyphs_initialized_p
2361 || (window
= window_from_coordinates (f
, gx
, gy
, &part
, false),
2364 width
= FRAME_SMALLEST_CHAR_WIDTH (f
);
2365 height
= FRAME_SMALLEST_FONT_HEIGHT (f
);
2369 w
= XWINDOW (window
);
2370 width
= WINDOW_FRAME_COLUMN_WIDTH (w
);
2371 height
= WINDOW_FRAME_LINE_HEIGHT (w
);
2373 x
= window_relative_x_coord (w
, part
, gx
);
2374 y
= gy
- WINDOW_TOP_EDGE_Y (w
);
2376 r
= MATRIX_FIRST_TEXT_ROW (w
->current_matrix
);
2377 end_row
= MATRIX_BOTTOM_TEXT_ROW (w
->current_matrix
, w
);
2379 if (w
->pseudo_window_p
)
2382 part
= ON_MODE_LINE
; /* Don't adjust margin. */
2388 case ON_LEFT_MARGIN
:
2389 area
= LEFT_MARGIN_AREA
;
2392 case ON_RIGHT_MARGIN
:
2393 area
= RIGHT_MARGIN_AREA
;
2396 case ON_HEADER_LINE
:
2398 gr
= (part
== ON_HEADER_LINE
2399 ? MATRIX_HEADER_LINE_ROW (w
->current_matrix
)
2400 : MATRIX_MODE_LINE_ROW (w
->current_matrix
));
2403 goto text_glyph_row_found
;
2410 for (; r
<= end_row
&& r
->enabled_p
; ++r
)
2411 if (r
->y
+ r
->height
> y
)
2417 text_glyph_row_found
:
2420 struct glyph
*g
= gr
->glyphs
[area
];
2421 struct glyph
*end
= g
+ gr
->used
[area
];
2423 height
= gr
->height
;
2424 for (gx
= gr
->x
; g
< end
; gx
+= g
->pixel_width
, ++g
)
2425 if (gx
+ g
->pixel_width
> x
)
2430 if (g
->type
== IMAGE_GLYPH
)
2432 /* Don't remember when mouse is over image, as
2433 image may have hot-spots. */
2434 STORE_NATIVE_RECT (*rect
, 0, 0, 0, 0);
2437 width
= g
->pixel_width
;
2441 /* Use nominal char spacing at end of line. */
2443 gx
+= (x
/ width
) * width
;
2446 if (part
!= ON_MODE_LINE
&& part
!= ON_HEADER_LINE
)
2448 gx
+= window_box_left_offset (w
, area
);
2449 /* Don't expand over the modeline to make sure the vertical
2450 drag cursor is shown early enough. */
2451 height
= min (height
,
2452 max (0, WINDOW_BOX_HEIGHT_NO_MODE_LINE (w
) - gy
));
2457 /* Use nominal line height at end of window. */
2458 gx
= (x
/ width
) * width
;
2460 gy
+= (y
/ height
) * height
;
2461 if (part
!= ON_MODE_LINE
&& part
!= ON_HEADER_LINE
)
2462 /* See comment above. */
2463 height
= min (height
,
2464 max (0, WINDOW_BOX_HEIGHT_NO_MODE_LINE (w
) - gy
));
2468 case ON_LEFT_FRINGE
:
2469 gx
= (WINDOW_HAS_FRINGES_OUTSIDE_MARGINS (w
)
2470 ? WINDOW_LEFT_SCROLL_BAR_AREA_WIDTH (w
)
2471 : window_box_right_offset (w
, LEFT_MARGIN_AREA
));
2472 width
= WINDOW_LEFT_FRINGE_WIDTH (w
);
2475 case ON_RIGHT_FRINGE
:
2476 gx
= (WINDOW_HAS_FRINGES_OUTSIDE_MARGINS (w
)
2477 ? window_box_right_offset (w
, RIGHT_MARGIN_AREA
)
2478 : window_box_right_offset (w
, TEXT_AREA
));
2479 if (WINDOW_RIGHT_DIVIDER_WIDTH (w
) == 0
2480 && !WINDOW_HAS_VERTICAL_SCROLL_BAR (w
)
2481 && !WINDOW_RIGHTMOST_P (w
))
2482 if (gx
< WINDOW_PIXEL_WIDTH (w
) - width
)
2483 /* Make sure the vertical border can get her own glyph to the
2484 right of the one we build here. */
2485 width
= WINDOW_RIGHT_FRINGE_WIDTH (w
) - width
;
2487 width
= WINDOW_PIXEL_WIDTH (w
) - gx
;
2489 width
= WINDOW_RIGHT_FRINGE_WIDTH (w
);
2493 case ON_VERTICAL_BORDER
:
2494 gx
= WINDOW_PIXEL_WIDTH (w
) - width
;
2497 case ON_VERTICAL_SCROLL_BAR
:
2498 gx
= (WINDOW_HAS_VERTICAL_SCROLL_BAR_ON_LEFT (w
)
2500 : (window_box_right_offset (w
, RIGHT_MARGIN_AREA
)
2501 + (WINDOW_HAS_FRINGES_OUTSIDE_MARGINS (w
)
2502 ? WINDOW_RIGHT_FRINGE_WIDTH (w
)
2504 width
= WINDOW_SCROLL_BAR_AREA_WIDTH (w
);
2508 for (; r
<= end_row
&& r
->enabled_p
; ++r
)
2509 if (r
->y
+ r
->height
> y
)
2516 height
= gr
->height
;
2519 /* Use nominal line height at end of window. */
2521 gy
+= (y
/ height
) * height
;
2525 case ON_RIGHT_DIVIDER
:
2526 gx
= WINDOW_PIXEL_WIDTH (w
) - WINDOW_RIGHT_DIVIDER_WIDTH (w
);
2527 width
= WINDOW_RIGHT_DIVIDER_WIDTH (w
);
2529 /* The bottom divider prevails. */
2530 height
= WINDOW_PIXEL_HEIGHT (w
) - WINDOW_BOTTOM_DIVIDER_WIDTH (w
);
2533 case ON_BOTTOM_DIVIDER
:
2535 width
= WINDOW_PIXEL_WIDTH (w
);
2536 gy
= WINDOW_PIXEL_HEIGHT (w
) - WINDOW_BOTTOM_DIVIDER_WIDTH (w
);
2537 height
= WINDOW_BOTTOM_DIVIDER_WIDTH (w
);
2543 /* If there is no glyph under the mouse, then we divide the screen
2544 into a grid of the smallest glyph in the frame, and use that
2547 /* Arrange for the division in FRAME_PIXEL_X_TO_COL etc. to
2548 round down even for negative values. */
2554 gx
= (gx
/ width
) * width
;
2555 gy
= (gy
/ height
) * height
;
2561 gx
+= WINDOW_LEFT_EDGE_X (w
);
2562 gy
+= WINDOW_TOP_EDGE_Y (w
);
2565 STORE_NATIVE_RECT (*rect
, gx
, gy
, width
, height
);
2567 /* Visible feedback for debugging. */
2568 #if false && defined HAVE_X_WINDOWS
2569 XDrawRectangle (FRAME_X_DISPLAY (f
), FRAME_X_DRAWABLE (f
),
2570 f
->output_data
.x
->normal_gc
,
2571 gx
, gy
, width
, height
);
2576 #endif /* HAVE_WINDOW_SYSTEM */
2579 adjust_window_ends (struct window
*w
, struct glyph_row
*row
, bool current
)
2582 w
->window_end_pos
= Z
- MATRIX_ROW_END_CHARPOS (row
);
2583 w
->window_end_bytepos
= Z_BYTE
- MATRIX_ROW_END_BYTEPOS (row
);
2585 = MATRIX_ROW_VPOS (row
, current
? w
->current_matrix
: w
->desired_matrix
);
2589 hscrolling_current_line_p (struct window
*w
)
2591 return (!w
->suspend_auto_hscroll
2592 && EQ (Fbuffer_local_value (Qauto_hscroll_mode
, w
->contents
),
2596 /***********************************************************************
2597 Lisp form evaluation
2598 ***********************************************************************/
2600 /* Error handler for safe_eval and safe_call. */
2603 safe_eval_handler (Lisp_Object arg
, ptrdiff_t nargs
, Lisp_Object
*args
)
2605 add_to_log ("Error during redisplay: %S signaled %S",
2606 Flist (nargs
, args
), arg
);
2610 /* Call function FUNC with the rest of NARGS - 1 arguments
2611 following. Return the result, or nil if something went
2612 wrong. Prevent redisplay during the evaluation. */
2615 safe__call (bool inhibit_quit
, ptrdiff_t nargs
, Lisp_Object func
, va_list ap
)
2619 if (inhibit_eval_during_redisplay
)
2624 ptrdiff_t count
= SPECPDL_INDEX ();
2627 SAFE_ALLOCA_LISP (args
, nargs
);
2630 for (i
= 1; i
< nargs
; i
++)
2631 args
[i
] = va_arg (ap
, Lisp_Object
);
2633 specbind (Qinhibit_redisplay
, Qt
);
2635 specbind (Qinhibit_quit
, Qt
);
2636 /* Use Qt to ensure debugger does not run,
2637 so there is no possibility of wanting to redisplay. */
2638 val
= internal_condition_case_n (Ffuncall
, nargs
, args
, Qt
,
2641 val
= unbind_to (count
, val
);
2648 safe_call (ptrdiff_t nargs
, Lisp_Object func
, ...)
2653 va_start (ap
, func
);
2654 retval
= safe__call (false, nargs
, func
, ap
);
2659 /* Call function FN with one argument ARG.
2660 Return the result, or nil if something went wrong. */
2663 safe_call1 (Lisp_Object fn
, Lisp_Object arg
)
2665 return safe_call (2, fn
, arg
);
2669 safe__call1 (bool inhibit_quit
, Lisp_Object fn
, ...)
2675 retval
= safe__call (inhibit_quit
, 2, fn
, ap
);
2681 safe_eval (Lisp_Object sexpr
)
2683 return safe__call1 (false, Qeval
, sexpr
);
2687 safe__eval (bool inhibit_quit
, Lisp_Object sexpr
)
2689 return safe__call1 (inhibit_quit
, Qeval
, sexpr
);
2692 /* Call function FN with two arguments ARG1 and ARG2.
2693 Return the result, or nil if something went wrong. */
2696 safe_call2 (Lisp_Object fn
, Lisp_Object arg1
, Lisp_Object arg2
)
2698 return safe_call (3, fn
, arg1
, arg2
);
2703 /***********************************************************************
2705 ***********************************************************************/
2707 /* Define CHECK_IT to perform sanity checks on iterators.
2708 This is for debugging. It is too slow to do unconditionally. */
2711 CHECK_IT (struct it
*it
)
2714 if (it
->method
== GET_FROM_STRING
)
2716 eassert (STRINGP (it
->string
));
2717 eassert (IT_STRING_CHARPOS (*it
) >= 0);
2721 eassert (IT_STRING_CHARPOS (*it
) < 0);
2722 if (it
->method
== GET_FROM_BUFFER
)
2724 /* Check that character and byte positions agree. */
2725 eassert (IT_CHARPOS (*it
) == BYTE_TO_CHAR (IT_BYTEPOS (*it
)));
2730 eassert (it
->current
.dpvec_index
>= 0);
2732 eassert (it
->current
.dpvec_index
< 0);
2737 /* Check that the window end of window W is what we expect it
2738 to be---the last row in the current matrix displaying text. */
2741 CHECK_WINDOW_END (struct window
*w
)
2743 #if defined GLYPH_DEBUG && defined ENABLE_CHECKING
2744 if (!MINI_WINDOW_P (w
) && w
->window_end_valid
)
2746 struct glyph_row
*row
;
2747 eassert ((row
= MATRIX_ROW (w
->current_matrix
, w
->window_end_vpos
),
2749 || MATRIX_ROW_DISPLAYS_TEXT_P (row
)
2750 || MATRIX_ROW_VPOS (row
, w
->current_matrix
) == 0));
2755 /***********************************************************************
2756 Iterator initialization
2757 ***********************************************************************/
2759 /* Initialize IT for displaying current_buffer in window W, starting
2760 at character position CHARPOS. CHARPOS < 0 means that no buffer
2761 position is specified which is useful when the iterator is assigned
2762 a position later. BYTEPOS is the byte position corresponding to
2765 If ROW is not null, calls to produce_glyphs with IT as parameter
2766 will produce glyphs in that row.
2768 BASE_FACE_ID is the id of a base face to use. It must be one of
2769 DEFAULT_FACE_ID for normal text, MODE_LINE_FACE_ID,
2770 MODE_LINE_INACTIVE_FACE_ID, or HEADER_LINE_FACE_ID for displaying
2771 mode lines, or TOOL_BAR_FACE_ID for displaying the tool-bar.
2773 If ROW is null and BASE_FACE_ID is equal to MODE_LINE_FACE_ID,
2774 MODE_LINE_INACTIVE_FACE_ID, or HEADER_LINE_FACE_ID, the iterator
2775 will be initialized to use the corresponding mode line glyph row of
2776 the desired matrix of W. */
2779 init_iterator (struct it
*it
, struct window
*w
,
2780 ptrdiff_t charpos
, ptrdiff_t bytepos
,
2781 struct glyph_row
*row
, enum face_id base_face_id
)
2783 enum face_id remapped_base_face_id
= base_face_id
;
2785 /* Some precondition checks. */
2786 eassert (w
!= NULL
&& it
!= NULL
);
2787 eassert (charpos
< 0 || (charpos
>= BUF_BEG (current_buffer
)
2790 /* If face attributes have been changed since the last redisplay,
2791 free realized faces now because they depend on face definitions
2792 that might have changed. Don't free faces while there might be
2793 desired matrices pending which reference these faces. */
2794 if (!inhibit_free_realized_faces
)
2798 face_change
= false;
2799 XFRAME (w
->frame
)->face_change
= 0;
2800 free_all_realized_faces (Qnil
);
2802 else if (XFRAME (w
->frame
)->face_change
)
2804 XFRAME (w
->frame
)->face_change
= 0;
2805 free_all_realized_faces (w
->frame
);
2809 /* Perhaps remap BASE_FACE_ID to a user-specified alternative. */
2810 if (! NILP (Vface_remapping_alist
))
2811 remapped_base_face_id
2812 = lookup_basic_face (w
, XFRAME (w
->frame
), base_face_id
);
2814 /* Use one of the mode line rows of W's desired matrix if
2818 if (base_face_id
== MODE_LINE_FACE_ID
2819 || base_face_id
== MODE_LINE_INACTIVE_FACE_ID
)
2820 row
= MATRIX_MODE_LINE_ROW (w
->desired_matrix
);
2821 else if (base_face_id
== HEADER_LINE_FACE_ID
)
2822 row
= MATRIX_HEADER_LINE_ROW (w
->desired_matrix
);
2825 /* Clear IT, and set it->object and other IT's Lisp objects to Qnil.
2826 Other parts of redisplay rely on that. */
2827 memclear (it
, sizeof *it
);
2828 it
->current
.overlay_string_index
= -1;
2829 it
->current
.dpvec_index
= -1;
2830 it
->base_face_id
= remapped_base_face_id
;
2831 IT_STRING_CHARPOS (*it
) = IT_STRING_BYTEPOS (*it
) = -1;
2832 it
->paragraph_embedding
= L2R
;
2835 /* The window in which we iterate over current_buffer: */
2836 XSETWINDOW (it
->window
, w
);
2838 it
->f
= XFRAME (w
->frame
);
2842 /* Extra space between lines (on window systems only). */
2843 if (base_face_id
== DEFAULT_FACE_ID
2844 && FRAME_WINDOW_P (it
->f
))
2846 if (NATNUMP (BVAR (current_buffer
, extra_line_spacing
)))
2847 it
->extra_line_spacing
= XFASTINT (BVAR (current_buffer
, extra_line_spacing
));
2848 else if (FLOATP (BVAR (current_buffer
, extra_line_spacing
)))
2849 it
->extra_line_spacing
= (XFLOAT_DATA (BVAR (current_buffer
, extra_line_spacing
))
2850 * FRAME_LINE_HEIGHT (it
->f
));
2851 else if (it
->f
->extra_line_spacing
> 0)
2852 it
->extra_line_spacing
= it
->f
->extra_line_spacing
;
2855 /* If realized faces have been removed, e.g. because of face
2856 attribute changes of named faces, recompute them. When running
2857 in batch mode, the face cache of the initial frame is null. If
2858 we happen to get called, make a dummy face cache. */
2859 if (FRAME_FACE_CACHE (it
->f
) == NULL
)
2860 init_frame_faces (it
->f
);
2861 if (FRAME_FACE_CACHE (it
->f
)->used
== 0)
2862 recompute_basic_faces (it
->f
);
2864 it
->override_ascent
= -1;
2866 /* Are control characters displayed as `^C'? */
2867 it
->ctl_arrow_p
= !NILP (BVAR (current_buffer
, ctl_arrow
));
2869 /* -1 means everything between a CR and the following line end
2870 is invisible. >0 means lines indented more than this value are
2872 it
->selective
= (INTEGERP (BVAR (current_buffer
, selective_display
))
2874 (-1, XINT (BVAR (current_buffer
, selective_display
)),
2876 : (!NILP (BVAR (current_buffer
, selective_display
))
2878 it
->selective_display_ellipsis_p
2879 = !NILP (BVAR (current_buffer
, selective_display_ellipses
));
2881 /* Display table to use. */
2882 it
->dp
= window_display_table (w
);
2884 /* Are multibyte characters enabled in current_buffer? */
2885 it
->multibyte_p
= !NILP (BVAR (current_buffer
, enable_multibyte_characters
));
2887 /* Get the position at which the redisplay_end_trigger hook should
2888 be run, if it is to be run at all. */
2889 if (MARKERP (w
->redisplay_end_trigger
)
2890 && XMARKER (w
->redisplay_end_trigger
)->buffer
!= 0)
2891 it
->redisplay_end_trigger_charpos
2892 = marker_position (w
->redisplay_end_trigger
);
2893 else if (INTEGERP (w
->redisplay_end_trigger
))
2894 it
->redisplay_end_trigger_charpos
2895 = clip_to_bounds (PTRDIFF_MIN
, XINT (w
->redisplay_end_trigger
),
2898 it
->tab_width
= SANE_TAB_WIDTH (current_buffer
);
2900 /* Are lines in the display truncated? */
2902 it
->line_wrap
= TRUNCATE
;
2903 if (base_face_id
== DEFAULT_FACE_ID
2905 && (WINDOW_FULL_WIDTH_P (it
->w
)
2906 || NILP (Vtruncate_partial_width_windows
)
2907 || (INTEGERP (Vtruncate_partial_width_windows
)
2908 /* PXW: Shall we do something about this? */
2909 && (XINT (Vtruncate_partial_width_windows
)
2910 <= WINDOW_TOTAL_COLS (it
->w
))))
2911 && NILP (BVAR (current_buffer
, truncate_lines
)))
2912 it
->line_wrap
= NILP (BVAR (current_buffer
, word_wrap
))
2913 ? WINDOW_WRAP
: WORD_WRAP
;
2915 /* Get dimensions of truncation and continuation glyphs. These are
2916 displayed as fringe bitmaps under X, but we need them for such
2917 frames when the fringes are turned off. The no_special_glyphs slot
2918 of the iterator's frame, when set, suppresses their display - by
2919 default for tooltip frames and when set via the 'no-special-glyphs'
2921 #ifdef HAVE_WINDOW_SYSTEM
2922 if (!(FRAME_WINDOW_P (it
->f
) && it
->f
->no_special_glyphs
))
2925 if (it
->line_wrap
== TRUNCATE
)
2927 /* We will need the truncation glyph. */
2928 eassert (it
->glyph_row
== NULL
);
2929 produce_special_glyphs (it
, IT_TRUNCATION
);
2930 it
->truncation_pixel_width
= it
->pixel_width
;
2934 /* We will need the continuation glyph. */
2935 eassert (it
->glyph_row
== NULL
);
2936 produce_special_glyphs (it
, IT_CONTINUATION
);
2937 it
->continuation_pixel_width
= it
->pixel_width
;
2941 /* Reset these values to zero because the produce_special_glyphs
2942 above has changed them. */
2943 it
->pixel_width
= it
->ascent
= it
->descent
= 0;
2944 it
->phys_ascent
= it
->phys_descent
= 0;
2946 /* Set this after getting the dimensions of truncation and
2947 continuation glyphs, so that we don't produce glyphs when calling
2948 produce_special_glyphs, above. */
2949 it
->glyph_row
= row
;
2950 it
->area
= TEXT_AREA
;
2952 /* Get the dimensions of the display area. The display area
2953 consists of the visible window area plus a horizontally scrolled
2954 part to the left of the window. All x-values are relative to the
2955 start of this total display area. */
2956 if (base_face_id
!= DEFAULT_FACE_ID
)
2958 /* Mode lines, menu bar in terminal frames. */
2959 it
->first_visible_x
= 0;
2960 it
->last_visible_x
= WINDOW_PIXEL_WIDTH (w
);
2964 /* When hscrolling only the current line, don't apply the
2965 hscroll here, it will be applied by display_line when it gets
2966 to laying out the line showing point. However, if the
2967 window's min_hscroll is positive, the user specified a lower
2968 bound for automatic hscrolling, so they expect the
2969 non-current lines to obey that hscroll amount. */
2970 if (hscrolling_current_line_p (w
))
2972 if (w
->min_hscroll
> 0)
2973 it
->first_visible_x
= w
->min_hscroll
* FRAME_COLUMN_WIDTH (it
->f
);
2975 it
->first_visible_x
= 0;
2978 it
->first_visible_x
=
2979 window_hscroll_limited (w
, it
->f
) * FRAME_COLUMN_WIDTH (it
->f
);
2980 it
->last_visible_x
= (it
->first_visible_x
2981 + window_box_width (w
, TEXT_AREA
));
2983 /* If we truncate lines, leave room for the truncation glyph(s) at
2984 the right margin. Otherwise, leave room for the continuation
2985 glyph(s). Done only if the window has no right fringe. */
2986 if (WINDOW_RIGHT_FRINGE_WIDTH (it
->w
) == 0)
2988 if (it
->line_wrap
== TRUNCATE
)
2989 it
->last_visible_x
-= it
->truncation_pixel_width
;
2991 it
->last_visible_x
-= it
->continuation_pixel_width
;
2994 it
->header_line_p
= window_wants_header_line (w
);
2995 it
->current_y
= WINDOW_HEADER_LINE_HEIGHT (w
) + w
->vscroll
;
2998 /* Leave room for a border glyph. */
2999 if (!FRAME_WINDOW_P (it
->f
)
3000 && !WINDOW_RIGHTMOST_P (it
->w
))
3001 it
->last_visible_x
-= 1;
3003 it
->last_visible_y
= window_text_bottom_y (w
);
3005 /* For mode lines and alike, arrange for the first glyph having a
3006 left box line if the face specifies a box. */
3007 if (base_face_id
!= DEFAULT_FACE_ID
)
3011 it
->face_id
= remapped_base_face_id
;
3013 /* If we have a boxed mode line, make the first character appear
3014 with a left box line. */
3015 face
= FACE_FROM_ID_OR_NULL (it
->f
, remapped_base_face_id
);
3016 if (face
&& face
->box
!= FACE_NO_BOX
)
3017 it
->start_of_box_run_p
= true;
3020 /* If a buffer position was specified, set the iterator there,
3021 getting overlays and face properties from that position. */
3022 if (charpos
>= BUF_BEG (current_buffer
))
3024 it
->stop_charpos
= charpos
;
3025 it
->end_charpos
= ZV
;
3026 eassert (charpos
== BYTE_TO_CHAR (bytepos
));
3027 IT_CHARPOS (*it
) = charpos
;
3028 IT_BYTEPOS (*it
) = bytepos
;
3030 /* We will rely on `reseat' to set this up properly, via
3031 handle_face_prop. */
3032 it
->face_id
= it
->base_face_id
;
3034 it
->start
= it
->current
;
3035 /* Do we need to reorder bidirectional text? Not if this is a
3036 unibyte buffer: by definition, none of the single-byte
3037 characters are strong R2L, so no reordering is needed. And
3038 bidi.c doesn't support unibyte buffers anyway. Also, don't
3039 reorder while we are loading loadup.el, since the tables of
3040 character properties needed for reordering are not yet
3043 !redisplay__inhibit_bidi
3044 && !NILP (BVAR (current_buffer
, bidi_display_reordering
))
3047 /* If we are to reorder bidirectional text, init the bidi
3051 /* Since we don't know at this point whether there will be
3052 any R2L lines in the window, we reserve space for
3053 truncation/continuation glyphs even if only the left
3054 fringe is absent. */
3055 if (base_face_id
== DEFAULT_FACE_ID
3056 && WINDOW_LEFT_FRINGE_WIDTH (it
->w
) == 0
3057 && WINDOW_RIGHT_FRINGE_WIDTH (it
->w
) != 0)
3059 if (it
->line_wrap
== TRUNCATE
)
3060 it
->last_visible_x
-= it
->truncation_pixel_width
;
3062 it
->last_visible_x
-= it
->continuation_pixel_width
;
3064 /* Note the paragraph direction that this buffer wants to
3066 if (EQ (BVAR (current_buffer
, bidi_paragraph_direction
),
3068 it
->paragraph_embedding
= L2R
;
3069 else if (EQ (BVAR (current_buffer
, bidi_paragraph_direction
),
3071 it
->paragraph_embedding
= R2L
;
3073 it
->paragraph_embedding
= NEUTRAL_DIR
;
3074 bidi_unshelve_cache (NULL
, false);
3075 bidi_init_it (charpos
, IT_BYTEPOS (*it
), FRAME_WINDOW_P (it
->f
),
3079 /* Compute faces etc. */
3080 reseat (it
, it
->current
.pos
, true);
3087 /* Initialize IT for the display of window W with window start POS. */
3090 start_display (struct it
*it
, struct window
*w
, struct text_pos pos
)
3092 struct glyph_row
*row
;
3093 bool first_vpos
= window_wants_header_line (w
);
3095 row
= w
->desired_matrix
->rows
+ first_vpos
;
3096 init_iterator (it
, w
, CHARPOS (pos
), BYTEPOS (pos
), row
, DEFAULT_FACE_ID
);
3097 it
->first_vpos
= first_vpos
;
3099 /* Don't reseat to previous visible line start if current start
3100 position is in a string or image. */
3101 if (it
->method
== GET_FROM_BUFFER
&& it
->line_wrap
!= TRUNCATE
)
3103 int first_y
= it
->current_y
;
3105 /* If window start is not at a line start, skip forward to POS to
3106 get the correct continuation lines width. */
3107 bool start_at_line_beg_p
= (CHARPOS (pos
) == BEGV
3108 || FETCH_BYTE (BYTEPOS (pos
) - 1) == '\n');
3109 if (!start_at_line_beg_p
)
3113 reseat_at_previous_visible_line_start (it
);
3114 move_it_to (it
, CHARPOS (pos
), -1, -1, -1, MOVE_TO_POS
);
3116 new_x
= it
->current_x
+ it
->pixel_width
;
3118 /* If lines are continued, this line may end in the middle
3119 of a multi-glyph character (e.g. a control character
3120 displayed as \003, or in the middle of an overlay
3121 string). In this case move_it_to above will not have
3122 taken us to the start of the continuation line but to the
3123 end of the continued line. */
3124 if (it
->current_x
> 0
3125 && it
->line_wrap
!= TRUNCATE
/* Lines are continued. */
3126 && (/* And glyph doesn't fit on the line. */
3127 new_x
> it
->last_visible_x
3128 /* Or it fits exactly and we're on a window
3130 || (new_x
== it
->last_visible_x
3131 && FRAME_WINDOW_P (it
->f
)
3132 && ((it
->bidi_p
&& it
->bidi_it
.paragraph_dir
== R2L
)
3133 ? WINDOW_LEFT_FRINGE_WIDTH (it
->w
)
3134 : WINDOW_RIGHT_FRINGE_WIDTH (it
->w
)))))
3136 if ((it
->current
.dpvec_index
>= 0
3137 || it
->current
.overlay_string_index
>= 0)
3138 /* If we are on a newline from a display vector or
3139 overlay string, then we are already at the end of
3140 a screen line; no need to go to the next line in
3141 that case, as this line is not really continued.
3142 (If we do go to the next line, C-e will not DTRT.) */
3145 set_iterator_to_next (it
, true);
3146 move_it_in_display_line_to (it
, -1, -1, 0);
3149 it
->continuation_lines_width
+= it
->current_x
;
3151 /* If the character at POS is displayed via a display
3152 vector, move_it_to above stops at the final glyph of
3153 IT->dpvec. To make the caller redisplay that character
3154 again (a.k.a. start at POS), we need to reset the
3155 dpvec_index to the beginning of IT->dpvec. */
3156 else if (it
->current
.dpvec_index
>= 0)
3157 it
->current
.dpvec_index
= 0;
3159 /* We're starting a new display line, not affected by the
3160 height of the continued line, so clear the appropriate
3161 fields in the iterator structure. */
3162 it
->max_ascent
= it
->max_descent
= 0;
3163 it
->max_phys_ascent
= it
->max_phys_descent
= 0;
3165 it
->current_y
= first_y
;
3167 it
->current_x
= it
->hpos
= 0;
3173 /* Return true if POS is a position in ellipses displayed for invisible
3174 text. W is the window we display, for text property lookup. */
3177 in_ellipses_for_invisible_text_p (struct display_pos
*pos
, struct window
*w
)
3179 Lisp_Object prop
, window
;
3180 bool ellipses_p
= false;
3181 ptrdiff_t charpos
= CHARPOS (pos
->pos
);
3183 /* If POS specifies a position in a display vector, this might
3184 be for an ellipsis displayed for invisible text. We won't
3185 get the iterator set up for delivering that ellipsis unless
3186 we make sure that it gets aware of the invisible text. */
3187 if (pos
->dpvec_index
>= 0
3188 && pos
->overlay_string_index
< 0
3189 && CHARPOS (pos
->string_pos
) < 0
3191 && (XSETWINDOW (window
, w
),
3192 prop
= Fget_char_property (make_number (charpos
),
3193 Qinvisible
, window
),
3194 TEXT_PROP_MEANS_INVISIBLE (prop
) == 0))
3196 prop
= Fget_char_property (make_number (charpos
- 1), Qinvisible
,
3198 ellipses_p
= 2 == TEXT_PROP_MEANS_INVISIBLE (prop
);
3205 /* Initialize IT for stepping through current_buffer in window W,
3206 starting at position POS that includes overlay string and display
3207 vector/ control character translation position information. Value
3208 is false if there are overlay strings with newlines at POS. */
3211 init_from_display_pos (struct it
*it
, struct window
*w
, struct display_pos
*pos
)
3213 ptrdiff_t charpos
= CHARPOS (pos
->pos
), bytepos
= BYTEPOS (pos
->pos
);
3215 bool overlay_strings_with_newlines
= false;
3217 /* If POS specifies a position in a display vector, this might
3218 be for an ellipsis displayed for invisible text. We won't
3219 get the iterator set up for delivering that ellipsis unless
3220 we make sure that it gets aware of the invisible text. */
3221 if (in_ellipses_for_invisible_text_p (pos
, w
))
3227 /* Keep in mind: the call to reseat in init_iterator skips invisible
3228 text, so we might end up at a position different from POS. This
3229 is only a problem when POS is a row start after a newline and an
3230 overlay starts there with an after-string, and the overlay has an
3231 invisible property. Since we don't skip invisible text in
3232 display_line and elsewhere immediately after consuming the
3233 newline before the row start, such a POS will not be in a string,
3234 but the call to init_iterator below will move us to the
3236 init_iterator (it
, w
, charpos
, bytepos
, NULL
, DEFAULT_FACE_ID
);
3238 /* This only scans the current chunk -- it should scan all chunks.
3239 However, OVERLAY_STRING_CHUNK_SIZE has been increased from 3 in 21.1
3240 to 16 in 22.1 to make this a lesser problem. */
3241 for (i
= 0; i
< it
->n_overlay_strings
&& i
< OVERLAY_STRING_CHUNK_SIZE
; ++i
)
3243 const char *s
= SSDATA (it
->overlay_strings
[i
]);
3244 const char *e
= s
+ SBYTES (it
->overlay_strings
[i
]);
3246 while (s
< e
&& *s
!= '\n')
3251 overlay_strings_with_newlines
= true;
3256 /* If position is within an overlay string, set up IT to the right
3258 if (pos
->overlay_string_index
>= 0)
3262 /* If the first overlay string happens to have a `display'
3263 property for an image, the iterator will be set up for that
3264 image, and we have to undo that setup first before we can
3265 correct the overlay string index. */
3266 if (it
->method
== GET_FROM_IMAGE
)
3269 /* We already have the first chunk of overlay strings in
3270 IT->overlay_strings. Load more until the one for
3271 pos->overlay_string_index is in IT->overlay_strings. */
3272 if (pos
->overlay_string_index
>= OVERLAY_STRING_CHUNK_SIZE
)
3274 ptrdiff_t n
= pos
->overlay_string_index
/ OVERLAY_STRING_CHUNK_SIZE
;
3275 it
->current
.overlay_string_index
= 0;
3278 load_overlay_strings (it
, 0);
3279 it
->current
.overlay_string_index
+= OVERLAY_STRING_CHUNK_SIZE
;
3283 it
->current
.overlay_string_index
= pos
->overlay_string_index
;
3284 relative_index
= (it
->current
.overlay_string_index
3285 % OVERLAY_STRING_CHUNK_SIZE
);
3286 it
->string
= it
->overlay_strings
[relative_index
];
3287 eassert (STRINGP (it
->string
));
3288 it
->current
.string_pos
= pos
->string_pos
;
3289 it
->method
= GET_FROM_STRING
;
3290 it
->end_charpos
= SCHARS (it
->string
);
3291 /* Set up the bidi iterator for this overlay string. */
3294 it
->bidi_it
.string
.lstring
= it
->string
;
3295 it
->bidi_it
.string
.s
= NULL
;
3296 it
->bidi_it
.string
.schars
= SCHARS (it
->string
);
3297 it
->bidi_it
.string
.bufpos
= it
->overlay_strings_charpos
;
3298 it
->bidi_it
.string
.from_disp_str
= it
->string_from_display_prop_p
;
3299 it
->bidi_it
.string
.unibyte
= !it
->multibyte_p
;
3300 it
->bidi_it
.w
= it
->w
;
3301 bidi_init_it (IT_STRING_CHARPOS (*it
), IT_STRING_BYTEPOS (*it
),
3302 FRAME_WINDOW_P (it
->f
), &it
->bidi_it
);
3304 /* Synchronize the state of the bidi iterator with
3305 pos->string_pos. For any string position other than
3306 zero, this will be done automagically when we resume
3307 iteration over the string and get_visually_first_element
3308 is called. But if string_pos is zero, and the string is
3309 to be reordered for display, we need to resync manually,
3310 since it could be that the iteration state recorded in
3311 pos ended at string_pos of 0 moving backwards in string. */
3312 if (CHARPOS (pos
->string_pos
) == 0)
3314 get_visually_first_element (it
);
3315 if (IT_STRING_CHARPOS (*it
) != 0)
3318 eassert (it
->bidi_it
.charpos
< it
->bidi_it
.string
.schars
);
3319 bidi_move_to_visually_next (&it
->bidi_it
);
3320 } while (it
->bidi_it
.charpos
!= 0);
3322 eassert (IT_STRING_CHARPOS (*it
) == it
->bidi_it
.charpos
3323 && IT_STRING_BYTEPOS (*it
) == it
->bidi_it
.bytepos
);
3327 if (CHARPOS (pos
->string_pos
) >= 0)
3329 /* Recorded position is not in an overlay string, but in another
3330 string. This can only be a string from a `display' property.
3331 IT should already be filled with that string. */
3332 it
->current
.string_pos
= pos
->string_pos
;
3333 eassert (STRINGP (it
->string
));
3335 bidi_init_it (IT_STRING_CHARPOS (*it
), IT_STRING_BYTEPOS (*it
),
3336 FRAME_WINDOW_P (it
->f
), &it
->bidi_it
);
3339 /* Restore position in display vector translations, control
3340 character translations or ellipses. */
3341 if (pos
->dpvec_index
>= 0)
3343 if (it
->dpvec
== NULL
)
3344 get_next_display_element (it
);
3345 eassert (it
->dpvec
&& it
->current
.dpvec_index
== 0);
3346 it
->current
.dpvec_index
= pos
->dpvec_index
;
3350 return !overlay_strings_with_newlines
;
3354 /* Initialize IT for stepping through current_buffer in window W
3355 starting at ROW->start. */
3358 init_to_row_start (struct it
*it
, struct window
*w
, struct glyph_row
*row
)
3360 init_from_display_pos (it
, w
, &row
->start
);
3361 it
->start
= row
->start
;
3362 it
->continuation_lines_width
= row
->continuation_lines_width
;
3367 /* Initialize IT for stepping through current_buffer in window W
3368 starting in the line following ROW, i.e. starting at ROW->end.
3369 Value is false if there are overlay strings with newlines at ROW's
3373 init_to_row_end (struct it
*it
, struct window
*w
, struct glyph_row
*row
)
3375 bool success
= false;
3377 if (init_from_display_pos (it
, w
, &row
->end
))
3379 if (row
->continued_p
)
3380 it
->continuation_lines_width
3381 = row
->continuation_lines_width
+ row
->pixel_width
;
3392 /***********************************************************************
3394 ***********************************************************************/
3396 /* Called when IT reaches IT->stop_charpos. Handle text property and
3397 overlay changes. Set IT->stop_charpos to the next position where
3401 handle_stop (struct it
*it
)
3403 enum prop_handled handled
;
3404 bool handle_overlay_change_p
;
3408 it
->current
.dpvec_index
= -1;
3409 handle_overlay_change_p
= !it
->ignore_overlay_strings_at_pos_p
;
3410 it
->ellipsis_p
= false;
3412 /* Use face of preceding text for ellipsis (if invisible) */
3413 if (it
->selective_display_ellipsis_p
)
3414 it
->saved_face_id
= it
->face_id
;
3416 /* Here's the description of the semantics of, and the logic behind,
3417 the various HANDLED_* statuses:
3419 HANDLED_NORMALLY means the handler did its job, and the loop
3420 should proceed to calling the next handler in order.
3422 HANDLED_RECOMPUTE_PROPS means the handler caused a significant
3423 change in the properties and overlays at current position, so the
3424 loop should be restarted, to re-invoke the handlers that were
3425 already called. This happens when fontification-functions were
3426 called by handle_fontified_prop, and actually fontified
3427 something. Another case where HANDLED_RECOMPUTE_PROPS is
3428 returned is when we discover overlay strings that need to be
3429 displayed right away. The loop below will continue for as long
3430 as the status is HANDLED_RECOMPUTE_PROPS.
3432 HANDLED_RETURN means return immediately to the caller, to
3433 continue iteration without calling any further handlers. This is
3434 used when we need to act on some property right away, for example
3435 when we need to display the ellipsis or a replacing display
3436 property, such as display string or image.
3438 HANDLED_OVERLAY_STRING_CONSUMED means an overlay string was just
3439 consumed, and the handler switched to the next overlay string.
3440 This signals the loop below to refrain from looking for more
3441 overlays before all the overlay strings of the current overlay
3444 Some of the handlers called by the loop push the iterator state
3445 onto the stack (see 'push_it'), and arrange for the iteration to
3446 continue with another object, such as an image, a display string,
3447 or an overlay string. In most such cases, it->stop_charpos is
3448 set to the first character of the string, so that when the
3449 iteration resumes, this function will immediately be called
3450 again, to examine the properties at the beginning of the string.
3452 When a display or overlay string is exhausted, the iterator state
3453 is popped (see 'pop_it'), and iteration continues with the
3454 previous object. Again, in many such cases this function is
3455 called again to find the next position where properties might
3460 handled
= HANDLED_NORMALLY
;
3462 /* Call text property handlers. */
3463 for (p
= it_props
; p
->handler
; ++p
)
3465 handled
= p
->handler (it
);
3467 if (handled
== HANDLED_RECOMPUTE_PROPS
)
3469 else if (handled
== HANDLED_RETURN
)
3471 /* We still want to show before and after strings from
3472 overlays even if the actual buffer text is replaced. */
3473 if (!handle_overlay_change_p
3475 /* Don't call get_overlay_strings_1 if we already
3476 have overlay strings loaded, because doing so
3477 will load them again and push the iterator state
3478 onto the stack one more time, which is not
3479 expected by the rest of the code that processes
3481 || (it
->current
.overlay_string_index
< 0
3482 && !get_overlay_strings_1 (it
, 0, false)))
3485 setup_for_ellipsis (it
, 0);
3486 /* When handling a display spec, we might load an
3487 empty string. In that case, discard it here. We
3488 used to discard it in handle_single_display_spec,
3489 but that causes get_overlay_strings_1, above, to
3490 ignore overlay strings that we must check. */
3491 if (STRINGP (it
->string
) && !SCHARS (it
->string
))
3495 else if (STRINGP (it
->string
) && !SCHARS (it
->string
))
3499 it
->string_from_display_prop_p
= false;
3500 it
->from_disp_prop_p
= false;
3501 handle_overlay_change_p
= false;
3503 handled
= HANDLED_RECOMPUTE_PROPS
;
3506 else if (handled
== HANDLED_OVERLAY_STRING_CONSUMED
)
3507 handle_overlay_change_p
= false;
3510 if (handled
!= HANDLED_RECOMPUTE_PROPS
)
3512 /* Don't check for overlay strings below when set to deliver
3513 characters from a display vector. */
3514 if (it
->method
== GET_FROM_DISPLAY_VECTOR
)
3515 handle_overlay_change_p
= false;
3517 /* Handle overlay changes.
3518 This sets HANDLED to HANDLED_RECOMPUTE_PROPS
3519 if it finds overlays. */
3520 if (handle_overlay_change_p
)
3521 handled
= handle_overlay_change (it
);
3526 setup_for_ellipsis (it
, 0);
3530 while (handled
== HANDLED_RECOMPUTE_PROPS
);
3532 /* Determine where to stop next. */
3533 if (handled
== HANDLED_NORMALLY
)
3534 compute_stop_pos (it
);
3538 /* Compute IT->stop_charpos from text property and overlay change
3539 information for IT's current position. */
3542 compute_stop_pos (struct it
*it
)
3544 register INTERVAL iv
, next_iv
;
3545 Lisp_Object object
, limit
, position
;
3546 ptrdiff_t charpos
, bytepos
;
3548 if (STRINGP (it
->string
))
3550 /* Strings are usually short, so don't limit the search for
3552 it
->stop_charpos
= it
->end_charpos
;
3553 object
= it
->string
;
3555 charpos
= IT_STRING_CHARPOS (*it
);
3556 bytepos
= IT_STRING_BYTEPOS (*it
);
3562 /* If end_charpos is out of range for some reason, such as a
3563 misbehaving display function, rationalize it (Bug#5984). */
3564 if (it
->end_charpos
> ZV
)
3565 it
->end_charpos
= ZV
;
3566 it
->stop_charpos
= it
->end_charpos
;
3568 /* If next overlay change is in front of the current stop pos
3569 (which is IT->end_charpos), stop there. Note: value of
3570 next_overlay_change is point-max if no overlay change
3572 charpos
= IT_CHARPOS (*it
);
3573 bytepos
= IT_BYTEPOS (*it
);
3574 pos
= next_overlay_change (charpos
);
3575 if (pos
< it
->stop_charpos
)
3576 it
->stop_charpos
= pos
;
3578 /* Set up variables for computing the stop position from text
3579 property changes. */
3580 XSETBUFFER (object
, current_buffer
);
3581 limit
= make_number (IT_CHARPOS (*it
) + TEXT_PROP_DISTANCE_LIMIT
);
3584 /* Get the interval containing IT's position. Value is a null
3585 interval if there isn't such an interval. */
3586 position
= make_number (charpos
);
3587 iv
= validate_interval_range (object
, &position
, &position
, false);
3590 Lisp_Object values_here
[LAST_PROP_IDX
];
3593 /* Get properties here. */
3594 for (p
= it_props
; p
->handler
; ++p
)
3595 values_here
[p
->idx
] = textget (iv
->plist
,
3596 builtin_lisp_symbol (p
->name
));
3598 /* Look for an interval following iv that has different
3600 for (next_iv
= next_interval (iv
);
3603 || XFASTINT (limit
) > next_iv
->position
));
3604 next_iv
= next_interval (next_iv
))
3606 for (p
= it_props
; p
->handler
; ++p
)
3608 Lisp_Object new_value
= textget (next_iv
->plist
,
3609 builtin_lisp_symbol (p
->name
));
3610 if (!EQ (values_here
[p
->idx
], new_value
))
3620 if (INTEGERP (limit
)
3621 && next_iv
->position
>= XFASTINT (limit
))
3622 /* No text property change up to limit. */
3623 it
->stop_charpos
= min (XFASTINT (limit
), it
->stop_charpos
);
3625 /* Text properties change in next_iv. */
3626 it
->stop_charpos
= min (it
->stop_charpos
, next_iv
->position
);
3630 if (it
->cmp_it
.id
< 0)
3632 ptrdiff_t stoppos
= it
->end_charpos
;
3634 if (it
->bidi_p
&& it
->bidi_it
.scan_dir
< 0)
3636 composition_compute_stop_pos (&it
->cmp_it
, charpos
, bytepos
,
3637 stoppos
, it
->string
);
3640 eassert (STRINGP (it
->string
)
3641 || (it
->stop_charpos
>= BEGV
3642 && it
->stop_charpos
>= IT_CHARPOS (*it
)));
3646 /* Return the position of the next overlay change after POS in
3647 current_buffer. Value is point-max if no overlay change
3648 follows. This is like `next-overlay-change' but doesn't use
3652 next_overlay_change (ptrdiff_t pos
)
3654 ptrdiff_t i
, noverlays
;
3656 Lisp_Object
*overlays
;
3659 /* Get all overlays at the given position. */
3660 GET_OVERLAYS_AT (pos
, overlays
, noverlays
, &endpos
, true);
3662 /* If any of these overlays ends before endpos,
3663 use its ending point instead. */
3664 for (i
= 0; i
< noverlays
; ++i
)
3669 oend
= OVERLAY_END (overlays
[i
]);
3670 oendpos
= OVERLAY_POSITION (oend
);
3671 endpos
= min (endpos
, oendpos
);
3678 /* How many characters forward to search for a display property or
3679 display string. Searching too far forward makes the bidi display
3680 sluggish, especially in small windows. */
3681 #define MAX_DISP_SCAN 250
3683 /* Return the character position of a display string at or after
3684 position specified by POSITION. If no display string exists at or
3685 after POSITION, return ZV. A display string is either an overlay
3686 with `display' property whose value is a string, or a `display'
3687 text property whose value is a string. STRING is data about the
3688 string to iterate; if STRING->lstring is nil, we are iterating a
3689 buffer. FRAME_WINDOW_P is true when we are displaying a window
3690 on a GUI frame. DISP_PROP is set to zero if we searched
3691 MAX_DISP_SCAN characters forward without finding any display
3692 strings, non-zero otherwise. It is set to 2 if the display string
3693 uses any kind of `(space ...)' spec that will produce a stretch of
3694 white space in the text area. */
3696 compute_display_string_pos (struct text_pos
*position
,
3697 struct bidi_string_data
*string
,
3699 bool frame_window_p
, int *disp_prop
)
3701 /* OBJECT = nil means current buffer. */
3702 Lisp_Object object
, object1
;
3703 Lisp_Object pos
, spec
, limpos
;
3704 bool string_p
= string
&& (STRINGP (string
->lstring
) || string
->s
);
3705 ptrdiff_t eob
= string_p
? string
->schars
: ZV
;
3706 ptrdiff_t begb
= string_p
? 0 : BEGV
;
3707 ptrdiff_t bufpos
, charpos
= CHARPOS (*position
);
3709 (charpos
< eob
- MAX_DISP_SCAN
) ? charpos
+ MAX_DISP_SCAN
: eob
;
3710 struct text_pos tpos
;
3713 if (string
&& STRINGP (string
->lstring
))
3714 object1
= object
= string
->lstring
;
3715 else if (w
&& !string_p
)
3717 XSETWINDOW (object
, w
);
3721 object1
= object
= Qnil
;
3726 /* We don't support display properties whose values are strings
3727 that have display string properties. */
3728 || string
->from_disp_str
3729 /* C strings cannot have display properties. */
3730 || (string
->s
&& !STRINGP (object
)))
3736 /* If the character at CHARPOS is where the display string begins,
3738 pos
= make_number (charpos
);
3739 if (STRINGP (object
))
3740 bufpos
= string
->bufpos
;
3744 if (!NILP (spec
= Fget_char_property (pos
, Qdisplay
, object
))
3746 || !EQ (Fget_char_property (make_number (charpos
- 1), Qdisplay
,
3749 && (rv
= handle_display_spec (NULL
, spec
, object
, Qnil
, &tpos
, bufpos
,
3757 /* Look forward for the first character with a `display' property
3758 that will replace the underlying text when displayed. */
3759 limpos
= make_number (lim
);
3761 pos
= Fnext_single_char_property_change (pos
, Qdisplay
, object1
, limpos
);
3762 CHARPOS (tpos
) = XFASTINT (pos
);
3763 if (CHARPOS (tpos
) >= lim
)
3768 if (STRINGP (object
))
3769 BYTEPOS (tpos
) = string_char_to_byte (object
, CHARPOS (tpos
));
3771 BYTEPOS (tpos
) = CHAR_TO_BYTE (CHARPOS (tpos
));
3772 spec
= Fget_char_property (pos
, Qdisplay
, object
);
3773 if (!STRINGP (object
))
3774 bufpos
= CHARPOS (tpos
);
3775 } while (NILP (spec
)
3776 || !(rv
= handle_display_spec (NULL
, spec
, object
, Qnil
, &tpos
,
3777 bufpos
, frame_window_p
)));
3781 return CHARPOS (tpos
);
3784 /* Return the character position of the end of the display string that
3785 started at CHARPOS. If there's no display string at CHARPOS,
3786 return -1. A display string is either an overlay with `display'
3787 property whose value is a string or a `display' text property whose
3788 value is a string. */
3790 compute_display_string_end (ptrdiff_t charpos
, struct bidi_string_data
*string
)
3792 /* OBJECT = nil means current buffer. */
3793 Lisp_Object object
=
3794 (string
&& STRINGP (string
->lstring
)) ? string
->lstring
: Qnil
;
3795 Lisp_Object pos
= make_number (charpos
);
3797 (STRINGP (object
) || (string
&& string
->s
)) ? string
->schars
: ZV
;
3799 if (charpos
>= eob
|| (string
->s
&& !STRINGP (object
)))
3802 /* It could happen that the display property or overlay was removed
3803 since we found it in compute_display_string_pos above. One way
3804 this can happen is if JIT font-lock was called (through
3805 handle_fontified_prop), and jit-lock-functions remove text
3806 properties or overlays from the portion of buffer that includes
3807 CHARPOS. Muse mode is known to do that, for example. In this
3808 case, we return -1 to the caller, to signal that no display
3809 string is actually present at CHARPOS. See bidi_fetch_char for
3810 how this is handled.
3812 An alternative would be to never look for display properties past
3813 it->stop_charpos. But neither compute_display_string_pos nor
3814 bidi_fetch_char that calls it know or care where the next
3816 if (NILP (Fget_char_property (pos
, Qdisplay
, object
)))
3819 /* Look forward for the first character where the `display' property
3821 pos
= Fnext_single_char_property_change (pos
, Qdisplay
, object
, Qnil
);
3823 return XFASTINT (pos
);
3828 /***********************************************************************
3830 ***********************************************************************/
3832 /* Handle changes in the `fontified' property of the current buffer by
3833 calling hook functions from Qfontification_functions to fontify
3836 static enum prop_handled
3837 handle_fontified_prop (struct it
*it
)
3839 Lisp_Object prop
, pos
;
3840 enum prop_handled handled
= HANDLED_NORMALLY
;
3842 if (!NILP (Vmemory_full
))
3845 /* Get the value of the `fontified' property at IT's current buffer
3846 position. (The `fontified' property doesn't have a special
3847 meaning in strings.) If the value is nil, call functions from
3848 Qfontification_functions. */
3849 if (!STRINGP (it
->string
)
3851 && !NILP (Vfontification_functions
)
3852 && !NILP (Vrun_hooks
)
3853 && (pos
= make_number (IT_CHARPOS (*it
)),
3854 prop
= Fget_char_property (pos
, Qfontified
, Qnil
),
3855 /* Ignore the special cased nil value always present at EOB since
3856 no amount of fontifying will be able to change it. */
3857 NILP (prop
) && IT_CHARPOS (*it
) < Z
))
3859 ptrdiff_t count
= SPECPDL_INDEX ();
3861 struct buffer
*obuf
= current_buffer
;
3862 ptrdiff_t begv
= BEGV
, zv
= ZV
;
3863 bool old_clip_changed
= current_buffer
->clip_changed
;
3865 val
= Vfontification_functions
;
3866 specbind (Qfontification_functions
, Qnil
);
3868 eassert (it
->end_charpos
== ZV
);
3870 if (!CONSP (val
) || EQ (XCAR (val
), Qlambda
))
3871 safe_call1 (val
, pos
);
3874 Lisp_Object fns
, fn
;
3878 for (; CONSP (val
); val
= XCDR (val
))
3884 /* A value of t indicates this hook has a local
3885 binding; it means to run the global binding too.
3886 In a global value, t should not occur. If it
3887 does, we must ignore it to avoid an endless
3889 for (fns
= Fdefault_value (Qfontification_functions
);
3895 safe_call1 (fn
, pos
);
3899 safe_call1 (fn
, pos
);
3903 unbind_to (count
, Qnil
);
3905 /* Fontification functions routinely call `save-restriction'.
3906 Normally, this tags clip_changed, which can confuse redisplay
3907 (see discussion in Bug#6671). Since we don't perform any
3908 special handling of fontification changes in the case where
3909 `save-restriction' isn't called, there's no point doing so in
3910 this case either. So, if the buffer's restrictions are
3911 actually left unchanged, reset clip_changed. */
3912 if (obuf
== current_buffer
)
3914 if (begv
== BEGV
&& zv
== ZV
)
3915 current_buffer
->clip_changed
= old_clip_changed
;
3917 /* There isn't much we can reasonably do to protect against
3918 misbehaving fontification, but here's a fig leaf. */
3919 else if (BUFFER_LIVE_P (obuf
))
3920 set_buffer_internal_1 (obuf
);
3922 /* The fontification code may have added/removed text.
3923 It could do even a lot worse, but let's at least protect against
3924 the most obvious case where only the text past `pos' gets changed',
3925 as is/was done in grep.el where some escapes sequences are turned
3926 into face properties (bug#7876). */
3927 it
->end_charpos
= ZV
;
3929 /* Return HANDLED_RECOMPUTE_PROPS only if function fontified
3930 something. This avoids an endless loop if they failed to
3931 fontify the text for which reason ever. */
3932 if (!NILP (Fget_char_property (pos
, Qfontified
, Qnil
)))
3933 handled
= HANDLED_RECOMPUTE_PROPS
;
3941 /***********************************************************************
3943 ***********************************************************************/
3945 /* Set up iterator IT from face properties at its current position.
3946 Called from handle_stop. */
3948 static enum prop_handled
3949 handle_face_prop (struct it
*it
)
3952 ptrdiff_t next_stop
;
3954 if (!STRINGP (it
->string
))
3957 = face_at_buffer_position (it
->w
,
3961 + TEXT_PROP_DISTANCE_LIMIT
),
3962 false, it
->base_face_id
);
3964 /* Is this a start of a run of characters with box face?
3965 Caveat: this can be called for a freshly initialized
3966 iterator; face_id is -1 in this case. We know that the new
3967 face will not change until limit, i.e. if the new face has a
3968 box, all characters up to limit will have one. But, as
3969 usual, we don't know whether limit is really the end. */
3970 if (new_face_id
!= it
->face_id
)
3972 struct face
*new_face
= FACE_FROM_ID (it
->f
, new_face_id
);
3973 /* If it->face_id is -1, old_face below will be NULL, see
3974 the definition of FACE_FROM_ID_OR_NULL. This will happen
3975 if this is the initial call that gets the face. */
3976 struct face
*old_face
= FACE_FROM_ID_OR_NULL (it
->f
, it
->face_id
);
3978 /* If the value of face_id of the iterator is -1, we have to
3979 look in front of IT's position and see whether there is a
3980 face there that's different from new_face_id. */
3981 if (!old_face
&& IT_CHARPOS (*it
) > BEG
)
3983 int prev_face_id
= face_before_it_pos (it
);
3985 old_face
= FACE_FROM_ID_OR_NULL (it
->f
, prev_face_id
);
3988 /* If the new face has a box, but the old face does not,
3989 this is the start of a run of characters with box face,
3990 i.e. this character has a shadow on the left side. */
3991 it
->start_of_box_run_p
= (new_face
->box
!= FACE_NO_BOX
3992 && (old_face
== NULL
|| !old_face
->box
));
3993 it
->face_box_p
= new_face
->box
!= FACE_NO_BOX
;
4001 Lisp_Object from_overlay
4002 = (it
->current
.overlay_string_index
>= 0
4003 ? it
->string_overlays
[it
->current
.overlay_string_index
4004 % OVERLAY_STRING_CHUNK_SIZE
]
4007 /* See if we got to this string directly or indirectly from
4008 an overlay property. That includes the before-string or
4009 after-string of an overlay, strings in display properties
4010 provided by an overlay, their text properties, etc.
4012 FROM_OVERLAY is the overlay that brought us here, or nil if none. */
4013 if (! NILP (from_overlay
))
4014 for (i
= it
->sp
- 1; i
>= 0; i
--)
4016 if (it
->stack
[i
].current
.overlay_string_index
>= 0)
4018 = it
->string_overlays
[it
->stack
[i
].current
.overlay_string_index
4019 % OVERLAY_STRING_CHUNK_SIZE
];
4020 else if (! NILP (it
->stack
[i
].from_overlay
))
4021 from_overlay
= it
->stack
[i
].from_overlay
;
4023 if (!NILP (from_overlay
))
4027 if (! NILP (from_overlay
))
4029 bufpos
= IT_CHARPOS (*it
);
4030 /* For a string from an overlay, the base face depends
4031 only on text properties and ignores overlays. */
4033 = face_for_overlay_string (it
->w
,
4037 + TEXT_PROP_DISTANCE_LIMIT
),
4045 /* For strings from a `display' property, use the face at
4046 IT's current buffer position as the base face to merge
4047 with, so that overlay strings appear in the same face as
4048 surrounding text, unless they specify their own faces.
4049 For strings from wrap-prefix and line-prefix properties,
4050 use the default face, possibly remapped via
4051 Vface_remapping_alist. */
4052 /* Note that the fact that we use the face at _buffer_
4053 position means that a 'display' property on an overlay
4054 string will not inherit the face of that overlay string,
4055 but will instead revert to the face of buffer text
4056 covered by the overlay. This is visible, e.g., when the
4057 overlay specifies a box face, but neither the buffer nor
4058 the display string do. This sounds like a design bug,
4059 but Emacs always did that since v21.1, so changing that
4060 might be a big deal. */
4061 base_face_id
= it
->string_from_prefix_prop_p
4062 ? (!NILP (Vface_remapping_alist
)
4063 ? lookup_basic_face (it
->w
, it
->f
, DEFAULT_FACE_ID
)
4065 : underlying_face_id (it
);
4068 new_face_id
= face_at_string_position (it
->w
,
4070 IT_STRING_CHARPOS (*it
),
4073 base_face_id
, false);
4075 /* Is this a start of a run of characters with box? Caveat:
4076 this can be called for a freshly allocated iterator; face_id
4077 is -1 is this case. We know that the new face will not
4078 change until the next check pos, i.e. if the new face has a
4079 box, all characters up to that position will have a
4080 box. But, as usual, we don't know whether that position
4081 is really the end. */
4082 if (new_face_id
!= it
->face_id
)
4084 struct face
*new_face
= FACE_FROM_ID (it
->f
, new_face_id
);
4085 struct face
*old_face
= FACE_FROM_ID_OR_NULL (it
->f
, it
->face_id
);
4087 /* If new face has a box but old face hasn't, this is the
4088 start of a run of characters with box, i.e. it has a
4089 shadow on the left side. */
4090 it
->start_of_box_run_p
4091 = new_face
->box
&& (old_face
== NULL
|| !old_face
->box
);
4092 it
->face_box_p
= new_face
->box
!= FACE_NO_BOX
;
4096 it
->face_id
= new_face_id
;
4097 return HANDLED_NORMALLY
;
4101 /* Return the ID of the face ``underlying'' IT's current position,
4102 which is in a string. If the iterator is associated with a
4103 buffer, return the face at IT's current buffer position.
4104 Otherwise, use the iterator's base_face_id. */
4107 underlying_face_id (struct it
*it
)
4109 int face_id
= it
->base_face_id
, i
;
4111 eassert (STRINGP (it
->string
));
4113 for (i
= it
->sp
- 1; i
>= 0; --i
)
4114 if (NILP (it
->stack
[i
].string
))
4115 face_id
= it
->stack
[i
].face_id
;
4121 /* Compute the face one character before or after the current position
4122 of IT, in the visual order. BEFORE_P means get the face
4123 in front (to the left in L2R paragraphs, to the right in R2L
4124 paragraphs) of IT's screen position. Value is the ID of the face. */
4127 face_before_or_after_it_pos (struct it
*it
, bool before_p
)
4130 ptrdiff_t next_check_charpos
;
4132 void *it_copy_data
= NULL
;
4134 eassert (it
->s
== NULL
);
4136 if (STRINGP (it
->string
))
4138 ptrdiff_t bufpos
, charpos
;
4141 /* No face change past the end of the string (for the case
4142 we are padding with spaces). No face change before the
4144 if (IT_STRING_CHARPOS (*it
) >= SCHARS (it
->string
)
4145 || (IT_STRING_CHARPOS (*it
) == 0 && before_p
))
4150 /* Set charpos to the position before or after IT's current
4151 position, in the logical order, which in the non-bidi
4152 case is the same as the visual order. */
4154 charpos
= IT_STRING_CHARPOS (*it
) - 1;
4155 else if (it
->what
== IT_COMPOSITION
)
4156 /* For composition, we must check the character after the
4158 charpos
= IT_STRING_CHARPOS (*it
) + it
->cmp_it
.nchars
;
4160 charpos
= IT_STRING_CHARPOS (*it
) + 1;
4166 /* With bidi iteration, the character before the current
4167 in the visual order cannot be found by simple
4168 iteration, because "reverse" reordering is not
4169 supported. Instead, we need to start from the string
4170 beginning and go all the way to the current string
4171 position, remembering the previous position. */
4172 /* Ignore face changes before the first visible
4173 character on this display line. */
4174 if (it
->current_x
<= it
->first_visible_x
)
4176 SAVE_IT (it_copy
, *it
, it_copy_data
);
4177 IT_STRING_CHARPOS (it_copy
) = 0;
4178 bidi_init_it (0, 0, FRAME_WINDOW_P (it_copy
.f
), &it_copy
.bidi_it
);
4182 charpos
= IT_STRING_CHARPOS (it_copy
);
4183 if (charpos
>= SCHARS (it
->string
))
4185 bidi_move_to_visually_next (&it_copy
.bidi_it
);
4187 while (IT_STRING_CHARPOS (it_copy
) != IT_STRING_CHARPOS (*it
));
4189 RESTORE_IT (it
, it
, it_copy_data
);
4193 /* Set charpos to the string position of the character
4194 that comes after IT's current position in the visual
4196 int n
= (it
->what
== IT_COMPOSITION
? it
->cmp_it
.nchars
: 1);
4200 bidi_move_to_visually_next (&it_copy
.bidi_it
);
4202 charpos
= it_copy
.bidi_it
.charpos
;
4205 eassert (0 <= charpos
&& charpos
<= SCHARS (it
->string
));
4207 if (it
->current
.overlay_string_index
>= 0)
4208 bufpos
= IT_CHARPOS (*it
);
4212 base_face_id
= underlying_face_id (it
);
4214 /* Get the face for ASCII, or unibyte. */
4215 face_id
= face_at_string_position (it
->w
,
4219 &next_check_charpos
,
4220 base_face_id
, false);
4222 /* Correct the face for charsets different from ASCII. Do it
4223 for the multibyte case only. The face returned above is
4224 suitable for unibyte text if IT->string is unibyte. */
4225 if (STRING_MULTIBYTE (it
->string
))
4227 struct text_pos pos1
= string_pos (charpos
, it
->string
);
4228 const unsigned char *p
= SDATA (it
->string
) + BYTEPOS (pos1
);
4230 struct face
*face
= FACE_FROM_ID (it
->f
, face_id
);
4232 c
= string_char_and_length (p
, &len
);
4233 face_id
= FACE_FOR_CHAR (it
->f
, face
, c
, charpos
, it
->string
);
4238 struct text_pos pos
;
4240 if ((IT_CHARPOS (*it
) >= ZV
&& !before_p
)
4241 || (IT_CHARPOS (*it
) <= BEGV
&& before_p
))
4244 limit
= IT_CHARPOS (*it
) + TEXT_PROP_DISTANCE_LIMIT
;
4245 pos
= it
->current
.pos
;
4250 DEC_TEXT_POS (pos
, it
->multibyte_p
);
4253 if (it
->what
== IT_COMPOSITION
)
4255 /* For composition, we must check the position after
4257 pos
.charpos
+= it
->cmp_it
.nchars
;
4258 pos
.bytepos
+= it
->len
;
4261 INC_TEXT_POS (pos
, it
->multibyte_p
);
4270 /* With bidi iteration, the character before the current
4271 in the visual order cannot be found by simple
4272 iteration, because "reverse" reordering is not
4273 supported. Instead, we need to use the move_it_*
4274 family of functions, and move to the previous
4275 character starting from the beginning of the visual
4277 /* Ignore face changes before the first visible
4278 character on this display line. */
4279 if (it
->current_x
<= it
->first_visible_x
)
4281 SAVE_IT (it_copy
, *it
, it_copy_data
);
4282 /* Implementation note: Since move_it_in_display_line
4283 works in the iterator geometry, and thinks the first
4284 character is always the leftmost, even in R2L lines,
4285 we don't need to distinguish between the R2L and L2R
4287 current_x
= it_copy
.current_x
;
4288 move_it_vertically_backward (&it_copy
, 0);
4289 move_it_in_display_line (&it_copy
, ZV
, current_x
- 1, MOVE_TO_X
);
4290 pos
= it_copy
.current
.pos
;
4291 RESTORE_IT (it
, it
, it_copy_data
);
4295 /* Set charpos to the buffer position of the character
4296 that comes after IT's current position in the visual
4298 int n
= (it
->what
== IT_COMPOSITION
? it
->cmp_it
.nchars
: 1);
4302 bidi_move_to_visually_next (&it_copy
.bidi_it
);
4305 it_copy
.bidi_it
.charpos
, it_copy
.bidi_it
.bytepos
);
4308 eassert (BEGV
<= CHARPOS (pos
) && CHARPOS (pos
) <= ZV
);
4310 /* Determine face for CHARSET_ASCII, or unibyte. */
4311 face_id
= face_at_buffer_position (it
->w
,
4313 &next_check_charpos
,
4316 /* Correct the face for charsets different from ASCII. Do it
4317 for the multibyte case only. The face returned above is
4318 suitable for unibyte text if current_buffer is unibyte. */
4319 if (it
->multibyte_p
)
4321 int c
= FETCH_MULTIBYTE_CHAR (BYTEPOS (pos
));
4322 struct face
*face
= FACE_FROM_ID (it
->f
, face_id
);
4323 face_id
= FACE_FOR_CHAR (it
->f
, face
, c
, CHARPOS (pos
), Qnil
);
4332 /***********************************************************************
4334 ***********************************************************************/
4336 /* Set up iterator IT from invisible properties at its current
4337 position. Called from handle_stop. */
4339 static enum prop_handled
4340 handle_invisible_prop (struct it
*it
)
4342 enum prop_handled handled
= HANDLED_NORMALLY
;
4346 if (STRINGP (it
->string
))
4348 Lisp_Object end_charpos
, limit
;
4350 /* Get the value of the invisible text property at the
4351 current position. Value will be nil if there is no such
4353 end_charpos
= make_number (IT_STRING_CHARPOS (*it
));
4354 prop
= Fget_text_property (end_charpos
, Qinvisible
, it
->string
);
4355 invis
= TEXT_PROP_MEANS_INVISIBLE (prop
);
4357 if (invis
!= 0 && IT_STRING_CHARPOS (*it
) < it
->end_charpos
)
4359 /* Record whether we have to display an ellipsis for the
4361 bool display_ellipsis_p
= (invis
== 2);
4362 ptrdiff_t len
, endpos
;
4364 handled
= HANDLED_RECOMPUTE_PROPS
;
4366 /* Get the position at which the next visible text can be
4367 found in IT->string, if any. */
4368 endpos
= len
= SCHARS (it
->string
);
4369 XSETINT (limit
, len
);
4373 = Fnext_single_property_change (end_charpos
, Qinvisible
,
4375 /* Since LIMIT is always an integer, so should be the
4376 value returned by Fnext_single_property_change. */
4377 eassert (INTEGERP (end_charpos
));
4378 if (INTEGERP (end_charpos
))
4380 endpos
= XFASTINT (end_charpos
);
4381 prop
= Fget_text_property (end_charpos
, Qinvisible
, it
->string
);
4382 invis
= TEXT_PROP_MEANS_INVISIBLE (prop
);
4384 display_ellipsis_p
= true;
4386 else /* Should never happen; but if it does, exit the loop. */
4389 while (invis
!= 0 && endpos
< len
);
4391 if (display_ellipsis_p
)
4392 it
->ellipsis_p
= true;
4396 /* Text at END_CHARPOS is visible. Move IT there. */
4397 struct text_pos old
;
4400 old
= it
->current
.string_pos
;
4401 oldpos
= CHARPOS (old
);
4404 if (it
->bidi_it
.first_elt
4405 && it
->bidi_it
.charpos
< SCHARS (it
->string
))
4406 bidi_paragraph_init (it
->paragraph_embedding
,
4407 &it
->bidi_it
, true);
4408 /* Bidi-iterate out of the invisible text. */
4411 bidi_move_to_visually_next (&it
->bidi_it
);
4413 while (oldpos
<= it
->bidi_it
.charpos
4414 && it
->bidi_it
.charpos
< endpos
4415 && it
->bidi_it
.charpos
< it
->bidi_it
.string
.schars
);
4417 IT_STRING_CHARPOS (*it
) = it
->bidi_it
.charpos
;
4418 IT_STRING_BYTEPOS (*it
) = it
->bidi_it
.bytepos
;
4419 if (IT_CHARPOS (*it
) >= endpos
)
4420 it
->prev_stop
= endpos
;
4424 IT_STRING_CHARPOS (*it
) = endpos
;
4425 compute_string_pos (&it
->current
.string_pos
, old
, it
->string
);
4430 /* The rest of the string is invisible. If this is an
4431 overlay string, proceed with the next overlay string
4432 or whatever comes and return a character from there. */
4433 if (it
->current
.overlay_string_index
>= 0
4434 && !display_ellipsis_p
)
4436 next_overlay_string (it
);
4437 /* Don't check for overlay strings when we just
4438 finished processing them. */
4439 handled
= HANDLED_OVERLAY_STRING_CONSUMED
;
4443 IT_STRING_CHARPOS (*it
) = SCHARS (it
->string
);
4444 IT_STRING_BYTEPOS (*it
) = SBYTES (it
->string
);
4451 ptrdiff_t newpos
, next_stop
, start_charpos
, tem
;
4452 Lisp_Object pos
, overlay
;
4454 /* First of all, is there invisible text at this position? */
4455 tem
= start_charpos
= IT_CHARPOS (*it
);
4456 pos
= make_number (tem
);
4457 prop
= get_char_property_and_overlay (pos
, Qinvisible
, it
->window
,
4459 invis
= TEXT_PROP_MEANS_INVISIBLE (prop
);
4461 /* If we are on invisible text, skip over it. */
4462 if (invis
!= 0 && start_charpos
< it
->end_charpos
)
4464 /* Record whether we have to display an ellipsis for the
4466 bool display_ellipsis_p
= invis
== 2;
4468 handled
= HANDLED_RECOMPUTE_PROPS
;
4470 /* Loop skipping over invisible text. The loop is left at
4471 ZV or with IT on the first char being visible again. */
4474 /* Try to skip some invisible text. Return value is the
4475 position reached which can be equal to where we start
4476 if there is nothing invisible there. This skips both
4477 over invisible text properties and overlays with
4478 invisible property. */
4479 newpos
= skip_invisible (tem
, &next_stop
, ZV
, it
->window
);
4481 /* If we skipped nothing at all we weren't at invisible
4482 text in the first place. If everything to the end of
4483 the buffer was skipped, end the loop. */
4484 if (newpos
== tem
|| newpos
>= ZV
)
4488 /* We skipped some characters but not necessarily
4489 all there are. Check if we ended up on visible
4490 text. Fget_char_property returns the property of
4491 the char before the given position, i.e. if we
4492 get invis = 0, this means that the char at
4493 newpos is visible. */
4494 pos
= make_number (newpos
);
4495 prop
= Fget_char_property (pos
, Qinvisible
, it
->window
);
4496 invis
= TEXT_PROP_MEANS_INVISIBLE (prop
);
4499 /* If we ended up on invisible text, proceed to
4500 skip starting with next_stop. */
4504 /* If there are adjacent invisible texts, don't lose the
4505 second one's ellipsis. */
4507 display_ellipsis_p
= true;
4511 /* The position newpos is now either ZV or on visible text. */
4514 ptrdiff_t bpos
= CHAR_TO_BYTE (newpos
);
4516 = bpos
== ZV_BYTE
|| FETCH_BYTE (bpos
) == '\n';
4518 = newpos
<= BEGV
|| FETCH_BYTE (bpos
- 1) == '\n';
4520 /* If the invisible text ends on a newline or on a
4521 character after a newline, we can avoid the costly,
4522 character by character, bidi iteration to NEWPOS, and
4523 instead simply reseat the iterator there. That's
4524 because all bidi reordering information is tossed at
4525 the newline. This is a big win for modes that hide
4526 complete lines, like Outline, Org, etc. */
4527 if (on_newline
|| after_newline
)
4529 struct text_pos tpos
;
4530 bidi_dir_t pdir
= it
->bidi_it
.paragraph_dir
;
4532 SET_TEXT_POS (tpos
, newpos
, bpos
);
4533 reseat_1 (it
, tpos
, false);
4534 /* If we reseat on a newline/ZV, we need to prep the
4535 bidi iterator for advancing to the next character
4536 after the newline/EOB, keeping the current paragraph
4537 direction (so that PRODUCE_GLYPHS does TRT wrt
4538 prepending/appending glyphs to a glyph row). */
4541 it
->bidi_it
.first_elt
= false;
4542 it
->bidi_it
.paragraph_dir
= pdir
;
4543 it
->bidi_it
.ch
= (bpos
== ZV_BYTE
) ? -1 : '\n';
4544 it
->bidi_it
.nchars
= 1;
4545 it
->bidi_it
.ch_len
= 1;
4548 else /* Must use the slow method. */
4550 /* With bidi iteration, the region of invisible text
4551 could start and/or end in the middle of a
4552 non-base embedding level. Therefore, we need to
4553 skip invisible text using the bidi iterator,
4554 starting at IT's current position, until we find
4555 ourselves outside of the invisible text.
4556 Skipping invisible text _after_ bidi iteration
4557 avoids affecting the visual order of the
4558 displayed text when invisible properties are
4559 added or removed. */
4560 if (it
->bidi_it
.first_elt
&& it
->bidi_it
.charpos
< ZV
)
4562 /* If we were `reseat'ed to a new paragraph,
4563 determine the paragraph base direction. We
4564 need to do it now because
4565 next_element_from_buffer may not have a
4566 chance to do it, if we are going to skip any
4567 text at the beginning, which resets the
4569 bidi_paragraph_init (it
->paragraph_embedding
,
4570 &it
->bidi_it
, true);
4574 bidi_move_to_visually_next (&it
->bidi_it
);
4576 while (it
->stop_charpos
<= it
->bidi_it
.charpos
4577 && it
->bidi_it
.charpos
< newpos
);
4578 IT_CHARPOS (*it
) = it
->bidi_it
.charpos
;
4579 IT_BYTEPOS (*it
) = it
->bidi_it
.bytepos
;
4580 /* If we overstepped NEWPOS, record its position in
4581 the iterator, so that we skip invisible text if
4582 later the bidi iteration lands us in the
4583 invisible region again. */
4584 if (IT_CHARPOS (*it
) >= newpos
)
4585 it
->prev_stop
= newpos
;
4590 IT_CHARPOS (*it
) = newpos
;
4591 IT_BYTEPOS (*it
) = CHAR_TO_BYTE (newpos
);
4594 if (display_ellipsis_p
)
4596 /* Make sure that the glyphs of the ellipsis will get
4597 correct `charpos' values. If we would not update
4598 it->position here, the glyphs would belong to the
4599 last visible character _before_ the invisible
4600 text, which confuses `set_cursor_from_row'.
4602 We use the last invisible position instead of the
4603 first because this way the cursor is always drawn on
4604 the first "." of the ellipsis, whenever PT is inside
4605 the invisible text. Otherwise the cursor would be
4606 placed _after_ the ellipsis when the point is after the
4607 first invisible character. */
4608 if (!STRINGP (it
->object
))
4610 it
->position
.charpos
= newpos
- 1;
4611 it
->position
.bytepos
= CHAR_TO_BYTE (it
->position
.charpos
);
4615 /* If there are before-strings at the start of invisible
4616 text, and the text is invisible because of a text
4617 property, arrange to show before-strings because 20.x did
4618 it that way. (If the text is invisible because of an
4619 overlay property instead of a text property, this is
4620 already handled in the overlay code.) */
4622 && get_overlay_strings (it
, it
->stop_charpos
))
4624 handled
= HANDLED_RECOMPUTE_PROPS
;
4627 it
->stack
[it
->sp
- 1].display_ellipsis_p
= display_ellipsis_p
;
4628 /* The call to get_overlay_strings above recomputes
4629 it->stop_charpos, but it only considers changes
4630 in properties and overlays beyond iterator's
4631 current position. This causes us to miss changes
4632 that happen exactly where the invisible property
4633 ended. So we play it safe here and force the
4634 iterator to check for potential stop positions
4635 immediately after the invisible text. Note that
4636 if get_overlay_strings returns true, it
4637 normally also pushed the iterator stack, so we
4638 need to update the stop position in the slot
4639 below the current one. */
4640 it
->stack
[it
->sp
- 1].stop_charpos
4641 = CHARPOS (it
->stack
[it
->sp
- 1].current
.pos
);
4644 else if (display_ellipsis_p
)
4646 it
->ellipsis_p
= true;
4647 /* Let the ellipsis display before
4648 considering any properties of the following char.
4649 Fixes jasonr@gnu.org 01 Oct 07 bug. */
4650 handled
= HANDLED_RETURN
;
4659 /* Make iterator IT return `...' next.
4660 Replaces LEN characters from buffer. */
4663 setup_for_ellipsis (struct it
*it
, int len
)
4665 /* Use the display table definition for `...'. Invalid glyphs
4666 will be handled by the method returning elements from dpvec. */
4667 if (it
->dp
&& VECTORP (DISP_INVIS_VECTOR (it
->dp
)))
4669 struct Lisp_Vector
*v
= XVECTOR (DISP_INVIS_VECTOR (it
->dp
));
4670 it
->dpvec
= v
->contents
;
4671 it
->dpend
= v
->contents
+ v
->header
.size
;
4675 /* Default `...'. */
4676 it
->dpvec
= default_invis_vector
;
4677 it
->dpend
= default_invis_vector
+ 3;
4680 it
->dpvec_char_len
= len
;
4681 it
->current
.dpvec_index
= 0;
4682 it
->dpvec_face_id
= -1;
4684 /* Use IT->saved_face_id for the ellipsis, so that it has the same
4685 face as the preceding text. IT->saved_face_id was set in
4686 handle_stop to the face of the preceding character, and will be
4687 different from IT->face_id only if the invisible text skipped in
4688 handle_invisible_prop has some non-default face on its first
4689 character. We thus ignore the face of the invisible text when we
4690 display the ellipsis. IT's face is restored in set_iterator_to_next. */
4691 if (it
->saved_face_id
>= 0)
4692 it
->face_id
= it
->saved_face_id
;
4694 /* If the ellipsis represents buffer text, it means we advanced in
4695 the buffer, so we should no longer ignore overlay strings. */
4696 if (it
->method
== GET_FROM_BUFFER
)
4697 it
->ignore_overlay_strings_at_pos_p
= false;
4699 it
->method
= GET_FROM_DISPLAY_VECTOR
;
4700 it
->ellipsis_p
= true;
4705 /***********************************************************************
4707 ***********************************************************************/
4709 /* Set up iterator IT from `display' property at its current position.
4710 Called from handle_stop.
4711 We return HANDLED_RETURN if some part of the display property
4712 overrides the display of the buffer text itself.
4713 Otherwise we return HANDLED_NORMALLY. */
4715 static enum prop_handled
4716 handle_display_prop (struct it
*it
)
4718 Lisp_Object propval
, object
, overlay
;
4719 struct text_pos
*position
;
4721 /* Nonzero if some property replaces the display of the text itself. */
4722 int display_replaced
= 0;
4724 if (STRINGP (it
->string
))
4726 object
= it
->string
;
4727 position
= &it
->current
.string_pos
;
4728 bufpos
= CHARPOS (it
->current
.pos
);
4732 XSETWINDOW (object
, it
->w
);
4733 position
= &it
->current
.pos
;
4734 bufpos
= CHARPOS (*position
);
4737 /* Reset those iterator values set from display property values. */
4738 it
->slice
.x
= it
->slice
.y
= it
->slice
.width
= it
->slice
.height
= Qnil
;
4739 it
->space_width
= Qnil
;
4740 it
->font_height
= Qnil
;
4743 /* We don't support recursive `display' properties, i.e. string
4744 values that have a string `display' property, that have a string
4745 `display' property etc. */
4746 if (!it
->string_from_display_prop_p
)
4747 it
->area
= TEXT_AREA
;
4749 propval
= get_char_property_and_overlay (make_number (position
->charpos
),
4750 Qdisplay
, object
, &overlay
);
4752 return HANDLED_NORMALLY
;
4753 /* Now OVERLAY is the overlay that gave us this property, or nil
4754 if it was a text property. */
4756 if (!STRINGP (it
->string
))
4757 object
= it
->w
->contents
;
4759 display_replaced
= handle_display_spec (it
, propval
, object
, overlay
,
4761 FRAME_WINDOW_P (it
->f
));
4762 return display_replaced
!= 0 ? HANDLED_RETURN
: HANDLED_NORMALLY
;
4765 /* Subroutine of handle_display_prop. Returns non-zero if the display
4766 specification in SPEC is a replacing specification, i.e. it would
4767 replace the text covered by `display' property with something else,
4768 such as an image or a display string. If SPEC includes any kind or
4769 `(space ...) specification, the value is 2; this is used by
4770 compute_display_string_pos, which see.
4772 See handle_single_display_spec for documentation of arguments.
4773 FRAME_WINDOW_P is true if the window being redisplayed is on a
4774 GUI frame; this argument is used only if IT is NULL, see below.
4776 IT can be NULL, if this is called by the bidi reordering code
4777 through compute_display_string_pos, which see. In that case, this
4778 function only examines SPEC, but does not otherwise "handle" it, in
4779 the sense that it doesn't set up members of IT from the display
4782 handle_display_spec (struct it
*it
, Lisp_Object spec
, Lisp_Object object
,
4783 Lisp_Object overlay
, struct text_pos
*position
,
4784 ptrdiff_t bufpos
, bool frame_window_p
)
4787 bool enable_eval
= true;
4789 /* Support (disable-eval PROP) which is used by enriched.el. */
4790 if (CONSP (spec
) && EQ (XCAR (spec
), Qdisable_eval
))
4792 enable_eval
= false;
4793 spec
= XCAR (XCDR (spec
));
4797 /* Simple specifications. */
4798 && !EQ (XCAR (spec
), Qimage
)
4799 #ifdef HAVE_XWIDGETS
4800 && !EQ (XCAR (spec
), Qxwidget
)
4802 && !EQ (XCAR (spec
), Qspace
)
4803 && !EQ (XCAR (spec
), Qwhen
)
4804 && !EQ (XCAR (spec
), Qslice
)
4805 && !EQ (XCAR (spec
), Qspace_width
)
4806 && !EQ (XCAR (spec
), Qheight
)
4807 && !EQ (XCAR (spec
), Qraise
)
4808 /* Marginal area specifications. */
4809 && !(CONSP (XCAR (spec
)) && EQ (XCAR (XCAR (spec
)), Qmargin
))
4810 && !EQ (XCAR (spec
), Qleft_fringe
)
4811 && !EQ (XCAR (spec
), Qright_fringe
)
4812 && !NILP (XCAR (spec
)))
4814 for (; CONSP (spec
); spec
= XCDR (spec
))
4816 int rv
= handle_single_display_spec (it
, XCAR (spec
), object
,
4817 overlay
, position
, bufpos
,
4818 replacing
, frame_window_p
,
4823 /* If some text in a string is replaced, `position' no
4824 longer points to the position of `object'. */
4825 if (!it
|| STRINGP (object
))
4830 else if (VECTORP (spec
))
4833 for (i
= 0; i
< ASIZE (spec
); ++i
)
4835 int rv
= handle_single_display_spec (it
, AREF (spec
, i
), object
,
4836 overlay
, position
, bufpos
,
4837 replacing
, frame_window_p
,
4842 /* If some text in a string is replaced, `position' no
4843 longer points to the position of `object'. */
4844 if (!it
|| STRINGP (object
))
4850 replacing
= handle_single_display_spec (it
, spec
, object
, overlay
, position
,
4851 bufpos
, 0, frame_window_p
,
4856 /* Value is the position of the end of the `display' property starting
4857 at START_POS in OBJECT. */
4859 static struct text_pos
4860 display_prop_end (struct it
*it
, Lisp_Object object
, struct text_pos start_pos
)
4863 struct text_pos end_pos
;
4865 end
= Fnext_single_char_property_change (make_number (CHARPOS (start_pos
)),
4866 Qdisplay
, object
, Qnil
);
4867 CHARPOS (end_pos
) = XFASTINT (end
);
4868 if (STRINGP (object
))
4869 compute_string_pos (&end_pos
, start_pos
, it
->string
);
4871 BYTEPOS (end_pos
) = CHAR_TO_BYTE (XFASTINT (end
));
4877 /* Set up IT from a single `display' property specification SPEC. OBJECT
4878 is the object in which the `display' property was found. *POSITION
4879 is the position in OBJECT at which the `display' property was found.
4880 BUFPOS is the buffer position of OBJECT (different from POSITION if
4881 OBJECT is not a buffer). DISPLAY_REPLACED non-zero means that we
4882 previously saw a display specification which already replaced text
4883 display with something else, for example an image; we ignore such
4884 properties after the first one has been processed.
4886 OVERLAY is the overlay this `display' property came from,
4887 or nil if it was a text property.
4889 If SPEC is a `space' or `image' specification, and in some other
4890 cases too, set *POSITION to the position where the `display'
4893 If IT is NULL, only examine the property specification in SPEC, but
4894 don't set up IT. In that case, FRAME_WINDOW_P means SPEC
4895 is intended to be displayed in a window on a GUI frame.
4897 Enable evaluation of Lisp forms only if ENABLE_EVAL_P is true.
4899 Value is non-zero if something was found which replaces the display
4900 of buffer or string text. */
4903 handle_single_display_spec (struct it
*it
, Lisp_Object spec
, Lisp_Object object
,
4904 Lisp_Object overlay
, struct text_pos
*position
,
4905 ptrdiff_t bufpos
, int display_replaced
,
4906 bool frame_window_p
, bool enable_eval_p
)
4909 Lisp_Object location
, value
;
4910 struct text_pos start_pos
= *position
;
4912 /* If SPEC is a list of the form `(when FORM . VALUE)', evaluate FORM.
4913 If the result is non-nil, use VALUE instead of SPEC. */
4915 if (CONSP (spec
) && EQ (XCAR (spec
), Qwhen
))
4924 if (!NILP (form
) && !EQ (form
, Qt
) && !enable_eval_p
)
4926 if (!NILP (form
) && !EQ (form
, Qt
))
4928 ptrdiff_t count
= SPECPDL_INDEX ();
4930 /* Bind `object' to the object having the `display' property, a
4931 buffer or string. Bind `position' to the position in the
4932 object where the property was found, and `buffer-position'
4933 to the current position in the buffer. */
4936 XSETBUFFER (object
, current_buffer
);
4937 specbind (Qobject
, object
);
4938 specbind (Qposition
, make_number (CHARPOS (*position
)));
4939 specbind (Qbuffer_position
, make_number (bufpos
));
4940 form
= safe_eval (form
);
4941 unbind_to (count
, Qnil
);
4947 /* Handle `(height HEIGHT)' specifications. */
4949 && EQ (XCAR (spec
), Qheight
)
4950 && CONSP (XCDR (spec
)))
4954 if (!FRAME_WINDOW_P (it
->f
))
4957 it
->font_height
= XCAR (XCDR (spec
));
4958 if (!NILP (it
->font_height
))
4960 int new_height
= -1;
4962 if (CONSP (it
->font_height
)
4963 && (EQ (XCAR (it
->font_height
), Qplus
)
4964 || EQ (XCAR (it
->font_height
), Qminus
))
4965 && CONSP (XCDR (it
->font_height
))
4966 && RANGED_INTEGERP (0, XCAR (XCDR (it
->font_height
)), INT_MAX
))
4968 /* `(+ N)' or `(- N)' where N is an integer. */
4969 int steps
= XINT (XCAR (XCDR (it
->font_height
)));
4970 if (EQ (XCAR (it
->font_height
), Qplus
))
4972 it
->face_id
= smaller_face (it
->f
, it
->face_id
, steps
);
4974 else if (FUNCTIONP (it
->font_height
) && enable_eval_p
)
4976 /* Call function with current height as argument.
4977 Value is the new height. */
4978 struct face
*face
= FACE_FROM_ID (it
->f
, it
->face_id
);
4980 height
= safe_call1 (it
->font_height
,
4981 face
->lface
[LFACE_HEIGHT_INDEX
]);
4982 if (NUMBERP (height
))
4983 new_height
= XFLOATINT (height
);
4985 else if (NUMBERP (it
->font_height
))
4987 /* Value is a multiple of the canonical char height. */
4990 f
= FACE_FROM_ID (it
->f
,
4991 lookup_basic_face (it
->w
, it
->f
, DEFAULT_FACE_ID
));
4992 new_height
= (XFLOATINT (it
->font_height
)
4993 * XINT (f
->lface
[LFACE_HEIGHT_INDEX
]));
4995 else if (enable_eval_p
)
4997 /* Evaluate IT->font_height with `height' bound to the
4998 current specified height to get the new height. */
4999 ptrdiff_t count
= SPECPDL_INDEX ();
5000 struct face
*face
= FACE_FROM_ID (it
->f
, it
->face_id
);
5002 specbind (Qheight
, face
->lface
[LFACE_HEIGHT_INDEX
]);
5003 value
= safe_eval (it
->font_height
);
5004 unbind_to (count
, Qnil
);
5006 if (NUMBERP (value
))
5007 new_height
= XFLOATINT (value
);
5011 it
->face_id
= face_with_height (it
->f
, it
->face_id
, new_height
);
5018 /* Handle `(space-width WIDTH)'. */
5020 && EQ (XCAR (spec
), Qspace_width
)
5021 && CONSP (XCDR (spec
)))
5025 if (!FRAME_WINDOW_P (it
->f
))
5028 value
= XCAR (XCDR (spec
));
5029 if (NUMBERP (value
) && XFLOATINT (value
) > 0)
5030 it
->space_width
= value
;
5036 /* Handle `(slice X Y WIDTH HEIGHT)'. */
5038 && EQ (XCAR (spec
), Qslice
))
5044 if (!FRAME_WINDOW_P (it
->f
))
5047 if (tem
= XCDR (spec
), CONSP (tem
))
5049 it
->slice
.x
= XCAR (tem
);
5050 if (tem
= XCDR (tem
), CONSP (tem
))
5052 it
->slice
.y
= XCAR (tem
);
5053 if (tem
= XCDR (tem
), CONSP (tem
))
5055 it
->slice
.width
= XCAR (tem
);
5056 if (tem
= XCDR (tem
), CONSP (tem
))
5057 it
->slice
.height
= XCAR (tem
);
5066 /* Handle `(raise FACTOR)'. */
5068 && EQ (XCAR (spec
), Qraise
)
5069 && CONSP (XCDR (spec
)))
5073 if (!FRAME_WINDOW_P (it
->f
))
5076 #ifdef HAVE_WINDOW_SYSTEM
5077 value
= XCAR (XCDR (spec
));
5078 if (NUMBERP (value
))
5080 struct face
*face
= FACE_FROM_ID (it
->f
, it
->face_id
);
5081 it
->voffset
= - (XFLOATINT (value
)
5082 * (normal_char_height (face
->font
, -1)));
5084 #endif /* HAVE_WINDOW_SYSTEM */
5090 /* Don't handle the other kinds of display specifications
5091 inside a string that we got from a `display' property. */
5092 if (it
&& it
->string_from_display_prop_p
)
5095 /* Characters having this form of property are not displayed, so
5096 we have to find the end of the property. */
5099 start_pos
= *position
;
5100 *position
= display_prop_end (it
, object
, start_pos
);
5101 /* If the display property comes from an overlay, don't consider
5102 any potential stop_charpos values before the end of that
5103 overlay. Since display_prop_end will happily find another
5104 'display' property coming from some other overlay or text
5105 property on buffer positions before this overlay's end, we
5106 need to ignore them, or else we risk displaying this
5107 overlay's display string/image twice. */
5108 if (!NILP (overlay
))
5110 ptrdiff_t ovendpos
= OVERLAY_POSITION (OVERLAY_END (overlay
));
5112 /* Some borderline-sane Lisp might call us with the current
5113 buffer narrowed so that overlay-end is outside the
5114 POINT_MIN..POINT_MAX region, which will then cause
5115 various assertion violations and crashes down the road,
5116 starting with pop_it when it will attempt to use POSITION
5117 set below. Prevent that. */
5118 ovendpos
= clip_to_bounds (BEGV
, ovendpos
, ZV
);
5120 if (ovendpos
> CHARPOS (*position
))
5121 SET_TEXT_POS (*position
, ovendpos
, CHAR_TO_BYTE (ovendpos
));
5126 /* Stop the scan at that end position--we assume that all
5127 text properties change there. */
5129 it
->stop_charpos
= position
->charpos
;
5131 /* Handle `(left-fringe BITMAP [FACE])'
5132 and `(right-fringe BITMAP [FACE])'. */
5134 && (EQ (XCAR (spec
), Qleft_fringe
)
5135 || EQ (XCAR (spec
), Qright_fringe
))
5136 && CONSP (XCDR (spec
)))
5140 if (!FRAME_WINDOW_P (it
->f
))
5141 /* If we return here, POSITION has been advanced
5142 across the text with this property. */
5144 /* Synchronize the bidi iterator with POSITION. This is
5145 needed because we are not going to push the iterator
5146 on behalf of this display property, so there will be
5147 no pop_it call to do this synchronization for us. */
5150 it
->position
= *position
;
5151 iterate_out_of_display_property (it
);
5152 *position
= it
->position
;
5157 else if (!frame_window_p
)
5160 #ifdef HAVE_WINDOW_SYSTEM
5161 value
= XCAR (XCDR (spec
));
5162 int fringe_bitmap
= SYMBOLP (value
) ? lookup_fringe_bitmap (value
) : 0;
5163 if (! fringe_bitmap
)
5164 /* If we return here, POSITION has been advanced
5165 across the text with this property. */
5167 if (it
&& it
->bidi_p
)
5169 it
->position
= *position
;
5170 iterate_out_of_display_property (it
);
5171 *position
= it
->position
;
5178 int face_id
= lookup_basic_face (it
->w
, it
->f
, DEFAULT_FACE_ID
);
5180 if (CONSP (XCDR (XCDR (spec
))))
5182 Lisp_Object face_name
= XCAR (XCDR (XCDR (spec
)));
5183 int face_id2
= lookup_derived_face (it
->w
, it
->f
, face_name
,
5184 FRINGE_FACE_ID
, false);
5189 /* Save current settings of IT so that we can restore them
5190 when we are finished with the glyph property value. */
5191 push_it (it
, position
);
5193 it
->area
= TEXT_AREA
;
5194 it
->what
= IT_IMAGE
;
5195 it
->image_id
= -1; /* no image */
5196 it
->position
= start_pos
;
5197 it
->object
= NILP (object
) ? it
->w
->contents
: object
;
5198 it
->method
= GET_FROM_IMAGE
;
5199 it
->from_overlay
= Qnil
;
5200 it
->face_id
= face_id
;
5201 it
->from_disp_prop_p
= true;
5203 /* Say that we haven't consumed the characters with
5204 `display' property yet. The call to pop_it in
5205 set_iterator_to_next will clean this up. */
5206 *position
= start_pos
;
5208 if (EQ (XCAR (spec
), Qleft_fringe
))
5210 it
->left_user_fringe_bitmap
= fringe_bitmap
;
5211 it
->left_user_fringe_face_id
= face_id
;
5215 it
->right_user_fringe_bitmap
= fringe_bitmap
;
5216 it
->right_user_fringe_face_id
= face_id
;
5219 #endif /* HAVE_WINDOW_SYSTEM */
5223 /* Prepare to handle `((margin left-margin) ...)',
5224 `((margin right-margin) ...)' and `((margin nil) ...)'
5225 prefixes for display specifications. */
5226 location
= Qunbound
;
5227 if (CONSP (spec
) && CONSP (XCAR (spec
)))
5231 value
= XCDR (spec
);
5233 value
= XCAR (value
);
5236 if (EQ (XCAR (tem
), Qmargin
)
5237 && (tem
= XCDR (tem
),
5238 tem
= CONSP (tem
) ? XCAR (tem
) : Qnil
,
5240 || EQ (tem
, Qleft_margin
)
5241 || EQ (tem
, Qright_margin
))))
5245 if (EQ (location
, Qunbound
))
5251 /* After this point, VALUE is the property after any
5252 margin prefix has been stripped. It must be a string,
5253 an image specification, or `(space ...)'.
5255 LOCATION specifies where to display: `left-margin',
5256 `right-margin' or nil. */
5258 bool valid_p
= (STRINGP (value
)
5259 #ifdef HAVE_WINDOW_SYSTEM
5260 || ((it
? FRAME_WINDOW_P (it
->f
) : frame_window_p
)
5261 && valid_image_p (value
))
5262 #endif /* not HAVE_WINDOW_SYSTEM */
5263 || (CONSP (value
) && EQ (XCAR (value
), Qspace
))
5264 || ((it
? FRAME_WINDOW_P (it
->f
) : frame_window_p
)
5265 && valid_xwidget_spec_p (value
)));
5267 if (valid_p
&& display_replaced
== 0)
5273 /* Callers need to know whether the display spec is any kind
5274 of `(space ...)' spec that is about to affect text-area
5276 if (CONSP (value
) && EQ (XCAR (value
), Qspace
) && NILP (location
))
5281 /* Save current settings of IT so that we can restore them
5282 when we are finished with the glyph property value. */
5283 push_it (it
, position
);
5284 it
->from_overlay
= overlay
;
5285 it
->from_disp_prop_p
= true;
5287 if (NILP (location
))
5288 it
->area
= TEXT_AREA
;
5289 else if (EQ (location
, Qleft_margin
))
5290 it
->area
= LEFT_MARGIN_AREA
;
5292 it
->area
= RIGHT_MARGIN_AREA
;
5294 if (STRINGP (value
))
5297 it
->multibyte_p
= STRING_MULTIBYTE (it
->string
);
5298 it
->current
.overlay_string_index
= -1;
5299 IT_STRING_CHARPOS (*it
) = IT_STRING_BYTEPOS (*it
) = 0;
5300 it
->end_charpos
= it
->string_nchars
= SCHARS (it
->string
);
5301 it
->method
= GET_FROM_STRING
;
5302 it
->stop_charpos
= 0;
5304 it
->base_level_stop
= 0;
5305 it
->string_from_display_prop_p
= true;
5307 /* Say that we haven't consumed the characters with
5308 `display' property yet. The call to pop_it in
5309 set_iterator_to_next will clean this up. */
5310 if (BUFFERP (object
))
5311 *position
= start_pos
;
5313 /* Force paragraph direction to be that of the parent
5314 object. If the parent object's paragraph direction is
5315 not yet determined, default to L2R. */
5316 if (it
->bidi_p
&& it
->bidi_it
.paragraph_dir
== R2L
)
5317 it
->paragraph_embedding
= it
->bidi_it
.paragraph_dir
;
5319 it
->paragraph_embedding
= L2R
;
5321 /* Set up the bidi iterator for this display string. */
5324 it
->bidi_it
.string
.lstring
= it
->string
;
5325 it
->bidi_it
.string
.s
= NULL
;
5326 it
->bidi_it
.string
.schars
= it
->end_charpos
;
5327 it
->bidi_it
.string
.bufpos
= bufpos
;
5328 it
->bidi_it
.string
.from_disp_str
= true;
5329 it
->bidi_it
.string
.unibyte
= !it
->multibyte_p
;
5330 it
->bidi_it
.w
= it
->w
;
5331 bidi_init_it (0, 0, FRAME_WINDOW_P (it
->f
), &it
->bidi_it
);
5334 else if (CONSP (value
) && EQ (XCAR (value
), Qspace
))
5336 it
->method
= GET_FROM_STRETCH
;
5338 *position
= it
->position
= start_pos
;
5339 retval
= 1 + (it
->area
== TEXT_AREA
);
5341 else if (valid_xwidget_spec_p (value
))
5343 it
->what
= IT_XWIDGET
;
5344 it
->method
= GET_FROM_XWIDGET
;
5345 it
->position
= start_pos
;
5346 it
->object
= NILP (object
) ? it
->w
->contents
: object
;
5347 *position
= start_pos
;
5348 it
->xwidget
= lookup_xwidget (value
);
5350 #ifdef HAVE_WINDOW_SYSTEM
5353 it
->what
= IT_IMAGE
;
5354 it
->image_id
= lookup_image (it
->f
, value
);
5355 it
->position
= start_pos
;
5356 it
->object
= NILP (object
) ? it
->w
->contents
: object
;
5357 it
->method
= GET_FROM_IMAGE
;
5359 /* Say that we haven't consumed the characters with
5360 `display' property yet. The call to pop_it in
5361 set_iterator_to_next will clean this up. */
5362 *position
= start_pos
;
5364 #endif /* HAVE_WINDOW_SYSTEM */
5369 /* Invalid property or property not supported. Restore
5370 POSITION to what it was before. */
5371 *position
= start_pos
;
5375 /* Check if PROP is a display property value whose text should be
5376 treated as intangible. OVERLAY is the overlay from which PROP
5377 came, or nil if it came from a text property. CHARPOS and BYTEPOS
5378 specify the buffer position covered by PROP. */
5381 display_prop_intangible_p (Lisp_Object prop
, Lisp_Object overlay
,
5382 ptrdiff_t charpos
, ptrdiff_t bytepos
)
5384 bool frame_window_p
= FRAME_WINDOW_P (XFRAME (selected_frame
));
5385 struct text_pos position
;
5387 SET_TEXT_POS (position
, charpos
, bytepos
);
5388 return (handle_display_spec (NULL
, prop
, Qnil
, overlay
,
5389 &position
, charpos
, frame_window_p
)
5394 /* Return true if PROP is a display sub-property value containing STRING.
5396 Implementation note: this and the following function are really
5397 special cases of handle_display_spec and
5398 handle_single_display_spec, and should ideally use the same code.
5399 Until they do, these two pairs must be consistent and must be
5400 modified in sync. */
5403 single_display_spec_string_p (Lisp_Object prop
, Lisp_Object string
)
5405 if (EQ (string
, prop
))
5408 /* Skip over `when FORM'. */
5409 if (CONSP (prop
) && EQ (XCAR (prop
), Qwhen
))
5414 /* Actually, the condition following `when' should be eval'ed,
5415 like handle_single_display_spec does, and we should return
5416 false if it evaluates to nil. However, this function is
5417 called only when the buffer was already displayed and some
5418 glyph in the glyph matrix was found to come from a display
5419 string. Therefore, the condition was already evaluated, and
5420 the result was non-nil, otherwise the display string wouldn't
5421 have been displayed and we would have never been called for
5422 this property. Thus, we can skip the evaluation and assume
5423 its result is non-nil. */
5428 /* Skip over `margin LOCATION'. */
5429 if (EQ (XCAR (prop
), Qmargin
))
5440 return EQ (prop
, string
) || (CONSP (prop
) && EQ (XCAR (prop
), string
));
5444 /* Return true if STRING appears in the `display' property PROP. */
5447 display_prop_string_p (Lisp_Object prop
, Lisp_Object string
)
5450 && !EQ (XCAR (prop
), Qwhen
)
5451 && !(CONSP (XCAR (prop
)) && EQ (Qmargin
, XCAR (XCAR (prop
)))))
5453 /* A list of sub-properties. */
5454 while (CONSP (prop
))
5456 if (single_display_spec_string_p (XCAR (prop
), string
))
5461 else if (VECTORP (prop
))
5463 /* A vector of sub-properties. */
5465 for (i
= 0; i
< ASIZE (prop
); ++i
)
5466 if (single_display_spec_string_p (AREF (prop
, i
), string
))
5470 return single_display_spec_string_p (prop
, string
);
5475 /* Look for STRING in overlays and text properties in the current
5476 buffer, between character positions FROM and TO (excluding TO).
5477 BACK_P means look back (in this case, TO is supposed to be
5479 Value is the first character position where STRING was found, or
5480 zero if it wasn't found before hitting TO.
5482 This function may only use code that doesn't eval because it is
5483 called asynchronously from note_mouse_highlight. */
5486 string_buffer_position_lim (Lisp_Object string
,
5487 ptrdiff_t from
, ptrdiff_t to
, bool back_p
)
5489 Lisp_Object limit
, prop
, pos
;
5492 pos
= make_number (max (from
, BEGV
));
5494 if (!back_p
) /* looking forward */
5496 limit
= make_number (min (to
, ZV
));
5497 while (!found
&& !EQ (pos
, limit
))
5499 prop
= Fget_char_property (pos
, Qdisplay
, Qnil
);
5500 if (!NILP (prop
) && display_prop_string_p (prop
, string
))
5503 pos
= Fnext_single_char_property_change (pos
, Qdisplay
, Qnil
,
5507 else /* looking back */
5509 limit
= make_number (max (to
, BEGV
));
5510 while (!found
&& !EQ (pos
, limit
))
5512 prop
= Fget_char_property (pos
, Qdisplay
, Qnil
);
5513 if (!NILP (prop
) && display_prop_string_p (prop
, string
))
5516 pos
= Fprevious_single_char_property_change (pos
, Qdisplay
, Qnil
,
5521 return found
? XINT (pos
) : 0;
5524 /* Determine which buffer position in current buffer STRING comes from.
5525 AROUND_CHARPOS is an approximate position where it could come from.
5526 Value is the buffer position or 0 if it couldn't be determined.
5528 This function is necessary because we don't record buffer positions
5529 in glyphs generated from strings (to keep struct glyph small).
5530 This function may only use code that doesn't eval because it is
5531 called asynchronously from note_mouse_highlight. */
5534 string_buffer_position (Lisp_Object string
, ptrdiff_t around_charpos
)
5536 const int MAX_DISTANCE
= 1000;
5537 ptrdiff_t found
= string_buffer_position_lim (string
, around_charpos
,
5538 around_charpos
+ MAX_DISTANCE
,
5542 found
= string_buffer_position_lim (string
, around_charpos
,
5543 around_charpos
- MAX_DISTANCE
, true);
5549 /***********************************************************************
5550 `composition' property
5551 ***********************************************************************/
5553 /* Set up iterator IT from `composition' property at its current
5554 position. Called from handle_stop. */
5556 static enum prop_handled
5557 handle_composition_prop (struct it
*it
)
5559 Lisp_Object prop
, string
;
5560 ptrdiff_t pos
, pos_byte
, start
, end
;
5562 if (STRINGP (it
->string
))
5566 pos
= IT_STRING_CHARPOS (*it
);
5567 pos_byte
= IT_STRING_BYTEPOS (*it
);
5568 string
= it
->string
;
5569 s
= SDATA (string
) + pos_byte
;
5570 it
->c
= STRING_CHAR (s
);
5574 pos
= IT_CHARPOS (*it
);
5575 pos_byte
= IT_BYTEPOS (*it
);
5577 it
->c
= FETCH_CHAR (pos_byte
);
5580 /* If there's a valid composition and point is not inside of the
5581 composition (in the case that the composition is from the current
5582 buffer), draw a glyph composed from the composition components. */
5583 if (find_composition (pos
, -1, &start
, &end
, &prop
, string
)
5584 && composition_valid_p (start
, end
, prop
)
5585 && (STRINGP (it
->string
) || (PT
<= start
|| PT
>= end
)))
5588 /* As we can't handle this situation (perhaps font-lock added
5589 a new composition), we just return here hoping that next
5590 redisplay will detect this composition much earlier. */
5591 return HANDLED_NORMALLY
;
5594 if (STRINGP (it
->string
))
5595 pos_byte
= string_char_to_byte (it
->string
, start
);
5597 pos_byte
= CHAR_TO_BYTE (start
);
5599 it
->cmp_it
.id
= get_composition_id (start
, pos_byte
, end
- start
,
5602 if (it
->cmp_it
.id
>= 0)
5605 it
->cmp_it
.nchars
= COMPOSITION_LENGTH (prop
);
5606 it
->cmp_it
.nglyphs
= -1;
5610 return HANDLED_NORMALLY
;
5615 /***********************************************************************
5617 ***********************************************************************/
5619 /* The following structure is used to record overlay strings for
5620 later sorting in load_overlay_strings. */
5622 struct overlay_entry
5624 Lisp_Object overlay
;
5627 bool after_string_p
;
5631 /* Set up iterator IT from overlay strings at its current position.
5632 Called from handle_stop. */
5634 static enum prop_handled
5635 handle_overlay_change (struct it
*it
)
5637 if (!STRINGP (it
->string
) && get_overlay_strings (it
, 0))
5638 return HANDLED_RECOMPUTE_PROPS
;
5640 return HANDLED_NORMALLY
;
5644 /* Set up the next overlay string for delivery by IT, if there is an
5645 overlay string to deliver. Called by set_iterator_to_next when the
5646 end of the current overlay string is reached. If there are more
5647 overlay strings to display, IT->string and
5648 IT->current.overlay_string_index are set appropriately here.
5649 Otherwise IT->string is set to nil. */
5652 next_overlay_string (struct it
*it
)
5654 ++it
->current
.overlay_string_index
;
5655 if (it
->current
.overlay_string_index
== it
->n_overlay_strings
)
5657 /* No more overlay strings. Restore IT's settings to what
5658 they were before overlay strings were processed, and
5659 continue to deliver from current_buffer. */
5661 it
->ellipsis_p
= it
->stack
[it
->sp
- 1].display_ellipsis_p
;
5664 || (NILP (it
->string
)
5665 && it
->method
== GET_FROM_BUFFER
5666 && it
->stop_charpos
>= BEGV
5667 && it
->stop_charpos
<= it
->end_charpos
));
5668 it
->current
.overlay_string_index
= -1;
5669 it
->n_overlay_strings
= 0;
5670 /* If there's an empty display string on the stack, pop the
5671 stack, to resync the bidi iterator with IT's position. Such
5672 empty strings are pushed onto the stack in
5673 get_overlay_strings_1. */
5674 if (it
->sp
> 0 && STRINGP (it
->string
) && !SCHARS (it
->string
))
5677 /* Since we've exhausted overlay strings at this buffer
5678 position, set the flag to ignore overlays until we move to
5679 another position. (The flag will be reset in
5680 next_element_from_buffer.) But don't do that if the overlay
5681 strings were loaded at position other than the current one,
5682 which could happen if we called pop_it above, or if the
5683 overlay strings were loaded by handle_invisible_prop at the
5684 beginning of invisible text. */
5685 if (it
->overlay_strings_charpos
== IT_CHARPOS (*it
))
5686 it
->ignore_overlay_strings_at_pos_p
= true;
5688 /* If we're at the end of the buffer, record that we have
5689 processed the overlay strings there already, so that
5690 next_element_from_buffer doesn't try it again. */
5691 if (NILP (it
->string
)
5692 && IT_CHARPOS (*it
) >= it
->end_charpos
5693 && it
->overlay_strings_charpos
>= it
->end_charpos
)
5694 it
->overlay_strings_at_end_processed_p
= true;
5695 /* Note: we reset overlay_strings_charpos only here, to make
5696 sure the just-processed overlays were indeed at EOB.
5697 Otherwise, overlays on text with invisible text property,
5698 which are processed with IT's position past the invisible
5699 text, might fool us into thinking the overlays at EOB were
5700 already processed (linum-mode can cause this, for
5702 it
->overlay_strings_charpos
= -1;
5706 /* There are more overlay strings to process. If
5707 IT->current.overlay_string_index has advanced to a position
5708 where we must load IT->overlay_strings with more strings, do
5709 it. We must load at the IT->overlay_strings_charpos where
5710 IT->n_overlay_strings was originally computed; when invisible
5711 text is present, this might not be IT_CHARPOS (Bug#7016). */
5712 int i
= it
->current
.overlay_string_index
% OVERLAY_STRING_CHUNK_SIZE
;
5714 if (it
->current
.overlay_string_index
&& i
== 0)
5715 load_overlay_strings (it
, it
->overlay_strings_charpos
);
5717 /* Initialize IT to deliver display elements from the overlay
5719 it
->string
= it
->overlay_strings
[i
];
5720 it
->multibyte_p
= STRING_MULTIBYTE (it
->string
);
5721 SET_TEXT_POS (it
->current
.string_pos
, 0, 0);
5722 it
->method
= GET_FROM_STRING
;
5723 it
->stop_charpos
= 0;
5724 it
->end_charpos
= SCHARS (it
->string
);
5725 if (it
->cmp_it
.stop_pos
>= 0)
5726 it
->cmp_it
.stop_pos
= 0;
5728 it
->base_level_stop
= 0;
5730 /* Set up the bidi iterator for this overlay string. */
5733 it
->bidi_it
.string
.lstring
= it
->string
;
5734 it
->bidi_it
.string
.s
= NULL
;
5735 it
->bidi_it
.string
.schars
= SCHARS (it
->string
);
5736 it
->bidi_it
.string
.bufpos
= it
->overlay_strings_charpos
;
5737 it
->bidi_it
.string
.from_disp_str
= it
->string_from_display_prop_p
;
5738 it
->bidi_it
.string
.unibyte
= !it
->multibyte_p
;
5739 it
->bidi_it
.w
= it
->w
;
5740 bidi_init_it (0, 0, FRAME_WINDOW_P (it
->f
), &it
->bidi_it
);
5748 /* Compare two overlay_entry structures E1 and E2. Used as a
5749 comparison function for qsort in load_overlay_strings. Overlay
5750 strings for the same position are sorted so that
5752 1. All after-strings come in front of before-strings, except
5753 when they come from the same overlay.
5755 2. Within after-strings, strings are sorted so that overlay strings
5756 from overlays with higher priorities come first.
5758 2. Within before-strings, strings are sorted so that overlay
5759 strings from overlays with higher priorities come last.
5761 Value is analogous to strcmp. */
5765 compare_overlay_entries (const void *e1
, const void *e2
)
5767 struct overlay_entry
const *entry1
= e1
;
5768 struct overlay_entry
const *entry2
= e2
;
5771 if (entry1
->after_string_p
!= entry2
->after_string_p
)
5773 /* Let after-strings appear in front of before-strings if
5774 they come from different overlays. */
5775 if (EQ (entry1
->overlay
, entry2
->overlay
))
5776 result
= entry1
->after_string_p
? 1 : -1;
5778 result
= entry1
->after_string_p
? -1 : 1;
5780 else if (entry1
->priority
!= entry2
->priority
)
5782 if (entry1
->after_string_p
)
5783 /* After-strings sorted in order of decreasing priority. */
5784 result
= entry2
->priority
< entry1
->priority
? -1 : 1;
5786 /* Before-strings sorted in order of increasing priority. */
5787 result
= entry1
->priority
< entry2
->priority
? -1 : 1;
5796 /* Load the vector IT->overlay_strings with overlay strings from IT's
5797 current buffer position, or from CHARPOS if that is > 0. Set
5798 IT->n_overlays to the total number of overlay strings found.
5800 Overlay strings are processed OVERLAY_STRING_CHUNK_SIZE strings at
5801 a time. On entry into load_overlay_strings,
5802 IT->current.overlay_string_index gives the number of overlay
5803 strings that have already been loaded by previous calls to this
5806 IT->add_overlay_start contains an additional overlay start
5807 position to consider for taking overlay strings from, if non-zero.
5808 This position comes into play when the overlay has an `invisible'
5809 property, and both before and after-strings. When we've skipped to
5810 the end of the overlay, because of its `invisible' property, we
5811 nevertheless want its before-string to appear.
5812 IT->add_overlay_start will contain the overlay start position
5815 Overlay strings are sorted so that after-string strings come in
5816 front of before-string strings. Within before and after-strings,
5817 strings are sorted by overlay priority. See also function
5818 compare_overlay_entries. */
5821 load_overlay_strings (struct it
*it
, ptrdiff_t charpos
)
5823 Lisp_Object overlay
, window
, str
, invisible
;
5824 struct Lisp_Overlay
*ov
;
5825 ptrdiff_t start
, end
;
5826 ptrdiff_t n
= 0, i
, j
;
5828 struct overlay_entry entriesbuf
[20];
5829 ptrdiff_t size
= ARRAYELTS (entriesbuf
);
5830 struct overlay_entry
*entries
= entriesbuf
;
5834 charpos
= IT_CHARPOS (*it
);
5836 /* Append the overlay string STRING of overlay OVERLAY to vector
5837 `entries' which has size `size' and currently contains `n'
5838 elements. AFTER_P means STRING is an after-string of
5840 #define RECORD_OVERLAY_STRING(OVERLAY, STRING, AFTER_P) \
5843 Lisp_Object priority; \
5847 struct overlay_entry *old = entries; \
5848 SAFE_NALLOCA (entries, 2, size); \
5849 memcpy (entries, old, size * sizeof *entries); \
5853 entries[n].string = (STRING); \
5854 entries[n].overlay = (OVERLAY); \
5855 priority = Foverlay_get ((OVERLAY), Qpriority); \
5856 entries[n].priority = INTEGERP (priority) ? XINT (priority) : 0; \
5857 entries[n].after_string_p = (AFTER_P); \
5862 /* Process overlay before the overlay center. */
5863 for (ov
= current_buffer
->overlays_before
; ov
; ov
= ov
->next
)
5865 XSETMISC (overlay
, ov
);
5866 eassert (OVERLAYP (overlay
));
5867 start
= OVERLAY_POSITION (OVERLAY_START (overlay
));
5868 end
= OVERLAY_POSITION (OVERLAY_END (overlay
));
5873 /* Skip this overlay if it doesn't start or end at IT's current
5875 if (end
!= charpos
&& start
!= charpos
)
5878 /* Skip this overlay if it doesn't apply to IT->w. */
5879 window
= Foverlay_get (overlay
, Qwindow
);
5880 if (WINDOWP (window
) && XWINDOW (window
) != it
->w
)
5883 /* If the text ``under'' the overlay is invisible, both before-
5884 and after-strings from this overlay are visible; start and
5885 end position are indistinguishable. */
5886 invisible
= Foverlay_get (overlay
, Qinvisible
);
5887 invis
= TEXT_PROP_MEANS_INVISIBLE (invisible
);
5889 /* If overlay has a non-empty before-string, record it. */
5890 if ((start
== charpos
|| (end
== charpos
&& invis
!= 0))
5891 && (str
= Foverlay_get (overlay
, Qbefore_string
), STRINGP (str
))
5893 RECORD_OVERLAY_STRING (overlay
, str
, false);
5895 /* If overlay has a non-empty after-string, record it. */
5896 if ((end
== charpos
|| (start
== charpos
&& invis
!= 0))
5897 && (str
= Foverlay_get (overlay
, Qafter_string
), STRINGP (str
))
5899 RECORD_OVERLAY_STRING (overlay
, str
, true);
5902 /* Process overlays after the overlay center. */
5903 for (ov
= current_buffer
->overlays_after
; ov
; ov
= ov
->next
)
5905 XSETMISC (overlay
, ov
);
5906 eassert (OVERLAYP (overlay
));
5907 start
= OVERLAY_POSITION (OVERLAY_START (overlay
));
5908 end
= OVERLAY_POSITION (OVERLAY_END (overlay
));
5910 if (start
> charpos
)
5913 /* Skip this overlay if it doesn't start or end at IT's current
5915 if (end
!= charpos
&& start
!= charpos
)
5918 /* Skip this overlay if it doesn't apply to IT->w. */
5919 window
= Foverlay_get (overlay
, Qwindow
);
5920 if (WINDOWP (window
) && XWINDOW (window
) != it
->w
)
5923 /* If the text ``under'' the overlay is invisible, it has a zero
5924 dimension, and both before- and after-strings apply. */
5925 invisible
= Foverlay_get (overlay
, Qinvisible
);
5926 invis
= TEXT_PROP_MEANS_INVISIBLE (invisible
);
5928 /* If overlay has a non-empty before-string, record it. */
5929 if ((start
== charpos
|| (end
== charpos
&& invis
!= 0))
5930 && (str
= Foverlay_get (overlay
, Qbefore_string
), STRINGP (str
))
5932 RECORD_OVERLAY_STRING (overlay
, str
, false);
5934 /* If overlay has a non-empty after-string, record it. */
5935 if ((end
== charpos
|| (start
== charpos
&& invis
!= 0))
5936 && (str
= Foverlay_get (overlay
, Qafter_string
), STRINGP (str
))
5938 RECORD_OVERLAY_STRING (overlay
, str
, true);
5941 #undef RECORD_OVERLAY_STRING
5945 qsort (entries
, n
, sizeof *entries
, compare_overlay_entries
);
5947 /* Record number of overlay strings, and where we computed it. */
5948 it
->n_overlay_strings
= n
;
5949 it
->overlay_strings_charpos
= charpos
;
5951 /* IT->current.overlay_string_index is the number of overlay strings
5952 that have already been consumed by IT. Copy some of the
5953 remaining overlay strings to IT->overlay_strings. */
5955 j
= it
->current
.overlay_string_index
;
5956 while (i
< OVERLAY_STRING_CHUNK_SIZE
&& j
< n
)
5958 it
->overlay_strings
[i
] = entries
[j
].string
;
5959 it
->string_overlays
[i
++] = entries
[j
++].overlay
;
5967 /* Get the first chunk of overlay strings at IT's current buffer
5968 position, or at CHARPOS if that is > 0. Value is true if at
5969 least one overlay string was found. */
5972 get_overlay_strings_1 (struct it
*it
, ptrdiff_t charpos
, bool compute_stop_p
)
5974 /* Get the first OVERLAY_STRING_CHUNK_SIZE overlay strings to
5975 process. This fills IT->overlay_strings with strings, and sets
5976 IT->n_overlay_strings to the total number of strings to process.
5977 IT->pos.overlay_string_index has to be set temporarily to zero
5978 because load_overlay_strings needs this; it must be set to -1
5979 when no overlay strings are found because a zero value would
5980 indicate a position in the first overlay string. */
5981 it
->current
.overlay_string_index
= 0;
5982 load_overlay_strings (it
, charpos
);
5984 /* If we found overlay strings, set up IT to deliver display
5985 elements from the first one. Otherwise set up IT to deliver
5986 from current_buffer. */
5987 if (it
->n_overlay_strings
)
5989 /* Make sure we know settings in current_buffer, so that we can
5990 restore meaningful values when we're done with the overlay
5993 compute_stop_pos (it
);
5994 eassert (it
->face_id
>= 0);
5996 /* Save IT's settings. They are restored after all overlay
5997 strings have been processed. */
5998 eassert (!compute_stop_p
|| it
->sp
== 0);
6000 /* When called from handle_stop, there might be an empty display
6001 string loaded. In that case, don't bother saving it. But
6002 don't use this optimization with the bidi iterator, since we
6003 need the corresponding pop_it call to resync the bidi
6004 iterator's position with IT's position, after we are done
6005 with the overlay strings. (The corresponding call to pop_it
6006 in case of an empty display string is in
6007 next_overlay_string.) */
6009 && STRINGP (it
->string
) && !SCHARS (it
->string
)))
6012 /* Set up IT to deliver display elements from the first overlay
6014 IT_STRING_CHARPOS (*it
) = IT_STRING_BYTEPOS (*it
) = 0;
6015 it
->string
= it
->overlay_strings
[0];
6016 it
->from_overlay
= Qnil
;
6017 it
->stop_charpos
= 0;
6018 eassert (STRINGP (it
->string
));
6019 it
->end_charpos
= SCHARS (it
->string
);
6021 it
->base_level_stop
= 0;
6022 it
->multibyte_p
= STRING_MULTIBYTE (it
->string
);
6023 it
->method
= GET_FROM_STRING
;
6024 it
->from_disp_prop_p
= 0;
6027 /* Force paragraph direction to be that of the parent
6029 if (it
->bidi_p
&& it
->bidi_it
.paragraph_dir
== R2L
)
6030 it
->paragraph_embedding
= it
->bidi_it
.paragraph_dir
;
6032 it
->paragraph_embedding
= L2R
;
6034 /* Set up the bidi iterator for this overlay string. */
6037 ptrdiff_t pos
= (charpos
> 0 ? charpos
: IT_CHARPOS (*it
));
6039 it
->bidi_it
.string
.lstring
= it
->string
;
6040 it
->bidi_it
.string
.s
= NULL
;
6041 it
->bidi_it
.string
.schars
= SCHARS (it
->string
);
6042 it
->bidi_it
.string
.bufpos
= pos
;
6043 it
->bidi_it
.string
.from_disp_str
= it
->string_from_display_prop_p
;
6044 it
->bidi_it
.string
.unibyte
= !it
->multibyte_p
;
6045 it
->bidi_it
.w
= it
->w
;
6046 bidi_init_it (0, 0, FRAME_WINDOW_P (it
->f
), &it
->bidi_it
);
6051 it
->current
.overlay_string_index
= -1;
6056 get_overlay_strings (struct it
*it
, ptrdiff_t charpos
)
6059 it
->method
= GET_FROM_BUFFER
;
6061 get_overlay_strings_1 (it
, charpos
, true);
6065 /* Value is true if we found at least one overlay string. */
6066 return STRINGP (it
->string
);
6071 /***********************************************************************
6072 Saving and restoring state
6073 ***********************************************************************/
6075 /* Save current settings of IT on IT->stack. Called, for example,
6076 before setting up IT for an overlay string, to be able to restore
6077 IT's settings to what they were after the overlay string has been
6078 processed. If POSITION is non-NULL, it is the position to save on
6079 the stack instead of IT->position. */
6082 push_it (struct it
*it
, struct text_pos
*position
)
6084 struct iterator_stack_entry
*p
;
6086 eassert (it
->sp
< IT_STACK_SIZE
);
6087 p
= it
->stack
+ it
->sp
;
6089 p
->stop_charpos
= it
->stop_charpos
;
6090 p
->prev_stop
= it
->prev_stop
;
6091 p
->base_level_stop
= it
->base_level_stop
;
6092 p
->cmp_it
= it
->cmp_it
;
6093 eassert (it
->face_id
>= 0);
6094 p
->face_id
= it
->face_id
;
6095 p
->string
= it
->string
;
6096 p
->method
= it
->method
;
6097 p
->from_overlay
= it
->from_overlay
;
6100 case GET_FROM_IMAGE
:
6101 p
->u
.image
.object
= it
->object
;
6102 p
->u
.image
.image_id
= it
->image_id
;
6103 p
->u
.image
.slice
= it
->slice
;
6105 case GET_FROM_STRETCH
:
6106 p
->u
.stretch
.object
= it
->object
;
6108 case GET_FROM_XWIDGET
:
6109 p
->u
.xwidget
.object
= it
->object
;
6111 case GET_FROM_BUFFER
:
6112 case GET_FROM_DISPLAY_VECTOR
:
6113 case GET_FROM_STRING
:
6114 case GET_FROM_C_STRING
:
6119 p
->position
= position
? *position
: it
->position
;
6120 p
->current
= it
->current
;
6121 p
->end_charpos
= it
->end_charpos
;
6122 p
->string_nchars
= it
->string_nchars
;
6124 p
->multibyte_p
= it
->multibyte_p
;
6125 p
->avoid_cursor_p
= it
->avoid_cursor_p
;
6126 p
->space_width
= it
->space_width
;
6127 p
->font_height
= it
->font_height
;
6128 p
->voffset
= it
->voffset
;
6129 p
->string_from_display_prop_p
= it
->string_from_display_prop_p
;
6130 p
->string_from_prefix_prop_p
= it
->string_from_prefix_prop_p
;
6131 p
->display_ellipsis_p
= false;
6132 p
->line_wrap
= it
->line_wrap
;
6133 p
->bidi_p
= it
->bidi_p
;
6134 p
->paragraph_embedding
= it
->paragraph_embedding
;
6135 p
->from_disp_prop_p
= it
->from_disp_prop_p
;
6138 /* Save the state of the bidi iterator as well. */
6140 bidi_push_it (&it
->bidi_it
);
6144 iterate_out_of_display_property (struct it
*it
)
6146 bool buffer_p
= !STRINGP (it
->string
);
6147 ptrdiff_t eob
= (buffer_p
? ZV
: it
->end_charpos
);
6148 ptrdiff_t bob
= (buffer_p
? BEGV
: 0);
6150 eassert (eob
>= CHARPOS (it
->position
) && CHARPOS (it
->position
) >= bob
);
6152 /* Maybe initialize paragraph direction. If we are at the beginning
6153 of a new paragraph, next_element_from_buffer may not have a
6154 chance to do that. */
6155 if (it
->bidi_it
.first_elt
&& it
->bidi_it
.charpos
< eob
)
6156 bidi_paragraph_init (it
->paragraph_embedding
, &it
->bidi_it
, true);
6157 /* prev_stop can be zero, so check against BEGV as well. */
6158 while (it
->bidi_it
.charpos
>= bob
6159 && it
->prev_stop
<= it
->bidi_it
.charpos
6160 && it
->bidi_it
.charpos
< CHARPOS (it
->position
)
6161 && it
->bidi_it
.charpos
< eob
)
6162 bidi_move_to_visually_next (&it
->bidi_it
);
6163 /* Record the stop_pos we just crossed, for when we cross it
6165 if (it
->bidi_it
.charpos
> CHARPOS (it
->position
))
6166 it
->prev_stop
= CHARPOS (it
->position
);
6167 /* If we ended up not where pop_it put us, resync IT's
6168 positional members with the bidi iterator. */
6169 if (it
->bidi_it
.charpos
!= CHARPOS (it
->position
))
6170 SET_TEXT_POS (it
->position
, it
->bidi_it
.charpos
, it
->bidi_it
.bytepos
);
6172 it
->current
.pos
= it
->position
;
6174 it
->current
.string_pos
= it
->position
;
6177 /* Restore IT's settings from IT->stack. Called, for example, when no
6178 more overlay strings must be processed, and we return to delivering
6179 display elements from a buffer, or when the end of a string from a
6180 `display' property is reached and we return to delivering display
6181 elements from an overlay string, or from a buffer. */
6184 pop_it (struct it
*it
)
6186 struct iterator_stack_entry
*p
;
6187 bool from_display_prop
= it
->from_disp_prop_p
;
6188 ptrdiff_t prev_pos
= IT_CHARPOS (*it
);
6190 eassert (it
->sp
> 0);
6192 p
= it
->stack
+ it
->sp
;
6193 it
->stop_charpos
= p
->stop_charpos
;
6194 it
->prev_stop
= p
->prev_stop
;
6195 it
->base_level_stop
= p
->base_level_stop
;
6196 it
->cmp_it
= p
->cmp_it
;
6197 it
->face_id
= p
->face_id
;
6198 it
->current
= p
->current
;
6199 it
->position
= p
->position
;
6200 it
->string
= p
->string
;
6201 it
->from_overlay
= p
->from_overlay
;
6202 if (NILP (it
->string
))
6203 SET_TEXT_POS (it
->current
.string_pos
, -1, -1);
6204 it
->method
= p
->method
;
6207 case GET_FROM_IMAGE
:
6208 it
->image_id
= p
->u
.image
.image_id
;
6209 it
->object
= p
->u
.image
.object
;
6210 it
->slice
= p
->u
.image
.slice
;
6212 case GET_FROM_XWIDGET
:
6213 it
->object
= p
->u
.xwidget
.object
;
6215 case GET_FROM_STRETCH
:
6216 it
->object
= p
->u
.stretch
.object
;
6218 case GET_FROM_BUFFER
:
6219 it
->object
= it
->w
->contents
;
6221 case GET_FROM_STRING
:
6223 struct face
*face
= FACE_FROM_ID_OR_NULL (it
->f
, it
->face_id
);
6225 /* Restore the face_box_p flag, since it could have been
6226 overwritten by the face of the object that we just finished
6229 it
->face_box_p
= face
->box
!= FACE_NO_BOX
;
6230 it
->object
= it
->string
;
6233 case GET_FROM_DISPLAY_VECTOR
:
6235 it
->method
= GET_FROM_C_STRING
;
6236 else if (STRINGP (it
->string
))
6237 it
->method
= GET_FROM_STRING
;
6240 it
->method
= GET_FROM_BUFFER
;
6241 it
->object
= it
->w
->contents
;
6244 case GET_FROM_C_STRING
:
6249 it
->end_charpos
= p
->end_charpos
;
6250 it
->string_nchars
= p
->string_nchars
;
6252 it
->multibyte_p
= p
->multibyte_p
;
6253 it
->avoid_cursor_p
= p
->avoid_cursor_p
;
6254 it
->space_width
= p
->space_width
;
6255 it
->font_height
= p
->font_height
;
6256 it
->voffset
= p
->voffset
;
6257 it
->string_from_display_prop_p
= p
->string_from_display_prop_p
;
6258 it
->string_from_prefix_prop_p
= p
->string_from_prefix_prop_p
;
6259 it
->line_wrap
= p
->line_wrap
;
6260 it
->bidi_p
= p
->bidi_p
;
6261 it
->paragraph_embedding
= p
->paragraph_embedding
;
6262 it
->from_disp_prop_p
= p
->from_disp_prop_p
;
6265 bidi_pop_it (&it
->bidi_it
);
6266 /* Bidi-iterate until we get out of the portion of text, if any,
6267 covered by a `display' text property or by an overlay with
6268 `display' property. (We cannot just jump there, because the
6269 internal coherency of the bidi iterator state can not be
6270 preserved across such jumps.) We also must determine the
6271 paragraph base direction if the overlay we just processed is
6272 at the beginning of a new paragraph. */
6273 if (from_display_prop
6274 && (it
->method
== GET_FROM_BUFFER
|| it
->method
== GET_FROM_STRING
))
6275 iterate_out_of_display_property (it
);
6277 eassert ((BUFFERP (it
->object
)
6278 && IT_CHARPOS (*it
) == it
->bidi_it
.charpos
6279 && IT_BYTEPOS (*it
) == it
->bidi_it
.bytepos
)
6280 || (STRINGP (it
->object
)
6281 && IT_STRING_CHARPOS (*it
) == it
->bidi_it
.charpos
6282 && IT_STRING_BYTEPOS (*it
) == it
->bidi_it
.bytepos
)
6283 || (CONSP (it
->object
) && it
->method
== GET_FROM_STRETCH
));
6285 /* If we move the iterator over text covered by a display property
6286 to a new buffer position, any info about previously seen overlays
6287 is no longer valid. */
6288 if (from_display_prop
&& it
->sp
== 0 && CHARPOS (it
->position
) != prev_pos
)
6289 it
->ignore_overlay_strings_at_pos_p
= false;
6294 /***********************************************************************
6296 ***********************************************************************/
6298 /* Set IT's current position to the previous line start. */
6301 back_to_previous_line_start (struct it
*it
)
6303 ptrdiff_t cp
= IT_CHARPOS (*it
), bp
= IT_BYTEPOS (*it
);
6306 IT_CHARPOS (*it
) = find_newline_no_quit (cp
, bp
, -1, &IT_BYTEPOS (*it
));
6310 /* Move IT to the next line start.
6312 Value is true if a newline was found. Set *SKIPPED_P to true if
6313 we skipped over part of the text (as opposed to moving the iterator
6314 continuously over the text). Otherwise, don't change the value
6317 If BIDI_IT_PREV is non-NULL, store into it the state of the bidi
6318 iterator on the newline, if it was found.
6320 Newlines may come from buffer text, overlay strings, or strings
6321 displayed via the `display' property. That's the reason we can't
6322 simply use find_newline_no_quit.
6324 Note that this function may not skip over invisible text that is so
6325 because of text properties and immediately follows a newline. If
6326 it would, function reseat_at_next_visible_line_start, when called
6327 from set_iterator_to_next, would effectively make invisible
6328 characters following a newline part of the wrong glyph row, which
6329 leads to wrong cursor motion. */
6332 forward_to_next_line_start (struct it
*it
, bool *skipped_p
,
6333 struct bidi_it
*bidi_it_prev
)
6335 ptrdiff_t old_selective
;
6336 bool newline_found_p
= false;
6338 const int MAX_NEWLINE_DISTANCE
= 500;
6340 /* If already on a newline, just consume it to avoid unintended
6341 skipping over invisible text below. */
6342 if (it
->what
== IT_CHARACTER
6344 && CHARPOS (it
->position
) == IT_CHARPOS (*it
))
6346 if (it
->bidi_p
&& bidi_it_prev
)
6347 *bidi_it_prev
= it
->bidi_it
;
6348 set_iterator_to_next (it
, false);
6353 /* Don't handle selective display in the following. It's (a)
6354 unnecessary because it's done by the caller, and (b) leads to an
6355 infinite recursion because next_element_from_ellipsis indirectly
6356 calls this function. */
6357 old_selective
= it
->selective
;
6360 /* Scan for a newline within MAX_NEWLINE_DISTANCE display elements
6361 from buffer text. */
6363 !newline_found_p
&& n
< MAX_NEWLINE_DISTANCE
;
6364 n
+= !STRINGP (it
->string
))
6366 if (!get_next_display_element (it
))
6368 newline_found_p
= it
->what
== IT_CHARACTER
&& it
->c
== '\n';
6369 if (newline_found_p
&& it
->bidi_p
&& bidi_it_prev
)
6370 *bidi_it_prev
= it
->bidi_it
;
6371 set_iterator_to_next (it
, false);
6374 /* If we didn't find a newline near enough, see if we can use a
6376 if (!newline_found_p
)
6378 ptrdiff_t bytepos
, start
= IT_CHARPOS (*it
);
6379 ptrdiff_t limit
= find_newline_no_quit (start
, IT_BYTEPOS (*it
),
6383 eassert (!STRINGP (it
->string
));
6385 /* If there isn't any `display' property in sight, and no
6386 overlays, we can just use the position of the newline in
6388 if (it
->stop_charpos
>= limit
6389 || ((pos
= Fnext_single_property_change (make_number (start
),
6391 make_number (limit
)),
6393 && next_overlay_change (start
) == ZV
))
6397 IT_CHARPOS (*it
) = limit
;
6398 IT_BYTEPOS (*it
) = bytepos
;
6402 struct bidi_it bprev
;
6404 /* Help bidi.c avoid expensive searches for display
6405 properties and overlays, by telling it that there are
6406 none up to `limit'. */
6407 if (it
->bidi_it
.disp_pos
< limit
)
6409 it
->bidi_it
.disp_pos
= limit
;
6410 it
->bidi_it
.disp_prop
= 0;
6413 bprev
= it
->bidi_it
;
6414 bidi_move_to_visually_next (&it
->bidi_it
);
6415 } while (it
->bidi_it
.charpos
!= limit
);
6416 IT_CHARPOS (*it
) = limit
;
6417 IT_BYTEPOS (*it
) = it
->bidi_it
.bytepos
;
6419 *bidi_it_prev
= bprev
;
6421 *skipped_p
= newline_found_p
= true;
6425 while (!newline_found_p
)
6427 if (!get_next_display_element (it
))
6429 newline_found_p
= ITERATOR_AT_END_OF_LINE_P (it
);
6430 if (newline_found_p
&& it
->bidi_p
&& bidi_it_prev
)
6431 *bidi_it_prev
= it
->bidi_it
;
6432 set_iterator_to_next (it
, false);
6437 it
->selective
= old_selective
;
6438 return newline_found_p
;
6442 /* Set IT's current position to the previous visible line start. Skip
6443 invisible text that is so either due to text properties or due to
6444 selective display. Caution: this does not change IT->current_x and
6448 back_to_previous_visible_line_start (struct it
*it
)
6450 while (IT_CHARPOS (*it
) > BEGV
)
6452 back_to_previous_line_start (it
);
6454 if (IT_CHARPOS (*it
) <= BEGV
)
6457 /* If selective > 0, then lines indented more than its value are
6459 if (it
->selective
> 0
6460 && indented_beyond_p (IT_CHARPOS (*it
), IT_BYTEPOS (*it
),
6464 /* Check the newline before point for invisibility. */
6467 prop
= Fget_char_property (make_number (IT_CHARPOS (*it
) - 1),
6468 Qinvisible
, it
->window
);
6469 if (TEXT_PROP_MEANS_INVISIBLE (prop
) != 0)
6473 if (IT_CHARPOS (*it
) <= BEGV
)
6478 void *it2data
= NULL
;
6481 Lisp_Object val
, overlay
;
6483 SAVE_IT (it2
, *it
, it2data
);
6485 /* If newline is part of a composition, continue from start of composition */
6486 if (find_composition (IT_CHARPOS (*it
), -1, &beg
, &end
, &val
, Qnil
)
6487 && beg
< IT_CHARPOS (*it
))
6490 /* If newline is replaced by a display property, find start of overlay
6491 or interval and continue search from that point. */
6492 pos
= --IT_CHARPOS (it2
);
6495 bidi_unshelve_cache (NULL
, false);
6496 it2
.string_from_display_prop_p
= false;
6497 it2
.from_disp_prop_p
= false;
6498 if (handle_display_prop (&it2
) == HANDLED_RETURN
6499 && !NILP (val
= get_char_property_and_overlay
6500 (make_number (pos
), Qdisplay
, Qnil
, &overlay
))
6501 && (OVERLAYP (overlay
)
6502 ? (beg
= OVERLAY_POSITION (OVERLAY_START (overlay
)))
6503 : get_property_and_range (pos
, Qdisplay
, &val
, &beg
, &end
, Qnil
)))
6505 RESTORE_IT (it
, it
, it2data
);
6509 /* Newline is not replaced by anything -- so we are done. */
6510 RESTORE_IT (it
, it
, it2data
);
6516 IT_CHARPOS (*it
) = beg
;
6517 IT_BYTEPOS (*it
) = buf_charpos_to_bytepos (current_buffer
, beg
);
6521 it
->continuation_lines_width
= 0;
6523 eassert (IT_CHARPOS (*it
) >= BEGV
);
6524 eassert (IT_CHARPOS (*it
) == BEGV
6525 || FETCH_BYTE (IT_BYTEPOS (*it
) - 1) == '\n');
6530 /* Reseat iterator IT at the previous visible line start. Skip
6531 invisible text that is so either due to text properties or due to
6532 selective display. At the end, update IT's overlay information,
6533 face information etc. */
6536 reseat_at_previous_visible_line_start (struct it
*it
)
6538 back_to_previous_visible_line_start (it
);
6539 reseat (it
, it
->current
.pos
, true);
6544 /* Reseat iterator IT on the next visible line start in the current
6545 buffer. ON_NEWLINE_P means position IT on the newline
6546 preceding the line start. Skip over invisible text that is so
6547 because of selective display. Compute faces, overlays etc at the
6548 new position. Note that this function does not skip over text that
6549 is invisible because of text properties. */
6552 reseat_at_next_visible_line_start (struct it
*it
, bool on_newline_p
)
6554 bool skipped_p
= false;
6555 struct bidi_it bidi_it_prev
;
6556 bool newline_found_p
6557 = forward_to_next_line_start (it
, &skipped_p
, &bidi_it_prev
);
6559 /* Skip over lines that are invisible because they are indented
6560 more than the value of IT->selective. */
6561 if (it
->selective
> 0)
6562 while (IT_CHARPOS (*it
) < ZV
6563 && indented_beyond_p (IT_CHARPOS (*it
), IT_BYTEPOS (*it
),
6566 eassert (IT_BYTEPOS (*it
) == BEGV
6567 || FETCH_BYTE (IT_BYTEPOS (*it
) - 1) == '\n');
6569 forward_to_next_line_start (it
, &skipped_p
, &bidi_it_prev
);
6572 /* Position on the newline if that's what's requested. */
6573 if (on_newline_p
&& newline_found_p
)
6575 if (STRINGP (it
->string
))
6577 if (IT_STRING_CHARPOS (*it
) > 0)
6581 --IT_STRING_CHARPOS (*it
);
6582 --IT_STRING_BYTEPOS (*it
);
6586 /* We need to restore the bidi iterator to the state
6587 it had on the newline, and resync the IT's
6588 position with that. */
6589 it
->bidi_it
= bidi_it_prev
;
6590 IT_STRING_CHARPOS (*it
) = it
->bidi_it
.charpos
;
6591 IT_STRING_BYTEPOS (*it
) = it
->bidi_it
.bytepos
;
6595 else if (IT_CHARPOS (*it
) > BEGV
)
6604 /* We need to restore the bidi iterator to the state it
6605 had on the newline and resync IT with that. */
6606 it
->bidi_it
= bidi_it_prev
;
6607 IT_CHARPOS (*it
) = it
->bidi_it
.charpos
;
6608 IT_BYTEPOS (*it
) = it
->bidi_it
.bytepos
;
6610 reseat (it
, it
->current
.pos
, false);
6614 reseat (it
, it
->current
.pos
, false);
6621 /***********************************************************************
6622 Changing an iterator's position
6623 ***********************************************************************/
6625 /* Change IT's current position to POS in current_buffer.
6626 If FORCE_P, always check for text properties at the new position.
6627 Otherwise, text properties are only looked up if POS >=
6628 IT->check_charpos of a property. */
6631 reseat (struct it
*it
, struct text_pos pos
, bool force_p
)
6633 ptrdiff_t original_pos
= IT_CHARPOS (*it
);
6635 reseat_1 (it
, pos
, false);
6637 /* Determine where to check text properties. Avoid doing it
6638 where possible because text property lookup is very expensive. */
6640 || CHARPOS (pos
) > it
->stop_charpos
6641 || CHARPOS (pos
) < original_pos
)
6645 /* For bidi iteration, we need to prime prev_stop and
6646 base_level_stop with our best estimations. */
6647 /* Implementation note: Of course, POS is not necessarily a
6648 stop position, so assigning prev_pos to it is a lie; we
6649 should have called compute_stop_backwards. However, if
6650 the current buffer does not include any R2L characters,
6651 that call would be a waste of cycles, because the
6652 iterator will never move back, and thus never cross this
6653 "fake" stop position. So we delay that backward search
6654 until the time we really need it, in next_element_from_buffer. */
6655 if (CHARPOS (pos
) != it
->prev_stop
)
6656 it
->prev_stop
= CHARPOS (pos
);
6657 if (CHARPOS (pos
) < it
->base_level_stop
)
6658 it
->base_level_stop
= 0; /* meaning it's unknown */
6664 it
->prev_stop
= it
->base_level_stop
= 0;
6673 /* Change IT's buffer position to POS. SET_STOP_P means set
6674 IT->stop_pos to POS, also. */
6677 reseat_1 (struct it
*it
, struct text_pos pos
, bool set_stop_p
)
6679 /* Don't call this function when scanning a C string. */
6680 eassert (it
->s
== NULL
);
6682 /* POS must be a reasonable value. */
6683 eassert (CHARPOS (pos
) >= BEGV
&& CHARPOS (pos
) <= ZV
);
6685 it
->current
.pos
= it
->position
= pos
;
6686 it
->end_charpos
= ZV
;
6688 it
->current
.dpvec_index
= -1;
6689 it
->current
.overlay_string_index
= -1;
6690 IT_STRING_CHARPOS (*it
) = -1;
6691 IT_STRING_BYTEPOS (*it
) = -1;
6693 it
->method
= GET_FROM_BUFFER
;
6694 it
->object
= it
->w
->contents
;
6695 it
->area
= TEXT_AREA
;
6696 it
->multibyte_p
= !NILP (BVAR (current_buffer
, enable_multibyte_characters
));
6698 it
->string_from_display_prop_p
= false;
6699 it
->string_from_prefix_prop_p
= false;
6701 it
->from_disp_prop_p
= false;
6702 it
->face_before_selective_p
= false;
6705 bidi_init_it (IT_CHARPOS (*it
), IT_BYTEPOS (*it
), FRAME_WINDOW_P (it
->f
),
6707 bidi_unshelve_cache (NULL
, false);
6708 it
->bidi_it
.paragraph_dir
= NEUTRAL_DIR
;
6709 it
->bidi_it
.string
.s
= NULL
;
6710 it
->bidi_it
.string
.lstring
= Qnil
;
6711 it
->bidi_it
.string
.bufpos
= 0;
6712 it
->bidi_it
.string
.from_disp_str
= false;
6713 it
->bidi_it
.string
.unibyte
= false;
6714 it
->bidi_it
.w
= it
->w
;
6719 it
->stop_charpos
= CHARPOS (pos
);
6720 it
->base_level_stop
= CHARPOS (pos
);
6722 /* This make the information stored in it->cmp_it invalidate. */
6727 /* Set up IT for displaying a string, starting at CHARPOS in window W.
6728 If S is non-null, it is a C string to iterate over. Otherwise,
6729 STRING gives a Lisp string to iterate over.
6731 If PRECISION > 0, don't return more then PRECISION number of
6732 characters from the string.
6734 If FIELD_WIDTH > 0, return padding spaces until FIELD_WIDTH
6735 characters have been returned. FIELD_WIDTH < 0 means an infinite
6738 MULTIBYTE = 0 means disable processing of multibyte characters,
6739 MULTIBYTE > 0 means enable it,
6740 MULTIBYTE < 0 means use IT->multibyte_p.
6742 IT must be initialized via a prior call to init_iterator before
6743 calling this function. */
6746 reseat_to_string (struct it
*it
, const char *s
, Lisp_Object string
,
6747 ptrdiff_t charpos
, ptrdiff_t precision
, int field_width
,
6750 /* No text property checks performed by default, but see below. */
6751 it
->stop_charpos
= -1;
6753 /* Set iterator position and end position. */
6754 memset (&it
->current
, 0, sizeof it
->current
);
6755 it
->current
.overlay_string_index
= -1;
6756 it
->current
.dpvec_index
= -1;
6757 eassert (charpos
>= 0);
6759 /* If STRING is specified, use its multibyteness, otherwise use the
6760 setting of MULTIBYTE, if specified. */
6762 it
->multibyte_p
= multibyte
> 0;
6764 /* Bidirectional reordering of strings is controlled by the default
6765 value of bidi-display-reordering. Don't try to reorder while
6766 loading loadup.el, as the necessary character property tables are
6767 not yet available. */
6769 !redisplay__inhibit_bidi
6770 && !NILP (BVAR (&buffer_defaults
, bidi_display_reordering
));
6774 eassert (STRINGP (string
));
6775 it
->string
= string
;
6777 it
->end_charpos
= it
->string_nchars
= SCHARS (string
);
6778 it
->method
= GET_FROM_STRING
;
6779 it
->current
.string_pos
= string_pos (charpos
, string
);
6783 it
->bidi_it
.string
.lstring
= string
;
6784 it
->bidi_it
.string
.s
= NULL
;
6785 it
->bidi_it
.string
.schars
= it
->end_charpos
;
6786 it
->bidi_it
.string
.bufpos
= 0;
6787 it
->bidi_it
.string
.from_disp_str
= false;
6788 it
->bidi_it
.string
.unibyte
= !it
->multibyte_p
;
6789 it
->bidi_it
.w
= it
->w
;
6790 bidi_init_it (charpos
, IT_STRING_BYTEPOS (*it
),
6791 FRAME_WINDOW_P (it
->f
), &it
->bidi_it
);
6796 it
->s
= (const unsigned char *) s
;
6799 /* Note that we use IT->current.pos, not it->current.string_pos,
6800 for displaying C strings. */
6801 IT_STRING_CHARPOS (*it
) = IT_STRING_BYTEPOS (*it
) = -1;
6802 if (it
->multibyte_p
)
6804 it
->current
.pos
= c_string_pos (charpos
, s
, true);
6805 it
->end_charpos
= it
->string_nchars
= number_of_chars (s
, true);
6809 IT_CHARPOS (*it
) = IT_BYTEPOS (*it
) = charpos
;
6810 it
->end_charpos
= it
->string_nchars
= strlen (s
);
6815 it
->bidi_it
.string
.lstring
= Qnil
;
6816 it
->bidi_it
.string
.s
= (const unsigned char *) s
;
6817 it
->bidi_it
.string
.schars
= it
->end_charpos
;
6818 it
->bidi_it
.string
.bufpos
= 0;
6819 it
->bidi_it
.string
.from_disp_str
= false;
6820 it
->bidi_it
.string
.unibyte
= !it
->multibyte_p
;
6821 it
->bidi_it
.w
= it
->w
;
6822 bidi_init_it (charpos
, IT_BYTEPOS (*it
), FRAME_WINDOW_P (it
->f
),
6825 it
->method
= GET_FROM_C_STRING
;
6828 /* PRECISION > 0 means don't return more than PRECISION characters
6830 if (precision
> 0 && it
->end_charpos
- charpos
> precision
)
6832 it
->end_charpos
= it
->string_nchars
= charpos
+ precision
;
6834 it
->bidi_it
.string
.schars
= it
->end_charpos
;
6837 /* FIELD_WIDTH > 0 means pad with spaces until FIELD_WIDTH
6838 characters have been returned. FIELD_WIDTH == 0 means don't pad,
6839 FIELD_WIDTH < 0 means infinite field width. This is useful for
6840 padding with `-' at the end of a mode line. */
6841 if (field_width
< 0)
6842 field_width
= DISP_INFINITY
;
6843 /* Implementation note: We deliberately don't enlarge
6844 it->bidi_it.string.schars here to fit it->end_charpos, because
6845 the bidi iterator cannot produce characters out of thin air. */
6846 if (field_width
> it
->end_charpos
- charpos
)
6847 it
->end_charpos
= charpos
+ field_width
;
6849 /* Use the standard display table for displaying strings. */
6850 if (DISP_TABLE_P (Vstandard_display_table
))
6851 it
->dp
= XCHAR_TABLE (Vstandard_display_table
);
6853 it
->stop_charpos
= charpos
;
6854 it
->prev_stop
= charpos
;
6855 it
->base_level_stop
= 0;
6858 it
->bidi_it
.first_elt
= true;
6859 it
->bidi_it
.paragraph_dir
= NEUTRAL_DIR
;
6860 it
->bidi_it
.disp_pos
= -1;
6862 if (s
== NULL
&& it
->multibyte_p
)
6864 ptrdiff_t endpos
= SCHARS (it
->string
);
6865 if (endpos
> it
->end_charpos
)
6866 endpos
= it
->end_charpos
;
6867 composition_compute_stop_pos (&it
->cmp_it
, charpos
, -1, endpos
,
6875 /***********************************************************************
6877 ***********************************************************************/
6879 /* Map enum it_method value to corresponding next_element_from_* function. */
6881 typedef bool (*next_element_function
) (struct it
*);
6883 static next_element_function
const get_next_element
[NUM_IT_METHODS
] =
6885 next_element_from_buffer
,
6886 next_element_from_display_vector
,
6887 next_element_from_string
,
6888 next_element_from_c_string
,
6889 next_element_from_image
,
6890 next_element_from_stretch
,
6891 next_element_from_xwidget
,
6894 #define GET_NEXT_DISPLAY_ELEMENT(it) (*get_next_element[(it)->method]) (it)
6897 /* Return true iff a character at CHARPOS (and BYTEPOS) is composed
6898 (possibly with the following characters). */
6900 #define CHAR_COMPOSED_P(IT,CHARPOS,BYTEPOS,END_CHARPOS) \
6901 ((IT)->cmp_it.id >= 0 \
6902 || ((IT)->cmp_it.stop_pos == (CHARPOS) \
6903 && composition_reseat_it (&(IT)->cmp_it, CHARPOS, BYTEPOS, \
6904 END_CHARPOS, (IT)->w, \
6905 FACE_FROM_ID_OR_NULL ((IT)->f, \
6910 /* Lookup the char-table Vglyphless_char_display for character C (-1
6911 if we want information for no-font case), and return the display
6912 method symbol. By side-effect, update it->what and
6913 it->glyphless_method. This function is called from
6914 get_next_display_element for each character element, and from
6915 x_produce_glyphs when no suitable font was found. */
6918 lookup_glyphless_char_display (int c
, struct it
*it
)
6920 Lisp_Object glyphless_method
= Qnil
;
6922 if (CHAR_TABLE_P (Vglyphless_char_display
)
6923 && CHAR_TABLE_EXTRA_SLOTS (XCHAR_TABLE (Vglyphless_char_display
)) >= 1)
6927 glyphless_method
= CHAR_TABLE_REF (Vglyphless_char_display
, c
);
6928 if (CONSP (glyphless_method
))
6929 glyphless_method
= FRAME_WINDOW_P (it
->f
)
6930 ? XCAR (glyphless_method
)
6931 : XCDR (glyphless_method
);
6934 glyphless_method
= XCHAR_TABLE (Vglyphless_char_display
)->extras
[0];
6938 if (NILP (glyphless_method
))
6941 /* The default is to display the character by a proper font. */
6943 /* The default for the no-font case is to display an empty box. */
6944 glyphless_method
= Qempty_box
;
6946 if (EQ (glyphless_method
, Qzero_width
))
6949 return glyphless_method
;
6950 /* This method can't be used for the no-font case. */
6951 glyphless_method
= Qempty_box
;
6953 if (EQ (glyphless_method
, Qthin_space
))
6954 it
->glyphless_method
= GLYPHLESS_DISPLAY_THIN_SPACE
;
6955 else if (EQ (glyphless_method
, Qempty_box
))
6956 it
->glyphless_method
= GLYPHLESS_DISPLAY_EMPTY_BOX
;
6957 else if (EQ (glyphless_method
, Qhex_code
))
6958 it
->glyphless_method
= GLYPHLESS_DISPLAY_HEX_CODE
;
6959 else if (STRINGP (glyphless_method
))
6960 it
->glyphless_method
= GLYPHLESS_DISPLAY_ACRONYM
;
6963 /* Invalid value. We use the default method. */
6964 glyphless_method
= Qnil
;
6967 it
->what
= IT_GLYPHLESS
;
6968 return glyphless_method
;
6971 /* Merge escape glyph face and cache the result. */
6973 static struct frame
*last_escape_glyph_frame
= NULL
;
6974 static int last_escape_glyph_face_id
= (1 << FACE_ID_BITS
);
6975 static int last_escape_glyph_merged_face_id
= 0;
6978 merge_escape_glyph_face (struct it
*it
)
6982 if (it
->f
== last_escape_glyph_frame
6983 && it
->face_id
== last_escape_glyph_face_id
)
6984 face_id
= last_escape_glyph_merged_face_id
;
6987 /* Merge the `escape-glyph' face into the current face. */
6988 face_id
= merge_faces (it
->w
, Qescape_glyph
, 0, it
->face_id
);
6989 last_escape_glyph_frame
= it
->f
;
6990 last_escape_glyph_face_id
= it
->face_id
;
6991 last_escape_glyph_merged_face_id
= face_id
;
6996 /* Likewise for glyphless glyph face. */
6998 static struct frame
*last_glyphless_glyph_frame
= NULL
;
6999 static int last_glyphless_glyph_face_id
= (1 << FACE_ID_BITS
);
7000 static int last_glyphless_glyph_merged_face_id
= 0;
7003 merge_glyphless_glyph_face (struct it
*it
)
7007 if (it
->f
== last_glyphless_glyph_frame
7008 && it
->face_id
== last_glyphless_glyph_face_id
)
7009 face_id
= last_glyphless_glyph_merged_face_id
;
7012 /* Merge the `glyphless-char' face into the current face. */
7013 face_id
= merge_faces (it
->w
, Qglyphless_char
, 0, it
->face_id
);
7014 last_glyphless_glyph_frame
= it
->f
;
7015 last_glyphless_glyph_face_id
= it
->face_id
;
7016 last_glyphless_glyph_merged_face_id
= face_id
;
7021 /* Forget the `escape-glyph' and `glyphless-char' faces. This should
7022 be called before redisplaying windows, and when the frame's face
7025 forget_escape_and_glyphless_faces (void)
7027 last_escape_glyph_frame
= NULL
;
7028 last_escape_glyph_face_id
= (1 << FACE_ID_BITS
);
7029 last_glyphless_glyph_frame
= NULL
;
7030 last_glyphless_glyph_face_id
= (1 << FACE_ID_BITS
);
7033 /* Load IT's display element fields with information about the next
7034 display element from the current position of IT. Value is false if
7035 end of buffer (or C string) is reached. */
7038 get_next_display_element (struct it
*it
)
7040 /* True means that we found a display element. False means that
7041 we hit the end of what we iterate over. Performance note: the
7042 function pointer `method' used here turns out to be faster than
7043 using a sequence of if-statements. */
7047 success_p
= GET_NEXT_DISPLAY_ELEMENT (it
);
7049 if (it
->what
== IT_CHARACTER
)
7051 /* UAX#9, L4: "A character is depicted by a mirrored glyph if
7052 and only if (a) the resolved directionality of that character
7054 /* FIXME: Do we need an exception for characters from display
7056 if (it
->bidi_p
&& it
->bidi_it
.type
== STRONG_R
7057 && !inhibit_bidi_mirroring
)
7058 it
->c
= bidi_mirror_char (it
->c
);
7059 /* Map via display table or translate control characters.
7060 IT->c, IT->len etc. have been set to the next character by
7061 the function call above. If we have a display table, and it
7062 contains an entry for IT->c, translate it. Don't do this if
7063 IT->c itself comes from a display table, otherwise we could
7064 end up in an infinite recursion. (An alternative could be to
7065 count the recursion depth of this function and signal an
7066 error when a certain maximum depth is reached.) Is it worth
7068 if (success_p
&& it
->dpvec
== NULL
)
7071 struct charset
*unibyte
= CHARSET_FROM_ID (charset_unibyte
);
7072 bool nonascii_space_p
= false;
7073 bool nonascii_hyphen_p
= false;
7074 int c
= it
->c
; /* This is the character to display. */
7076 if (! it
->multibyte_p
&& ! ASCII_CHAR_P (c
))
7078 eassert (SINGLE_BYTE_CHAR_P (c
));
7079 if (unibyte_display_via_language_environment
)
7081 c
= DECODE_CHAR (unibyte
, c
);
7083 c
= BYTE8_TO_CHAR (it
->c
);
7086 c
= BYTE8_TO_CHAR (it
->c
);
7090 && (dv
= DISP_CHAR_VECTOR (it
->dp
, c
),
7093 struct Lisp_Vector
*v
= XVECTOR (dv
);
7095 /* Return the first character from the display table
7096 entry, if not empty. If empty, don't display the
7097 current character. */
7100 it
->dpvec_char_len
= it
->len
;
7101 it
->dpvec
= v
->contents
;
7102 it
->dpend
= v
->contents
+ v
->header
.size
;
7103 it
->current
.dpvec_index
= 0;
7104 it
->dpvec_face_id
= -1;
7105 it
->saved_face_id
= it
->face_id
;
7106 it
->method
= GET_FROM_DISPLAY_VECTOR
;
7107 it
->ellipsis_p
= false;
7111 set_iterator_to_next (it
, false);
7116 if (! NILP (lookup_glyphless_char_display (c
, it
)))
7118 if (it
->what
== IT_GLYPHLESS
)
7120 /* Don't display this character. */
7121 set_iterator_to_next (it
, false);
7125 /* If `nobreak-char-display' is non-nil, we display
7126 non-ASCII spaces and hyphens specially. */
7127 if (! ASCII_CHAR_P (c
) && ! NILP (Vnobreak_char_display
))
7129 if (c
== NO_BREAK_SPACE
)
7130 nonascii_space_p
= true;
7131 else if (c
== SOFT_HYPHEN
|| c
== HYPHEN
7132 || c
== NON_BREAKING_HYPHEN
)
7133 nonascii_hyphen_p
= true;
7136 /* Translate control characters into `\003' or `^C' form.
7137 Control characters coming from a display table entry are
7138 currently not translated because we use IT->dpvec to hold
7139 the translation. This could easily be changed but I
7140 don't believe that it is worth doing.
7142 The characters handled by `nobreak-char-display' must be
7145 Non-printable characters and raw-byte characters are also
7146 translated to octal or hexadecimal form. */
7147 if (((c
< ' ' || c
== 127) /* ASCII control chars. */
7148 ? (it
->area
!= TEXT_AREA
7149 /* In mode line, treat \n, \t like other crl chars. */
7152 && (it
->glyph_row
->mode_line_p
|| it
->avoid_cursor_p
))
7153 || (c
!= '\n' && c
!= '\t'))
7155 || nonascii_hyphen_p
7157 || ! CHAR_PRINTABLE_P (c
))))
7159 /* C is a control character, non-ASCII space/hyphen,
7160 raw-byte, or a non-printable character which must be
7161 displayed either as '\003' or as `^C' where the '\\'
7162 and '^' can be defined in the display table. Fill
7163 IT->ctl_chars with glyphs for what we have to
7164 display. Then, set IT->dpvec to these glyphs. */
7171 /* Handle control characters with ^. */
7173 if (ASCII_CHAR_P (c
) && it
->ctl_arrow_p
)
7177 g
= '^'; /* default glyph for Control */
7178 /* Set IT->ctl_chars[0] to the glyph for `^'. */
7180 && (gc
= DISP_CTRL_GLYPH (it
->dp
), GLYPH_CODE_P (gc
)))
7182 g
= GLYPH_CODE_CHAR (gc
);
7183 lface_id
= GLYPH_CODE_FACE (gc
);
7187 ? merge_faces (it
->w
, Qt
, lface_id
, it
->face_id
)
7188 : merge_escape_glyph_face (it
));
7190 XSETINT (it
->ctl_chars
[0], g
);
7191 XSETINT (it
->ctl_chars
[1], c
^ 0100);
7193 goto display_control
;
7196 /* Handle non-ascii space in the mode where it only gets
7199 if (nonascii_space_p
&& EQ (Vnobreak_char_display
, Qt
))
7201 /* Merge `nobreak-space' into the current face. */
7202 face_id
= merge_faces (it
->w
, Qnobreak_space
, 0,
7204 XSETINT (it
->ctl_chars
[0], ' ');
7206 goto display_control
;
7209 /* Handle non-ascii hyphens in the mode where it only
7210 gets highlighting. */
7212 if (nonascii_hyphen_p
&& EQ (Vnobreak_char_display
, Qt
))
7214 /* Merge `nobreak-space' into the current face. */
7215 face_id
= merge_faces (it
->w
, Qnobreak_hyphen
, 0,
7217 XSETINT (it
->ctl_chars
[0], '-');
7219 goto display_control
;
7222 /* Handle sequences that start with the "escape glyph". */
7224 /* the default escape glyph is \. */
7225 escape_glyph
= '\\';
7228 && (gc
= DISP_ESCAPE_GLYPH (it
->dp
), GLYPH_CODE_P (gc
)))
7230 escape_glyph
= GLYPH_CODE_CHAR (gc
);
7231 lface_id
= GLYPH_CODE_FACE (gc
);
7235 ? merge_faces (it
->w
, Qt
, lface_id
, it
->face_id
)
7236 : merge_escape_glyph_face (it
));
7238 /* Draw non-ASCII space/hyphen with escape glyph: */
7240 if (nonascii_space_p
|| nonascii_hyphen_p
)
7242 XSETINT (it
->ctl_chars
[0], escape_glyph
);
7243 XSETINT (it
->ctl_chars
[1], nonascii_space_p
? ' ' : '-');
7245 goto display_control
;
7252 if (CHAR_BYTE8_P (c
))
7253 /* Display \200 or \x80 instead of \17777600. */
7254 c
= CHAR_TO_BYTE8 (c
);
7255 const char *format_string
= display_raw_bytes_as_hex
7258 len
= sprintf (str
, format_string
, c
+ 0u);
7260 XSETINT (it
->ctl_chars
[0], escape_glyph
);
7261 for (i
= 0; i
< len
; i
++)
7262 XSETINT (it
->ctl_chars
[i
+ 1], str
[i
]);
7267 /* Set up IT->dpvec and return first character from it. */
7268 it
->dpvec_char_len
= it
->len
;
7269 it
->dpvec
= it
->ctl_chars
;
7270 it
->dpend
= it
->dpvec
+ ctl_len
;
7271 it
->current
.dpvec_index
= 0;
7272 it
->dpvec_face_id
= face_id
;
7273 it
->saved_face_id
= it
->face_id
;
7274 it
->method
= GET_FROM_DISPLAY_VECTOR
;
7275 it
->ellipsis_p
= false;
7278 it
->char_to_display
= c
;
7282 it
->char_to_display
= it
->c
;
7286 #ifdef HAVE_WINDOW_SYSTEM
7287 /* Adjust face id for a multibyte character. There are no multibyte
7288 character in unibyte text. */
7289 if ((it
->what
== IT_CHARACTER
|| it
->what
== IT_COMPOSITION
)
7292 && FRAME_WINDOW_P (it
->f
))
7294 struct face
*face
= FACE_FROM_ID (it
->f
, it
->face_id
);
7296 if (it
->what
== IT_COMPOSITION
&& it
->cmp_it
.ch
>= 0)
7298 /* Automatic composition with glyph-string. */
7299 Lisp_Object gstring
= composition_gstring_from_id (it
->cmp_it
.id
);
7301 it
->face_id
= face_for_font (it
->f
, LGSTRING_FONT (gstring
), face
);
7305 ptrdiff_t pos
= (it
->s
? -1
7306 : STRINGP (it
->string
) ? IT_STRING_CHARPOS (*it
)
7307 : IT_CHARPOS (*it
));
7310 if (it
->what
== IT_CHARACTER
)
7311 c
= it
->char_to_display
;
7314 struct composition
*cmp
= composition_table
[it
->cmp_it
.id
];
7318 for (i
= 0; i
< cmp
->glyph_len
; i
++)
7319 /* TAB in a composition means display glyphs with
7320 padding space on the left or right. */
7321 if ((c
= COMPOSITION_GLYPH (cmp
, i
)) != '\t')
7324 it
->face_id
= FACE_FOR_CHAR (it
->f
, face
, c
, pos
, it
->string
);
7327 #endif /* HAVE_WINDOW_SYSTEM */
7330 /* Is this character the last one of a run of characters with
7331 box? If yes, set IT->end_of_box_run_p to true. */
7335 if (it
->method
== GET_FROM_STRING
&& it
->sp
)
7337 int face_id
= underlying_face_id (it
);
7338 struct face
*face
= FACE_FROM_ID_OR_NULL (it
->f
, face_id
);
7342 if (face
->box
== FACE_NO_BOX
)
7344 /* If the box comes from face properties in a
7345 display string, check faces in that string. */
7346 int string_face_id
= face_after_it_pos (it
);
7347 it
->end_of_box_run_p
7348 = (FACE_FROM_ID (it
->f
, string_face_id
)->box
7351 /* Otherwise, the box comes from the underlying face.
7352 If this is the last string character displayed, check
7353 the next buffer location. */
7354 else if ((IT_STRING_CHARPOS (*it
) >= SCHARS (it
->string
) - 1)
7355 /* n_overlay_strings is unreliable unless
7356 overlay_string_index is non-negative. */
7357 && ((it
->current
.overlay_string_index
>= 0
7358 && (it
->current
.overlay_string_index
7359 == it
->n_overlay_strings
- 1))
7360 /* A string from display property. */
7361 || it
->from_disp_prop_p
))
7365 bool text_from_string
= false;
7366 /* Normally, the next buffer location is stored in
7367 IT->current.pos... */
7368 struct text_pos pos
= it
->current
.pos
;
7370 /* ...but for a string from a display property, the
7371 next buffer position is stored in the 'position'
7372 member of the iteration stack slot below the
7373 current one, see handle_single_display_spec. By
7374 contrast, it->current.pos was not yet updated to
7375 point to that buffer position; that will happen
7376 in pop_it, after we finish displaying the current
7377 string. Note that we already checked above that
7378 it->sp is positive, so subtracting one from it is
7380 if (it
->from_disp_prop_p
)
7382 int stackp
= it
->sp
- 1;
7384 /* Find the stack level with data from buffer. */
7386 && STRINGP ((it
->stack
+ stackp
)->string
))
7390 /* If no stack slot was found for iterating
7391 a buffer, we are displaying text from a
7392 string, most probably the mode line or
7393 the header line, and that string has a
7394 display string on some of its
7396 text_from_string
= true;
7397 pos
= it
->stack
[it
->sp
- 1].position
;
7400 pos
= (it
->stack
+ stackp
)->position
;
7403 INC_TEXT_POS (pos
, it
->multibyte_p
);
7405 if (text_from_string
)
7407 Lisp_Object base_string
= it
->stack
[it
->sp
- 1].string
;
7409 if (CHARPOS (pos
) >= SCHARS (base_string
) - 1)
7410 it
->end_of_box_run_p
= true;
7414 = face_at_string_position (it
->w
, base_string
,
7416 &ignore
, face_id
, false);
7417 it
->end_of_box_run_p
7418 = (FACE_FROM_ID (it
->f
, next_face_id
)->box
7422 else if (CHARPOS (pos
) >= ZV
)
7423 it
->end_of_box_run_p
= true;
7427 face_at_buffer_position (it
->w
, CHARPOS (pos
), &ignore
,
7429 + TEXT_PROP_DISTANCE_LIMIT
,
7431 it
->end_of_box_run_p
7432 = (FACE_FROM_ID (it
->f
, next_face_id
)->box
7438 /* next_element_from_display_vector sets this flag according to
7439 faces of the display vector glyphs, see there. */
7440 else if (it
->method
!= GET_FROM_DISPLAY_VECTOR
)
7442 int face_id
= face_after_it_pos (it
);
7443 it
->end_of_box_run_p
7444 = (face_id
!= it
->face_id
7445 && FACE_FROM_ID (it
->f
, face_id
)->box
== FACE_NO_BOX
);
7448 /* If we reached the end of the object we've been iterating (e.g., a
7449 display string or an overlay string), and there's something on
7450 IT->stack, proceed with what's on the stack. It doesn't make
7451 sense to return false if there's unprocessed stuff on the stack,
7452 because otherwise that stuff will never be displayed. */
7453 if (!success_p
&& it
->sp
> 0)
7455 set_iterator_to_next (it
, false);
7456 success_p
= get_next_display_element (it
);
7459 /* Value is false if end of buffer or string reached. */
7464 /* Move IT to the next display element.
7466 RESEAT_P means if called on a newline in buffer text,
7467 skip to the next visible line start.
7469 Functions get_next_display_element and set_iterator_to_next are
7470 separate because I find this arrangement easier to handle than a
7471 get_next_display_element function that also increments IT's
7472 position. The way it is we can first look at an iterator's current
7473 display element, decide whether it fits on a line, and if it does,
7474 increment the iterator position. The other way around we probably
7475 would either need a flag indicating whether the iterator has to be
7476 incremented the next time, or we would have to implement a
7477 decrement position function which would not be easy to write. */
7480 set_iterator_to_next (struct it
*it
, bool reseat_p
)
7482 /* Reset flags indicating start and end of a sequence of characters
7483 with box. Reset them at the start of this function because
7484 moving the iterator to a new position might set them. */
7485 it
->start_of_box_run_p
= it
->end_of_box_run_p
= false;
7489 case GET_FROM_BUFFER
:
7490 /* The current display element of IT is a character from
7491 current_buffer. Advance in the buffer, and maybe skip over
7492 invisible lines that are so because of selective display. */
7493 if (ITERATOR_AT_END_OF_LINE_P (it
) && reseat_p
)
7494 reseat_at_next_visible_line_start (it
, false);
7495 else if (it
->cmp_it
.id
>= 0)
7497 /* We are currently getting glyphs from a composition. */
7500 IT_CHARPOS (*it
) += it
->cmp_it
.nchars
;
7501 IT_BYTEPOS (*it
) += it
->cmp_it
.nbytes
;
7507 /* Update IT's char/byte positions to point to the first
7508 character of the next grapheme cluster, or to the
7509 character visually after the current composition. */
7510 for (i
= 0; i
< it
->cmp_it
.nchars
; i
++)
7511 bidi_move_to_visually_next (&it
->bidi_it
);
7512 IT_BYTEPOS (*it
) = it
->bidi_it
.bytepos
;
7513 IT_CHARPOS (*it
) = it
->bidi_it
.charpos
;
7516 if ((! it
->bidi_p
|| ! it
->cmp_it
.reversed_p
)
7517 && it
->cmp_it
.to
< it
->cmp_it
.nglyphs
)
7519 /* Composition created while scanning forward. Proceed
7520 to the next grapheme cluster. */
7521 it
->cmp_it
.from
= it
->cmp_it
.to
;
7523 else if ((it
->bidi_p
&& it
->cmp_it
.reversed_p
)
7524 && it
->cmp_it
.from
> 0)
7526 /* Composition created while scanning backward. Proceed
7527 to the previous grapheme cluster. */
7528 it
->cmp_it
.to
= it
->cmp_it
.from
;
7532 /* No more grapheme clusters in this composition.
7533 Find the next stop position. */
7534 ptrdiff_t stop
= it
->end_charpos
;
7536 if (it
->bidi_it
.scan_dir
< 0)
7537 /* Now we are scanning backward and don't know
7540 composition_compute_stop_pos (&it
->cmp_it
, IT_CHARPOS (*it
),
7541 IT_BYTEPOS (*it
), stop
, Qnil
);
7546 eassert (it
->len
!= 0);
7550 IT_BYTEPOS (*it
) += it
->len
;
7551 IT_CHARPOS (*it
) += 1;
7555 int prev_scan_dir
= it
->bidi_it
.scan_dir
;
7556 /* If this is a new paragraph, determine its base
7557 direction (a.k.a. its base embedding level). */
7558 if (it
->bidi_it
.new_paragraph
)
7559 bidi_paragraph_init (it
->paragraph_embedding
, &it
->bidi_it
,
7561 bidi_move_to_visually_next (&it
->bidi_it
);
7562 IT_BYTEPOS (*it
) = it
->bidi_it
.bytepos
;
7563 IT_CHARPOS (*it
) = it
->bidi_it
.charpos
;
7564 if (prev_scan_dir
!= it
->bidi_it
.scan_dir
)
7566 /* As the scan direction was changed, we must
7567 re-compute the stop position for composition. */
7568 ptrdiff_t stop
= it
->end_charpos
;
7569 if (it
->bidi_it
.scan_dir
< 0)
7571 composition_compute_stop_pos (&it
->cmp_it
, IT_CHARPOS (*it
),
7572 IT_BYTEPOS (*it
), stop
, Qnil
);
7575 eassert (IT_BYTEPOS (*it
) == CHAR_TO_BYTE (IT_CHARPOS (*it
)));
7579 case GET_FROM_C_STRING
:
7580 /* Current display element of IT is from a C string. */
7582 /* If the string position is beyond string's end, it means
7583 next_element_from_c_string is padding the string with
7584 blanks, in which case we bypass the bidi iterator,
7585 because it cannot deal with such virtual characters. */
7586 || IT_CHARPOS (*it
) >= it
->bidi_it
.string
.schars
)
7588 IT_BYTEPOS (*it
) += it
->len
;
7589 IT_CHARPOS (*it
) += 1;
7593 bidi_move_to_visually_next (&it
->bidi_it
);
7594 IT_BYTEPOS (*it
) = it
->bidi_it
.bytepos
;
7595 IT_CHARPOS (*it
) = it
->bidi_it
.charpos
;
7599 case GET_FROM_DISPLAY_VECTOR
:
7600 /* Current display element of IT is from a display table entry.
7601 Advance in the display table definition. Reset it to null if
7602 end reached, and continue with characters from buffers/
7604 ++it
->current
.dpvec_index
;
7606 /* Restore face of the iterator to what they were before the
7607 display vector entry (these entries may contain faces). */
7608 it
->face_id
= it
->saved_face_id
;
7610 if (it
->dpvec
+ it
->current
.dpvec_index
>= it
->dpend
)
7612 bool recheck_faces
= it
->ellipsis_p
;
7615 it
->method
= GET_FROM_C_STRING
;
7616 else if (STRINGP (it
->string
))
7617 it
->method
= GET_FROM_STRING
;
7620 it
->method
= GET_FROM_BUFFER
;
7621 it
->object
= it
->w
->contents
;
7625 it
->current
.dpvec_index
= -1;
7627 /* Skip over characters which were displayed via IT->dpvec. */
7628 if (it
->dpvec_char_len
< 0)
7629 reseat_at_next_visible_line_start (it
, true);
7630 else if (it
->dpvec_char_len
> 0)
7632 it
->len
= it
->dpvec_char_len
;
7633 set_iterator_to_next (it
, reseat_p
);
7636 /* Maybe recheck faces after display vector. */
7639 if (it
->method
== GET_FROM_STRING
)
7640 it
->stop_charpos
= IT_STRING_CHARPOS (*it
);
7642 it
->stop_charpos
= IT_CHARPOS (*it
);
7647 case GET_FROM_STRING
:
7648 /* Current display element is a character from a Lisp string. */
7649 eassert (it
->s
== NULL
&& STRINGP (it
->string
));
7650 /* Don't advance past string end. These conditions are true
7651 when set_iterator_to_next is called at the end of
7652 get_next_display_element, in which case the Lisp string is
7653 already exhausted, and all we want is pop the iterator
7655 if (it
->current
.overlay_string_index
>= 0)
7657 /* This is an overlay string, so there's no padding with
7658 spaces, and the number of characters in the string is
7659 where the string ends. */
7660 if (IT_STRING_CHARPOS (*it
) >= SCHARS (it
->string
))
7661 goto consider_string_end
;
7665 /* Not an overlay string. There could be padding, so test
7666 against it->end_charpos. */
7667 if (IT_STRING_CHARPOS (*it
) >= it
->end_charpos
)
7668 goto consider_string_end
;
7670 if (it
->cmp_it
.id
>= 0)
7672 /* We are delivering display elements from a composition.
7673 Update the string position past the grapheme cluster
7674 we've just processed. */
7677 IT_STRING_CHARPOS (*it
) += it
->cmp_it
.nchars
;
7678 IT_STRING_BYTEPOS (*it
) += it
->cmp_it
.nbytes
;
7684 for (i
= 0; i
< it
->cmp_it
.nchars
; i
++)
7685 bidi_move_to_visually_next (&it
->bidi_it
);
7686 IT_STRING_BYTEPOS (*it
) = it
->bidi_it
.bytepos
;
7687 IT_STRING_CHARPOS (*it
) = it
->bidi_it
.charpos
;
7690 /* Did we exhaust all the grapheme clusters of this
7692 if ((! it
->bidi_p
|| ! it
->cmp_it
.reversed_p
)
7693 && (it
->cmp_it
.to
< it
->cmp_it
.nglyphs
))
7695 /* Not all the grapheme clusters were processed yet;
7696 advance to the next cluster. */
7697 it
->cmp_it
.from
= it
->cmp_it
.to
;
7699 else if ((it
->bidi_p
&& it
->cmp_it
.reversed_p
)
7700 && it
->cmp_it
.from
> 0)
7702 /* Likewise: advance to the next cluster, but going in
7703 the reverse direction. */
7704 it
->cmp_it
.to
= it
->cmp_it
.from
;
7708 /* This composition was fully processed; find the next
7709 candidate place for checking for composed
7711 /* Always limit string searches to the string length;
7712 any padding spaces are not part of the string, and
7713 there cannot be any compositions in that padding. */
7714 ptrdiff_t stop
= SCHARS (it
->string
);
7716 if (it
->bidi_p
&& it
->bidi_it
.scan_dir
< 0)
7718 else if (it
->end_charpos
< stop
)
7720 /* Cf. PRECISION in reseat_to_string: we might be
7721 limited in how many of the string characters we
7723 stop
= it
->end_charpos
;
7725 composition_compute_stop_pos (&it
->cmp_it
,
7726 IT_STRING_CHARPOS (*it
),
7727 IT_STRING_BYTEPOS (*it
), stop
,
7734 /* If the string position is beyond string's end, it
7735 means next_element_from_string is padding the string
7736 with blanks, in which case we bypass the bidi
7737 iterator, because it cannot deal with such virtual
7739 || IT_STRING_CHARPOS (*it
) >= it
->bidi_it
.string
.schars
)
7741 IT_STRING_BYTEPOS (*it
) += it
->len
;
7742 IT_STRING_CHARPOS (*it
) += 1;
7746 int prev_scan_dir
= it
->bidi_it
.scan_dir
;
7748 bidi_move_to_visually_next (&it
->bidi_it
);
7749 IT_STRING_BYTEPOS (*it
) = it
->bidi_it
.bytepos
;
7750 IT_STRING_CHARPOS (*it
) = it
->bidi_it
.charpos
;
7751 /* If the scan direction changes, we may need to update
7752 the place where to check for composed characters. */
7753 if (prev_scan_dir
!= it
->bidi_it
.scan_dir
)
7755 ptrdiff_t stop
= SCHARS (it
->string
);
7757 if (it
->bidi_it
.scan_dir
< 0)
7759 else if (it
->end_charpos
< stop
)
7760 stop
= it
->end_charpos
;
7762 composition_compute_stop_pos (&it
->cmp_it
,
7763 IT_STRING_CHARPOS (*it
),
7764 IT_STRING_BYTEPOS (*it
), stop
,
7770 consider_string_end
:
7772 if (it
->current
.overlay_string_index
>= 0)
7774 /* IT->string is an overlay string. Advance to the
7775 next, if there is one. */
7776 if (IT_STRING_CHARPOS (*it
) >= SCHARS (it
->string
))
7778 it
->ellipsis_p
= false;
7779 next_overlay_string (it
);
7781 setup_for_ellipsis (it
, 0);
7786 /* IT->string is not an overlay string. If we reached
7787 its end, and there is something on IT->stack, proceed
7788 with what is on the stack. This can be either another
7789 string, this time an overlay string, or a buffer. */
7790 if (IT_STRING_CHARPOS (*it
) == SCHARS (it
->string
)
7794 if (it
->method
== GET_FROM_STRING
)
7795 goto consider_string_end
;
7800 case GET_FROM_IMAGE
:
7801 case GET_FROM_STRETCH
:
7802 case GET_FROM_XWIDGET
:
7804 /* The position etc with which we have to proceed are on
7805 the stack. The position may be at the end of a string,
7806 if the `display' property takes up the whole string. */
7807 eassert (it
->sp
> 0);
7809 if (it
->method
== GET_FROM_STRING
)
7810 goto consider_string_end
;
7814 /* There are no other methods defined, so this should be a bug. */
7818 eassert (it
->method
!= GET_FROM_STRING
7819 || (STRINGP (it
->string
)
7820 && IT_STRING_CHARPOS (*it
) >= 0));
7823 /* Load IT's display element fields with information about the next
7824 display element which comes from a display table entry or from the
7825 result of translating a control character to one of the forms `^C'
7828 IT->dpvec holds the glyphs to return as characters.
7829 IT->saved_face_id holds the face id before the display vector--it
7830 is restored into IT->face_id in set_iterator_to_next. */
7833 next_element_from_display_vector (struct it
*it
)
7836 int prev_face_id
= it
->face_id
;
7840 eassert (it
->dpvec
&& it
->current
.dpvec_index
>= 0);
7842 it
->face_id
= it
->saved_face_id
;
7844 /* KFS: This code used to check ip->dpvec[0] instead of the current element.
7845 That seemed totally bogus - so I changed it... */
7846 if (it
->dpend
- it
->dpvec
> 0 /* empty dpvec[] is invalid */
7847 && (gc
= it
->dpvec
[it
->current
.dpvec_index
], GLYPH_CODE_P (gc
)))
7849 struct face
*this_face
, *prev_face
, *next_face
;
7851 it
->c
= GLYPH_CODE_CHAR (gc
);
7852 it
->len
= CHAR_BYTES (it
->c
);
7854 /* The entry may contain a face id to use. Such a face id is
7855 the id of a Lisp face, not a realized face. A face id of
7856 zero means no face is specified. */
7857 if (it
->dpvec_face_id
>= 0)
7858 it
->face_id
= it
->dpvec_face_id
;
7861 int lface_id
= GLYPH_CODE_FACE (gc
);
7863 it
->face_id
= merge_faces (it
->w
, Qt
, lface_id
,
7867 /* Glyphs in the display vector could have the box face, so we
7868 need to set the related flags in the iterator, as
7870 this_face
= FACE_FROM_ID_OR_NULL (it
->f
, it
->face_id
);
7871 prev_face
= FACE_FROM_ID_OR_NULL (it
->f
, prev_face_id
);
7873 /* Is this character the first character of a box-face run? */
7874 it
->start_of_box_run_p
= (this_face
&& this_face
->box
!= FACE_NO_BOX
7876 || prev_face
->box
== FACE_NO_BOX
));
7878 /* For the last character of the box-face run, we need to look
7879 either at the next glyph from the display vector, or at the
7880 face we saw before the display vector. */
7881 next_face_id
= it
->saved_face_id
;
7882 if (it
->current
.dpvec_index
< it
->dpend
- it
->dpvec
- 1)
7884 if (it
->dpvec_face_id
>= 0)
7885 next_face_id
= it
->dpvec_face_id
;
7889 GLYPH_CODE_FACE (it
->dpvec
[it
->current
.dpvec_index
+ 1]);
7892 next_face_id
= merge_faces (it
->w
, Qt
, lface_id
,
7896 next_face
= FACE_FROM_ID_OR_NULL (it
->f
, next_face_id
);
7897 it
->end_of_box_run_p
= (this_face
&& this_face
->box
!= FACE_NO_BOX
7899 || next_face
->box
== FACE_NO_BOX
));
7900 it
->face_box_p
= this_face
&& this_face
->box
!= FACE_NO_BOX
;
7903 /* Display table entry is invalid. Return a space. */
7904 it
->c
= ' ', it
->len
= 1;
7906 /* Don't change position and object of the iterator here. They are
7907 still the values of the character that had this display table
7908 entry or was translated, and that's what we want. */
7909 it
->what
= IT_CHARACTER
;
7913 /* Get the first element of string/buffer in the visual order, after
7914 being reseated to a new position in a string or a buffer. */
7916 get_visually_first_element (struct it
*it
)
7918 bool string_p
= STRINGP (it
->string
) || it
->s
;
7919 ptrdiff_t eob
= (string_p
? it
->bidi_it
.string
.schars
: ZV
);
7920 ptrdiff_t bob
= (string_p
? 0 : BEGV
);
7922 if (STRINGP (it
->string
))
7924 it
->bidi_it
.charpos
= IT_STRING_CHARPOS (*it
);
7925 it
->bidi_it
.bytepos
= IT_STRING_BYTEPOS (*it
);
7929 it
->bidi_it
.charpos
= IT_CHARPOS (*it
);
7930 it
->bidi_it
.bytepos
= IT_BYTEPOS (*it
);
7933 if (it
->bidi_it
.charpos
== eob
)
7935 /* Nothing to do, but reset the FIRST_ELT flag, like
7936 bidi_paragraph_init does, because we are not going to
7938 it
->bidi_it
.first_elt
= false;
7940 else if (it
->bidi_it
.charpos
== bob
7942 && (FETCH_CHAR (it
->bidi_it
.bytepos
- 1) == '\n'
7943 || FETCH_CHAR (it
->bidi_it
.bytepos
) == '\n')))
7945 /* If we are at the beginning of a line/string, we can produce
7946 the next element right away. */
7947 bidi_paragraph_init (it
->paragraph_embedding
, &it
->bidi_it
, true);
7948 bidi_move_to_visually_next (&it
->bidi_it
);
7952 ptrdiff_t orig_bytepos
= it
->bidi_it
.bytepos
;
7954 /* We need to prime the bidi iterator starting at the line's or
7955 string's beginning, before we will be able to produce the
7958 it
->bidi_it
.charpos
= it
->bidi_it
.bytepos
= 0;
7960 it
->bidi_it
.charpos
= find_newline_no_quit (IT_CHARPOS (*it
),
7961 IT_BYTEPOS (*it
), -1,
7962 &it
->bidi_it
.bytepos
);
7963 bidi_paragraph_init (it
->paragraph_embedding
, &it
->bidi_it
, true);
7966 /* Now return to buffer/string position where we were asked
7967 to get the next display element, and produce that. */
7968 bidi_move_to_visually_next (&it
->bidi_it
);
7970 while (it
->bidi_it
.bytepos
!= orig_bytepos
7971 && it
->bidi_it
.charpos
< eob
);
7974 /* Adjust IT's position information to where we ended up. */
7975 if (STRINGP (it
->string
))
7977 IT_STRING_CHARPOS (*it
) = it
->bidi_it
.charpos
;
7978 IT_STRING_BYTEPOS (*it
) = it
->bidi_it
.bytepos
;
7982 IT_CHARPOS (*it
) = it
->bidi_it
.charpos
;
7983 IT_BYTEPOS (*it
) = it
->bidi_it
.bytepos
;
7986 if (STRINGP (it
->string
) || !it
->s
)
7988 ptrdiff_t stop
, charpos
, bytepos
;
7990 if (STRINGP (it
->string
))
7993 stop
= SCHARS (it
->string
);
7994 if (stop
> it
->end_charpos
)
7995 stop
= it
->end_charpos
;
7996 charpos
= IT_STRING_CHARPOS (*it
);
7997 bytepos
= IT_STRING_BYTEPOS (*it
);
8001 stop
= it
->end_charpos
;
8002 charpos
= IT_CHARPOS (*it
);
8003 bytepos
= IT_BYTEPOS (*it
);
8005 if (it
->bidi_it
.scan_dir
< 0)
8007 composition_compute_stop_pos (&it
->cmp_it
, charpos
, bytepos
, stop
,
8012 /* Load IT with the next display element from Lisp string IT->string.
8013 IT->current.string_pos is the current position within the string.
8014 If IT->current.overlay_string_index >= 0, the Lisp string is an
8018 next_element_from_string (struct it
*it
)
8020 struct text_pos position
;
8022 eassert (STRINGP (it
->string
));
8023 eassert (!it
->bidi_p
|| EQ (it
->string
, it
->bidi_it
.string
.lstring
));
8024 eassert (IT_STRING_CHARPOS (*it
) >= 0);
8025 position
= it
->current
.string_pos
;
8027 /* With bidi reordering, the character to display might not be the
8028 character at IT_STRING_CHARPOS. BIDI_IT.FIRST_ELT means
8029 that we were reseat()ed to a new string, whose paragraph
8030 direction is not known. */
8031 if (it
->bidi_p
&& it
->bidi_it
.first_elt
)
8033 get_visually_first_element (it
);
8034 SET_TEXT_POS (position
, IT_STRING_CHARPOS (*it
), IT_STRING_BYTEPOS (*it
));
8037 /* Time to check for invisible text? */
8038 if (IT_STRING_CHARPOS (*it
) < it
->end_charpos
)
8040 if (IT_STRING_CHARPOS (*it
) >= it
->stop_charpos
)
8043 || BIDI_AT_BASE_LEVEL (it
->bidi_it
)
8044 || IT_STRING_CHARPOS (*it
) == it
->stop_charpos
))
8046 /* With bidi non-linear iteration, we could find
8047 ourselves far beyond the last computed stop_charpos,
8048 with several other stop positions in between that we
8049 missed. Scan them all now, in buffer's logical
8050 order, until we find and handle the last stop_charpos
8051 that precedes our current position. */
8052 handle_stop_backwards (it
, it
->stop_charpos
);
8053 return GET_NEXT_DISPLAY_ELEMENT (it
);
8059 /* Take note of the stop position we just moved
8060 across, for when we will move back across it. */
8061 it
->prev_stop
= it
->stop_charpos
;
8062 /* If we are at base paragraph embedding level, take
8063 note of the last stop position seen at this
8065 if (BIDI_AT_BASE_LEVEL (it
->bidi_it
))
8066 it
->base_level_stop
= it
->stop_charpos
;
8070 /* Since a handler may have changed IT->method, we must
8072 return GET_NEXT_DISPLAY_ELEMENT (it
);
8076 /* If we are before prev_stop, we may have overstepped
8077 on our way backwards a stop_pos, and if so, we need
8078 to handle that stop_pos. */
8079 && IT_STRING_CHARPOS (*it
) < it
->prev_stop
8080 /* We can sometimes back up for reasons that have nothing
8081 to do with bidi reordering. E.g., compositions. The
8082 code below is only needed when we are above the base
8083 embedding level, so test for that explicitly. */
8084 && !BIDI_AT_BASE_LEVEL (it
->bidi_it
))
8086 /* If we lost track of base_level_stop, we have no better
8087 place for handle_stop_backwards to start from than string
8088 beginning. This happens, e.g., when we were reseated to
8089 the previous screenful of text by vertical-motion. */
8090 if (it
->base_level_stop
<= 0
8091 || IT_STRING_CHARPOS (*it
) < it
->base_level_stop
)
8092 it
->base_level_stop
= 0;
8093 handle_stop_backwards (it
, it
->base_level_stop
);
8094 return GET_NEXT_DISPLAY_ELEMENT (it
);
8098 if (it
->current
.overlay_string_index
>= 0)
8100 /* Get the next character from an overlay string. In overlay
8101 strings, there is no field width or padding with spaces to
8103 if (IT_STRING_CHARPOS (*it
) >= SCHARS (it
->string
))
8108 else if (CHAR_COMPOSED_P (it
, IT_STRING_CHARPOS (*it
),
8109 IT_STRING_BYTEPOS (*it
),
8110 it
->bidi_it
.scan_dir
< 0
8112 : SCHARS (it
->string
))
8113 && next_element_from_composition (it
))
8117 else if (STRING_MULTIBYTE (it
->string
))
8119 const unsigned char *s
= (SDATA (it
->string
)
8120 + IT_STRING_BYTEPOS (*it
));
8121 it
->c
= string_char_and_length (s
, &it
->len
);
8125 it
->c
= SREF (it
->string
, IT_STRING_BYTEPOS (*it
));
8131 /* Get the next character from a Lisp string that is not an
8132 overlay string. Such strings come from the mode line, for
8133 example. We may have to pad with spaces, or truncate the
8134 string. See also next_element_from_c_string. */
8135 if (IT_STRING_CHARPOS (*it
) >= it
->end_charpos
)
8140 else if (IT_STRING_CHARPOS (*it
) >= it
->string_nchars
)
8142 /* Pad with spaces. */
8143 it
->c
= ' ', it
->len
= 1;
8144 CHARPOS (position
) = BYTEPOS (position
) = -1;
8146 else if (CHAR_COMPOSED_P (it
, IT_STRING_CHARPOS (*it
),
8147 IT_STRING_BYTEPOS (*it
),
8148 it
->bidi_it
.scan_dir
< 0
8150 : it
->string_nchars
)
8151 && next_element_from_composition (it
))
8155 else if (STRING_MULTIBYTE (it
->string
))
8157 const unsigned char *s
= (SDATA (it
->string
)
8158 + IT_STRING_BYTEPOS (*it
));
8159 it
->c
= string_char_and_length (s
, &it
->len
);
8163 it
->c
= SREF (it
->string
, IT_STRING_BYTEPOS (*it
));
8168 /* Record what we have and where it came from. */
8169 it
->what
= IT_CHARACTER
;
8170 it
->object
= it
->string
;
8171 it
->position
= position
;
8176 /* Load IT with next display element from C string IT->s.
8177 IT->string_nchars is the maximum number of characters to return
8178 from the string. IT->end_charpos may be greater than
8179 IT->string_nchars when this function is called, in which case we
8180 may have to return padding spaces. Value is false if end of string
8181 reached, including padding spaces. */
8184 next_element_from_c_string (struct it
*it
)
8186 bool success_p
= true;
8189 eassert (!it
->bidi_p
|| it
->s
== it
->bidi_it
.string
.s
);
8190 it
->what
= IT_CHARACTER
;
8191 BYTEPOS (it
->position
) = CHARPOS (it
->position
) = 0;
8192 it
->object
= make_number (0);
8194 /* With bidi reordering, the character to display might not be the
8195 character at IT_CHARPOS. BIDI_IT.FIRST_ELT means that
8196 we were reseated to a new string, whose paragraph direction is
8198 if (it
->bidi_p
&& it
->bidi_it
.first_elt
)
8199 get_visually_first_element (it
);
8201 /* IT's position can be greater than IT->string_nchars in case a
8202 field width or precision has been specified when the iterator was
8204 if (IT_CHARPOS (*it
) >= it
->end_charpos
)
8206 /* End of the game. */
8210 else if (IT_CHARPOS (*it
) >= it
->string_nchars
)
8212 /* Pad with spaces. */
8213 it
->c
= ' ', it
->len
= 1;
8214 BYTEPOS (it
->position
) = CHARPOS (it
->position
) = -1;
8216 else if (it
->multibyte_p
)
8217 it
->c
= string_char_and_length (it
->s
+ IT_BYTEPOS (*it
), &it
->len
);
8219 it
->c
= it
->s
[IT_BYTEPOS (*it
)], it
->len
= 1;
8225 /* Set up IT to return characters from an ellipsis, if appropriate.
8226 The definition of the ellipsis glyphs may come from a display table
8227 entry. This function fills IT with the first glyph from the
8228 ellipsis if an ellipsis is to be displayed. */
8231 next_element_from_ellipsis (struct it
*it
)
8233 if (it
->selective_display_ellipsis_p
)
8234 setup_for_ellipsis (it
, it
->len
);
8237 /* The face at the current position may be different from the
8238 face we find after the invisible text. Remember what it
8239 was in IT->saved_face_id, and signal that it's there by
8240 setting face_before_selective_p. */
8241 it
->saved_face_id
= it
->face_id
;
8242 it
->method
= GET_FROM_BUFFER
;
8243 it
->object
= it
->w
->contents
;
8244 reseat_at_next_visible_line_start (it
, true);
8245 it
->face_before_selective_p
= true;
8248 return GET_NEXT_DISPLAY_ELEMENT (it
);
8252 /* Deliver an image display element. The iterator IT is already
8253 filled with image information (done in handle_display_prop). Value
8258 next_element_from_image (struct it
*it
)
8260 it
->what
= IT_IMAGE
;
8265 next_element_from_xwidget (struct it
*it
)
8267 it
->what
= IT_XWIDGET
;
8272 /* Fill iterator IT with next display element from a stretch glyph
8273 property. IT->object is the value of the text property. Value is
8277 next_element_from_stretch (struct it
*it
)
8279 it
->what
= IT_STRETCH
;
8283 /* Scan backwards from IT's current position until we find a stop
8284 position, or until BEGV. This is called when we find ourself
8285 before both the last known prev_stop and base_level_stop while
8286 reordering bidirectional text. */
8289 compute_stop_pos_backwards (struct it
*it
)
8291 const int SCAN_BACK_LIMIT
= 1000;
8292 struct text_pos pos
;
8293 struct display_pos save_current
= it
->current
;
8294 struct text_pos save_position
= it
->position
;
8295 ptrdiff_t charpos
= IT_CHARPOS (*it
);
8296 ptrdiff_t where_we_are
= charpos
;
8297 ptrdiff_t save_stop_pos
= it
->stop_charpos
;
8298 ptrdiff_t save_end_pos
= it
->end_charpos
;
8300 eassert (NILP (it
->string
) && !it
->s
);
8301 eassert (it
->bidi_p
);
8305 it
->end_charpos
= min (charpos
+ 1, ZV
);
8306 charpos
= max (charpos
- SCAN_BACK_LIMIT
, BEGV
);
8307 SET_TEXT_POS (pos
, charpos
, CHAR_TO_BYTE (charpos
));
8308 reseat_1 (it
, pos
, false);
8309 compute_stop_pos (it
);
8310 /* We must advance forward, right? */
8311 if (it
->stop_charpos
<= charpos
)
8314 while (charpos
> BEGV
&& it
->stop_charpos
>= it
->end_charpos
);
8316 if (it
->stop_charpos
<= where_we_are
)
8317 it
->prev_stop
= it
->stop_charpos
;
8319 it
->prev_stop
= BEGV
;
8321 it
->current
= save_current
;
8322 it
->position
= save_position
;
8323 it
->stop_charpos
= save_stop_pos
;
8324 it
->end_charpos
= save_end_pos
;
8327 /* Scan forward from CHARPOS in the current buffer/string, until we
8328 find a stop position > current IT's position. Then handle the stop
8329 position before that. This is called when we bump into a stop
8330 position while reordering bidirectional text. CHARPOS should be
8331 the last previously processed stop_pos (or BEGV/0, if none were
8332 processed yet) whose position is less that IT's current
8336 handle_stop_backwards (struct it
*it
, ptrdiff_t charpos
)
8338 bool bufp
= !STRINGP (it
->string
);
8339 ptrdiff_t where_we_are
= (bufp
? IT_CHARPOS (*it
) : IT_STRING_CHARPOS (*it
));
8340 struct display_pos save_current
= it
->current
;
8341 struct text_pos save_position
= it
->position
;
8342 struct text_pos pos1
;
8343 ptrdiff_t next_stop
;
8345 /* Scan in strict logical order. */
8346 eassert (it
->bidi_p
);
8350 it
->prev_stop
= charpos
;
8353 SET_TEXT_POS (pos1
, charpos
, CHAR_TO_BYTE (charpos
));
8354 reseat_1 (it
, pos1
, false);
8357 it
->current
.string_pos
= string_pos (charpos
, it
->string
);
8358 compute_stop_pos (it
);
8359 /* We must advance forward, right? */
8360 if (it
->stop_charpos
<= it
->prev_stop
)
8362 charpos
= it
->stop_charpos
;
8364 while (charpos
<= where_we_are
);
8367 it
->current
= save_current
;
8368 it
->position
= save_position
;
8369 next_stop
= it
->stop_charpos
;
8370 it
->stop_charpos
= it
->prev_stop
;
8372 it
->stop_charpos
= next_stop
;
8375 /* Load IT with the next display element from current_buffer. Value
8376 is false if end of buffer reached. IT->stop_charpos is the next
8377 position at which to stop and check for text properties or buffer
8381 next_element_from_buffer (struct it
*it
)
8383 bool success_p
= true;
8385 eassert (IT_CHARPOS (*it
) >= BEGV
);
8386 eassert (NILP (it
->string
) && !it
->s
);
8387 eassert (!it
->bidi_p
8388 || (EQ (it
->bidi_it
.string
.lstring
, Qnil
)
8389 && it
->bidi_it
.string
.s
== NULL
));
8391 /* With bidi reordering, the character to display might not be the
8392 character at IT_CHARPOS. BIDI_IT.FIRST_ELT means that
8393 we were reseat()ed to a new buffer position, which is potentially
8394 a different paragraph. */
8395 if (it
->bidi_p
&& it
->bidi_it
.first_elt
)
8397 get_visually_first_element (it
);
8398 SET_TEXT_POS (it
->position
, IT_CHARPOS (*it
), IT_BYTEPOS (*it
));
8401 if (IT_CHARPOS (*it
) >= it
->stop_charpos
)
8403 if (IT_CHARPOS (*it
) >= it
->end_charpos
)
8405 bool overlay_strings_follow_p
;
8407 /* End of the game, except when overlay strings follow that
8408 haven't been returned yet. */
8409 if (it
->overlay_strings_at_end_processed_p
)
8410 overlay_strings_follow_p
= false;
8413 it
->overlay_strings_at_end_processed_p
= true;
8414 overlay_strings_follow_p
= get_overlay_strings (it
, 0);
8417 if (overlay_strings_follow_p
)
8418 success_p
= GET_NEXT_DISPLAY_ELEMENT (it
);
8422 it
->position
= it
->current
.pos
;
8426 else if (!(!it
->bidi_p
8427 || BIDI_AT_BASE_LEVEL (it
->bidi_it
)
8428 || IT_CHARPOS (*it
) == it
->stop_charpos
))
8430 /* With bidi non-linear iteration, we could find ourselves
8431 far beyond the last computed stop_charpos, with several
8432 other stop positions in between that we missed. Scan
8433 them all now, in buffer's logical order, until we find
8434 and handle the last stop_charpos that precedes our
8435 current position. */
8436 handle_stop_backwards (it
, it
->stop_charpos
);
8437 it
->ignore_overlay_strings_at_pos_p
= false;
8438 return GET_NEXT_DISPLAY_ELEMENT (it
);
8444 /* Take note of the stop position we just moved across,
8445 for when we will move back across it. */
8446 it
->prev_stop
= it
->stop_charpos
;
8447 /* If we are at base paragraph embedding level, take
8448 note of the last stop position seen at this
8450 if (BIDI_AT_BASE_LEVEL (it
->bidi_it
))
8451 it
->base_level_stop
= it
->stop_charpos
;
8454 it
->ignore_overlay_strings_at_pos_p
= false;
8455 return GET_NEXT_DISPLAY_ELEMENT (it
);
8459 /* If we are before prev_stop, we may have overstepped on
8460 our way backwards a stop_pos, and if so, we need to
8461 handle that stop_pos. */
8462 && IT_CHARPOS (*it
) < it
->prev_stop
8463 /* We can sometimes back up for reasons that have nothing
8464 to do with bidi reordering. E.g., compositions. The
8465 code below is only needed when we are above the base
8466 embedding level, so test for that explicitly. */
8467 && !BIDI_AT_BASE_LEVEL (it
->bidi_it
))
8469 if (it
->base_level_stop
<= 0
8470 || IT_CHARPOS (*it
) < it
->base_level_stop
)
8472 /* If we lost track of base_level_stop, we need to find
8473 prev_stop by looking backwards. This happens, e.g., when
8474 we were reseated to the previous screenful of text by
8476 it
->base_level_stop
= BEGV
;
8477 compute_stop_pos_backwards (it
);
8478 handle_stop_backwards (it
, it
->prev_stop
);
8481 handle_stop_backwards (it
, it
->base_level_stop
);
8482 it
->ignore_overlay_strings_at_pos_p
= false;
8483 return GET_NEXT_DISPLAY_ELEMENT (it
);
8487 /* No face changes, overlays etc. in sight, so just return a
8488 character from current_buffer. */
8492 /* We moved to the next buffer position, so any info about
8493 previously seen overlays is no longer valid. */
8494 it
->ignore_overlay_strings_at_pos_p
= false;
8496 /* Maybe run the redisplay end trigger hook. Performance note:
8497 This doesn't seem to cost measurable time. */
8498 if (it
->redisplay_end_trigger_charpos
8500 && IT_CHARPOS (*it
) >= it
->redisplay_end_trigger_charpos
)
8501 run_redisplay_end_trigger_hook (it
);
8503 stop
= it
->bidi_it
.scan_dir
< 0 ? -1 : it
->end_charpos
;
8504 if (CHAR_COMPOSED_P (it
, IT_CHARPOS (*it
), IT_BYTEPOS (*it
),
8506 && next_element_from_composition (it
))
8511 /* Get the next character, maybe multibyte. */
8512 p
= BYTE_POS_ADDR (IT_BYTEPOS (*it
));
8513 if (it
->multibyte_p
&& !ASCII_CHAR_P (*p
))
8514 it
->c
= STRING_CHAR_AND_LENGTH (p
, it
->len
);
8516 it
->c
= *p
, it
->len
= 1;
8518 /* Record what we have and where it came from. */
8519 it
->what
= IT_CHARACTER
;
8520 it
->object
= it
->w
->contents
;
8521 it
->position
= it
->current
.pos
;
8523 /* Normally we return the character found above, except when we
8524 really want to return an ellipsis for selective display. */
8529 /* A value of selective > 0 means hide lines indented more
8530 than that number of columns. */
8531 if (it
->selective
> 0
8532 && IT_CHARPOS (*it
) + 1 < ZV
8533 && indented_beyond_p (IT_CHARPOS (*it
) + 1,
8534 IT_BYTEPOS (*it
) + 1,
8537 success_p
= next_element_from_ellipsis (it
);
8538 it
->dpvec_char_len
= -1;
8541 else if (it
->c
== '\r' && it
->selective
== -1)
8543 /* A value of selective == -1 means that everything from the
8544 CR to the end of the line is invisible, with maybe an
8545 ellipsis displayed for it. */
8546 success_p
= next_element_from_ellipsis (it
);
8547 it
->dpvec_char_len
= -1;
8552 /* Value is false if end of buffer reached. */
8553 eassert (!success_p
|| it
->what
!= IT_CHARACTER
|| it
->len
> 0);
8558 /* Run the redisplay end trigger hook for IT. */
8561 run_redisplay_end_trigger_hook (struct it
*it
)
8563 /* IT->glyph_row should be non-null, i.e. we should be actually
8564 displaying something, or otherwise we should not run the hook. */
8565 eassert (it
->glyph_row
);
8567 ptrdiff_t charpos
= it
->redisplay_end_trigger_charpos
;
8568 it
->redisplay_end_trigger_charpos
= 0;
8570 /* Since we are *trying* to run these functions, don't try to run
8571 them again, even if they get an error. */
8572 wset_redisplay_end_trigger (it
->w
, Qnil
);
8573 CALLN (Frun_hook_with_args
, Qredisplay_end_trigger_functions
, it
->window
,
8574 make_number (charpos
));
8576 /* Notice if it changed the face of the character we are on. */
8577 handle_face_prop (it
);
8581 /* Deliver a composition display element. Unlike the other
8582 next_element_from_XXX, this function is not registered in the array
8583 get_next_element[]. It is called from next_element_from_buffer and
8584 next_element_from_string when necessary. */
8587 next_element_from_composition (struct it
*it
)
8589 it
->what
= IT_COMPOSITION
;
8590 it
->len
= it
->cmp_it
.nbytes
;
8591 if (STRINGP (it
->string
))
8595 IT_STRING_CHARPOS (*it
) += it
->cmp_it
.nchars
;
8596 IT_STRING_BYTEPOS (*it
) += it
->cmp_it
.nbytes
;
8599 it
->position
= it
->current
.string_pos
;
8600 it
->object
= it
->string
;
8601 it
->c
= composition_update_it (&it
->cmp_it
, IT_STRING_CHARPOS (*it
),
8602 IT_STRING_BYTEPOS (*it
), it
->string
);
8608 IT_CHARPOS (*it
) += it
->cmp_it
.nchars
;
8609 IT_BYTEPOS (*it
) += it
->cmp_it
.nbytes
;
8612 if (it
->bidi_it
.new_paragraph
)
8613 bidi_paragraph_init (it
->paragraph_embedding
, &it
->bidi_it
,
8615 /* Resync the bidi iterator with IT's new position.
8616 FIXME: this doesn't support bidirectional text. */
8617 while (it
->bidi_it
.charpos
< IT_CHARPOS (*it
))
8618 bidi_move_to_visually_next (&it
->bidi_it
);
8622 it
->position
= it
->current
.pos
;
8623 it
->object
= it
->w
->contents
;
8624 it
->c
= composition_update_it (&it
->cmp_it
, IT_CHARPOS (*it
),
8625 IT_BYTEPOS (*it
), Qnil
);
8632 /***********************************************************************
8633 Moving an iterator without producing glyphs
8634 ***********************************************************************/
8636 /* Check if iterator is at a position corresponding to a valid buffer
8637 position after some move_it_ call. */
8639 #define IT_POS_VALID_AFTER_MOVE_P(it) \
8640 ((it)->method != GET_FROM_STRING || IT_STRING_CHARPOS (*it) == 0)
8643 /* Move iterator IT to a specified buffer or X position within one
8644 line on the display without producing glyphs.
8646 OP should be a bit mask including some or all of these bits:
8647 MOVE_TO_X: Stop upon reaching x-position TO_X.
8648 MOVE_TO_POS: Stop upon reaching buffer or string position TO_CHARPOS.
8649 Regardless of OP's value, stop upon reaching the end of the display line.
8651 TO_X is normally a value 0 <= TO_X <= IT->last_visible_x.
8652 This means, in particular, that TO_X includes window's horizontal
8655 The return value has several possible values that
8656 say what condition caused the scan to stop:
8658 MOVE_POS_MATCH_OR_ZV
8659 - when TO_POS or ZV was reached.
8662 -when TO_X was reached before TO_POS or ZV were reached.
8665 - when we reached the end of the display area and the line must
8669 - when we reached the end of the display area and the line is
8673 - when we stopped at a line end, i.e. a newline or a CR and selective
8676 static enum move_it_result
8677 move_it_in_display_line_to (struct it
*it
,
8678 ptrdiff_t to_charpos
, int to_x
,
8679 enum move_operation_enum op
)
8681 enum move_it_result result
= MOVE_UNDEFINED
;
8682 struct glyph_row
*saved_glyph_row
;
8683 struct it wrap_it
, atpos_it
, atx_it
, ppos_it
;
8684 void *wrap_data
= NULL
, *atpos_data
= NULL
, *atx_data
= NULL
;
8685 void *ppos_data
= NULL
;
8686 bool may_wrap
= false;
8687 enum it_method prev_method
= it
->method
;
8688 ptrdiff_t closest_pos UNINIT
;
8689 ptrdiff_t prev_pos
= IT_CHARPOS (*it
);
8690 bool saw_smaller_pos
= prev_pos
< to_charpos
;
8691 bool line_number_pending
= false;
8693 /* Don't produce glyphs in produce_glyphs. */
8694 saved_glyph_row
= it
->glyph_row
;
8695 it
->glyph_row
= NULL
;
8697 /* Use wrap_it to save a copy of IT wherever a word wrap could
8698 occur. Use atpos_it to save a copy of IT at the desired buffer
8699 position, if found, so that we can scan ahead and check if the
8700 word later overshoots the window edge. Use atx_it similarly, for
8706 /* Use ppos_it under bidi reordering to save a copy of IT for the
8707 initial position. We restore that position in IT when we have
8708 scanned the entire display line without finding a match for
8709 TO_CHARPOS and all the character positions are greater than
8710 TO_CHARPOS. We then restart the scan from the initial position,
8711 and stop at CLOSEST_POS, which is a position > TO_CHARPOS that is
8712 the closest to TO_CHARPOS. */
8715 if ((op
& MOVE_TO_POS
) && IT_CHARPOS (*it
) >= to_charpos
)
8717 SAVE_IT (ppos_it
, *it
, ppos_data
);
8718 closest_pos
= IT_CHARPOS (*it
);
8724 #define BUFFER_POS_REACHED_P() \
8725 ((op & MOVE_TO_POS) != 0 \
8726 && BUFFERP (it->object) \
8727 && (IT_CHARPOS (*it) == to_charpos \
8729 || BIDI_AT_BASE_LEVEL (it->bidi_it)) \
8730 && IT_CHARPOS (*it) > to_charpos) \
8731 || (it->what == IT_COMPOSITION \
8732 && ((IT_CHARPOS (*it) > to_charpos \
8733 && to_charpos >= it->cmp_it.charpos) \
8734 || (IT_CHARPOS (*it) < to_charpos \
8735 && to_charpos <= it->cmp_it.charpos)))) \
8736 && (it->method == GET_FROM_BUFFER \
8737 || (it->method == GET_FROM_DISPLAY_VECTOR \
8738 && it->dpvec + it->current.dpvec_index + 1 >= it->dpend)))
8742 /* If line numbers are being displayed, produce a line number.
8743 But don't do that if we are to reach first_visible_x, because
8744 line numbers are not relevant to stuff that is not visible on
8746 if (!((op
&& MOVE_TO_X
) && to_x
== it
->first_visible_x
)
8747 && should_produce_line_number (it
))
8749 if (it
->current_x
== it
->first_visible_x
)
8750 maybe_produce_line_number (it
);
8752 line_number_pending
= true;
8754 /* If there's a line-/wrap-prefix, handle it. */
8755 if (it
->method
== GET_FROM_BUFFER
)
8756 handle_line_prefix (it
);
8759 if (IT_CHARPOS (*it
) < CHARPOS (this_line_min_pos
))
8760 SET_TEXT_POS (this_line_min_pos
, IT_CHARPOS (*it
), IT_BYTEPOS (*it
));
8764 int x
, i
, ascent
= 0, descent
= 0;
8766 /* Utility macro to reset an iterator with x, ascent, and descent. */
8767 #define IT_RESET_X_ASCENT_DESCENT(IT) \
8768 ((IT)->current_x = x, (IT)->max_ascent = ascent, \
8769 (IT)->max_descent = descent)
8771 /* Stop if we move beyond TO_CHARPOS (after an image or a
8772 display string or stretch glyph). */
8773 if ((op
& MOVE_TO_POS
) != 0
8774 && BUFFERP (it
->object
)
8775 && it
->method
== GET_FROM_BUFFER
8777 /* When the iterator is at base embedding level, we
8778 are guaranteed that characters are delivered for
8779 display in strictly increasing order of their
8780 buffer positions. */
8781 || BIDI_AT_BASE_LEVEL (it
->bidi_it
))
8782 && IT_CHARPOS (*it
) > to_charpos
)
8784 && (prev_method
== GET_FROM_IMAGE
8785 || prev_method
== GET_FROM_STRETCH
8786 || prev_method
== GET_FROM_STRING
)
8787 /* Passed TO_CHARPOS from left to right. */
8788 && ((prev_pos
< to_charpos
8789 && IT_CHARPOS (*it
) > to_charpos
)
8790 /* Passed TO_CHARPOS from right to left. */
8791 || (prev_pos
> to_charpos
8792 && IT_CHARPOS (*it
) < to_charpos
)))))
8794 if (it
->line_wrap
!= WORD_WRAP
|| wrap_it
.sp
< 0)
8796 result
= MOVE_POS_MATCH_OR_ZV
;
8799 else if (it
->line_wrap
== WORD_WRAP
&& atpos_it
.sp
< 0)
8800 /* If wrap_it is valid, the current position might be in a
8801 word that is wrapped. So, save the iterator in
8802 atpos_it and continue to see if wrapping happens. */
8803 SAVE_IT (atpos_it
, *it
, atpos_data
);
8806 /* Stop when ZV reached.
8807 We used to stop here when TO_CHARPOS reached as well, but that is
8808 too soon if this glyph does not fit on this line. So we handle it
8809 explicitly below. */
8810 if (!get_next_display_element (it
))
8812 result
= MOVE_POS_MATCH_OR_ZV
;
8816 if (it
->line_wrap
== TRUNCATE
)
8818 /* If it->pixel_width is zero, the last PRODUCE_GLYPHS call
8819 produced something that doesn't consume any screen estate
8820 in the text area, so we don't want to exit the loop at
8821 TO_CHARPOS, before we produce the glyph for that buffer
8822 position. This happens, e.g., when there's an overlay at
8823 TO_CHARPOS that draws a fringe bitmap. */
8824 if (BUFFER_POS_REACHED_P ()
8825 && (it
->pixel_width
> 0
8826 || IT_CHARPOS (*it
) > to_charpos
8827 || it
->area
!= TEXT_AREA
))
8829 result
= MOVE_POS_MATCH_OR_ZV
;
8835 if (it
->line_wrap
== WORD_WRAP
&& it
->area
== TEXT_AREA
)
8837 if (IT_DISPLAYING_WHITESPACE (it
))
8841 /* We have reached a glyph that follows one or more
8842 whitespace characters. If the position is
8843 already found, we are done. */
8844 if (atpos_it
.sp
>= 0)
8846 RESTORE_IT (it
, &atpos_it
, atpos_data
);
8847 result
= MOVE_POS_MATCH_OR_ZV
;
8852 RESTORE_IT (it
, &atx_it
, atx_data
);
8853 result
= MOVE_X_REACHED
;
8856 /* Otherwise, we can wrap here. */
8857 SAVE_IT (wrap_it
, *it
, wrap_data
);
8863 /* Remember the line height for the current line, in case
8864 the next element doesn't fit on the line. */
8865 ascent
= it
->max_ascent
;
8866 descent
= it
->max_descent
;
8868 /* The call to produce_glyphs will get the metrics of the
8869 display element IT is loaded with. Record the x-position
8870 before this display element, in case it doesn't fit on the
8874 PRODUCE_GLYPHS (it
);
8876 if (it
->area
!= TEXT_AREA
)
8878 prev_method
= it
->method
;
8879 if (it
->method
== GET_FROM_BUFFER
)
8880 prev_pos
= IT_CHARPOS (*it
);
8881 set_iterator_to_next (it
, true);
8882 if (IT_CHARPOS (*it
) < CHARPOS (this_line_min_pos
))
8883 SET_TEXT_POS (this_line_min_pos
,
8884 IT_CHARPOS (*it
), IT_BYTEPOS (*it
));
8886 && (op
& MOVE_TO_POS
)
8887 && IT_CHARPOS (*it
) > to_charpos
8888 && IT_CHARPOS (*it
) < closest_pos
)
8889 closest_pos
= IT_CHARPOS (*it
);
8893 /* The number of glyphs we get back in IT->nglyphs will normally
8894 be 1 except when IT->c is (i) a TAB, or (ii) a multi-glyph
8895 character on a terminal frame, or (iii) a line end. For the
8896 second case, IT->nglyphs - 1 padding glyphs will be present.
8897 (On X frames, there is only one glyph produced for a
8898 composite character.)
8900 The behavior implemented below means, for continuation lines,
8901 that as many spaces of a TAB as fit on the current line are
8902 displayed there. For terminal frames, as many glyphs of a
8903 multi-glyph character are displayed in the current line, too.
8904 This is what the old redisplay code did, and we keep it that
8905 way. Under X, the whole shape of a complex character must
8906 fit on the line or it will be completely displayed in the
8909 Note that both for tabs and padding glyphs, all glyphs have
8913 /* More than one glyph or glyph doesn't fit on line. All
8914 glyphs have the same width. */
8915 int single_glyph_width
= it
->pixel_width
/ it
->nglyphs
;
8917 int x_before_this_char
= x
;
8918 int hpos_before_this_char
= it
->hpos
;
8920 for (i
= 0; i
< it
->nglyphs
; ++i
, x
= new_x
)
8922 new_x
= x
+ single_glyph_width
;
8924 /* We want to leave anything reaching TO_X to the caller. */
8925 if ((op
& MOVE_TO_X
) && new_x
> to_x
)
8927 if (BUFFER_POS_REACHED_P ())
8929 if (it
->line_wrap
!= WORD_WRAP
|| wrap_it
.sp
< 0)
8930 goto buffer_pos_reached
;
8931 if (atpos_it
.sp
< 0)
8933 SAVE_IT (atpos_it
, *it
, atpos_data
);
8934 IT_RESET_X_ASCENT_DESCENT (&atpos_it
);
8939 if (it
->line_wrap
!= WORD_WRAP
|| wrap_it
.sp
< 0)
8942 result
= MOVE_X_REACHED
;
8947 SAVE_IT (atx_it
, *it
, atx_data
);
8948 IT_RESET_X_ASCENT_DESCENT (&atx_it
);
8953 if (/* Lines are continued. */
8954 it
->line_wrap
!= TRUNCATE
8955 && (/* And glyph doesn't fit on the line. */
8956 new_x
> it
->last_visible_x
8957 /* Or it fits exactly and we're on a window
8959 || (new_x
== it
->last_visible_x
8960 && FRAME_WINDOW_P (it
->f
)
8961 && ((it
->bidi_p
&& it
->bidi_it
.paragraph_dir
== R2L
)
8962 ? WINDOW_LEFT_FRINGE_WIDTH (it
->w
)
8963 : WINDOW_RIGHT_FRINGE_WIDTH (it
->w
)))))
8965 bool moved_forward
= false;
8967 if (/* IT->hpos == 0 means the very first glyph
8968 doesn't fit on the line, e.g. a wide image. */
8970 || (new_x
== it
->last_visible_x
8971 && FRAME_WINDOW_P (it
->f
)))
8974 it
->current_x
= new_x
;
8976 /* The character's last glyph just barely fits
8978 if (i
== it
->nglyphs
- 1)
8980 /* If this is the destination position,
8981 return a position *before* it in this row,
8982 now that we know it fits in this row. */
8983 if (BUFFER_POS_REACHED_P ())
8985 bool can_wrap
= true;
8987 /* If we are at a whitespace character
8988 that barely fits on this screen line,
8989 but the next character is also
8990 whitespace, we cannot wrap here. */
8991 if (it
->line_wrap
== WORD_WRAP
8994 && IT_OVERFLOW_NEWLINE_INTO_FRINGE (it
))
8997 void *tem_data
= NULL
;
8999 SAVE_IT (tem_it
, *it
, tem_data
);
9000 set_iterator_to_next (it
, true);
9001 if (get_next_display_element (it
)
9002 && IT_DISPLAYING_WHITESPACE (it
))
9004 RESTORE_IT (it
, &tem_it
, tem_data
);
9006 if (it
->line_wrap
!= WORD_WRAP
9008 /* If we've just found whitespace
9009 where we can wrap, effectively
9010 ignore the previous wrap point --
9011 it is no longer relevant, but we
9012 won't have an opportunity to
9013 update it, since we've reached
9014 the edge of this screen line. */
9015 || (may_wrap
&& can_wrap
9016 && IT_OVERFLOW_NEWLINE_INTO_FRINGE (it
)))
9018 it
->hpos
= hpos_before_this_char
;
9019 it
->current_x
= x_before_this_char
;
9020 result
= MOVE_POS_MATCH_OR_ZV
;
9023 if (it
->line_wrap
== WORD_WRAP
9026 SAVE_IT (atpos_it
, *it
, atpos_data
);
9027 atpos_it
.current_x
= x_before_this_char
;
9028 atpos_it
.hpos
= hpos_before_this_char
;
9032 prev_method
= it
->method
;
9033 if (it
->method
== GET_FROM_BUFFER
)
9034 prev_pos
= IT_CHARPOS (*it
);
9035 set_iterator_to_next (it
, true);
9036 if (IT_CHARPOS (*it
) < CHARPOS (this_line_min_pos
))
9037 SET_TEXT_POS (this_line_min_pos
,
9038 IT_CHARPOS (*it
), IT_BYTEPOS (*it
));
9039 /* On graphical terminals, newlines may
9040 "overflow" into the fringe if
9041 overflow-newline-into-fringe is non-nil.
9042 On text terminals, and on graphical
9043 terminals with no right margin, newlines
9044 may overflow into the last glyph on the
9046 if (!FRAME_WINDOW_P (it
->f
)
9048 && it
->bidi_it
.paragraph_dir
== R2L
)
9049 ? WINDOW_LEFT_FRINGE_WIDTH (it
->w
)
9050 : WINDOW_RIGHT_FRINGE_WIDTH (it
->w
)) == 0
9051 || IT_OVERFLOW_NEWLINE_INTO_FRINGE (it
))
9053 if (!get_next_display_element (it
))
9055 result
= MOVE_POS_MATCH_OR_ZV
;
9058 moved_forward
= true;
9059 if (BUFFER_POS_REACHED_P ())
9061 if (ITERATOR_AT_END_OF_LINE_P (it
))
9062 result
= MOVE_POS_MATCH_OR_ZV
;
9064 result
= MOVE_LINE_CONTINUED
;
9067 if (ITERATOR_AT_END_OF_LINE_P (it
)
9068 && (it
->line_wrap
!= WORD_WRAP
9070 || IT_OVERFLOW_NEWLINE_INTO_FRINGE (it
)))
9072 result
= MOVE_NEWLINE_OR_CR
;
9079 IT_RESET_X_ASCENT_DESCENT (it
);
9081 /* If the screen line ends with whitespace, and we
9082 are under word-wrap, don't use wrap_it: it is no
9083 longer relevant, but we won't have an opportunity
9084 to update it, since we are done with this screen
9086 if (may_wrap
&& IT_OVERFLOW_NEWLINE_INTO_FRINGE (it
)
9087 /* If the character after the one which set the
9088 may_wrap flag is also whitespace, we can't
9089 wrap here, since the screen line cannot be
9090 wrapped in the middle of whitespace.
9091 Therefore, wrap_it _is_ relevant in that
9093 && !(moved_forward
&& IT_DISPLAYING_WHITESPACE (it
)))
9095 /* If we've found TO_X, go back there, as we now
9096 know the last word fits on this screen line. */
9097 if ((op
& MOVE_TO_X
) && new_x
== it
->last_visible_x
9100 RESTORE_IT (it
, &atx_it
, atx_data
);
9103 result
= MOVE_X_REACHED
;
9107 else if (wrap_it
.sp
>= 0)
9109 RESTORE_IT (it
, &wrap_it
, wrap_data
);
9114 TRACE_MOVE ((stderr
, "move_it_in: continued at %d\n",
9116 result
= MOVE_LINE_CONTINUED
;
9120 if (BUFFER_POS_REACHED_P ())
9122 if (it
->line_wrap
!= WORD_WRAP
|| wrap_it
.sp
< 0)
9123 goto buffer_pos_reached
;
9124 if (it
->line_wrap
== WORD_WRAP
&& atpos_it
.sp
< 0)
9126 SAVE_IT (atpos_it
, *it
, atpos_data
);
9127 IT_RESET_X_ASCENT_DESCENT (&atpos_it
);
9131 if (new_x
> it
->first_visible_x
)
9133 /* If we have reached the visible portion of the
9134 screen line, produce the line number if needed. */
9135 if (line_number_pending
)
9137 line_number_pending
= false;
9138 it
->current_x
= it
->first_visible_x
;
9139 maybe_produce_line_number (it
);
9140 it
->current_x
+= new_x
- it
->first_visible_x
;
9142 /* Glyph is visible. Increment number of glyphs that
9143 would be displayed. */
9148 if (result
!= MOVE_UNDEFINED
)
9151 else if (BUFFER_POS_REACHED_P ())
9154 IT_RESET_X_ASCENT_DESCENT (it
);
9155 result
= MOVE_POS_MATCH_OR_ZV
;
9158 else if ((op
& MOVE_TO_X
) && it
->current_x
>= to_x
)
9160 /* Stop when TO_X specified and reached. This check is
9161 necessary here because of lines consisting of a line end,
9162 only. The line end will not produce any glyphs and we
9163 would never get MOVE_X_REACHED. */
9164 eassert (it
->nglyphs
== 0);
9165 result
= MOVE_X_REACHED
;
9169 /* Is this a line end? If yes, we're done. */
9170 if (ITERATOR_AT_END_OF_LINE_P (it
))
9172 /* If we are past TO_CHARPOS, but never saw any character
9173 positions smaller than TO_CHARPOS, return
9174 MOVE_POS_MATCH_OR_ZV, like the unidirectional display
9176 if (it
->bidi_p
&& (op
& MOVE_TO_POS
) != 0)
9178 if (!saw_smaller_pos
&& IT_CHARPOS (*it
) > to_charpos
)
9180 if (closest_pos
< ZV
)
9182 RESTORE_IT (it
, &ppos_it
, ppos_data
);
9183 /* Don't recurse if closest_pos is equal to
9184 to_charpos, since we have just tried that. */
9185 if (closest_pos
!= to_charpos
)
9186 move_it_in_display_line_to (it
, closest_pos
, -1,
9188 result
= MOVE_POS_MATCH_OR_ZV
;
9191 goto buffer_pos_reached
;
9193 else if (it
->line_wrap
== WORD_WRAP
&& atpos_it
.sp
>= 0
9194 && IT_CHARPOS (*it
) > to_charpos
)
9195 goto buffer_pos_reached
;
9197 result
= MOVE_NEWLINE_OR_CR
;
9200 result
= MOVE_NEWLINE_OR_CR
;
9201 /* If we've processed the newline, make sure this flag is
9202 reset, as it must only be set when the newline itself is
9204 if (result
== MOVE_NEWLINE_OR_CR
)
9205 it
->constrain_row_ascent_descent_p
= false;
9209 prev_method
= it
->method
;
9210 if (it
->method
== GET_FROM_BUFFER
)
9211 prev_pos
= IT_CHARPOS (*it
);
9213 /* Detect overly-wide wrap-prefixes made of (space ...) display
9214 properties. When such a wrap prefix reaches past the right
9215 margin of the window, we need to avoid the call to
9216 set_iterator_to_next below, so that it->line_wrap is left at
9217 its TRUNCATE value wisely set by handle_line_prefix.
9218 Otherwise, set_iterator_to_next will pop the iterator stack,
9219 restore it->line_wrap, and we might miss the opportunity to
9220 exit the loop and return. */
9221 bool overwide_wrap_prefix
=
9222 CONSP (it
->object
) && EQ (XCAR (it
->object
), Qspace
)
9223 && it
->sp
> 0 && it
->method
== GET_FROM_STRETCH
9224 && it
->current_x
>= it
->last_visible_x
9225 && it
->continuation_lines_width
> 0
9226 && it
->line_wrap
== TRUNCATE
&& it
->stack
[0].line_wrap
!= TRUNCATE
;
9227 /* The current display element has been consumed. Advance
9229 if (!overwide_wrap_prefix
)
9230 set_iterator_to_next (it
, true);
9231 if (IT_CHARPOS (*it
) < CHARPOS (this_line_min_pos
))
9232 SET_TEXT_POS (this_line_min_pos
, IT_CHARPOS (*it
), IT_BYTEPOS (*it
));
9233 if (IT_CHARPOS (*it
) < to_charpos
)
9234 saw_smaller_pos
= true;
9236 && (op
& MOVE_TO_POS
)
9237 && IT_CHARPOS (*it
) >= to_charpos
9238 && IT_CHARPOS (*it
) < closest_pos
)
9239 closest_pos
= IT_CHARPOS (*it
);
9241 /* Stop if lines are truncated and IT's current x-position is
9242 past the right edge of the window now. */
9243 if (it
->line_wrap
== TRUNCATE
9244 && it
->current_x
>= it
->last_visible_x
)
9246 if (!FRAME_WINDOW_P (it
->f
)
9247 || ((it
->bidi_p
&& it
->bidi_it
.paragraph_dir
== R2L
)
9248 ? WINDOW_LEFT_FRINGE_WIDTH (it
->w
)
9249 : WINDOW_RIGHT_FRINGE_WIDTH (it
->w
)) == 0
9250 || IT_OVERFLOW_NEWLINE_INTO_FRINGE (it
))
9252 bool at_eob_p
= false;
9254 if ((at_eob_p
= !get_next_display_element (it
))
9255 || BUFFER_POS_REACHED_P ()
9256 /* If we are past TO_CHARPOS, but never saw any
9257 character positions smaller than TO_CHARPOS,
9258 return MOVE_POS_MATCH_OR_ZV, like the
9259 unidirectional display did. */
9260 || (it
->bidi_p
&& (op
& MOVE_TO_POS
) != 0
9262 && IT_CHARPOS (*it
) > to_charpos
))
9265 && !BUFFER_POS_REACHED_P ()
9266 && !at_eob_p
&& closest_pos
< ZV
)
9268 RESTORE_IT (it
, &ppos_it
, ppos_data
);
9269 if (closest_pos
!= to_charpos
)
9270 move_it_in_display_line_to (it
, closest_pos
, -1,
9273 result
= MOVE_POS_MATCH_OR_ZV
;
9276 if (ITERATOR_AT_END_OF_LINE_P (it
))
9278 result
= MOVE_NEWLINE_OR_CR
;
9282 else if (it
->bidi_p
&& (op
& MOVE_TO_POS
) != 0
9284 && IT_CHARPOS (*it
) > to_charpos
)
9286 if (closest_pos
< ZV
)
9288 RESTORE_IT (it
, &ppos_it
, ppos_data
);
9289 if (closest_pos
!= to_charpos
)
9290 move_it_in_display_line_to (it
, closest_pos
, -1,
9293 result
= MOVE_POS_MATCH_OR_ZV
;
9296 result
= MOVE_LINE_TRUNCATED
;
9299 #undef IT_RESET_X_ASCENT_DESCENT
9302 #undef BUFFER_POS_REACHED_P
9304 /* If we scanned beyond TO_POS, restore the saved iterator either to
9305 the wrap point (if found), or to atpos/atx location. We decide which
9306 data to use to restore the saved iterator state by their X coordinates,
9307 since buffer positions might increase non-monotonically with screen
9308 coordinates due to bidi reordering. */
9309 if (result
== MOVE_LINE_CONTINUED
9310 && it
->line_wrap
== WORD_WRAP
9312 && ((atpos_it
.sp
>= 0 && wrap_it
.current_x
< atpos_it
.current_x
)
9313 || (atx_it
.sp
>= 0 && wrap_it
.current_x
< atx_it
.current_x
)))
9314 RESTORE_IT (it
, &wrap_it
, wrap_data
);
9315 else if (atpos_it
.sp
>= 0)
9316 RESTORE_IT (it
, &atpos_it
, atpos_data
);
9317 else if (atx_it
.sp
>= 0)
9318 RESTORE_IT (it
, &atx_it
, atx_data
);
9323 bidi_unshelve_cache (atpos_data
, true);
9325 bidi_unshelve_cache (atx_data
, true);
9327 bidi_unshelve_cache (wrap_data
, true);
9329 bidi_unshelve_cache (ppos_data
, true);
9331 /* Restore the iterator settings altered at the beginning of this
9333 it
->glyph_row
= saved_glyph_row
;
9337 /* For external use. */
9339 move_it_in_display_line (struct it
*it
,
9340 ptrdiff_t to_charpos
, int to_x
,
9341 enum move_operation_enum op
)
9343 if (it
->line_wrap
== WORD_WRAP
9344 && (op
& MOVE_TO_X
))
9347 void *save_data
= NULL
;
9350 SAVE_IT (save_it
, *it
, save_data
);
9351 skip
= move_it_in_display_line_to (it
, to_charpos
, to_x
, op
);
9352 /* When word-wrap is on, TO_X may lie past the end
9353 of a wrapped line. Then it->current is the
9354 character on the next line, so backtrack to the
9355 space before the wrap point. */
9356 if (skip
== MOVE_LINE_CONTINUED
)
9358 int prev_x
= max (it
->current_x
- 1, 0);
9359 RESTORE_IT (it
, &save_it
, save_data
);
9360 move_it_in_display_line_to
9361 (it
, -1, prev_x
, MOVE_TO_X
);
9364 bidi_unshelve_cache (save_data
, true);
9367 move_it_in_display_line_to (it
, to_charpos
, to_x
, op
);
9371 /* Move IT forward until it satisfies one or more of the criteria in
9372 TO_CHARPOS, TO_X, TO_Y, and TO_VPOS.
9374 OP is a bit-mask that specifies where to stop, and in particular,
9375 which of those four position arguments makes a difference. See the
9376 description of enum move_operation_enum.
9378 If TO_CHARPOS is in invisible text, e.g. a truncated part of a
9379 screen line, this function will set IT to the next position that is
9380 displayed to the right of TO_CHARPOS on the screen.
9382 Return the maximum pixel length of any line scanned but never more
9383 than it.last_visible_x. */
9386 move_it_to (struct it
*it
, ptrdiff_t to_charpos
, int to_x
, int to_y
, int to_vpos
, int op
)
9388 enum move_it_result skip
, skip2
= MOVE_X_REACHED
;
9389 int line_height
, line_start_x
= 0, reached
= 0;
9390 int max_current_x
= 0;
9391 void *backup_data
= NULL
;
9395 if (op
& MOVE_TO_VPOS
)
9397 /* If no TO_CHARPOS and no TO_X specified, stop at the
9398 start of the line TO_VPOS. */
9399 if ((op
& (MOVE_TO_X
| MOVE_TO_POS
)) == 0)
9401 if (it
->vpos
== to_vpos
)
9407 skip
= move_it_in_display_line_to (it
, -1, -1, 0);
9411 /* TO_VPOS >= 0 means stop at TO_X in the line at
9412 TO_VPOS, or at TO_POS, whichever comes first. */
9413 if (it
->vpos
== to_vpos
)
9419 skip
= move_it_in_display_line_to (it
, to_charpos
, to_x
, op
);
9421 if (skip
== MOVE_POS_MATCH_OR_ZV
|| it
->vpos
== to_vpos
)
9426 else if (skip
== MOVE_X_REACHED
&& it
->vpos
!= to_vpos
)
9428 /* We have reached TO_X but not in the line we want. */
9429 skip
= move_it_in_display_line_to (it
, to_charpos
,
9431 if (skip
== MOVE_POS_MATCH_OR_ZV
)
9439 else if (op
& MOVE_TO_Y
)
9441 struct it it_backup
;
9443 if (it
->line_wrap
== WORD_WRAP
)
9444 SAVE_IT (it_backup
, *it
, backup_data
);
9446 /* TO_Y specified means stop at TO_X in the line containing
9447 TO_Y---or at TO_CHARPOS if this is reached first. The
9448 problem is that we can't really tell whether the line
9449 contains TO_Y before we have completely scanned it, and
9450 this may skip past TO_X. What we do is to first scan to
9453 If TO_X is not specified, use a TO_X of zero. The reason
9454 is to make the outcome of this function more predictable.
9455 If we didn't use TO_X == 0, we would stop at the end of
9456 the line which is probably not what a caller would expect
9458 skip
= move_it_in_display_line_to
9459 (it
, to_charpos
, ((op
& MOVE_TO_X
) ? to_x
: 0),
9460 (MOVE_TO_X
| (op
& MOVE_TO_POS
)));
9462 /* If TO_CHARPOS is reached or ZV, we don't have to do more. */
9463 if (skip
== MOVE_POS_MATCH_OR_ZV
)
9465 else if (skip
== MOVE_X_REACHED
)
9467 /* If TO_X was reached, we want to know whether TO_Y is
9468 in the line. We know this is the case if the already
9469 scanned glyphs make the line tall enough. Otherwise,
9470 we must check by scanning the rest of the line. */
9471 line_height
= it
->max_ascent
+ it
->max_descent
;
9472 if (to_y
>= it
->current_y
9473 && to_y
< it
->current_y
+ line_height
)
9478 SAVE_IT (it_backup
, *it
, backup_data
);
9479 TRACE_MOVE ((stderr
, "move_it: from %d\n", IT_CHARPOS (*it
)));
9480 skip2
= move_it_in_display_line_to (it
, to_charpos
, -1,
9482 TRACE_MOVE ((stderr
, "move_it: to %d\n", IT_CHARPOS (*it
)));
9483 line_height
= it
->max_ascent
+ it
->max_descent
;
9484 TRACE_MOVE ((stderr
, "move_it: line_height = %d\n", line_height
));
9486 if (to_y
>= it
->current_y
9487 && to_y
< it
->current_y
+ line_height
)
9489 /* If TO_Y is in this line and TO_X was reached
9490 above, we scanned too far. We have to restore
9491 IT's settings to the ones before skipping. But
9492 keep the more accurate values of max_ascent and
9493 max_descent we've found while skipping the rest
9494 of the line, for the sake of callers, such as
9495 pos_visible_p, that need to know the line
9497 int max_ascent
= it
->max_ascent
;
9498 int max_descent
= it
->max_descent
;
9500 RESTORE_IT (it
, &it_backup
, backup_data
);
9501 it
->max_ascent
= max_ascent
;
9502 it
->max_descent
= max_descent
;
9508 if (skip
== MOVE_POS_MATCH_OR_ZV
)
9514 /* Check whether TO_Y is in this line. */
9515 line_height
= it
->max_ascent
+ it
->max_descent
;
9516 TRACE_MOVE ((stderr
, "move_it: line_height = %d\n", line_height
));
9518 if (to_y
>= it
->current_y
9519 && to_y
< it
->current_y
+ line_height
)
9521 if (to_y
> it
->current_y
)
9522 max_current_x
= max (it
->current_x
, max_current_x
);
9524 /* When word-wrap is on, TO_X may lie past the end
9525 of a wrapped line. Then it->current is the
9526 character on the next line, so backtrack to the
9527 space before the wrap point. */
9528 if (skip
== MOVE_LINE_CONTINUED
9529 && it
->line_wrap
== WORD_WRAP
)
9531 int prev_x
= max (it
->current_x
- 1, 0);
9532 RESTORE_IT (it
, &it_backup
, backup_data
);
9533 skip
= move_it_in_display_line_to
9534 (it
, -1, prev_x
, MOVE_TO_X
);
9543 max_current_x
= max (it
->current_x
, max_current_x
);
9547 else if (BUFFERP (it
->object
)
9548 && (it
->method
== GET_FROM_BUFFER
9549 || it
->method
== GET_FROM_STRETCH
)
9550 && IT_CHARPOS (*it
) >= to_charpos
9551 /* Under bidi iteration, a call to set_iterator_to_next
9552 can scan far beyond to_charpos if the initial
9553 portion of the next line needs to be reordered. In
9554 that case, give move_it_in_display_line_to another
9557 && it
->bidi_it
.scan_dir
== -1))
9558 skip
= MOVE_POS_MATCH_OR_ZV
;
9560 skip
= move_it_in_display_line_to (it
, to_charpos
, -1, MOVE_TO_POS
);
9564 case MOVE_POS_MATCH_OR_ZV
:
9565 max_current_x
= max (it
->current_x
, max_current_x
);
9569 case MOVE_NEWLINE_OR_CR
:
9570 max_current_x
= max (it
->current_x
, max_current_x
);
9571 set_iterator_to_next (it
, true);
9572 it
->continuation_lines_width
= 0;
9575 case MOVE_LINE_TRUNCATED
:
9576 max_current_x
= it
->last_visible_x
;
9577 it
->continuation_lines_width
= 0;
9578 reseat_at_next_visible_line_start (it
, false);
9579 if ((op
& MOVE_TO_POS
) != 0
9580 && IT_CHARPOS (*it
) > to_charpos
)
9587 case MOVE_LINE_CONTINUED
:
9588 max_current_x
= it
->last_visible_x
;
9589 /* For continued lines ending in a tab, some of the glyphs
9590 associated with the tab are displayed on the current
9591 line. Since it->current_x does not include these glyphs,
9592 we use it->last_visible_x instead. */
9595 it
->continuation_lines_width
+= it
->last_visible_x
;
9596 /* When moving by vpos, ensure that the iterator really
9597 advances to the next line (bug#847, bug#969). Fixme:
9598 do we need to do this in other circumstances? */
9599 if (it
->current_x
!= it
->last_visible_x
9600 && (op
& MOVE_TO_VPOS
)
9601 && !(op
& (MOVE_TO_X
| MOVE_TO_POS
)))
9603 line_start_x
= it
->current_x
+ it
->pixel_width
9604 - it
->last_visible_x
;
9605 if (FRAME_WINDOW_P (it
->f
))
9607 struct face
*face
= FACE_FROM_ID (it
->f
, it
->face_id
);
9608 struct font
*face_font
= face
->font
;
9610 /* When display_line produces a continued line
9611 that ends in a TAB, it skips a tab stop that
9612 is closer than the font's space character
9613 width (see x_produce_glyphs where it produces
9614 the stretch glyph which represents a TAB).
9615 We need to reproduce the same logic here. */
9616 eassert (face_font
);
9619 if (line_start_x
< face_font
->space_width
)
9621 += it
->tab_width
* face_font
->space_width
;
9624 set_iterator_to_next (it
, false);
9628 it
->continuation_lines_width
+= it
->current_x
;
9635 /* Reset/increment for the next run. */
9636 recenter_overlay_lists (current_buffer
, IT_CHARPOS (*it
));
9637 it
->current_x
= line_start_x
;
9640 it
->line_number_produced_p
= false;
9641 it
->current_y
+= it
->max_ascent
+ it
->max_descent
;
9643 last_height
= it
->max_ascent
+ it
->max_descent
;
9644 it
->max_ascent
= it
->max_descent
= 0;
9649 /* On text terminals, we may stop at the end of a line in the middle
9650 of a multi-character glyph. If the glyph itself is continued,
9651 i.e. it is actually displayed on the next line, don't treat this
9652 stopping point as valid; move to the next line instead (unless
9653 that brings us offscreen). */
9654 if (!FRAME_WINDOW_P (it
->f
)
9656 && IT_CHARPOS (*it
) == to_charpos
9657 && it
->what
== IT_CHARACTER
9659 && it
->line_wrap
== WINDOW_WRAP
9660 && it
->current_x
== it
->last_visible_x
- 1
9663 && it
->w
->window_end_valid
9664 && it
->vpos
< it
->w
->window_end_vpos
)
9666 it
->continuation_lines_width
+= it
->current_x
;
9667 it
->current_x
= it
->hpos
= it
->max_ascent
= it
->max_descent
= 0;
9668 it
->current_y
+= it
->max_ascent
+ it
->max_descent
;
9670 last_height
= it
->max_ascent
+ it
->max_descent
;
9674 bidi_unshelve_cache (backup_data
, true);
9676 TRACE_MOVE ((stderr
, "move_it_to: reached %d\n", reached
));
9678 return max_current_x
;
9682 /* Move iterator IT backward by a specified y-distance DY, DY >= 0.
9684 If DY > 0, move IT backward at least that many pixels. DY = 0
9685 means move IT backward to the preceding line start or BEGV. This
9686 function may move over more than DY pixels if IT->current_y - DY
9687 ends up in the middle of a line; in this case IT->current_y will be
9688 set to the top of the line moved to. */
9691 move_it_vertically_backward (struct it
*it
, int dy
)
9695 void *it2data
= NULL
, *it3data
= NULL
;
9696 ptrdiff_t start_pos
;
9698 = (it
->last_visible_x
- it
->first_visible_x
) / FRAME_COLUMN_WIDTH (it
->f
);
9699 ptrdiff_t pos_limit
;
9704 start_pos
= IT_CHARPOS (*it
);
9706 /* Estimate how many newlines we must move back. */
9707 nlines
= max (1, dy
/ default_line_pixel_height (it
->w
));
9708 if (it
->line_wrap
== TRUNCATE
|| nchars_per_row
== 0)
9711 pos_limit
= max (start_pos
- nlines
* nchars_per_row
, BEGV
);
9713 /* Set the iterator's position that many lines back. But don't go
9714 back more than NLINES full screen lines -- this wins a day with
9715 buffers which have very long lines. */
9716 while (nlines
-- && IT_CHARPOS (*it
) > pos_limit
)
9717 back_to_previous_visible_line_start (it
);
9719 /* Reseat the iterator here. When moving backward, we don't want
9720 reseat to skip forward over invisible text, set up the iterator
9721 to deliver from overlay strings at the new position etc. So,
9722 use reseat_1 here. */
9723 reseat_1 (it
, it
->current
.pos
, true);
9725 /* We are now surely at a line start. */
9726 it
->current_x
= it
->hpos
= 0; /* FIXME: this is incorrect when bidi
9727 reordering is in effect. */
9728 it
->continuation_lines_width
= 0;
9730 /* Move forward and see what y-distance we moved. First move to the
9731 start of the next line so that we get its height. We need this
9732 height to be able to tell whether we reached the specified
9734 SAVE_IT (it2
, *it
, it2data
);
9735 it2
.max_ascent
= it2
.max_descent
= 0;
9738 move_it_to (&it2
, start_pos
, -1, -1, it2
.vpos
+ 1,
9739 MOVE_TO_POS
| MOVE_TO_VPOS
);
9741 while (!(IT_POS_VALID_AFTER_MOVE_P (&it2
)
9742 /* If we are in a display string which starts at START_POS,
9743 and that display string includes a newline, and we are
9744 right after that newline (i.e. at the beginning of a
9745 display line), exit the loop, because otherwise we will
9746 infloop, since move_it_to will see that it is already at
9747 START_POS and will not move. */
9748 || (it2
.method
== GET_FROM_STRING
9749 && IT_CHARPOS (it2
) == start_pos
9750 && SREF (it2
.string
, IT_STRING_BYTEPOS (it2
) - 1) == '\n')));
9751 eassert (IT_CHARPOS (*it
) >= BEGV
);
9752 SAVE_IT (it3
, it2
, it3data
);
9754 move_it_to (&it2
, start_pos
, -1, -1, -1, MOVE_TO_POS
);
9755 eassert (IT_CHARPOS (*it
) >= BEGV
);
9756 /* H is the actual vertical distance from the position in *IT
9757 and the starting position. */
9758 h
= it2
.current_y
- it
->current_y
;
9759 /* NLINES is the distance in number of lines. */
9760 nlines
= it2
.vpos
- it
->vpos
;
9762 /* Correct IT's y and vpos position
9763 so that they are relative to the starting point. */
9769 /* DY == 0 means move to the start of the screen line. The
9770 value of nlines is > 0 if continuation lines were involved,
9771 or if the original IT position was at start of a line. */
9772 RESTORE_IT (it
, it
, it2data
);
9774 move_it_by_lines (it
, nlines
);
9775 /* The above code moves us to some position NLINES down,
9776 usually to its first glyph (leftmost in an L2R line), but
9777 that's not necessarily the start of the line, under bidi
9778 reordering. We want to get to the character position
9779 that is immediately after the newline of the previous
9782 && !it
->continuation_lines_width
9783 && !STRINGP (it
->string
)
9784 && IT_CHARPOS (*it
) > BEGV
9785 && FETCH_BYTE (IT_BYTEPOS (*it
) - 1) != '\n')
9787 ptrdiff_t cp
= IT_CHARPOS (*it
), bp
= IT_BYTEPOS (*it
);
9790 cp
= find_newline_no_quit (cp
, bp
, -1, NULL
);
9791 move_it_to (it
, cp
, -1, -1, -1, MOVE_TO_POS
);
9793 bidi_unshelve_cache (it3data
, true);
9797 /* The y-position we try to reach, relative to *IT.
9798 Note that H has been subtracted in front of the if-statement. */
9799 int target_y
= it
->current_y
+ h
- dy
;
9800 int y0
= it3
.current_y
;
9804 RESTORE_IT (&it3
, &it3
, it3data
);
9805 y1
= line_bottom_y (&it3
);
9806 line_height
= y1
- y0
;
9807 RESTORE_IT (it
, it
, it2data
);
9808 /* If we did not reach target_y, try to move further backward if
9809 we can. If we moved too far backward, try to move forward. */
9810 if (target_y
< it
->current_y
9811 /* This is heuristic. In a window that's 3 lines high, with
9812 a line height of 13 pixels each, recentering with point
9813 on the bottom line will try to move -39/2 = 19 pixels
9814 backward. Try to avoid moving into the first line. */
9815 && (it
->current_y
- target_y
9816 > min (window_box_height (it
->w
), line_height
* 2 / 3))
9817 && IT_CHARPOS (*it
) > BEGV
)
9819 TRACE_MOVE ((stderr
, " not far enough -> move_vert %d\n",
9820 target_y
- it
->current_y
));
9821 dy
= it
->current_y
- target_y
;
9822 goto move_further_back
;
9824 else if (target_y
>= it
->current_y
+ line_height
9825 && IT_CHARPOS (*it
) < ZV
)
9827 /* Should move forward by at least one line, maybe more.
9829 Note: Calling move_it_by_lines can be expensive on
9830 terminal frames, where compute_motion is used (via
9831 vmotion) to do the job, when there are very long lines
9832 and truncate-lines is nil. That's the reason for
9833 treating terminal frames specially here. */
9835 if (!FRAME_WINDOW_P (it
->f
))
9836 move_it_vertically (it
, target_y
- it
->current_y
);
9841 move_it_by_lines (it
, 1);
9843 while (target_y
>= line_bottom_y (it
) && IT_CHARPOS (*it
) < ZV
);
9850 /* Move IT by a specified amount of pixel lines DY. DY negative means
9851 move backwards. DY = 0 means move to start of screen line. At the
9852 end, IT will be on the start of a screen line. */
9855 move_it_vertically (struct it
*it
, int dy
)
9858 move_it_vertically_backward (it
, -dy
);
9861 TRACE_MOVE ((stderr
, "move_it_v: from %d, %d\n", IT_CHARPOS (*it
), dy
));
9862 move_it_to (it
, ZV
, -1, it
->current_y
+ dy
, -1,
9863 MOVE_TO_POS
| MOVE_TO_Y
);
9864 TRACE_MOVE ((stderr
, "move_it_v: to %d\n", IT_CHARPOS (*it
)));
9866 /* If buffer ends in ZV without a newline, move to the start of
9867 the line to satisfy the post-condition. */
9868 if (IT_CHARPOS (*it
) == ZV
9870 && FETCH_BYTE (IT_BYTEPOS (*it
) - 1) != '\n')
9871 move_it_by_lines (it
, 0);
9876 /* Move iterator IT past the end of the text line it is in. */
9879 move_it_past_eol (struct it
*it
)
9881 enum move_it_result rc
;
9883 rc
= move_it_in_display_line_to (it
, Z
, 0, MOVE_TO_POS
);
9884 if (rc
== MOVE_NEWLINE_OR_CR
)
9885 set_iterator_to_next (it
, false);
9889 /* Move IT by a specified number DVPOS of screen lines down. DVPOS
9890 negative means move up. DVPOS == 0 means move to the start of the
9893 Optimization idea: If we would know that IT->f doesn't use
9894 a face with proportional font, we could be faster for
9895 truncate-lines nil. */
9898 move_it_by_lines (struct it
*it
, ptrdiff_t dvpos
)
9901 /* The commented-out optimization uses vmotion on terminals. This
9902 gives bad results, because elements like it->what, on which
9903 callers such as pos_visible_p rely, aren't updated. */
9904 /* struct position pos;
9905 if (!FRAME_WINDOW_P (it->f))
9907 struct text_pos textpos;
9909 pos = *vmotion (IT_CHARPOS (*it), dvpos, it->w);
9910 SET_TEXT_POS (textpos, pos.bufpos, pos.bytepos);
9911 reseat (it, textpos, true);
9912 it->vpos += pos.vpos;
9913 it->current_y += pos.vpos;
9919 /* DVPOS == 0 means move to the start of the screen line. */
9920 move_it_vertically_backward (it
, 0);
9921 /* Let next call to line_bottom_y calculate real line height. */
9926 move_it_to (it
, -1, -1, -1, it
->vpos
+ dvpos
, MOVE_TO_VPOS
);
9927 if (!IT_POS_VALID_AFTER_MOVE_P (it
))
9929 /* Only move to the next buffer position if we ended up in a
9930 string from display property, not in an overlay string
9931 (before-string or after-string). That is because the
9932 latter don't conceal the underlying buffer position, so
9933 we can ask to move the iterator to the exact position we
9934 are interested in. Note that, even if we are already at
9935 IT_CHARPOS (*it), the call below is not a no-op, as it
9936 will detect that we are at the end of the string, pop the
9937 iterator, and compute it->current_x and it->hpos
9939 move_it_to (it
, IT_CHARPOS (*it
) + it
->string_from_display_prop_p
,
9940 -1, -1, -1, MOVE_TO_POS
);
9946 void *it2data
= NULL
;
9947 ptrdiff_t start_charpos
, i
;
9949 = (it
->last_visible_x
- it
->first_visible_x
) / FRAME_COLUMN_WIDTH (it
->f
);
9950 bool hit_pos_limit
= false;
9951 ptrdiff_t pos_limit
;
9953 /* Start at the beginning of the screen line containing IT's
9954 position. This may actually move vertically backwards,
9955 in case of overlays, so adjust dvpos accordingly. */
9957 move_it_vertically_backward (it
, 0);
9960 /* Go back -DVPOS buffer lines, but no farther than -DVPOS full
9961 screen lines, and reseat the iterator there. */
9962 start_charpos
= IT_CHARPOS (*it
);
9963 if (it
->line_wrap
== TRUNCATE
|| nchars_per_row
== 0)
9966 pos_limit
= max (start_charpos
+ dvpos
* nchars_per_row
, BEGV
);
9968 for (i
= -dvpos
; i
> 0 && IT_CHARPOS (*it
) > pos_limit
; --i
)
9969 back_to_previous_visible_line_start (it
);
9970 if (i
> 0 && IT_CHARPOS (*it
) <= pos_limit
)
9971 hit_pos_limit
= true;
9972 reseat (it
, it
->current
.pos
, true);
9974 /* Move further back if we end up in a string or an image. */
9975 while (!IT_POS_VALID_AFTER_MOVE_P (it
))
9977 /* First try to move to start of display line. */
9979 move_it_vertically_backward (it
, 0);
9981 if (IT_POS_VALID_AFTER_MOVE_P (it
))
9983 /* If start of line is still in string or image,
9984 move further back. */
9985 back_to_previous_visible_line_start (it
);
9986 reseat (it
, it
->current
.pos
, true);
9990 it
->current_x
= it
->hpos
= 0;
9992 /* Above call may have moved too far if continuation lines
9993 are involved. Scan forward and see if it did. */
9994 SAVE_IT (it2
, *it
, it2data
);
9995 it2
.vpos
= it2
.current_y
= 0;
9996 move_it_to (&it2
, start_charpos
, -1, -1, -1, MOVE_TO_POS
);
9997 it
->vpos
-= it2
.vpos
;
9998 it
->current_y
-= it2
.current_y
;
9999 it
->current_x
= it
->hpos
= 0;
10001 /* If we moved too far back, move IT some lines forward. */
10002 if (it2
.vpos
> -dvpos
)
10004 int delta
= it2
.vpos
+ dvpos
;
10006 RESTORE_IT (&it2
, &it2
, it2data
);
10007 SAVE_IT (it2
, *it
, it2data
);
10008 move_it_to (it
, -1, -1, -1, it
->vpos
+ delta
, MOVE_TO_VPOS
);
10009 /* Move back again if we got too far ahead. */
10010 if (IT_CHARPOS (*it
) >= start_charpos
)
10011 RESTORE_IT (it
, &it2
, it2data
);
10013 bidi_unshelve_cache (it2data
, true);
10015 else if (hit_pos_limit
&& pos_limit
> BEGV
10016 && dvpos
< 0 && it2
.vpos
< -dvpos
)
10018 /* If we hit the limit, but still didn't make it far enough
10019 back, that means there's a display string with a newline
10020 covering a large chunk of text, and that caused
10021 back_to_previous_visible_line_start try to go too far.
10022 Punish those who commit such atrocities by going back
10023 until we've reached DVPOS, after lifting the limit, which
10024 could make it slow for very long lines. "If it hurts,
10027 RESTORE_IT (it
, it
, it2data
);
10028 for (i
= -dvpos
; i
> 0; --i
)
10030 back_to_previous_visible_line_start (it
);
10033 reseat_1 (it
, it
->current
.pos
, true);
10036 RESTORE_IT (it
, it
, it2data
);
10041 partial_line_height (struct it
*it_origin
)
10043 int partial_height
;
10044 void *it_data
= NULL
;
10046 SAVE_IT (it
, *it_origin
, it_data
);
10047 move_it_to (&it
, ZV
, -1, it
.last_visible_y
, -1,
10048 MOVE_TO_POS
| MOVE_TO_Y
);
10049 if (it
.what
== IT_EOB
)
10051 int vis_height
= it
.last_visible_y
- it
.current_y
;
10052 int height
= it
.ascent
+ it
.descent
;
10053 partial_height
= (vis_height
< height
) ? vis_height
: 0;
10057 int last_line_y
= it
.current_y
;
10058 move_it_by_lines (&it
, 1);
10059 partial_height
= (it
.current_y
> it
.last_visible_y
)
10060 ? it
.last_visible_y
- last_line_y
: 0;
10062 RESTORE_IT (&it
, &it
, it_data
);
10063 return partial_height
;
10066 /* Return true if IT points into the middle of a display vector. */
10069 in_display_vector_p (struct it
*it
)
10071 return (it
->method
== GET_FROM_DISPLAY_VECTOR
10072 && it
->current
.dpvec_index
> 0
10073 && it
->dpvec
+ it
->current
.dpvec_index
!= it
->dpend
);
10076 DEFUN ("window-text-pixel-size", Fwindow_text_pixel_size
, Swindow_text_pixel_size
, 0, 6, 0,
10077 doc
: /* Return the size of the text of WINDOW's buffer in pixels.
10078 WINDOW must be a live window and defaults to the selected one. The
10079 return value is a cons of the maximum pixel-width of any text line and
10080 the maximum pixel-height of all text lines.
10082 The optional argument FROM, if non-nil, specifies the first text
10083 position and defaults to the minimum accessible position of the buffer.
10084 If FROM is t, use the minimum accessible position that starts a
10085 non-empty line. TO, if non-nil, specifies the last text position and
10086 defaults to the maximum accessible position of the buffer. If TO is t,
10087 use the maximum accessible position that ends a non-empty line.
10089 The optional argument X-LIMIT, if non-nil, specifies the maximum text
10090 width that can be returned. X-LIMIT nil or omitted, means to use the
10091 pixel-width of WINDOW's body; use this if you want to know how high
10092 WINDOW should be become in order to fit all of its buffer's text with
10093 the width of WINDOW unaltered. Use the maximum width WINDOW may assume
10094 if you intend to change WINDOW's width. In any case, text whose
10095 x-coordinate is beyond X-LIMIT is ignored. Since calculating the width
10096 of long lines can take some time, it's always a good idea to make this
10097 argument as small as possible; in particular, if the buffer contains
10098 long lines that shall be truncated anyway.
10100 The optional argument Y-LIMIT, if non-nil, specifies the maximum text
10101 height (excluding the height of the mode- or header-line, if any) that
10102 can be returned. Text lines whose y-coordinate is beyond Y-LIMIT are
10103 ignored. Since calculating the text height of a large buffer can take
10104 some time, it makes sense to specify this argument if the size of the
10105 buffer is large or unknown.
10107 Optional argument MODE-AND-HEADER-LINE nil or omitted means do not
10108 include the height of the mode- or header-line of WINDOW in the return
10109 value. If it is either the symbol `mode-line' or `header-line', include
10110 only the height of that line, if present, in the return value. If t,
10111 include the height of both, if present, in the return value. */)
10112 (Lisp_Object window
, Lisp_Object from
, Lisp_Object to
, Lisp_Object x_limit
,
10113 Lisp_Object y_limit
, Lisp_Object mode_and_header_line
)
10115 struct window
*w
= decode_live_window (window
);
10116 Lisp_Object buffer
= w
->contents
;
10119 struct buffer
*old_b
= NULL
;
10120 ptrdiff_t start
, end
, pos
;
10121 struct text_pos startp
;
10122 void *itdata
= NULL
;
10123 int c
, max_x
= 0, max_y
= 0, x
= 0, y
= 0;
10125 CHECK_BUFFER (buffer
);
10126 b
= XBUFFER (buffer
);
10128 if (b
!= current_buffer
)
10130 old_b
= current_buffer
;
10131 set_buffer_internal (b
);
10136 else if (EQ (from
, Qt
))
10138 start
= pos
= BEGV
;
10139 while ((pos
++ < ZV
) && (c
= FETCH_CHAR (pos
))
10140 && (c
== ' ' || c
== '\t' || c
== '\n' || c
== '\r'))
10142 while ((pos
-- > BEGV
) && (c
= FETCH_CHAR (pos
)) && (c
== ' ' || c
== '\t'))
10147 CHECK_NUMBER_COERCE_MARKER (from
);
10148 start
= min (max (XINT (from
), BEGV
), ZV
);
10153 else if (EQ (to
, Qt
))
10156 while ((pos
-- > BEGV
) && (c
= FETCH_CHAR (pos
))
10157 && (c
== ' ' || c
== '\t' || c
== '\n' || c
== '\r'))
10159 while ((pos
++ < ZV
) && (c
= FETCH_CHAR (pos
)) && (c
== ' ' || c
== '\t'))
10164 CHECK_NUMBER_COERCE_MARKER (to
);
10165 end
= max (start
, min (XINT (to
), ZV
));
10168 if (!NILP (x_limit
) && RANGED_INTEGERP (0, x_limit
, INT_MAX
))
10169 max_x
= XINT (x_limit
);
10171 if (NILP (y_limit
))
10173 else if (RANGED_INTEGERP (0, y_limit
, INT_MAX
))
10174 max_y
= XINT (y_limit
);
10176 itdata
= bidi_shelve_cache ();
10177 SET_TEXT_POS (startp
, start
, CHAR_TO_BYTE (start
));
10178 start_display (&it
, w
, startp
);
10179 /* It makes no sense to measure dimensions of region of text that
10180 crosses the point where bidi reordering changes scan direction.
10181 By using unidirectional movement here we at least support the use
10182 case of measuring regions of text that have a uniformly R2L
10183 directionality, and regions that begin and end in text of the
10184 same directionality. */
10187 int move_op
= MOVE_TO_POS
| MOVE_TO_Y
;
10189 if (!NILP (x_limit
))
10191 it
.last_visible_x
= max_x
;
10192 /* Actually, we never want move_it_to stop at to_x. But to make
10193 sure that move_it_in_display_line_to always moves far enough,
10194 we set to_x to INT_MAX and specify MOVE_TO_X. */
10195 move_op
|= MOVE_TO_X
;
10199 void *it2data
= NULL
;
10201 SAVE_IT (it2
, it
, it2data
);
10203 x
= move_it_to (&it
, end
, to_x
, max_y
, -1, move_op
);
10205 /* We could have a display property at END, in which case asking
10206 move_it_to to stop at END will overshoot and stop at position
10207 after END. So we try again, stopping before END, and account for
10208 the width of the last buffer position manually. */
10209 if (IT_CHARPOS (it
) > end
)
10212 RESTORE_IT (&it
, &it2
, it2data
);
10213 x
= move_it_to (&it
, end
, to_x
, max_y
, -1, move_op
);
10214 /* Add the width of the thing at TO, but only if we didn't
10215 overshoot it; if we did, it is already accounted for. Also,
10216 account for the height of the thing at TO. */
10217 if (IT_CHARPOS (it
) == end
)
10219 x
+= it
.pixel_width
;
10220 it
.max_ascent
= max (it
.max_ascent
, it
.ascent
);
10221 it
.max_descent
= max (it
.max_descent
, it
.descent
);
10224 if (!NILP (x_limit
))
10226 /* Don't return more than X-LIMIT. */
10231 /* Subtract height of header-line which was counted automatically by
10233 y
= it
.current_y
+ it
.max_ascent
+ it
.max_descent
10234 - WINDOW_HEADER_LINE_HEIGHT (w
);
10235 /* Don't return more than Y-LIMIT. */
10239 if (EQ (mode_and_header_line
, Qheader_line
)
10240 || EQ (mode_and_header_line
, Qt
))
10241 /* Re-add height of header-line as requested. */
10242 y
= y
+ WINDOW_HEADER_LINE_HEIGHT (w
);
10244 if (EQ (mode_and_header_line
, Qmode_line
)
10245 || EQ (mode_and_header_line
, Qt
))
10246 /* Add height of mode-line as requested. */
10247 y
= y
+ WINDOW_MODE_LINE_HEIGHT (w
);
10249 bidi_unshelve_cache (itdata
, false);
10252 set_buffer_internal (old_b
);
10254 return Fcons (make_number (x
), make_number (y
));
10257 /***********************************************************************
10259 ***********************************************************************/
10261 /* Return the number of arguments the format string FORMAT needs. */
10264 format_nargs (char const *format
)
10266 ptrdiff_t nargs
= 0;
10267 for (char const *p
= format
; (p
= strchr (p
, '%')); p
++)
10275 /* Add a message with format string FORMAT and formatted arguments
10279 add_to_log (const char *format
, ...)
10282 va_start (ap
, format
);
10283 vadd_to_log (format
, ap
);
10288 vadd_to_log (char const *format
, va_list ap
)
10290 ptrdiff_t form_nargs
= format_nargs (format
);
10291 ptrdiff_t nargs
= 1 + form_nargs
;
10292 Lisp_Object args
[10];
10293 eassert (nargs
<= ARRAYELTS (args
));
10294 AUTO_STRING (args0
, format
);
10296 for (ptrdiff_t i
= 1; i
<= nargs
; i
++)
10297 args
[i
] = va_arg (ap
, Lisp_Object
);
10298 Lisp_Object msg
= Qnil
;
10299 msg
= Fformat_message (nargs
, args
);
10301 ptrdiff_t len
= SBYTES (msg
) + 1;
10303 char *buffer
= SAFE_ALLOCA (len
);
10304 memcpy (buffer
, SDATA (msg
), len
);
10306 message_dolog (buffer
, len
- 1, true, STRING_MULTIBYTE (msg
));
10311 /* Output a newline in the *Messages* buffer if "needs" one. */
10314 message_log_maybe_newline (void)
10316 if (message_log_need_newline
)
10317 message_dolog ("", 0, true, false);
10321 /* Add a string M of length NBYTES to the message log, optionally
10322 terminated with a newline when NLFLAG is true. MULTIBYTE, if
10323 true, means interpret the contents of M as multibyte. This
10324 function calls low-level routines in order to bypass text property
10325 hooks, etc. which might not be safe to run.
10327 This may GC (insert may run before/after change hooks),
10328 so the buffer M must NOT point to a Lisp string. */
10331 message_dolog (const char *m
, ptrdiff_t nbytes
, bool nlflag
, bool multibyte
)
10333 const unsigned char *msg
= (const unsigned char *) m
;
10335 if (!NILP (Vmemory_full
))
10338 if (!NILP (Vmessage_log_max
))
10340 struct buffer
*oldbuf
;
10341 Lisp_Object oldpoint
, oldbegv
, oldzv
;
10342 int old_windows_or_buffers_changed
= windows_or_buffers_changed
;
10343 ptrdiff_t point_at_end
= 0;
10344 ptrdiff_t zv_at_end
= 0;
10345 Lisp_Object old_deactivate_mark
;
10347 old_deactivate_mark
= Vdeactivate_mark
;
10348 oldbuf
= current_buffer
;
10350 /* Ensure the Messages buffer exists, and switch to it.
10351 If we created it, set the major-mode. */
10352 bool newbuffer
= NILP (Fget_buffer (Vmessages_buffer_name
));
10353 Fset_buffer (Fget_buffer_create (Vmessages_buffer_name
));
10355 && !NILP (Ffboundp (intern ("messages-buffer-mode"))))
10356 call0 (intern ("messages-buffer-mode"));
10358 bset_undo_list (current_buffer
, Qt
);
10359 bset_cache_long_scans (current_buffer
, Qnil
);
10361 oldpoint
= message_dolog_marker1
;
10362 set_marker_restricted_both (oldpoint
, Qnil
, PT
, PT_BYTE
);
10363 oldbegv
= message_dolog_marker2
;
10364 set_marker_restricted_both (oldbegv
, Qnil
, BEGV
, BEGV_BYTE
);
10365 oldzv
= message_dolog_marker3
;
10366 set_marker_restricted_both (oldzv
, Qnil
, ZV
, ZV_BYTE
);
10374 BEGV_BYTE
= BEG_BYTE
;
10377 TEMP_SET_PT_BOTH (Z
, Z_BYTE
);
10379 /* Insert the string--maybe converting multibyte to single byte
10380 or vice versa, so that all the text fits the buffer. */
10382 && NILP (BVAR (current_buffer
, enable_multibyte_characters
)))
10388 /* Convert a multibyte string to single-byte
10389 for the *Message* buffer. */
10390 for (i
= 0; i
< nbytes
; i
+= char_bytes
)
10392 c
= string_char_and_length (msg
+ i
, &char_bytes
);
10393 work
[0] = CHAR_TO_BYTE8 (c
);
10394 insert_1_both (work
, 1, 1, true, false, false);
10397 else if (! multibyte
10398 && ! NILP (BVAR (current_buffer
, enable_multibyte_characters
)))
10402 unsigned char str
[MAX_MULTIBYTE_LENGTH
];
10403 /* Convert a single-byte string to multibyte
10404 for the *Message* buffer. */
10405 for (i
= 0; i
< nbytes
; i
++)
10408 MAKE_CHAR_MULTIBYTE (c
);
10409 char_bytes
= CHAR_STRING (c
, str
);
10410 insert_1_both ((char *) str
, 1, char_bytes
, true, false, false);
10414 insert_1_both (m
, chars_in_text (msg
, nbytes
), nbytes
,
10415 true, false, false);
10419 ptrdiff_t this_bol
, this_bol_byte
, prev_bol
, prev_bol_byte
;
10422 insert_1_both ("\n", 1, 1, true, false, false);
10424 scan_newline (Z
, Z_BYTE
, BEG
, BEG_BYTE
, -2, false);
10426 this_bol_byte
= PT_BYTE
;
10428 /* See if this line duplicates the previous one.
10429 If so, combine duplicates. */
10430 if (this_bol
> BEG
)
10432 scan_newline (PT
, PT_BYTE
, BEG
, BEG_BYTE
, -2, false);
10434 prev_bol_byte
= PT_BYTE
;
10436 dups
= message_log_check_duplicate (prev_bol_byte
,
10440 del_range_both (prev_bol
, prev_bol_byte
,
10441 this_bol
, this_bol_byte
, false);
10444 char dupstr
[sizeof " [ times]"
10445 + INT_STRLEN_BOUND (printmax_t
)];
10447 /* If you change this format, don't forget to also
10448 change message_log_check_duplicate. */
10449 int duplen
= sprintf (dupstr
, " [%"pMd
" times]", dups
);
10450 TEMP_SET_PT_BOTH (Z
- 1, Z_BYTE
- 1);
10451 insert_1_both (dupstr
, duplen
, duplen
,
10452 true, false, true);
10457 /* If we have more than the desired maximum number of lines
10458 in the *Messages* buffer now, delete the oldest ones.
10459 This is safe because we don't have undo in this buffer. */
10461 if (NATNUMP (Vmessage_log_max
))
10463 scan_newline (Z
, Z_BYTE
, BEG
, BEG_BYTE
,
10464 -XFASTINT (Vmessage_log_max
) - 1, false);
10465 del_range_both (BEG
, BEG_BYTE
, PT
, PT_BYTE
, false);
10468 BEGV
= marker_position (oldbegv
);
10469 BEGV_BYTE
= marker_byte_position (oldbegv
);
10478 ZV
= marker_position (oldzv
);
10479 ZV_BYTE
= marker_byte_position (oldzv
);
10483 TEMP_SET_PT_BOTH (Z
, Z_BYTE
);
10485 /* We can't do Fgoto_char (oldpoint) because it will run some
10487 TEMP_SET_PT_BOTH (marker_position (oldpoint
),
10488 marker_byte_position (oldpoint
));
10490 unchain_marker (XMARKER (oldpoint
));
10491 unchain_marker (XMARKER (oldbegv
));
10492 unchain_marker (XMARKER (oldzv
));
10494 /* We called insert_1_both above with its 5th argument (PREPARE)
10495 false, which prevents insert_1_both from calling
10496 prepare_to_modify_buffer, which in turns prevents us from
10497 incrementing windows_or_buffers_changed even if *Messages* is
10498 shown in some window. So we must manually set
10499 windows_or_buffers_changed here to make up for that. */
10500 windows_or_buffers_changed
= old_windows_or_buffers_changed
;
10501 bset_redisplay (current_buffer
);
10503 set_buffer_internal (oldbuf
);
10505 message_log_need_newline
= !nlflag
;
10506 Vdeactivate_mark
= old_deactivate_mark
;
10511 /* We are at the end of the buffer after just having inserted a newline.
10512 (Note: We depend on the fact we won't be crossing the gap.)
10513 Check to see if the most recent message looks a lot like the previous one.
10514 Return 0 if different, 1 if the new one should just replace it, or a
10515 value N > 1 if we should also append " [N times]". */
10518 message_log_check_duplicate (ptrdiff_t prev_bol_byte
, ptrdiff_t this_bol_byte
)
10521 ptrdiff_t len
= Z_BYTE
- 1 - this_bol_byte
;
10522 bool seen_dots
= false;
10523 unsigned char *p1
= BUF_BYTE_ADDRESS (current_buffer
, prev_bol_byte
);
10524 unsigned char *p2
= BUF_BYTE_ADDRESS (current_buffer
, this_bol_byte
);
10526 for (i
= 0; i
< len
; i
++)
10528 if (i
>= 3 && p1
[i
- 3] == '.' && p1
[i
- 2] == '.' && p1
[i
- 1] == '.')
10530 if (p1
[i
] != p2
[i
])
10536 if (*p1
++ == ' ' && *p1
++ == '[')
10539 intmax_t n
= strtoimax ((char *) p1
, &pend
, 10);
10540 if (0 < n
&& n
< INTMAX_MAX
&& strncmp (pend
, " times]\n", 8) == 0)
10547 /* Display an echo area message M with a specified length of NBYTES
10548 bytes. The string may include null characters. If M is not a
10549 string, clear out any existing message, and let the mini-buffer
10552 This function cancels echoing. */
10555 message3 (Lisp_Object m
)
10557 clear_message (true, true);
10560 /* First flush out any partial line written with print. */
10561 message_log_maybe_newline ();
10564 ptrdiff_t nbytes
= SBYTES (m
);
10565 bool multibyte
= STRING_MULTIBYTE (m
);
10568 SAFE_ALLOCA_STRING (buffer
, m
);
10569 message_dolog (buffer
, nbytes
, true, multibyte
);
10572 if (! inhibit_message
)
10573 message3_nolog (m
);
10576 /* Log the message M to stderr. Log an empty line if M is not a string. */
10579 message_to_stderr (Lisp_Object m
)
10581 if (noninteractive_need_newline
)
10583 noninteractive_need_newline
= false;
10584 fputc ('\n', stderr
);
10588 Lisp_Object coding_system
= Vlocale_coding_system
;
10591 if (!NILP (Vcoding_system_for_write
))
10592 coding_system
= Vcoding_system_for_write
;
10593 if (!NILP (coding_system
))
10594 s
= code_convert_string_norecord (m
, coding_system
, true);
10598 fwrite (SDATA (s
), SBYTES (s
), 1, stderr
);
10600 if (!cursor_in_echo_area
)
10601 fputc ('\n', stderr
);
10605 /* The non-logging version of message3.
10606 This does not cancel echoing, because it is used for echoing.
10607 Perhaps we need to make a separate function for echoing
10608 and make this cancel echoing. */
10611 message3_nolog (Lisp_Object m
)
10613 struct frame
*sf
= SELECTED_FRAME ();
10615 if (FRAME_INITIAL_P (sf
))
10616 message_to_stderr (m
);
10617 /* Error messages get reported properly by cmd_error, so this must be just an
10618 informative message; if the frame hasn't really been initialized yet, just
10620 else if (INTERACTIVE
&& sf
->glyphs_initialized_p
)
10622 /* Get the frame containing the mini-buffer
10623 that the selected frame is using. */
10624 Lisp_Object mini_window
= FRAME_MINIBUF_WINDOW (sf
);
10625 Lisp_Object frame
= XWINDOW (mini_window
)->frame
;
10626 struct frame
*f
= XFRAME (frame
);
10628 if (FRAME_VISIBLE_P (sf
) && !FRAME_VISIBLE_P (f
))
10629 Fmake_frame_visible (frame
);
10631 if (STRINGP (m
) && SCHARS (m
) > 0)
10634 if (minibuffer_auto_raise
)
10635 Fraise_frame (frame
);
10636 /* Assume we are not echoing.
10637 (If we are, echo_now will override this.) */
10638 echo_message_buffer
= Qnil
;
10641 clear_message (true, true);
10643 do_pending_window_change (false);
10644 echo_area_display (true);
10645 do_pending_window_change (false);
10646 if (FRAME_TERMINAL (f
)->frame_up_to_date_hook
)
10647 (*FRAME_TERMINAL (f
)->frame_up_to_date_hook
) (f
);
10652 /* Display a null-terminated echo area message M. If M is 0, clear
10653 out any existing message, and let the mini-buffer text show through.
10655 The buffer M must continue to exist until after the echo area gets
10656 cleared or some other message gets displayed there. Do not pass
10657 text that is stored in a Lisp string. Do not pass text in a buffer
10658 that was alloca'd. */
10661 message1 (const char *m
)
10663 message3 (m
? build_unibyte_string (m
) : Qnil
);
10667 /* The non-logging counterpart of message1. */
10670 message1_nolog (const char *m
)
10672 message3_nolog (m
? build_unibyte_string (m
) : Qnil
);
10675 /* Display a message M which contains a single %s
10676 which gets replaced with STRING. */
10679 message_with_string (const char *m
, Lisp_Object string
, bool log
)
10681 CHECK_STRING (string
);
10684 if (noninteractive
)
10685 need_message
= !!m
;
10686 else if (!INTERACTIVE
)
10687 need_message
= false;
10690 /* The frame whose minibuffer we're going to display the message on.
10691 It may be larger than the selected frame, so we need
10692 to use its buffer, not the selected frame's buffer. */
10693 Lisp_Object mini_window
;
10694 struct frame
*f
, *sf
= SELECTED_FRAME ();
10696 /* Get the frame containing the minibuffer
10697 that the selected frame is using. */
10698 mini_window
= FRAME_MINIBUF_WINDOW (sf
);
10699 f
= XFRAME (WINDOW_FRAME (XWINDOW (mini_window
)));
10701 /* Error messages get reported properly by cmd_error, so this must be
10702 just an informative message; if the frame hasn't really been
10703 initialized yet, just toss it. */
10704 need_message
= f
->glyphs_initialized_p
;
10709 AUTO_STRING (fmt
, m
);
10710 Lisp_Object msg
= CALLN (Fformat_message
, fmt
, string
);
10712 if (noninteractive
)
10713 message_to_stderr (msg
);
10719 message3_nolog (msg
);
10721 /* Print should start at the beginning of the message
10722 buffer next time. */
10723 message_buf_print
= false;
10729 /* Dump an informative message to the minibuf. If M is 0, clear out
10730 any existing message, and let the mini-buffer text show through.
10732 The message must be safe ASCII (because when Emacs is
10733 non-interactive the message is sent straight to stderr without
10734 encoding first) and the format must not contain ` or ' (because
10735 this function does not account for `text-quoting-style'). If your
10736 message and format do not fit into this category, convert your
10737 arguments to Lisp objects and use Fmessage instead. */
10739 static void ATTRIBUTE_FORMAT_PRINTF (1, 0)
10740 vmessage (const char *m
, va_list ap
)
10742 if (noninteractive
)
10746 if (noninteractive_need_newline
)
10747 putc ('\n', stderr
);
10748 noninteractive_need_newline
= false;
10749 vfprintf (stderr
, m
, ap
);
10750 if (!cursor_in_echo_area
)
10751 fprintf (stderr
, "\n");
10755 else if (INTERACTIVE
)
10757 /* The frame whose mini-buffer we're going to display the message
10758 on. It may be larger than the selected frame, so we need to
10759 use its buffer, not the selected frame's buffer. */
10760 Lisp_Object mini_window
;
10761 struct frame
*f
, *sf
= SELECTED_FRAME ();
10763 /* Get the frame containing the mini-buffer
10764 that the selected frame is using. */
10765 mini_window
= FRAME_MINIBUF_WINDOW (sf
);
10766 f
= XFRAME (WINDOW_FRAME (XWINDOW (mini_window
)));
10768 /* Error messages get reported properly by cmd_error, so this must be
10769 just an informative message; if the frame hasn't really been
10770 initialized yet, just toss it. */
10771 if (f
->glyphs_initialized_p
)
10776 ptrdiff_t maxsize
= FRAME_MESSAGE_BUF_SIZE (f
);
10778 char *message_buf
= SAFE_ALLOCA (maxsize
+ 1);
10780 len
= doprnt (message_buf
, maxsize
, m
, 0, ap
);
10782 message3 (make_string (message_buf
, len
));
10788 /* Print should start at the beginning of the message
10789 buffer next time. */
10790 message_buf_print
= false;
10795 /* See vmessage for restrictions on the text of the message. */
10797 message (const char *m
, ...)
10806 /* Display the current message in the current mini-buffer. This is
10807 only called from error handlers in process.c, and is not time
10811 update_echo_area (void)
10813 if (!NILP (echo_area_buffer
[0]))
10815 Lisp_Object string
;
10816 string
= Fcurrent_message ();
10822 /* Make sure echo area buffers in `echo_buffers' are live.
10823 If they aren't, make new ones. */
10826 ensure_echo_area_buffers (void)
10828 for (int i
= 0; i
< 2; i
++)
10829 if (!BUFFERP (echo_buffer
[i
])
10830 || !BUFFER_LIVE_P (XBUFFER (echo_buffer
[i
])))
10832 Lisp_Object old_buffer
= echo_buffer
[i
];
10833 static char const name_fmt
[] = " *Echo Area %d*";
10834 char name
[sizeof name_fmt
+ INT_STRLEN_BOUND (int)];
10835 AUTO_STRING_WITH_LEN (lname
, name
, sprintf (name
, name_fmt
, i
));
10836 echo_buffer
[i
] = Fget_buffer_create (lname
);
10837 bset_truncate_lines (XBUFFER (echo_buffer
[i
]), Qnil
);
10838 /* to force word wrap in echo area -
10839 it was decided to postpone this*/
10840 /* XBUFFER (echo_buffer[i])->word_wrap = Qt; */
10842 for (int j
= 0; j
< 2; j
++)
10843 if (EQ (old_buffer
, echo_area_buffer
[j
]))
10844 echo_area_buffer
[j
] = echo_buffer
[i
];
10849 /* Call FN with args A1..A2 with either the current or last displayed
10850 echo_area_buffer as current buffer.
10852 WHICH zero means use the current message buffer
10853 echo_area_buffer[0]. If that is nil, choose a suitable buffer
10854 from echo_buffer[] and clear it.
10856 WHICH > 0 means use echo_area_buffer[1]. If that is nil, choose a
10857 suitable buffer from echo_buffer[] and clear it.
10859 If WHICH < 0, set echo_area_buffer[1] to echo_area_buffer[0], so
10860 that the current message becomes the last displayed one, choose a
10861 suitable buffer for echo_area_buffer[0], and clear it.
10863 Value is what FN returns. */
10866 with_echo_area_buffer (struct window
*w
, int which
,
10867 bool (*fn
) (ptrdiff_t, Lisp_Object
),
10868 ptrdiff_t a1
, Lisp_Object a2
)
10870 Lisp_Object buffer
;
10871 bool this_one
, the_other
, clear_buffer_p
, rc
;
10872 ptrdiff_t count
= SPECPDL_INDEX ();
10874 /* If buffers aren't live, make new ones. */
10875 ensure_echo_area_buffers ();
10877 clear_buffer_p
= false;
10880 this_one
= false, the_other
= true;
10881 else if (which
> 0)
10882 this_one
= true, the_other
= false;
10885 this_one
= false, the_other
= true;
10886 clear_buffer_p
= true;
10888 /* We need a fresh one in case the current echo buffer equals
10889 the one containing the last displayed echo area message. */
10890 if (!NILP (echo_area_buffer
[this_one
])
10891 && EQ (echo_area_buffer
[this_one
], echo_area_buffer
[the_other
]))
10892 echo_area_buffer
[this_one
] = Qnil
;
10895 /* Choose a suitable buffer from echo_buffer[] if we don't
10897 if (NILP (echo_area_buffer
[this_one
]))
10899 echo_area_buffer
[this_one
]
10900 = (EQ (echo_area_buffer
[the_other
], echo_buffer
[this_one
])
10901 ? echo_buffer
[the_other
]
10902 : echo_buffer
[this_one
]);
10903 clear_buffer_p
= true;
10906 buffer
= echo_area_buffer
[this_one
];
10908 /* Don't get confused by reusing the buffer used for echoing
10909 for a different purpose. */
10910 if (echo_kboard
== NULL
&& EQ (buffer
, echo_message_buffer
))
10913 record_unwind_protect (unwind_with_echo_area_buffer
,
10914 with_echo_area_buffer_unwind_data (w
));
10916 /* Make the echo area buffer current. Note that for display
10917 purposes, it is not necessary that the displayed window's buffer
10918 == current_buffer, except for text property lookup. So, let's
10919 only set that buffer temporarily here without doing a full
10920 Fset_window_buffer. We must also change w->pointm, though,
10921 because otherwise an assertions in unshow_buffer fails, and Emacs
10923 set_buffer_internal_1 (XBUFFER (buffer
));
10926 wset_buffer (w
, buffer
);
10927 set_marker_both (w
->pointm
, buffer
, BEG
, BEG_BYTE
);
10928 set_marker_both (w
->old_pointm
, buffer
, BEG
, BEG_BYTE
);
10931 bset_undo_list (current_buffer
, Qt
);
10932 bset_read_only (current_buffer
, Qnil
);
10933 specbind (Qinhibit_read_only
, Qt
);
10934 specbind (Qinhibit_modification_hooks
, Qt
);
10936 if (clear_buffer_p
&& Z
> BEG
)
10937 del_range (BEG
, Z
);
10939 eassert (BEGV
>= BEG
);
10940 eassert (ZV
<= Z
&& ZV
>= BEGV
);
10944 eassert (BEGV
>= BEG
);
10945 eassert (ZV
<= Z
&& ZV
>= BEGV
);
10947 unbind_to (count
, Qnil
);
10952 /* Save state that should be preserved around the call to the function
10953 FN called in with_echo_area_buffer. */
10956 with_echo_area_buffer_unwind_data (struct window
*w
)
10959 Lisp_Object vector
, tmp
;
10961 /* Reduce consing by keeping one vector in
10962 Vwith_echo_area_save_vector. */
10963 vector
= Vwith_echo_area_save_vector
;
10964 Vwith_echo_area_save_vector
= Qnil
;
10967 vector
= Fmake_vector (make_number (11), Qnil
);
10969 XSETBUFFER (tmp
, current_buffer
); ASET (vector
, i
, tmp
); ++i
;
10970 ASET (vector
, i
, Vdeactivate_mark
); ++i
;
10971 ASET (vector
, i
, make_number (windows_or_buffers_changed
)); ++i
;
10975 XSETWINDOW (tmp
, w
); ASET (vector
, i
, tmp
); ++i
;
10976 ASET (vector
, i
, w
->contents
); ++i
;
10977 ASET (vector
, i
, make_number (marker_position (w
->pointm
))); ++i
;
10978 ASET (vector
, i
, make_number (marker_byte_position (w
->pointm
))); ++i
;
10979 ASET (vector
, i
, make_number (marker_position (w
->old_pointm
))); ++i
;
10980 ASET (vector
, i
, make_number (marker_byte_position (w
->old_pointm
))); ++i
;
10981 ASET (vector
, i
, make_number (marker_position (w
->start
))); ++i
;
10982 ASET (vector
, i
, make_number (marker_byte_position (w
->start
))); ++i
;
10987 for (; i
< end
; ++i
)
10988 ASET (vector
, i
, Qnil
);
10991 eassert (i
== ASIZE (vector
));
10996 /* Restore global state from VECTOR which was created by
10997 with_echo_area_buffer_unwind_data. */
11000 unwind_with_echo_area_buffer (Lisp_Object vector
)
11002 set_buffer_internal_1 (XBUFFER (AREF (vector
, 0)));
11003 Vdeactivate_mark
= AREF (vector
, 1);
11004 windows_or_buffers_changed
= XFASTINT (AREF (vector
, 2));
11006 if (WINDOWP (AREF (vector
, 3)))
11009 Lisp_Object buffer
;
11011 w
= XWINDOW (AREF (vector
, 3));
11012 buffer
= AREF (vector
, 4);
11014 wset_buffer (w
, buffer
);
11015 set_marker_both (w
->pointm
, buffer
,
11016 XFASTINT (AREF (vector
, 5)),
11017 XFASTINT (AREF (vector
, 6)));
11018 set_marker_both (w
->old_pointm
, buffer
,
11019 XFASTINT (AREF (vector
, 7)),
11020 XFASTINT (AREF (vector
, 8)));
11021 set_marker_both (w
->start
, buffer
,
11022 XFASTINT (AREF (vector
, 9)),
11023 XFASTINT (AREF (vector
, 10)));
11026 Vwith_echo_area_save_vector
= vector
;
11030 /* Set up the echo area for use by print functions. MULTIBYTE_P
11031 means we will print multibyte. */
11034 setup_echo_area_for_printing (bool multibyte_p
)
11036 /* If we can't find an echo area any more, exit. */
11037 if (! FRAME_LIVE_P (XFRAME (selected_frame
)))
11038 Fkill_emacs (Qnil
);
11040 ensure_echo_area_buffers ();
11042 if (!message_buf_print
)
11044 /* A message has been output since the last time we printed.
11045 Choose a fresh echo area buffer. */
11046 if (EQ (echo_area_buffer
[1], echo_buffer
[0]))
11047 echo_area_buffer
[0] = echo_buffer
[1];
11049 echo_area_buffer
[0] = echo_buffer
[0];
11051 /* Switch to that buffer and clear it. */
11052 set_buffer_internal (XBUFFER (echo_area_buffer
[0]));
11053 bset_truncate_lines (current_buffer
, Qnil
);
11057 ptrdiff_t count
= SPECPDL_INDEX ();
11058 specbind (Qinhibit_read_only
, Qt
);
11059 /* Note that undo recording is always disabled. */
11060 del_range (BEG
, Z
);
11061 unbind_to (count
, Qnil
);
11063 TEMP_SET_PT_BOTH (BEG
, BEG_BYTE
);
11065 /* Set up the buffer for the multibyteness we need. We always
11066 set it to be multibyte, except when
11067 unibyte-display-via-language-environment is non-nil and the
11068 buffer from which we are called is unibyte, because in that
11069 case unibyte characters should not be displayed as octal
11071 if (unibyte_display_via_language_environment
11073 && !NILP (BVAR (current_buffer
, enable_multibyte_characters
)))
11074 Fset_buffer_multibyte (Qnil
);
11075 else if (NILP (BVAR (current_buffer
, enable_multibyte_characters
)))
11076 Fset_buffer_multibyte (Qt
);
11078 /* Raise the frame containing the echo area. */
11079 if (minibuffer_auto_raise
)
11081 struct frame
*sf
= SELECTED_FRAME ();
11082 Lisp_Object mini_window
;
11083 mini_window
= FRAME_MINIBUF_WINDOW (sf
);
11084 Fraise_frame (WINDOW_FRAME (XWINDOW (mini_window
)));
11087 message_log_maybe_newline ();
11088 message_buf_print
= true;
11092 if (NILP (echo_area_buffer
[0]))
11094 if (EQ (echo_area_buffer
[1], echo_buffer
[0]))
11095 echo_area_buffer
[0] = echo_buffer
[1];
11097 echo_area_buffer
[0] = echo_buffer
[0];
11100 if (current_buffer
!= XBUFFER (echo_area_buffer
[0]))
11102 /* Someone switched buffers between print requests. */
11103 set_buffer_internal (XBUFFER (echo_area_buffer
[0]));
11104 bset_truncate_lines (current_buffer
, Qnil
);
11110 /* Display an echo area message in window W. Value is true if W's
11111 height is changed. If display_last_displayed_message_p,
11112 display the message that was last displayed, otherwise
11113 display the current message. */
11116 display_echo_area (struct window
*w
)
11118 bool no_message_p
, window_height_changed_p
;
11120 /* Temporarily disable garbage collections while displaying the echo
11121 area. This is done because a GC can print a message itself.
11122 That message would modify the echo area buffer's contents while a
11123 redisplay of the buffer is going on, and seriously confuse
11125 ptrdiff_t count
= inhibit_garbage_collection ();
11127 /* If there is no message, we must call display_echo_area_1
11128 nevertheless because it resizes the window. But we will have to
11129 reset the echo_area_buffer in question to nil at the end because
11130 with_echo_area_buffer will sets it to an empty buffer. */
11131 bool i
= display_last_displayed_message_p
;
11132 /* According to the C99, C11 and C++11 standards, the integral value
11133 of a "bool" is always 0 or 1, so this array access is safe here,
11135 no_message_p
= NILP (echo_area_buffer
[i
]);
11137 window_height_changed_p
11138 = with_echo_area_buffer (w
, display_last_displayed_message_p
,
11139 display_echo_area_1
,
11140 (intptr_t) w
, Qnil
);
11143 echo_area_buffer
[i
] = Qnil
;
11145 unbind_to (count
, Qnil
);
11146 return window_height_changed_p
;
11150 /* Helper for display_echo_area. Display the current buffer which
11151 contains the current echo area message in window W, a mini-window,
11152 a pointer to which is passed in A1. A2..A4 are currently not used.
11153 Change the height of W so that all of the message is displayed.
11154 Value is true if height of W was changed. */
11157 display_echo_area_1 (ptrdiff_t a1
, Lisp_Object a2
)
11160 struct window
*w
= (struct window
*) i1
;
11161 Lisp_Object window
;
11162 struct text_pos start
;
11164 /* We are about to enter redisplay without going through
11165 redisplay_internal, so we need to forget these faces by hand
11167 forget_escape_and_glyphless_faces ();
11169 /* Do this before displaying, so that we have a large enough glyph
11170 matrix for the display. If we can't get enough space for the
11171 whole text, display the last N lines. That works by setting w->start. */
11172 bool window_height_changed_p
= resize_mini_window (w
, false);
11174 /* Use the starting position chosen by resize_mini_window. */
11175 SET_TEXT_POS_FROM_MARKER (start
, w
->start
);
11178 clear_glyph_matrix (w
->desired_matrix
);
11179 XSETWINDOW (window
, w
);
11180 try_window (window
, start
, 0);
11182 return window_height_changed_p
;
11186 /* Resize the echo area window to exactly the size needed for the
11187 currently displayed message, if there is one. If a mini-buffer
11188 is active, don't shrink it. */
11191 resize_echo_area_exactly (void)
11193 if (BUFFERP (echo_area_buffer
[0])
11194 && WINDOWP (echo_area_window
))
11196 struct window
*w
= XWINDOW (echo_area_window
);
11197 Lisp_Object resize_exactly
= (minibuf_level
== 0 ? Qt
: Qnil
);
11198 bool resized_p
= with_echo_area_buffer (w
, 0, resize_mini_window_1
,
11199 (intptr_t) w
, resize_exactly
);
11202 windows_or_buffers_changed
= 42;
11203 update_mode_lines
= 30;
11204 redisplay_internal ();
11210 /* Callback function for with_echo_area_buffer, when used from
11211 resize_echo_area_exactly. A1 contains a pointer to the window to
11212 resize, EXACTLY non-nil means resize the mini-window exactly to the
11213 size of the text displayed. A3 and A4 are not used. Value is what
11214 resize_mini_window returns. */
11217 resize_mini_window_1 (ptrdiff_t a1
, Lisp_Object exactly
)
11220 return resize_mini_window ((struct window
*) i1
, !NILP (exactly
));
11224 /* Resize mini-window W to fit the size of its contents. EXACT_P
11225 means size the window exactly to the size needed. Otherwise, it's
11226 only enlarged until W's buffer is empty.
11228 Set W->start to the right place to begin display. If the whole
11229 contents fit, start at the beginning. Otherwise, start so as
11230 to make the end of the contents appear. This is particularly
11231 important for y-or-n-p, but seems desirable generally.
11233 Value is true if the window height has been changed. */
11236 resize_mini_window (struct window
*w
, bool exact_p
)
11238 struct frame
*f
= XFRAME (w
->frame
);
11239 bool window_height_changed_p
= false;
11241 eassert (MINI_WINDOW_P (w
));
11243 /* By default, start display at the beginning. */
11244 set_marker_both (w
->start
, w
->contents
,
11245 BUF_BEGV (XBUFFER (w
->contents
)),
11246 BUF_BEGV_BYTE (XBUFFER (w
->contents
)));
11248 /* Don't resize windows while redisplaying a window; it would
11249 confuse redisplay functions when the size of the window they are
11250 displaying changes from under them. Such a resizing can happen,
11251 for instance, when which-func prints a long message while
11252 we are running fontification-functions. We're running these
11253 functions with safe_call which binds inhibit-redisplay to t. */
11254 if (!NILP (Vinhibit_redisplay
))
11257 /* Nil means don't try to resize. */
11258 if (NILP (Vresize_mini_windows
)
11259 || (FRAME_X_P (f
) && FRAME_X_OUTPUT (f
) == NULL
))
11262 if (!FRAME_MINIBUF_ONLY_P (f
))
11265 int total_height
= (WINDOW_PIXEL_HEIGHT (XWINDOW (FRAME_ROOT_WINDOW (f
)))
11266 + WINDOW_PIXEL_HEIGHT (w
));
11267 int unit
= FRAME_LINE_HEIGHT (f
);
11268 int height
, max_height
;
11269 struct text_pos start
;
11270 struct buffer
*old_current_buffer
= NULL
;
11272 if (current_buffer
!= XBUFFER (w
->contents
))
11274 old_current_buffer
= current_buffer
;
11275 set_buffer_internal (XBUFFER (w
->contents
));
11278 init_iterator (&it
, w
, BEGV
, BEGV_BYTE
, NULL
, DEFAULT_FACE_ID
);
11280 /* Compute the max. number of lines specified by the user. */
11281 if (FLOATP (Vmax_mini_window_height
))
11282 max_height
= XFLOAT_DATA (Vmax_mini_window_height
) * total_height
;
11283 else if (INTEGERP (Vmax_mini_window_height
))
11284 max_height
= XINT (Vmax_mini_window_height
) * unit
;
11286 max_height
= total_height
/ 4;
11288 /* Correct that max. height if it's bogus. */
11289 max_height
= clip_to_bounds (unit
, max_height
, total_height
);
11291 /* Find out the height of the text in the window. */
11292 if (it
.line_wrap
== TRUNCATE
)
11297 move_it_to (&it
, ZV
, -1, -1, -1, MOVE_TO_POS
);
11298 if (it
.max_ascent
== 0 && it
.max_descent
== 0)
11299 height
= it
.current_y
+ last_height
;
11301 height
= it
.current_y
+ it
.max_ascent
+ it
.max_descent
;
11302 height
-= min (it
.extra_line_spacing
, it
.max_extra_line_spacing
);
11305 /* Compute a suitable window start. */
11306 if (height
> max_height
)
11308 height
= (max_height
/ unit
) * unit
;
11309 init_iterator (&it
, w
, ZV
, ZV_BYTE
, NULL
, DEFAULT_FACE_ID
);
11310 move_it_vertically_backward (&it
, height
- unit
);
11311 start
= it
.current
.pos
;
11314 SET_TEXT_POS (start
, BEGV
, BEGV_BYTE
);
11315 SET_MARKER_FROM_TEXT_POS (w
->start
, start
);
11317 if (EQ (Vresize_mini_windows
, Qgrow_only
))
11319 /* Let it grow only, until we display an empty message, in which
11320 case the window shrinks again. */
11321 if (height
> WINDOW_PIXEL_HEIGHT (w
))
11323 int old_height
= WINDOW_PIXEL_HEIGHT (w
);
11325 FRAME_WINDOWS_FROZEN (f
) = true;
11326 grow_mini_window (w
, height
- WINDOW_PIXEL_HEIGHT (w
), true);
11327 window_height_changed_p
= WINDOW_PIXEL_HEIGHT (w
) != old_height
;
11329 else if (height
< WINDOW_PIXEL_HEIGHT (w
)
11330 && (exact_p
|| BEGV
== ZV
))
11332 int old_height
= WINDOW_PIXEL_HEIGHT (w
);
11334 FRAME_WINDOWS_FROZEN (f
) = false;
11335 shrink_mini_window (w
, true);
11336 window_height_changed_p
= WINDOW_PIXEL_HEIGHT (w
) != old_height
;
11341 /* Always resize to exact size needed. */
11342 if (height
> WINDOW_PIXEL_HEIGHT (w
))
11344 int old_height
= WINDOW_PIXEL_HEIGHT (w
);
11346 FRAME_WINDOWS_FROZEN (f
) = true;
11347 grow_mini_window (w
, height
- WINDOW_PIXEL_HEIGHT (w
), true);
11348 window_height_changed_p
= WINDOW_PIXEL_HEIGHT (w
) != old_height
;
11350 else if (height
< WINDOW_PIXEL_HEIGHT (w
))
11352 int old_height
= WINDOW_PIXEL_HEIGHT (w
);
11354 FRAME_WINDOWS_FROZEN (f
) = false;
11355 shrink_mini_window (w
, true);
11359 FRAME_WINDOWS_FROZEN (f
) = true;
11360 grow_mini_window (w
, height
- WINDOW_PIXEL_HEIGHT (w
), true);
11363 window_height_changed_p
= WINDOW_PIXEL_HEIGHT (w
) != old_height
;
11367 if (old_current_buffer
)
11368 set_buffer_internal (old_current_buffer
);
11371 return window_height_changed_p
;
11375 /* Value is the current message, a string, or nil if there is no
11376 current message. */
11379 current_message (void)
11383 if (!BUFFERP (echo_area_buffer
[0]))
11387 with_echo_area_buffer (0, 0, current_message_1
,
11388 (intptr_t) &msg
, Qnil
);
11390 echo_area_buffer
[0] = Qnil
;
11398 current_message_1 (ptrdiff_t a1
, Lisp_Object a2
)
11401 Lisp_Object
*msg
= (Lisp_Object
*) i1
;
11404 *msg
= make_buffer_string (BEG
, Z
, true);
11411 /* Push the current message on Vmessage_stack for later restoration
11412 by restore_message. Value is true if the current message isn't
11413 empty. This is a relatively infrequent operation, so it's not
11414 worth optimizing. */
11417 push_message (void)
11419 Lisp_Object msg
= current_message ();
11420 Vmessage_stack
= Fcons (msg
, Vmessage_stack
);
11421 return STRINGP (msg
);
11425 /* Restore message display from the top of Vmessage_stack. */
11428 restore_message (void)
11430 eassert (CONSP (Vmessage_stack
));
11431 message3_nolog (XCAR (Vmessage_stack
));
11435 /* Handler for unwind-protect calling pop_message. */
11438 pop_message_unwind (void)
11440 /* Pop the top-most entry off Vmessage_stack. */
11441 eassert (CONSP (Vmessage_stack
));
11442 Vmessage_stack
= XCDR (Vmessage_stack
);
11446 /* Check that Vmessage_stack is nil. Called from emacs.c when Emacs
11447 exits. If the stack is not empty, we have a missing pop_message
11451 check_message_stack (void)
11453 if (!NILP (Vmessage_stack
))
11458 /* Truncate to NCHARS what will be displayed in the echo area the next
11459 time we display it---but don't redisplay it now. */
11462 truncate_echo_area (ptrdiff_t nchars
)
11465 echo_area_buffer
[0] = Qnil
;
11466 else if (!noninteractive
11468 && !NILP (echo_area_buffer
[0]))
11470 struct frame
*sf
= SELECTED_FRAME ();
11471 /* Error messages get reported properly by cmd_error, so this must be
11472 just an informative message; if the frame hasn't really been
11473 initialized yet, just toss it. */
11474 if (sf
->glyphs_initialized_p
)
11475 with_echo_area_buffer (0, 0, truncate_message_1
, nchars
, Qnil
);
11480 /* Helper function for truncate_echo_area. Truncate the current
11481 message to at most NCHARS characters. */
11484 truncate_message_1 (ptrdiff_t nchars
, Lisp_Object a2
)
11486 if (BEG
+ nchars
< Z
)
11487 del_range (BEG
+ nchars
, Z
);
11489 echo_area_buffer
[0] = Qnil
;
11493 /* Set the current message to STRING. */
11496 set_message (Lisp_Object string
)
11498 eassert (STRINGP (string
));
11500 message_enable_multibyte
= STRING_MULTIBYTE (string
);
11502 with_echo_area_buffer (0, -1, set_message_1
, 0, string
);
11503 message_buf_print
= false;
11504 help_echo_showing_p
= false;
11506 if (STRINGP (Vdebug_on_message
)
11507 && STRINGP (string
)
11508 && fast_string_match (Vdebug_on_message
, string
) >= 0)
11509 call_debugger (list2 (Qerror
, string
));
11513 /* Helper function for set_message. First argument is ignored and second
11514 argument has the same meaning as for set_message.
11515 This function is called with the echo area buffer being current. */
11518 set_message_1 (ptrdiff_t a1
, Lisp_Object string
)
11520 eassert (STRINGP (string
));
11522 /* Change multibyteness of the echo buffer appropriately. We always
11523 set it to be multibyte, except when
11524 unibyte-display-via-language-environment is non-nil and the
11525 string to display is unibyte, because in that case unibyte
11526 characters should not be displayed as octal escapes. */
11527 if (!message_enable_multibyte
11528 && unibyte_display_via_language_environment
11529 && !NILP (BVAR (current_buffer
, enable_multibyte_characters
)))
11530 Fset_buffer_multibyte (Qnil
);
11531 else if (NILP (BVAR (current_buffer
, enable_multibyte_characters
)))
11532 Fset_buffer_multibyte (Qt
);
11534 bset_truncate_lines (current_buffer
, message_truncate_lines
? Qt
: Qnil
);
11535 if (!NILP (BVAR (current_buffer
, bidi_display_reordering
)))
11536 bset_bidi_paragraph_direction (current_buffer
, Qleft_to_right
);
11538 /* Insert new message at BEG. */
11539 TEMP_SET_PT_BOTH (BEG
, BEG_BYTE
);
11541 /* This function takes care of single/multibyte conversion.
11542 We just have to ensure that the echo area buffer has the right
11543 setting of enable_multibyte_characters. */
11544 insert_from_string (string
, 0, 0, SCHARS (string
), SBYTES (string
), true);
11550 /* Clear messages. CURRENT_P means clear the current message.
11551 LAST_DISPLAYED_P means clear the message last displayed. */
11554 clear_message (bool current_p
, bool last_displayed_p
)
11558 echo_area_buffer
[0] = Qnil
;
11559 message_cleared_p
= true;
11562 if (last_displayed_p
)
11563 echo_area_buffer
[1] = Qnil
;
11565 message_buf_print
= false;
11568 /* Clear garbaged frames.
11570 This function is used where the old redisplay called
11571 redraw_garbaged_frames which in turn called redraw_frame which in
11572 turn called clear_frame. The call to clear_frame was a source of
11573 flickering. I believe a clear_frame is not necessary. It should
11574 suffice in the new redisplay to invalidate all current matrices,
11575 and ensure a complete redisplay of all windows. */
11578 clear_garbaged_frames (void)
11580 if (frame_garbaged
)
11582 Lisp_Object tail
, frame
;
11583 struct frame
*sf
= SELECTED_FRAME ();
11585 FOR_EACH_FRAME (tail
, frame
)
11587 struct frame
*f
= XFRAME (frame
);
11589 if (FRAME_VISIBLE_P (f
) && FRAME_GARBAGED_P (f
))
11592 /* It makes no sense to redraw a non-selected TTY
11593 frame, since that will actually clear the
11594 selected frame, and might leave the selected
11595 frame with corrupted display, if it happens not
11596 to be marked garbaged. */
11597 && !(f
!= sf
&& (FRAME_TERMCAP_P (f
) || FRAME_MSDOS_P (f
))))
11600 clear_current_matrices (f
);
11602 #if defined (HAVE_WINDOW_SYSTEM) && !defined (HAVE_NS)
11603 x_clear_under_internal_border (f
);
11604 #endif /* HAVE_WINDOW_SYSTEM && !HAVE_NS */
11606 fset_redisplay (f
);
11607 f
->garbaged
= false;
11608 f
->resized_p
= false;
11612 frame_garbaged
= false;
11617 /* Redisplay the echo area of the selected frame. If UPDATE_FRAME_P, update
11621 echo_area_display (bool update_frame_p
)
11623 Lisp_Object mini_window
;
11626 bool window_height_changed_p
= false;
11627 struct frame
*sf
= SELECTED_FRAME ();
11629 mini_window
= FRAME_MINIBUF_WINDOW (sf
);
11630 if (NILP (mini_window
))
11633 w
= XWINDOW (mini_window
);
11634 f
= XFRAME (WINDOW_FRAME (w
));
11636 /* Don't display if frame is invisible or not yet initialized. */
11637 if (!FRAME_VISIBLE_P (f
) || !f
->glyphs_initialized_p
)
11640 #ifdef HAVE_WINDOW_SYSTEM
11641 /* When Emacs starts, selected_frame may be the initial terminal
11642 frame. If we let this through, a message would be displayed on
11644 if (FRAME_INITIAL_P (XFRAME (selected_frame
)))
11646 #endif /* HAVE_WINDOW_SYSTEM */
11648 /* Redraw garbaged frames. */
11649 clear_garbaged_frames ();
11651 if (!NILP (echo_area_buffer
[0]) || minibuf_level
== 0)
11653 echo_area_window
= mini_window
;
11654 window_height_changed_p
= display_echo_area (w
);
11655 w
->must_be_updated_p
= true;
11657 /* Update the display, unless called from redisplay_internal.
11658 Also don't update the screen during redisplay itself. The
11659 update will happen at the end of redisplay, and an update
11660 here could cause confusion. */
11661 if (update_frame_p
&& !redisplaying_p
)
11665 /* If the display update has been interrupted by pending
11666 input, update mode lines in the frame. Due to the
11667 pending input, it might have been that redisplay hasn't
11668 been called, so that mode lines above the echo area are
11669 garbaged. This looks odd, so we prevent it here. */
11670 if (!display_completed
)
11672 n
= redisplay_mode_lines (FRAME_ROOT_WINDOW (f
), false);
11674 #if defined (HAVE_WINDOW_SYSTEM) && !defined (HAVE_NS)
11675 x_clear_under_internal_border (f
);
11676 #endif /* HAVE_WINDOW_SYSTEM && !HAVE_NS */
11680 if (window_height_changed_p
11681 /* Don't do this if Emacs is shutting down. Redisplay
11682 needs to run hooks. */
11683 && !NILP (Vrun_hooks
))
11685 /* Must update other windows. Likewise as in other
11686 cases, don't let this update be interrupted by
11688 ptrdiff_t count
= SPECPDL_INDEX ();
11689 specbind (Qredisplay_dont_pause
, Qt
);
11690 fset_redisplay (f
);
11691 redisplay_internal ();
11692 unbind_to (count
, Qnil
);
11694 else if (FRAME_WINDOW_P (f
) && n
== 0)
11696 /* Window configuration is the same as before.
11697 Can do with a display update of the echo area,
11698 unless we displayed some mode lines. */
11699 update_single_window (w
);
11703 update_frame (f
, true, true);
11705 /* If cursor is in the echo area, make sure that the next
11706 redisplay displays the minibuffer, so that the cursor will
11707 be replaced with what the minibuffer wants. */
11708 if (cursor_in_echo_area
)
11709 wset_redisplay (XWINDOW (mini_window
));
11712 else if (!EQ (mini_window
, selected_window
))
11713 wset_redisplay (XWINDOW (mini_window
));
11715 /* Last displayed message is now the current message. */
11716 echo_area_buffer
[1] = echo_area_buffer
[0];
11717 /* Inform read_char that we're not echoing. */
11718 echo_message_buffer
= Qnil
;
11720 /* Prevent redisplay optimization in redisplay_internal by resetting
11721 this_line_start_pos. This is done because the mini-buffer now
11722 displays the message instead of its buffer text. */
11723 if (EQ (mini_window
, selected_window
))
11724 CHARPOS (this_line_start_pos
) = 0;
11726 if (window_height_changed_p
)
11728 fset_redisplay (f
);
11730 /* If window configuration was changed, frames may have been
11731 marked garbaged. Clear them or we will experience
11732 surprises wrt scrolling.
11733 FIXME: How/why/when? */
11734 clear_garbaged_frames ();
11738 /* True if W's buffer was changed but not saved. */
11741 window_buffer_changed (struct window
*w
)
11743 struct buffer
*b
= XBUFFER (w
->contents
);
11745 eassert (BUFFER_LIVE_P (b
));
11747 return (BUF_SAVE_MODIFF (b
) < BUF_MODIFF (b
)) != w
->last_had_star
;
11750 /* True if W has %c or %C in its mode line and mode line should be updated. */
11753 mode_line_update_needed (struct window
*w
)
11755 return (w
->column_number_displayed
!= -1
11756 && !(PT
== w
->last_point
&& !window_outdated (w
))
11757 && (w
->column_number_displayed
!= current_column ()));
11760 /* True if window start of W is frozen and may not be changed during
11764 window_frozen_p (struct window
*w
)
11766 if (FRAME_WINDOWS_FROZEN (XFRAME (WINDOW_FRAME (w
))))
11768 Lisp_Object window
;
11770 XSETWINDOW (window
, w
);
11771 if (MINI_WINDOW_P (w
))
11773 else if (EQ (window
, selected_window
))
11775 else if (MINI_WINDOW_P (XWINDOW (selected_window
))
11776 && EQ (window
, Vminibuf_scroll_window
))
11777 /* This special window can't be frozen too. */
11785 /***********************************************************************
11786 Mode Lines and Frame Titles
11787 ***********************************************************************/
11789 /* A buffer for constructing non-propertized mode-line strings and
11790 frame titles in it; allocated from the heap in init_xdisp and
11791 resized as needed in store_mode_line_noprop_char. */
11793 static char *mode_line_noprop_buf
;
11795 /* The buffer's end, and a current output position in it. */
11797 static char *mode_line_noprop_buf_end
;
11798 static char *mode_line_noprop_ptr
;
11800 #define MODE_LINE_NOPROP_LEN(start) \
11801 ((mode_line_noprop_ptr - mode_line_noprop_buf) - start)
11804 MODE_LINE_DISPLAY
= 0,
11808 } mode_line_target
;
11810 /* Alist that caches the results of :propertize.
11811 Each element is (PROPERTIZED-STRING . PROPERTY-LIST). */
11812 static Lisp_Object mode_line_proptrans_alist
;
11814 /* List of strings making up the mode-line. */
11815 static Lisp_Object mode_line_string_list
;
11817 /* Base face property when building propertized mode line string. */
11818 static Lisp_Object mode_line_string_face
;
11819 static Lisp_Object mode_line_string_face_prop
;
11822 /* Unwind data for mode line strings */
11824 static Lisp_Object Vmode_line_unwind_vector
;
11827 format_mode_line_unwind_data (struct frame
*target_frame
,
11828 struct buffer
*obuf
,
11830 bool save_proptrans
)
11832 Lisp_Object vector
, tmp
;
11834 /* Reduce consing by keeping one vector in
11835 Vwith_echo_area_save_vector. */
11836 vector
= Vmode_line_unwind_vector
;
11837 Vmode_line_unwind_vector
= Qnil
;
11840 vector
= Fmake_vector (make_number (10), Qnil
);
11842 ASET (vector
, 0, make_number (mode_line_target
));
11843 ASET (vector
, 1, make_number (MODE_LINE_NOPROP_LEN (0)));
11844 ASET (vector
, 2, mode_line_string_list
);
11845 ASET (vector
, 3, save_proptrans
? mode_line_proptrans_alist
: Qt
);
11846 ASET (vector
, 4, mode_line_string_face
);
11847 ASET (vector
, 5, mode_line_string_face_prop
);
11850 XSETBUFFER (tmp
, obuf
);
11853 ASET (vector
, 6, tmp
);
11854 ASET (vector
, 7, owin
);
11857 /* Similarly to `with-selected-window', if the operation selects
11858 a window on another frame, we must restore that frame's
11859 selected window, and (for a tty) the top-frame. */
11860 ASET (vector
, 8, target_frame
->selected_window
);
11861 if (FRAME_TERMCAP_P (target_frame
))
11862 ASET (vector
, 9, FRAME_TTY (target_frame
)->top_frame
);
11869 unwind_format_mode_line (Lisp_Object vector
)
11871 Lisp_Object old_window
= AREF (vector
, 7);
11872 Lisp_Object target_frame_window
= AREF (vector
, 8);
11873 Lisp_Object old_top_frame
= AREF (vector
, 9);
11875 mode_line_target
= XINT (AREF (vector
, 0));
11876 mode_line_noprop_ptr
= mode_line_noprop_buf
+ XINT (AREF (vector
, 1));
11877 mode_line_string_list
= AREF (vector
, 2);
11878 if (! EQ (AREF (vector
, 3), Qt
))
11879 mode_line_proptrans_alist
= AREF (vector
, 3);
11880 mode_line_string_face
= AREF (vector
, 4);
11881 mode_line_string_face_prop
= AREF (vector
, 5);
11883 /* Select window before buffer, since it may change the buffer. */
11884 if (!NILP (old_window
))
11886 /* If the operation that we are unwinding had selected a window
11887 on a different frame, reset its frame-selected-window. For a
11888 text terminal, reset its top-frame if necessary. */
11889 if (!NILP (target_frame_window
))
11892 = WINDOW_FRAME (XWINDOW (target_frame_window
));
11894 if (!EQ (frame
, WINDOW_FRAME (XWINDOW (old_window
))))
11895 Fselect_window (target_frame_window
, Qt
);
11897 if (!NILP (old_top_frame
) && !EQ (old_top_frame
, frame
))
11898 Fselect_frame (old_top_frame
, Qt
);
11901 Fselect_window (old_window
, Qt
);
11904 if (!NILP (AREF (vector
, 6)))
11906 set_buffer_internal_1 (XBUFFER (AREF (vector
, 6)));
11907 ASET (vector
, 6, Qnil
);
11910 Vmode_line_unwind_vector
= vector
;
11914 /* Store a single character C for the frame title in mode_line_noprop_buf.
11915 Re-allocate mode_line_noprop_buf if necessary. */
11918 store_mode_line_noprop_char (char c
)
11920 /* If output position has reached the end of the allocated buffer,
11921 increase the buffer's size. */
11922 if (mode_line_noprop_ptr
== mode_line_noprop_buf_end
)
11924 ptrdiff_t len
= MODE_LINE_NOPROP_LEN (0);
11925 ptrdiff_t size
= len
;
11926 mode_line_noprop_buf
=
11927 xpalloc (mode_line_noprop_buf
, &size
, 1, STRING_BYTES_BOUND
, 1);
11928 mode_line_noprop_buf_end
= mode_line_noprop_buf
+ size
;
11929 mode_line_noprop_ptr
= mode_line_noprop_buf
+ len
;
11932 *mode_line_noprop_ptr
++ = c
;
11936 /* Store part of a frame title in mode_line_noprop_buf, beginning at
11937 mode_line_noprop_ptr. STRING is the string to store. Do not copy
11938 characters that yield more columns than PRECISION; PRECISION <= 0
11939 means copy the whole string. Pad with spaces until FIELD_WIDTH
11940 number of characters have been copied; FIELD_WIDTH <= 0 means don't
11941 pad. Called from display_mode_element when it is used to build a
11945 store_mode_line_noprop (const char *string
, int field_width
, int precision
)
11947 const unsigned char *str
= (const unsigned char *) string
;
11949 ptrdiff_t dummy
, nbytes
;
11951 /* Copy at most PRECISION chars from STR. */
11952 nbytes
= strlen (string
);
11953 n
+= c_string_width (str
, nbytes
, precision
, &dummy
, &nbytes
);
11955 store_mode_line_noprop_char (*str
++);
11957 /* Fill up with spaces until FIELD_WIDTH reached. */
11958 while (field_width
> 0
11959 && n
< field_width
)
11961 store_mode_line_noprop_char (' ');
11968 /***********************************************************************
11970 ***********************************************************************/
11972 #ifdef HAVE_WINDOW_SYSTEM
11974 /* Set the title of FRAME, if it has changed. The title format is
11975 Vicon_title_format if FRAME is iconified, otherwise it is
11976 frame_title_format. */
11979 x_consider_frame_title (Lisp_Object frame
)
11981 struct frame
*f
= XFRAME (frame
);
11983 if ((FRAME_WINDOW_P (f
)
11984 || FRAME_MINIBUF_ONLY_P (f
)
11985 || f
->explicit_name
)
11986 && !FRAME_TOOLTIP_P (f
))
11988 /* Do we have more than one visible frame on this X display? */
11989 Lisp_Object tail
, other_frame
, fmt
;
11990 ptrdiff_t title_start
;
11994 ptrdiff_t count
= SPECPDL_INDEX ();
11996 FOR_EACH_FRAME (tail
, other_frame
)
11998 struct frame
*tf
= XFRAME (other_frame
);
12001 && FRAME_KBOARD (tf
) == FRAME_KBOARD (f
)
12002 && !FRAME_MINIBUF_ONLY_P (tf
)
12003 && !FRAME_PARENT_FRAME (tf
)
12004 && !FRAME_TOOLTIP_P (tf
)
12005 && (FRAME_VISIBLE_P (tf
) || FRAME_ICONIFIED_P (tf
)))
12009 /* Set global variable indicating that multiple frames exist. */
12010 multiple_frames
= CONSP (tail
);
12012 /* Switch to the buffer of selected window of the frame. Set up
12013 mode_line_target so that display_mode_element will output into
12014 mode_line_noprop_buf; then display the title. */
12015 record_unwind_protect (unwind_format_mode_line
,
12016 format_mode_line_unwind_data
12017 (f
, current_buffer
, selected_window
, false));
12018 /* select-frame calls resize_mini_window, which could resize the
12019 mini-window and by that undo the effect of this redisplay
12020 cycle wrt minibuffer and echo-area display. Binding
12021 inhibit-redisplay to t makes the call to resize_mini_window a
12022 no-op, thus avoiding the adverse side effects. */
12023 specbind (Qinhibit_redisplay
, Qt
);
12025 Fselect_window (f
->selected_window
, Qt
);
12026 set_buffer_internal_1
12027 (XBUFFER (XWINDOW (f
->selected_window
)->contents
));
12028 fmt
= FRAME_ICONIFIED_P (f
) ? Vicon_title_format
: Vframe_title_format
;
12030 mode_line_target
= MODE_LINE_TITLE
;
12031 title_start
= MODE_LINE_NOPROP_LEN (0);
12032 init_iterator (&it
, XWINDOW (f
->selected_window
), -1, -1,
12033 NULL
, DEFAULT_FACE_ID
);
12034 display_mode_element (&it
, 0, -1, -1, fmt
, Qnil
, false);
12035 len
= MODE_LINE_NOPROP_LEN (title_start
);
12036 title
= mode_line_noprop_buf
+ title_start
;
12037 unbind_to (count
, Qnil
);
12039 /* Set the title only if it's changed. This avoids consing in
12040 the common case where it hasn't. (If it turns out that we've
12041 already wasted too much time by walking through the list with
12042 display_mode_element, then we might need to optimize at a
12043 higher level than this.) */
12044 if (! STRINGP (f
->name
)
12045 || SBYTES (f
->name
) != len
12046 || memcmp (title
, SDATA (f
->name
), len
) != 0)
12047 x_implicitly_set_name (f
, make_string (title
, len
), Qnil
);
12051 #endif /* not HAVE_WINDOW_SYSTEM */
12054 /***********************************************************************
12056 ***********************************************************************/
12058 /* True if we will not redisplay all visible windows. */
12059 #define REDISPLAY_SOME_P() \
12060 ((windows_or_buffers_changed == 0 \
12061 || windows_or_buffers_changed == REDISPLAY_SOME) \
12062 && (update_mode_lines == 0 \
12063 || update_mode_lines == REDISPLAY_SOME))
12065 /* Prepare for redisplay by updating menu-bar item lists when
12066 appropriate. This can call eval. */
12069 prepare_menu_bars (void)
12071 bool all_windows
= windows_or_buffers_changed
|| update_mode_lines
;
12072 bool some_windows
= REDISPLAY_SOME_P ();
12074 if (FUNCTIONP (Vpre_redisplay_function
))
12076 Lisp_Object windows
= all_windows
? Qt
: Qnil
;
12077 if (all_windows
&& some_windows
)
12079 Lisp_Object ws
= window_list ();
12080 for (windows
= Qnil
; CONSP (ws
); ws
= XCDR (ws
))
12082 Lisp_Object
this = XCAR (ws
);
12083 struct window
*w
= XWINDOW (this);
12085 || XFRAME (w
->frame
)->redisplay
12086 || XBUFFER (w
->contents
)->text
->redisplay
)
12088 windows
= Fcons (this, windows
);
12092 safe__call1 (true, Vpre_redisplay_function
, windows
);
12095 /* Update all frame titles based on their buffer names, etc. We do
12096 this before the menu bars so that the buffer-menu will show the
12097 up-to-date frame titles. */
12098 #ifdef HAVE_WINDOW_SYSTEM
12101 Lisp_Object tail
, frame
;
12103 FOR_EACH_FRAME (tail
, frame
)
12105 struct frame
*f
= XFRAME (frame
);
12106 struct window
*w
= XWINDOW (FRAME_SELECTED_WINDOW (f
));
12110 && !XBUFFER (w
->contents
)->text
->redisplay
)
12113 if (!FRAME_TOOLTIP_P (f
)
12114 && !FRAME_PARENT_FRAME (f
)
12115 && (FRAME_ICONIFIED_P (f
)
12116 || FRAME_VISIBLE_P (f
) == 1
12117 /* Exclude TTY frames that are obscured because they
12118 are not the top frame on their console. This is
12119 because x_consider_frame_title actually switches
12120 to the frame, which for TTY frames means it is
12121 marked as garbaged, and will be completely
12122 redrawn on the next redisplay cycle. This causes
12123 TTY frames to be completely redrawn, when there
12124 are more than one of them, even though nothing
12125 should be changed on display. */
12126 || (FRAME_VISIBLE_P (f
) == 2 && FRAME_WINDOW_P (f
))))
12127 x_consider_frame_title (frame
);
12130 #endif /* HAVE_WINDOW_SYSTEM */
12132 /* Update the menu bar item lists, if appropriate. This has to be
12133 done before any actual redisplay or generation of display lines. */
12137 Lisp_Object tail
, frame
;
12138 ptrdiff_t count
= SPECPDL_INDEX ();
12139 /* True means that update_menu_bar has run its hooks
12140 so any further calls to update_menu_bar shouldn't do so again. */
12141 bool menu_bar_hooks_run
= false;
12143 record_unwind_save_match_data ();
12145 FOR_EACH_FRAME (tail
, frame
)
12147 struct frame
*f
= XFRAME (frame
);
12148 struct window
*w
= XWINDOW (FRAME_SELECTED_WINDOW (f
));
12150 /* Ignore tooltip frame. */
12151 if (FRAME_TOOLTIP_P (f
))
12157 && !XBUFFER (w
->contents
)->text
->redisplay
)
12160 run_window_size_change_functions (frame
);
12162 if (FRAME_PARENT_FRAME (f
))
12165 menu_bar_hooks_run
= update_menu_bar (f
, false, menu_bar_hooks_run
);
12166 #ifdef HAVE_WINDOW_SYSTEM
12167 update_tool_bar (f
, false);
12171 unbind_to (count
, Qnil
);
12175 struct frame
*sf
= SELECTED_FRAME ();
12176 update_menu_bar (sf
, true, false);
12177 #ifdef HAVE_WINDOW_SYSTEM
12178 update_tool_bar (sf
, true);
12184 /* Update the menu bar item list for frame F. This has to be done
12185 before we start to fill in any display lines, because it can call
12188 If SAVE_MATCH_DATA, we must save and restore it here.
12190 If HOOKS_RUN, a previous call to update_menu_bar
12191 already ran the menu bar hooks for this redisplay, so there
12192 is no need to run them again. The return value is the
12193 updated value of this flag, to pass to the next call. */
12196 update_menu_bar (struct frame
*f
, bool save_match_data
, bool hooks_run
)
12198 Lisp_Object window
;
12201 /* If called recursively during a menu update, do nothing. This can
12202 happen when, for instance, an activate-menubar-hook causes a
12204 if (inhibit_menubar_update
)
12207 window
= FRAME_SELECTED_WINDOW (f
);
12208 w
= XWINDOW (window
);
12210 if (FRAME_WINDOW_P (f
)
12212 #if defined (USE_X_TOOLKIT) || defined (HAVE_NTGUI) \
12213 || defined (HAVE_NS) || defined (USE_GTK)
12214 FRAME_EXTERNAL_MENU_BAR (f
)
12216 FRAME_MENU_BAR_LINES (f
) > 0
12218 : FRAME_MENU_BAR_LINES (f
) > 0)
12220 /* If the user has switched buffers or windows, we need to
12221 recompute to reflect the new bindings. But we'll
12222 recompute when update_mode_lines is set too; that means
12223 that people can use force-mode-line-update to request
12224 that the menu bar be recomputed. The adverse effect on
12225 the rest of the redisplay algorithm is about the same as
12226 windows_or_buffers_changed anyway. */
12227 if (windows_or_buffers_changed
12228 /* This used to test w->update_mode_line, but we believe
12229 there is no need to recompute the menu in that case. */
12230 || update_mode_lines
12231 || window_buffer_changed (w
))
12233 struct buffer
*prev
= current_buffer
;
12234 ptrdiff_t count
= SPECPDL_INDEX ();
12236 specbind (Qinhibit_menubar_update
, Qt
);
12238 set_buffer_internal_1 (XBUFFER (w
->contents
));
12239 if (save_match_data
)
12240 record_unwind_save_match_data ();
12241 if (NILP (Voverriding_local_map_menu_flag
))
12243 specbind (Qoverriding_terminal_local_map
, Qnil
);
12244 specbind (Qoverriding_local_map
, Qnil
);
12249 /* Run the Lucid hook. */
12250 safe_run_hooks (Qactivate_menubar_hook
);
12252 /* If it has changed current-menubar from previous value,
12253 really recompute the menu-bar from the value. */
12254 if (! NILP (Vlucid_menu_bar_dirty_flag
))
12255 call0 (Qrecompute_lucid_menubar
);
12257 safe_run_hooks (Qmenu_bar_update_hook
);
12262 XSETFRAME (Vmenu_updating_frame
, f
);
12263 fset_menu_bar_items (f
, menu_bar_items (FRAME_MENU_BAR_ITEMS (f
)));
12265 /* Redisplay the menu bar in case we changed it. */
12266 #if defined (USE_X_TOOLKIT) || defined (HAVE_NTGUI) \
12267 || defined (HAVE_NS) || defined (USE_GTK)
12268 if (FRAME_WINDOW_P (f
))
12270 #if defined (HAVE_NS)
12271 /* All frames on Mac OS share the same menubar. So only
12272 the selected frame should be allowed to set it. */
12273 if (f
== SELECTED_FRAME ())
12275 set_frame_menubar (f
, false, false);
12278 /* On a terminal screen, the menu bar is an ordinary screen
12279 line, and this makes it get updated. */
12280 w
->update_mode_line
= true;
12281 #else /* ! (USE_X_TOOLKIT || HAVE_NTGUI || HAVE_NS || USE_GTK) */
12282 /* In the non-toolkit version, the menu bar is an ordinary screen
12283 line, and this makes it get updated. */
12284 w
->update_mode_line
= true;
12285 #endif /* ! (USE_X_TOOLKIT || HAVE_NTGUI || HAVE_NS || USE_GTK) */
12287 unbind_to (count
, Qnil
);
12288 set_buffer_internal_1 (prev
);
12295 /***********************************************************************
12297 ***********************************************************************/
12299 #ifdef HAVE_WINDOW_SYSTEM
12301 /* Select `frame' temporarily without running all the code in
12303 FIXME: Maybe do_switch_frame should be trimmed down similarly
12304 when `norecord' is set. */
12306 fast_set_selected_frame (Lisp_Object frame
)
12308 if (!EQ (selected_frame
, frame
))
12310 selected_frame
= frame
;
12311 selected_window
= XFRAME (frame
)->selected_window
;
12315 /* Update the tool-bar item list for frame F. This has to be done
12316 before we start to fill in any display lines. Called from
12317 prepare_menu_bars. If SAVE_MATCH_DATA, we must save
12318 and restore it here. */
12321 update_tool_bar (struct frame
*f
, bool save_match_data
)
12323 #if defined (USE_GTK) || defined (HAVE_NS)
12324 bool do_update
= FRAME_EXTERNAL_TOOL_BAR (f
);
12326 bool do_update
= (WINDOWP (f
->tool_bar_window
)
12327 && WINDOW_TOTAL_LINES (XWINDOW (f
->tool_bar_window
)) > 0);
12332 Lisp_Object window
;
12335 window
= FRAME_SELECTED_WINDOW (f
);
12336 w
= XWINDOW (window
);
12338 /* If the user has switched buffers or windows, we need to
12339 recompute to reflect the new bindings. But we'll
12340 recompute when update_mode_lines is set too; that means
12341 that people can use force-mode-line-update to request
12342 that the menu bar be recomputed. The adverse effect on
12343 the rest of the redisplay algorithm is about the same as
12344 windows_or_buffers_changed anyway. */
12345 if (windows_or_buffers_changed
12346 || w
->update_mode_line
12347 || update_mode_lines
12348 || window_buffer_changed (w
))
12350 struct buffer
*prev
= current_buffer
;
12351 ptrdiff_t count
= SPECPDL_INDEX ();
12352 Lisp_Object frame
, new_tool_bar
;
12353 int new_n_tool_bar
;
12355 /* Set current_buffer to the buffer of the selected
12356 window of the frame, so that we get the right local
12358 set_buffer_internal_1 (XBUFFER (w
->contents
));
12360 /* Save match data, if we must. */
12361 if (save_match_data
)
12362 record_unwind_save_match_data ();
12364 /* Make sure that we don't accidentally use bogus keymaps. */
12365 if (NILP (Voverriding_local_map_menu_flag
))
12367 specbind (Qoverriding_terminal_local_map
, Qnil
);
12368 specbind (Qoverriding_local_map
, Qnil
);
12371 /* We must temporarily set the selected frame to this frame
12372 before calling tool_bar_items, because the calculation of
12373 the tool-bar keymap uses the selected frame (see
12374 `tool-bar-make-keymap' in tool-bar.el). */
12375 eassert (EQ (selected_window
,
12376 /* Since we only explicitly preserve selected_frame,
12377 check that selected_window would be redundant. */
12378 XFRAME (selected_frame
)->selected_window
));
12379 record_unwind_protect (fast_set_selected_frame
, selected_frame
);
12380 XSETFRAME (frame
, f
);
12381 fast_set_selected_frame (frame
);
12383 /* Build desired tool-bar items from keymaps. */
12385 = tool_bar_items (Fcopy_sequence (f
->tool_bar_items
),
12388 /* Redisplay the tool-bar if we changed it. */
12389 if (new_n_tool_bar
!= f
->n_tool_bar_items
12390 || NILP (Fequal (new_tool_bar
, f
->tool_bar_items
)))
12392 /* Redisplay that happens asynchronously due to an expose event
12393 may access f->tool_bar_items. Make sure we update both
12394 variables within BLOCK_INPUT so no such event interrupts. */
12396 fset_tool_bar_items (f
, new_tool_bar
);
12397 f
->n_tool_bar_items
= new_n_tool_bar
;
12398 w
->update_mode_line
= true;
12402 unbind_to (count
, Qnil
);
12403 set_buffer_internal_1 (prev
);
12408 #if ! defined (USE_GTK) && ! defined (HAVE_NS)
12410 /* Set F->desired_tool_bar_string to a Lisp string representing frame
12411 F's desired tool-bar contents. F->tool_bar_items must have
12412 been set up previously by calling prepare_menu_bars. */
12415 build_desired_tool_bar_string (struct frame
*f
)
12417 int i
, size
, size_needed
;
12418 Lisp_Object image
, plist
;
12420 image
= plist
= Qnil
;
12422 /* Prepare F->desired_tool_bar_string. If we can reuse it, do so.
12423 Otherwise, make a new string. */
12425 /* The size of the string we might be able to reuse. */
12426 size
= (STRINGP (f
->desired_tool_bar_string
)
12427 ? SCHARS (f
->desired_tool_bar_string
)
12430 /* We need one space in the string for each image. */
12431 size_needed
= f
->n_tool_bar_items
;
12433 /* Reuse f->desired_tool_bar_string, if possible. */
12434 if (size
< size_needed
|| NILP (f
->desired_tool_bar_string
))
12435 fset_desired_tool_bar_string
12436 (f
, Fmake_string (make_number (size_needed
), make_number (' '), Qnil
));
12439 AUTO_LIST4 (props
, Qdisplay
, Qnil
, Qmenu_item
, Qnil
);
12440 Fremove_text_properties (make_number (0), make_number (size
),
12441 props
, f
->desired_tool_bar_string
);
12444 /* Put a `display' property on the string for the images to display,
12445 put a `menu_item' property on tool-bar items with a value that
12446 is the index of the item in F's tool-bar item vector. */
12447 for (i
= 0; i
< f
->n_tool_bar_items
; ++i
)
12449 #define PROP(IDX) \
12450 AREF (f->tool_bar_items, i * TOOL_BAR_ITEM_NSLOTS + (IDX))
12452 bool enabled_p
= !NILP (PROP (TOOL_BAR_ITEM_ENABLED_P
));
12453 bool selected_p
= !NILP (PROP (TOOL_BAR_ITEM_SELECTED_P
));
12454 int hmargin
, vmargin
, relief
, idx
, end
;
12456 /* If image is a vector, choose the image according to the
12458 image
= PROP (TOOL_BAR_ITEM_IMAGES
);
12459 if (VECTORP (image
))
12463 ? TOOL_BAR_IMAGE_ENABLED_SELECTED
12464 : TOOL_BAR_IMAGE_ENABLED_DESELECTED
);
12467 ? TOOL_BAR_IMAGE_DISABLED_SELECTED
12468 : TOOL_BAR_IMAGE_DISABLED_DESELECTED
);
12470 eassert (ASIZE (image
) >= idx
);
12471 image
= AREF (image
, idx
);
12476 /* Ignore invalid image specifications. */
12477 if (!valid_image_p (image
))
12480 /* Display the tool-bar button pressed, or depressed. */
12481 plist
= Fcopy_sequence (XCDR (image
));
12483 /* Compute margin and relief to draw. */
12484 relief
= (tool_bar_button_relief
>= 0
12485 ? tool_bar_button_relief
12486 : DEFAULT_TOOL_BAR_BUTTON_RELIEF
);
12487 hmargin
= vmargin
= relief
;
12489 if (RANGED_INTEGERP (1, Vtool_bar_button_margin
,
12490 INT_MAX
- max (hmargin
, vmargin
)))
12492 hmargin
+= XFASTINT (Vtool_bar_button_margin
);
12493 vmargin
+= XFASTINT (Vtool_bar_button_margin
);
12495 else if (CONSP (Vtool_bar_button_margin
))
12497 if (RANGED_INTEGERP (1, XCAR (Vtool_bar_button_margin
),
12498 INT_MAX
- hmargin
))
12499 hmargin
+= XFASTINT (XCAR (Vtool_bar_button_margin
));
12501 if (RANGED_INTEGERP (1, XCDR (Vtool_bar_button_margin
),
12502 INT_MAX
- vmargin
))
12503 vmargin
+= XFASTINT (XCDR (Vtool_bar_button_margin
));
12506 if (auto_raise_tool_bar_buttons_p
)
12508 /* Add a `:relief' property to the image spec if the item is
12512 plist
= Fplist_put (plist
, QCrelief
, make_number (-relief
));
12519 /* If image is selected, display it pressed, i.e. with a
12520 negative relief. If it's not selected, display it with a
12522 plist
= Fplist_put (plist
, QCrelief
,
12524 ? make_number (-relief
)
12525 : make_number (relief
)));
12530 /* Put a margin around the image. */
12531 if (hmargin
|| vmargin
)
12533 if (hmargin
== vmargin
)
12534 plist
= Fplist_put (plist
, QCmargin
, make_number (hmargin
));
12536 plist
= Fplist_put (plist
, QCmargin
,
12537 Fcons (make_number (hmargin
),
12538 make_number (vmargin
)));
12541 /* If button is not enabled, and we don't have special images
12542 for the disabled state, make the image appear disabled by
12543 applying an appropriate algorithm to it. */
12544 if (!enabled_p
&& idx
< 0)
12545 plist
= Fplist_put (plist
, QCconversion
, Qdisabled
);
12547 /* Put a `display' text property on the string for the image to
12548 display. Put a `menu-item' property on the string that gives
12549 the start of this item's properties in the tool-bar items
12551 image
= Fcons (Qimage
, plist
);
12552 AUTO_LIST4 (props
, Qdisplay
, image
, Qmenu_item
,
12553 make_number (i
* TOOL_BAR_ITEM_NSLOTS
));
12555 /* Let the last image hide all remaining spaces in the tool bar
12556 string. The string can be longer than needed when we reuse a
12557 previous string. */
12558 if (i
+ 1 == f
->n_tool_bar_items
)
12559 end
= SCHARS (f
->desired_tool_bar_string
);
12562 Fadd_text_properties (make_number (i
), make_number (end
),
12563 props
, f
->desired_tool_bar_string
);
12569 /* Display one line of the tool-bar of frame IT->f.
12571 HEIGHT specifies the desired height of the tool-bar line.
12572 If the actual height of the glyph row is less than HEIGHT, the
12573 row's height is increased to HEIGHT, and the icons are centered
12574 vertically in the new height.
12576 If HEIGHT is -1, we are counting needed tool-bar lines, so don't
12577 count a final empty row in case the tool-bar width exactly matches
12582 display_tool_bar_line (struct it
*it
, int height
)
12584 struct glyph_row
*row
= it
->glyph_row
;
12585 int max_x
= it
->last_visible_x
;
12586 struct glyph
*last
;
12588 /* Don't extend on a previously drawn tool bar items (Bug#16058). */
12589 clear_glyph_row (row
);
12590 row
->enabled_p
= true;
12591 row
->y
= it
->current_y
;
12593 /* Note that this isn't made use of if the face hasn't a box,
12594 so there's no need to check the face here. */
12595 it
->start_of_box_run_p
= true;
12597 while (it
->current_x
< max_x
)
12599 int x
, n_glyphs_before
, i
, nglyphs
;
12600 struct it it_before
;
12602 /* Get the next display element. */
12603 if (!get_next_display_element (it
))
12605 /* Don't count empty row if we are counting needed tool-bar lines. */
12606 if (height
< 0 && !it
->hpos
)
12611 /* Produce glyphs. */
12612 n_glyphs_before
= row
->used
[TEXT_AREA
];
12615 PRODUCE_GLYPHS (it
);
12617 nglyphs
= row
->used
[TEXT_AREA
] - n_glyphs_before
;
12619 x
= it_before
.current_x
;
12620 while (i
< nglyphs
)
12622 struct glyph
*glyph
= row
->glyphs
[TEXT_AREA
] + n_glyphs_before
+ i
;
12624 if (x
+ glyph
->pixel_width
> max_x
)
12626 /* Glyph doesn't fit on line. Backtrack. */
12627 row
->used
[TEXT_AREA
] = n_glyphs_before
;
12629 /* If this is the only glyph on this line, it will never fit on the
12630 tool-bar, so skip it. But ensure there is at least one glyph,
12631 so we don't accidentally disable the tool-bar. */
12632 if (n_glyphs_before
== 0
12633 && (it
->vpos
> 0 || IT_STRING_CHARPOS (*it
) < it
->end_charpos
-1))
12639 x
+= glyph
->pixel_width
;
12643 /* Stop at line end. */
12644 if (ITERATOR_AT_END_OF_LINE_P (it
))
12647 set_iterator_to_next (it
, true);
12652 row
->displays_text_p
= row
->used
[TEXT_AREA
] != 0;
12654 /* Use default face for the border below the tool bar.
12656 FIXME: When auto-resize-tool-bars is grow-only, there is
12657 no additional border below the possibly empty tool-bar lines.
12658 So to make the extra empty lines look "normal", we have to
12659 use the tool-bar face for the border too. */
12660 if (!MATRIX_ROW_DISPLAYS_TEXT_P (row
)
12661 && !EQ (Vauto_resize_tool_bars
, Qgrow_only
))
12662 it
->face_id
= DEFAULT_FACE_ID
;
12664 extend_face_to_end_of_line (it
);
12665 last
= row
->glyphs
[TEXT_AREA
] + row
->used
[TEXT_AREA
] - 1;
12666 last
->right_box_line_p
= true;
12667 if (last
== row
->glyphs
[TEXT_AREA
])
12668 last
->left_box_line_p
= true;
12670 /* Make line the desired height and center it vertically. */
12671 if ((height
-= it
->max_ascent
+ it
->max_descent
) > 0)
12673 /* Don't add more than one line height. */
12674 height
%= FRAME_LINE_HEIGHT (it
->f
);
12675 it
->max_ascent
+= height
/ 2;
12676 it
->max_descent
+= (height
+ 1) / 2;
12679 compute_line_metrics (it
);
12681 /* If line is empty, make it occupy the rest of the tool-bar. */
12682 if (!MATRIX_ROW_DISPLAYS_TEXT_P (row
))
12684 row
->height
= row
->phys_height
= it
->last_visible_y
- row
->y
;
12685 row
->visible_height
= row
->height
;
12686 row
->ascent
= row
->phys_ascent
= 0;
12687 row
->extra_line_spacing
= 0;
12690 row
->full_width_p
= true;
12691 row
->continued_p
= false;
12692 row
->truncated_on_left_p
= false;
12693 row
->truncated_on_right_p
= false;
12695 it
->current_x
= it
->hpos
= 0;
12696 it
->current_y
+= row
->height
;
12702 /* Value is the number of pixels needed to make all tool-bar items of
12703 frame F visible. The actual number of glyph rows needed is
12704 returned in *N_ROWS if non-NULL. */
12706 tool_bar_height (struct frame
*f
, int *n_rows
, bool pixelwise
)
12708 struct window
*w
= XWINDOW (f
->tool_bar_window
);
12710 /* tool_bar_height is called from redisplay_tool_bar after building
12711 the desired matrix, so use (unused) mode-line row as temporary row to
12712 avoid destroying the first tool-bar row. */
12713 struct glyph_row
*temp_row
= MATRIX_MODE_LINE_ROW (w
->desired_matrix
);
12715 /* Initialize an iterator for iteration over
12716 F->desired_tool_bar_string in the tool-bar window of frame F. */
12717 init_iterator (&it
, w
, -1, -1, temp_row
, TOOL_BAR_FACE_ID
);
12718 temp_row
->reversed_p
= false;
12719 it
.first_visible_x
= 0;
12720 it
.last_visible_x
= WINDOW_PIXEL_WIDTH (w
);
12721 reseat_to_string (&it
, NULL
, f
->desired_tool_bar_string
, 0, 0, 0, -1);
12722 it
.paragraph_embedding
= L2R
;
12724 while (!ITERATOR_AT_END_P (&it
))
12726 clear_glyph_row (temp_row
);
12727 it
.glyph_row
= temp_row
;
12728 display_tool_bar_line (&it
, -1);
12730 clear_glyph_row (temp_row
);
12732 /* f->n_tool_bar_rows == 0 means "unknown"; -1 means no tool-bar. */
12734 *n_rows
= it
.vpos
> 0 ? it
.vpos
: -1;
12737 return it
.current_y
;
12739 return (it
.current_y
+ FRAME_LINE_HEIGHT (f
) - 1) / FRAME_LINE_HEIGHT (f
);
12742 #endif /* !USE_GTK && !HAVE_NS */
12744 DEFUN ("tool-bar-height", Ftool_bar_height
, Stool_bar_height
,
12746 doc
: /* Return the number of lines occupied by the tool bar of FRAME.
12747 If FRAME is nil or omitted, use the selected frame. Optional argument
12748 PIXELWISE non-nil means return the height of the tool bar in pixels. */)
12749 (Lisp_Object frame
, Lisp_Object pixelwise
)
12753 #if ! defined (USE_GTK) && ! defined (HAVE_NS)
12754 struct frame
*f
= decode_any_frame (frame
);
12756 if (WINDOWP (f
->tool_bar_window
)
12757 && WINDOW_PIXEL_HEIGHT (XWINDOW (f
->tool_bar_window
)) > 0)
12759 update_tool_bar (f
, true);
12760 if (f
->n_tool_bar_items
)
12762 build_desired_tool_bar_string (f
);
12763 height
= tool_bar_height (f
, NULL
, !NILP (pixelwise
));
12768 return make_number (height
);
12772 /* Display the tool-bar of frame F. Value is true if tool-bar's
12773 height should be changed. */
12775 redisplay_tool_bar (struct frame
*f
)
12777 f
->tool_bar_redisplayed
= true;
12778 #if defined (USE_GTK) || defined (HAVE_NS)
12780 if (FRAME_EXTERNAL_TOOL_BAR (f
))
12781 update_frame_tool_bar (f
);
12784 #else /* !USE_GTK && !HAVE_NS */
12788 struct glyph_row
*row
;
12790 /* If frame hasn't a tool-bar window or if it is zero-height, don't
12791 do anything. This means you must start with tool-bar-lines
12792 non-zero to get the auto-sizing effect. Or in other words, you
12793 can turn off tool-bars by specifying tool-bar-lines zero. */
12794 if (!WINDOWP (f
->tool_bar_window
)
12795 || (w
= XWINDOW (f
->tool_bar_window
),
12796 WINDOW_TOTAL_LINES (w
) == 0))
12799 /* Set up an iterator for the tool-bar window. */
12800 init_iterator (&it
, w
, -1, -1, w
->desired_matrix
->rows
, TOOL_BAR_FACE_ID
);
12801 it
.first_visible_x
= 0;
12802 it
.last_visible_x
= WINDOW_PIXEL_WIDTH (w
);
12803 row
= it
.glyph_row
;
12804 row
->reversed_p
= false;
12806 /* Build a string that represents the contents of the tool-bar. */
12807 build_desired_tool_bar_string (f
);
12808 reseat_to_string (&it
, NULL
, f
->desired_tool_bar_string
, 0, 0, 0, -1);
12809 /* FIXME: This should be controlled by a user option. But it
12810 doesn't make sense to have an R2L tool bar if the menu bar cannot
12811 be drawn also R2L, and making the menu bar R2L is tricky due
12812 toolkit-specific code that implements it. If an R2L tool bar is
12813 ever supported, display_tool_bar_line should also be augmented to
12814 call unproduce_glyphs like display_line and display_string
12816 it
.paragraph_embedding
= L2R
;
12818 if (f
->n_tool_bar_rows
== 0)
12820 int new_height
= tool_bar_height (f
, &f
->n_tool_bar_rows
, true);
12822 if (new_height
!= WINDOW_PIXEL_HEIGHT (w
))
12824 x_change_tool_bar_height (f
, new_height
);
12825 frame_default_tool_bar_height
= new_height
;
12826 /* Always do that now. */
12827 clear_glyph_matrix (w
->desired_matrix
);
12828 f
->fonts_changed
= true;
12833 /* Display as many lines as needed to display all tool-bar items. */
12835 if (f
->n_tool_bar_rows
> 0)
12837 int border
, rows
, height
, extra
;
12839 if (TYPE_RANGED_INTEGERP (int, Vtool_bar_border
))
12840 border
= XINT (Vtool_bar_border
);
12841 else if (EQ (Vtool_bar_border
, Qinternal_border_width
))
12842 border
= FRAME_INTERNAL_BORDER_WIDTH (f
);
12843 else if (EQ (Vtool_bar_border
, Qborder_width
))
12844 border
= f
->border_width
;
12850 rows
= f
->n_tool_bar_rows
;
12851 height
= max (1, (it
.last_visible_y
- border
) / rows
);
12852 extra
= it
.last_visible_y
- border
- height
* rows
;
12854 while (it
.current_y
< it
.last_visible_y
)
12857 if (extra
> 0 && rows
-- > 0)
12859 h
= (extra
+ rows
- 1) / rows
;
12862 display_tool_bar_line (&it
, height
+ h
);
12867 while (it
.current_y
< it
.last_visible_y
)
12868 display_tool_bar_line (&it
, 0);
12871 /* It doesn't make much sense to try scrolling in the tool-bar
12872 window, so don't do it. */
12873 w
->desired_matrix
->no_scrolling_p
= true;
12874 w
->must_be_updated_p
= true;
12876 if (!NILP (Vauto_resize_tool_bars
))
12878 bool change_height_p
= true;
12880 /* If we couldn't display everything, change the tool-bar's
12881 height if there is room for more. */
12882 if (IT_STRING_CHARPOS (it
) < it
.end_charpos
)
12883 change_height_p
= true;
12885 /* We subtract 1 because display_tool_bar_line advances the
12886 glyph_row pointer before returning to its caller. We want to
12887 examine the last glyph row produced by
12888 display_tool_bar_line. */
12889 row
= it
.glyph_row
- 1;
12891 /* If there are blank lines at the end, except for a partially
12892 visible blank line at the end that is smaller than
12893 FRAME_LINE_HEIGHT, change the tool-bar's height. */
12894 if (!MATRIX_ROW_DISPLAYS_TEXT_P (row
)
12895 && row
->height
>= FRAME_LINE_HEIGHT (f
))
12896 change_height_p
= true;
12898 /* If row displays tool-bar items, but is partially visible,
12899 change the tool-bar's height. */
12900 if (MATRIX_ROW_DISPLAYS_TEXT_P (row
)
12901 && MATRIX_ROW_BOTTOM_Y (row
) > it
.last_visible_y
)
12902 change_height_p
= true;
12904 /* Resize windows as needed by changing the `tool-bar-lines'
12905 frame parameter. */
12906 if (change_height_p
)
12909 int new_height
= tool_bar_height (f
, &nrows
, true);
12911 change_height_p
= ((EQ (Vauto_resize_tool_bars
, Qgrow_only
)
12912 && !f
->minimize_tool_bar_window_p
)
12913 ? (new_height
> WINDOW_PIXEL_HEIGHT (w
))
12914 : (new_height
!= WINDOW_PIXEL_HEIGHT (w
)));
12915 f
->minimize_tool_bar_window_p
= false;
12917 if (change_height_p
)
12919 x_change_tool_bar_height (f
, new_height
);
12920 frame_default_tool_bar_height
= new_height
;
12921 clear_glyph_matrix (w
->desired_matrix
);
12922 f
->n_tool_bar_rows
= nrows
;
12923 f
->fonts_changed
= true;
12930 f
->minimize_tool_bar_window_p
= false;
12933 #endif /* USE_GTK || HAVE_NS */
12936 #if ! defined (USE_GTK) && ! defined (HAVE_NS)
12938 /* Get information about the tool-bar item which is displayed in GLYPH
12939 on frame F. Return in *PROP_IDX the index where tool-bar item
12940 properties start in F->tool_bar_items. Value is false if
12941 GLYPH doesn't display a tool-bar item. */
12944 tool_bar_item_info (struct frame
*f
, struct glyph
*glyph
, int *prop_idx
)
12949 /* This function can be called asynchronously, which means we must
12950 exclude any possibility that Fget_text_property signals an
12952 charpos
= min (SCHARS (f
->current_tool_bar_string
), glyph
->charpos
);
12953 charpos
= max (0, charpos
);
12955 /* Get the text property `menu-item' at pos. The value of that
12956 property is the start index of this item's properties in
12957 F->tool_bar_items. */
12958 prop
= Fget_text_property (make_number (charpos
),
12959 Qmenu_item
, f
->current_tool_bar_string
);
12960 if (! INTEGERP (prop
))
12962 *prop_idx
= XINT (prop
);
12967 /* Get information about the tool-bar item at position X/Y on frame F.
12968 Return in *GLYPH a pointer to the glyph of the tool-bar item in
12969 the current matrix of the tool-bar window of F, or NULL if not
12970 on a tool-bar item. Return in *PROP_IDX the index of the tool-bar
12971 item in F->tool_bar_items. Value is
12973 -1 if X/Y is not on a tool-bar item
12974 0 if X/Y is on the same item that was highlighted before.
12978 get_tool_bar_item (struct frame
*f
, int x
, int y
, struct glyph
**glyph
,
12979 int *hpos
, int *vpos
, int *prop_idx
)
12981 Mouse_HLInfo
*hlinfo
= MOUSE_HL_INFO (f
);
12982 struct window
*w
= XWINDOW (f
->tool_bar_window
);
12985 /* Find the glyph under X/Y. */
12986 *glyph
= x_y_to_hpos_vpos (w
, x
, y
, hpos
, vpos
, 0, 0, &area
);
12987 if (*glyph
== NULL
)
12990 /* Get the start of this tool-bar item's properties in
12991 f->tool_bar_items. */
12992 if (!tool_bar_item_info (f
, *glyph
, prop_idx
))
12995 /* Is mouse on the highlighted item? */
12996 if (EQ (f
->tool_bar_window
, hlinfo
->mouse_face_window
)
12997 && *vpos
>= hlinfo
->mouse_face_beg_row
12998 && *vpos
<= hlinfo
->mouse_face_end_row
12999 && (*vpos
> hlinfo
->mouse_face_beg_row
13000 || *hpos
>= hlinfo
->mouse_face_beg_col
)
13001 && (*vpos
< hlinfo
->mouse_face_end_row
13002 || *hpos
< hlinfo
->mouse_face_end_col
13003 || hlinfo
->mouse_face_past_end
))
13011 Handle mouse button event on the tool-bar of frame F, at
13012 frame-relative coordinates X/Y. DOWN_P is true for a button press,
13013 false for button release. MODIFIERS is event modifiers for button
13017 handle_tool_bar_click (struct frame
*f
, int x
, int y
, bool down_p
,
13020 Mouse_HLInfo
*hlinfo
= MOUSE_HL_INFO (f
);
13021 struct window
*w
= XWINDOW (f
->tool_bar_window
);
13022 int hpos
, vpos
, prop_idx
;
13023 struct glyph
*glyph
;
13024 Lisp_Object enabled_p
;
13027 /* If not on the highlighted tool-bar item, and mouse-highlight is
13028 non-nil, return. This is so we generate the tool-bar button
13029 click only when the mouse button is released on the same item as
13030 where it was pressed. However, when mouse-highlight is disabled,
13031 generate the click when the button is released regardless of the
13032 highlight, since tool-bar items are not highlighted in that
13034 frame_to_window_pixel_xy (w
, &x
, &y
);
13035 ts
= get_tool_bar_item (f
, x
, y
, &glyph
, &hpos
, &vpos
, &prop_idx
);
13037 || (ts
!= 0 && !NILP (Vmouse_highlight
)))
13040 /* When mouse-highlight is off, generate the click for the item
13041 where the button was pressed, disregarding where it was
13043 if (NILP (Vmouse_highlight
) && !down_p
)
13044 prop_idx
= f
->last_tool_bar_item
;
13046 /* If item is disabled, do nothing. */
13047 enabled_p
= AREF (f
->tool_bar_items
, prop_idx
+ TOOL_BAR_ITEM_ENABLED_P
);
13048 if (NILP (enabled_p
))
13053 /* Show item in pressed state. */
13054 if (!NILP (Vmouse_highlight
))
13055 show_mouse_face (hlinfo
, DRAW_IMAGE_SUNKEN
);
13056 f
->last_tool_bar_item
= prop_idx
;
13060 Lisp_Object key
, frame
;
13061 struct input_event event
;
13062 EVENT_INIT (event
);
13064 /* Show item in released state. */
13065 if (!NILP (Vmouse_highlight
))
13066 show_mouse_face (hlinfo
, DRAW_IMAGE_RAISED
);
13068 key
= AREF (f
->tool_bar_items
, prop_idx
+ TOOL_BAR_ITEM_KEY
);
13070 XSETFRAME (frame
, f
);
13071 event
.kind
= TOOL_BAR_EVENT
;
13072 event
.frame_or_window
= frame
;
13074 kbd_buffer_store_event (&event
);
13076 event
.kind
= TOOL_BAR_EVENT
;
13077 event
.frame_or_window
= frame
;
13079 event
.modifiers
= modifiers
;
13080 kbd_buffer_store_event (&event
);
13081 f
->last_tool_bar_item
= -1;
13086 /* Possibly highlight a tool-bar item on frame F when mouse moves to
13087 tool-bar window-relative coordinates X/Y. Called from
13088 note_mouse_highlight. */
13091 note_tool_bar_highlight (struct frame
*f
, int x
, int y
)
13093 Lisp_Object window
= f
->tool_bar_window
;
13094 struct window
*w
= XWINDOW (window
);
13095 Display_Info
*dpyinfo
= FRAME_DISPLAY_INFO (f
);
13096 Mouse_HLInfo
*hlinfo
= MOUSE_HL_INFO (f
);
13098 struct glyph
*glyph
;
13099 struct glyph_row
*row
;
13101 Lisp_Object enabled_p
;
13103 enum draw_glyphs_face draw
= DRAW_IMAGE_RAISED
;
13107 /* Function note_mouse_highlight is called with negative X/Y
13108 values when mouse moves outside of the frame. */
13109 if (x
<= 0 || y
<= 0)
13111 clear_mouse_face (hlinfo
);
13115 rc
= get_tool_bar_item (f
, x
, y
, &glyph
, &hpos
, &vpos
, &prop_idx
);
13118 /* Not on tool-bar item. */
13119 clear_mouse_face (hlinfo
);
13123 /* On same tool-bar item as before. */
13124 goto set_help_echo
;
13126 clear_mouse_face (hlinfo
);
13128 /* Mouse is down, but on different tool-bar item? */
13129 mouse_down_p
= (x_mouse_grabbed (dpyinfo
)
13130 && f
== dpyinfo
->last_mouse_frame
);
13132 if (mouse_down_p
&& f
->last_tool_bar_item
!= prop_idx
)
13135 draw
= mouse_down_p
? DRAW_IMAGE_SUNKEN
: DRAW_IMAGE_RAISED
;
13137 /* If tool-bar item is not enabled, don't highlight it. */
13138 enabled_p
= AREF (f
->tool_bar_items
, prop_idx
+ TOOL_BAR_ITEM_ENABLED_P
);
13139 if (!NILP (enabled_p
) && !NILP (Vmouse_highlight
))
13141 /* Compute the x-position of the glyph. In front and past the
13142 image is a space. We include this in the highlighted area. */
13143 row
= MATRIX_ROW (w
->current_matrix
, vpos
);
13144 for (i
= x
= 0; i
< hpos
; ++i
)
13145 x
+= row
->glyphs
[TEXT_AREA
][i
].pixel_width
;
13147 /* Record this as the current active region. */
13148 hlinfo
->mouse_face_beg_col
= hpos
;
13149 hlinfo
->mouse_face_beg_row
= vpos
;
13150 hlinfo
->mouse_face_beg_x
= x
;
13151 hlinfo
->mouse_face_past_end
= false;
13153 hlinfo
->mouse_face_end_col
= hpos
+ 1;
13154 hlinfo
->mouse_face_end_row
= vpos
;
13155 hlinfo
->mouse_face_end_x
= x
+ glyph
->pixel_width
;
13156 hlinfo
->mouse_face_window
= window
;
13157 hlinfo
->mouse_face_face_id
= TOOL_BAR_FACE_ID
;
13159 /* Display it as active. */
13160 show_mouse_face (hlinfo
, draw
);
13165 /* Set help_echo_string to a help string to display for this tool-bar item.
13166 XTread_socket does the rest. */
13167 help_echo_object
= help_echo_window
= Qnil
;
13168 help_echo_pos
= -1;
13169 help_echo_string
= AREF (f
->tool_bar_items
, prop_idx
+ TOOL_BAR_ITEM_HELP
);
13170 if (NILP (help_echo_string
))
13171 help_echo_string
= AREF (f
->tool_bar_items
, prop_idx
+ TOOL_BAR_ITEM_CAPTION
);
13174 #endif /* !USE_GTK && !HAVE_NS */
13176 #endif /* HAVE_WINDOW_SYSTEM */
13180 /************************************************************************
13181 Horizontal scrolling
13182 ************************************************************************/
13184 /* For all leaf windows in the window tree rooted at WINDOW, set their
13185 hscroll value so that PT is (i) visible in the window, and (ii) so
13186 that it is not within a certain margin at the window's left and
13187 right border. Value is true if any window's hscroll has been
13191 hscroll_window_tree (Lisp_Object window
)
13193 bool hscrolled_p
= false;
13194 bool hscroll_relative_p
= FLOATP (Vhscroll_step
);
13195 int hscroll_step_abs
= 0;
13196 double hscroll_step_rel
= 0;
13198 if (hscroll_relative_p
)
13200 hscroll_step_rel
= XFLOAT_DATA (Vhscroll_step
);
13201 if (hscroll_step_rel
< 0)
13203 hscroll_relative_p
= false;
13204 hscroll_step_abs
= 0;
13207 else if (TYPE_RANGED_INTEGERP (int, Vhscroll_step
))
13209 hscroll_step_abs
= XINT (Vhscroll_step
);
13210 if (hscroll_step_abs
< 0)
13211 hscroll_step_abs
= 0;
13214 hscroll_step_abs
= 0;
13216 while (WINDOWP (window
))
13218 struct window
*w
= XWINDOW (window
);
13220 if (WINDOWP (w
->contents
))
13221 hscrolled_p
|= hscroll_window_tree (w
->contents
);
13222 else if (w
->cursor
.vpos
>= 0)
13225 int text_area_width
;
13226 struct glyph_row
*cursor_row
;
13227 struct glyph_row
*bottom_row
;
13229 bottom_row
= MATRIX_BOTTOM_TEXT_ROW (w
->desired_matrix
, w
);
13230 if (w
->cursor
.vpos
< bottom_row
- w
->desired_matrix
->rows
)
13231 cursor_row
= MATRIX_ROW (w
->desired_matrix
, w
->cursor
.vpos
);
13233 cursor_row
= bottom_row
- 1;
13235 if (!cursor_row
->enabled_p
)
13237 bottom_row
= MATRIX_BOTTOM_TEXT_ROW (w
->current_matrix
, w
);
13238 if (w
->cursor
.vpos
< bottom_row
- w
->current_matrix
->rows
)
13239 cursor_row
= MATRIX_ROW (w
->current_matrix
, w
->cursor
.vpos
);
13241 cursor_row
= bottom_row
- 1;
13243 bool row_r2l_p
= cursor_row
->reversed_p
;
13244 bool hscl
= hscrolling_current_line_p (w
);
13246 /* When line numbers are displayed, we need to account for
13247 the horizontal space they consume. */
13248 if (!NILP (Vdisplay_line_numbers
))
13253 for (g
= cursor_row
->glyphs
[TEXT_AREA
];
13254 g
< cursor_row
->glyphs
[TEXT_AREA
]
13255 + cursor_row
->used
[TEXT_AREA
];
13258 if (!(NILP (g
->object
) && g
->charpos
< 0))
13260 x_offset
+= g
->pixel_width
;
13265 for (g
= cursor_row
->glyphs
[TEXT_AREA
]
13266 + cursor_row
->used
[TEXT_AREA
];
13267 g
> cursor_row
->glyphs
[TEXT_AREA
];
13270 if (!(NILP ((g
- 1)->object
) && (g
- 1)->charpos
< 0))
13272 x_offset
+= (g
- 1)->pixel_width
;
13276 if (cursor_row
->truncated_on_left_p
)
13278 /* On TTY frames, don't count the left truncation glyph. */
13279 struct frame
*f
= XFRAME (WINDOW_FRAME (w
));
13280 x_offset
-= (FRAME_TERMCAP_P (f
) || FRAME_MSDOS_P (f
));
13283 text_area_width
= window_box_width (w
, TEXT_AREA
);
13285 /* Scroll when cursor is inside this scroll margin. */
13286 h_margin
= hscroll_margin
* WINDOW_FRAME_COLUMN_WIDTH (w
);
13288 /* If the position of this window's point has explicitly
13289 changed, no more suspend auto hscrolling. */
13290 if (w
->suspend_auto_hscroll
13291 && NILP (Fequal (Fwindow_point (window
),
13292 Fwindow_old_point (window
))))
13294 w
->suspend_auto_hscroll
= false;
13295 /* When hscrolling just the current line, and the rest
13296 of lines were temporarily hscrolled, but no longer
13297 are, force thorough redisplay of this window, to show
13298 the effect of disabling hscroll suspension immediately. */
13299 if (w
->min_hscroll
== 0 && w
->hscroll
> 0
13300 && EQ (Fbuffer_local_value (Qauto_hscroll_mode
, w
->contents
),
13302 SET_FRAME_GARBAGED (XFRAME (w
->frame
));
13305 /* Remember window point. */
13306 Fset_marker (w
->old_pointm
,
13307 ((w
== XWINDOW (selected_window
))
13308 ? make_number (BUF_PT (XBUFFER (w
->contents
)))
13309 : Fmarker_position (w
->pointm
)),
13312 if (!NILP (Fbuffer_local_value (Qauto_hscroll_mode
, w
->contents
))
13313 && !w
->suspend_auto_hscroll
13314 /* In some pathological cases, like restoring a window
13315 configuration into a frame that is much smaller than
13316 the one from which the configuration was saved, we
13317 get glyph rows whose start and end have zero buffer
13318 positions, which we cannot handle below. Just skip
13320 && CHARPOS (cursor_row
->start
.pos
) >= BUF_BEG (w
->contents
)
13321 /* For left-to-right rows, hscroll when cursor is either
13322 (i) inside the right hscroll margin, or (ii) if it is
13323 inside the left margin and the window is already
13326 && ((w
->hscroll
&& w
->cursor
.x
<= h_margin
+ x_offset
)
13327 || (cursor_row
->enabled_p
13328 && cursor_row
->truncated_on_right_p
13329 && (w
->cursor
.x
>= text_area_width
- h_margin
))))
13330 /* For right-to-left rows, the logic is similar,
13331 except that rules for scrolling to left and right
13332 are reversed. E.g., if cursor.x <= h_margin, we
13333 need to hscroll "to the right" unconditionally,
13334 and that will scroll the screen to the left so as
13335 to reveal the next portion of the row. */
13337 && ((cursor_row
->enabled_p
13338 /* FIXME: It is confusing to set the
13339 truncated_on_right_p flag when R2L rows
13340 are actually truncated on the left. */
13341 && cursor_row
->truncated_on_right_p
13342 && w
->cursor
.x
<= h_margin
)
13344 && (w
->cursor
.x
>= (text_area_width
- h_margin
13346 /* This last condition is needed when moving
13347 vertically from an hscrolled line to a short line
13348 that doesn't need to be hscrolled. If we omit
13349 this condition, the line from which we move will
13350 remain hscrolled. */
13352 && w
->hscroll
!= w
->min_hscroll
13353 && !cursor_row
->truncated_on_left_p
)))
13357 struct buffer
*saved_current_buffer
;
13361 /* Find point in a display of infinite width. */
13362 saved_current_buffer
= current_buffer
;
13363 current_buffer
= XBUFFER (w
->contents
);
13365 if (w
== XWINDOW (selected_window
))
13368 pt
= clip_to_bounds (BEGV
, marker_position (w
->pointm
), ZV
);
13370 /* Move iterator to pt starting at cursor_row->start in
13371 a line with infinite width. */
13372 init_to_row_start (&it
, w
, cursor_row
);
13374 it
.first_visible_x
= window_hscroll_limited (w
, it
.f
)
13375 * FRAME_COLUMN_WIDTH (it
.f
);
13376 it
.last_visible_x
= DISP_INFINITY
;
13377 move_it_in_display_line_to (&it
, pt
, -1, MOVE_TO_POS
);
13378 /* If the line ends in an overlay string with a newline,
13379 we might infloop, because displaying the window will
13380 want to put the cursor after the overlay, i.e. at X
13381 coordinate of zero on the next screen line. So we
13382 use the buffer position prior to the overlay string
13384 if (it
.method
== GET_FROM_STRING
&& pt
> 1)
13386 init_to_row_start (&it
, w
, cursor_row
);
13388 it
.first_visible_x
= (window_hscroll_limited (w
, it
.f
)
13389 * FRAME_COLUMN_WIDTH (it
.f
));
13390 move_it_in_display_line_to (&it
, pt
- 1, -1, MOVE_TO_POS
);
13392 current_buffer
= saved_current_buffer
;
13394 /* Position cursor in window. */
13395 if (!hscroll_relative_p
&& hscroll_step_abs
== 0)
13396 hscroll
= max (0, (it
.current_x
13397 - (ITERATOR_AT_END_OF_LINE_P (&it
)
13398 ? (text_area_width
- 4 * FRAME_COLUMN_WIDTH (it
.f
))
13399 : (text_area_width
/ 2))))
13400 / FRAME_COLUMN_WIDTH (it
.f
);
13401 else if ((!row_r2l_p
13402 && w
->cursor
.x
>= text_area_width
- h_margin
)
13403 || (row_r2l_p
&& w
->cursor
.x
<= h_margin
))
13405 if (hscroll_relative_p
)
13406 wanted_x
= text_area_width
* (1 - hscroll_step_rel
)
13409 wanted_x
= text_area_width
13410 - hscroll_step_abs
* FRAME_COLUMN_WIDTH (it
.f
)
13413 = max (0, it
.current_x
- wanted_x
) / FRAME_COLUMN_WIDTH (it
.f
);
13417 if (hscroll_relative_p
)
13418 wanted_x
= text_area_width
* hscroll_step_rel
13421 wanted_x
= hscroll_step_abs
* FRAME_COLUMN_WIDTH (it
.f
)
13424 = max (0, it
.current_x
- wanted_x
) / FRAME_COLUMN_WIDTH (it
.f
);
13426 hscroll
= max (hscroll
, w
->min_hscroll
);
13428 /* Don't prevent redisplay optimizations if hscroll
13429 hasn't changed, as it will unnecessarily slow down
13431 if (w
->hscroll
!= hscroll
13432 /* When hscrolling only the current line, we need to
13433 report hscroll even if its value is equal to the
13434 previous one, because the new line might need a
13435 different value. */
13436 || (hscl
&& w
->last_cursor_vpos
!= w
->cursor
.vpos
))
13438 struct buffer
*b
= XBUFFER (w
->contents
);
13439 b
->prevent_redisplay_optimizations_p
= true;
13440 w
->hscroll
= hscroll
;
13441 hscrolled_p
= true;
13449 /* Value is true if hscroll of any leaf window has been changed. */
13450 return hscrolled_p
;
13454 /* Set hscroll so that cursor is visible and not inside horizontal
13455 scroll margins for all windows in the tree rooted at WINDOW. See
13456 also hscroll_window_tree above. Value is true if any window's
13457 hscroll has been changed. If it has, desired matrices on the frame
13458 of WINDOW are cleared. */
13461 hscroll_windows (Lisp_Object window
)
13463 bool hscrolled_p
= hscroll_window_tree (window
);
13465 clear_desired_matrices (XFRAME (WINDOW_FRAME (XWINDOW (window
))));
13466 return hscrolled_p
;
13471 /************************************************************************
13473 ************************************************************************/
13475 /* Variables holding some state of redisplay if GLYPH_DEBUG is defined.
13476 This is sometimes handy to have in a debugger session. */
13480 /* First and last unchanged row for try_window_id. */
13482 static int debug_first_unchanged_at_end_vpos
;
13483 static int debug_last_unchanged_at_beg_vpos
;
13485 /* Delta vpos and y. */
13487 static int debug_dvpos
, debug_dy
;
13489 /* Delta in characters and bytes for try_window_id. */
13491 static ptrdiff_t debug_delta
, debug_delta_bytes
;
13493 /* Values of window_end_pos and window_end_vpos at the end of
13496 static ptrdiff_t debug_end_vpos
;
13498 /* Append a string to W->desired_matrix->method. FMT is a printf
13499 format string. If trace_redisplay_p is true also printf the
13500 resulting string to stderr. */
13502 static void debug_method_add (struct window
*, char const *, ...)
13503 ATTRIBUTE_FORMAT_PRINTF (2, 3);
13506 debug_method_add (struct window
*w
, char const *fmt
, ...)
13509 char *method
= w
->desired_matrix
->method
;
13510 int len
= strlen (method
);
13511 int size
= sizeof w
->desired_matrix
->method
;
13512 int remaining
= size
- len
- 1;
13515 if (len
&& remaining
)
13518 --remaining
, ++len
;
13521 va_start (ap
, fmt
);
13522 vsnprintf (method
+ len
, remaining
+ 1, fmt
, ap
);
13525 if (trace_redisplay_p
)
13526 fprintf (stderr
, "%p (%s): %s\n",
13528 ((BUFFERP (w
->contents
)
13529 && STRINGP (BVAR (XBUFFER (w
->contents
), name
)))
13530 ? SSDATA (BVAR (XBUFFER (w
->contents
), name
))
13535 #endif /* GLYPH_DEBUG */
13538 /* Value is true if all changes in window W, which displays
13539 current_buffer, are in the text between START and END. START is a
13540 buffer position, END is given as a distance from Z. Used in
13541 redisplay_internal for display optimization. */
13544 text_outside_line_unchanged_p (struct window
*w
,
13545 ptrdiff_t start
, ptrdiff_t end
)
13547 bool unchanged_p
= true;
13549 /* If text or overlays have changed, see where. */
13550 if (window_outdated (w
))
13552 /* Gap in the line? */
13553 if (GPT
< start
|| Z
- GPT
< end
)
13554 unchanged_p
= false;
13556 /* Changes start in front of the line, or end after it? */
13558 && (BEG_UNCHANGED
< start
- 1
13559 || END_UNCHANGED
< end
))
13560 unchanged_p
= false;
13562 /* If selective display, can't optimize if changes start at the
13563 beginning of the line. */
13565 && INTEGERP (BVAR (current_buffer
, selective_display
))
13566 && XINT (BVAR (current_buffer
, selective_display
)) > 0
13567 && (BEG_UNCHANGED
< start
|| GPT
<= start
))
13568 unchanged_p
= false;
13570 /* If there are overlays at the start or end of the line, these
13571 may have overlay strings with newlines in them. A change at
13572 START, for instance, may actually concern the display of such
13573 overlay strings as well, and they are displayed on different
13574 lines. So, quickly rule out this case. (For the future, it
13575 might be desirable to implement something more telling than
13576 just BEG/END_UNCHANGED.) */
13579 if (BEG
+ BEG_UNCHANGED
== start
13580 && overlay_touches_p (start
))
13581 unchanged_p
= false;
13582 if (END_UNCHANGED
== end
13583 && overlay_touches_p (Z
- end
))
13584 unchanged_p
= false;
13587 /* Under bidi reordering, adding or deleting a character in the
13588 beginning of a paragraph, before the first strong directional
13589 character, can change the base direction of the paragraph (unless
13590 the buffer specifies a fixed paragraph direction), which will
13591 require redisplaying the whole paragraph. It might be worthwhile
13592 to find the paragraph limits and widen the range of redisplayed
13593 lines to that, but for now just give up this optimization. */
13594 if (!NILP (BVAR (XBUFFER (w
->contents
), bidi_display_reordering
))
13595 && NILP (BVAR (XBUFFER (w
->contents
), bidi_paragraph_direction
)))
13596 unchanged_p
= false;
13599 return unchanged_p
;
13603 /* Do a frame update, taking possible shortcuts into account. This is
13604 the main external entry point for redisplay.
13606 If the last redisplay displayed an echo area message and that message
13607 is no longer requested, we clear the echo area or bring back the
13608 mini-buffer if that is in use. */
13613 redisplay_internal ();
13618 overlay_arrow_string_or_property (Lisp_Object var
)
13622 if (val
= Fget (var
, Qoverlay_arrow_string
), STRINGP (val
))
13625 return Voverlay_arrow_string
;
13628 /* Return true if there are any overlay-arrows in current_buffer. */
13630 overlay_arrow_in_current_buffer_p (void)
13634 for (vlist
= Voverlay_arrow_variable_list
;
13636 vlist
= XCDR (vlist
))
13638 Lisp_Object var
= XCAR (vlist
);
13641 if (!SYMBOLP (var
))
13643 val
= find_symbol_value (var
);
13645 && current_buffer
== XMARKER (val
)->buffer
)
13652 /* Return true if any overlay_arrows have moved or overlay-arrow-string
13654 If SET_REDISPLAY is true, additionally, set the `redisplay' bit in those
13655 buffers that are affected. */
13658 overlay_arrows_changed_p (bool set_redisplay
)
13661 bool changed
= false;
13663 for (vlist
= Voverlay_arrow_variable_list
;
13665 vlist
= XCDR (vlist
))
13667 Lisp_Object var
= XCAR (vlist
);
13668 Lisp_Object val
, pstr
;
13670 if (!SYMBOLP (var
))
13672 val
= find_symbol_value (var
);
13673 if (!MARKERP (val
))
13675 if (! EQ (COERCE_MARKER (val
),
13676 /* FIXME: Don't we have a problem, using such a global
13677 * "last-position" if the variable is buffer-local? */
13678 Fget (var
, Qlast_arrow_position
))
13679 || ! (pstr
= overlay_arrow_string_or_property (var
),
13680 EQ (pstr
, Fget (var
, Qlast_arrow_string
))))
13682 struct buffer
*buf
= XMARKER (val
)->buffer
;
13687 bset_redisplay (buf
);
13697 /* Mark overlay arrows to be updated on next redisplay. */
13700 update_overlay_arrows (int up_to_date
)
13704 for (vlist
= Voverlay_arrow_variable_list
;
13706 vlist
= XCDR (vlist
))
13708 Lisp_Object var
= XCAR (vlist
);
13710 if (!SYMBOLP (var
))
13713 if (up_to_date
> 0)
13715 Lisp_Object val
= find_symbol_value (var
);
13716 if (!MARKERP (val
))
13718 Fput (var
, Qlast_arrow_position
,
13719 COERCE_MARKER (val
));
13720 Fput (var
, Qlast_arrow_string
,
13721 overlay_arrow_string_or_property (var
));
13723 else if (up_to_date
< 0
13724 || !NILP (Fget (var
, Qlast_arrow_position
)))
13726 Fput (var
, Qlast_arrow_position
, Qt
);
13727 Fput (var
, Qlast_arrow_string
, Qt
);
13733 /* Return overlay arrow string to display at row.
13734 Return integer (bitmap number) for arrow bitmap in left fringe.
13735 Return nil if no overlay arrow. */
13738 overlay_arrow_at_row (struct it
*it
, struct glyph_row
*row
)
13742 for (vlist
= Voverlay_arrow_variable_list
;
13744 vlist
= XCDR (vlist
))
13746 Lisp_Object var
= XCAR (vlist
);
13749 if (!SYMBOLP (var
))
13752 val
= find_symbol_value (var
);
13755 && current_buffer
== XMARKER (val
)->buffer
13756 && (MATRIX_ROW_START_CHARPOS (row
) == marker_position (val
)))
13758 if (FRAME_WINDOW_P (it
->f
)
13759 /* FIXME: if ROW->reversed_p is set, this should test
13760 the right fringe, not the left one. */
13761 && WINDOW_LEFT_FRINGE_WIDTH (it
->w
) > 0)
13763 #ifdef HAVE_WINDOW_SYSTEM
13764 if (val
= Fget (var
, Qoverlay_arrow_bitmap
), SYMBOLP (val
))
13766 int fringe_bitmap
= lookup_fringe_bitmap (val
);
13767 if (fringe_bitmap
!= 0)
13768 return make_number (fringe_bitmap
);
13771 return make_number (-1); /* Use default arrow bitmap. */
13773 return overlay_arrow_string_or_property (var
);
13780 /* Return true if point moved out of or into a composition. Otherwise
13781 return false. PREV_BUF and PREV_PT are the last point buffer and
13782 position. BUF and PT are the current point buffer and position. */
13785 check_point_in_composition (struct buffer
*prev_buf
, ptrdiff_t prev_pt
,
13786 struct buffer
*buf
, ptrdiff_t pt
)
13788 ptrdiff_t start
, end
;
13790 Lisp_Object buffer
;
13792 XSETBUFFER (buffer
, buf
);
13793 /* Check a composition at the last point if point moved within the
13795 if (prev_buf
== buf
)
13798 /* Point didn't move. */
13801 if (prev_pt
> BUF_BEGV (buf
) && prev_pt
< BUF_ZV (buf
)
13802 && find_composition (prev_pt
, -1, &start
, &end
, &prop
, buffer
)
13803 && composition_valid_p (start
, end
, prop
)
13804 && start
< prev_pt
&& end
> prev_pt
)
13805 /* The last point was within the composition. Return true iff
13806 point moved out of the composition. */
13807 return (pt
<= start
|| pt
>= end
);
13810 /* Check a composition at the current point. */
13811 return (pt
> BUF_BEGV (buf
) && pt
< BUF_ZV (buf
)
13812 && find_composition (pt
, -1, &start
, &end
, &prop
, buffer
)
13813 && composition_valid_p (start
, end
, prop
)
13814 && start
< pt
&& end
> pt
);
13817 /* Reconsider the clip changes of buffer which is displayed in W. */
13820 reconsider_clip_changes (struct window
*w
)
13822 struct buffer
*b
= XBUFFER (w
->contents
);
13824 if (b
->clip_changed
13825 && w
->window_end_valid
13826 && w
->current_matrix
->buffer
== b
13827 && w
->current_matrix
->zv
== BUF_ZV (b
)
13828 && w
->current_matrix
->begv
== BUF_BEGV (b
))
13829 b
->clip_changed
= false;
13831 /* If display wasn't paused, and W is not a tool bar window, see if
13832 point has been moved into or out of a composition. In that case,
13833 set b->clip_changed to force updating the screen. If
13834 b->clip_changed has already been set, skip this check. */
13835 if (!b
->clip_changed
&& w
->window_end_valid
)
13837 ptrdiff_t pt
= (w
== XWINDOW (selected_window
)
13838 ? PT
: marker_position (w
->pointm
));
13840 if ((w
->current_matrix
->buffer
!= b
|| pt
!= w
->last_point
)
13841 && check_point_in_composition (w
->current_matrix
->buffer
,
13842 w
->last_point
, b
, pt
))
13843 b
->clip_changed
= true;
13848 propagate_buffer_redisplay (void)
13849 { /* Resetting b->text->redisplay is problematic!
13850 We can't just reset it in the case that some window that displays
13851 it has not been redisplayed; and such a window can stay
13852 unredisplayed for a long time if it's currently invisible.
13853 But we do want to reset it at the end of redisplay otherwise
13854 its displayed windows will keep being redisplayed over and over
13856 So we copy all b->text->redisplay flags up to their windows here,
13857 such that mark_window_display_accurate can safely reset
13858 b->text->redisplay. */
13859 Lisp_Object ws
= window_list ();
13860 for (; CONSP (ws
); ws
= XCDR (ws
))
13862 struct window
*thisw
= XWINDOW (XCAR (ws
));
13863 struct buffer
*thisb
= XBUFFER (thisw
->contents
);
13864 if (thisb
->text
->redisplay
)
13865 thisw
->redisplay
= true;
13869 #define STOP_POLLING \
13870 do { if (! polling_stopped_here) stop_polling (); \
13871 polling_stopped_here = true; } while (false)
13873 #define RESUME_POLLING \
13874 do { if (polling_stopped_here) start_polling (); \
13875 polling_stopped_here = false; } while (false)
13878 /* Perhaps in the future avoid recentering windows if it
13879 is not necessary; currently that causes some problems. */
13882 redisplay_internal (void)
13884 struct window
*w
= XWINDOW (selected_window
);
13888 bool must_finish
= false, match_p
;
13889 struct text_pos tlbufpos
, tlendpos
;
13890 int number_of_visible_frames
;
13893 bool polling_stopped_here
= false;
13894 Lisp_Object tail
, frame
;
13896 /* Set a limit to the number of retries we perform due to horizontal
13897 scrolling, this avoids getting stuck in an uninterruptible
13898 infinite loop (Bug #24633). */
13899 enum { MAX_HSCROLL_RETRIES
= 16 };
13900 int hscroll_retries
= 0;
13902 /* Limit the number of retries for when frame(s) become garbaged as
13903 result of redisplaying them. Some packages set various redisplay
13904 hooks, such as window-scroll-functions, to run Lisp that always
13905 calls APIs which cause the frame's garbaged flag to become set,
13906 so we loop indefinitely. */
13907 enum {MAX_GARBAGED_FRAME_RETRIES
= 2 };
13908 int garbaged_frame_retries
= 0;
13910 /* True means redisplay has to consider all windows on all
13911 frames. False, only selected_window is considered. */
13912 bool consider_all_windows_p
;
13914 /* True means redisplay has to redisplay the miniwindow. */
13915 bool update_miniwindow_p
= false;
13917 TRACE ((stderr
, "redisplay_internal %d\n", redisplaying_p
));
13919 /* No redisplay if running in batch mode or frame is not yet fully
13920 initialized, or redisplay is explicitly turned off by setting
13921 Vinhibit_redisplay. */
13922 if (FRAME_INITIAL_P (SELECTED_FRAME ())
13923 || !NILP (Vinhibit_redisplay
))
13926 /* Don't examine these until after testing Vinhibit_redisplay.
13927 When Emacs is shutting down, perhaps because its connection to
13928 X has dropped, we should not look at them at all. */
13929 fr
= XFRAME (w
->frame
);
13930 sf
= SELECTED_FRAME ();
13932 if (!fr
->glyphs_initialized_p
)
13935 #if defined (USE_X_TOOLKIT) || defined (USE_GTK) || defined (HAVE_NS)
13936 if (popup_activated ())
13938 #ifdef NS_IMPL_COCOA
13939 /* On macOS we may have disabled screen updates due to window
13940 resizing. We should re-enable them so the popup can be
13942 ns_enable_screen_updates ();
13948 /* I don't think this happens but let's be paranoid. */
13949 if (redisplaying_p
)
13952 /* Record a function that clears redisplaying_p
13953 when we leave this function. */
13954 count
= SPECPDL_INDEX ();
13955 record_unwind_protect_void (unwind_redisplay
);
13956 redisplaying_p
= true;
13957 block_buffer_flips ();
13958 specbind (Qinhibit_free_realized_faces
, Qnil
);
13960 /* Record this function, so it appears on the profiler's backtraces. */
13961 record_in_backtrace (Qredisplay_internal_xC_functionx
, 0, 0);
13963 FOR_EACH_FRAME (tail
, frame
)
13964 XFRAME (frame
)->already_hscrolled_p
= false;
13967 /* Remember the currently selected window. */
13971 forget_escape_and_glyphless_faces ();
13973 inhibit_free_realized_faces
= false;
13975 /* If face_change, init_iterator will free all realized faces, which
13976 includes the faces referenced from current matrices. So, we
13977 can't reuse current matrices in this case. */
13979 windows_or_buffers_changed
= 47;
13981 if ((FRAME_TERMCAP_P (sf
) || FRAME_MSDOS_P (sf
))
13982 && FRAME_TTY (sf
)->previous_frame
!= sf
)
13984 /* Since frames on a single ASCII terminal share the same
13985 display area, displaying a different frame means redisplay
13986 the whole thing. */
13987 SET_FRAME_GARBAGED (sf
);
13989 set_tty_color_mode (FRAME_TTY (sf
), sf
);
13991 FRAME_TTY (sf
)->previous_frame
= sf
;
13994 /* Set the visible flags for all frames. Do this before checking for
13995 resized or garbaged frames; they want to know if their frames are
13996 visible. See the comment in frame.h for FRAME_SAMPLE_VISIBILITY. */
13997 number_of_visible_frames
= 0;
13999 FOR_EACH_FRAME (tail
, frame
)
14001 struct frame
*f
= XFRAME (frame
);
14003 if (FRAME_VISIBLE_P (f
))
14005 ++number_of_visible_frames
;
14006 /* Adjust matrices for visible frames only. */
14007 if (f
->fonts_changed
)
14009 adjust_frame_glyphs (f
);
14010 /* Disable all redisplay optimizations for this frame.
14011 This is because adjust_frame_glyphs resets the
14012 enabled_p flag for all glyph rows of all windows, so
14013 many optimizations will fail anyway, and some might
14014 fail to test that flag and do bogus things as
14016 SET_FRAME_GARBAGED (f
);
14017 f
->fonts_changed
= false;
14019 /* If cursor type has been changed on the frame
14020 other than selected, consider all frames. */
14021 if (f
!= sf
&& f
->cursor_type_changed
)
14022 fset_redisplay (f
);
14024 clear_desired_matrices (f
);
14027 /* Notice any pending interrupt request to change frame size. */
14028 do_pending_window_change (true);
14030 /* Clear frames marked as garbaged. */
14031 clear_garbaged_frames ();
14033 /* Build menubar and tool-bar items. */
14034 if (NILP (Vmemory_full
))
14035 prepare_menu_bars ();
14037 /* do_pending_window_change could change the selected_window due to
14038 frame resizing which makes the selected window too small.
14039 prepare_menu_bars may call lisp hooks and hence also change the
14040 selected_window. */
14041 if (WINDOWP (selected_window
) && (w
= XWINDOW (selected_window
)) != sw
)
14044 reconsider_clip_changes (w
);
14046 /* In most cases selected window displays current buffer. */
14047 match_p
= XBUFFER (w
->contents
) == current_buffer
;
14050 /* Detect case that we need to write or remove a star in the mode line. */
14051 if ((SAVE_MODIFF
< MODIFF
) != w
->last_had_star
)
14052 w
->update_mode_line
= true;
14054 if (mode_line_update_needed (w
))
14055 w
->update_mode_line
= true;
14057 /* If reconsider_clip_changes above decided that the narrowing
14058 in the current buffer changed, make sure all other windows
14059 showing that buffer will be redisplayed. */
14060 if (current_buffer
->clip_changed
)
14061 bset_update_mode_line (current_buffer
);
14064 /* Normally the message* functions will have already displayed and
14065 updated the echo area, but the frame may have been trashed, or
14066 the update may have been preempted, so display the echo area
14067 again here. Checking message_cleared_p captures the case that
14068 the echo area should be cleared. */
14069 if ((!NILP (echo_area_buffer
[0]) && !display_last_displayed_message_p
)
14070 || (!NILP (echo_area_buffer
[1]) && display_last_displayed_message_p
)
14071 || (message_cleared_p
14072 && minibuf_level
== 0
14073 /* If the mini-window is currently selected, this means the
14074 echo-area doesn't show through. */
14075 && !MINI_WINDOW_P (XWINDOW (selected_window
))))
14077 echo_area_display (false);
14079 /* If echo_area_display resizes the mini-window, the redisplay and
14080 window_sizes_changed flags of the selected frame are set, but
14081 it's too late for the hooks in window-size-change-functions,
14082 which have been examined already in prepare_menu_bars. So in
14083 that case we call the hooks here only for the selected frame. */
14086 ptrdiff_t count1
= SPECPDL_INDEX ();
14088 record_unwind_save_match_data ();
14089 run_window_size_change_functions (selected_frame
);
14090 unbind_to (count1
, Qnil
);
14093 if (message_cleared_p
)
14094 update_miniwindow_p
= true;
14096 must_finish
= true;
14098 /* If we don't display the current message, don't clear the
14099 message_cleared_p flag, because, if we did, we wouldn't clear
14100 the echo area in the next redisplay which doesn't preserve
14102 if (!display_last_displayed_message_p
)
14103 message_cleared_p
= false;
14105 else if (EQ (selected_window
, minibuf_window
)
14106 && (current_buffer
->clip_changed
|| window_outdated (w
))
14107 && resize_mini_window (w
, false))
14111 ptrdiff_t count1
= SPECPDL_INDEX ();
14113 record_unwind_save_match_data ();
14114 run_window_size_change_functions (selected_frame
);
14115 unbind_to (count1
, Qnil
);
14118 /* Resized active mini-window to fit the size of what it is
14119 showing if its contents might have changed. */
14120 must_finish
= true;
14122 /* If window configuration was changed, frames may have been
14123 marked garbaged. Clear them or we will experience
14124 surprises wrt scrolling. */
14125 clear_garbaged_frames ();
14128 if (windows_or_buffers_changed
&& !update_mode_lines
)
14129 /* Code that sets windows_or_buffers_changed doesn't distinguish whether
14130 only the windows's contents needs to be refreshed, or whether the
14131 mode-lines also need a refresh. */
14132 update_mode_lines
= (windows_or_buffers_changed
== REDISPLAY_SOME
14133 ? REDISPLAY_SOME
: 32);
14135 /* If specs for an arrow have changed, do thorough redisplay
14136 to ensure we remove any arrow that should no longer exist. */
14137 /* Apparently, this is the only case where we update other windows,
14138 without updating other mode-lines. */
14139 overlay_arrows_changed_p (true);
14141 consider_all_windows_p
= (update_mode_lines
14142 || windows_or_buffers_changed
);
14144 #define AINC(a,i) \
14146 Lisp_Object entry = Fgethash (make_number (i), a, make_number (0)); \
14147 if (INTEGERP (entry)) \
14148 Fputhash (make_number (i), make_number (1 + XINT (entry)), a); \
14151 AINC (Vredisplay__all_windows_cause
, windows_or_buffers_changed
);
14152 AINC (Vredisplay__mode_lines_cause
, update_mode_lines
);
14154 /* Optimize the case that only the line containing the cursor in the
14155 selected window has changed. Variables starting with this_ are
14156 set in display_line and record information about the line
14157 containing the cursor. */
14158 tlbufpos
= this_line_start_pos
;
14159 tlendpos
= this_line_end_pos
;
14160 if (!consider_all_windows_p
14161 && CHARPOS (tlbufpos
) > 0
14162 && !w
->update_mode_line
14163 && !current_buffer
->clip_changed
14164 && !current_buffer
->prevent_redisplay_optimizations_p
14165 && FRAME_VISIBLE_P (XFRAME (w
->frame
))
14166 && !FRAME_OBSCURED_P (XFRAME (w
->frame
))
14167 && !XFRAME (w
->frame
)->cursor_type_changed
14168 && !XFRAME (w
->frame
)->face_change
14169 /* Make sure recorded data applies to current buffer, etc. */
14170 && this_line_buffer
== current_buffer
14173 && !w
->optional_new_start
14174 /* Point must be on the line that we have info recorded about. */
14175 && PT
>= CHARPOS (tlbufpos
)
14176 && PT
<= Z
- CHARPOS (tlendpos
)
14177 /* All text outside that line, including its final newline,
14178 must be unchanged. */
14179 && text_outside_line_unchanged_p (w
, CHARPOS (tlbufpos
),
14180 CHARPOS (tlendpos
)))
14182 if (CHARPOS (tlbufpos
) > BEGV
14183 && FETCH_BYTE (BYTEPOS (tlbufpos
) - 1) != '\n'
14184 && (CHARPOS (tlbufpos
) == ZV
14185 || FETCH_BYTE (BYTEPOS (tlbufpos
)) == '\n'))
14186 /* Former continuation line has disappeared by becoming empty. */
14188 else if (window_outdated (w
) || MINI_WINDOW_P (w
))
14190 /* We have to handle the case of continuation around a
14191 wide-column character (see the comment in indent.c around
14194 For instance, in the following case:
14196 -------- Insert --------
14197 K_A_N_\\ `a' K_A_N_a\ `X_' are wide-column chars.
14198 J_I_ ==> J_I_ `^^' are cursors.
14202 As we have to redraw the line above, we cannot use this
14206 int line_height_before
= this_line_pixel_height
;
14208 /* Note that start_display will handle the case that the
14209 line starting at tlbufpos is a continuation line. */
14210 start_display (&it
, w
, tlbufpos
);
14212 /* Implementation note: It this still necessary? */
14213 if (it
.current_x
!= this_line_start_x
)
14216 TRACE ((stderr
, "trying display optimization 1\n"));
14217 w
->cursor
.vpos
= -1;
14218 overlay_arrow_seen
= false;
14219 it
.vpos
= this_line_vpos
;
14220 it
.current_y
= this_line_y
;
14221 it
.glyph_row
= MATRIX_ROW (w
->desired_matrix
, this_line_vpos
);
14222 display_line (&it
, -1);
14224 /* If line contains point, is not continued,
14225 and ends at same distance from eob as before, we win. */
14226 if (w
->cursor
.vpos
>= 0
14227 /* Line is not continued, otherwise this_line_start_pos
14228 would have been set to 0 in display_line. */
14229 && CHARPOS (this_line_start_pos
)
14230 /* Line ends as before. */
14231 && CHARPOS (this_line_end_pos
) == CHARPOS (tlendpos
)
14232 /* Line has same height as before. Otherwise other lines
14233 would have to be shifted up or down. */
14234 && this_line_pixel_height
== line_height_before
)
14236 /* If this is not the window's last line, we must adjust
14237 the charstarts of the lines below. */
14238 if (it
.current_y
< it
.last_visible_y
)
14240 struct glyph_row
*row
14241 = MATRIX_ROW (w
->current_matrix
, this_line_vpos
+ 1);
14242 ptrdiff_t delta
, delta_bytes
;
14244 /* We used to distinguish between two cases here,
14245 conditioned by Z - CHARPOS (tlendpos) == ZV, for
14246 when the line ends in a newline or the end of the
14247 buffer's accessible portion. But both cases did
14248 the same, so they were collapsed. */
14250 - CHARPOS (tlendpos
)
14251 - MATRIX_ROW_START_CHARPOS (row
));
14252 delta_bytes
= (Z_BYTE
14253 - BYTEPOS (tlendpos
)
14254 - MATRIX_ROW_START_BYTEPOS (row
));
14256 increment_matrix_positions (w
->current_matrix
,
14257 this_line_vpos
+ 1,
14258 w
->current_matrix
->nrows
,
14259 delta
, delta_bytes
);
14262 /* If this row displays text now but previously didn't,
14263 or vice versa, w->window_end_vpos may have to be
14265 if (MATRIX_ROW_DISPLAYS_TEXT_P (it
.glyph_row
- 1))
14267 if (w
->window_end_vpos
< this_line_vpos
)
14268 w
->window_end_vpos
= this_line_vpos
;
14270 else if (w
->window_end_vpos
== this_line_vpos
14271 && this_line_vpos
> 0)
14272 w
->window_end_vpos
= this_line_vpos
- 1;
14273 w
->window_end_valid
= false;
14275 /* Update hint: No need to try to scroll in update_window. */
14276 w
->desired_matrix
->no_scrolling_p
= true;
14279 *w
->desired_matrix
->method
= 0;
14280 debug_method_add (w
, "optimization 1");
14282 #ifdef HAVE_WINDOW_SYSTEM
14283 update_window_fringes (w
, false);
14290 else if (/* Cursor position hasn't changed. */
14291 PT
== w
->last_point
14292 /* Make sure the cursor was last displayed
14293 in this window. Otherwise we have to reposition it. */
14295 /* PXW: Must be converted to pixels, probably. */
14296 && 0 <= w
->cursor
.vpos
14297 && w
->cursor
.vpos
< WINDOW_TOTAL_LINES (w
))
14301 do_pending_window_change (true);
14302 /* If selected_window changed, redisplay again. */
14303 if (WINDOWP (selected_window
)
14304 && (w
= XWINDOW (selected_window
)) != sw
)
14307 /* We used to always goto end_of_redisplay here, but this
14308 isn't enough if we have a blinking cursor. */
14309 if (w
->cursor_off_p
== w
->last_cursor_off_p
)
14310 goto end_of_redisplay
;
14314 /* If highlighting the region, or if the cursor is in the echo area,
14315 then we can't just move the cursor. */
14316 else if (NILP (Vshow_trailing_whitespace
)
14317 && !cursor_in_echo_area
)
14320 struct glyph_row
*row
;
14322 /* Skip from tlbufpos to PT and see where it is. Note that
14323 PT may be in invisible text. If so, we will end at the
14324 next visible position. */
14325 init_iterator (&it
, w
, CHARPOS (tlbufpos
), BYTEPOS (tlbufpos
),
14326 NULL
, DEFAULT_FACE_ID
);
14327 it
.current_x
= this_line_start_x
;
14328 it
.current_y
= this_line_y
;
14329 it
.vpos
= this_line_vpos
;
14331 /* The call to move_it_to stops in front of PT, but
14332 moves over before-strings. */
14333 move_it_to (&it
, PT
, -1, -1, -1, MOVE_TO_POS
);
14335 if (it
.vpos
== this_line_vpos
14336 && (row
= MATRIX_ROW (w
->current_matrix
, this_line_vpos
),
14339 eassert (this_line_vpos
== it
.vpos
);
14340 eassert (this_line_y
== it
.current_y
);
14341 set_cursor_from_row (w
, row
, w
->current_matrix
, 0, 0, 0, 0);
14342 if (cursor_row_fully_visible_p (w
, false, true))
14345 *w
->desired_matrix
->method
= 0;
14346 debug_method_add (w
, "optimization 3");
14358 /* Text changed drastically or point moved off of line. */
14359 SET_MATRIX_ROW_ENABLED_P (w
->desired_matrix
, this_line_vpos
, false);
14362 CHARPOS (this_line_start_pos
) = 0;
14363 ++clear_face_cache_count
;
14364 #ifdef HAVE_WINDOW_SYSTEM
14365 ++clear_image_cache_count
;
14368 /* Build desired matrices, and update the display. If
14369 consider_all_windows_p, do it for all windows on all frames that
14370 require redisplay, as specified by their 'redisplay' flag.
14371 Otherwise do it for selected_window, only. */
14373 if (consider_all_windows_p
)
14375 FOR_EACH_FRAME (tail
, frame
)
14376 XFRAME (frame
)->updated_p
= false;
14378 propagate_buffer_redisplay ();
14380 FOR_EACH_FRAME (tail
, frame
)
14382 struct frame
*f
= XFRAME (frame
);
14384 /* We don't have to do anything for unselected terminal
14386 if ((FRAME_TERMCAP_P (f
) || FRAME_MSDOS_P (f
))
14387 && !EQ (FRAME_TTY (f
)->top_frame
, frame
))
14391 if (FRAME_WINDOW_P (f
) || FRAME_TERMCAP_P (f
) || f
== sf
)
14394 /* Only GC scrollbars when we redisplay the whole frame. */
14395 = f
->redisplay
|| !REDISPLAY_SOME_P ();
14396 bool f_redisplay_flag
= f
->redisplay
;
14397 /* Mark all the scroll bars to be removed; we'll redeem
14398 the ones we want when we redisplay their windows. */
14399 if (gcscrollbars
&& FRAME_TERMINAL (f
)->condemn_scroll_bars_hook
)
14400 FRAME_TERMINAL (f
)->condemn_scroll_bars_hook (f
);
14402 if (FRAME_VISIBLE_P (f
) && !FRAME_OBSCURED_P (f
))
14403 redisplay_windows (FRAME_ROOT_WINDOW (f
));
14404 /* Remember that the invisible frames need to be redisplayed next
14405 time they're visible. */
14406 else if (!REDISPLAY_SOME_P ())
14407 f
->redisplay
= true;
14409 /* The X error handler may have deleted that frame. */
14410 if (!FRAME_LIVE_P (f
))
14413 /* Any scroll bars which redisplay_windows should have
14414 nuked should now go away. */
14415 if (gcscrollbars
&& FRAME_TERMINAL (f
)->judge_scroll_bars_hook
)
14416 FRAME_TERMINAL (f
)->judge_scroll_bars_hook (f
);
14418 if (FRAME_VISIBLE_P (f
) && !FRAME_OBSCURED_P (f
))
14420 /* If fonts changed on visible frame, display again. */
14421 if (f
->fonts_changed
)
14423 adjust_frame_glyphs (f
);
14424 /* Disable all redisplay optimizations for this
14425 frame. For the reasons, see the comment near
14426 the previous call to adjust_frame_glyphs above. */
14427 SET_FRAME_GARBAGED (f
);
14428 f
->fonts_changed
= false;
14432 /* See if we have to hscroll. */
14433 if (!f
->already_hscrolled_p
)
14435 f
->already_hscrolled_p
= true;
14436 if (hscroll_retries
<= MAX_HSCROLL_RETRIES
14437 && hscroll_windows (f
->root_window
))
14444 /* If the frame's redisplay flag was not set before
14445 we went about redisplaying its windows, but it is
14446 set now, that means we employed some redisplay
14447 optimizations inside redisplay_windows, and
14448 bypassed producing some screen lines. But if
14449 f->redisplay is now set, it might mean the old
14450 faces are no longer valid (e.g., if redisplaying
14451 some window called some Lisp which defined a new
14452 face or redefined an existing face), so trying to
14453 use them in update_frame will segfault.
14454 Therefore, we must redisplay this frame. */
14455 if (!f_redisplay_flag
&& f
->redisplay
)
14457 /* In some case (e.g., window resize), we notice
14458 only during window updating that the window
14459 content changed unpredictably (e.g., a GTK
14460 scrollbar moved, or some Lisp hook that winds up
14461 calling adjust_frame_glyphs) and that our
14462 previous estimation of the frame content was
14463 garbage. We have to start over. These cases
14464 should be rare, so going all the way back to the
14465 top of redisplay should be good enough. */
14466 if (FRAME_GARBAGED_P (f
)
14467 && garbaged_frame_retries
++ < MAX_GARBAGED_FRAME_RETRIES
)
14470 #if defined (HAVE_WINDOW_SYSTEM) && !defined (HAVE_NS)
14471 x_clear_under_internal_border (f
);
14472 #endif /* HAVE_WINDOW_SYSTEM && !HAVE_NS */
14474 /* Prevent various kinds of signals during display
14475 update. stdio is not robust about handling
14476 signals, which can cause an apparent I/O error. */
14477 if (interrupt_input
)
14478 unrequest_sigio ();
14481 pending
|= update_frame (f
, false, false);
14482 f
->cursor_type_changed
= false;
14483 f
->updated_p
= true;
14488 eassert (EQ (XFRAME (selected_frame
)->selected_window
, selected_window
));
14492 /* Do the mark_window_display_accurate after all windows have
14493 been redisplayed because this call resets flags in buffers
14494 which are needed for proper redisplay. */
14495 FOR_EACH_FRAME (tail
, frame
)
14497 struct frame
*f
= XFRAME (frame
);
14500 f
->redisplay
= false;
14501 f
->garbaged
= false;
14502 mark_window_display_accurate (f
->root_window
, true);
14503 if (FRAME_TERMINAL (f
)->frame_up_to_date_hook
)
14504 FRAME_TERMINAL (f
)->frame_up_to_date_hook (f
);
14509 else if (FRAME_VISIBLE_P (sf
) && !FRAME_OBSCURED_P (sf
))
14511 displayed_buffer
= XBUFFER (XWINDOW (selected_window
)->contents
);
14512 /* Use list_of_error, not Qerror, so that
14513 we catch only errors and don't run the debugger. */
14514 internal_condition_case_1 (redisplay_window_1
, selected_window
,
14516 redisplay_window_error
);
14517 if (update_miniwindow_p
)
14518 internal_condition_case_1 (redisplay_window_1
,
14519 FRAME_MINIBUF_WINDOW (sf
), list_of_error
,
14520 redisplay_window_error
);
14522 /* Compare desired and current matrices, perform output. */
14525 /* If fonts changed, display again. Likewise if redisplay_window_1
14526 above caused some change (e.g., a change in faces) that requires
14527 considering the entire frame again. */
14528 if (sf
->fonts_changed
|| sf
->redisplay
)
14532 /* Set this to force a more thorough redisplay.
14533 Otherwise, we might immediately loop back to the
14534 above "else-if" clause (since all the conditions that
14535 led here might still be true), and we will then
14536 infloop, because the selected-frame's redisplay flag
14537 is not (and cannot be) reset. */
14538 windows_or_buffers_changed
= 50;
14543 /* Prevent freeing of realized faces, since desired matrices are
14544 pending that reference the faces we computed and cached. */
14545 inhibit_free_realized_faces
= true;
14547 /* Prevent various kinds of signals during display update.
14548 stdio is not robust about handling signals,
14549 which can cause an apparent I/O error. */
14550 if (interrupt_input
)
14551 unrequest_sigio ();
14554 if (FRAME_VISIBLE_P (sf
) && !FRAME_OBSCURED_P (sf
))
14556 if (hscroll_retries
<= MAX_HSCROLL_RETRIES
14557 && hscroll_windows (selected_window
))
14563 XWINDOW (selected_window
)->must_be_updated_p
= true;
14564 pending
= update_frame (sf
, false, false);
14565 sf
->cursor_type_changed
= false;
14568 /* We may have called echo_area_display at the top of this
14569 function. If the echo area is on another frame, that may
14570 have put text on a frame other than the selected one, so the
14571 above call to update_frame would not have caught it. Catch
14573 Lisp_Object mini_window
= FRAME_MINIBUF_WINDOW (sf
);
14574 struct frame
*mini_frame
= XFRAME (WINDOW_FRAME (XWINDOW (mini_window
)));
14576 if (mini_frame
!= sf
&& FRAME_WINDOW_P (mini_frame
))
14578 XWINDOW (mini_window
)->must_be_updated_p
= true;
14579 pending
|= update_frame (mini_frame
, false, false);
14580 mini_frame
->cursor_type_changed
= false;
14581 if (!pending
&& hscroll_retries
<= MAX_HSCROLL_RETRIES
14582 && hscroll_windows (mini_window
))
14590 /* If display was paused because of pending input, make sure we do a
14591 thorough update the next time. */
14594 /* Prevent the optimization at the beginning of
14595 redisplay_internal that tries a single-line update of the
14596 line containing the cursor in the selected window. */
14597 CHARPOS (this_line_start_pos
) = 0;
14599 /* Let the overlay arrow be updated the next time. */
14600 update_overlay_arrows (0);
14602 /* If we pause after scrolling, some rows in the current
14603 matrices of some windows are not valid. */
14604 if (!WINDOW_FULL_WIDTH_P (w
)
14605 && !FRAME_WINDOW_P (XFRAME (w
->frame
)))
14606 update_mode_lines
= 36;
14610 if (!consider_all_windows_p
)
14612 /* This has already been done above if
14613 consider_all_windows_p is set. */
14614 if (XBUFFER (w
->contents
)->text
->redisplay
14615 && buffer_window_count (XBUFFER (w
->contents
)) > 1)
14616 /* This can happen if b->text->redisplay was set during
14618 propagate_buffer_redisplay ();
14619 mark_window_display_accurate_1 (w
, true);
14621 /* Say overlay arrows are up to date. */
14622 update_overlay_arrows (1);
14624 if (FRAME_TERMINAL (sf
)->frame_up_to_date_hook
!= 0)
14625 FRAME_TERMINAL (sf
)->frame_up_to_date_hook (sf
);
14628 update_mode_lines
= 0;
14629 windows_or_buffers_changed
= 0;
14632 /* Start SIGIO interrupts coming again. Having them off during the
14633 code above makes it less likely one will discard output, but not
14634 impossible, since there might be stuff in the system buffer here.
14635 But it is much hairier to try to do anything about that. */
14636 if (interrupt_input
)
14640 /* If a frame has become visible which was not before, redisplay
14641 again, so that we display it. Expose events for such a frame
14642 (which it gets when becoming visible) don't call the parts of
14643 redisplay constructing glyphs, so simply exposing a frame won't
14644 display anything in this case. So, we have to display these
14645 frames here explicitly. */
14650 FOR_EACH_FRAME (tail
, frame
)
14652 if (XFRAME (frame
)->visible
)
14656 if (new_count
!= number_of_visible_frames
)
14657 windows_or_buffers_changed
= 52;
14660 /* Change frame size now if a change is pending. */
14661 do_pending_window_change (true);
14663 /* If we just did a pending size change, or have additional
14664 visible frames, or selected_window changed, redisplay again. */
14665 if ((windows_or_buffers_changed
&& !pending
)
14666 || (WINDOWP (selected_window
) && (w
= XWINDOW (selected_window
)) != sw
))
14669 /* Clear the face and image caches.
14671 We used to do this only if consider_all_windows_p. But the cache
14672 needs to be cleared if a timer creates images in the current
14673 buffer (e.g. the test case in Bug#6230). */
14675 if (clear_face_cache_count
> CLEAR_FACE_CACHE_COUNT
)
14677 clear_face_cache (false);
14678 clear_face_cache_count
= 0;
14681 #ifdef HAVE_WINDOW_SYSTEM
14682 if (clear_image_cache_count
> CLEAR_IMAGE_CACHE_COUNT
)
14684 clear_image_caches (Qnil
);
14685 clear_image_cache_count
= 0;
14687 #endif /* HAVE_WINDOW_SYSTEM */
14691 ns_set_doc_edited ();
14693 if (interrupt_input
&& interrupts_deferred
)
14696 unbind_to (count
, Qnil
);
14701 unwind_redisplay_preserve_echo_area (void)
14703 unblock_buffer_flips ();
14706 /* Redisplay, but leave alone any recent echo area message unless
14707 another message has been requested in its place.
14709 This is useful in situations where you need to redisplay but no
14710 user action has occurred, making it inappropriate for the message
14711 area to be cleared. See tracking_off and
14712 wait_reading_process_output for examples of these situations.
14714 FROM_WHERE is an integer saying from where this function was
14715 called. This is useful for debugging. */
14718 redisplay_preserve_echo_area (int from_where
)
14720 TRACE ((stderr
, "redisplay_preserve_echo_area (%d)\n", from_where
));
14723 ptrdiff_t count
= SPECPDL_INDEX ();
14724 record_unwind_protect_void (unwind_redisplay_preserve_echo_area
);
14725 block_buffer_flips ();
14728 if (!NILP (echo_area_buffer
[1]))
14730 /* We have a previously displayed message, but no current
14731 message. Redisplay the previous message. */
14732 display_last_displayed_message_p
= true;
14733 redisplay_internal ();
14734 display_last_displayed_message_p
= false;
14737 redisplay_internal ();
14739 flush_frame (SELECTED_FRAME ());
14740 unbind_to (count
, Qnil
);
14744 /* Function registered with record_unwind_protect in redisplay_internal. */
14747 unwind_redisplay (void)
14749 redisplaying_p
= false;
14750 unblock_buffer_flips ();
14751 #ifdef NS_IMPL_COCOA
14752 /* On macOS we may have disabled screen updates due to window
14753 resizing. When redisplay completes we want to re-enable
14755 ns_enable_screen_updates ();
14760 /* Mark the display of leaf window W as accurate or inaccurate.
14761 If ACCURATE_P, mark display of W as accurate.
14762 If !ACCURATE_P, arrange for W to be redisplayed the next
14763 time redisplay_internal is called. */
14766 mark_window_display_accurate_1 (struct window
*w
, bool accurate_p
)
14768 struct buffer
*b
= XBUFFER (w
->contents
);
14770 w
->last_modified
= accurate_p
? BUF_MODIFF (b
) : 0;
14771 w
->last_overlay_modified
= accurate_p
? BUF_OVERLAY_MODIFF (b
) : 0;
14772 w
->last_had_star
= BUF_MODIFF (b
) > BUF_SAVE_MODIFF (b
);
14776 b
->clip_changed
= false;
14777 b
->prevent_redisplay_optimizations_p
= false;
14778 eassert (buffer_window_count (b
) > 0);
14779 /* Resetting b->text->redisplay is problematic!
14780 In order to make it safer to do it here, redisplay_internal must
14781 have copied all b->text->redisplay to their respective windows. */
14782 b
->text
->redisplay
= false;
14784 BUF_UNCHANGED_MODIFIED (b
) = BUF_MODIFF (b
);
14785 BUF_OVERLAY_UNCHANGED_MODIFIED (b
) = BUF_OVERLAY_MODIFF (b
);
14786 BUF_BEG_UNCHANGED (b
) = BUF_GPT (b
) - BUF_BEG (b
);
14787 BUF_END_UNCHANGED (b
) = BUF_Z (b
) - BUF_GPT (b
);
14789 w
->current_matrix
->buffer
= b
;
14790 w
->current_matrix
->begv
= BUF_BEGV (b
);
14791 w
->current_matrix
->zv
= BUF_ZV (b
);
14793 w
->last_cursor_vpos
= w
->cursor
.vpos
;
14794 w
->last_cursor_off_p
= w
->cursor_off_p
;
14796 if (w
== XWINDOW (selected_window
))
14797 w
->last_point
= BUF_PT (b
);
14799 w
->last_point
= marker_position (w
->pointm
);
14801 w
->window_end_valid
= true;
14802 w
->update_mode_line
= false;
14805 w
->redisplay
= !accurate_p
;
14809 /* Mark the display of windows in the window tree rooted at WINDOW as
14810 accurate or inaccurate. If ACCURATE_P, mark display of
14811 windows as accurate. If !ACCURATE_P, arrange for windows to
14812 be redisplayed the next time redisplay_internal is called. */
14815 mark_window_display_accurate (Lisp_Object window
, bool accurate_p
)
14819 for (; !NILP (window
); window
= w
->next
)
14821 w
= XWINDOW (window
);
14822 if (WINDOWP (w
->contents
))
14823 mark_window_display_accurate (w
->contents
, accurate_p
);
14825 mark_window_display_accurate_1 (w
, accurate_p
);
14829 update_overlay_arrows (1);
14831 /* Force a thorough redisplay the next time by setting
14832 last_arrow_position and last_arrow_string to t, which is
14833 unequal to any useful value of Voverlay_arrow_... */
14834 update_overlay_arrows (-1);
14838 /* Return value in display table DP (Lisp_Char_Table *) for character
14839 C. Since a display table doesn't have any parent, we don't have to
14840 follow parent. Do not call this function directly but use the
14841 macro DISP_CHAR_VECTOR. */
14844 disp_char_vector (struct Lisp_Char_Table
*dp
, int c
)
14848 if (ASCII_CHAR_P (c
))
14851 if (SUB_CHAR_TABLE_P (val
))
14852 val
= XSUB_CHAR_TABLE (val
)->contents
[c
];
14858 XSETCHAR_TABLE (table
, dp
);
14859 val
= char_table_ref (table
, c
);
14866 static int buffer_flip_blocked_depth
;
14869 block_buffer_flips (void)
14871 eassert (buffer_flip_blocked_depth
>= 0);
14872 buffer_flip_blocked_depth
++;
14876 unblock_buffer_flips (void)
14878 eassert (buffer_flip_blocked_depth
> 0);
14879 if (--buffer_flip_blocked_depth
== 0)
14881 Lisp_Object tail
, frame
;
14883 FOR_EACH_FRAME (tail
, frame
)
14885 struct frame
*f
= XFRAME (frame
);
14886 if (FRAME_TERMINAL (f
)->buffer_flipping_unblocked_hook
)
14887 (*FRAME_TERMINAL (f
)->buffer_flipping_unblocked_hook
) (f
);
14894 buffer_flipping_blocked_p (void)
14896 return buffer_flip_blocked_depth
> 0;
14900 /***********************************************************************
14902 ***********************************************************************/
14904 /* Redisplay all leaf windows in the window tree rooted at WINDOW. */
14907 redisplay_windows (Lisp_Object window
)
14909 while (!NILP (window
))
14911 struct window
*w
= XWINDOW (window
);
14913 if (WINDOWP (w
->contents
))
14914 redisplay_windows (w
->contents
);
14915 else if (BUFFERP (w
->contents
))
14917 displayed_buffer
= XBUFFER (w
->contents
);
14918 /* Use list_of_error, not Qerror, so that
14919 we catch only errors and don't run the debugger. */
14920 internal_condition_case_1 (redisplay_window_0
, window
,
14922 redisplay_window_error
);
14930 redisplay_window_error (Lisp_Object ignore
)
14932 displayed_buffer
->display_error_modiff
= BUF_MODIFF (displayed_buffer
);
14937 redisplay_window_0 (Lisp_Object window
)
14939 if (displayed_buffer
->display_error_modiff
< BUF_MODIFF (displayed_buffer
))
14940 redisplay_window (window
, false);
14945 redisplay_window_1 (Lisp_Object window
)
14947 if (displayed_buffer
->display_error_modiff
< BUF_MODIFF (displayed_buffer
))
14948 redisplay_window (window
, true);
14953 /* Set cursor position of W. PT is assumed to be displayed in ROW.
14954 DELTA and DELTA_BYTES are the numbers of characters and bytes by
14955 which positions recorded in ROW differ from current buffer
14958 Return true iff cursor is on this row. */
14961 set_cursor_from_row (struct window
*w
, struct glyph_row
*row
,
14962 struct glyph_matrix
*matrix
,
14963 ptrdiff_t delta
, ptrdiff_t delta_bytes
,
14966 struct glyph
*glyph
= row
->glyphs
[TEXT_AREA
];
14967 struct glyph
*end
= glyph
+ row
->used
[TEXT_AREA
];
14968 struct glyph
*cursor
= NULL
;
14969 /* The last known character position in row. */
14970 ptrdiff_t last_pos
= MATRIX_ROW_START_CHARPOS (row
) + delta
;
14972 ptrdiff_t pt_old
= PT
- delta
;
14973 ptrdiff_t pos_before
= MATRIX_ROW_START_CHARPOS (row
) + delta
;
14974 ptrdiff_t pos_after
= MATRIX_ROW_END_CHARPOS (row
) + delta
;
14975 struct glyph
*glyph_before
= glyph
- 1, *glyph_after
= end
;
14976 /* A glyph beyond the edge of TEXT_AREA which we should never
14978 struct glyph
*glyphs_end
= end
;
14979 /* True means we've found a match for cursor position, but that
14980 glyph has the avoid_cursor_p flag set. */
14981 bool match_with_avoid_cursor
= false;
14982 /* True means we've seen at least one glyph that came from a
14984 bool string_seen
= false;
14985 /* Largest and smallest buffer positions seen so far during scan of
14987 ptrdiff_t bpos_max
= pos_before
;
14988 ptrdiff_t bpos_min
= pos_after
;
14989 /* Last buffer position covered by an overlay string with an integer
14990 `cursor' property. */
14991 ptrdiff_t bpos_covered
= 0;
14992 /* True means the display string on which to display the cursor
14993 comes from a text property, not from an overlay. */
14994 bool string_from_text_prop
= false;
14996 /* Don't even try doing anything if called for a mode-line or
14997 header-line row, since the rest of the code isn't prepared to
14998 deal with such calamities. */
14999 eassert (!row
->mode_line_p
);
15000 if (row
->mode_line_p
)
15003 /* Skip over glyphs not having an object at the start and the end of
15004 the row. These are special glyphs like truncation marks on
15005 terminal frames. */
15006 if (MATRIX_ROW_DISPLAYS_TEXT_P (row
))
15008 if (!row
->reversed_p
)
15011 && NILP (glyph
->object
)
15012 && glyph
->charpos
< 0)
15014 x
+= glyph
->pixel_width
;
15018 && NILP ((end
- 1)->object
)
15019 /* CHARPOS is zero for blanks and stretch glyphs
15020 inserted by extend_face_to_end_of_line. */
15021 && (end
- 1)->charpos
<= 0)
15023 glyph_before
= glyph
- 1;
15030 /* If the glyph row is reversed, we need to process it from back
15031 to front, so swap the edge pointers. */
15032 glyphs_end
= end
= glyph
- 1;
15033 glyph
+= row
->used
[TEXT_AREA
] - 1;
15035 while (glyph
> end
+ 1
15036 && NILP (glyph
->object
)
15037 && glyph
->charpos
< 0)
15039 if (NILP (glyph
->object
) && glyph
->charpos
< 0)
15041 /* By default, in reversed rows we put the cursor on the
15042 rightmost (first in the reading order) glyph. */
15043 for (x
= 0, g
= end
+ 1; g
< glyph
; g
++)
15044 x
+= g
->pixel_width
;
15046 && NILP ((end
+ 1)->object
)
15047 && (end
+ 1)->charpos
<= 0)
15049 glyph_before
= glyph
+ 1;
15053 else if (row
->reversed_p
)
15055 /* In R2L rows that don't display text, put the cursor on the
15056 rightmost glyph. Case in point: an empty last line that is
15057 part of an R2L paragraph. */
15059 /* Avoid placing the cursor on the last glyph of the row, where
15060 on terminal frames we hold the vertical border between
15061 adjacent windows. */
15062 if (!FRAME_WINDOW_P (WINDOW_XFRAME (w
))
15063 && !WINDOW_RIGHTMOST_P (w
)
15064 && cursor
== row
->glyphs
[LAST_AREA
] - 1)
15066 x
= -1; /* will be computed below, at label compute_x */
15069 /* Step 1: Try to find the glyph whose character position
15070 corresponds to point. If that's not possible, find 2 glyphs
15071 whose character positions are the closest to point, one before
15072 point, the other after it. */
15073 if (!row
->reversed_p
)
15074 while (/* not marched to end of glyph row */
15076 /* glyph was not inserted by redisplay for internal purposes */
15077 && !NILP (glyph
->object
))
15079 if (BUFFERP (glyph
->object
))
15081 ptrdiff_t dpos
= glyph
->charpos
- pt_old
;
15083 if (glyph
->charpos
> bpos_max
)
15084 bpos_max
= glyph
->charpos
;
15085 if (glyph
->charpos
< bpos_min
)
15086 bpos_min
= glyph
->charpos
;
15087 if (!glyph
->avoid_cursor_p
)
15089 /* If we hit point, we've found the glyph on which to
15090 display the cursor. */
15093 match_with_avoid_cursor
= false;
15096 /* See if we've found a better approximation to
15097 POS_BEFORE or to POS_AFTER. */
15098 if (0 > dpos
&& dpos
> pos_before
- pt_old
)
15100 pos_before
= glyph
->charpos
;
15101 glyph_before
= glyph
;
15103 else if (0 < dpos
&& dpos
< pos_after
- pt_old
)
15105 pos_after
= glyph
->charpos
;
15106 glyph_after
= glyph
;
15109 else if (dpos
== 0)
15110 match_with_avoid_cursor
= true;
15112 else if (STRINGP (glyph
->object
))
15114 Lisp_Object chprop
;
15115 ptrdiff_t glyph_pos
= glyph
->charpos
;
15117 chprop
= Fget_char_property (make_number (glyph_pos
), Qcursor
,
15119 if (!NILP (chprop
))
15121 /* If the string came from a `display' text property,
15122 look up the buffer position of that property and
15123 use that position to update bpos_max, as if we
15124 actually saw such a position in one of the row's
15125 glyphs. This helps with supporting integer values
15126 of `cursor' property on the display string in
15127 situations where most or all of the row's buffer
15128 text is completely covered by display properties,
15129 so that no glyph with valid buffer positions is
15130 ever seen in the row. */
15131 ptrdiff_t prop_pos
=
15132 string_buffer_position_lim (glyph
->object
, pos_before
,
15135 if (prop_pos
>= pos_before
)
15136 bpos_max
= prop_pos
;
15138 if (INTEGERP (chprop
))
15140 bpos_covered
= bpos_max
+ XINT (chprop
);
15141 /* If the `cursor' property covers buffer positions up
15142 to and including point, we should display cursor on
15143 this glyph. Note that, if a `cursor' property on one
15144 of the string's characters has an integer value, we
15145 will break out of the loop below _before_ we get to
15146 the position match above. IOW, integer values of
15147 the `cursor' property override the "exact match for
15148 point" strategy of positioning the cursor. */
15149 /* Implementation note: bpos_max == pt_old when, e.g.,
15150 we are in an empty line, where bpos_max is set to
15151 MATRIX_ROW_START_CHARPOS, see above. */
15152 if (bpos_max
<= pt_old
&& bpos_covered
>= pt_old
)
15159 string_seen
= true;
15161 x
+= glyph
->pixel_width
;
15164 else if (glyph
> end
) /* row is reversed */
15165 while (!NILP (glyph
->object
))
15167 if (BUFFERP (glyph
->object
))
15169 ptrdiff_t dpos
= glyph
->charpos
- pt_old
;
15171 if (glyph
->charpos
> bpos_max
)
15172 bpos_max
= glyph
->charpos
;
15173 if (glyph
->charpos
< bpos_min
)
15174 bpos_min
= glyph
->charpos
;
15175 if (!glyph
->avoid_cursor_p
)
15179 match_with_avoid_cursor
= false;
15182 if (0 > dpos
&& dpos
> pos_before
- pt_old
)
15184 pos_before
= glyph
->charpos
;
15185 glyph_before
= glyph
;
15187 else if (0 < dpos
&& dpos
< pos_after
- pt_old
)
15189 pos_after
= glyph
->charpos
;
15190 glyph_after
= glyph
;
15193 else if (dpos
== 0)
15194 match_with_avoid_cursor
= true;
15196 else if (STRINGP (glyph
->object
))
15198 Lisp_Object chprop
;
15199 ptrdiff_t glyph_pos
= glyph
->charpos
;
15201 chprop
= Fget_char_property (make_number (glyph_pos
), Qcursor
,
15203 if (!NILP (chprop
))
15205 ptrdiff_t prop_pos
=
15206 string_buffer_position_lim (glyph
->object
, pos_before
,
15209 if (prop_pos
>= pos_before
)
15210 bpos_max
= prop_pos
;
15212 if (INTEGERP (chprop
))
15214 bpos_covered
= bpos_max
+ XINT (chprop
);
15215 /* If the `cursor' property covers buffer positions up
15216 to and including point, we should display cursor on
15218 if (bpos_max
<= pt_old
&& bpos_covered
>= pt_old
)
15224 string_seen
= true;
15227 if (glyph
== glyphs_end
) /* don't dereference outside TEXT_AREA */
15229 x
--; /* can't use any pixel_width */
15232 x
-= glyph
->pixel_width
;
15235 /* Step 2: If we didn't find an exact match for point, we need to
15236 look for a proper place to put the cursor among glyphs between
15237 GLYPH_BEFORE and GLYPH_AFTER. */
15238 if (!((row
->reversed_p
? glyph
> glyphs_end
: glyph
< glyphs_end
)
15239 && BUFFERP (glyph
->object
) && glyph
->charpos
== pt_old
)
15240 && !(bpos_max
<= pt_old
&& pt_old
<= bpos_covered
))
15242 /* An empty line has a single glyph whose OBJECT is nil and
15243 whose CHARPOS is the position of a newline on that line.
15244 Note that on a TTY, there are more glyphs after that, which
15245 were produced by extend_face_to_end_of_line, but their
15246 CHARPOS is zero or negative. */
15247 bool empty_line_p
=
15248 ((row
->reversed_p
? glyph
> glyphs_end
: glyph
< glyphs_end
)
15249 && NILP (glyph
->object
) && glyph
->charpos
> 0
15250 /* On a TTY, continued and truncated rows also have a glyph at
15251 their end whose OBJECT is nil and whose CHARPOS is
15252 positive (the continuation and truncation glyphs), but such
15253 rows are obviously not "empty". */
15254 && !(row
->continued_p
|| row
->truncated_on_right_p
));
15256 if (row
->ends_in_ellipsis_p
&& pos_after
== last_pos
)
15258 ptrdiff_t ellipsis_pos
;
15260 /* Scan back over the ellipsis glyphs. */
15261 if (!row
->reversed_p
)
15263 ellipsis_pos
= (glyph
- 1)->charpos
;
15264 while (glyph
> row
->glyphs
[TEXT_AREA
]
15265 && (glyph
- 1)->charpos
== ellipsis_pos
)
15266 glyph
--, x
-= glyph
->pixel_width
;
15267 /* That loop always goes one position too far, including
15268 the glyph before the ellipsis. So scan forward over
15270 x
+= glyph
->pixel_width
;
15273 else /* row is reversed */
15275 ellipsis_pos
= (glyph
+ 1)->charpos
;
15276 while (glyph
< row
->glyphs
[TEXT_AREA
] + row
->used
[TEXT_AREA
] - 1
15277 && (glyph
+ 1)->charpos
== ellipsis_pos
)
15278 glyph
++, x
+= glyph
->pixel_width
;
15279 x
-= glyph
->pixel_width
;
15283 else if (match_with_avoid_cursor
)
15285 cursor
= glyph_after
;
15288 else if (string_seen
)
15290 int incr
= row
->reversed_p
? -1 : +1;
15292 /* Need to find the glyph that came out of a string which is
15293 present at point. That glyph is somewhere between
15294 GLYPH_BEFORE and GLYPH_AFTER, and it came from a string
15295 positioned between POS_BEFORE and POS_AFTER in the
15297 struct glyph
*start
, *stop
;
15298 ptrdiff_t pos
= pos_before
;
15302 /* If the row ends in a newline from a display string,
15303 reordering could have moved the glyphs belonging to the
15304 string out of the [GLYPH_BEFORE..GLYPH_AFTER] range. So
15305 in this case we extend the search to the last glyph in
15306 the row that was not inserted by redisplay. */
15307 if (row
->ends_in_newline_from_string_p
)
15310 pos_after
= MATRIX_ROW_END_CHARPOS (row
) + delta
;
15313 /* GLYPH_BEFORE and GLYPH_AFTER are the glyphs that
15314 correspond to POS_BEFORE and POS_AFTER, respectively. We
15315 need START and STOP in the order that corresponds to the
15316 row's direction as given by its reversed_p flag. If the
15317 directionality of characters between POS_BEFORE and
15318 POS_AFTER is the opposite of the row's base direction,
15319 these characters will have been reordered for display,
15320 and we need to reverse START and STOP. */
15321 if (!row
->reversed_p
)
15323 start
= min (glyph_before
, glyph_after
);
15324 stop
= max (glyph_before
, glyph_after
);
15328 start
= max (glyph_before
, glyph_after
);
15329 stop
= min (glyph_before
, glyph_after
);
15331 for (glyph
= start
+ incr
;
15332 row
->reversed_p
? glyph
> stop
: glyph
< stop
; )
15335 /* Any glyphs that come from the buffer are here because
15336 of bidi reordering. Skip them, and only pay
15337 attention to glyphs that came from some string. */
15338 if (STRINGP (glyph
->object
))
15342 /* If the display property covers the newline, we
15343 need to search for it one position farther. */
15344 ptrdiff_t lim
= pos_after
15345 + (pos_after
== MATRIX_ROW_END_CHARPOS (row
) + delta
);
15347 string_from_text_prop
= false;
15348 str
= glyph
->object
;
15349 tem
= string_buffer_position_lim (str
, pos
, lim
, false);
15350 if (tem
== 0 /* from overlay */
15353 /* If the string from which this glyph came is
15354 found in the buffer at point, or at position
15355 that is closer to point than pos_after, then
15356 we've found the glyph we've been looking for.
15357 If it comes from an overlay (tem == 0), and
15358 it has the `cursor' property on one of its
15359 glyphs, record that glyph as a candidate for
15360 displaying the cursor. (As in the
15361 unidirectional version, we will display the
15362 cursor on the last candidate we find.) */
15365 || (tem
- pt_old
> 0 && tem
< pos_after
))
15367 /* The glyphs from this string could have
15368 been reordered. Find the one with the
15369 smallest string position. Or there could
15370 be a character in the string with the
15371 `cursor' property, which means display
15372 cursor on that character's glyph. */
15373 ptrdiff_t strpos
= glyph
->charpos
;
15378 string_from_text_prop
= true;
15381 (row
->reversed_p
? glyph
> stop
: glyph
< stop
)
15382 && EQ (glyph
->object
, str
);
15386 ptrdiff_t gpos
= glyph
->charpos
;
15388 cprop
= Fget_char_property (make_number (gpos
),
15396 if (tem
&& glyph
->charpos
< strpos
)
15398 strpos
= glyph
->charpos
;
15404 || (tem
- pt_old
> 0 && tem
< pos_after
))
15408 pos
= tem
+ 1; /* don't find previous instances */
15410 /* This string is not what we want; skip all of the
15411 glyphs that came from it. */
15412 while ((row
->reversed_p
? glyph
> stop
: glyph
< stop
)
15413 && EQ (glyph
->object
, str
))
15420 /* If we reached the end of the line, and END was from a string,
15421 the cursor is not on this line. */
15423 && (row
->reversed_p
? glyph
<= end
: glyph
>= end
)
15424 && (row
->reversed_p
? end
> glyphs_end
: end
< glyphs_end
)
15425 && STRINGP (end
->object
)
15426 && row
->continued_p
)
15429 /* A truncated row may not include PT among its character positions.
15430 Setting the cursor inside the scroll margin will trigger
15431 recalculation of hscroll in hscroll_window_tree. But if a
15432 display string covers point, defer to the string-handling
15433 code below to figure this out. */
15434 else if (row
->truncated_on_left_p
&& pt_old
< bpos_min
)
15436 cursor
= glyph_before
;
15439 else if ((row
->truncated_on_right_p
&& pt_old
> bpos_max
)
15440 /* Zero-width characters produce no glyphs. */
15442 && (row
->reversed_p
15443 ? glyph_after
> glyphs_end
15444 : glyph_after
< glyphs_end
)))
15446 cursor
= glyph_after
;
15452 if (cursor
!= NULL
)
15454 else if (glyph
== glyphs_end
15455 && pos_before
== pos_after
15456 && STRINGP ((row
->reversed_p
15457 ? row
->glyphs
[TEXT_AREA
] + row
->used
[TEXT_AREA
] - 1
15458 : row
->glyphs
[TEXT_AREA
])->object
))
15460 /* If all the glyphs of this row came from strings, put the
15461 cursor on the first glyph of the row. This avoids having the
15462 cursor outside of the text area in this very rare and hard
15466 ? row
->glyphs
[TEXT_AREA
] + row
->used
[TEXT_AREA
] - 1
15467 : row
->glyphs
[TEXT_AREA
];
15473 /* Need to compute x that corresponds to GLYPH. */
15474 for (g
= row
->glyphs
[TEXT_AREA
], x
= row
->x
; g
< glyph
; g
++)
15476 if (g
>= row
->glyphs
[TEXT_AREA
] + row
->used
[TEXT_AREA
])
15478 x
+= g
->pixel_width
;
15482 /* ROW could be part of a continued line, which, under bidi
15483 reordering, might have other rows whose start and end charpos
15484 occlude point. Only set w->cursor if we found a better
15485 approximation to the cursor position than we have from previously
15486 examined candidate rows belonging to the same continued line. */
15487 if (/* We already have a candidate row. */
15488 w
->cursor
.vpos
>= 0
15489 /* That candidate is not the row we are processing. */
15490 && MATRIX_ROW (matrix
, w
->cursor
.vpos
) != row
15491 /* Make sure cursor.vpos specifies a row whose start and end
15492 charpos occlude point, and it is valid candidate for being a
15493 cursor-row. This is because some callers of this function
15494 leave cursor.vpos at the row where the cursor was displayed
15495 during the last redisplay cycle. */
15496 && MATRIX_ROW_START_CHARPOS (MATRIX_ROW (matrix
, w
->cursor
.vpos
)) <= pt_old
15497 && pt_old
<= MATRIX_ROW_END_CHARPOS (MATRIX_ROW (matrix
, w
->cursor
.vpos
))
15498 && cursor_row_p (MATRIX_ROW (matrix
, w
->cursor
.vpos
)))
15501 = MATRIX_ROW_GLYPH_START (matrix
, w
->cursor
.vpos
) + w
->cursor
.hpos
;
15503 /* Don't consider glyphs that are outside TEXT_AREA. */
15504 if (!(row
->reversed_p
? glyph
> glyphs_end
: glyph
< glyphs_end
))
15506 /* Keep the candidate whose buffer position is the closest to
15507 point or has the `cursor' property. */
15508 if (/* Previous candidate is a glyph in TEXT_AREA of that row. */
15509 w
->cursor
.hpos
>= 0
15510 && w
->cursor
.hpos
< MATRIX_ROW_USED (matrix
, w
->cursor
.vpos
)
15511 && ((BUFFERP (g1
->object
)
15512 && (g1
->charpos
== pt_old
/* An exact match always wins. */
15513 || (BUFFERP (glyph
->object
)
15514 && eabs (g1
->charpos
- pt_old
)
15515 < eabs (glyph
->charpos
- pt_old
))))
15516 /* Previous candidate is a glyph from a string that has
15517 a non-nil `cursor' property. */
15518 || (STRINGP (g1
->object
)
15519 && (!NILP (Fget_char_property (make_number (g1
->charpos
),
15520 Qcursor
, g1
->object
))
15521 /* Previous candidate is from the same display
15522 string as this one, and the display string
15523 came from a text property. */
15524 || (EQ (g1
->object
, glyph
->object
)
15525 && string_from_text_prop
)
15526 /* this candidate is from newline and its
15527 position is not an exact match */
15528 || (NILP (glyph
->object
)
15529 && glyph
->charpos
!= pt_old
)))))
15531 /* If this candidate gives an exact match, use that. */
15532 if (!((BUFFERP (glyph
->object
) && glyph
->charpos
== pt_old
)
15533 /* If this candidate is a glyph created for the
15534 terminating newline of a line, and point is on that
15535 newline, it wins because it's an exact match. */
15536 || (!row
->continued_p
15537 && NILP (glyph
->object
)
15538 && glyph
->charpos
== 0
15539 && pt_old
== MATRIX_ROW_END_CHARPOS (row
) - 1))
15540 /* Otherwise, keep the candidate that comes from a row
15541 spanning less buffer positions. This may win when one or
15542 both candidate positions are on glyphs that came from
15543 display strings, for which we cannot compare buffer
15545 && MATRIX_ROW_END_CHARPOS (MATRIX_ROW (matrix
, w
->cursor
.vpos
))
15546 - MATRIX_ROW_START_CHARPOS (MATRIX_ROW (matrix
, w
->cursor
.vpos
))
15547 < MATRIX_ROW_END_CHARPOS (row
) - MATRIX_ROW_START_CHARPOS (row
))
15550 w
->cursor
.hpos
= glyph
- row
->glyphs
[TEXT_AREA
];
15552 w
->cursor
.vpos
= MATRIX_ROW_VPOS (row
, matrix
) + dvpos
;
15553 w
->cursor
.y
= row
->y
+ dy
;
15555 if (w
== XWINDOW (selected_window
))
15557 if (!row
->continued_p
15558 && !MATRIX_ROW_CONTINUATION_LINE_P (row
)
15561 this_line_buffer
= XBUFFER (w
->contents
);
15563 CHARPOS (this_line_start_pos
)
15564 = MATRIX_ROW_START_CHARPOS (row
) + delta
;
15565 BYTEPOS (this_line_start_pos
)
15566 = MATRIX_ROW_START_BYTEPOS (row
) + delta_bytes
;
15568 CHARPOS (this_line_end_pos
)
15569 = Z
- (MATRIX_ROW_END_CHARPOS (row
) + delta
);
15570 BYTEPOS (this_line_end_pos
)
15571 = Z_BYTE
- (MATRIX_ROW_END_BYTEPOS (row
) + delta_bytes
);
15573 this_line_y
= w
->cursor
.y
;
15574 this_line_pixel_height
= row
->height
;
15575 this_line_vpos
= w
->cursor
.vpos
;
15576 this_line_start_x
= row
->x
;
15579 CHARPOS (this_line_start_pos
) = 0;
15586 /* Run window scroll functions, if any, for WINDOW with new window
15587 start STARTP. Sets the window start of WINDOW to that position.
15589 We assume that the window's buffer is really current. */
15591 static struct text_pos
15592 run_window_scroll_functions (Lisp_Object window
, struct text_pos startp
)
15594 struct window
*w
= XWINDOW (window
);
15595 SET_MARKER_FROM_TEXT_POS (w
->start
, startp
);
15597 eassert (current_buffer
== XBUFFER (w
->contents
));
15599 if (!NILP (Vwindow_scroll_functions
))
15601 run_hook_with_args_2 (Qwindow_scroll_functions
, window
,
15602 make_number (CHARPOS (startp
)));
15603 SET_TEXT_POS_FROM_MARKER (startp
, w
->start
);
15604 /* In case the hook functions switch buffers. */
15605 set_buffer_internal (XBUFFER (w
->contents
));
15612 /* Make sure the line containing the cursor is fully visible.
15613 A value of true means there is nothing to be done.
15614 (Either the line is fully visible, or it cannot be made so,
15615 or we cannot tell.)
15617 If FORCE_P, return false even if partial visible cursor row
15618 is higher than window.
15620 If CURRENT_MATRIX_P, use the information from the
15621 window's current glyph matrix; otherwise use the desired glyph
15624 A value of false means the caller should do scrolling
15625 as if point had gone off the screen. */
15628 cursor_row_fully_visible_p (struct window
*w
, bool force_p
,
15629 bool current_matrix_p
)
15631 struct glyph_matrix
*matrix
;
15632 struct glyph_row
*row
;
15635 if (!make_cursor_line_fully_visible_p
)
15638 /* It's not always possible to find the cursor, e.g, when a window
15639 is full of overlay strings. Don't do anything in that case. */
15640 if (w
->cursor
.vpos
< 0)
15643 matrix
= current_matrix_p
? w
->current_matrix
: w
->desired_matrix
;
15644 row
= MATRIX_ROW (matrix
, w
->cursor
.vpos
);
15646 /* If the cursor row is not partially visible, there's nothing to do. */
15647 if (!MATRIX_ROW_PARTIALLY_VISIBLE_P (w
, row
))
15650 /* If the row the cursor is in is taller than the window's height,
15651 it's not clear what to do, so do nothing. */
15652 window_height
= window_box_height (w
);
15653 if (row
->height
>= window_height
)
15655 if (!force_p
|| MINI_WINDOW_P (w
)
15656 || w
->vscroll
|| w
->cursor
.vpos
== 0)
15663 /* Try scrolling PT into view in window WINDOW. JUST_THIS_ONE_P
15664 means only WINDOW is redisplayed in redisplay_internal.
15665 TEMP_SCROLL_STEP has the same meaning as emacs_scroll_step, and is used
15666 in redisplay_window to bring a partially visible line into view in
15667 the case that only the cursor has moved.
15669 LAST_LINE_MISFIT should be true if we're scrolling because the
15670 last screen line's vertical height extends past the end of the screen.
15674 1 if scrolling succeeded
15676 0 if scrolling didn't find point.
15678 -1 if new fonts have been loaded so that we must interrupt
15679 redisplay, adjust glyph matrices, and try again. */
15685 SCROLLING_NEED_LARGER_MATRICES
15688 /* If scroll-conservatively is more than this, never recenter.
15690 If you change this, don't forget to update the doc string of
15691 `scroll-conservatively' and the Emacs manual. */
15692 #define SCROLL_LIMIT 100
15695 try_scrolling (Lisp_Object window
, bool just_this_one_p
,
15696 ptrdiff_t arg_scroll_conservatively
, ptrdiff_t scroll_step
,
15697 bool temp_scroll_step
, bool last_line_misfit
)
15699 struct window
*w
= XWINDOW (window
);
15700 struct text_pos pos
, startp
;
15702 int this_scroll_margin
, scroll_max
, rc
, height
;
15703 int dy
= 0, amount_to_scroll
= 0;
15704 bool scroll_down_p
= false;
15705 int extra_scroll_margin_lines
= last_line_misfit
;
15706 Lisp_Object aggressive
;
15707 /* We will never try scrolling more than this number of lines. */
15708 int scroll_limit
= SCROLL_LIMIT
;
15709 int frame_line_height
= default_line_pixel_height (w
);
15712 debug_method_add (w
, "try_scrolling");
15715 SET_TEXT_POS_FROM_MARKER (startp
, w
->start
);
15717 this_scroll_margin
= window_scroll_margin (w
, MARGIN_IN_PIXELS
);
15719 /* Force arg_scroll_conservatively to have a reasonable value, to
15720 avoid scrolling too far away with slow move_it_* functions. Note
15721 that the user can supply scroll-conservatively equal to
15722 `most-positive-fixnum', which can be larger than INT_MAX. */
15723 if (arg_scroll_conservatively
> scroll_limit
)
15725 arg_scroll_conservatively
= scroll_limit
+ 1;
15726 scroll_max
= scroll_limit
* frame_line_height
;
15728 else if (scroll_step
|| arg_scroll_conservatively
|| temp_scroll_step
)
15729 /* Compute how much we should try to scroll maximally to bring
15730 point into view. */
15731 scroll_max
= (max (scroll_step
,
15732 max (arg_scroll_conservatively
, temp_scroll_step
))
15733 * frame_line_height
);
15734 else if (NUMBERP (BVAR (current_buffer
, scroll_down_aggressively
))
15735 || NUMBERP (BVAR (current_buffer
, scroll_up_aggressively
)))
15736 /* We're trying to scroll because of aggressive scrolling but no
15737 scroll_step is set. Choose an arbitrary one. */
15738 scroll_max
= 10 * frame_line_height
;
15744 /* Decide whether to scroll down. */
15745 if (PT
> CHARPOS (startp
))
15747 int scroll_margin_y
;
15749 /* Compute the pixel ypos of the scroll margin, then move IT to
15750 either that ypos or PT, whichever comes first. */
15751 start_display (&it
, w
, startp
);
15752 scroll_margin_y
= it
.last_visible_y
- partial_line_height (&it
)
15753 - this_scroll_margin
15754 - frame_line_height
* extra_scroll_margin_lines
;
15755 move_it_to (&it
, PT
, -1, scroll_margin_y
- 1, -1,
15756 (MOVE_TO_POS
| MOVE_TO_Y
));
15758 if (PT
> CHARPOS (it
.current
.pos
))
15760 int y0
= line_bottom_y (&it
);
15761 /* Compute how many pixels below window bottom to stop searching
15762 for PT. This avoids costly search for PT that is far away if
15763 the user limited scrolling by a small number of lines, but
15764 always finds PT if scroll_conservatively is set to a large
15765 number, such as most-positive-fixnum. */
15766 int slack
= max (scroll_max
, 10 * frame_line_height
);
15767 int y_to_move
= it
.last_visible_y
+ slack
;
15769 /* Compute the distance from the scroll margin to PT or to
15770 the scroll limit, whichever comes first. This should
15771 include the height of the cursor line, to make that line
15773 move_it_to (&it
, PT
, -1, y_to_move
,
15774 -1, MOVE_TO_POS
| MOVE_TO_Y
);
15775 dy
= line_bottom_y (&it
) - y0
;
15777 if (dy
> scroll_max
)
15778 return SCROLLING_FAILED
;
15781 scroll_down_p
= true;
15783 else if (PT
== IT_CHARPOS (it
)
15784 && IT_CHARPOS (it
) < ZV
15785 && it
.method
== GET_FROM_STRING
15786 && arg_scroll_conservatively
> scroll_limit
15787 && it
.current_x
== 0)
15789 enum move_it_result skip
;
15790 int y1
= it
.current_y
;
15793 /* A before-string that includes newlines and is displayed
15794 on the last visible screen line could fail us under
15795 scroll-conservatively > 100, because we will be unable to
15796 position the cursor on that last visible line. Try to
15797 recover by finding the first screen line that has some
15798 glyphs coming from the buffer text. */
15800 skip
= move_it_in_display_line_to (&it
, ZV
, -1, MOVE_TO_POS
);
15801 if (skip
!= MOVE_NEWLINE_OR_CR
15802 || IT_CHARPOS (it
) != PT
15803 || it
.method
== GET_FROM_BUFFER
)
15806 move_it_to (&it
, -1, -1, -1, vpos
+ 1, MOVE_TO_VPOS
);
15807 } while (it
.vpos
> vpos
);
15809 dy
= it
.current_y
- y1
;
15811 if (dy
> scroll_max
)
15812 return SCROLLING_FAILED
;
15815 scroll_down_p
= true;
15821 /* Point is in or below the bottom scroll margin, so move the
15822 window start down. If scrolling conservatively, move it just
15823 enough down to make point visible. If scroll_step is set,
15824 move it down by scroll_step. */
15825 if (arg_scroll_conservatively
)
15827 = min (max (dy
, frame_line_height
),
15828 frame_line_height
* arg_scroll_conservatively
);
15829 else if (scroll_step
|| temp_scroll_step
)
15830 amount_to_scroll
= scroll_max
;
15833 aggressive
= BVAR (current_buffer
, scroll_up_aggressively
);
15834 height
= WINDOW_BOX_TEXT_HEIGHT (w
);
15835 if (NUMBERP (aggressive
))
15837 double float_amount
= XFLOATINT (aggressive
) * height
;
15838 int aggressive_scroll
= float_amount
;
15839 if (aggressive_scroll
== 0 && float_amount
> 0)
15840 aggressive_scroll
= 1;
15841 /* Don't let point enter the scroll margin near top of
15842 the window. This could happen if the value of
15843 scroll_up_aggressively is too large and there are
15844 non-zero margins, because scroll_up_aggressively
15845 means put point that fraction of window height
15846 _from_the_bottom_margin_. */
15847 if (aggressive_scroll
+ 2 * this_scroll_margin
> height
)
15848 aggressive_scroll
= height
- 2 * this_scroll_margin
;
15849 amount_to_scroll
= dy
+ aggressive_scroll
;
15853 if (amount_to_scroll
<= 0)
15854 return SCROLLING_FAILED
;
15856 start_display (&it
, w
, startp
);
15857 if (arg_scroll_conservatively
<= scroll_limit
)
15858 move_it_vertically (&it
, amount_to_scroll
);
15861 /* Extra precision for users who set scroll-conservatively
15862 to a large number: make sure the amount we scroll
15863 the window start is never less than amount_to_scroll,
15864 which was computed as distance from window bottom to
15865 point. This matters when lines at window top and lines
15866 below window bottom have different height. */
15868 void *it1data
= NULL
;
15869 /* We use a temporary it1 because line_bottom_y can modify
15870 its argument, if it moves one line down; see there. */
15873 SAVE_IT (it1
, it
, it1data
);
15874 start_y
= line_bottom_y (&it1
);
15876 RESTORE_IT (&it
, &it
, it1data
);
15877 move_it_by_lines (&it
, 1);
15878 SAVE_IT (it1
, it
, it1data
);
15879 } while (IT_CHARPOS (it
) < ZV
15880 && line_bottom_y (&it1
) - start_y
< amount_to_scroll
);
15881 bidi_unshelve_cache (it1data
, true);
15884 /* If STARTP is unchanged, move it down another screen line. */
15885 if (IT_CHARPOS (it
) == CHARPOS (startp
))
15886 move_it_by_lines (&it
, 1);
15887 startp
= it
.current
.pos
;
15891 struct text_pos scroll_margin_pos
= startp
;
15894 /* See if point is inside the scroll margin at the top of the
15896 if (this_scroll_margin
)
15900 start_display (&it
, w
, startp
);
15901 y_start
= it
.current_y
;
15902 move_it_vertically (&it
, this_scroll_margin
);
15903 scroll_margin_pos
= it
.current
.pos
;
15904 /* If we didn't move enough before hitting ZV, request
15905 additional amount of scroll, to move point out of the
15907 if (IT_CHARPOS (it
) == ZV
15908 && it
.current_y
- y_start
< this_scroll_margin
)
15909 y_offset
= this_scroll_margin
- (it
.current_y
- y_start
);
15912 if (PT
< CHARPOS (scroll_margin_pos
))
15914 /* Point is in the scroll margin at the top of the window or
15915 above what is displayed in the window. */
15918 /* Compute the vertical distance from PT to the scroll
15919 margin position. Move as far as scroll_max allows, or
15920 one screenful, or 10 screen lines, whichever is largest.
15921 Give up if distance is greater than scroll_max or if we
15922 didn't reach the scroll margin position. */
15923 SET_TEXT_POS (pos
, PT
, PT_BYTE
);
15924 start_display (&it
, w
, pos
);
15926 y_to_move
= max (it
.last_visible_y
,
15927 max (scroll_max
, 10 * frame_line_height
));
15928 move_it_to (&it
, CHARPOS (scroll_margin_pos
), 0,
15930 MOVE_TO_POS
| MOVE_TO_X
| MOVE_TO_Y
);
15931 dy
= it
.current_y
- y0
;
15932 if (dy
> scroll_max
15933 || IT_CHARPOS (it
) < CHARPOS (scroll_margin_pos
))
15934 return SCROLLING_FAILED
;
15936 /* Additional scroll for when ZV was too close to point. */
15939 /* Compute new window start. */
15940 start_display (&it
, w
, startp
);
15942 if (arg_scroll_conservatively
)
15943 amount_to_scroll
= max (dy
, frame_line_height
15944 * max (scroll_step
, temp_scroll_step
));
15945 else if (scroll_step
|| temp_scroll_step
)
15946 amount_to_scroll
= scroll_max
;
15949 aggressive
= BVAR (current_buffer
, scroll_down_aggressively
);
15950 height
= WINDOW_BOX_TEXT_HEIGHT (w
);
15951 if (NUMBERP (aggressive
))
15953 double float_amount
= XFLOATINT (aggressive
) * height
;
15954 int aggressive_scroll
= float_amount
;
15955 if (aggressive_scroll
== 0 && float_amount
> 0)
15956 aggressive_scroll
= 1;
15957 /* Don't let point enter the scroll margin near
15958 bottom of the window, if the value of
15959 scroll_down_aggressively happens to be too
15961 if (aggressive_scroll
+ 2 * this_scroll_margin
> height
)
15962 aggressive_scroll
= height
- 2 * this_scroll_margin
;
15963 amount_to_scroll
= dy
+ aggressive_scroll
;
15967 if (amount_to_scroll
<= 0)
15968 return SCROLLING_FAILED
;
15970 move_it_vertically_backward (&it
, amount_to_scroll
);
15971 startp
= it
.current
.pos
;
15975 /* Run window scroll functions. */
15976 startp
= run_window_scroll_functions (window
, startp
);
15978 /* Display the window. Give up if new fonts are loaded, or if point
15980 if (!try_window (window
, startp
, 0))
15981 rc
= SCROLLING_NEED_LARGER_MATRICES
;
15982 else if (w
->cursor
.vpos
< 0)
15984 clear_glyph_matrix (w
->desired_matrix
);
15985 rc
= SCROLLING_FAILED
;
15989 /* Maybe forget recorded base line for line number display. */
15990 if (!just_this_one_p
15991 || current_buffer
->clip_changed
15992 || BEG_UNCHANGED
< CHARPOS (startp
))
15993 w
->base_line_number
= 0;
15995 /* If cursor ends up on a partially visible line,
15996 treat that as being off the bottom of the screen. */
15997 if (! cursor_row_fully_visible_p (w
, extra_scroll_margin_lines
<= 1,
15999 /* It's possible that the cursor is on the first line of the
16000 buffer, which is partially obscured due to a vscroll
16001 (Bug#7537). In that case, avoid looping forever. */
16002 && extra_scroll_margin_lines
< w
->desired_matrix
->nrows
- 1)
16004 clear_glyph_matrix (w
->desired_matrix
);
16005 ++extra_scroll_margin_lines
;
16008 rc
= SCROLLING_SUCCESS
;
16015 /* Compute a suitable window start for window W if display of W starts
16016 on a continuation line. Value is true if a new window start
16019 The new window start will be computed, based on W's width, starting
16020 from the start of the continued line. It is the start of the
16021 screen line with the minimum distance from the old start W->start,
16022 which is still before point (otherwise point will definitely not
16023 be visible in the window). */
16026 compute_window_start_on_continuation_line (struct window
*w
)
16028 struct text_pos pos
, start_pos
, pos_before_pt
;
16029 bool window_start_changed_p
= false;
16031 SET_TEXT_POS_FROM_MARKER (start_pos
, w
->start
);
16033 /* If window start is on a continuation line... Window start may be
16034 < BEGV in case there's invisible text at the start of the
16035 buffer (M-x rmail, for example). */
16036 if (CHARPOS (start_pos
) > BEGV
16037 && FETCH_BYTE (BYTEPOS (start_pos
) - 1) != '\n')
16040 struct glyph_row
*row
;
16042 /* Handle the case that the window start is out of range. */
16043 if (CHARPOS (start_pos
) < BEGV
)
16044 SET_TEXT_POS (start_pos
, BEGV
, BEGV_BYTE
);
16045 else if (CHARPOS (start_pos
) > ZV
)
16046 SET_TEXT_POS (start_pos
, ZV
, ZV_BYTE
);
16048 /* Find the start of the continued line. This should be fast
16049 because find_newline is fast (newline cache). */
16050 row
= w
->desired_matrix
->rows
+ window_wants_header_line (w
);
16051 init_iterator (&it
, w
, CHARPOS (start_pos
), BYTEPOS (start_pos
),
16052 row
, DEFAULT_FACE_ID
);
16053 reseat_at_previous_visible_line_start (&it
);
16055 /* If the line start is "too far" away from the window start,
16056 say it takes too much time to compute a new window start.
16057 Also, give up if the line start is after point, as in that
16058 case point will not be visible with any window start we
16060 if (IT_CHARPOS (it
) <= PT
16061 || (CHARPOS (start_pos
) - IT_CHARPOS (it
)
16062 /* PXW: Do we need upper bounds here? */
16063 < WINDOW_TOTAL_LINES (w
) * WINDOW_TOTAL_COLS (w
)))
16065 int min_distance
, distance
;
16067 /* Move forward by display lines to find the new window
16068 start. If window width was enlarged, the new start can
16069 be expected to be > the old start. If window width was
16070 decreased, the new window start will be < the old start.
16071 So, we're looking for the display line start with the
16072 minimum distance from the old window start. */
16073 pos_before_pt
= pos
= it
.current
.pos
;
16074 min_distance
= DISP_INFINITY
;
16075 while ((distance
= eabs (CHARPOS (start_pos
) - IT_CHARPOS (it
))),
16076 distance
< min_distance
)
16078 min_distance
= distance
;
16079 if (CHARPOS (pos
) <= PT
)
16080 pos_before_pt
= pos
;
16081 pos
= it
.current
.pos
;
16082 if (it
.line_wrap
== WORD_WRAP
)
16084 /* Under WORD_WRAP, move_it_by_lines is likely to
16085 overshoot and stop not at the first, but the
16086 second character from the left margin. So in
16087 that case, we need a more tight control on the X
16088 coordinate of the iterator than move_it_by_lines
16089 promises in its contract. The method is to first
16090 go to the last (rightmost) visible character of a
16091 line, then move to the leftmost character on the
16092 next line in a separate call. */
16093 move_it_to (&it
, ZV
, it
.last_visible_x
, it
.current_y
, -1,
16094 MOVE_TO_POS
| MOVE_TO_X
| MOVE_TO_Y
);
16095 move_it_to (&it
, ZV
, 0,
16096 it
.current_y
+ it
.max_ascent
+ it
.max_descent
, -1,
16097 MOVE_TO_POS
| MOVE_TO_X
| MOVE_TO_Y
);
16100 move_it_by_lines (&it
, 1);
16103 /* It makes very little sense to make the new window start
16104 after point, as point won't be visible. If that's what
16105 the loop above finds, fall back on the candidate before
16106 or at point that is closest to the old window start. */
16107 if (CHARPOS (pos
) > PT
)
16108 pos
= pos_before_pt
;
16110 /* Set the window start there. */
16111 SET_MARKER_FROM_TEXT_POS (w
->start
, pos
);
16112 window_start_changed_p
= true;
16116 return window_start_changed_p
;
16120 /* Try cursor movement in case text has not changed in window WINDOW,
16121 with window start STARTP. Value is
16123 CURSOR_MOVEMENT_SUCCESS if successful
16125 CURSOR_MOVEMENT_CANNOT_BE_USED if this method cannot be used
16127 CURSOR_MOVEMENT_MUST_SCROLL if we know we have to scroll the
16128 display. *SCROLL_STEP is set to true, under certain circumstances, if
16129 we want to scroll as if scroll-step were set to 1. See the code.
16131 CURSOR_MOVEMENT_NEED_LARGER_MATRICES if we need larger matrices, in
16132 which case we have to abort this redisplay, and adjust matrices
16137 CURSOR_MOVEMENT_SUCCESS
,
16138 CURSOR_MOVEMENT_CANNOT_BE_USED
,
16139 CURSOR_MOVEMENT_MUST_SCROLL
,
16140 CURSOR_MOVEMENT_NEED_LARGER_MATRICES
16144 try_cursor_movement (Lisp_Object window
, struct text_pos startp
,
16147 struct window
*w
= XWINDOW (window
);
16148 struct frame
*f
= XFRAME (w
->frame
);
16149 int rc
= CURSOR_MOVEMENT_CANNOT_BE_USED
;
16152 if (inhibit_try_cursor_movement
)
16156 /* Previously, there was a check for Lisp integer in the
16157 if-statement below. Now, this field is converted to
16158 ptrdiff_t, thus zero means invalid position in a buffer. */
16159 eassert (w
->last_point
> 0);
16160 /* Likewise there was a check whether window_end_vpos is nil or larger
16161 than the window. Now window_end_vpos is int and so never nil, but
16162 let's leave eassert to check whether it fits in the window. */
16163 eassert (!w
->window_end_valid
16164 || w
->window_end_vpos
< w
->current_matrix
->nrows
);
16166 /* Handle case where text has not changed, only point, and it has
16167 not moved off the frame. */
16168 if (/* Point may be in this window. */
16169 PT
>= CHARPOS (startp
)
16170 /* Selective display hasn't changed. */
16171 && !current_buffer
->clip_changed
16172 /* Function force-mode-line-update is used to force a thorough
16173 redisplay. It sets either windows_or_buffers_changed or
16174 update_mode_lines. So don't take a shortcut here for these
16176 && !update_mode_lines
16177 && !windows_or_buffers_changed
16178 && !f
->cursor_type_changed
16179 && NILP (Vshow_trailing_whitespace
)
16180 /* When display-line-numbers is in relative mode, moving point
16181 requires to redraw the entire window. */
16182 && !EQ (Vdisplay_line_numbers
, Qrelative
)
16183 && !EQ (Vdisplay_line_numbers
, Qvisual
)
16184 /* When the current line number should be displayed in a
16185 distinct face, moving point cannot be handled in optimized
16187 && !(!NILP (Vdisplay_line_numbers
)
16188 && NILP (Finternal_lisp_face_equal_p (Qline_number
,
16189 Qline_number_current_line
,
16191 /* This code is not used for mini-buffer for the sake of the case
16192 of redisplaying to replace an echo area message; since in
16193 that case the mini-buffer contents per se are usually
16194 unchanged. This code is of no real use in the mini-buffer
16195 since the handling of this_line_start_pos, etc., in redisplay
16196 handles the same cases. */
16197 && !EQ (window
, minibuf_window
)
16198 /* When overlay arrow is shown in current buffer, point movement
16199 is no longer "simple", as it typically causes the overlay
16200 arrow to move as well. */
16201 && !overlay_arrow_in_current_buffer_p ())
16203 int this_scroll_margin
, top_scroll_margin
;
16204 struct glyph_row
*row
= NULL
;
16207 debug_method_add (w
, "cursor movement");
16210 this_scroll_margin
= window_scroll_margin (w
, MARGIN_IN_PIXELS
);
16212 top_scroll_margin
= this_scroll_margin
;
16213 if (window_wants_header_line (w
))
16214 top_scroll_margin
+= CURRENT_HEADER_LINE_HEIGHT (w
);
16216 /* Start with the row the cursor was displayed during the last
16217 not paused redisplay. Give up if that row is not valid. */
16218 if (w
->last_cursor_vpos
< 0
16219 || w
->last_cursor_vpos
>= w
->current_matrix
->nrows
)
16220 rc
= CURSOR_MOVEMENT_MUST_SCROLL
;
16223 row
= MATRIX_ROW (w
->current_matrix
, w
->last_cursor_vpos
);
16224 if (row
->mode_line_p
)
16226 if (!row
->enabled_p
)
16227 rc
= CURSOR_MOVEMENT_MUST_SCROLL
;
16230 if (rc
== CURSOR_MOVEMENT_CANNOT_BE_USED
)
16232 bool scroll_p
= false, must_scroll
= false;
16233 int last_y
= window_text_bottom_y (w
) - this_scroll_margin
;
16235 if (PT
> w
->last_point
)
16237 /* Point has moved forward. */
16238 while (MATRIX_ROW_END_CHARPOS (row
) < PT
16239 && MATRIX_ROW_BOTTOM_Y (row
) < last_y
)
16241 eassert (row
->enabled_p
);
16245 /* If the end position of a row equals the start
16246 position of the next row, and PT is at that position,
16247 we would rather display cursor in the next line. */
16248 while (MATRIX_ROW_BOTTOM_Y (row
) < last_y
16249 && MATRIX_ROW_END_CHARPOS (row
) == PT
16250 && row
< MATRIX_MODE_LINE_ROW (w
->current_matrix
)
16251 && MATRIX_ROW_START_CHARPOS (row
+1) == PT
16252 && !cursor_row_p (row
))
16255 /* If within the scroll margin, scroll. Note that
16256 MATRIX_ROW_BOTTOM_Y gives the pixel position at which
16257 the next line would be drawn, and that
16258 this_scroll_margin can be zero. */
16259 if (MATRIX_ROW_BOTTOM_Y (row
) > last_y
16260 || PT
> MATRIX_ROW_END_CHARPOS (row
)
16261 /* Line is completely visible last line in window
16262 and PT is to be set in the next line. */
16263 || (MATRIX_ROW_BOTTOM_Y (row
) == last_y
16264 && PT
== MATRIX_ROW_END_CHARPOS (row
)
16265 && !row
->ends_at_zv_p
16266 && !MATRIX_ROW_ENDS_IN_MIDDLE_OF_CHAR_P (row
)))
16269 else if (PT
< w
->last_point
)
16271 /* Cursor has to be moved backward. Note that PT >=
16272 CHARPOS (startp) because of the outer if-statement. */
16273 while (!row
->mode_line_p
16274 && (MATRIX_ROW_START_CHARPOS (row
) > PT
16275 || (MATRIX_ROW_START_CHARPOS (row
) == PT
16276 && (MATRIX_ROW_STARTS_IN_MIDDLE_OF_CHAR_P (row
)
16277 || (/* STARTS_IN_MIDDLE_OF_STRING_P (row) */
16278 row
> w
->current_matrix
->rows
16279 && (row
-1)->ends_in_newline_from_string_p
))))
16280 && (row
->y
> top_scroll_margin
16281 || CHARPOS (startp
) == BEGV
))
16283 eassert (row
->enabled_p
);
16287 /* Consider the following case: Window starts at BEGV,
16288 there is invisible, intangible text at BEGV, so that
16289 display starts at some point START > BEGV. It can
16290 happen that we are called with PT somewhere between
16291 BEGV and START. Try to handle that case. */
16292 if (row
< w
->current_matrix
->rows
16293 || row
->mode_line_p
)
16295 row
= w
->current_matrix
->rows
;
16296 if (row
->mode_line_p
)
16300 /* Due to newlines in overlay strings, we may have to
16301 skip forward over overlay strings. */
16302 while (MATRIX_ROW_BOTTOM_Y (row
) < last_y
16303 && MATRIX_ROW_END_CHARPOS (row
) == PT
16304 && !cursor_row_p (row
))
16307 /* If within the scroll margin, scroll. */
16308 if (row
->y
< top_scroll_margin
16309 && CHARPOS (startp
) != BEGV
)
16314 /* Cursor did not move. So don't scroll even if cursor line
16315 is partially visible, as it was so before. */
16316 rc
= CURSOR_MOVEMENT_SUCCESS
;
16319 if (PT
< MATRIX_ROW_START_CHARPOS (row
)
16320 || PT
> MATRIX_ROW_END_CHARPOS (row
))
16322 /* if PT is not in the glyph row, give up. */
16323 rc
= CURSOR_MOVEMENT_MUST_SCROLL
;
16324 must_scroll
= true;
16326 else if (rc
!= CURSOR_MOVEMENT_SUCCESS
16327 && !NILP (BVAR (XBUFFER (w
->contents
), bidi_display_reordering
)))
16329 struct glyph_row
*row1
;
16331 /* If rows are bidi-reordered and point moved, back up
16332 until we find a row that does not belong to a
16333 continuation line. This is because we must consider
16334 all rows of a continued line as candidates for the
16335 new cursor positioning, since row start and end
16336 positions change non-linearly with vertical position
16338 /* FIXME: Revisit this when glyph ``spilling'' in
16339 continuation lines' rows is implemented for
16340 bidi-reordered rows. */
16341 for (row1
= MATRIX_FIRST_TEXT_ROW (w
->current_matrix
);
16342 MATRIX_ROW_CONTINUATION_LINE_P (row
);
16345 /* If we hit the beginning of the displayed portion
16346 without finding the first row of a continued
16350 rc
= CURSOR_MOVEMENT_MUST_SCROLL
;
16353 eassert (row
->enabled_p
);
16358 else if (rc
!= CURSOR_MOVEMENT_SUCCESS
16359 && MATRIX_ROW_PARTIALLY_VISIBLE_P (w
, row
)
16360 /* Make sure this isn't a header line by any chance, since
16361 then MATRIX_ROW_PARTIALLY_VISIBLE_P might yield true. */
16362 && !row
->mode_line_p
16363 && make_cursor_line_fully_visible_p
)
16365 if (PT
== MATRIX_ROW_END_CHARPOS (row
)
16366 && !row
->ends_at_zv_p
16367 && !MATRIX_ROW_ENDS_IN_MIDDLE_OF_CHAR_P (row
))
16368 rc
= CURSOR_MOVEMENT_MUST_SCROLL
;
16369 else if (row
->height
> window_box_height (w
))
16371 /* If we end up in a partially visible line, let's
16372 make it fully visible, except when it's taller
16373 than the window, in which case we can't do much
16375 *scroll_step
= true;
16376 rc
= CURSOR_MOVEMENT_MUST_SCROLL
;
16380 set_cursor_from_row (w
, row
, w
->current_matrix
, 0, 0, 0, 0);
16381 if (!cursor_row_fully_visible_p (w
, false, true))
16382 rc
= CURSOR_MOVEMENT_MUST_SCROLL
;
16384 rc
= CURSOR_MOVEMENT_SUCCESS
;
16388 rc
= CURSOR_MOVEMENT_MUST_SCROLL
;
16389 else if (rc
!= CURSOR_MOVEMENT_SUCCESS
16390 && !NILP (BVAR (XBUFFER (w
->contents
), bidi_display_reordering
)))
16392 /* With bidi-reordered rows, there could be more than
16393 one candidate row whose start and end positions
16394 occlude point. We need to let set_cursor_from_row
16395 find the best candidate. */
16396 /* FIXME: Revisit this when glyph ``spilling'' in
16397 continuation lines' rows is implemented for
16398 bidi-reordered rows. */
16403 bool at_zv_p
= false, exact_match_p
= false;
16405 if (MATRIX_ROW_START_CHARPOS (row
) <= PT
16406 && PT
<= MATRIX_ROW_END_CHARPOS (row
)
16407 && cursor_row_p (row
))
16408 rv
|= set_cursor_from_row (w
, row
, w
->current_matrix
,
16410 /* As soon as we've found the exact match for point,
16411 or the first suitable row whose ends_at_zv_p flag
16412 is set, we are done. */
16415 at_zv_p
= MATRIX_ROW (w
->current_matrix
,
16416 w
->cursor
.vpos
)->ends_at_zv_p
;
16418 && w
->cursor
.hpos
>= 0
16419 && w
->cursor
.hpos
< MATRIX_ROW_USED (w
->current_matrix
,
16422 struct glyph_row
*candidate
=
16423 MATRIX_ROW (w
->current_matrix
, w
->cursor
.vpos
);
16425 candidate
->glyphs
[TEXT_AREA
] + w
->cursor
.hpos
;
16426 ptrdiff_t endpos
= MATRIX_ROW_END_CHARPOS (candidate
);
16429 (BUFFERP (g
->object
) && g
->charpos
== PT
)
16430 || (NILP (g
->object
)
16431 && (g
->charpos
== PT
16432 || (g
->charpos
== 0 && endpos
- 1 == PT
)));
16434 if (at_zv_p
|| exact_match_p
)
16436 rc
= CURSOR_MOVEMENT_SUCCESS
;
16440 if (MATRIX_ROW_BOTTOM_Y (row
) == last_y
)
16444 while (((MATRIX_ROW_CONTINUATION_LINE_P (row
)
16445 || row
->continued_p
)
16446 && MATRIX_ROW_BOTTOM_Y (row
) <= last_y
)
16447 || (MATRIX_ROW_START_CHARPOS (row
) == PT
16448 && MATRIX_ROW_BOTTOM_Y (row
) < last_y
));
16449 /* If we didn't find any candidate rows, or exited the
16450 loop before all the candidates were examined, signal
16451 to the caller that this method failed. */
16452 if (rc
!= CURSOR_MOVEMENT_SUCCESS
16454 && !MATRIX_ROW_CONTINUATION_LINE_P (row
)
16455 && !row
->continued_p
))
16456 rc
= CURSOR_MOVEMENT_MUST_SCROLL
;
16458 rc
= CURSOR_MOVEMENT_SUCCESS
;
16464 if (set_cursor_from_row (w
, row
, w
->current_matrix
, 0, 0, 0, 0))
16466 rc
= CURSOR_MOVEMENT_SUCCESS
;
16471 while (MATRIX_ROW_BOTTOM_Y (row
) < last_y
16472 && MATRIX_ROW_START_CHARPOS (row
) == PT
16473 && cursor_row_p (row
));
16483 set_vertical_scroll_bar (struct window
*w
)
16485 ptrdiff_t start
, end
, whole
;
16487 /* Calculate the start and end positions for the current window.
16488 At some point, it would be nice to choose between scrollbars
16489 which reflect the whole buffer size, with special markers
16490 indicating narrowing, and scrollbars which reflect only the
16493 Note that mini-buffers sometimes aren't displaying any text. */
16494 if (!MINI_WINDOW_P (w
)
16495 || (w
== XWINDOW (minibuf_window
)
16496 && NILP (echo_area_buffer
[0])))
16498 struct buffer
*buf
= XBUFFER (w
->contents
);
16499 whole
= BUF_ZV (buf
) - BUF_BEGV (buf
);
16500 start
= marker_position (w
->start
) - BUF_BEGV (buf
);
16501 /* I don't think this is guaranteed to be right. For the
16502 moment, we'll pretend it is. */
16503 end
= BUF_Z (buf
) - w
->window_end_pos
- BUF_BEGV (buf
);
16507 if (whole
< (end
- start
))
16508 whole
= end
- start
;
16511 start
= end
= whole
= 0;
16513 /* Indicate what this scroll bar ought to be displaying now. */
16514 if (FRAME_TERMINAL (XFRAME (w
->frame
))->set_vertical_scroll_bar_hook
)
16515 (*FRAME_TERMINAL (XFRAME (w
->frame
))->set_vertical_scroll_bar_hook
)
16516 (w
, end
- start
, whole
, start
);
16521 set_horizontal_scroll_bar (struct window
*w
)
16523 int start
, end
, whole
, portion
;
16525 if (!MINI_WINDOW_P (w
)
16526 || (w
== XWINDOW (minibuf_window
)
16527 && NILP (echo_area_buffer
[0])))
16529 struct buffer
*b
= XBUFFER (w
->contents
);
16530 struct buffer
*old_buffer
= NULL
;
16532 struct text_pos startp
;
16534 if (b
!= current_buffer
)
16536 old_buffer
= current_buffer
;
16537 set_buffer_internal (b
);
16540 SET_TEXT_POS_FROM_MARKER (startp
, w
->start
);
16541 start_display (&it
, w
, startp
);
16542 it
.last_visible_x
= INT_MAX
;
16543 whole
= move_it_to (&it
, -1, INT_MAX
, window_box_height (w
), -1,
16544 MOVE_TO_X
| MOVE_TO_Y
);
16545 /* whole = move_it_to (&it, w->window_end_pos, INT_MAX,
16546 window_box_height (w), -1,
16547 MOVE_TO_POS | MOVE_TO_X | MOVE_TO_Y); */
16549 start
= w
->hscroll
* FRAME_COLUMN_WIDTH (WINDOW_XFRAME (w
));
16550 end
= start
+ window_box_width (w
, TEXT_AREA
);
16551 portion
= end
- start
;
16552 /* After enlarging a horizontally scrolled window such that it
16553 gets at least as wide as the text it contains, make sure that
16554 the thumb doesn't fill the entire scroll bar so we can still
16555 drag it back to see the entire text. */
16556 whole
= max (whole
, end
);
16562 pdir
= Fcurrent_bidi_paragraph_direction (Qnil
);
16563 if (EQ (pdir
, Qright_to_left
))
16565 start
= whole
- end
;
16566 end
= start
+ portion
;
16571 set_buffer_internal (old_buffer
);
16574 start
= end
= whole
= portion
= 0;
16576 w
->hscroll_whole
= whole
;
16578 /* Indicate what this scroll bar ought to be displaying now. */
16579 if (FRAME_TERMINAL (XFRAME (w
->frame
))->set_horizontal_scroll_bar_hook
)
16580 (*FRAME_TERMINAL (XFRAME (w
->frame
))->set_horizontal_scroll_bar_hook
)
16581 (w
, portion
, whole
, start
);
16585 /* Redisplay leaf window WINDOW. JUST_THIS_ONE_P means only
16586 selected_window is redisplayed.
16588 We can return without actually redisplaying the window if fonts has been
16589 changed on window's frame. In that case, redisplay_internal will retry.
16591 As one of the important parts of redisplaying a window, we need to
16592 decide whether the previous window-start position (stored in the
16593 window's w->start marker position) is still valid, and if it isn't,
16594 recompute it. Some details about that:
16596 . The previous window-start could be in a continuation line, in
16597 which case we need to recompute it when the window width
16598 changes. See compute_window_start_on_continuation_line and its
16601 . The text that changed since last redisplay could include the
16602 previous window-start position. In that case, we try to salvage
16603 what we can from the current glyph matrix by calling
16604 try_scrolling, which see.
16606 . Some Emacs command could force us to use a specific window-start
16607 position by setting the window's force_start flag, or gently
16608 propose doing that by setting the window's optional_new_start
16609 flag. In these cases, we try using the specified start point if
16610 that succeeds (i.e. the window desired matrix is successfully
16611 recomputed, and point location is within the window). In case
16612 of optional_new_start, we first check if the specified start
16613 position is feasible, i.e. if it will allow point to be
16614 displayed in the window. If using the specified start point
16615 fails, e.g., if new fonts are needed to be loaded, we abort the
16616 redisplay cycle and leave it up to the next cycle to figure out
16619 . Note that the window's force_start flag is sometimes set by
16620 redisplay itself, when it decides that the previous window start
16621 point is fine and should be kept. Search for "goto force_start"
16622 below to see the details. Like the values of window-start
16623 specified outside of redisplay, these internally-deduced values
16624 are tested for feasibility, and ignored if found to be
16627 . Note that the function try_window, used to completely redisplay
16628 a window, accepts the window's start point as its argument.
16629 This is used several times in the redisplay code to control
16630 where the window start will be, according to user options such
16631 as scroll-conservatively, and also to ensure the screen line
16632 showing point will be fully (as opposed to partially) visible on
16636 redisplay_window (Lisp_Object window
, bool just_this_one_p
)
16638 struct window
*w
= XWINDOW (window
);
16639 struct frame
*f
= XFRAME (w
->frame
);
16640 struct buffer
*buffer
= XBUFFER (w
->contents
);
16641 struct buffer
*old
= current_buffer
;
16642 struct text_pos lpoint
, opoint
, startp
;
16643 bool update_mode_line
;
16646 /* Record it now because it's overwritten. */
16647 bool current_matrix_up_to_date_p
= false;
16648 bool used_current_matrix_p
= false;
16649 /* This is less strict than current_matrix_up_to_date_p.
16650 It indicates that the buffer contents and narrowing are unchanged. */
16651 bool buffer_unchanged_p
= false;
16652 bool temp_scroll_step
= false;
16653 ptrdiff_t count
= SPECPDL_INDEX ();
16655 int centering_position
= -1;
16656 bool last_line_misfit
= false;
16657 ptrdiff_t beg_unchanged
, end_unchanged
;
16658 int frame_line_height
, margin
;
16659 bool use_desired_matrix
;
16660 void *itdata
= NULL
;
16662 SET_TEXT_POS (lpoint
, PT
, PT_BYTE
);
16666 *w
->desired_matrix
->method
= 0;
16669 if (!just_this_one_p
16670 && REDISPLAY_SOME_P ()
16672 && !w
->update_mode_line
16675 && !buffer
->text
->redisplay
16676 && BUF_PT (buffer
) == w
->last_point
)
16679 /* Make sure that both W's markers are valid. */
16680 eassert (XMARKER (w
->start
)->buffer
== buffer
);
16681 eassert (XMARKER (w
->pointm
)->buffer
== buffer
);
16683 reconsider_clip_changes (w
);
16684 frame_line_height
= default_line_pixel_height (w
);
16685 margin
= window_scroll_margin (w
, MARGIN_IN_LINES
);
16688 /* Has the mode line to be updated? */
16689 update_mode_line
= (w
->update_mode_line
16690 || update_mode_lines
16691 || buffer
->clip_changed
16692 || buffer
->prevent_redisplay_optimizations_p
);
16694 if (!just_this_one_p
)
16695 /* If `just_this_one_p' is set, we apparently set must_be_updated_p more
16696 cleverly elsewhere. */
16697 w
->must_be_updated_p
= true;
16699 if (MINI_WINDOW_P (w
))
16701 if (w
== XWINDOW (echo_area_window
)
16702 && !NILP (echo_area_buffer
[0]))
16704 if (update_mode_line
)
16705 /* We may have to update a tty frame's menu bar or a
16706 tool-bar. Example `M-x C-h C-h C-g'. */
16707 goto finish_menu_bars
;
16709 /* We've already displayed the echo area glyphs in this window. */
16710 goto finish_scroll_bars
;
16712 else if ((w
!= XWINDOW (minibuf_window
)
16713 || minibuf_level
== 0)
16714 /* When buffer is nonempty, redisplay window normally. */
16715 && BUF_Z (XBUFFER (w
->contents
)) == BUF_BEG (XBUFFER (w
->contents
))
16716 /* Quail displays non-mini buffers in minibuffer window.
16717 In that case, redisplay the window normally. */
16718 && !NILP (Fmemq (w
->contents
, Vminibuffer_list
)))
16720 /* W is a mini-buffer window, but it's not active, so clear
16722 int yb
= window_text_bottom_y (w
);
16723 struct glyph_row
*row
;
16726 for (y
= 0, row
= w
->desired_matrix
->rows
;
16728 y
+= row
->height
, ++row
)
16729 blank_row (w
, row
, y
);
16730 goto finish_scroll_bars
;
16733 clear_glyph_matrix (w
->desired_matrix
);
16736 /* Otherwise set up data on this window; select its buffer and point
16738 /* Really select the buffer, for the sake of buffer-local
16740 set_buffer_internal_1 (XBUFFER (w
->contents
));
16742 current_matrix_up_to_date_p
16743 = (w
->window_end_valid
16744 && !current_buffer
->clip_changed
16745 && !current_buffer
->prevent_redisplay_optimizations_p
16746 && !window_outdated (w
)
16747 && !hscrolling_current_line_p (w
));
16749 beg_unchanged
= BEG_UNCHANGED
;
16750 end_unchanged
= END_UNCHANGED
;
16752 SET_TEXT_POS (opoint
, PT
, PT_BYTE
);
16754 specbind (Qinhibit_point_motion_hooks
, Qt
);
16757 = (w
->window_end_valid
16758 && !current_buffer
->clip_changed
16759 && !window_outdated (w
));
16761 /* When windows_or_buffers_changed is non-zero, we can't rely
16762 on the window end being valid, so set it to zero there. */
16763 if (windows_or_buffers_changed
)
16765 /* If window starts on a continuation line, maybe adjust the
16766 window start in case the window's width changed. */
16767 if (XMARKER (w
->start
)->buffer
== current_buffer
)
16768 compute_window_start_on_continuation_line (w
);
16770 w
->window_end_valid
= false;
16771 /* If so, we also can't rely on current matrix
16772 and should not fool try_cursor_movement below. */
16773 current_matrix_up_to_date_p
= false;
16776 /* Some sanity checks. */
16777 CHECK_WINDOW_END (w
);
16778 if (Z
== Z_BYTE
&& CHARPOS (opoint
) != BYTEPOS (opoint
))
16780 if (BYTEPOS (opoint
) < CHARPOS (opoint
))
16783 if (mode_line_update_needed (w
))
16784 update_mode_line
= true;
16786 /* Point refers normally to the selected window. For any other
16787 window, set up appropriate value. */
16788 if (!EQ (window
, selected_window
))
16790 ptrdiff_t new_pt
= marker_position (w
->pointm
);
16791 ptrdiff_t new_pt_byte
= marker_byte_position (w
->pointm
);
16796 new_pt_byte
= BEGV_BYTE
;
16797 set_marker_both (w
->pointm
, Qnil
, BEGV
, BEGV_BYTE
);
16799 else if (new_pt
> (ZV
- 1))
16802 new_pt_byte
= ZV_BYTE
;
16803 set_marker_both (w
->pointm
, Qnil
, ZV
, ZV_BYTE
);
16806 /* We don't use SET_PT so that the point-motion hooks don't run. */
16807 TEMP_SET_PT_BOTH (new_pt
, new_pt_byte
);
16810 /* If any of the character widths specified in the display table
16811 have changed, invalidate the width run cache. It's true that
16812 this may be a bit late to catch such changes, but the rest of
16813 redisplay goes (non-fatally) haywire when the display table is
16814 changed, so why should we worry about doing any better? */
16815 if (current_buffer
->width_run_cache
16816 || (current_buffer
->base_buffer
16817 && current_buffer
->base_buffer
->width_run_cache
))
16819 struct Lisp_Char_Table
*disptab
= buffer_display_table ();
16821 if (! disptab_matches_widthtab
16822 (disptab
, XVECTOR (BVAR (current_buffer
, width_table
))))
16824 struct buffer
*buf
= current_buffer
;
16826 if (buf
->base_buffer
)
16827 buf
= buf
->base_buffer
;
16828 invalidate_region_cache (buf
, buf
->width_run_cache
, BEG
, Z
);
16829 recompute_width_table (current_buffer
, disptab
);
16833 /* If window-start is screwed up, choose a new one. */
16834 if (XMARKER (w
->start
)->buffer
!= current_buffer
)
16837 SET_TEXT_POS_FROM_MARKER (startp
, w
->start
);
16839 /* If someone specified a new starting point but did not insist,
16840 check whether it can be used. */
16841 if ((w
->optional_new_start
|| window_frozen_p (w
))
16842 && CHARPOS (startp
) >= BEGV
16843 && CHARPOS (startp
) <= ZV
)
16845 ptrdiff_t it_charpos
;
16847 w
->optional_new_start
= false;
16848 start_display (&it
, w
, startp
);
16849 move_it_to (&it
, PT
, 0, it
.last_visible_y
, -1,
16850 MOVE_TO_POS
| MOVE_TO_X
| MOVE_TO_Y
);
16851 /* Record IT's position now, since line_bottom_y might change
16853 it_charpos
= IT_CHARPOS (it
);
16854 /* Make sure we set the force_start flag only if the cursor row
16855 will be fully visible. Otherwise, the code under force_start
16856 label below will try to move point back into view, which is
16857 not what the code which sets optional_new_start wants. */
16858 if ((it
.current_y
== 0 || line_bottom_y (&it
) < it
.last_visible_y
)
16859 && !w
->force_start
)
16861 if (it_charpos
== PT
)
16862 w
->force_start
= true;
16863 /* IT may overshoot PT if text at PT is invisible. */
16864 else if (it_charpos
> PT
&& CHARPOS (startp
) <= PT
)
16865 w
->force_start
= true;
16867 if (w
->force_start
)
16869 if (window_frozen_p (w
))
16870 debug_method_add (w
, "set force_start from frozen window start");
16872 debug_method_add (w
, "set force_start from optional_new_start");
16880 /* Handle case where place to start displaying has been specified,
16881 unless the specified location is outside the accessible range. */
16882 if (w
->force_start
)
16884 /* We set this later on if we have to adjust point. */
16887 w
->force_start
= false;
16889 w
->window_end_valid
= false;
16891 /* Forget any recorded base line for line number display. */
16892 if (!buffer_unchanged_p
)
16893 w
->base_line_number
= 0;
16895 /* Redisplay the mode line. Select the buffer properly for that.
16896 Also, run the hook window-scroll-functions
16897 because we have scrolled. */
16898 /* Note, we do this after clearing force_start because
16899 if there's an error, it is better to forget about force_start
16900 than to get into an infinite loop calling the hook functions
16901 and having them get more errors. */
16902 if (!update_mode_line
16903 || ! NILP (Vwindow_scroll_functions
))
16905 update_mode_line
= true;
16906 w
->update_mode_line
= true;
16907 startp
= run_window_scroll_functions (window
, startp
);
16910 if (CHARPOS (startp
) < BEGV
)
16911 SET_TEXT_POS (startp
, BEGV
, BEGV_BYTE
);
16912 else if (CHARPOS (startp
) > ZV
)
16913 SET_TEXT_POS (startp
, ZV
, ZV_BYTE
);
16915 /* Redisplay, then check if cursor has been set during the
16916 redisplay. Give up if new fonts were loaded. */
16917 /* We used to issue a CHECK_MARGINS argument to try_window here,
16918 but this causes scrolling to fail when point begins inside
16919 the scroll margin (bug#148) -- cyd */
16920 if (!try_window (window
, startp
, 0))
16922 w
->force_start
= true;
16923 clear_glyph_matrix (w
->desired_matrix
);
16924 goto need_larger_matrices
;
16927 if (w
->cursor
.vpos
< 0)
16929 /* If point does not appear, try to move point so it does
16930 appear. The desired matrix has been built above, so we
16931 can use it here. First see if point is in invisible
16932 text, and if so, move it to the first visible buffer
16933 position past that. */
16934 struct glyph_row
*r
= NULL
;
16935 Lisp_Object invprop
=
16936 get_char_property_and_overlay (make_number (PT
), Qinvisible
,
16939 if (TEXT_PROP_MEANS_INVISIBLE (invprop
) != 0)
16942 Lisp_Object invprop_end
=
16943 Fnext_single_char_property_change (make_number (PT
), Qinvisible
,
16946 if (NATNUMP (invprop_end
))
16947 alt_pt
= XFASTINT (invprop_end
);
16950 r
= row_containing_pos (w
, alt_pt
, w
->desired_matrix
->rows
,
16954 new_vpos
= MATRIX_ROW_BOTTOM_Y (r
);
16955 else /* Give up and just move to the middle of the window. */
16956 new_vpos
= window_box_height (w
) / 2;
16959 if (!cursor_row_fully_visible_p (w
, false, false))
16961 /* Point does appear, but on a line partly visible at end of window.
16962 Move it back to a fully-visible line. */
16963 new_vpos
= window_box_height (w
);
16964 /* But if window_box_height suggests a Y coordinate that is
16965 not less than we already have, that line will clearly not
16966 be fully visible, so give up and scroll the display.
16967 This can happen when the default face uses a font whose
16968 dimensions are different from the frame's default
16970 if (new_vpos
>= w
->cursor
.y
)
16972 w
->cursor
.vpos
= -1;
16973 clear_glyph_matrix (w
->desired_matrix
);
16974 goto try_to_scroll
;
16977 else if (w
->cursor
.vpos
>= 0)
16979 /* Some people insist on not letting point enter the scroll
16980 margin, even though this part handles windows that didn't
16982 int pixel_margin
= margin
* frame_line_height
;
16983 bool header_line
= window_wants_header_line (w
);
16985 /* Note: We add an extra FRAME_LINE_HEIGHT, because the loop
16986 below, which finds the row to move point to, advances by
16987 the Y coordinate of the _next_ row, see the definition of
16988 MATRIX_ROW_BOTTOM_Y. */
16989 if (w
->cursor
.vpos
< margin
+ header_line
)
16991 w
->cursor
.vpos
= -1;
16992 clear_glyph_matrix (w
->desired_matrix
);
16993 goto try_to_scroll
;
16997 int window_height
= window_box_height (w
);
17000 window_height
+= CURRENT_HEADER_LINE_HEIGHT (w
);
17001 if (w
->cursor
.y
>= window_height
- pixel_margin
)
17003 w
->cursor
.vpos
= -1;
17004 clear_glyph_matrix (w
->desired_matrix
);
17005 goto try_to_scroll
;
17010 /* If we need to move point for either of the above reasons,
17011 now actually do it. */
17014 struct glyph_row
*row
;
17016 row
= MATRIX_FIRST_TEXT_ROW (w
->desired_matrix
);
17017 while (MATRIX_ROW_BOTTOM_Y (row
) < new_vpos
)
17020 TEMP_SET_PT_BOTH (MATRIX_ROW_START_CHARPOS (row
),
17021 MATRIX_ROW_START_BYTEPOS (row
));
17023 if (w
!= XWINDOW (selected_window
))
17024 set_marker_both (w
->pointm
, Qnil
, PT
, PT_BYTE
);
17025 else if (current_buffer
== old
)
17026 SET_TEXT_POS (lpoint
, PT
, PT_BYTE
);
17028 set_cursor_from_row (w
, row
, w
->desired_matrix
, 0, 0, 0, 0);
17030 /* Re-run pre-redisplay-function so it can update the region
17031 according to the new position of point. */
17032 /* Other than the cursor, w's redisplay is done so we can set its
17033 redisplay to false. Also the buffer's redisplay can be set to
17034 false, since propagate_buffer_redisplay should have already
17035 propagated its info to `w' anyway. */
17036 w
->redisplay
= false;
17037 XBUFFER (w
->contents
)->text
->redisplay
= false;
17038 safe__call1 (true, Vpre_redisplay_function
, Fcons (window
, Qnil
));
17040 if (w
->redisplay
|| XBUFFER (w
->contents
)->text
->redisplay
17041 || ((EQ (Vdisplay_line_numbers
, Qrelative
)
17042 || EQ (Vdisplay_line_numbers
, Qvisual
))
17043 && row
!= MATRIX_FIRST_TEXT_ROW (w
->desired_matrix
)))
17045 /* Either pre-redisplay-function made changes (e.g. move
17046 the region), or we moved point in a window that is
17047 under display-line-numbers = relative mode. We need
17048 another round of redisplay. */
17049 clear_glyph_matrix (w
->desired_matrix
);
17050 if (!try_window (window
, startp
, 0))
17051 goto need_larger_matrices
;
17054 if (w
->cursor
.vpos
< 0 || !cursor_row_fully_visible_p (w
, false, false))
17056 clear_glyph_matrix (w
->desired_matrix
);
17057 goto try_to_scroll
;
17061 debug_method_add (w
, "forced window start");
17066 /* Handle case where text has not changed, only point, and it has
17067 not moved off the frame, and we are not retrying after hscroll.
17068 (current_matrix_up_to_date_p is true when retrying.) */
17069 if (current_matrix_up_to_date_p
17070 && (rc
= try_cursor_movement (window
, startp
, &temp_scroll_step
),
17071 rc
!= CURSOR_MOVEMENT_CANNOT_BE_USED
))
17075 case CURSOR_MOVEMENT_SUCCESS
:
17076 used_current_matrix_p
= true;
17079 case CURSOR_MOVEMENT_MUST_SCROLL
:
17080 goto try_to_scroll
;
17086 /* If current starting point was originally the beginning of a line
17087 but no longer is, find a new starting point. */
17088 else if (w
->start_at_line_beg
17089 && !(CHARPOS (startp
) <= BEGV
17090 || FETCH_BYTE (BYTEPOS (startp
) - 1) == '\n'))
17093 debug_method_add (w
, "recenter 1");
17098 /* Try scrolling with try_window_id. Value is > 0 if update has
17099 been done, it is -1 if we know that the same window start will
17100 not work. It is 0 if unsuccessful for some other reason. */
17101 else if ((tem
= try_window_id (w
)) != 0)
17104 debug_method_add (w
, "try_window_id %d", tem
);
17107 if (f
->fonts_changed
)
17108 goto need_larger_matrices
;
17112 /* Otherwise try_window_id has returned -1 which means that we
17113 don't want the alternative below this comment to execute. */
17115 else if (CHARPOS (startp
) >= BEGV
17116 && CHARPOS (startp
) <= ZV
17117 && PT
>= CHARPOS (startp
)
17118 && (CHARPOS (startp
) < ZV
17119 /* Avoid starting at end of buffer. */
17120 || CHARPOS (startp
) == BEGV
17121 || !window_outdated (w
)))
17123 int d1
, d2
, d5
, d6
;
17126 /* If first window line is a continuation line, and window start
17127 is inside the modified region, but the first change is before
17128 current window start, we must select a new window start.
17130 However, if this is the result of a down-mouse event (e.g. by
17131 extending the mouse-drag-overlay), we don't want to select a
17132 new window start, since that would change the position under
17133 the mouse, resulting in an unwanted mouse-movement rather
17134 than a simple mouse-click. */
17135 if (!w
->start_at_line_beg
17136 && NILP (do_mouse_tracking
)
17137 && CHARPOS (startp
) > BEGV
17138 && CHARPOS (startp
) > BEG
+ beg_unchanged
17139 && CHARPOS (startp
) <= Z
- end_unchanged
17140 /* Even if w->start_at_line_beg is nil, a new window may
17141 start at a line_beg, since that's how set_buffer_window
17142 sets it. So, we need to check the return value of
17143 compute_window_start_on_continuation_line. (See also
17145 && XMARKER (w
->start
)->buffer
== current_buffer
17146 && compute_window_start_on_continuation_line (w
)
17147 /* It doesn't make sense to force the window start like we
17148 do at label force_start if it is already known that point
17149 will not be fully visible in the resulting window, because
17150 doing so will move point from its correct position
17151 instead of scrolling the window to bring point into view.
17153 && pos_visible_p (w
, PT
, &d1
, &d2
, &rtop
, &rbot
, &d5
, &d6
)
17154 /* A very tall row could need more than the window height,
17155 in which case we accept that it is partially visible. */
17156 && (rtop
!= 0) == (rbot
!= 0))
17158 w
->force_start
= true;
17159 SET_TEXT_POS_FROM_MARKER (startp
, w
->start
);
17161 debug_method_add (w
, "recomputed window start in continuation line");
17167 debug_method_add (w
, "same window start");
17170 /* Try to redisplay starting at same place as before.
17171 If point has not moved off frame, accept the results. */
17172 if (!current_matrix_up_to_date_p
17173 /* Don't use try_window_reusing_current_matrix in this case
17174 because a window scroll function can have changed the
17176 || !NILP (Vwindow_scroll_functions
)
17177 || MINI_WINDOW_P (w
)
17178 || !(used_current_matrix_p
17179 = try_window_reusing_current_matrix (w
)))
17181 IF_DEBUG (debug_method_add (w
, "1"));
17182 clear_glyph_matrix (w
->desired_matrix
);
17183 if (try_window (window
, startp
, TRY_WINDOW_CHECK_MARGINS
) < 0)
17184 /* -1 means we need to scroll.
17185 0 means we need new matrices, but fonts_changed
17186 is set in that case, so we will detect it below. */
17187 goto try_to_scroll
;
17190 if (f
->fonts_changed
)
17191 goto need_larger_matrices
;
17193 if (w
->cursor
.vpos
>= 0)
17195 if (!just_this_one_p
17196 || current_buffer
->clip_changed
17197 || BEG_UNCHANGED
< CHARPOS (startp
))
17198 /* Forget any recorded base line for line number display. */
17199 w
->base_line_number
= 0;
17201 if (!cursor_row_fully_visible_p (w
, true, false))
17203 clear_glyph_matrix (w
->desired_matrix
);
17204 last_line_misfit
= true;
17206 /* Drop through and scroll. */
17211 clear_glyph_matrix (w
->desired_matrix
);
17216 /* Redisplay the mode line. Select the buffer properly for that. */
17217 if (!update_mode_line
)
17219 update_mode_line
= true;
17220 w
->update_mode_line
= true;
17223 /* Try to scroll by specified few lines. */
17224 if ((scroll_conservatively
17225 || emacs_scroll_step
17226 || temp_scroll_step
17227 || NUMBERP (BVAR (current_buffer
, scroll_up_aggressively
))
17228 || NUMBERP (BVAR (current_buffer
, scroll_down_aggressively
)))
17229 && CHARPOS (startp
) >= BEGV
17230 && CHARPOS (startp
) <= ZV
)
17232 /* The function returns -1 if new fonts were loaded, 1 if
17233 successful, 0 if not successful. */
17234 int ss
= try_scrolling (window
, just_this_one_p
,
17235 scroll_conservatively
,
17237 temp_scroll_step
, last_line_misfit
);
17240 case SCROLLING_SUCCESS
:
17243 case SCROLLING_NEED_LARGER_MATRICES
:
17244 goto need_larger_matrices
;
17246 case SCROLLING_FAILED
:
17254 /* Finally, just choose a place to start which positions point
17255 according to user preferences. */
17260 debug_method_add (w
, "recenter");
17263 /* Forget any previously recorded base line for line number display. */
17264 if (!buffer_unchanged_p
)
17265 w
->base_line_number
= 0;
17267 /* Determine the window start relative to point. */
17268 init_iterator (&it
, w
, PT
, PT_BYTE
, NULL
, DEFAULT_FACE_ID
);
17269 it
.current_y
= it
.last_visible_y
;
17270 if (centering_position
< 0)
17272 ptrdiff_t margin_pos
= CHARPOS (startp
);
17273 Lisp_Object aggressive
;
17276 /* If there is a scroll margin at the top of the window, find
17277 its character position. */
17279 /* Cannot call start_display if startp is not in the
17280 accessible region of the buffer. This can happen when we
17281 have just switched to a different buffer and/or changed
17282 its restriction. In that case, startp is initialized to
17283 the character position 1 (BEGV) because we did not yet
17284 have chance to display the buffer even once. */
17285 && BEGV
<= CHARPOS (startp
) && CHARPOS (startp
) <= ZV
)
17288 void *it1data
= NULL
;
17290 SAVE_IT (it1
, it
, it1data
);
17291 start_display (&it1
, w
, startp
);
17292 move_it_vertically (&it1
, margin
* frame_line_height
);
17293 margin_pos
= IT_CHARPOS (it1
);
17294 RESTORE_IT (&it
, &it
, it1data
);
17296 scrolling_up
= PT
> margin_pos
;
17299 ? BVAR (current_buffer
, scroll_up_aggressively
)
17300 : BVAR (current_buffer
, scroll_down_aggressively
);
17302 if (!MINI_WINDOW_P (w
)
17303 && (scroll_conservatively
> SCROLL_LIMIT
|| NUMBERP (aggressive
)))
17307 /* Setting scroll-conservatively overrides
17308 scroll-*-aggressively. */
17309 if (!scroll_conservatively
&& NUMBERP (aggressive
))
17311 double float_amount
= XFLOATINT (aggressive
);
17313 pt_offset
= float_amount
* WINDOW_BOX_TEXT_HEIGHT (w
);
17314 if (pt_offset
== 0 && float_amount
> 0)
17316 if (pt_offset
&& margin
> 0)
17319 /* Compute how much to move the window start backward from
17320 point so that point will be displayed where the user
17324 centering_position
= it
.last_visible_y
;
17326 centering_position
-= pt_offset
;
17327 centering_position
-=
17328 (frame_line_height
* (1 + margin
+ last_line_misfit
)
17329 + WINDOW_HEADER_LINE_HEIGHT (w
));
17330 /* Don't let point enter the scroll margin near top of
17332 if (centering_position
< margin
* frame_line_height
)
17333 centering_position
= margin
* frame_line_height
;
17336 centering_position
= margin
* frame_line_height
+ pt_offset
;
17339 /* Set the window start half the height of the window backward
17341 centering_position
= window_box_height (w
) / 2;
17343 move_it_vertically_backward (&it
, centering_position
);
17345 eassert (IT_CHARPOS (it
) >= BEGV
);
17347 /* The function move_it_vertically_backward may move over more
17348 than the specified y-distance. If it->w is small, e.g. a
17349 mini-buffer window, we may end up in front of the window's
17350 display area. Start displaying at the start of the line
17351 containing PT in this case. */
17352 if (it
.current_y
<= 0)
17354 init_iterator (&it
, w
, PT
, PT_BYTE
, NULL
, DEFAULT_FACE_ID
);
17355 move_it_vertically_backward (&it
, 0);
17359 it
.current_x
= it
.hpos
= 0;
17361 /* Set the window start position here explicitly, to avoid an
17362 infinite loop in case the functions in window-scroll-functions
17364 set_marker_both (w
->start
, Qnil
, IT_CHARPOS (it
), IT_BYTEPOS (it
));
17366 /* Run scroll hooks. */
17367 startp
= run_window_scroll_functions (window
, it
.current
.pos
);
17369 /* We invoke try_window and try_window_reusing_current_matrix below,
17370 and they manipulate the bidi cache. Save and restore the cache
17371 state of our iterator, so we could continue using it after that. */
17372 itdata
= bidi_shelve_cache ();
17374 /* Redisplay the window. */
17375 use_desired_matrix
= false;
17376 if (!current_matrix_up_to_date_p
17377 || windows_or_buffers_changed
17378 || f
->cursor_type_changed
17379 /* Don't use try_window_reusing_current_matrix in this case
17380 because it can have changed the buffer. */
17381 || !NILP (Vwindow_scroll_functions
)
17382 || !just_this_one_p
17383 || MINI_WINDOW_P (w
)
17384 || !(used_current_matrix_p
17385 = try_window_reusing_current_matrix (w
)))
17386 use_desired_matrix
= (try_window (window
, startp
, 0) == 1);
17388 bidi_unshelve_cache (itdata
, false);
17390 /* If new fonts have been loaded (due to fontsets), give up. We
17391 have to start a new redisplay since we need to re-adjust glyph
17393 if (f
->fonts_changed
)
17394 goto need_larger_matrices
;
17396 /* If cursor did not appear assume that the middle of the window is
17397 in the first line of the window. Do it again with the next line.
17398 (Imagine a window of height 100, displaying two lines of height
17399 60. Moving back 50 from it->last_visible_y will end in the first
17401 if (w
->cursor
.vpos
< 0)
17403 if (w
->window_end_valid
&& PT
>= Z
- w
->window_end_pos
)
17405 clear_glyph_matrix (w
->desired_matrix
);
17406 move_it_by_lines (&it
, 1);
17407 try_window (window
, it
.current
.pos
, 0);
17409 else if (PT
< IT_CHARPOS (it
))
17411 clear_glyph_matrix (w
->desired_matrix
);
17412 move_it_by_lines (&it
, -1);
17413 try_window (window
, it
.current
.pos
, 0);
17415 else if (scroll_conservatively
> SCROLL_LIMIT
17416 && (it
.method
== GET_FROM_STRING
17417 || overlay_touches_p (IT_CHARPOS (it
)))
17418 && IT_CHARPOS (it
) < ZV
)
17420 /* If the window starts with a before-string that spans more
17421 than one screen line, using that position to display the
17422 window might fail to bring point into the view, because
17423 start_display will always start by displaying the string,
17424 whereas the code above determines where to set w->start
17425 by the buffer position of the place where it takes screen
17426 coordinates. Try to recover by finding the next screen
17427 line that displays buffer text. */
17428 ptrdiff_t pos0
= IT_CHARPOS (it
);
17430 clear_glyph_matrix (w
->desired_matrix
);
17432 move_it_by_lines (&it
, 1);
17433 } while (IT_CHARPOS (it
) == pos0
);
17434 try_window (window
, it
.current
.pos
, 0);
17438 /* Not much we can do about it. */
17442 /* Consider the following case: Window starts at BEGV, there is
17443 invisible, intangible text at BEGV, so that display starts at
17444 some point START > BEGV. It can happen that we are called with
17445 PT somewhere between BEGV and START. Try to handle that case,
17446 and similar ones. */
17447 if (w
->cursor
.vpos
< 0)
17449 /* Prefer the desired matrix to the current matrix, if possible,
17450 in the fallback calculations below. This is because using
17451 the current matrix might completely goof, e.g. if its first
17452 row is after point. */
17453 struct glyph_matrix
*matrix
=
17454 use_desired_matrix
? w
->desired_matrix
: w
->current_matrix
;
17455 /* First, try locating the proper glyph row for PT. */
17456 struct glyph_row
*row
=
17457 row_containing_pos (w
, PT
, matrix
->rows
, NULL
, 0);
17459 /* Sometimes point is at the beginning of invisible text that is
17460 before the 1st character displayed in the row. In that case,
17461 row_containing_pos fails to find the row, because no glyphs
17462 with appropriate buffer positions are present in the row.
17463 Therefore, we next try to find the row which shows the 1st
17464 position after the invisible text. */
17468 get_char_property_and_overlay (make_number (PT
), Qinvisible
,
17471 if (TEXT_PROP_MEANS_INVISIBLE (val
) != 0)
17474 Lisp_Object invis_end
=
17475 Fnext_single_char_property_change (make_number (PT
), Qinvisible
,
17478 if (NATNUMP (invis_end
))
17479 alt_pos
= XFASTINT (invis_end
);
17482 row
= row_containing_pos (w
, alt_pos
, matrix
->rows
, NULL
, 0);
17485 /* Finally, fall back on the first row of the window after the
17486 header line (if any). This is slightly better than not
17487 displaying the cursor at all. */
17490 row
= matrix
->rows
;
17491 if (row
->mode_line_p
)
17494 set_cursor_from_row (w
, row
, matrix
, 0, 0, 0, 0);
17497 if (!cursor_row_fully_visible_p (w
, false, false))
17499 /* If vscroll is enabled, disable it and try again. */
17503 clear_glyph_matrix (w
->desired_matrix
);
17507 /* Users who set scroll-conservatively to a large number want
17508 point just above/below the scroll margin. If we ended up
17509 with point's row partially visible, move the window start to
17510 make that row fully visible and out of the margin. */
17511 if (scroll_conservatively
> SCROLL_LIMIT
)
17513 int window_total_lines
17514 = WINDOW_TOTAL_LINES (w
) * FRAME_LINE_HEIGHT (f
) / frame_line_height
;
17515 bool move_down
= w
->cursor
.vpos
>= window_total_lines
/ 2;
17517 move_it_by_lines (&it
, move_down
? margin
+ 1 : -(margin
+ 1));
17518 clear_glyph_matrix (w
->desired_matrix
);
17519 if (1 == try_window (window
, it
.current
.pos
,
17520 TRY_WINDOW_CHECK_MARGINS
))
17524 /* If centering point failed to make the whole line visible,
17525 put point at the top instead. That has to make the whole line
17526 visible, if it can be done. */
17527 if (centering_position
== 0)
17530 clear_glyph_matrix (w
->desired_matrix
);
17531 centering_position
= 0;
17537 SET_TEXT_POS_FROM_MARKER (startp
, w
->start
);
17538 w
->start_at_line_beg
= (CHARPOS (startp
) == BEGV
17539 || FETCH_BYTE (BYTEPOS (startp
) - 1) == '\n');
17541 /* Display the mode line, if we must. */
17542 if ((update_mode_line
17543 /* If window not full width, must redo its mode line
17544 if (a) the window to its side is being redone and
17545 (b) we do a frame-based redisplay. This is a consequence
17546 of how inverted lines are drawn in frame-based redisplay. */
17547 || (!just_this_one_p
17548 && !FRAME_WINDOW_P (f
)
17549 && !WINDOW_FULL_WIDTH_P (w
))
17550 /* Line number to display. */
17551 || w
->base_line_pos
> 0
17552 /* Column number is displayed and different from the one displayed. */
17553 || (w
->column_number_displayed
!= -1
17554 && (w
->column_number_displayed
!= current_column ())))
17555 /* This means that the window has a mode line. */
17556 && (window_wants_mode_line (w
)
17557 || window_wants_header_line (w
)))
17560 display_mode_lines (w
);
17562 /* If mode line height has changed, arrange for a thorough
17563 immediate redisplay using the correct mode line height. */
17564 if (window_wants_mode_line (w
)
17565 && CURRENT_MODE_LINE_HEIGHT (w
) != DESIRED_MODE_LINE_HEIGHT (w
))
17567 f
->fonts_changed
= true;
17568 w
->mode_line_height
= -1;
17569 MATRIX_MODE_LINE_ROW (w
->current_matrix
)->height
17570 = DESIRED_MODE_LINE_HEIGHT (w
);
17573 /* If header line height has changed, arrange for a thorough
17574 immediate redisplay using the correct header line height. */
17575 if (window_wants_header_line (w
)
17576 && CURRENT_HEADER_LINE_HEIGHT (w
) != DESIRED_HEADER_LINE_HEIGHT (w
))
17578 f
->fonts_changed
= true;
17579 w
->header_line_height
= -1;
17580 MATRIX_HEADER_LINE_ROW (w
->current_matrix
)->height
17581 = DESIRED_HEADER_LINE_HEIGHT (w
);
17584 if (f
->fonts_changed
)
17585 goto need_larger_matrices
;
17588 if (!line_number_displayed
&& w
->base_line_pos
!= -1)
17590 w
->base_line_pos
= 0;
17591 w
->base_line_number
= 0;
17596 /* When we reach a frame's selected window, redo the frame's menu
17597 bar and the frame's title. */
17598 if (update_mode_line
17599 && EQ (FRAME_SELECTED_WINDOW (f
), window
))
17601 bool redisplay_menu_p
;
17603 if (FRAME_WINDOW_P (f
))
17605 #if defined (USE_X_TOOLKIT) || defined (HAVE_NTGUI) \
17606 || defined (HAVE_NS) || defined (USE_GTK)
17607 redisplay_menu_p
= FRAME_EXTERNAL_MENU_BAR (f
);
17609 redisplay_menu_p
= FRAME_MENU_BAR_LINES (f
) > 0;
17613 redisplay_menu_p
= FRAME_MENU_BAR_LINES (f
) > 0;
17615 if (redisplay_menu_p
)
17616 display_menu_bar (w
);
17618 #ifdef HAVE_WINDOW_SYSTEM
17619 if (FRAME_WINDOW_P (f
))
17621 #if defined (USE_GTK) || defined (HAVE_NS)
17622 if (FRAME_EXTERNAL_TOOL_BAR (f
))
17623 redisplay_tool_bar (f
);
17625 if (WINDOWP (f
->tool_bar_window
)
17626 && (FRAME_TOOL_BAR_LINES (f
) > 0
17627 || !NILP (Vauto_resize_tool_bars
))
17628 && redisplay_tool_bar (f
))
17629 ignore_mouse_drag_p
= true;
17632 x_consider_frame_title (w
->frame
);
17636 #ifdef HAVE_WINDOW_SYSTEM
17637 if (FRAME_WINDOW_P (f
)
17638 && update_window_fringes (w
, (just_this_one_p
17639 || (!used_current_matrix_p
&& !overlay_arrow_seen
)
17640 || w
->pseudo_window_p
)))
17644 if (draw_window_fringes (w
, true))
17646 if (WINDOW_RIGHT_DIVIDER_WIDTH (w
))
17647 x_draw_right_divider (w
);
17649 x_draw_vertical_border (w
);
17655 if (WINDOW_BOTTOM_DIVIDER_WIDTH (w
))
17656 x_draw_bottom_divider (w
);
17657 #endif /* HAVE_WINDOW_SYSTEM */
17659 /* We go to this label, with fonts_changed set, if it is
17660 necessary to try again using larger glyph matrices.
17661 We have to redeem the scroll bar even in this case,
17662 because the loop in redisplay_internal expects that. */
17663 need_larger_matrices
:
17665 finish_scroll_bars
:
17667 if (WINDOW_HAS_VERTICAL_SCROLL_BAR (w
) || WINDOW_HAS_HORIZONTAL_SCROLL_BAR (w
))
17669 if (WINDOW_HAS_VERTICAL_SCROLL_BAR (w
))
17670 /* Set the thumb's position and size. */
17671 set_vertical_scroll_bar (w
);
17673 if (WINDOW_HAS_HORIZONTAL_SCROLL_BAR (w
))
17674 /* Set the thumb's position and size. */
17675 set_horizontal_scroll_bar (w
);
17677 /* Note that we actually used the scroll bar attached to this
17678 window, so it shouldn't be deleted at the end of redisplay. */
17679 if (FRAME_TERMINAL (f
)->redeem_scroll_bar_hook
)
17680 (*FRAME_TERMINAL (f
)->redeem_scroll_bar_hook
) (w
);
17683 /* Restore current_buffer and value of point in it. The window
17684 update may have changed the buffer, so first make sure `opoint'
17685 is still valid (Bug#6177). */
17686 if (CHARPOS (opoint
) < BEGV
)
17687 TEMP_SET_PT_BOTH (BEGV
, BEGV_BYTE
);
17688 else if (CHARPOS (opoint
) > ZV
)
17689 TEMP_SET_PT_BOTH (Z
, Z_BYTE
);
17691 TEMP_SET_PT_BOTH (CHARPOS (opoint
), BYTEPOS (opoint
));
17693 set_buffer_internal_1 (old
);
17694 /* Avoid an abort in TEMP_SET_PT_BOTH if the buffer has become
17695 shorter. This can be caused by log truncation in *Messages*. */
17696 if (CHARPOS (lpoint
) <= ZV
)
17697 TEMP_SET_PT_BOTH (CHARPOS (lpoint
), BYTEPOS (lpoint
));
17699 unbind_to (count
, Qnil
);
17703 /* Build the complete desired matrix of WINDOW with a window start
17704 buffer position POS.
17706 Value is 1 if successful. It is zero if fonts were loaded during
17707 redisplay which makes re-adjusting glyph matrices necessary, and -1
17708 if point would appear in the scroll margins.
17709 (We check the former only if TRY_WINDOW_IGNORE_FONTS_CHANGE is
17710 unset in FLAGS, and the latter only if TRY_WINDOW_CHECK_MARGINS is
17714 try_window (Lisp_Object window
, struct text_pos pos
, int flags
)
17716 struct window
*w
= XWINDOW (window
);
17718 struct glyph_row
*last_text_row
= NULL
;
17719 struct frame
*f
= XFRAME (w
->frame
);
17720 int cursor_vpos
= w
->cursor
.vpos
;
17722 /* Make POS the new window start. */
17723 set_marker_both (w
->start
, Qnil
, CHARPOS (pos
), BYTEPOS (pos
));
17725 /* Mark cursor position as unknown. No overlay arrow seen. */
17726 w
->cursor
.vpos
= -1;
17727 overlay_arrow_seen
= false;
17729 /* Initialize iterator and info to start at POS. */
17730 start_display (&it
, w
, pos
);
17731 it
.glyph_row
->reversed_p
= false;
17733 /* Display all lines of W. */
17734 while (it
.current_y
< it
.last_visible_y
)
17736 if (display_line (&it
, cursor_vpos
))
17737 last_text_row
= it
.glyph_row
- 1;
17738 if (f
->fonts_changed
&& !(flags
& TRY_WINDOW_IGNORE_FONTS_CHANGE
))
17742 /* Save the character position of 'it' before we call
17743 'start_display' again. */
17744 ptrdiff_t it_charpos
= IT_CHARPOS (it
);
17746 /* Don't let the cursor end in the scroll margins. */
17747 if ((flags
& TRY_WINDOW_CHECK_MARGINS
)
17748 && !MINI_WINDOW_P (w
))
17750 int this_scroll_margin
= window_scroll_margin (w
, MARGIN_IN_PIXELS
);
17751 start_display (&it
, w
, pos
);
17753 if ((w
->cursor
.y
>= 0 /* not vscrolled */
17754 && w
->cursor
.y
< this_scroll_margin
17755 && CHARPOS (pos
) > BEGV
17756 && it_charpos
< ZV
)
17757 /* rms: considering make_cursor_line_fully_visible_p here
17758 seems to give wrong results. We don't want to recenter
17759 when the last line is partly visible, we want to allow
17760 that case to be handled in the usual way. */
17761 || w
->cursor
.y
> (it
.last_visible_y
- partial_line_height (&it
)
17762 - this_scroll_margin
- 1))
17764 w
->cursor
.vpos
= -1;
17765 clear_glyph_matrix (w
->desired_matrix
);
17770 /* If bottom moved off end of frame, change mode line percentage. */
17771 if (w
->window_end_pos
<= 0 && Z
!= it_charpos
)
17772 w
->update_mode_line
= true;
17774 /* Set window_end_pos to the offset of the last character displayed
17775 on the window from the end of current_buffer. Set
17776 window_end_vpos to its row number. */
17779 eassert (MATRIX_ROW_DISPLAYS_TEXT_P (last_text_row
));
17780 adjust_window_ends (w
, last_text_row
, false);
17782 (MATRIX_ROW_DISPLAYS_TEXT_P (MATRIX_ROW (w
->desired_matrix
,
17783 w
->window_end_vpos
)));
17787 w
->window_end_bytepos
= Z_BYTE
- ZV_BYTE
;
17788 w
->window_end_pos
= Z
- ZV
;
17789 w
->window_end_vpos
= 0;
17792 /* But that is not valid info until redisplay finishes. */
17793 w
->window_end_valid
= false;
17799 /************************************************************************
17800 Window redisplay reusing current matrix when buffer has not changed
17801 ************************************************************************/
17803 /* Try redisplay of window W showing an unchanged buffer with a
17804 different window start than the last time it was displayed by
17805 reusing its current matrix. Value is true if successful.
17806 W->start is the new window start. */
17809 try_window_reusing_current_matrix (struct window
*w
)
17811 struct frame
*f
= XFRAME (w
->frame
);
17812 struct glyph_row
*bottom_row
;
17815 struct text_pos start
, new_start
;
17816 int nrows_scrolled
, i
;
17817 struct glyph_row
*last_text_row
;
17818 struct glyph_row
*last_reused_text_row
;
17819 struct glyph_row
*start_row
;
17820 int start_vpos
, min_y
, max_y
;
17823 if (inhibit_try_window_reusing
)
17827 if (/* This function doesn't handle terminal frames. */
17828 !FRAME_WINDOW_P (f
)
17829 /* Don't try to reuse the display if windows have been split
17831 || windows_or_buffers_changed
17832 || f
->cursor_type_changed
17833 /* This function cannot handle buffers where the overlay arrow
17834 is shown on the fringes, because if the arrow position
17835 changes, we cannot just reuse the current matrix. */
17836 || overlay_arrow_in_current_buffer_p ())
17839 /* Can't do this if showing trailing whitespace. */
17840 if (!NILP (Vshow_trailing_whitespace
))
17843 /* If top-line visibility has changed, give up. */
17844 if (window_wants_header_line (w
)
17845 != MATRIX_HEADER_LINE_ROW (w
->current_matrix
)->mode_line_p
)
17848 /* Give up if old or new display is scrolled vertically. We could
17849 make this function handle this, but right now it doesn't. */
17850 start_row
= MATRIX_FIRST_TEXT_ROW (w
->current_matrix
);
17851 if (w
->vscroll
|| MATRIX_ROW_PARTIALLY_VISIBLE_P (w
, start_row
))
17854 /* Clear the desired matrix for the display below. */
17855 clear_glyph_matrix (w
->desired_matrix
);
17857 /* Give up if line numbers are being displayed, because reusing the
17858 current matrix might use the wrong width for line-number
17860 if (!NILP (Vdisplay_line_numbers
))
17863 /* The variable new_start now holds the new window start. The old
17864 start `start' can be determined from the current matrix. */
17865 SET_TEXT_POS_FROM_MARKER (new_start
, w
->start
);
17866 start
= start_row
->minpos
;
17867 start_vpos
= MATRIX_ROW_VPOS (start_row
, w
->current_matrix
);
17869 if (CHARPOS (new_start
) <= CHARPOS (start
))
17871 /* Don't use this method if the display starts with an ellipsis
17872 displayed for invisible text. It's not easy to handle that case
17873 below, and it's certainly not worth the effort since this is
17874 not a frequent case. */
17875 if (in_ellipses_for_invisible_text_p (&start_row
->start
, w
))
17878 IF_DEBUG (debug_method_add (w
, "twu1"));
17880 /* Display up to a row that can be reused. The variable
17881 last_text_row is set to the last row displayed that displays
17882 text. Note that it.vpos == 0 if or if not there is a
17883 header-line; it's not the same as the MATRIX_ROW_VPOS! */
17884 start_display (&it
, w
, new_start
);
17885 w
->cursor
.vpos
= -1;
17886 last_text_row
= last_reused_text_row
= NULL
;
17888 while (it
.current_y
< it
.last_visible_y
&& !f
->fonts_changed
)
17890 /* If we have reached into the characters in the START row,
17891 that means the line boundaries have changed. So we
17892 can't start copying with the row START. Maybe it will
17893 work to start copying with the following row. */
17894 while (IT_CHARPOS (it
) > CHARPOS (start
))
17896 /* Advance to the next row as the "start". */
17898 start
= start_row
->minpos
;
17899 /* If there are no more rows to try, or just one, give up. */
17900 if (start_row
== MATRIX_MODE_LINE_ROW (w
->current_matrix
) - 1
17901 || w
->vscroll
|| MATRIX_ROW_PARTIALLY_VISIBLE_P (w
, start_row
)
17902 || CHARPOS (start
) == ZV
)
17904 clear_glyph_matrix (w
->desired_matrix
);
17908 start_vpos
= MATRIX_ROW_VPOS (start_row
, w
->current_matrix
);
17910 /* If we have reached alignment, we can copy the rest of the
17912 if (IT_CHARPOS (it
) == CHARPOS (start
)
17913 /* Don't accept "alignment" inside a display vector,
17914 since start_row could have started in the middle of
17915 that same display vector (thus their character
17916 positions match), and we have no way of telling if
17917 that is the case. */
17918 && it
.current
.dpvec_index
< 0)
17921 it
.glyph_row
->reversed_p
= false;
17922 if (display_line (&it
, -1))
17923 last_text_row
= it
.glyph_row
- 1;
17927 /* A value of current_y < last_visible_y means that we stopped
17928 at the previous window start, which in turn means that we
17929 have at least one reusable row. */
17930 if (it
.current_y
< it
.last_visible_y
)
17932 struct glyph_row
*row
;
17934 /* IT.vpos always starts from 0; it counts text lines. */
17935 nrows_scrolled
= it
.vpos
- (start_row
- MATRIX_FIRST_TEXT_ROW (w
->current_matrix
));
17937 /* Find PT if not already found in the lines displayed. */
17938 if (w
->cursor
.vpos
< 0)
17940 int dy
= it
.current_y
- start_row
->y
;
17942 row
= MATRIX_FIRST_TEXT_ROW (w
->current_matrix
);
17943 row
= row_containing_pos (w
, PT
, row
, NULL
, dy
);
17945 set_cursor_from_row (w
, row
, w
->current_matrix
, 0, 0,
17946 dy
, nrows_scrolled
);
17949 clear_glyph_matrix (w
->desired_matrix
);
17954 /* Scroll the display. Do it before the current matrix is
17955 changed. The problem here is that update has not yet
17956 run, i.e. part of the current matrix is not up to date.
17957 scroll_run_hook will clear the cursor, and use the
17958 current matrix to get the height of the row the cursor is
17960 run
.current_y
= start_row
->y
;
17961 run
.desired_y
= it
.current_y
;
17962 run
.height
= it
.last_visible_y
- it
.current_y
;
17964 if (run
.height
> 0 && run
.current_y
!= run
.desired_y
)
17967 FRAME_RIF (f
)->update_window_begin_hook (w
);
17968 FRAME_RIF (f
)->clear_window_mouse_face (w
);
17969 FRAME_RIF (f
)->scroll_run_hook (w
, &run
);
17970 FRAME_RIF (f
)->update_window_end_hook (w
, false, false);
17974 /* Shift current matrix down by nrows_scrolled lines. */
17975 bottom_row
= MATRIX_BOTTOM_TEXT_ROW (w
->current_matrix
, w
);
17976 rotate_matrix (w
->current_matrix
,
17978 MATRIX_ROW_VPOS (bottom_row
, w
->current_matrix
),
17981 /* Disable lines that must be updated. */
17982 for (i
= 0; i
< nrows_scrolled
; ++i
)
17983 (start_row
+ i
)->enabled_p
= false;
17985 /* Re-compute Y positions. */
17986 min_y
= WINDOW_HEADER_LINE_HEIGHT (w
);
17987 max_y
= it
.last_visible_y
;
17988 for (row
= start_row
+ nrows_scrolled
;
17992 row
->y
= it
.current_y
;
17993 row
->visible_height
= row
->height
;
17995 if (row
->y
< min_y
)
17996 row
->visible_height
-= min_y
- row
->y
;
17997 if (row
->y
+ row
->height
> max_y
)
17998 row
->visible_height
-= row
->y
+ row
->height
- max_y
;
17999 if (row
->fringe_bitmap_periodic_p
)
18000 row
->redraw_fringe_bitmaps_p
= true;
18002 it
.current_y
+= row
->height
;
18004 if (MATRIX_ROW_DISPLAYS_TEXT_P (row
))
18005 last_reused_text_row
= row
;
18006 if (MATRIX_ROW_BOTTOM_Y (row
) >= it
.last_visible_y
)
18010 /* Disable lines in the current matrix which are now
18011 below the window. */
18012 for (++row
; row
< bottom_row
; ++row
)
18013 row
->enabled_p
= row
->mode_line_p
= false;
18016 /* Update window_end_pos etc.; last_reused_text_row is the last
18017 reused row from the current matrix containing text, if any.
18018 The value of last_text_row is the last displayed line
18019 containing text. */
18020 if (last_reused_text_row
)
18021 adjust_window_ends (w
, last_reused_text_row
, true);
18022 else if (last_text_row
)
18023 adjust_window_ends (w
, last_text_row
, false);
18026 /* This window must be completely empty. */
18027 w
->window_end_bytepos
= Z_BYTE
- ZV_BYTE
;
18028 w
->window_end_pos
= Z
- ZV
;
18029 w
->window_end_vpos
= 0;
18031 w
->window_end_valid
= false;
18033 /* Update hint: don't try scrolling again in update_window. */
18034 w
->desired_matrix
->no_scrolling_p
= true;
18037 debug_method_add (w
, "try_window_reusing_current_matrix 1");
18041 else if (CHARPOS (new_start
) > CHARPOS (start
))
18043 struct glyph_row
*pt_row
, *row
;
18044 struct glyph_row
*first_reusable_row
;
18045 struct glyph_row
*first_row_to_display
;
18047 int yb
= window_text_bottom_y (w
);
18049 /* Find the row starting at new_start, if there is one. Don't
18050 reuse a partially visible line at the end. */
18051 first_reusable_row
= start_row
;
18052 while (first_reusable_row
->enabled_p
18053 && MATRIX_ROW_BOTTOM_Y (first_reusable_row
) < yb
18054 && (MATRIX_ROW_START_CHARPOS (first_reusable_row
)
18055 < CHARPOS (new_start
)))
18056 ++first_reusable_row
;
18058 /* Give up if there is no row to reuse. */
18059 if (MATRIX_ROW_BOTTOM_Y (first_reusable_row
) >= yb
18060 || !first_reusable_row
->enabled_p
18061 || (MATRIX_ROW_START_CHARPOS (first_reusable_row
)
18062 != CHARPOS (new_start
)))
18065 /* We can reuse fully visible rows beginning with
18066 first_reusable_row to the end of the window. Set
18067 first_row_to_display to the first row that cannot be reused.
18068 Set pt_row to the row containing point, if there is any. */
18070 for (first_row_to_display
= first_reusable_row
;
18071 MATRIX_ROW_BOTTOM_Y (first_row_to_display
) < yb
;
18072 ++first_row_to_display
)
18074 if (PT
>= MATRIX_ROW_START_CHARPOS (first_row_to_display
)
18075 && (PT
< MATRIX_ROW_END_CHARPOS (first_row_to_display
)
18076 || (PT
== MATRIX_ROW_END_CHARPOS (first_row_to_display
)
18077 && first_row_to_display
->ends_at_zv_p
18078 && pt_row
== NULL
)))
18079 pt_row
= first_row_to_display
;
18082 /* Start displaying at the start of first_row_to_display. */
18083 eassert (first_row_to_display
->y
< yb
);
18084 init_to_row_start (&it
, w
, first_row_to_display
);
18086 nrows_scrolled
= (MATRIX_ROW_VPOS (first_reusable_row
, w
->current_matrix
)
18088 it
.vpos
= (MATRIX_ROW_VPOS (first_row_to_display
, w
->current_matrix
)
18090 it
.current_y
= (first_row_to_display
->y
- first_reusable_row
->y
18091 + WINDOW_HEADER_LINE_HEIGHT (w
));
18093 /* Display lines beginning with first_row_to_display in the
18094 desired matrix. Set last_text_row to the last row displayed
18095 that displays text. */
18096 it
.glyph_row
= MATRIX_ROW (w
->desired_matrix
, it
.vpos
);
18097 if (pt_row
== NULL
)
18098 w
->cursor
.vpos
= -1;
18099 last_text_row
= NULL
;
18100 while (it
.current_y
< it
.last_visible_y
&& !f
->fonts_changed
)
18101 if (display_line (&it
, w
->cursor
.vpos
))
18102 last_text_row
= it
.glyph_row
- 1;
18104 /* If point is in a reused row, adjust y and vpos of the cursor
18108 w
->cursor
.vpos
-= nrows_scrolled
;
18109 w
->cursor
.y
-= first_reusable_row
->y
- start_row
->y
;
18112 /* Give up if point isn't in a row displayed or reused. (This
18113 also handles the case where w->cursor.vpos < nrows_scrolled
18114 after the calls to display_line, which can happen with scroll
18115 margins. See bug#1295.) */
18116 if (w
->cursor
.vpos
< 0)
18118 clear_glyph_matrix (w
->desired_matrix
);
18122 /* Scroll the display. */
18123 run
.current_y
= first_reusable_row
->y
;
18124 run
.desired_y
= WINDOW_HEADER_LINE_HEIGHT (w
);
18125 run
.height
= it
.last_visible_y
- run
.current_y
;
18126 dy
= run
.current_y
- run
.desired_y
;
18131 FRAME_RIF (f
)->update_window_begin_hook (w
);
18132 FRAME_RIF (f
)->clear_window_mouse_face (w
);
18133 FRAME_RIF (f
)->scroll_run_hook (w
, &run
);
18134 FRAME_RIF (f
)->update_window_end_hook (w
, false, false);
18138 /* Adjust Y positions of reused rows. */
18139 bottom_row
= MATRIX_BOTTOM_TEXT_ROW (w
->current_matrix
, w
);
18140 min_y
= WINDOW_HEADER_LINE_HEIGHT (w
);
18141 max_y
= it
.last_visible_y
;
18142 for (row
= first_reusable_row
; row
< first_row_to_display
; ++row
)
18145 row
->visible_height
= row
->height
;
18146 if (row
->y
< min_y
)
18147 row
->visible_height
-= min_y
- row
->y
;
18148 if (row
->y
+ row
->height
> max_y
)
18149 row
->visible_height
-= row
->y
+ row
->height
- max_y
;
18150 if (row
->fringe_bitmap_periodic_p
)
18151 row
->redraw_fringe_bitmaps_p
= true;
18154 /* Scroll the current matrix. */
18155 eassert (nrows_scrolled
> 0);
18156 rotate_matrix (w
->current_matrix
,
18158 MATRIX_ROW_VPOS (bottom_row
, w
->current_matrix
),
18161 /* Disable rows not reused. */
18162 for (row
-= nrows_scrolled
; row
< bottom_row
; ++row
)
18163 row
->enabled_p
= false;
18165 /* Point may have moved to a different line, so we cannot assume that
18166 the previous cursor position is valid; locate the correct row. */
18169 for (row
= MATRIX_ROW (w
->current_matrix
, w
->cursor
.vpos
);
18171 && PT
>= MATRIX_ROW_END_CHARPOS (row
)
18172 && !row
->ends_at_zv_p
;
18176 w
->cursor
.y
= row
->y
;
18178 if (row
< bottom_row
)
18180 /* Can't simply scan the row for point with
18181 bidi-reordered glyph rows. Let set_cursor_from_row
18182 figure out where to put the cursor, and if it fails,
18184 if (!NILP (BVAR (XBUFFER (w
->contents
), bidi_display_reordering
)))
18186 if (!set_cursor_from_row (w
, row
, w
->current_matrix
,
18189 clear_glyph_matrix (w
->desired_matrix
);
18195 struct glyph
*glyph
= row
->glyphs
[TEXT_AREA
] + w
->cursor
.hpos
;
18196 struct glyph
*end
= row
->glyphs
[TEXT_AREA
] + row
->used
[TEXT_AREA
];
18199 && (!BUFFERP (glyph
->object
)
18200 || glyph
->charpos
< PT
);
18204 w
->cursor
.x
+= glyph
->pixel_width
;
18210 /* Adjust window end. A null value of last_text_row means that
18211 the window end is in reused rows which in turn means that
18212 only its vpos can have changed. */
18214 adjust_window_ends (w
, last_text_row
, false);
18216 w
->window_end_vpos
-= nrows_scrolled
;
18218 w
->window_end_valid
= false;
18219 w
->desired_matrix
->no_scrolling_p
= true;
18222 debug_method_add (w
, "try_window_reusing_current_matrix 2");
18232 /************************************************************************
18233 Window redisplay reusing current matrix when buffer has changed
18234 ************************************************************************/
18236 static struct glyph_row
*find_last_unchanged_at_beg_row (struct window
*);
18237 static struct glyph_row
*find_first_unchanged_at_end_row (struct window
*,
18238 ptrdiff_t *, ptrdiff_t *);
18239 static struct glyph_row
*
18240 find_last_row_displaying_text (struct glyph_matrix
*, struct it
*,
18241 struct glyph_row
*);
18244 /* Return the last row in MATRIX displaying text. If row START is
18245 non-null, start searching with that row. IT gives the dimensions
18246 of the display. Value is null if matrix is empty; otherwise it is
18247 a pointer to the row found. */
18249 static struct glyph_row
*
18250 find_last_row_displaying_text (struct glyph_matrix
*matrix
, struct it
*it
,
18251 struct glyph_row
*start
)
18253 struct glyph_row
*row
, *row_found
;
18255 /* Set row_found to the last row in IT->w's current matrix
18256 displaying text. The loop looks funny but think of partially
18259 row
= start
? start
: MATRIX_FIRST_TEXT_ROW (matrix
);
18260 while (MATRIX_ROW_DISPLAYS_TEXT_P (row
))
18262 eassert (row
->enabled_p
);
18264 if (MATRIX_ROW_BOTTOM_Y (row
) >= it
->last_visible_y
)
18273 /* Return the last row in the current matrix of W that is not affected
18274 by changes at the start of current_buffer that occurred since W's
18275 current matrix was built. Value is null if no such row exists.
18277 BEG_UNCHANGED us the number of characters unchanged at the start of
18278 current_buffer. BEG + BEG_UNCHANGED is the buffer position of the
18279 first changed character in current_buffer. Characters at positions <
18280 BEG + BEG_UNCHANGED are at the same buffer positions as they were
18281 when the current matrix was built. */
18283 static struct glyph_row
*
18284 find_last_unchanged_at_beg_row (struct window
*w
)
18286 ptrdiff_t first_changed_pos
= BEG
+ BEG_UNCHANGED
;
18287 struct glyph_row
*row
;
18288 struct glyph_row
*row_found
= NULL
;
18289 int yb
= window_text_bottom_y (w
);
18291 /* Find the last row displaying unchanged text. */
18292 for (row
= MATRIX_FIRST_TEXT_ROW (w
->current_matrix
);
18293 MATRIX_ROW_DISPLAYS_TEXT_P (row
)
18294 && MATRIX_ROW_START_CHARPOS (row
) < first_changed_pos
;
18297 if (/* If row ends before first_changed_pos, it is unchanged,
18298 except in some case. */
18299 MATRIX_ROW_END_CHARPOS (row
) <= first_changed_pos
18300 /* When row ends in ZV and we write at ZV it is not
18302 && !row
->ends_at_zv_p
18303 /* When first_changed_pos is the end of a continued line,
18304 row is not unchanged because it may be no longer
18306 && !(MATRIX_ROW_END_CHARPOS (row
) == first_changed_pos
18307 && (row
->continued_p
18308 || row
->exact_window_width_line_p
))
18309 /* If ROW->end is beyond ZV, then ROW->end is outdated and
18310 needs to be recomputed, so don't consider this row as
18311 unchanged. This happens when the last line was
18312 bidi-reordered and was killed immediately before this
18313 redisplay cycle. In that case, ROW->end stores the
18314 buffer position of the first visual-order character of
18315 the killed text, which is now beyond ZV. */
18316 && CHARPOS (row
->end
.pos
) <= ZV
)
18319 /* Stop if last visible row. */
18320 if (MATRIX_ROW_BOTTOM_Y (row
) >= yb
)
18328 /* Find the first glyph row in the current matrix of W that is not
18329 affected by changes at the end of current_buffer since the
18330 time W's current matrix was built.
18332 Return in *DELTA the number of chars by which buffer positions in
18333 unchanged text at the end of current_buffer must be adjusted.
18335 Return in *DELTA_BYTES the corresponding number of bytes.
18337 Value is null if no such row exists, i.e. all rows are affected by
18340 static struct glyph_row
*
18341 find_first_unchanged_at_end_row (struct window
*w
,
18342 ptrdiff_t *delta
, ptrdiff_t *delta_bytes
)
18344 struct glyph_row
*row
;
18345 struct glyph_row
*row_found
= NULL
;
18347 *delta
= *delta_bytes
= 0;
18349 /* Display must not have been paused, otherwise the current matrix
18350 is not up to date. */
18351 eassert (w
->window_end_valid
);
18353 /* A value of window_end_pos >= END_UNCHANGED means that the window
18354 end is in the range of changed text. If so, there is no
18355 unchanged row at the end of W's current matrix. */
18356 if (w
->window_end_pos
>= END_UNCHANGED
)
18359 /* Set row to the last row in W's current matrix displaying text. */
18360 row
= MATRIX_ROW (w
->current_matrix
, w
->window_end_vpos
);
18362 /* If matrix is entirely empty, no unchanged row exists. */
18363 if (MATRIX_ROW_DISPLAYS_TEXT_P (row
))
18365 /* The value of row is the last glyph row in the matrix having a
18366 meaningful buffer position in it. The end position of row
18367 corresponds to window_end_pos. This allows us to translate
18368 buffer positions in the current matrix to current buffer
18369 positions for characters not in changed text. */
18371 MATRIX_ROW_END_CHARPOS (row
) + w
->window_end_pos
;
18372 ptrdiff_t Z_BYTE_old
=
18373 MATRIX_ROW_END_BYTEPOS (row
) + w
->window_end_bytepos
;
18374 ptrdiff_t last_unchanged_pos
, last_unchanged_pos_old
;
18375 struct glyph_row
*first_text_row
18376 = MATRIX_FIRST_TEXT_ROW (w
->current_matrix
);
18378 *delta
= Z
- Z_old
;
18379 *delta_bytes
= Z_BYTE
- Z_BYTE_old
;
18381 /* Set last_unchanged_pos to the buffer position of the last
18382 character in the buffer that has not been changed. Z is the
18383 index + 1 of the last character in current_buffer, i.e. by
18384 subtracting END_UNCHANGED we get the index of the last
18385 unchanged character, and we have to add BEG to get its buffer
18387 last_unchanged_pos
= Z
- END_UNCHANGED
+ BEG
;
18388 last_unchanged_pos_old
= last_unchanged_pos
- *delta
;
18390 /* Search backward from ROW for a row displaying a line that
18391 starts at a minimum position >= last_unchanged_pos_old. */
18392 for (; row
> first_text_row
; --row
)
18394 /* This used to abort, but it can happen.
18395 It is ok to just stop the search instead here. KFS. */
18396 if (!row
->enabled_p
|| !MATRIX_ROW_DISPLAYS_TEXT_P (row
))
18399 if (MATRIX_ROW_START_CHARPOS (row
) >= last_unchanged_pos_old
)
18404 eassert (!row_found
|| MATRIX_ROW_DISPLAYS_TEXT_P (row_found
));
18410 /* Make sure that glyph rows in the current matrix of window W
18411 reference the same glyph memory as corresponding rows in the
18412 frame's frame matrix. This function is called after scrolling W's
18413 current matrix on a terminal frame in try_window_id and
18414 try_window_reusing_current_matrix. */
18417 sync_frame_with_window_matrix_rows (struct window
*w
)
18419 struct frame
*f
= XFRAME (w
->frame
);
18420 struct glyph_row
*window_row
, *window_row_end
, *frame_row
;
18422 /* Preconditions: W must be a leaf window and full-width. Its frame
18423 must have a frame matrix. */
18424 eassert (BUFFERP (w
->contents
));
18425 eassert (WINDOW_FULL_WIDTH_P (w
));
18426 eassert (!FRAME_WINDOW_P (f
));
18428 /* If W is a full-width window, glyph pointers in W's current matrix
18429 have, by definition, to be the same as glyph pointers in the
18430 corresponding frame matrix. Note that frame matrices have no
18431 marginal areas (see build_frame_matrix). */
18432 window_row
= w
->current_matrix
->rows
;
18433 window_row_end
= window_row
+ w
->current_matrix
->nrows
;
18434 frame_row
= f
->current_matrix
->rows
+ WINDOW_TOP_EDGE_LINE (w
);
18435 while (window_row
< window_row_end
)
18437 struct glyph
*start
= window_row
->glyphs
[LEFT_MARGIN_AREA
];
18438 struct glyph
*end
= window_row
->glyphs
[LAST_AREA
];
18440 frame_row
->glyphs
[LEFT_MARGIN_AREA
] = start
;
18441 frame_row
->glyphs
[TEXT_AREA
] = start
;
18442 frame_row
->glyphs
[RIGHT_MARGIN_AREA
] = end
;
18443 frame_row
->glyphs
[LAST_AREA
] = end
;
18445 /* Disable frame rows whose corresponding window rows have
18446 been disabled in try_window_id. */
18447 if (!window_row
->enabled_p
)
18448 frame_row
->enabled_p
= false;
18450 ++window_row
, ++frame_row
;
18455 /* Find the glyph row in window W containing CHARPOS. Consider all
18456 rows between START and END (not inclusive). END null means search
18457 all rows to the end of the display area of W. Value is the row
18458 containing CHARPOS or null. */
18461 row_containing_pos (struct window
*w
, ptrdiff_t charpos
,
18462 struct glyph_row
*start
, struct glyph_row
*end
, int dy
)
18464 struct glyph_row
*row
= start
;
18465 struct glyph_row
*best_row
= NULL
;
18466 ptrdiff_t mindif
= BUF_ZV (XBUFFER (w
->contents
)) + 1;
18469 /* If we happen to start on a header-line, skip that. */
18470 if (row
->mode_line_p
)
18473 if ((end
&& row
>= end
) || !row
->enabled_p
)
18476 last_y
= window_text_bottom_y (w
) - dy
;
18480 /* Give up if we have gone too far. */
18481 if ((end
&& row
>= end
) || !row
->enabled_p
)
18483 /* This formerly returned if they were equal.
18484 I think that both quantities are of a "last plus one" type;
18485 if so, when they are equal, the row is within the screen. -- rms. */
18486 if (MATRIX_ROW_BOTTOM_Y (row
) > last_y
)
18489 /* If it is in this row, return this row. */
18490 if (! (MATRIX_ROW_END_CHARPOS (row
) < charpos
18491 || (MATRIX_ROW_END_CHARPOS (row
) == charpos
18492 /* The end position of a row equals the start
18493 position of the next row. If CHARPOS is there, we
18494 would rather consider it displayed in the next
18495 line, except when this line ends in ZV. */
18496 && !row_for_charpos_p (row
, charpos
)))
18497 && charpos
>= MATRIX_ROW_START_CHARPOS (row
))
18501 if (NILP (BVAR (XBUFFER (w
->contents
), bidi_display_reordering
))
18502 || (!best_row
&& !row
->continued_p
))
18504 /* In bidi-reordered rows, there could be several rows whose
18505 edges surround CHARPOS, all of these rows belonging to
18506 the same continued line. We need to find the row which
18507 fits CHARPOS the best. */
18508 for (g
= row
->glyphs
[TEXT_AREA
];
18509 g
< row
->glyphs
[TEXT_AREA
] + row
->used
[TEXT_AREA
];
18512 if (!STRINGP (g
->object
))
18514 if (g
->charpos
> 0 && eabs (g
->charpos
- charpos
) < mindif
)
18516 mindif
= eabs (g
->charpos
- charpos
);
18518 /* Exact match always wins. */
18525 else if (best_row
&& !row
->continued_p
)
18532 /* Try to redisplay window W by reusing its existing display. W's
18533 current matrix must be up to date when this function is called,
18534 i.e., window_end_valid must be true.
18538 >= 1 if successful, i.e. display has been updated
18540 1 means the changes were in front of a newline that precedes
18541 the window start, and the whole current matrix was reused
18542 2 means the changes were after the last position displayed
18543 in the window, and the whole current matrix was reused
18544 3 means portions of the current matrix were reused, while
18545 some of the screen lines were redrawn
18546 -1 if redisplay with same window start is known not to succeed
18547 0 if otherwise unsuccessful
18549 The following steps are performed:
18551 1. Find the last row in the current matrix of W that is not
18552 affected by changes at the start of current_buffer. If no such row
18555 2. Find the first row in W's current matrix that is not affected by
18556 changes at the end of current_buffer. Maybe there is no such row.
18558 3. Display lines beginning with the row + 1 found in step 1 to the
18559 row found in step 2 or, if step 2 didn't find a row, to the end of
18562 4. If cursor is not known to appear on the window, give up.
18564 5. If display stopped at the row found in step 2, scroll the
18565 display and current matrix as needed.
18567 6. Maybe display some lines at the end of W, if we must. This can
18568 happen under various circumstances, like a partially visible line
18569 becoming fully visible, or because newly displayed lines are displayed
18570 in smaller font sizes.
18572 7. Update W's window end information. */
18575 try_window_id (struct window
*w
)
18577 struct frame
*f
= XFRAME (w
->frame
);
18578 struct glyph_matrix
*current_matrix
= w
->current_matrix
;
18579 struct glyph_matrix
*desired_matrix
= w
->desired_matrix
;
18580 struct glyph_row
*last_unchanged_at_beg_row
;
18581 struct glyph_row
*first_unchanged_at_end_row
;
18582 struct glyph_row
*row
;
18583 struct glyph_row
*bottom_row
;
18586 ptrdiff_t delta
= 0, delta_bytes
= 0, stop_pos
;
18588 struct text_pos start_pos
;
18590 int first_unchanged_at_end_vpos
= 0;
18591 struct glyph_row
*last_text_row
, *last_text_row_at_end
;
18592 struct text_pos start
;
18593 ptrdiff_t first_changed_charpos
, last_changed_charpos
;
18596 if (inhibit_try_window_id
)
18600 /* This is handy for debugging. */
18602 #define GIVE_UP(X) \
18604 TRACE ((stderr, "try_window_id give up %d\n", (X))); \
18608 #define GIVE_UP(X) return 0
18611 SET_TEXT_POS_FROM_MARKER (start
, w
->start
);
18613 /* Don't use this for mini-windows because these can show
18614 messages and mini-buffers, and we don't handle that here. */
18615 if (MINI_WINDOW_P (w
))
18618 /* This flag is used to prevent redisplay optimizations. */
18619 if (windows_or_buffers_changed
|| f
->cursor_type_changed
)
18622 /* This function's optimizations cannot be used if overlays have
18623 changed in the buffer displayed by the window, so give up if they
18625 if (w
->last_overlay_modified
!= OVERLAY_MODIFF
)
18628 /* Verify that narrowing has not changed.
18629 Also verify that we were not told to prevent redisplay optimizations.
18630 It would be nice to further
18631 reduce the number of cases where this prevents try_window_id. */
18632 if (current_buffer
->clip_changed
18633 || current_buffer
->prevent_redisplay_optimizations_p
)
18636 /* Window must either use window-based redisplay or be full width. */
18637 if (!FRAME_WINDOW_P (f
)
18638 && (!FRAME_LINE_INS_DEL_OK (f
)
18639 || !WINDOW_FULL_WIDTH_P (w
)))
18642 /* Give up if point is known NOT to appear in W. */
18643 if (PT
< CHARPOS (start
))
18646 /* Another way to prevent redisplay optimizations. */
18647 if (w
->last_modified
== 0)
18650 /* Verify that window is not hscrolled. */
18651 if (w
->hscroll
!= 0)
18654 /* Verify that display wasn't paused. */
18655 if (!w
->window_end_valid
)
18658 /* Likewise if highlighting trailing whitespace. */
18659 if (!NILP (Vshow_trailing_whitespace
))
18662 /* Can't use this if overlay arrow position and/or string have
18664 if (overlay_arrows_changed_p (false))
18667 /* When word-wrap is on, adding a space to the first word of a
18668 wrapped line can change the wrap position, altering the line
18669 above it. It might be worthwhile to handle this more
18670 intelligently, but for now just redisplay from scratch. */
18671 if (!NILP (BVAR (XBUFFER (w
->contents
), word_wrap
)))
18674 /* Under bidi reordering, adding or deleting a character in the
18675 beginning of a paragraph, before the first strong directional
18676 character, can change the base direction of the paragraph (unless
18677 the buffer specifies a fixed paragraph direction), which will
18678 require redisplaying the whole paragraph. It might be worthwhile
18679 to find the paragraph limits and widen the range of redisplayed
18680 lines to that, but for now just give up this optimization and
18681 redisplay from scratch. */
18682 if (!NILP (BVAR (XBUFFER (w
->contents
), bidi_display_reordering
))
18683 && NILP (BVAR (XBUFFER (w
->contents
), bidi_paragraph_direction
)))
18686 /* Give up if the buffer has line-spacing set, as Lisp-level changes
18687 to that variable require thorough redisplay. */
18688 if (!NILP (BVAR (XBUFFER (w
->contents
), extra_line_spacing
)))
18691 /* Give up if display-line-numbers is in relative mode, or when the
18692 current line's number needs to be displayed in a distinct face. */
18693 if (EQ (Vdisplay_line_numbers
, Qrelative
)
18694 || EQ (Vdisplay_line_numbers
, Qvisual
)
18695 || (!NILP (Vdisplay_line_numbers
)
18696 && NILP (Finternal_lisp_face_equal_p (Qline_number
,
18697 Qline_number_current_line
,
18701 /* Make sure beg_unchanged and end_unchanged are up to date. Do it
18702 only if buffer has really changed. The reason is that the gap is
18703 initially at Z for freshly visited files. The code below would
18704 set end_unchanged to 0 in that case. */
18705 if (MODIFF
> SAVE_MODIFF
18706 /* This seems to happen sometimes after saving a buffer. */
18707 || BEG_UNCHANGED
+ END_UNCHANGED
> Z_BYTE
)
18709 if (GPT
- BEG
< BEG_UNCHANGED
)
18710 BEG_UNCHANGED
= GPT
- BEG
;
18711 if (Z
- GPT
< END_UNCHANGED
)
18712 END_UNCHANGED
= Z
- GPT
;
18715 /* The position of the first and last character that has been changed. */
18716 first_changed_charpos
= BEG
+ BEG_UNCHANGED
;
18717 last_changed_charpos
= Z
- END_UNCHANGED
;
18719 /* If window starts after a line end, and the last change is in
18720 front of that newline, then changes don't affect the display.
18721 This case happens with stealth-fontification. Note that although
18722 the display is unchanged, glyph positions in the matrix have to
18723 be adjusted, of course. */
18724 row
= MATRIX_ROW (w
->current_matrix
, w
->window_end_vpos
);
18725 if (MATRIX_ROW_DISPLAYS_TEXT_P (row
)
18726 && ((last_changed_charpos
< CHARPOS (start
)
18727 && CHARPOS (start
) == BEGV
)
18728 || (last_changed_charpos
< CHARPOS (start
) - 1
18729 && FETCH_BYTE (BYTEPOS (start
) - 1) == '\n')))
18731 ptrdiff_t Z_old
, Z_delta
, Z_BYTE_old
, Z_delta_bytes
;
18732 struct glyph_row
*r0
;
18734 /* Compute how many chars/bytes have been added to or removed
18735 from the buffer. */
18736 Z_old
= MATRIX_ROW_END_CHARPOS (row
) + w
->window_end_pos
;
18737 Z_BYTE_old
= MATRIX_ROW_END_BYTEPOS (row
) + w
->window_end_bytepos
;
18738 Z_delta
= Z
- Z_old
;
18739 Z_delta_bytes
= Z_BYTE
- Z_BYTE_old
;
18741 /* Give up if PT is not in the window. Note that it already has
18742 been checked at the start of try_window_id that PT is not in
18743 front of the window start. */
18744 if (PT
>= MATRIX_ROW_END_CHARPOS (row
) + Z_delta
)
18747 /* If window start is unchanged, we can reuse the whole matrix
18748 as is, after adjusting glyph positions. No need to compute
18749 the window end again, since its offset from Z hasn't changed. */
18750 r0
= MATRIX_FIRST_TEXT_ROW (current_matrix
);
18751 if (CHARPOS (start
) == MATRIX_ROW_START_CHARPOS (r0
) + Z_delta
18752 && BYTEPOS (start
) == MATRIX_ROW_START_BYTEPOS (r0
) + Z_delta_bytes
18753 /* PT must not be in a partially visible line. */
18754 && !(PT
>= MATRIX_ROW_START_CHARPOS (row
) + Z_delta
18755 && MATRIX_ROW_BOTTOM_Y (row
) > window_text_bottom_y (w
)))
18757 /* Adjust positions in the glyph matrix. */
18758 if (Z_delta
|| Z_delta_bytes
)
18760 struct glyph_row
*r1
18761 = MATRIX_BOTTOM_TEXT_ROW (current_matrix
, w
);
18762 increment_matrix_positions (w
->current_matrix
,
18763 MATRIX_ROW_VPOS (r0
, current_matrix
),
18764 MATRIX_ROW_VPOS (r1
, current_matrix
),
18765 Z_delta
, Z_delta_bytes
);
18768 /* Set the cursor. */
18769 row
= row_containing_pos (w
, PT
, r0
, NULL
, 0);
18771 set_cursor_from_row (w
, row
, current_matrix
, 0, 0, 0, 0);
18776 /* Handle the case that changes are all below what is displayed in
18777 the window, and that PT is in the window. This shortcut cannot
18778 be taken if ZV is visible in the window, and text has been added
18779 there that is visible in the window. */
18780 if (first_changed_charpos
>= MATRIX_ROW_END_CHARPOS (row
)
18781 /* ZV is not visible in the window, or there are no
18782 changes at ZV, actually. */
18783 && (current_matrix
->zv
> MATRIX_ROW_END_CHARPOS (row
)
18784 || first_changed_charpos
== last_changed_charpos
))
18786 struct glyph_row
*r0
;
18788 /* Give up if PT is not in the window. Note that it already has
18789 been checked at the start of try_window_id that PT is not in
18790 front of the window start. */
18791 if (PT
>= MATRIX_ROW_END_CHARPOS (row
))
18794 /* If window start is unchanged, we can reuse the whole matrix
18795 as is, without changing glyph positions since no text has
18796 been added/removed in front of the window end. */
18797 r0
= MATRIX_FIRST_TEXT_ROW (current_matrix
);
18798 if (TEXT_POS_EQUAL_P (start
, r0
->minpos
)
18799 /* PT must not be in a partially visible line. */
18800 && !(PT
>= MATRIX_ROW_START_CHARPOS (row
)
18801 && MATRIX_ROW_BOTTOM_Y (row
) > window_text_bottom_y (w
)))
18803 /* We have to compute the window end anew since text
18804 could have been added/removed after it. */
18805 w
->window_end_pos
= Z
- MATRIX_ROW_END_CHARPOS (row
);
18806 w
->window_end_bytepos
= Z_BYTE
- MATRIX_ROW_END_BYTEPOS (row
);
18808 /* Set the cursor. */
18809 row
= row_containing_pos (w
, PT
, r0
, NULL
, 0);
18811 set_cursor_from_row (w
, row
, current_matrix
, 0, 0, 0, 0);
18816 /* Give up if window start is in the changed area.
18818 The condition used to read
18820 (BEG_UNCHANGED + END_UNCHANGED != Z - BEG && ...)
18822 but why that was tested escapes me at the moment. */
18823 if (CHARPOS (start
) >= first_changed_charpos
18824 && CHARPOS (start
) <= last_changed_charpos
)
18827 /* Check that window start agrees with the start of the first glyph
18828 row in its current matrix. Check this after we know the window
18829 start is not in changed text, otherwise positions would not be
18831 row
= MATRIX_FIRST_TEXT_ROW (current_matrix
);
18832 if (!TEXT_POS_EQUAL_P (start
, row
->minpos
))
18835 /* Give up if the window ends in strings. Overlay strings
18836 at the end are difficult to handle, so don't try. */
18837 row
= MATRIX_ROW (current_matrix
, w
->window_end_vpos
);
18838 if (MATRIX_ROW_START_CHARPOS (row
) == MATRIX_ROW_END_CHARPOS (row
))
18841 /* Compute the position at which we have to start displaying new
18842 lines. Some of the lines at the top of the window might be
18843 reusable because they are not displaying changed text. Find the
18844 last row in W's current matrix not affected by changes at the
18845 start of current_buffer. Value is null if changes start in the
18846 first line of window. */
18847 last_unchanged_at_beg_row
= find_last_unchanged_at_beg_row (w
);
18848 if (last_unchanged_at_beg_row
)
18850 /* Avoid starting to display in the middle of a character, a TAB
18851 for instance. This is easier than to set up the iterator
18852 exactly, and it's not a frequent case, so the additional
18853 effort wouldn't really pay off. */
18854 while ((MATRIX_ROW_ENDS_IN_MIDDLE_OF_CHAR_P (last_unchanged_at_beg_row
)
18855 || last_unchanged_at_beg_row
->ends_in_newline_from_string_p
)
18856 && last_unchanged_at_beg_row
> w
->current_matrix
->rows
)
18857 --last_unchanged_at_beg_row
;
18859 if (MATRIX_ROW_ENDS_IN_MIDDLE_OF_CHAR_P (last_unchanged_at_beg_row
))
18862 if (! init_to_row_end (&it
, w
, last_unchanged_at_beg_row
))
18864 start_pos
= it
.current
.pos
;
18866 /* Start displaying new lines in the desired matrix at the same
18867 vpos we would use in the current matrix, i.e. below
18868 last_unchanged_at_beg_row. */
18869 it
.vpos
= 1 + MATRIX_ROW_VPOS (last_unchanged_at_beg_row
,
18871 it
.glyph_row
= MATRIX_ROW (desired_matrix
, it
.vpos
);
18872 it
.current_y
= MATRIX_ROW_BOTTOM_Y (last_unchanged_at_beg_row
);
18874 eassert (it
.hpos
== 0 && it
.current_x
== 0);
18878 /* There are no reusable lines at the start of the window.
18879 Start displaying in the first text line. */
18880 start_display (&it
, w
, start
);
18881 it
.vpos
= it
.first_vpos
;
18882 start_pos
= it
.current
.pos
;
18885 /* Find the first row that is not affected by changes at the end of
18886 the buffer. Value will be null if there is no unchanged row, in
18887 which case we must redisplay to the end of the window. delta
18888 will be set to the value by which buffer positions beginning with
18889 first_unchanged_at_end_row have to be adjusted due to text
18891 first_unchanged_at_end_row
18892 = find_first_unchanged_at_end_row (w
, &delta
, &delta_bytes
);
18893 IF_DEBUG (debug_delta
= delta
);
18894 IF_DEBUG (debug_delta_bytes
= delta_bytes
);
18896 /* Set stop_pos to the buffer position up to which we will have to
18897 display new lines. If first_unchanged_at_end_row != NULL, this
18898 is the buffer position of the start of the line displayed in that
18899 row. For first_unchanged_at_end_row == NULL, use 0 to indicate
18900 that we don't stop at a buffer position. */
18902 if (first_unchanged_at_end_row
)
18904 eassert (last_unchanged_at_beg_row
== NULL
18905 || first_unchanged_at_end_row
>= last_unchanged_at_beg_row
);
18907 /* If this is a continuation line, move forward to the next one
18908 that isn't. Changes in lines above affect this line.
18909 Caution: this may move first_unchanged_at_end_row to a row
18910 not displaying text. */
18911 while (MATRIX_ROW_CONTINUATION_LINE_P (first_unchanged_at_end_row
)
18912 && MATRIX_ROW_DISPLAYS_TEXT_P (first_unchanged_at_end_row
)
18913 && (MATRIX_ROW_BOTTOM_Y (first_unchanged_at_end_row
)
18914 < it
.last_visible_y
))
18915 ++first_unchanged_at_end_row
;
18917 if (!MATRIX_ROW_DISPLAYS_TEXT_P (first_unchanged_at_end_row
)
18918 || (MATRIX_ROW_BOTTOM_Y (first_unchanged_at_end_row
)
18919 >= it
.last_visible_y
))
18920 first_unchanged_at_end_row
= NULL
;
18923 stop_pos
= (MATRIX_ROW_START_CHARPOS (first_unchanged_at_end_row
)
18925 first_unchanged_at_end_vpos
18926 = MATRIX_ROW_VPOS (first_unchanged_at_end_row
, current_matrix
);
18927 eassert (stop_pos
>= Z
- END_UNCHANGED
);
18930 else if (last_unchanged_at_beg_row
== NULL
)
18936 /* Either there is no unchanged row at the end, or the one we have
18937 now displays text. This is a necessary condition for the window
18938 end pos calculation at the end of this function. */
18939 eassert (first_unchanged_at_end_row
== NULL
18940 || MATRIX_ROW_DISPLAYS_TEXT_P (first_unchanged_at_end_row
));
18942 debug_last_unchanged_at_beg_vpos
18943 = (last_unchanged_at_beg_row
18944 ? MATRIX_ROW_VPOS (last_unchanged_at_beg_row
, current_matrix
)
18946 debug_first_unchanged_at_end_vpos
= first_unchanged_at_end_vpos
;
18948 #endif /* GLYPH_DEBUG */
18951 /* Display new lines. Set last_text_row to the last new line
18952 displayed which has text on it, i.e. might end up as being the
18953 line where the window_end_vpos is. */
18954 w
->cursor
.vpos
= -1;
18955 last_text_row
= NULL
;
18956 overlay_arrow_seen
= false;
18957 if (it
.current_y
< it
.last_visible_y
18958 && !f
->fonts_changed
18959 && (first_unchanged_at_end_row
== NULL
18960 || IT_CHARPOS (it
) < stop_pos
))
18961 it
.glyph_row
->reversed_p
= false;
18962 while (it
.current_y
< it
.last_visible_y
18963 && !f
->fonts_changed
18964 && (first_unchanged_at_end_row
== NULL
18965 || IT_CHARPOS (it
) < stop_pos
))
18967 if (display_line (&it
, -1))
18968 last_text_row
= it
.glyph_row
- 1;
18971 if (f
->fonts_changed
)
18974 /* The redisplay iterations in display_line above could have
18975 triggered font-lock, which could have done something that
18976 invalidates IT->w window's end-point information, on which we
18977 rely below. E.g., one package, which will remain unnamed, used
18978 to install a font-lock-fontify-region-function that called
18979 bury-buffer, whose side effect is to switch the buffer displayed
18980 by IT->w, and that predictably resets IT->w's window_end_valid
18981 flag, which we already tested at the entry to this function.
18982 Amply punish such packages/modes by giving up on this
18983 optimization in those cases. */
18984 if (!w
->window_end_valid
)
18986 clear_glyph_matrix (w
->desired_matrix
);
18990 /* Compute differences in buffer positions, y-positions etc. for
18991 lines reused at the bottom of the window. Compute what we can
18993 if (first_unchanged_at_end_row
18994 /* No lines reused because we displayed everything up to the
18995 bottom of the window. */
18996 && it
.current_y
< it
.last_visible_y
)
18999 - MATRIX_ROW_VPOS (first_unchanged_at_end_row
,
19001 dy
= it
.current_y
- first_unchanged_at_end_row
->y
;
19002 run
.current_y
= first_unchanged_at_end_row
->y
;
19003 run
.desired_y
= run
.current_y
+ dy
;
19004 run
.height
= it
.last_visible_y
- max (run
.current_y
, run
.desired_y
);
19008 delta
= delta_bytes
= dvpos
= dy
19009 = run
.current_y
= run
.desired_y
= run
.height
= 0;
19010 first_unchanged_at_end_row
= NULL
;
19012 IF_DEBUG ((debug_dvpos
= dvpos
, debug_dy
= dy
));
19015 /* Find the cursor if not already found. We have to decide whether
19016 PT will appear on this window (it sometimes doesn't, but this is
19017 not a very frequent case.) This decision has to be made before
19018 the current matrix is altered. A value of cursor.vpos < 0 means
19019 that PT is either in one of the lines beginning at
19020 first_unchanged_at_end_row or below the window. Don't care for
19021 lines that might be displayed later at the window end; as
19022 mentioned, this is not a frequent case. */
19023 if (w
->cursor
.vpos
< 0)
19025 /* Cursor in unchanged rows at the top? */
19026 if (PT
< CHARPOS (start_pos
)
19027 && last_unchanged_at_beg_row
)
19029 row
= row_containing_pos (w
, PT
,
19030 MATRIX_FIRST_TEXT_ROW (w
->current_matrix
),
19031 last_unchanged_at_beg_row
+ 1, 0);
19033 set_cursor_from_row (w
, row
, w
->current_matrix
, 0, 0, 0, 0);
19036 /* Start from first_unchanged_at_end_row looking for PT. */
19037 else if (first_unchanged_at_end_row
)
19039 row
= row_containing_pos (w
, PT
- delta
,
19040 first_unchanged_at_end_row
, NULL
, 0);
19042 set_cursor_from_row (w
, row
, w
->current_matrix
, delta
,
19043 delta_bytes
, dy
, dvpos
);
19046 /* Give up if cursor was not found. */
19047 if (w
->cursor
.vpos
< 0)
19049 clear_glyph_matrix (w
->desired_matrix
);
19054 /* Don't let the cursor end in the scroll margins. */
19056 int this_scroll_margin
= window_scroll_margin (w
, MARGIN_IN_PIXELS
);
19057 int cursor_height
= MATRIX_ROW (w
->desired_matrix
, w
->cursor
.vpos
)->height
;
19059 if ((w
->cursor
.y
< this_scroll_margin
19060 && CHARPOS (start
) > BEGV
)
19061 /* Old redisplay didn't take scroll margin into account at the bottom,
19062 but then global-hl-line-mode doesn't scroll. KFS 2004-06-14 */
19063 || (w
->cursor
.y
+ (make_cursor_line_fully_visible_p
19064 ? cursor_height
+ this_scroll_margin
19065 : 1)) > it
.last_visible_y
)
19067 w
->cursor
.vpos
= -1;
19068 clear_glyph_matrix (w
->desired_matrix
);
19073 /* Scroll the display. Do it before changing the current matrix so
19074 that xterm.c doesn't get confused about where the cursor glyph is
19076 if (dy
&& run
.height
)
19080 if (FRAME_WINDOW_P (f
))
19082 FRAME_RIF (f
)->update_window_begin_hook (w
);
19083 FRAME_RIF (f
)->clear_window_mouse_face (w
);
19084 FRAME_RIF (f
)->scroll_run_hook (w
, &run
);
19085 FRAME_RIF (f
)->update_window_end_hook (w
, false, false);
19089 /* Terminal frame. In this case, dvpos gives the number of
19090 lines to scroll by; dvpos < 0 means scroll up. */
19092 = MATRIX_ROW_VPOS (first_unchanged_at_end_row
, w
->current_matrix
);
19093 int from
= WINDOW_TOP_EDGE_LINE (w
) + from_vpos
;
19094 int end
= (WINDOW_TOP_EDGE_LINE (w
)
19095 + window_wants_header_line (w
)
19096 + window_internal_height (w
));
19098 #if defined (HAVE_GPM) || defined (MSDOS)
19099 x_clear_window_mouse_face (w
);
19101 /* Perform the operation on the screen. */
19104 /* Scroll last_unchanged_at_beg_row to the end of the
19105 window down dvpos lines. */
19106 set_terminal_window (f
, end
);
19108 /* On dumb terminals delete dvpos lines at the end
19109 before inserting dvpos empty lines. */
19110 if (!FRAME_SCROLL_REGION_OK (f
))
19111 ins_del_lines (f
, end
- dvpos
, -dvpos
);
19113 /* Insert dvpos empty lines in front of
19114 last_unchanged_at_beg_row. */
19115 ins_del_lines (f
, from
, dvpos
);
19117 else if (dvpos
< 0)
19119 /* Scroll up last_unchanged_at_beg_vpos to the end of
19120 the window to last_unchanged_at_beg_vpos - |dvpos|. */
19121 set_terminal_window (f
, end
);
19123 /* Delete dvpos lines in front of
19124 last_unchanged_at_beg_vpos. ins_del_lines will set
19125 the cursor to the given vpos and emit |dvpos| delete
19127 ins_del_lines (f
, from
+ dvpos
, dvpos
);
19129 /* On a dumb terminal insert dvpos empty lines at the
19131 if (!FRAME_SCROLL_REGION_OK (f
))
19132 ins_del_lines (f
, end
+ dvpos
, -dvpos
);
19135 set_terminal_window (f
, 0);
19141 /* Shift reused rows of the current matrix to the right position.
19142 BOTTOM_ROW is the last + 1 row in the current matrix reserved for
19144 bottom_row
= MATRIX_BOTTOM_TEXT_ROW (current_matrix
, w
);
19145 bottom_vpos
= MATRIX_ROW_VPOS (bottom_row
, current_matrix
);
19148 rotate_matrix (current_matrix
, first_unchanged_at_end_vpos
+ dvpos
,
19149 bottom_vpos
, dvpos
);
19150 clear_glyph_matrix_rows (current_matrix
, bottom_vpos
+ dvpos
,
19153 else if (dvpos
> 0)
19155 rotate_matrix (current_matrix
, first_unchanged_at_end_vpos
,
19156 bottom_vpos
, dvpos
);
19157 clear_glyph_matrix_rows (current_matrix
, first_unchanged_at_end_vpos
,
19158 first_unchanged_at_end_vpos
+ dvpos
);
19161 /* For frame-based redisplay, make sure that current frame and window
19162 matrix are in sync with respect to glyph memory. */
19163 if (!FRAME_WINDOW_P (f
))
19164 sync_frame_with_window_matrix_rows (w
);
19166 /* Adjust buffer positions in reused rows. */
19167 if (delta
|| delta_bytes
)
19168 increment_matrix_positions (current_matrix
,
19169 first_unchanged_at_end_vpos
+ dvpos
,
19170 bottom_vpos
, delta
, delta_bytes
);
19172 /* Adjust Y positions. */
19174 shift_glyph_matrix (w
, current_matrix
,
19175 first_unchanged_at_end_vpos
+ dvpos
,
19178 if (first_unchanged_at_end_row
)
19180 first_unchanged_at_end_row
+= dvpos
;
19181 if (first_unchanged_at_end_row
->y
>= it
.last_visible_y
19182 || !MATRIX_ROW_DISPLAYS_TEXT_P (first_unchanged_at_end_row
))
19183 first_unchanged_at_end_row
= NULL
;
19186 /* If scrolling up, there may be some lines to display at the end of
19188 last_text_row_at_end
= NULL
;
19191 /* Scrolling up can leave for example a partially visible line
19192 at the end of the window to be redisplayed. */
19193 /* Set last_row to the glyph row in the current matrix where the
19194 window end line is found. It has been moved up or down in
19195 the matrix by dvpos. */
19196 int last_vpos
= w
->window_end_vpos
+ dvpos
;
19197 struct glyph_row
*last_row
= MATRIX_ROW (current_matrix
, last_vpos
);
19199 /* If last_row is the window end line, it should display text. */
19200 eassert (MATRIX_ROW_DISPLAYS_TEXT_P (last_row
));
19202 /* If window end line was partially visible before, begin
19203 displaying at that line. Otherwise begin displaying with the
19204 line following it. */
19205 if (MATRIX_ROW_BOTTOM_Y (last_row
) - dy
>= it
.last_visible_y
)
19207 init_to_row_start (&it
, w
, last_row
);
19208 it
.vpos
= last_vpos
;
19209 it
.current_y
= last_row
->y
;
19213 init_to_row_end (&it
, w
, last_row
);
19214 it
.vpos
= 1 + last_vpos
;
19215 it
.current_y
= MATRIX_ROW_BOTTOM_Y (last_row
);
19219 /* We may start in a continuation line. If so, we have to
19220 get the right continuation_lines_width and current_x. */
19221 it
.continuation_lines_width
= last_row
->continuation_lines_width
;
19222 it
.hpos
= it
.current_x
= 0;
19224 /* Display the rest of the lines at the window end. */
19225 it
.glyph_row
= MATRIX_ROW (desired_matrix
, it
.vpos
);
19226 while (it
.current_y
< it
.last_visible_y
&& !f
->fonts_changed
)
19228 /* Is it always sure that the display agrees with lines in
19229 the current matrix? I don't think so, so we mark rows
19230 displayed invalid in the current matrix by setting their
19231 enabled_p flag to false. */
19232 SET_MATRIX_ROW_ENABLED_P (w
->current_matrix
, it
.vpos
, false);
19233 if (display_line (&it
, w
->cursor
.vpos
))
19234 last_text_row_at_end
= it
.glyph_row
- 1;
19238 /* Update window_end_pos and window_end_vpos. */
19239 if (first_unchanged_at_end_row
&& !last_text_row_at_end
)
19241 /* Window end line if one of the preserved rows from the current
19242 matrix. Set row to the last row displaying text in current
19243 matrix starting at first_unchanged_at_end_row, after
19245 eassert (MATRIX_ROW_DISPLAYS_TEXT_P (first_unchanged_at_end_row
));
19246 row
= find_last_row_displaying_text (w
->current_matrix
, &it
,
19247 first_unchanged_at_end_row
);
19248 eassume (row
&& MATRIX_ROW_DISPLAYS_TEXT_P (row
));
19249 adjust_window_ends (w
, row
, true);
19250 eassert (w
->window_end_bytepos
>= 0);
19251 IF_DEBUG (debug_method_add (w
, "A"));
19253 else if (last_text_row_at_end
)
19255 adjust_window_ends (w
, last_text_row_at_end
, false);
19256 eassert (w
->window_end_bytepos
>= 0);
19257 IF_DEBUG (debug_method_add (w
, "B"));
19259 else if (last_text_row
)
19261 /* We have displayed either to the end of the window or at the
19262 end of the window, i.e. the last row with text is to be found
19263 in the desired matrix. */
19264 adjust_window_ends (w
, last_text_row
, false);
19265 eassert (w
->window_end_bytepos
>= 0);
19267 else if (first_unchanged_at_end_row
== NULL
19268 && last_text_row
== NULL
19269 && last_text_row_at_end
== NULL
)
19271 /* Displayed to end of window, but no line containing text was
19272 displayed. Lines were deleted at the end of the window. */
19273 bool first_vpos
= window_wants_header_line (w
);
19274 int vpos
= w
->window_end_vpos
;
19275 struct glyph_row
*current_row
= current_matrix
->rows
+ vpos
;
19276 struct glyph_row
*desired_row
= desired_matrix
->rows
+ vpos
;
19278 for (row
= NULL
; !row
; --vpos
, --current_row
, --desired_row
)
19280 eassert (first_vpos
<= vpos
);
19281 if (desired_row
->enabled_p
)
19283 if (MATRIX_ROW_DISPLAYS_TEXT_P (desired_row
))
19286 else if (MATRIX_ROW_DISPLAYS_TEXT_P (current_row
))
19290 w
->window_end_vpos
= vpos
+ 1;
19291 w
->window_end_pos
= Z
- MATRIX_ROW_END_CHARPOS (row
);
19292 w
->window_end_bytepos
= Z_BYTE
- MATRIX_ROW_END_BYTEPOS (row
);
19293 eassert (w
->window_end_bytepos
>= 0);
19294 IF_DEBUG (debug_method_add (w
, "C"));
19299 IF_DEBUG ((debug_end_pos
= w
->window_end_pos
,
19300 debug_end_vpos
= w
->window_end_vpos
));
19302 /* Record that display has not been completed. */
19303 w
->window_end_valid
= false;
19304 w
->desired_matrix
->no_scrolling_p
= true;
19312 /***********************************************************************
19313 More debugging support
19314 ***********************************************************************/
19318 void dump_glyph_row (struct glyph_row
*, int, int) EXTERNALLY_VISIBLE
;
19319 void dump_glyph_matrix (struct glyph_matrix
*, int) EXTERNALLY_VISIBLE
;
19320 void dump_glyph (struct glyph_row
*, struct glyph
*, int) EXTERNALLY_VISIBLE
;
19323 /* Dump the contents of glyph matrix MATRIX on stderr.
19325 GLYPHS 0 means don't show glyph contents.
19326 GLYPHS 1 means show glyphs in short form
19327 GLYPHS > 1 means show glyphs in long form. */
19330 dump_glyph_matrix (struct glyph_matrix
*matrix
, int glyphs
)
19333 for (i
= 0; i
< matrix
->nrows
; ++i
)
19334 dump_glyph_row (MATRIX_ROW (matrix
, i
), i
, glyphs
);
19338 /* Dump contents of glyph GLYPH to stderr. ROW and AREA are
19339 the glyph row and area where the glyph comes from. */
19342 dump_glyph (struct glyph_row
*row
, struct glyph
*glyph
, int area
)
19344 if (glyph
->type
== CHAR_GLYPH
19345 || glyph
->type
== GLYPHLESS_GLYPH
)
19348 " %5"pD
"d %c %9"pD
"d %c %3d 0x%06x %c %4d %1.1d%1.1d\n",
19349 glyph
- row
->glyphs
[TEXT_AREA
],
19350 (glyph
->type
== CHAR_GLYPH
19354 (BUFFERP (glyph
->object
)
19356 : (STRINGP (glyph
->object
)
19358 : (NILP (glyph
->object
)
19361 glyph
->pixel_width
,
19363 (glyph
->u
.ch
< 0x80 && glyph
->u
.ch
>= ' '
19364 ? (int) glyph
->u
.ch
19367 glyph
->left_box_line_p
,
19368 glyph
->right_box_line_p
);
19370 else if (glyph
->type
== STRETCH_GLYPH
)
19373 " %5"pD
"d %c %9"pD
"d %c %3d 0x%06x %c %4d %1.1d%1.1d\n",
19374 glyph
- row
->glyphs
[TEXT_AREA
],
19377 (BUFFERP (glyph
->object
)
19379 : (STRINGP (glyph
->object
)
19381 : (NILP (glyph
->object
)
19384 glyph
->pixel_width
,
19388 glyph
->left_box_line_p
,
19389 glyph
->right_box_line_p
);
19391 else if (glyph
->type
== IMAGE_GLYPH
)
19394 " %5"pD
"d %c %9"pD
"d %c %3d 0x%06x %c %4d %1.1d%1.1d\n",
19395 glyph
- row
->glyphs
[TEXT_AREA
],
19398 (BUFFERP (glyph
->object
)
19400 : (STRINGP (glyph
->object
)
19402 : (NILP (glyph
->object
)
19405 glyph
->pixel_width
,
19406 (unsigned int) glyph
->u
.img_id
,
19409 glyph
->left_box_line_p
,
19410 glyph
->right_box_line_p
);
19412 else if (glyph
->type
== COMPOSITE_GLYPH
)
19415 " %5"pD
"d %c %9"pD
"d %c %3d 0x%06x",
19416 glyph
- row
->glyphs
[TEXT_AREA
],
19419 (BUFFERP (glyph
->object
)
19421 : (STRINGP (glyph
->object
)
19423 : (NILP (glyph
->object
)
19426 glyph
->pixel_width
,
19427 (unsigned int) glyph
->u
.cmp
.id
);
19428 if (glyph
->u
.cmp
.automatic
)
19431 glyph
->slice
.cmp
.from
, glyph
->slice
.cmp
.to
);
19432 fprintf (stderr
, " . %4d %1.1d%1.1d\n",
19434 glyph
->left_box_line_p
,
19435 glyph
->right_box_line_p
);
19437 else if (glyph
->type
== XWIDGET_GLYPH
)
19439 #ifndef HAVE_XWIDGETS
19443 " %5d %4c %6d %c %3d 0x%05x %c %4d %1.1d%1.1d\n",
19444 glyph
- row
->glyphs
[TEXT_AREA
],
19447 (BUFFERP (glyph
->object
)
19449 : (STRINGP (glyph
->object
)
19452 glyph
->pixel_width
,
19456 glyph
->left_box_line_p
,
19457 glyph
->right_box_line_p
);
19463 /* Dump the contents of glyph row at VPOS in MATRIX to stderr.
19464 GLYPHS 0 means don't show glyph contents.
19465 GLYPHS 1 means show glyphs in short form
19466 GLYPHS > 1 means show glyphs in long form. */
19469 dump_glyph_row (struct glyph_row
*row
, int vpos
, int glyphs
)
19473 fprintf (stderr
, "Row Start End Used oE><\\CTZFesm X Y W H V A P\n");
19474 fprintf (stderr
, "==============================================================================\n");
19476 fprintf (stderr
, "%3d %9"pD
"d %9"pD
"d %4d %1.1d%1.1d%1.1d%1.1d\
19477 %1.1d%1.1d%1.1d%1.1d%1.1d%1.1d%1.1d%1.1d %4d %4d %4d %4d %4d %4d %4d\n",
19479 MATRIX_ROW_START_CHARPOS (row
),
19480 MATRIX_ROW_END_CHARPOS (row
),
19481 row
->used
[TEXT_AREA
],
19482 row
->contains_overlapping_glyphs_p
,
19484 row
->truncated_on_left_p
,
19485 row
->truncated_on_right_p
,
19487 MATRIX_ROW_CONTINUATION_LINE_P (row
),
19488 MATRIX_ROW_DISPLAYS_TEXT_P (row
),
19491 row
->ends_in_middle_of_char_p
,
19492 row
->starts_in_middle_of_char_p
,
19498 row
->visible_height
,
19501 /* The next 3 lines should align to "Start" in the header. */
19502 fprintf (stderr
, " %9"pD
"d %9"pD
"d\t%5d\n", row
->start
.overlay_string_index
,
19503 row
->end
.overlay_string_index
,
19504 row
->continuation_lines_width
);
19505 fprintf (stderr
, " %9"pD
"d %9"pD
"d\n",
19506 CHARPOS (row
->start
.string_pos
),
19507 CHARPOS (row
->end
.string_pos
));
19508 fprintf (stderr
, " %9d %9d\n", row
->start
.dpvec_index
,
19509 row
->end
.dpvec_index
);
19516 for (area
= LEFT_MARGIN_AREA
; area
< LAST_AREA
; ++area
)
19518 struct glyph
*glyph
= row
->glyphs
[area
];
19519 struct glyph
*glyph_end
= glyph
+ row
->used
[area
];
19521 /* Glyph for a line end in text. */
19522 if (area
== TEXT_AREA
&& glyph
== glyph_end
&& glyph
->charpos
> 0)
19525 if (glyph
< glyph_end
)
19526 fprintf (stderr
, " Glyph# Type Pos O W Code C Face LR\n");
19528 for (; glyph
< glyph_end
; ++glyph
)
19529 dump_glyph (row
, glyph
, area
);
19532 else if (glyphs
== 1)
19535 char s
[SHRT_MAX
+ 4];
19537 for (area
= LEFT_MARGIN_AREA
; area
< LAST_AREA
; ++area
)
19541 for (i
= 0; i
< row
->used
[area
]; ++i
)
19543 struct glyph
*glyph
= row
->glyphs
[area
] + i
;
19544 if (i
== row
->used
[area
] - 1
19545 && area
== TEXT_AREA
19546 && NILP (glyph
->object
)
19547 && glyph
->type
== CHAR_GLYPH
19548 && glyph
->u
.ch
== ' ')
19550 strcpy (&s
[i
], "[\\n]");
19553 else if (glyph
->type
== CHAR_GLYPH
19554 && glyph
->u
.ch
< 0x80
19555 && glyph
->u
.ch
>= ' ')
19556 s
[i
] = glyph
->u
.ch
;
19562 fprintf (stderr
, "%3d: (%d) '%s'\n", vpos
, row
->enabled_p
, s
);
19568 DEFUN ("dump-glyph-matrix", Fdump_glyph_matrix
,
19569 Sdump_glyph_matrix
, 0, 1, "p",
19570 doc
: /* Dump the current matrix of the selected window to stderr.
19571 Shows contents of glyph row structures. With non-nil
19572 parameter GLYPHS, dump glyphs as well. If GLYPHS is 1 show
19573 glyphs in short form, otherwise show glyphs in long form.
19575 Interactively, no argument means show glyphs in short form;
19576 with numeric argument, its value is passed as the GLYPHS flag. */)
19577 (Lisp_Object glyphs
)
19579 struct window
*w
= XWINDOW (selected_window
);
19580 struct buffer
*buffer
= XBUFFER (w
->contents
);
19582 fprintf (stderr
, "PT = %"pD
"d, BEGV = %"pD
"d. ZV = %"pD
"d\n",
19583 BUF_PT (buffer
), BUF_BEGV (buffer
), BUF_ZV (buffer
));
19584 fprintf (stderr
, "Cursor x = %d, y = %d, hpos = %d, vpos = %d\n",
19585 w
->cursor
.x
, w
->cursor
.y
, w
->cursor
.hpos
, w
->cursor
.vpos
);
19586 fprintf (stderr
, "=============================================\n");
19587 dump_glyph_matrix (w
->current_matrix
,
19588 TYPE_RANGED_INTEGERP (int, glyphs
) ? XINT (glyphs
) : 0);
19593 DEFUN ("dump-frame-glyph-matrix", Fdump_frame_glyph_matrix
,
19594 Sdump_frame_glyph_matrix
, 0, 0, "", doc
: /* Dump the current glyph matrix of the selected frame to stderr.
19595 Only text-mode frames have frame glyph matrices. */)
19598 struct frame
*f
= XFRAME (selected_frame
);
19600 if (f
->current_matrix
)
19601 dump_glyph_matrix (f
->current_matrix
, 1);
19603 fprintf (stderr
, "*** This frame doesn't have a frame glyph matrix ***\n");
19608 DEFUN ("dump-glyph-row", Fdump_glyph_row
, Sdump_glyph_row
, 1, 2, "P",
19609 doc
: /* Dump glyph row ROW to stderr.
19610 Interactively, ROW is the prefix numeric argument and defaults to
19611 the row which displays point.
19612 Optional argument GLYPHS 0 means don't dump glyphs.
19613 GLYPHS 1 means dump glyphs in short form.
19614 GLYPHS > 1 or omitted means dump glyphs in long form. */)
19615 (Lisp_Object row
, Lisp_Object glyphs
)
19617 struct glyph_matrix
*matrix
;
19622 int d1
, d2
, d3
, d4
, d5
, ypos
;
19623 bool visible_p
= pos_visible_p (XWINDOW (selected_window
), PT
,
19624 &d1
, &d2
, &d3
, &d4
, &d5
, &ypos
);
19632 CHECK_NUMBER (row
);
19635 matrix
= XWINDOW (selected_window
)->current_matrix
;
19636 if (vpos
>= 0 && vpos
< matrix
->nrows
)
19637 dump_glyph_row (MATRIX_ROW (matrix
, vpos
),
19639 TYPE_RANGED_INTEGERP (int, glyphs
) ? XINT (glyphs
) : 2);
19644 DEFUN ("dump-tool-bar-row", Fdump_tool_bar_row
, Sdump_tool_bar_row
, 1, 2, "P",
19645 doc
: /* Dump glyph row ROW of the tool-bar of the current frame to stderr.
19646 Interactively, ROW is the prefix numeric argument and defaults to zero.
19647 GLYPHS 0 means don't dump glyphs.
19648 GLYPHS 1 means dump glyphs in short form.
19649 GLYPHS > 1 or omitted means dump glyphs in long form.
19651 If there's no tool-bar, or if the tool-bar is not drawn by Emacs,
19653 (Lisp_Object row
, Lisp_Object glyphs
)
19655 #if defined (HAVE_WINDOW_SYSTEM) && ! defined (USE_GTK) && ! defined (HAVE_NS)
19656 struct frame
*sf
= SELECTED_FRAME ();
19657 struct glyph_matrix
*m
= XWINDOW (sf
->tool_bar_window
)->current_matrix
;
19664 CHECK_NUMBER (row
);
19667 if (vpos
>= 0 && vpos
< m
->nrows
)
19668 dump_glyph_row (MATRIX_ROW (m
, vpos
), vpos
,
19669 TYPE_RANGED_INTEGERP (int, glyphs
) ? XINT (glyphs
) : 2);
19675 DEFUN ("trace-redisplay", Ftrace_redisplay
, Strace_redisplay
, 0, 1, "P",
19676 doc
: /* Toggle tracing of redisplay.
19677 With ARG, turn tracing on if and only if ARG is positive. */)
19681 trace_redisplay_p
= !trace_redisplay_p
;
19684 arg
= Fprefix_numeric_value (arg
);
19685 trace_redisplay_p
= XINT (arg
) > 0;
19692 DEFUN ("trace-to-stderr", Ftrace_to_stderr
, Strace_to_stderr
, 1, MANY
, "",
19693 doc
: /* Like `format', but print result to stderr.
19694 usage: (trace-to-stderr STRING &rest OBJECTS) */)
19695 (ptrdiff_t nargs
, Lisp_Object
*args
)
19697 Lisp_Object s
= Fformat (nargs
, args
);
19698 fwrite (SDATA (s
), 1, SBYTES (s
), stderr
);
19702 #endif /* GLYPH_DEBUG */
19706 /***********************************************************************
19707 Building Desired Matrix Rows
19708 ***********************************************************************/
19710 /* Return a temporary glyph row holding the glyphs of an overlay arrow.
19711 Used for non-window-redisplay windows, and for windows w/o left fringe. */
19713 static struct glyph_row
*
19714 get_overlay_arrow_glyph_row (struct window
*w
, Lisp_Object overlay_arrow_string
)
19716 struct frame
*f
= XFRAME (WINDOW_FRAME (w
));
19717 struct buffer
*buffer
= XBUFFER (w
->contents
);
19718 struct buffer
*old
= current_buffer
;
19719 const unsigned char *arrow_string
= SDATA (overlay_arrow_string
);
19720 ptrdiff_t arrow_len
= SCHARS (overlay_arrow_string
);
19721 const unsigned char *arrow_end
= arrow_string
+ arrow_len
;
19722 const unsigned char *p
;
19725 int n_glyphs_before
;
19727 set_buffer_temp (buffer
);
19728 init_iterator (&it
, w
, -1, -1, &scratch_glyph_row
, DEFAULT_FACE_ID
);
19729 scratch_glyph_row
.reversed_p
= false;
19730 it
.glyph_row
->used
[TEXT_AREA
] = 0;
19731 SET_TEXT_POS (it
.position
, 0, 0);
19733 multibyte_p
= !NILP (BVAR (buffer
, enable_multibyte_characters
));
19735 while (p
< arrow_end
)
19737 Lisp_Object face
, ilisp
;
19739 /* Get the next character. */
19741 it
.c
= it
.char_to_display
= string_char_and_length (p
, &it
.len
);
19744 it
.c
= it
.char_to_display
= *p
, it
.len
= 1;
19745 if (! ASCII_CHAR_P (it
.c
))
19746 it
.char_to_display
= BYTE8_TO_CHAR (it
.c
);
19750 /* Get its face. */
19751 ilisp
= make_number (p
- arrow_string
);
19752 face
= Fget_text_property (ilisp
, Qface
, overlay_arrow_string
);
19753 it
.face_id
= compute_char_face (f
, it
.char_to_display
, face
);
19755 /* Compute its width, get its glyphs. */
19756 n_glyphs_before
= it
.glyph_row
->used
[TEXT_AREA
];
19757 SET_TEXT_POS (it
.position
, -1, -1);
19758 PRODUCE_GLYPHS (&it
);
19760 /* If this character doesn't fit any more in the line, we have
19761 to remove some glyphs. */
19762 if (it
.current_x
> it
.last_visible_x
)
19764 it
.glyph_row
->used
[TEXT_AREA
] = n_glyphs_before
;
19769 set_buffer_temp (old
);
19770 return it
.glyph_row
;
19774 /* Insert truncation glyphs at the start of IT->glyph_row. Which
19775 glyphs to insert is determined by produce_special_glyphs. */
19778 insert_left_trunc_glyphs (struct it
*it
)
19780 struct it truncate_it
;
19781 struct glyph
*from
, *end
, *to
, *toend
;
19783 eassert (!FRAME_WINDOW_P (it
->f
)
19784 || (!it
->glyph_row
->reversed_p
19785 && WINDOW_LEFT_FRINGE_WIDTH (it
->w
) == 0)
19786 || (it
->glyph_row
->reversed_p
19787 && WINDOW_RIGHT_FRINGE_WIDTH (it
->w
) == 0));
19789 /* Get the truncation glyphs. */
19791 truncate_it
.current_x
= 0;
19792 truncate_it
.face_id
= DEFAULT_FACE_ID
;
19793 truncate_it
.glyph_row
= &scratch_glyph_row
;
19794 truncate_it
.area
= TEXT_AREA
;
19795 truncate_it
.glyph_row
->used
[TEXT_AREA
] = 0;
19796 CHARPOS (truncate_it
.position
) = BYTEPOS (truncate_it
.position
) = -1;
19797 truncate_it
.object
= Qnil
;
19798 produce_special_glyphs (&truncate_it
, IT_TRUNCATION
);
19800 /* Overwrite glyphs from IT with truncation glyphs. */
19801 if (!it
->glyph_row
->reversed_p
)
19803 short tused
= truncate_it
.glyph_row
->used
[TEXT_AREA
];
19805 from
= truncate_it
.glyph_row
->glyphs
[TEXT_AREA
];
19806 end
= from
+ tused
;
19807 to
= it
->glyph_row
->glyphs
[TEXT_AREA
];
19808 toend
= to
+ it
->glyph_row
->used
[TEXT_AREA
];
19809 if (FRAME_WINDOW_P (it
->f
))
19811 /* On GUI frames, when variable-size fonts are displayed,
19812 the truncation glyphs may need more pixels than the row's
19813 glyphs they overwrite. We overwrite more glyphs to free
19814 enough screen real estate, and enlarge the stretch glyph
19815 on the right (see display_line), if there is one, to
19816 preserve the screen position of the truncation glyphs on
19819 struct glyph
*g
= to
;
19822 /* The first glyph could be partially visible, in which case
19823 it->glyph_row->x will be negative. But we want the left
19824 truncation glyphs to be aligned at the left margin of the
19825 window, so we override the x coordinate at which the row
19827 it
->glyph_row
->x
= 0;
19828 while (g
< toend
&& w
< it
->truncation_pixel_width
)
19830 w
+= g
->pixel_width
;
19833 if (g
- to
- tused
> 0)
19835 memmove (to
+ tused
, g
, (toend
- g
) * sizeof(*g
));
19836 it
->glyph_row
->used
[TEXT_AREA
] -= g
- to
- tused
;
19838 used
= it
->glyph_row
->used
[TEXT_AREA
];
19839 if (it
->glyph_row
->truncated_on_right_p
19840 && WINDOW_RIGHT_FRINGE_WIDTH (it
->w
) == 0
19841 && it
->glyph_row
->glyphs
[TEXT_AREA
][used
- 2].type
19844 int extra
= w
- it
->truncation_pixel_width
;
19846 it
->glyph_row
->glyphs
[TEXT_AREA
][used
- 2].pixel_width
+= extra
;
19853 /* There may be padding glyphs left over. Overwrite them too. */
19854 if (!FRAME_WINDOW_P (it
->f
))
19856 while (to
< toend
&& CHAR_GLYPH_PADDING_P (*to
))
19858 from
= truncate_it
.glyph_row
->glyphs
[TEXT_AREA
];
19865 it
->glyph_row
->used
[TEXT_AREA
] = to
- it
->glyph_row
->glyphs
[TEXT_AREA
];
19869 short tused
= truncate_it
.glyph_row
->used
[TEXT_AREA
];
19871 /* In R2L rows, overwrite the last (rightmost) glyphs, and do
19872 that back to front. */
19873 end
= truncate_it
.glyph_row
->glyphs
[TEXT_AREA
];
19874 from
= end
+ truncate_it
.glyph_row
->used
[TEXT_AREA
] - 1;
19875 toend
= it
->glyph_row
->glyphs
[TEXT_AREA
];
19876 to
= toend
+ it
->glyph_row
->used
[TEXT_AREA
] - 1;
19877 if (FRAME_WINDOW_P (it
->f
))
19880 struct glyph
*g
= to
;
19882 while (g
>= toend
&& w
< it
->truncation_pixel_width
)
19884 w
+= g
->pixel_width
;
19887 if (to
- g
- tused
> 0)
19889 if (it
->glyph_row
->truncated_on_right_p
19890 && WINDOW_LEFT_FRINGE_WIDTH (it
->w
) == 0
19891 && it
->glyph_row
->glyphs
[TEXT_AREA
][1].type
== STRETCH_GLYPH
)
19893 int extra
= w
- it
->truncation_pixel_width
;
19895 it
->glyph_row
->glyphs
[TEXT_AREA
][1].pixel_width
+= extra
;
19899 while (from
>= end
&& to
>= toend
)
19901 if (!FRAME_WINDOW_P (it
->f
))
19903 while (to
>= toend
&& CHAR_GLYPH_PADDING_P (*to
))
19906 truncate_it
.glyph_row
->glyphs
[TEXT_AREA
]
19907 + truncate_it
.glyph_row
->used
[TEXT_AREA
] - 1;
19908 while (from
>= end
&& to
>= toend
)
19914 /* Need to free some room before prepending additional
19916 int move_by
= from
- end
+ 1;
19917 struct glyph
*g0
= it
->glyph_row
->glyphs
[TEXT_AREA
];
19918 struct glyph
*g
= g0
+ it
->glyph_row
->used
[TEXT_AREA
] - 1;
19920 for ( ; g
>= g0
; g
--)
19922 while (from
>= end
)
19924 it
->glyph_row
->used
[TEXT_AREA
] += move_by
;
19929 /* Compute the hash code for ROW. */
19931 row_hash (struct glyph_row
*row
)
19934 unsigned hashval
= 0;
19936 for (area
= LEFT_MARGIN_AREA
; area
< LAST_AREA
; ++area
)
19937 for (k
= 0; k
< row
->used
[area
]; ++k
)
19938 hashval
= ((((hashval
<< 4) + (hashval
>> 24)) & 0x0fffffff)
19939 + row
->glyphs
[area
][k
].u
.val
19940 + row
->glyphs
[area
][k
].face_id
19941 + row
->glyphs
[area
][k
].padding_p
19942 + (row
->glyphs
[area
][k
].type
<< 2));
19947 /* Compute the pixel height and width of IT->glyph_row.
19949 Most of the time, ascent and height of a display line will be equal
19950 to the max_ascent and max_height values of the display iterator
19951 structure. This is not the case if
19953 1. We hit ZV without displaying anything. In this case, max_ascent
19954 and max_height will be zero.
19956 2. We have some glyphs that don't contribute to the line height.
19957 (The glyph row flag contributes_to_line_height_p is for future
19958 pixmap extensions).
19960 The first case is easily covered by using default values because in
19961 these cases, the line height does not really matter, except that it
19962 must not be zero. */
19965 compute_line_metrics (struct it
*it
)
19967 struct glyph_row
*row
= it
->glyph_row
;
19969 if (FRAME_WINDOW_P (it
->f
))
19971 int i
, min_y
, max_y
;
19973 /* The line may consist of one space only, that was added to
19974 place the cursor on it. If so, the row's height hasn't been
19976 if (row
->height
== 0)
19978 if (it
->max_ascent
+ it
->max_descent
== 0)
19979 it
->max_descent
= it
->max_phys_descent
= FRAME_LINE_HEIGHT (it
->f
);
19980 row
->ascent
= it
->max_ascent
;
19981 row
->height
= it
->max_ascent
+ it
->max_descent
;
19982 row
->phys_ascent
= it
->max_phys_ascent
;
19983 row
->phys_height
= it
->max_phys_ascent
+ it
->max_phys_descent
;
19984 row
->extra_line_spacing
= it
->max_extra_line_spacing
;
19987 /* Compute the width of this line. */
19988 row
->pixel_width
= row
->x
;
19989 for (i
= 0; i
< row
->used
[TEXT_AREA
]; ++i
)
19990 row
->pixel_width
+= row
->glyphs
[TEXT_AREA
][i
].pixel_width
;
19992 eassert (row
->pixel_width
>= 0);
19993 eassert (row
->ascent
>= 0 && row
->height
> 0);
19995 row
->overlapping_p
= (MATRIX_ROW_OVERLAPS_SUCC_P (row
)
19996 || MATRIX_ROW_OVERLAPS_PRED_P (row
));
19998 /* If first line's physical ascent is larger than its logical
19999 ascent, use the physical ascent, and make the row taller.
20000 This makes accented characters fully visible. */
20001 if (row
== MATRIX_FIRST_TEXT_ROW (it
->w
->desired_matrix
)
20002 && row
->phys_ascent
> row
->ascent
)
20004 row
->height
+= row
->phys_ascent
- row
->ascent
;
20005 row
->ascent
= row
->phys_ascent
;
20008 /* Compute how much of the line is visible. */
20009 row
->visible_height
= row
->height
;
20011 min_y
= WINDOW_HEADER_LINE_HEIGHT (it
->w
);
20012 max_y
= WINDOW_BOX_HEIGHT_NO_MODE_LINE (it
->w
);
20014 if (row
->y
< min_y
)
20015 row
->visible_height
-= min_y
- row
->y
;
20016 if (row
->y
+ row
->height
> max_y
)
20017 row
->visible_height
-= row
->y
+ row
->height
- max_y
;
20021 row
->pixel_width
= row
->used
[TEXT_AREA
];
20022 if (row
->continued_p
)
20023 row
->pixel_width
-= it
->continuation_pixel_width
;
20024 else if (row
->truncated_on_right_p
)
20025 row
->pixel_width
-= it
->truncation_pixel_width
;
20026 row
->ascent
= row
->phys_ascent
= 0;
20027 row
->height
= row
->phys_height
= row
->visible_height
= 1;
20028 row
->extra_line_spacing
= 0;
20031 /* Compute a hash code for this row. */
20032 row
->hash
= row_hash (row
);
20034 it
->max_ascent
= it
->max_descent
= 0;
20035 it
->max_phys_ascent
= it
->max_phys_descent
= 0;
20039 /* Append one space to the glyph row of iterator IT if doing a
20040 window-based redisplay. The space has the same face as
20041 IT->face_id. Value is true if a space was added.
20043 This function is called to make sure that there is always one glyph
20044 at the end of a glyph row that the cursor can be set on under
20045 window-systems. (If there weren't such a glyph we would not know
20046 how wide and tall a box cursor should be displayed).
20048 At the same time this space let's a nicely handle clearing to the
20049 end of the line if the row ends in italic text. */
20052 append_space_for_newline (struct it
*it
, bool default_face_p
)
20054 if (FRAME_WINDOW_P (it
->f
))
20056 int n
= it
->glyph_row
->used
[TEXT_AREA
];
20058 if (it
->glyph_row
->glyphs
[TEXT_AREA
] + n
20059 < it
->glyph_row
->glyphs
[1 + TEXT_AREA
])
20061 /* Save some values that must not be changed.
20062 Must save IT->c and IT->len because otherwise
20063 ITERATOR_AT_END_P wouldn't work anymore after
20064 append_space_for_newline has been called. */
20065 enum display_element_type saved_what
= it
->what
;
20066 int saved_c
= it
->c
, saved_len
= it
->len
;
20067 int saved_char_to_display
= it
->char_to_display
;
20068 int saved_x
= it
->current_x
;
20069 int saved_face_id
= it
->face_id
;
20070 bool saved_box_end
= it
->end_of_box_run_p
;
20071 struct text_pos saved_pos
;
20072 Lisp_Object saved_object
;
20075 saved_object
= it
->object
;
20076 saved_pos
= it
->position
;
20078 it
->what
= IT_CHARACTER
;
20079 memset (&it
->position
, 0, sizeof it
->position
);
20081 it
->c
= it
->char_to_display
= ' ';
20084 /* If the default face was remapped, be sure to use the
20085 remapped face for the appended newline. */
20086 if (default_face_p
)
20087 it
->face_id
= lookup_basic_face (it
->w
, it
->f
, DEFAULT_FACE_ID
);
20088 else if (it
->face_before_selective_p
)
20089 it
->face_id
= it
->saved_face_id
;
20090 face
= FACE_FROM_ID (it
->f
, it
->face_id
);
20091 it
->face_id
= FACE_FOR_CHAR (it
->f
, face
, 0, -1, Qnil
);
20092 /* In R2L rows, we will prepend a stretch glyph that will
20093 have the end_of_box_run_p flag set for it, so there's no
20094 need for the appended newline glyph to have that flag
20096 if (it
->glyph_row
->reversed_p
20097 /* But if the appended newline glyph goes all the way to
20098 the end of the row, there will be no stretch glyph,
20099 so leave the box flag set. */
20100 && saved_x
+ FRAME_COLUMN_WIDTH (it
->f
) < it
->last_visible_x
)
20101 it
->end_of_box_run_p
= false;
20103 PRODUCE_GLYPHS (it
);
20105 #ifdef HAVE_WINDOW_SYSTEM
20106 /* Make sure this space glyph has the right ascent and
20107 descent values, or else cursor at end of line will look
20108 funny, and height of empty lines will be incorrect. */
20109 struct glyph
*g
= it
->glyph_row
->glyphs
[TEXT_AREA
] + n
;
20110 struct font
*font
= face
->font
? face
->font
: FRAME_FONT (it
->f
);
20113 Lisp_Object height
, total_height
;
20114 int extra_line_spacing
= it
->extra_line_spacing
;
20115 int boff
= font
->baseline_offset
;
20117 if (font
->vertical_centering
)
20118 boff
= VCENTER_BASELINE_OFFSET (font
, it
->f
) - boff
;
20120 it
->object
= saved_object
; /* get_it_property needs this */
20121 normal_char_ascent_descent (font
, -1, &it
->ascent
, &it
->descent
);
20122 /* Must do a subset of line height processing from
20123 x_produce_glyph for newline characters. */
20124 height
= get_it_property (it
, Qline_height
);
20126 && CONSP (XCDR (height
))
20127 && NILP (XCDR (XCDR (height
))))
20129 total_height
= XCAR (XCDR (height
));
20130 height
= XCAR (height
);
20133 total_height
= Qnil
;
20134 height
= calc_line_height_property (it
, height
, font
, boff
, true);
20136 if (it
->override_ascent
>= 0)
20138 it
->ascent
= it
->override_ascent
;
20139 it
->descent
= it
->override_descent
;
20140 boff
= it
->override_boff
;
20142 if (EQ (height
, Qt
))
20143 extra_line_spacing
= 0;
20146 Lisp_Object spacing
;
20148 it
->phys_ascent
= it
->ascent
;
20149 it
->phys_descent
= it
->descent
;
20151 && XINT (height
) > it
->ascent
+ it
->descent
)
20152 it
->ascent
= XINT (height
) - it
->descent
;
20154 if (!NILP (total_height
))
20155 spacing
= calc_line_height_property (it
, total_height
, font
,
20159 spacing
= get_it_property (it
, Qline_spacing
);
20160 spacing
= calc_line_height_property (it
, spacing
, font
,
20163 if (INTEGERP (spacing
))
20165 extra_line_spacing
= XINT (spacing
);
20166 if (!NILP (total_height
))
20167 extra_line_spacing
-= (it
->phys_ascent
+ it
->phys_descent
);
20170 if (extra_line_spacing
> 0)
20172 it
->descent
+= extra_line_spacing
;
20173 if (extra_line_spacing
> it
->max_extra_line_spacing
)
20174 it
->max_extra_line_spacing
= extra_line_spacing
;
20176 it
->max_ascent
= it
->ascent
;
20177 it
->max_descent
= it
->descent
;
20178 /* Make sure compute_line_metrics recomputes the row height. */
20179 it
->glyph_row
->height
= 0;
20182 g
->ascent
= it
->max_ascent
;
20183 g
->descent
= it
->max_descent
;
20186 it
->override_ascent
= -1;
20187 it
->constrain_row_ascent_descent_p
= false;
20188 it
->current_x
= saved_x
;
20189 it
->object
= saved_object
;
20190 it
->position
= saved_pos
;
20191 it
->what
= saved_what
;
20192 it
->face_id
= saved_face_id
;
20193 it
->len
= saved_len
;
20195 it
->char_to_display
= saved_char_to_display
;
20196 it
->end_of_box_run_p
= saved_box_end
;
20205 /* Extend the face of the last glyph in the text area of IT->glyph_row
20206 to the end of the display line. Called from display_line. If the
20207 glyph row is empty, add a space glyph to it so that we know the
20208 face to draw. Set the glyph row flag fill_line_p. If the glyph
20209 row is R2L, prepend a stretch glyph to cover the empty space to the
20210 left of the leftmost glyph. */
20213 extend_face_to_end_of_line (struct it
*it
)
20215 struct face
*face
, *default_face
;
20216 struct frame
*f
= it
->f
;
20218 /* If line is already filled, do nothing. Non window-system frames
20219 get a grace of one more ``pixel'' because their characters are
20220 1-``pixel'' wide, so they hit the equality too early. This grace
20221 is needed only for R2L rows that are not continued, to produce
20222 one extra blank where we could display the cursor. */
20223 if ((it
->current_x
>= it
->last_visible_x
20224 + (!FRAME_WINDOW_P (f
)
20225 && it
->glyph_row
->reversed_p
20226 && !it
->glyph_row
->continued_p
))
20227 /* If the window has display margins, we will need to extend
20228 their face even if the text area is filled. */
20229 && !(WINDOW_LEFT_MARGIN_WIDTH (it
->w
) > 0
20230 || WINDOW_RIGHT_MARGIN_WIDTH (it
->w
) > 0))
20233 /* The default face, possibly remapped. */
20235 FACE_FROM_ID_OR_NULL (f
, lookup_basic_face (it
->w
, f
, DEFAULT_FACE_ID
));
20237 /* Face extension extends the background and box of IT->face_id
20238 to the end of the line. If the background equals the background
20239 of the frame, we don't have to do anything. */
20240 face
= FACE_FROM_ID (f
, (it
->face_before_selective_p
20241 ? it
->saved_face_id
20244 if (FRAME_WINDOW_P (f
)
20245 && MATRIX_ROW_DISPLAYS_TEXT_P (it
->glyph_row
)
20246 && face
->box
== FACE_NO_BOX
20247 && face
->background
== FRAME_BACKGROUND_PIXEL (f
)
20248 #ifdef HAVE_WINDOW_SYSTEM
20251 && !it
->glyph_row
->reversed_p
)
20254 /* Set the glyph row flag indicating that the face of the last glyph
20255 in the text area has to be drawn to the end of the text area. */
20256 it
->glyph_row
->fill_line_p
= true;
20258 /* If current character of IT is not ASCII, make sure we have the
20259 ASCII face. This will be automatically undone the next time
20260 get_next_display_element returns a multibyte character. Note
20261 that the character will always be single byte in unibyte
20263 if (!ASCII_CHAR_P (it
->c
))
20265 it
->face_id
= FACE_FOR_CHAR (f
, face
, 0, -1, Qnil
);
20268 if (FRAME_WINDOW_P (f
))
20270 /* If the row is empty, add a space with the current face of IT,
20271 so that we know which face to draw. */
20272 if (it
->glyph_row
->used
[TEXT_AREA
] == 0)
20274 it
->glyph_row
->glyphs
[TEXT_AREA
][0] = space_glyph
;
20275 it
->glyph_row
->glyphs
[TEXT_AREA
][0].face_id
= face
->id
;
20276 it
->glyph_row
->used
[TEXT_AREA
] = 1;
20278 /* Mode line and the header line don't have margins, and
20279 likewise the frame's tool-bar window, if there is any. */
20280 if (!(it
->glyph_row
->mode_line_p
20281 #if defined (HAVE_WINDOW_SYSTEM) && ! defined (USE_GTK) && ! defined (HAVE_NS)
20282 || (WINDOWP (f
->tool_bar_window
)
20283 && it
->w
== XWINDOW (f
->tool_bar_window
))
20287 if (WINDOW_LEFT_MARGIN_WIDTH (it
->w
) > 0
20288 && it
->glyph_row
->used
[LEFT_MARGIN_AREA
] == 0)
20290 it
->glyph_row
->glyphs
[LEFT_MARGIN_AREA
][0] = space_glyph
;
20291 it
->glyph_row
->glyphs
[LEFT_MARGIN_AREA
][0].face_id
=
20293 it
->glyph_row
->used
[LEFT_MARGIN_AREA
] = 1;
20295 if (WINDOW_RIGHT_MARGIN_WIDTH (it
->w
) > 0
20296 && it
->glyph_row
->used
[RIGHT_MARGIN_AREA
] == 0)
20298 it
->glyph_row
->glyphs
[RIGHT_MARGIN_AREA
][0] = space_glyph
;
20299 it
->glyph_row
->glyphs
[RIGHT_MARGIN_AREA
][0].face_id
=
20301 it
->glyph_row
->used
[RIGHT_MARGIN_AREA
] = 1;
20304 #ifdef HAVE_WINDOW_SYSTEM
20305 if (it
->glyph_row
->reversed_p
)
20307 /* Prepend a stretch glyph to the row, such that the
20308 rightmost glyph will be drawn flushed all the way to the
20309 right margin of the window. The stretch glyph that will
20310 occupy the empty space, if any, to the left of the
20312 struct font
*font
= face
->font
? face
->font
: FRAME_FONT (f
);
20313 struct glyph
*row_start
= it
->glyph_row
->glyphs
[TEXT_AREA
];
20314 struct glyph
*row_end
= row_start
+ it
->glyph_row
->used
[TEXT_AREA
];
20316 int row_width
, stretch_ascent
, stretch_width
;
20317 struct text_pos saved_pos
;
20319 bool saved_avoid_cursor
, saved_box_start
;
20321 for (row_width
= 0, g
= row_start
; g
< row_end
; g
++)
20322 row_width
+= g
->pixel_width
;
20324 /* FIXME: There are various minor display glitches in R2L
20325 rows when only one of the fringes is missing. The
20326 strange condition below produces the least bad effect. */
20327 if ((WINDOW_LEFT_FRINGE_WIDTH (it
->w
) == 0)
20328 == (WINDOW_RIGHT_FRINGE_WIDTH (it
->w
) == 0)
20329 || WINDOW_RIGHT_FRINGE_WIDTH (it
->w
) != 0)
20330 stretch_width
= window_box_width (it
->w
, TEXT_AREA
);
20332 stretch_width
= it
->last_visible_x
- it
->first_visible_x
;
20333 stretch_width
-= row_width
;
20335 if (stretch_width
> 0)
20338 (((it
->ascent
+ it
->descent
)
20339 * FONT_BASE (font
)) / FONT_HEIGHT (font
));
20340 saved_pos
= it
->position
;
20341 memset (&it
->position
, 0, sizeof it
->position
);
20342 saved_avoid_cursor
= it
->avoid_cursor_p
;
20343 it
->avoid_cursor_p
= true;
20344 saved_face_id
= it
->face_id
;
20345 saved_box_start
= it
->start_of_box_run_p
;
20346 /* The last row's stretch glyph should get the default
20347 face, to avoid painting the rest of the window with
20348 the region face, if the region ends at ZV. */
20349 if (it
->glyph_row
->ends_at_zv_p
)
20350 it
->face_id
= default_face
->id
;
20352 it
->face_id
= face
->id
;
20353 it
->start_of_box_run_p
= false;
20354 append_stretch_glyph (it
, Qnil
, stretch_width
,
20355 it
->ascent
+ it
->descent
, stretch_ascent
);
20356 it
->position
= saved_pos
;
20357 it
->avoid_cursor_p
= saved_avoid_cursor
;
20358 it
->face_id
= saved_face_id
;
20359 it
->start_of_box_run_p
= saved_box_start
;
20361 /* If stretch_width comes out negative, it means that the
20362 last glyph is only partially visible. In R2L rows, we
20363 want the leftmost glyph to be partially visible, so we
20364 need to give the row the corresponding left offset. */
20365 if (stretch_width
< 0)
20366 it
->glyph_row
->x
= stretch_width
;
20368 #endif /* HAVE_WINDOW_SYSTEM */
20372 /* Save some values that must not be changed. */
20373 int saved_x
= it
->current_x
;
20374 struct text_pos saved_pos
;
20375 Lisp_Object saved_object
;
20376 enum display_element_type saved_what
= it
->what
;
20377 int saved_face_id
= it
->face_id
;
20379 saved_object
= it
->object
;
20380 saved_pos
= it
->position
;
20382 it
->what
= IT_CHARACTER
;
20383 memset (&it
->position
, 0, sizeof it
->position
);
20385 it
->c
= it
->char_to_display
= ' ';
20388 if (WINDOW_LEFT_MARGIN_WIDTH (it
->w
) > 0
20389 && (it
->glyph_row
->used
[LEFT_MARGIN_AREA
]
20390 < WINDOW_LEFT_MARGIN_WIDTH (it
->w
))
20391 && !it
->glyph_row
->mode_line_p
20392 && default_face
->background
!= FRAME_BACKGROUND_PIXEL (f
))
20394 struct glyph
*g
= it
->glyph_row
->glyphs
[LEFT_MARGIN_AREA
];
20395 struct glyph
*e
= g
+ it
->glyph_row
->used
[LEFT_MARGIN_AREA
];
20397 for (it
->current_x
= 0; g
< e
; g
++)
20398 it
->current_x
+= g
->pixel_width
;
20400 it
->area
= LEFT_MARGIN_AREA
;
20401 it
->face_id
= default_face
->id
;
20402 while (it
->glyph_row
->used
[LEFT_MARGIN_AREA
]
20403 < WINDOW_LEFT_MARGIN_WIDTH (it
->w
)
20404 && g
< it
->glyph_row
->glyphs
[TEXT_AREA
])
20406 PRODUCE_GLYPHS (it
);
20407 /* term.c:produce_glyphs advances it->current_x only for
20409 it
->current_x
+= it
->pixel_width
;
20413 it
->current_x
= saved_x
;
20414 it
->area
= TEXT_AREA
;
20417 /* The last row's blank glyphs should get the default face, to
20418 avoid painting the rest of the window with the region face,
20419 if the region ends at ZV. */
20420 if (it
->glyph_row
->ends_at_zv_p
)
20421 it
->face_id
= default_face
->id
;
20423 it
->face_id
= face
->id
;
20424 PRODUCE_GLYPHS (it
);
20426 while (it
->current_x
<= it
->last_visible_x
)
20427 PRODUCE_GLYPHS (it
);
20429 if (WINDOW_RIGHT_MARGIN_WIDTH (it
->w
) > 0
20430 && (it
->glyph_row
->used
[RIGHT_MARGIN_AREA
]
20431 < WINDOW_RIGHT_MARGIN_WIDTH (it
->w
))
20432 && !it
->glyph_row
->mode_line_p
20433 && default_face
->background
!= FRAME_BACKGROUND_PIXEL (f
))
20435 struct glyph
*g
= it
->glyph_row
->glyphs
[RIGHT_MARGIN_AREA
];
20436 struct glyph
*e
= g
+ it
->glyph_row
->used
[RIGHT_MARGIN_AREA
];
20438 for ( ; g
< e
; g
++)
20439 it
->current_x
+= g
->pixel_width
;
20441 it
->area
= RIGHT_MARGIN_AREA
;
20442 it
->face_id
= default_face
->id
;
20443 while (it
->glyph_row
->used
[RIGHT_MARGIN_AREA
]
20444 < WINDOW_RIGHT_MARGIN_WIDTH (it
->w
)
20445 && g
< it
->glyph_row
->glyphs
[LAST_AREA
])
20447 PRODUCE_GLYPHS (it
);
20448 it
->current_x
+= it
->pixel_width
;
20452 it
->area
= TEXT_AREA
;
20455 /* Don't count these blanks really. It would let us insert a left
20456 truncation glyph below and make us set the cursor on them, maybe. */
20457 it
->current_x
= saved_x
;
20458 it
->object
= saved_object
;
20459 it
->position
= saved_pos
;
20460 it
->what
= saved_what
;
20461 it
->face_id
= saved_face_id
;
20466 /* Value is true if text starting at CHARPOS in current_buffer is
20467 trailing whitespace. */
20470 trailing_whitespace_p (ptrdiff_t charpos
)
20472 ptrdiff_t bytepos
= CHAR_TO_BYTE (charpos
);
20475 while (bytepos
< ZV_BYTE
20476 && (c
= FETCH_CHAR (bytepos
),
20477 c
== ' ' || c
== '\t'))
20480 if (bytepos
>= ZV_BYTE
|| c
== '\n' || c
== '\r')
20482 if (bytepos
!= PT_BYTE
)
20489 /* Highlight trailing whitespace, if any, in row at IT. */
20492 highlight_trailing_whitespace (struct it
*it
)
20494 struct glyph_row
*row
= it
->glyph_row
;
20495 int used
= row
->used
[TEXT_AREA
];
20499 struct glyph
*start
= row
->glyphs
[TEXT_AREA
];
20500 struct glyph
*glyph
= start
+ used
- 1;
20502 if (row
->reversed_p
)
20504 /* Right-to-left rows need to be processed in the opposite
20505 direction, so swap the edge pointers. */
20507 start
= row
->glyphs
[TEXT_AREA
] + used
- 1;
20510 /* Skip over glyphs inserted to display the cursor at the
20511 end of a line, for extending the face of the last glyph
20512 to the end of the line on terminals, and for truncation
20513 and continuation glyphs. */
20514 if (!row
->reversed_p
)
20516 while (glyph
>= start
20517 && glyph
->type
== CHAR_GLYPH
20518 && NILP (glyph
->object
))
20523 while (glyph
<= start
20524 && glyph
->type
== CHAR_GLYPH
20525 && NILP (glyph
->object
))
20529 /* If last glyph is a space or stretch, and it's trailing
20530 whitespace, set the face of all trailing whitespace glyphs in
20531 IT->glyph_row to `trailing-whitespace'. */
20532 if ((row
->reversed_p
? glyph
<= start
: glyph
>= start
)
20533 && BUFFERP (glyph
->object
)
20534 && (glyph
->type
== STRETCH_GLYPH
20535 || (glyph
->type
== CHAR_GLYPH
20536 && glyph
->u
.ch
== ' '))
20537 && trailing_whitespace_p (glyph
->charpos
))
20539 int face_id
= lookup_named_face (it
->w
, it
->f
, Qtrailing_whitespace
, false);
20543 if (!row
->reversed_p
)
20545 while (glyph
>= start
20546 && BUFFERP (glyph
->object
)
20547 && (glyph
->type
== STRETCH_GLYPH
20548 || (glyph
->type
== CHAR_GLYPH
20549 && glyph
->u
.ch
== ' ')))
20550 (glyph
--)->face_id
= face_id
;
20554 while (glyph
<= start
20555 && BUFFERP (glyph
->object
)
20556 && (glyph
->type
== STRETCH_GLYPH
20557 || (glyph
->type
== CHAR_GLYPH
20558 && glyph
->u
.ch
== ' ')))
20559 (glyph
++)->face_id
= face_id
;
20566 /* Value is true if glyph row ROW should be
20567 considered to hold the buffer position CHARPOS. */
20570 row_for_charpos_p (struct glyph_row
*row
, ptrdiff_t charpos
)
20572 bool result
= true;
20574 if (charpos
== CHARPOS (row
->end
.pos
)
20575 || charpos
== MATRIX_ROW_END_CHARPOS (row
))
20577 /* Suppose the row ends on a string.
20578 Unless the row is continued, that means it ends on a newline
20579 in the string. If it's anything other than a display string
20580 (e.g., a before-string from an overlay), we don't want the
20581 cursor there. (This heuristic seems to give the optimal
20582 behavior for the various types of multi-line strings.)
20583 One exception: if the string has `cursor' property on one of
20584 its characters, we _do_ want the cursor there. */
20585 if (CHARPOS (row
->end
.string_pos
) >= 0)
20587 if (row
->continued_p
)
20591 /* Check for `display' property. */
20592 struct glyph
*beg
= row
->glyphs
[TEXT_AREA
];
20593 struct glyph
*end
= beg
+ row
->used
[TEXT_AREA
] - 1;
20594 struct glyph
*glyph
;
20597 for (glyph
= end
; glyph
>= beg
; --glyph
)
20598 if (STRINGP (glyph
->object
))
20601 = Fget_char_property (make_number (charpos
),
20605 && display_prop_string_p (prop
, glyph
->object
));
20606 /* If there's a `cursor' property on one of the
20607 string's characters, this row is a cursor row,
20608 even though this is not a display string. */
20611 Lisp_Object s
= glyph
->object
;
20613 for ( ; glyph
>= beg
&& EQ (glyph
->object
, s
); --glyph
)
20615 ptrdiff_t gpos
= glyph
->charpos
;
20617 if (!NILP (Fget_char_property (make_number (gpos
),
20629 else if (MATRIX_ROW_ENDS_IN_MIDDLE_OF_CHAR_P (row
))
20631 /* If the row ends in middle of a real character,
20632 and the line is continued, we want the cursor here.
20633 That's because CHARPOS (ROW->end.pos) would equal
20634 PT if PT is before the character. */
20635 if (!row
->ends_in_ellipsis_p
)
20636 result
= row
->continued_p
;
20638 /* If the row ends in an ellipsis, then
20639 CHARPOS (ROW->end.pos) will equal point after the
20640 invisible text. We want that position to be displayed
20641 after the ellipsis. */
20644 /* If the row ends at ZV, display the cursor at the end of that
20645 row instead of at the start of the row below. */
20647 result
= row
->ends_at_zv_p
;
20653 /* Value is true if glyph row ROW should be
20654 used to hold the cursor. */
20657 cursor_row_p (struct glyph_row
*row
)
20659 return row_for_charpos_p (row
, PT
);
20664 /* Push the property PROP so that it will be rendered at the current
20665 position in IT. Return true if PROP was successfully pushed, false
20666 otherwise. Called from handle_line_prefix to handle the
20667 `line-prefix' and `wrap-prefix' properties. */
20670 push_prefix_prop (struct it
*it
, Lisp_Object prop
)
20672 struct text_pos pos
=
20673 STRINGP (it
->string
) ? it
->current
.string_pos
: it
->current
.pos
;
20675 eassert (it
->method
== GET_FROM_BUFFER
20676 || it
->method
== GET_FROM_DISPLAY_VECTOR
20677 || it
->method
== GET_FROM_STRING
20678 || it
->method
== GET_FROM_IMAGE
);
20680 /* We need to save the current buffer/string position, so it will be
20681 restored by pop_it, because iterate_out_of_display_property
20682 depends on that being set correctly, but some situations leave
20683 it->position not yet set when this function is called. */
20684 push_it (it
, &pos
);
20686 if (STRINGP (prop
))
20688 if (SCHARS (prop
) == 0)
20695 it
->string_from_prefix_prop_p
= true;
20696 it
->multibyte_p
= STRING_MULTIBYTE (it
->string
);
20697 it
->current
.overlay_string_index
= -1;
20698 IT_STRING_CHARPOS (*it
) = IT_STRING_BYTEPOS (*it
) = 0;
20699 it
->end_charpos
= it
->string_nchars
= SCHARS (it
->string
);
20700 it
->method
= GET_FROM_STRING
;
20701 it
->stop_charpos
= 0;
20703 it
->base_level_stop
= 0;
20704 it
->cmp_it
.id
= -1;
20706 /* Force paragraph direction to be that of the parent
20708 if (it
->bidi_p
&& it
->bidi_it
.paragraph_dir
== R2L
)
20709 it
->paragraph_embedding
= it
->bidi_it
.paragraph_dir
;
20711 it
->paragraph_embedding
= L2R
;
20713 /* Set up the bidi iterator for this display string. */
20716 it
->bidi_it
.string
.lstring
= it
->string
;
20717 it
->bidi_it
.string
.s
= NULL
;
20718 it
->bidi_it
.string
.schars
= it
->end_charpos
;
20719 it
->bidi_it
.string
.bufpos
= IT_CHARPOS (*it
);
20720 it
->bidi_it
.string
.from_disp_str
= it
->string_from_display_prop_p
;
20721 it
->bidi_it
.string
.unibyte
= !it
->multibyte_p
;
20722 it
->bidi_it
.w
= it
->w
;
20723 bidi_init_it (0, 0, FRAME_WINDOW_P (it
->f
), &it
->bidi_it
);
20726 else if (CONSP (prop
) && EQ (XCAR (prop
), Qspace
))
20728 it
->method
= GET_FROM_STRETCH
;
20731 #ifdef HAVE_WINDOW_SYSTEM
20732 else if (IMAGEP (prop
))
20734 it
->what
= IT_IMAGE
;
20735 it
->image_id
= lookup_image (it
->f
, prop
);
20736 it
->method
= GET_FROM_IMAGE
;
20738 #endif /* HAVE_WINDOW_SYSTEM */
20741 pop_it (it
); /* bogus display property, give up */
20748 /* Return the character-property PROP at the current position in IT. */
20751 get_it_property (struct it
*it
, Lisp_Object prop
)
20753 Lisp_Object position
, object
= it
->object
;
20755 if (STRINGP (object
))
20756 position
= make_number (IT_STRING_CHARPOS (*it
));
20757 else if (BUFFERP (object
))
20759 position
= make_number (IT_CHARPOS (*it
));
20760 object
= it
->window
;
20765 return Fget_char_property (position
, prop
, object
);
20768 /* See if there's a line- or wrap-prefix, and if so, push it on IT. */
20771 handle_line_prefix (struct it
*it
)
20773 Lisp_Object prefix
;
20775 if (it
->continuation_lines_width
> 0)
20777 prefix
= get_it_property (it
, Qwrap_prefix
);
20779 prefix
= Vwrap_prefix
;
20783 prefix
= get_it_property (it
, Qline_prefix
);
20785 prefix
= Vline_prefix
;
20787 if (! NILP (prefix
) && push_prefix_prop (it
, prefix
))
20789 /* If the prefix is wider than the window, and we try to wrap
20790 it, it would acquire its own wrap prefix, and so on till the
20791 iterator stack overflows. So, don't wrap the prefix. */
20792 it
->line_wrap
= TRUNCATE
;
20793 it
->avoid_cursor_p
= true;
20799 /* Remove N glyphs at the start of a reversed IT->glyph_row. Called
20800 only for R2L lines from display_line and display_string, when they
20801 decide that too many glyphs were produced by PRODUCE_GLYPHS, and
20802 the line/string needs to be continued on the next glyph row. */
20804 unproduce_glyphs (struct it
*it
, int n
)
20806 struct glyph
*glyph
, *end
;
20808 eassert (it
->glyph_row
);
20809 eassert (it
->glyph_row
->reversed_p
);
20810 eassert (it
->area
== TEXT_AREA
);
20811 eassert (n
<= it
->glyph_row
->used
[TEXT_AREA
]);
20813 if (n
> it
->glyph_row
->used
[TEXT_AREA
])
20814 n
= it
->glyph_row
->used
[TEXT_AREA
];
20815 glyph
= it
->glyph_row
->glyphs
[TEXT_AREA
] + n
;
20816 end
= it
->glyph_row
->glyphs
[TEXT_AREA
] + it
->glyph_row
->used
[TEXT_AREA
];
20817 for ( ; glyph
< end
; glyph
++)
20818 glyph
[-n
] = *glyph
;
20821 /* Find the positions in a bidi-reordered ROW to serve as ROW->minpos
20822 and ROW->maxpos. */
20824 find_row_edges (struct it
*it
, struct glyph_row
*row
,
20825 ptrdiff_t min_pos
, ptrdiff_t min_bpos
,
20826 ptrdiff_t max_pos
, ptrdiff_t max_bpos
)
20828 /* FIXME: Revisit this when glyph ``spilling'' in continuation
20829 lines' rows is implemented for bidi-reordered rows. */
20831 /* ROW->minpos is the value of min_pos, the minimal buffer position
20832 we have in ROW, or ROW->start.pos if that is smaller. */
20833 if (min_pos
<= ZV
&& min_pos
< row
->start
.pos
.charpos
)
20834 SET_TEXT_POS (row
->minpos
, min_pos
, min_bpos
);
20836 /* We didn't find buffer positions smaller than ROW->start, or
20837 didn't find _any_ valid buffer positions in any of the glyphs,
20838 so we must trust the iterator's computed positions. */
20839 row
->minpos
= row
->start
.pos
;
20842 max_pos
= CHARPOS (it
->current
.pos
);
20843 max_bpos
= BYTEPOS (it
->current
.pos
);
20846 /* Here are the various use-cases for ending the row, and the
20847 corresponding values for ROW->maxpos:
20849 Line ends in a newline from buffer eol_pos + 1
20850 Line is continued from buffer max_pos + 1
20851 Line is truncated on right it->current.pos
20852 Line ends in a newline from string max_pos + 1(*)
20853 (*) + 1 only when line ends in a forward scan
20854 Line is continued from string max_pos
20855 Line is continued from display vector max_pos
20856 Line is entirely from a string min_pos == max_pos
20857 Line is entirely from a display vector min_pos == max_pos
20858 Line that ends at ZV ZV
20860 If you discover other use-cases, please add them here as
20862 if (row
->ends_at_zv_p
)
20863 row
->maxpos
= it
->current
.pos
;
20864 else if (row
->used
[TEXT_AREA
])
20866 bool seen_this_string
= false;
20867 struct glyph_row
*r1
= row
- 1;
20869 /* Did we see the same display string on the previous row? */
20870 if (STRINGP (it
->object
)
20871 /* this is not the first row */
20872 && row
> it
->w
->desired_matrix
->rows
20873 /* previous row is not the header line */
20874 && !r1
->mode_line_p
20875 /* previous row also ends in a newline from a string */
20876 && r1
->ends_in_newline_from_string_p
)
20878 struct glyph
*start
, *end
;
20880 /* Search for the last glyph of the previous row that came
20881 from buffer or string. Depending on whether the row is
20882 L2R or R2L, we need to process it front to back or the
20883 other way round. */
20884 if (!r1
->reversed_p
)
20886 start
= r1
->glyphs
[TEXT_AREA
];
20887 end
= start
+ r1
->used
[TEXT_AREA
];
20888 /* Glyphs inserted by redisplay have nil as their object. */
20890 && NILP ((end
- 1)->object
)
20891 && (end
- 1)->charpos
<= 0)
20895 if (EQ ((end
- 1)->object
, it
->object
))
20896 seen_this_string
= true;
20899 /* If all the glyphs of the previous row were inserted
20900 by redisplay, it means the previous row was
20901 produced from a single newline, which is only
20902 possible if that newline came from the same string
20903 as the one which produced this ROW. */
20904 seen_this_string
= true;
20908 end
= r1
->glyphs
[TEXT_AREA
] - 1;
20909 start
= end
+ r1
->used
[TEXT_AREA
];
20911 && NILP ((end
+ 1)->object
)
20912 && (end
+ 1)->charpos
<= 0)
20916 if (EQ ((end
+ 1)->object
, it
->object
))
20917 seen_this_string
= true;
20920 seen_this_string
= true;
20923 /* Take note of each display string that covers a newline only
20924 once, the first time we see it. This is for when a display
20925 string includes more than one newline in it. */
20926 if (row
->ends_in_newline_from_string_p
&& !seen_this_string
)
20928 /* If we were scanning the buffer forward when we displayed
20929 the string, we want to account for at least one buffer
20930 position that belongs to this row (position covered by
20931 the display string), so that cursor positioning will
20932 consider this row as a candidate when point is at the end
20933 of the visual line represented by this row. This is not
20934 required when scanning back, because max_pos will already
20935 have a much larger value. */
20936 if (CHARPOS (row
->end
.pos
) > max_pos
)
20937 INC_BOTH (max_pos
, max_bpos
);
20938 SET_TEXT_POS (row
->maxpos
, max_pos
, max_bpos
);
20940 else if (CHARPOS (it
->eol_pos
) > 0)
20941 SET_TEXT_POS (row
->maxpos
,
20942 CHARPOS (it
->eol_pos
) + 1, BYTEPOS (it
->eol_pos
) + 1);
20943 else if (row
->continued_p
)
20945 /* If max_pos is different from IT's current position, it
20946 means IT->method does not belong to the display element
20947 at max_pos. However, it also means that the display
20948 element at max_pos was displayed in its entirety on this
20949 line, which is equivalent to saying that the next line
20950 starts at the next buffer position. */
20951 if (IT_CHARPOS (*it
) == max_pos
&& it
->method
!= GET_FROM_BUFFER
)
20952 SET_TEXT_POS (row
->maxpos
, max_pos
, max_bpos
);
20955 INC_BOTH (max_pos
, max_bpos
);
20956 SET_TEXT_POS (row
->maxpos
, max_pos
, max_bpos
);
20959 else if (row
->truncated_on_right_p
)
20960 /* display_line already called reseat_at_next_visible_line_start,
20961 which puts the iterator at the beginning of the next line, in
20962 the logical order. */
20963 row
->maxpos
= it
->current
.pos
;
20964 else if (max_pos
== min_pos
&& it
->method
!= GET_FROM_BUFFER
)
20965 /* A line that is entirely from a string/image/stretch... */
20966 row
->maxpos
= row
->minpos
;
20971 row
->maxpos
= it
->current
.pos
;
20974 /* Like display_count_lines, but capable of counting outside of the
20975 current narrowed region. */
20977 display_count_lines_logically (ptrdiff_t start_byte
, ptrdiff_t limit_byte
,
20978 ptrdiff_t count
, ptrdiff_t *byte_pos_ptr
)
20980 if (!display_line_numbers_widen
|| (BEGV
== BEG
&& ZV
== Z
))
20981 return display_count_lines (start_byte
, limit_byte
, count
, byte_pos_ptr
);
20984 ptrdiff_t pdl_count
= SPECPDL_INDEX ();
20985 record_unwind_protect (save_restriction_restore
, save_restriction_save ());
20987 val
= display_count_lines (start_byte
, limit_byte
, count
, byte_pos_ptr
);
20988 unbind_to (pdl_count
, Qnil
);
20992 /* Count the number of screen lines in window IT->w between character
20993 position IT_CHARPOS(*IT) and the line showing that window's point. */
20995 display_count_lines_visually (struct it
*it
)
20999 struct text_pos from
;
21001 /* If we already calculated a relative line number, use that. This
21002 trick relies on the fact that visual lines (a.k.a. "glyph rows")
21003 are laid out sequentially, one by one, for each sequence of calls
21004 to display_line or other similar function that follows a call to
21006 if (it
->lnum_bytepos
> 0)
21007 return it
->lnum
+ 1;
21010 ptrdiff_t count
= SPECPDL_INDEX ();
21012 if (IT_CHARPOS (*it
) <= PT
)
21014 from
= it
->current
.pos
;
21019 SET_TEXT_POS (from
, PT
, PT_BYTE
);
21020 to
= IT_CHARPOS (*it
);
21022 start_display (&tem_it
, it
->w
, from
);
21023 /* Need to disable visual mode temporarily, since otherwise the
21024 call to move_it_to will cause infinite recursion. */
21025 specbind (Qdisplay_line_numbers
, Qrelative
);
21026 /* Some redisplay optimizations could invoke us very far from
21027 PT, which will make the caller painfully slow. There should
21028 be no need to go too far beyond the window's bottom, as any
21029 such optimization will fail to show point anyway. */
21030 move_it_to (&tem_it
, to
, -1,
21031 tem_it
.last_visible_y
21032 + (SCROLL_LIMIT
+ 10) * FRAME_LINE_HEIGHT (tem_it
.f
),
21033 -1, MOVE_TO_POS
| MOVE_TO_Y
);
21034 unbind_to (count
, Qnil
);
21035 return IT_CHARPOS (*it
) <= PT
? -tem_it
.vpos
: tem_it
.vpos
;
21039 /* Produce the line-number glyphs for the current glyph_row. If
21040 IT->glyph_row is non-NULL, populate the row with the produced
21043 maybe_produce_line_number (struct it
*it
)
21045 ptrdiff_t last_line
= it
->lnum
;
21046 ptrdiff_t start_from
, bytepos
;
21047 ptrdiff_t this_line
;
21048 bool first_time
= false;
21049 ptrdiff_t beg_byte
= display_line_numbers_widen
? BEG_BYTE
: BEGV_BYTE
;
21050 ptrdiff_t z_byte
= display_line_numbers_widen
? Z_BYTE
: ZV_BYTE
;
21051 void *itdata
= bidi_shelve_cache ();
21053 if (EQ (Vdisplay_line_numbers
, Qvisual
))
21054 this_line
= display_count_lines_visually (it
);
21059 /* If possible, reuse data cached by line-number-mode. */
21060 if (it
->w
->base_line_number
> 0
21061 && it
->w
->base_line_pos
> 0
21062 && it
->w
->base_line_pos
<= IT_CHARPOS (*it
)
21063 /* line-number-mode always displays narrowed line
21064 numbers, so we cannot use its data if the user wants
21065 line numbers that disregard narrowing, or if the
21066 buffer's narrowing has just changed. */
21067 && !(display_line_numbers_widen
21068 && (BEG_BYTE
!= BEGV_BYTE
|| Z_BYTE
!= ZV_BYTE
))
21069 && !current_buffer
->clip_changed
)
21071 start_from
= CHAR_TO_BYTE (it
->w
->base_line_pos
);
21072 last_line
= it
->w
->base_line_number
- 1;
21075 start_from
= beg_byte
;
21076 if (!it
->lnum_bytepos
)
21080 start_from
= it
->lnum_bytepos
;
21082 /* Paranoia: what if someone changes the narrowing since the
21083 last time display_line was called? Shouldn't really happen,
21084 but who knows what some crazy Lisp invoked by :eval could do? */
21085 if (!(beg_byte
<= start_from
&& start_from
<= z_byte
))
21088 start_from
= beg_byte
;
21092 last_line
+ display_count_lines_logically (start_from
,
21094 IT_CHARPOS (*it
), &bytepos
);
21095 eassert (this_line
> 0 || (this_line
== 0 && start_from
== beg_byte
));
21096 eassert (bytepos
== IT_BYTEPOS (*it
));
21099 /* Record the line number information. */
21100 if (this_line
!= last_line
|| !it
->lnum_bytepos
)
21102 it
->lnum
= this_line
;
21103 it
->lnum_bytepos
= IT_BYTEPOS (*it
);
21106 /* Produce the glyphs for the line number. */
21108 char lnum_buf
[INT_STRLEN_BOUND (ptrdiff_t) + 1];
21109 bool beyond_zv
= IT_BYTEPOS (*it
) >= ZV_BYTE
? true : false;
21110 ptrdiff_t lnum_offset
= -1; /* to produce 1-based line numbers */
21111 int lnum_face_id
= merge_faces (it
->w
, Qline_number
, 0, DEFAULT_FACE_ID
);
21112 int current_lnum_face_id
21113 = merge_faces (it
->w
, Qline_number_current_line
, 0, DEFAULT_FACE_ID
);
21114 /* Compute point's line number if needed. */
21115 if ((EQ (Vdisplay_line_numbers
, Qrelative
)
21116 || EQ (Vdisplay_line_numbers
, Qvisual
)
21117 || lnum_face_id
!= current_lnum_face_id
)
21121 if (PT_BYTE
> it
->lnum_bytepos
&& !EQ (Vdisplay_line_numbers
, Qvisual
))
21123 this_line
+ display_count_lines_logically (it
->lnum_bytepos
, PT_BYTE
,
21126 it
->pt_lnum
= display_count_lines_logically (beg_byte
, PT_BYTE
, PT
,
21129 /* Compute the required width if needed. */
21130 if (!it
->lnum_width
)
21132 if (NATNUMP (Vdisplay_line_numbers_width
))
21133 it
->lnum_width
= XFASTINT (Vdisplay_line_numbers_width
);
21135 /* Max line number to be displayed cannot be more than the one
21136 corresponding to the last row of the desired matrix. */
21137 ptrdiff_t max_lnum
;
21139 if (NILP (Vdisplay_line_numbers_current_absolute
)
21140 && (EQ (Vdisplay_line_numbers
, Qrelative
)
21141 || EQ (Vdisplay_line_numbers
, Qvisual
)))
21142 /* We subtract one more because the current line is always
21143 zero in this mode. */
21144 max_lnum
= it
->w
->desired_matrix
->nrows
- 2;
21145 else if (EQ (Vdisplay_line_numbers
, Qvisual
))
21146 max_lnum
= it
->pt_lnum
+ it
->w
->desired_matrix
->nrows
- 1;
21148 max_lnum
= this_line
+ it
->w
->desired_matrix
->nrows
- 1 - it
->vpos
;
21149 max_lnum
= max (1, max_lnum
);
21150 it
->lnum_width
= max (it
->lnum_width
, log10 (max_lnum
) + 1);
21151 eassert (it
->lnum_width
> 0);
21153 if (EQ (Vdisplay_line_numbers
, Qrelative
))
21154 lnum_offset
= it
->pt_lnum
;
21155 else if (EQ (Vdisplay_line_numbers
, Qvisual
))
21158 /* Under 'relative', display the absolute line number for the
21159 current line, unless the user requests otherwise. */
21160 ptrdiff_t lnum_to_display
= eabs (this_line
- lnum_offset
);
21161 if ((EQ (Vdisplay_line_numbers
, Qrelative
)
21162 || EQ (Vdisplay_line_numbers
, Qvisual
))
21163 && lnum_to_display
== 0
21164 && !NILP (Vdisplay_line_numbers_current_absolute
))
21165 lnum_to_display
= it
->pt_lnum
+ 1;
21166 /* In L2R rows we need to append the blank separator, in R2L
21167 rows we need to prepend it. But this function is usually
21168 called when no display elements were produced from the
21169 following line, so the paragraph direction might be unknown.
21170 Therefore we cheat and add 2 blanks, one on either side. */
21171 pint2str (lnum_buf
, it
->lnum_width
+ 1, lnum_to_display
);
21172 strcat (lnum_buf
, " ");
21174 /* Setup for producing the glyphs. */
21175 init_iterator (&tem_it
, it
->w
, -1, -1, &scratch_glyph_row
,
21176 /* FIXME: Use specialized face. */
21178 scratch_glyph_row
.reversed_p
= false;
21179 scratch_glyph_row
.used
[TEXT_AREA
] = 0;
21180 SET_TEXT_POS (tem_it
.position
, 0, 0);
21181 tem_it
.avoid_cursor_p
= true;
21182 tem_it
.bidi_p
= true;
21183 tem_it
.bidi_it
.type
= WEAK_EN
;
21184 /* According to UAX#9, EN goes up 2 levels in L2R paragraph and
21185 1 level in R2L paragraphs. Emulate that, assuming we are in
21186 an L2R paragraph. */
21187 tem_it
.bidi_it
.resolved_level
= 2;
21189 /* Produce glyphs for the line number in a scratch glyph_row. */
21190 int n_glyphs_before
;
21191 for (const char *p
= lnum_buf
; *p
; p
++)
21193 /* For continuation lines and lines after ZV, instead of a line
21194 number, produce a blank prefix of the same width. Use the
21195 default face for the blank field beyond ZV. */
21197 tem_it
.face_id
= it
->base_face_id
;
21198 else if (lnum_face_id
!= current_lnum_face_id
21199 && (EQ (Vdisplay_line_numbers
, Qvisual
)
21201 : this_line
== it
->pt_lnum
))
21202 tem_it
.face_id
= current_lnum_face_id
;
21204 tem_it
.face_id
= lnum_face_id
;
21206 /* Don't display the same line number more than once. */
21207 || (!EQ (Vdisplay_line_numbers
, Qvisual
)
21208 && (it
->continuation_lines_width
> 0
21209 || (this_line
== last_line
&& !first_time
))))
21210 tem_it
.c
= tem_it
.char_to_display
= ' ';
21212 tem_it
.c
= tem_it
.char_to_display
= *p
;
21214 n_glyphs_before
= scratch_glyph_row
.used
[TEXT_AREA
];
21215 /* Make sure these glyphs will have a "position" of -1. */
21216 SET_TEXT_POS (tem_it
.position
, -1, -1);
21217 PRODUCE_GLYPHS (&tem_it
);
21219 /* Stop producing glyphs if we don't have enough space on
21220 this line. FIXME: should we refrain from producing the
21221 line number at all in that case? */
21222 if (tem_it
.current_x
> tem_it
.last_visible_x
)
21224 scratch_glyph_row
.used
[TEXT_AREA
] = n_glyphs_before
;
21229 /* Record the width in pixels we need for the line number display. */
21230 it
->lnum_pixel_width
= tem_it
.current_x
;
21231 /* Copy the produced glyphs into IT's glyph_row. */
21232 struct glyph
*g
= scratch_glyph_row
.glyphs
[TEXT_AREA
];
21233 struct glyph
*e
= g
+ scratch_glyph_row
.used
[TEXT_AREA
];
21234 struct glyph
*p
= it
->glyph_row
? it
->glyph_row
->glyphs
[TEXT_AREA
] : NULL
;
21235 short *u
= it
->glyph_row
? &it
->glyph_row
->used
[TEXT_AREA
] : NULL
;
21237 eassert (it
->glyph_row
== NULL
|| it
->glyph_row
->used
[TEXT_AREA
] == 0);
21239 for ( ; g
< e
; g
++)
21241 it
->current_x
+= g
->pixel_width
;
21242 /* The following is important when this function is called
21243 from move_it_in_display_line_to: HPOS is incremented only
21244 when we are in the visible portion of the glyph row. */
21245 if (it
->current_x
> it
->first_visible_x
)
21254 /* Update IT's metrics due to glyphs produced for line numbers. */
21257 struct glyph_row
*row
= it
->glyph_row
;
21259 it
->max_ascent
= max (row
->ascent
, tem_it
.max_ascent
);
21260 it
->max_descent
= max (row
->height
- row
->ascent
, tem_it
.max_descent
);
21261 it
->max_phys_ascent
= max (row
->phys_ascent
, tem_it
.max_phys_ascent
);
21262 it
->max_phys_descent
= max (row
->phys_height
- row
->phys_ascent
,
21263 tem_it
.max_phys_descent
);
21267 it
->max_ascent
= max (it
->max_ascent
, tem_it
.max_ascent
);
21268 it
->max_descent
= max (it
->max_descent
, tem_it
.max_descent
);
21269 it
->max_phys_ascent
= max (it
->max_phys_ascent
, tem_it
.max_phys_ascent
);
21270 it
->max_phys_descent
= max (it
->max_phys_descent
, tem_it
.max_phys_descent
);
21273 it
->line_number_produced_p
= true;
21275 bidi_unshelve_cache (itdata
, false);
21278 /* Return true if this glyph row needs a line number to be produced
21281 should_produce_line_number (struct it
*it
)
21283 if (NILP (Vdisplay_line_numbers
))
21286 /* Don't display line numbers in minibuffer windows. */
21287 if (MINI_WINDOW_P (it
->w
))
21290 #ifdef HAVE_WINDOW_SYSTEM
21291 /* Don't display line number in tooltip frames. */
21292 if (FRAME_TOOLTIP_P (XFRAME (WINDOW_FRAME (it
->w
))))
21296 /* If the character at current position has a non-nil special
21297 property, disable line numbers for this row. This is for
21298 packages such as company-mode, which need this for their tricky
21299 layout, where line numbers get in the way. */
21300 Lisp_Object val
= Fget_char_property (make_number (IT_CHARPOS (*it
)),
21301 Qdisplay_line_numbers_disable
,
21303 /* For ZV, we need to also look in empty overlays at that point,
21304 because get-char-property always returns nil for ZV, except if
21305 the property is in 'default-text-properties'. */
21306 if (NILP (val
) && IT_CHARPOS (*it
) >= ZV
)
21307 val
= disable_line_numbers_overlay_at_eob ();
21308 return NILP (val
) ? true : false;
21311 /* Return true if ROW has no glyphs except those inserted by the
21312 display engine. This is needed for indicate-empty-lines and
21313 similar features when the glyph row starts with glyphs which didn't
21314 come from buffer or string. */
21316 row_text_area_empty (struct glyph_row
*row
)
21318 if (!row
->reversed_p
)
21320 for (struct glyph
*g
= row
->glyphs
[TEXT_AREA
];
21321 g
< row
->glyphs
[TEXT_AREA
] + row
->used
[TEXT_AREA
];
21323 if (!NILP (g
->object
) || g
->charpos
> 0)
21328 for (struct glyph
*g
= row
->glyphs
[TEXT_AREA
] + row
->used
[TEXT_AREA
] - 1;
21329 g
> row
->glyphs
[TEXT_AREA
];
21331 if (!NILP ((g
- 1)->object
) || (g
- 1)->charpos
> 0)
21338 /* Construct the glyph row IT->glyph_row in the desired matrix of
21339 IT->w from text at the current position of IT. See dispextern.h
21340 for an overview of struct it. Value is true if
21341 IT->glyph_row displays text, as opposed to a line displaying ZV
21342 only. CURSOR_VPOS is the window-relative vertical position of
21343 the glyph row displaying the cursor, or -1 if unknown. */
21346 display_line (struct it
*it
, int cursor_vpos
)
21348 struct glyph_row
*row
= it
->glyph_row
;
21349 Lisp_Object overlay_arrow_string
;
21351 void *wrap_data
= NULL
;
21352 bool may_wrap
= false;
21354 int wrap_row_used
= -1;
21355 int wrap_row_ascent UNINIT
, wrap_row_height UNINIT
;
21356 int wrap_row_phys_ascent UNINIT
, wrap_row_phys_height UNINIT
;
21357 int wrap_row_extra_line_spacing UNINIT
;
21358 ptrdiff_t wrap_row_min_pos UNINIT
, wrap_row_min_bpos UNINIT
;
21359 ptrdiff_t wrap_row_max_pos UNINIT
, wrap_row_max_bpos UNINIT
;
21361 ptrdiff_t min_pos
= ZV
+ 1, max_pos
= 0;
21362 ptrdiff_t min_bpos UNINIT
, max_bpos UNINIT
;
21363 bool pending_handle_line_prefix
= false;
21364 int header_line
= window_wants_header_line (it
->w
);
21365 bool hscroll_this_line
= (cursor_vpos
>= 0
21366 && it
->vpos
== cursor_vpos
- header_line
21367 && hscrolling_current_line_p (it
->w
));
21368 int first_visible_x
= it
->first_visible_x
;
21369 int last_visible_x
= it
->last_visible_x
;
21372 /* We always start displaying at hpos zero even if hscrolled. */
21373 eassert (it
->hpos
== 0 && it
->current_x
== 0);
21375 if (MATRIX_ROW_VPOS (row
, it
->w
->desired_matrix
)
21376 >= it
->w
->desired_matrix
->nrows
)
21378 it
->w
->nrows_scale_factor
++;
21379 it
->f
->fonts_changed
= true;
21383 /* Clear the result glyph row and enable it. */
21384 prepare_desired_row (it
->w
, row
, false);
21386 row
->y
= it
->current_y
;
21387 row
->start
= it
->start
;
21388 row
->continuation_lines_width
= it
->continuation_lines_width
;
21389 row
->displays_text_p
= true;
21390 row
->starts_in_middle_of_char_p
= it
->starts_in_middle_of_char_p
;
21391 it
->starts_in_middle_of_char_p
= false;
21392 it
->tab_offset
= 0;
21393 it
->line_number_produced_p
= false;
21395 /* Arrange the overlays nicely for our purposes. Usually, we call
21396 display_line on only one line at a time, in which case this
21397 can't really hurt too much, or we call it on lines which appear
21398 one after another in the buffer, in which case all calls to
21399 recenter_overlay_lists but the first will be pretty cheap. */
21400 recenter_overlay_lists (current_buffer
, IT_CHARPOS (*it
));
21402 /* If we are going to display the cursor's line, account for the
21403 hscroll of that line. We subtract the window's min_hscroll,
21404 because that was already accounted for in init_iterator. */
21405 if (hscroll_this_line
)
21407 (window_hscroll_limited (it
->w
, it
->f
) - it
->w
->min_hscroll
)
21408 * FRAME_COLUMN_WIDTH (it
->f
);
21410 bool line_number_needed
= should_produce_line_number (it
);
21412 /* Move over display elements that are not visible because we are
21413 hscrolled. This may stop at an x-position < first_visible_x
21414 if the first glyph is partially visible or if we hit a line end. */
21415 if (it
->current_x
< it
->first_visible_x
+ x_incr
)
21417 enum move_it_result move_result
;
21419 this_line_min_pos
= row
->start
.pos
;
21420 if (hscroll_this_line
)
21422 it
->first_visible_x
+= x_incr
;
21423 it
->last_visible_x
+= x_incr
;
21425 move_result
= move_it_in_display_line_to (it
, ZV
, it
->first_visible_x
,
21426 MOVE_TO_POS
| MOVE_TO_X
);
21427 /* If we are under a large hscroll, move_it_in_display_line_to
21428 could hit the end of the line without reaching
21429 first_visible_x. Pretend that we did reach it. This is
21430 especially important on a TTY, where we will call
21431 extend_face_to_end_of_line, which needs to know how many
21432 blank glyphs to produce. */
21433 if (it
->current_x
< it
->first_visible_x
21434 && (move_result
== MOVE_NEWLINE_OR_CR
21435 || move_result
== MOVE_POS_MATCH_OR_ZV
))
21436 it
->current_x
= it
->first_visible_x
;
21438 /* In case move_it_in_display_line_to above "produced" the line
21440 it
->line_number_produced_p
= false;
21442 /* Record the smallest positions seen while we moved over
21443 display elements that are not visible. This is needed by
21444 redisplay_internal for optimizing the case where the cursor
21445 stays inside the same line. The rest of this function only
21446 considers positions that are actually displayed, so
21447 RECORD_MAX_MIN_POS will not otherwise record positions that
21448 are hscrolled to the left of the left edge of the window. */
21449 min_pos
= CHARPOS (this_line_min_pos
);
21450 min_bpos
= BYTEPOS (this_line_min_pos
);
21452 /* Produce line number, if needed. */
21453 if (line_number_needed
)
21454 maybe_produce_line_number (it
);
21456 else if (it
->area
== TEXT_AREA
)
21458 /* Line numbers should precede the line-prefix or wrap-prefix. */
21459 if (line_number_needed
)
21460 maybe_produce_line_number (it
);
21462 /* We only do this when not calling move_it_in_display_line_to
21463 above, because that function calls itself handle_line_prefix. */
21464 handle_line_prefix (it
);
21468 /* Line-prefix and wrap-prefix are always displayed in the text
21469 area. But if this is the first call to display_line after
21470 init_iterator, the iterator might have been set up to write
21471 into a marginal area, e.g. if the line begins with some
21472 display property that writes to the margins. So we need to
21473 wait with the call to handle_line_prefix until whatever
21474 writes to the margin has done its job. */
21475 pending_handle_line_prefix
= true;
21478 /* Get the initial row height. This is either the height of the
21479 text hscrolled, if there is any, or zero. */
21480 row
->ascent
= it
->max_ascent
;
21481 row
->height
= it
->max_ascent
+ it
->max_descent
;
21482 row
->phys_ascent
= it
->max_phys_ascent
;
21483 row
->phys_height
= it
->max_phys_ascent
+ it
->max_phys_descent
;
21484 row
->extra_line_spacing
= it
->max_extra_line_spacing
;
21486 /* Utility macro to record max and min buffer positions seen until now. */
21487 #define RECORD_MAX_MIN_POS(IT) \
21490 bool composition_p \
21491 = !STRINGP ((IT)->string) && ((IT)->what == IT_COMPOSITION); \
21492 ptrdiff_t current_pos = \
21493 composition_p ? (IT)->cmp_it.charpos \
21494 : IT_CHARPOS (*(IT)); \
21495 ptrdiff_t current_bpos = \
21496 composition_p ? CHAR_TO_BYTE (current_pos) \
21497 : IT_BYTEPOS (*(IT)); \
21498 if (current_pos < min_pos) \
21500 min_pos = current_pos; \
21501 min_bpos = current_bpos; \
21503 if (IT_CHARPOS (*it) > max_pos) \
21505 max_pos = IT_CHARPOS (*it); \
21506 max_bpos = IT_BYTEPOS (*it); \
21511 /* Loop generating characters. The loop is left with IT on the next
21512 character to display. */
21515 int n_glyphs_before
, hpos_before
, x_before
;
21517 int ascent
= 0, descent
= 0, phys_ascent
= 0, phys_descent
= 0;
21519 /* Retrieve the next thing to display. Value is false if end of
21521 if (!get_next_display_element (it
))
21523 bool row_has_glyphs
= false;
21524 /* Maybe add a space at the end of this line that is used to
21525 display the cursor there under X. Set the charpos of the
21526 first glyph of blank lines not corresponding to any text
21528 if (IT_OVERFLOW_NEWLINE_INTO_FRINGE (it
))
21529 row
->exact_window_width_line_p
= true;
21530 else if ((append_space_for_newline (it
, true)
21531 && row
->used
[TEXT_AREA
] == 1)
21532 || row
->used
[TEXT_AREA
] == 0
21533 || (row_has_glyphs
= row_text_area_empty (row
)))
21535 row
->glyphs
[TEXT_AREA
]->charpos
= -1;
21536 /* Don't reset the displays_text_p flag if we are
21537 displaying line numbers or line-prefix. */
21538 if (!row_has_glyphs
)
21539 row
->displays_text_p
= false;
21541 if (!NILP (BVAR (XBUFFER (it
->w
->contents
), indicate_empty_lines
))
21542 && (!MINI_WINDOW_P (it
->w
)))
21543 row
->indicate_empty_line_p
= true;
21546 it
->continuation_lines_width
= 0;
21547 /* Reset those iterator values set from display property
21548 values. This is for the case when the display property
21549 ends at ZV, and is not a replacing property, so pop_it is
21551 it
->font_height
= Qnil
;
21553 row
->ends_at_zv_p
= true;
21554 /* A row that displays right-to-left text must always have
21555 its last face extended all the way to the end of line,
21556 even if this row ends in ZV, because we still write to
21557 the screen left to right. We also need to extend the
21558 last face if the default face is remapped to some
21559 different face, otherwise the functions that clear
21560 portions of the screen will clear with the default face's
21561 background color. */
21562 if (row
->reversed_p
21563 || lookup_basic_face (it
->w
, it
->f
, DEFAULT_FACE_ID
)
21564 != DEFAULT_FACE_ID
)
21565 extend_face_to_end_of_line (it
);
21569 /* Now, get the metrics of what we want to display. This also
21570 generates glyphs in `row' (which is IT->glyph_row). */
21571 n_glyphs_before
= row
->used
[TEXT_AREA
];
21574 /* Remember the line height so far in case the next element doesn't
21575 fit on the line. */
21576 if (it
->line_wrap
!= TRUNCATE
)
21578 ascent
= it
->max_ascent
;
21579 descent
= it
->max_descent
;
21580 phys_ascent
= it
->max_phys_ascent
;
21581 phys_descent
= it
->max_phys_descent
;
21583 if (it
->line_wrap
== WORD_WRAP
&& it
->area
== TEXT_AREA
)
21585 if (IT_DISPLAYING_WHITESPACE (it
))
21589 SAVE_IT (wrap_it
, *it
, wrap_data
);
21591 wrap_row_used
= row
->used
[TEXT_AREA
];
21592 wrap_row_ascent
= row
->ascent
;
21593 wrap_row_height
= row
->height
;
21594 wrap_row_phys_ascent
= row
->phys_ascent
;
21595 wrap_row_phys_height
= row
->phys_height
;
21596 wrap_row_extra_line_spacing
= row
->extra_line_spacing
;
21597 wrap_row_min_pos
= min_pos
;
21598 wrap_row_min_bpos
= min_bpos
;
21599 wrap_row_max_pos
= max_pos
;
21600 wrap_row_max_bpos
= max_bpos
;
21606 PRODUCE_GLYPHS (it
);
21608 /* If this display element was in marginal areas, continue with
21610 if (it
->area
!= TEXT_AREA
)
21612 row
->ascent
= max (row
->ascent
, it
->max_ascent
);
21613 row
->height
= max (row
->height
, it
->max_ascent
+ it
->max_descent
);
21614 row
->phys_ascent
= max (row
->phys_ascent
, it
->max_phys_ascent
);
21615 row
->phys_height
= max (row
->phys_height
,
21616 it
->max_phys_ascent
+ it
->max_phys_descent
);
21617 row
->extra_line_spacing
= max (row
->extra_line_spacing
,
21618 it
->max_extra_line_spacing
);
21619 set_iterator_to_next (it
, true);
21620 /* If we didn't handle the line/wrap prefix above, and the
21621 call to set_iterator_to_next just switched to TEXT_AREA,
21622 process the prefix now. */
21623 if (it
->area
== TEXT_AREA
&& pending_handle_line_prefix
)
21625 /* Line numbers should precede the line-prefix or wrap-prefix. */
21626 if (line_number_needed
)
21627 maybe_produce_line_number (it
);
21629 pending_handle_line_prefix
= false;
21630 handle_line_prefix (it
);
21635 /* Does the display element fit on the line? If we truncate
21636 lines, we should draw past the right edge of the window. If
21637 we don't truncate, we want to stop so that we can display the
21638 continuation glyph before the right margin. If lines are
21639 continued, there are two possible strategies for characters
21640 resulting in more than 1 glyph (e.g. tabs): Display as many
21641 glyphs as possible in this line and leave the rest for the
21642 continuation line, or display the whole element in the next
21643 line. Original redisplay did the former, so we do it also. */
21644 nglyphs
= row
->used
[TEXT_AREA
] - n_glyphs_before
;
21645 hpos_before
= it
->hpos
;
21648 if (/* Not a newline. */
21650 /* Glyphs produced fit entirely in the line. */
21651 && it
->current_x
< it
->last_visible_x
)
21653 it
->hpos
+= nglyphs
;
21654 row
->ascent
= max (row
->ascent
, it
->max_ascent
);
21655 row
->height
= max (row
->height
, it
->max_ascent
+ it
->max_descent
);
21656 row
->phys_ascent
= max (row
->phys_ascent
, it
->max_phys_ascent
);
21657 row
->phys_height
= max (row
->phys_height
,
21658 it
->max_phys_ascent
+ it
->max_phys_descent
);
21659 row
->extra_line_spacing
= max (row
->extra_line_spacing
,
21660 it
->max_extra_line_spacing
);
21661 if (it
->current_x
- it
->pixel_width
< it
->first_visible_x
21662 /* When line numbers are displayed, row->x should not be
21663 offset, as the first glyph after the line number can
21664 never be partially visible. */
21665 && !line_number_needed
21666 /* In R2L rows, we arrange in extend_face_to_end_of_line
21667 to add a right offset to the line, by a suitable
21668 change to the stretch glyph that is the leftmost
21669 glyph of the line. */
21670 && !row
->reversed_p
)
21671 row
->x
= x
- it
->first_visible_x
;
21672 /* Record the maximum and minimum buffer positions seen so
21673 far in glyphs that will be displayed by this row. */
21675 RECORD_MAX_MIN_POS (it
);
21680 struct glyph
*glyph
;
21682 for (i
= 0; i
< nglyphs
; ++i
, x
= new_x
)
21684 /* Identify the glyphs added by the last call to
21685 PRODUCE_GLYPHS. In R2L rows, they are prepended to
21686 the previous glyphs. */
21687 if (!row
->reversed_p
)
21688 glyph
= row
->glyphs
[TEXT_AREA
] + n_glyphs_before
+ i
;
21690 glyph
= row
->glyphs
[TEXT_AREA
] + nglyphs
- 1 - i
;
21691 new_x
= x
+ glyph
->pixel_width
;
21693 if (/* Lines are continued. */
21694 it
->line_wrap
!= TRUNCATE
21695 && (/* Glyph doesn't fit on the line. */
21696 new_x
> it
->last_visible_x
21697 /* Or it fits exactly on a window system frame. */
21698 || (new_x
== it
->last_visible_x
21699 && FRAME_WINDOW_P (it
->f
)
21700 && (row
->reversed_p
21701 ? WINDOW_LEFT_FRINGE_WIDTH (it
->w
)
21702 : WINDOW_RIGHT_FRINGE_WIDTH (it
->w
)))))
21704 /* End of a continued line. */
21707 || (new_x
== it
->last_visible_x
21708 && FRAME_WINDOW_P (it
->f
)
21709 && (row
->reversed_p
21710 ? WINDOW_LEFT_FRINGE_WIDTH (it
->w
)
21711 : WINDOW_RIGHT_FRINGE_WIDTH (it
->w
))))
21713 /* Current glyph is the only one on the line or
21714 fits exactly on the line. We must continue
21715 the line because we can't draw the cursor
21716 after the glyph. */
21717 row
->continued_p
= true;
21718 it
->current_x
= new_x
;
21719 it
->continuation_lines_width
+= new_x
;
21721 if (i
== nglyphs
- 1)
21723 /* If line-wrap is on, check if a previous
21724 wrap point was found. */
21725 if (!IT_OVERFLOW_NEWLINE_INTO_FRINGE (it
)
21726 && wrap_row_used
> 0
21727 /* Even if there is a previous wrap
21728 point, continue the line here as
21729 usual, if (i) the previous character
21730 was a space or tab AND (ii) the
21731 current character is not. */
21733 || IT_DISPLAYING_WHITESPACE (it
)))
21736 /* Record the maximum and minimum buffer
21737 positions seen so far in glyphs that will be
21738 displayed by this row. */
21740 RECORD_MAX_MIN_POS (it
);
21741 set_iterator_to_next (it
, true);
21742 if (IT_OVERFLOW_NEWLINE_INTO_FRINGE (it
))
21744 if (!get_next_display_element (it
))
21746 row
->exact_window_width_line_p
= true;
21747 it
->continuation_lines_width
= 0;
21748 it
->font_height
= Qnil
;
21750 row
->continued_p
= false;
21751 row
->ends_at_zv_p
= true;
21753 else if (ITERATOR_AT_END_OF_LINE_P (it
))
21755 row
->continued_p
= false;
21756 row
->exact_window_width_line_p
= true;
21758 /* If line-wrap is on, check if a
21759 previous wrap point was found. */
21760 else if (wrap_row_used
> 0
21761 /* Even if there is a previous wrap
21762 point, continue the line here as
21763 usual, if (i) the previous character
21764 was a space or tab AND (ii) the
21765 current character is not. */
21767 || IT_DISPLAYING_WHITESPACE (it
)))
21772 else if (it
->bidi_p
)
21773 RECORD_MAX_MIN_POS (it
);
21774 if (WINDOW_LEFT_MARGIN_WIDTH (it
->w
) > 0
21775 || WINDOW_RIGHT_MARGIN_WIDTH (it
->w
) > 0)
21776 extend_face_to_end_of_line (it
);
21778 else if (CHAR_GLYPH_PADDING_P (*glyph
)
21779 && !FRAME_WINDOW_P (it
->f
))
21781 /* A padding glyph that doesn't fit on this line.
21782 This means the whole character doesn't fit
21784 if (row
->reversed_p
)
21785 unproduce_glyphs (it
, row
->used
[TEXT_AREA
]
21786 - n_glyphs_before
);
21787 row
->used
[TEXT_AREA
] = n_glyphs_before
;
21789 /* Fill the rest of the row with continuation
21790 glyphs like in 20.x. */
21791 while (row
->glyphs
[TEXT_AREA
] + row
->used
[TEXT_AREA
]
21792 < row
->glyphs
[1 + TEXT_AREA
])
21793 produce_special_glyphs (it
, IT_CONTINUATION
);
21795 row
->continued_p
= true;
21796 it
->current_x
= x_before
;
21797 it
->continuation_lines_width
+= x_before
;
21799 /* Restore the height to what it was before the
21800 element not fitting on the line. */
21801 it
->max_ascent
= ascent
;
21802 it
->max_descent
= descent
;
21803 it
->max_phys_ascent
= phys_ascent
;
21804 it
->max_phys_descent
= phys_descent
;
21805 if (WINDOW_LEFT_MARGIN_WIDTH (it
->w
) > 0
21806 || WINDOW_RIGHT_MARGIN_WIDTH (it
->w
) > 0)
21807 extend_face_to_end_of_line (it
);
21809 else if (wrap_row_used
> 0)
21812 if (row
->reversed_p
)
21813 unproduce_glyphs (it
,
21814 row
->used
[TEXT_AREA
] - wrap_row_used
);
21815 RESTORE_IT (it
, &wrap_it
, wrap_data
);
21816 it
->continuation_lines_width
+= wrap_x
;
21817 row
->used
[TEXT_AREA
] = wrap_row_used
;
21818 row
->ascent
= wrap_row_ascent
;
21819 row
->height
= wrap_row_height
;
21820 row
->phys_ascent
= wrap_row_phys_ascent
;
21821 row
->phys_height
= wrap_row_phys_height
;
21822 row
->extra_line_spacing
= wrap_row_extra_line_spacing
;
21823 min_pos
= wrap_row_min_pos
;
21824 min_bpos
= wrap_row_min_bpos
;
21825 max_pos
= wrap_row_max_pos
;
21826 max_bpos
= wrap_row_max_bpos
;
21827 row
->continued_p
= true;
21828 row
->ends_at_zv_p
= false;
21829 row
->exact_window_width_line_p
= false;
21831 /* Make sure that a non-default face is extended
21832 up to the right margin of the window. */
21833 extend_face_to_end_of_line (it
);
21835 else if ((it
->what
== IT_CHARACTER
21836 || it
->what
== IT_STRETCH
21837 || it
->what
== IT_COMPOSITION
)
21838 && it
->c
== '\t' && FRAME_WINDOW_P (it
->f
))
21840 /* A TAB that extends past the right edge of the
21841 window. This produces a single glyph on
21842 window system frames. We leave the glyph in
21843 this row and let it fill the row, but don't
21844 consume the TAB. */
21845 if ((row
->reversed_p
21846 ? WINDOW_LEFT_FRINGE_WIDTH (it
->w
)
21847 : WINDOW_RIGHT_FRINGE_WIDTH (it
->w
)) == 0)
21848 produce_special_glyphs (it
, IT_CONTINUATION
);
21849 it
->continuation_lines_width
+= it
->last_visible_x
;
21850 row
->ends_in_middle_of_char_p
= true;
21851 row
->continued_p
= true;
21852 glyph
->pixel_width
= it
->last_visible_x
- x
;
21853 it
->starts_in_middle_of_char_p
= true;
21854 if (WINDOW_LEFT_MARGIN_WIDTH (it
->w
) > 0
21855 || WINDOW_RIGHT_MARGIN_WIDTH (it
->w
) > 0)
21856 extend_face_to_end_of_line (it
);
21860 /* Something other than a TAB that draws past
21861 the right edge of the window. Restore
21862 positions to values before the element. */
21863 if (row
->reversed_p
)
21864 unproduce_glyphs (it
, row
->used
[TEXT_AREA
]
21865 - (n_glyphs_before
+ i
));
21866 row
->used
[TEXT_AREA
] = n_glyphs_before
+ i
;
21868 /* Display continuation glyphs. */
21869 it
->current_x
= x_before
;
21870 it
->continuation_lines_width
+= x
;
21871 if (!FRAME_WINDOW_P (it
->f
)
21872 || (row
->reversed_p
21873 ? WINDOW_LEFT_FRINGE_WIDTH (it
->w
)
21874 : WINDOW_RIGHT_FRINGE_WIDTH (it
->w
)) == 0)
21875 produce_special_glyphs (it
, IT_CONTINUATION
);
21876 row
->continued_p
= true;
21878 extend_face_to_end_of_line (it
);
21880 if (nglyphs
> 1 && i
> 0)
21882 row
->ends_in_middle_of_char_p
= true;
21883 it
->starts_in_middle_of_char_p
= true;
21886 /* Restore the height to what it was before the
21887 element not fitting on the line. */
21888 it
->max_ascent
= ascent
;
21889 it
->max_descent
= descent
;
21890 it
->max_phys_ascent
= phys_ascent
;
21891 it
->max_phys_descent
= phys_descent
;
21896 else if (new_x
> it
->first_visible_x
)
21898 /* Increment number of glyphs actually displayed. */
21901 /* Record the maximum and minimum buffer positions
21902 seen so far in glyphs that will be displayed by
21905 RECORD_MAX_MIN_POS (it
);
21907 if (x
< it
->first_visible_x
&& !row
->reversed_p
21908 && !line_number_needed
)
21909 /* Glyph is partially visible, i.e. row starts at
21910 negative X position. Don't do that in R2L
21911 rows, where we arrange to add a right offset to
21912 the line in extend_face_to_end_of_line, by a
21913 suitable change to the stretch glyph that is
21914 the leftmost glyph of the line. */
21915 row
->x
= x
- it
->first_visible_x
;
21916 /* When the last glyph of an R2L row only fits
21917 partially on the line, we need to set row->x to a
21918 negative offset, so that the leftmost glyph is
21919 the one that is partially visible. But if we are
21920 going to produce the truncation glyph, this will
21921 be taken care of in produce_special_glyphs. */
21922 if (row
->reversed_p
21923 && new_x
> it
->last_visible_x
21924 && !line_number_needed
21925 && !(it
->line_wrap
== TRUNCATE
21926 && WINDOW_LEFT_FRINGE_WIDTH (it
->w
) == 0))
21928 eassert (FRAME_WINDOW_P (it
->f
));
21929 row
->x
= it
->last_visible_x
- new_x
;
21934 /* Glyph is completely off the left margin of the
21935 window. This should not happen because of the
21936 move_it_in_display_line at the start of this
21937 function, unless the text display area of the
21938 window is empty. */
21939 eassert (it
->first_visible_x
<= it
->last_visible_x
);
21942 /* Even if this display element produced no glyphs at all,
21943 we want to record its position. */
21944 if (it
->bidi_p
&& nglyphs
== 0)
21945 RECORD_MAX_MIN_POS (it
);
21947 row
->ascent
= max (row
->ascent
, it
->max_ascent
);
21948 row
->height
= max (row
->height
, it
->max_ascent
+ it
->max_descent
);
21949 row
->phys_ascent
= max (row
->phys_ascent
, it
->max_phys_ascent
);
21950 row
->phys_height
= max (row
->phys_height
,
21951 it
->max_phys_ascent
+ it
->max_phys_descent
);
21952 row
->extra_line_spacing
= max (row
->extra_line_spacing
,
21953 it
->max_extra_line_spacing
);
21955 /* End of this display line if row is continued. */
21956 if (row
->continued_p
|| row
->ends_at_zv_p
)
21961 /* Is this a line end? If yes, we're also done, after making
21962 sure that a non-default face is extended up to the right
21963 margin of the window. */
21964 if (ITERATOR_AT_END_OF_LINE_P (it
))
21966 int used_before
= row
->used
[TEXT_AREA
];
21968 row
->ends_in_newline_from_string_p
= STRINGP (it
->object
);
21970 /* Add a space at the end of the line that is used to
21971 display the cursor there. */
21972 if (!IT_OVERFLOW_NEWLINE_INTO_FRINGE (it
))
21973 append_space_for_newline (it
, false);
21975 /* Extend the face to the end of the line. */
21976 extend_face_to_end_of_line (it
);
21978 /* Make sure we have the position. */
21979 if (used_before
== 0)
21980 row
->glyphs
[TEXT_AREA
]->charpos
= CHARPOS (it
->position
);
21982 /* Record the position of the newline, for use in
21984 it
->eol_pos
= it
->current
.pos
;
21986 /* Consume the line end. This skips over invisible lines. */
21987 set_iterator_to_next (it
, true);
21988 it
->continuation_lines_width
= 0;
21992 /* Detect overly-wide wrap-prefixes made of (space ...) display
21993 properties. When such a wrap prefix reaches past the right
21994 margin of the window, we need to avoid the call to
21995 set_iterator_to_next below, so that it->line_wrap is left at
21996 its TRUNCATE value wisely set by handle_line_prefix.
21997 Otherwise, set_iterator_to_next will pop the iterator stack,
21998 restore it->line_wrap, and redisplay might infloop. */
21999 bool overwide_wrap_prefix
=
22000 CONSP (it
->object
) && EQ (XCAR (it
->object
), Qspace
)
22001 && it
->sp
> 0 && it
->method
== GET_FROM_STRETCH
22002 && it
->current_x
>= it
->last_visible_x
22003 && it
->continuation_lines_width
> 0
22004 && it
->line_wrap
== TRUNCATE
&& it
->stack
[0].line_wrap
!= TRUNCATE
;
22006 /* Proceed with next display element. Note that this skips
22007 over lines invisible because of selective display. */
22008 if (!overwide_wrap_prefix
)
22009 set_iterator_to_next (it
, true);
22011 /* If we truncate lines, we are done when the last displayed
22012 glyphs reach past the right margin of the window. */
22013 if (it
->line_wrap
== TRUNCATE
22014 && ((FRAME_WINDOW_P (it
->f
)
22015 /* Images are preprocessed in produce_image_glyph such
22016 that they are cropped at the right edge of the
22017 window, so an image glyph will always end exactly at
22018 last_visible_x, even if there's no right fringe. */
22019 && ((row
->reversed_p
22020 ? WINDOW_LEFT_FRINGE_WIDTH (it
->w
)
22021 : WINDOW_RIGHT_FRINGE_WIDTH (it
->w
))
22022 || it
->what
== IT_IMAGE
))
22023 ? (it
->current_x
>= it
->last_visible_x
)
22024 : (it
->current_x
> it
->last_visible_x
)))
22026 /* Maybe add truncation glyphs. */
22027 if (!FRAME_WINDOW_P (it
->f
)
22028 || (row
->reversed_p
22029 ? WINDOW_LEFT_FRINGE_WIDTH (it
->w
)
22030 : WINDOW_RIGHT_FRINGE_WIDTH (it
->w
)) == 0)
22034 if (!row
->reversed_p
)
22036 for (i
= row
->used
[TEXT_AREA
] - 1; i
> 0; --i
)
22037 if (!CHAR_GLYPH_PADDING_P (row
->glyphs
[TEXT_AREA
][i
]))
22042 for (i
= 0; i
< row
->used
[TEXT_AREA
]; i
++)
22043 if (!CHAR_GLYPH_PADDING_P (row
->glyphs
[TEXT_AREA
][i
]))
22045 /* Remove any padding glyphs at the front of ROW, to
22046 make room for the truncation glyphs we will be
22047 adding below. The loop below always inserts at
22048 least one truncation glyph, so also remove the
22049 last glyph added to ROW. */
22050 unproduce_glyphs (it
, i
+ 1);
22051 /* Adjust i for the loop below. */
22052 i
= row
->used
[TEXT_AREA
] - (i
+ 1);
22055 /* produce_special_glyphs overwrites the last glyph, so
22056 we don't want that if we want to keep that last
22057 glyph, which means it's an image. */
22058 if (it
->current_x
> it
->last_visible_x
)
22060 it
->current_x
= x_before
;
22061 if (!FRAME_WINDOW_P (it
->f
))
22063 for (n
= row
->used
[TEXT_AREA
]; i
< n
; ++i
)
22065 row
->used
[TEXT_AREA
] = i
;
22066 produce_special_glyphs (it
, IT_TRUNCATION
);
22071 row
->used
[TEXT_AREA
] = i
;
22072 produce_special_glyphs (it
, IT_TRUNCATION
);
22074 it
->hpos
= hpos_before
;
22077 else if (IT_OVERFLOW_NEWLINE_INTO_FRINGE (it
))
22079 /* Don't truncate if we can overflow newline into fringe. */
22080 if (!get_next_display_element (it
))
22082 it
->continuation_lines_width
= 0;
22083 it
->font_height
= Qnil
;
22085 row
->ends_at_zv_p
= true;
22086 row
->exact_window_width_line_p
= true;
22089 if (ITERATOR_AT_END_OF_LINE_P (it
))
22091 row
->exact_window_width_line_p
= true;
22092 goto at_end_of_line
;
22094 it
->current_x
= x_before
;
22095 it
->hpos
= hpos_before
;
22098 row
->truncated_on_right_p
= true;
22099 it
->continuation_lines_width
= 0;
22100 reseat_at_next_visible_line_start (it
, false);
22101 /* We insist below that IT's position be at ZV because in
22102 bidi-reordered lines the character at visible line start
22103 might not be the character that follows the newline in
22104 the logical order. */
22105 if (IT_BYTEPOS (*it
) > BEG_BYTE
)
22106 row
->ends_at_zv_p
=
22107 IT_BYTEPOS (*it
) >= ZV_BYTE
&& FETCH_BYTE (ZV_BYTE
- 1) != '\n';
22109 row
->ends_at_zv_p
= false;
22115 bidi_unshelve_cache (wrap_data
, true);
22117 /* If line is not empty and hscrolled, maybe insert truncation glyphs
22118 at the left window margin. */
22119 if (it
->first_visible_x
22120 && IT_CHARPOS (*it
) != CHARPOS (row
->start
.pos
))
22122 if (!FRAME_WINDOW_P (it
->f
)
22123 || (((row
->reversed_p
22124 ? WINDOW_RIGHT_FRINGE_WIDTH (it
->w
)
22125 : WINDOW_LEFT_FRINGE_WIDTH (it
->w
)) == 0)
22126 /* Don't let insert_left_trunc_glyphs overwrite the
22127 first glyph of the row if it is an image. */
22128 && row
->glyphs
[TEXT_AREA
]->type
!= IMAGE_GLYPH
))
22129 insert_left_trunc_glyphs (it
);
22130 row
->truncated_on_left_p
= true;
22133 /* Remember the position at which this line ends.
22135 BIDI Note: any code that needs MATRIX_ROW_START/END_CHARPOS
22136 cannot be before the call to find_row_edges below, since that is
22137 where these positions are determined. */
22138 row
->end
= it
->current
;
22141 row
->minpos
= row
->start
.pos
;
22142 row
->maxpos
= row
->end
.pos
;
22146 /* ROW->minpos and ROW->maxpos must be the smallest and
22147 `1 + the largest' buffer positions in ROW. But if ROW was
22148 bidi-reordered, these two positions can be anywhere in the
22149 row, so we must determine them now. */
22150 find_row_edges (it
, row
, min_pos
, min_bpos
, max_pos
, max_bpos
);
22153 /* If the start of this line is the overlay arrow-position, then
22154 mark this glyph row as the one containing the overlay arrow.
22155 This is clearly a mess with variable size fonts. It would be
22156 better to let it be displayed like cursors under X. */
22157 if ((MATRIX_ROW_DISPLAYS_TEXT_P (row
) || !overlay_arrow_seen
)
22158 && (overlay_arrow_string
= overlay_arrow_at_row (it
, row
),
22159 !NILP (overlay_arrow_string
)))
22161 /* Overlay arrow in window redisplay is a fringe bitmap. */
22162 if (STRINGP (overlay_arrow_string
))
22164 struct glyph_row
*arrow_row
22165 = get_overlay_arrow_glyph_row (it
->w
, overlay_arrow_string
);
22166 struct glyph
*glyph
= arrow_row
->glyphs
[TEXT_AREA
];
22167 struct glyph
*arrow_end
= glyph
+ arrow_row
->used
[TEXT_AREA
];
22168 struct glyph
*p
= row
->glyphs
[TEXT_AREA
];
22169 struct glyph
*p2
, *end
;
22171 /* Copy the arrow glyphs. */
22172 while (glyph
< arrow_end
)
22175 /* Throw away padding glyphs. */
22177 end
= row
->glyphs
[TEXT_AREA
] + row
->used
[TEXT_AREA
];
22178 while (p2
< end
&& CHAR_GLYPH_PADDING_P (*p2
))
22184 row
->used
[TEXT_AREA
] = p2
- row
->glyphs
[TEXT_AREA
];
22189 eassert (INTEGERP (overlay_arrow_string
));
22190 row
->overlay_arrow_bitmap
= XINT (overlay_arrow_string
);
22192 overlay_arrow_seen
= true;
22195 /* Highlight trailing whitespace. */
22196 if (!NILP (Vshow_trailing_whitespace
))
22197 highlight_trailing_whitespace (it
);
22199 /* Compute pixel dimensions of this line. */
22200 compute_line_metrics (it
);
22202 /* Implementation note: No changes in the glyphs of ROW or in their
22203 faces can be done past this point, because compute_line_metrics
22204 computes ROW's hash value and stores it within the glyph_row
22207 /* Record whether this row ends inside an ellipsis. */
22208 row
->ends_in_ellipsis_p
22209 = (it
->method
== GET_FROM_DISPLAY_VECTOR
22210 && it
->ellipsis_p
);
22212 /* Save fringe bitmaps in this row. */
22213 row
->left_user_fringe_bitmap
= it
->left_user_fringe_bitmap
;
22214 row
->left_user_fringe_face_id
= it
->left_user_fringe_face_id
;
22215 row
->right_user_fringe_bitmap
= it
->right_user_fringe_bitmap
;
22216 row
->right_user_fringe_face_id
= it
->right_user_fringe_face_id
;
22218 it
->left_user_fringe_bitmap
= 0;
22219 it
->left_user_fringe_face_id
= 0;
22220 it
->right_user_fringe_bitmap
= 0;
22221 it
->right_user_fringe_face_id
= 0;
22223 /* Maybe set the cursor. */
22224 cvpos
= it
->w
->cursor
.vpos
;
22226 /* In bidi-reordered rows, keep checking for proper cursor
22227 position even if one has been found already, because buffer
22228 positions in such rows change non-linearly with ROW->VPOS,
22229 when a line is continued. One exception: when we are at ZV,
22230 display cursor on the first suitable glyph row, since all
22231 the empty rows after that also have their position set to ZV. */
22232 /* FIXME: Revisit this when glyph ``spilling'' in continuation
22233 lines' rows is implemented for bidi-reordered rows. */
22235 && !MATRIX_ROW (it
->w
->desired_matrix
, cvpos
)->ends_at_zv_p
))
22236 && PT
>= MATRIX_ROW_START_CHARPOS (row
)
22237 && PT
<= MATRIX_ROW_END_CHARPOS (row
)
22238 && cursor_row_p (row
))
22239 set_cursor_from_row (it
->w
, row
, it
->w
->desired_matrix
, 0, 0, 0, 0);
22241 /* Prepare for the next line. This line starts horizontally at (X
22242 HPOS) = (0 0). Vertical positions are incremented. As a
22243 convenience for the caller, IT->glyph_row is set to the next
22245 it
->current_x
= it
->hpos
= 0;
22246 it
->current_y
+= row
->height
;
22247 /* Restore the first and last visible X if we adjusted them for
22248 current-line hscrolling. */
22249 if (hscroll_this_line
)
22251 it
->first_visible_x
= first_visible_x
;
22252 it
->last_visible_x
= last_visible_x
;
22254 SET_TEXT_POS (it
->eol_pos
, 0, 0);
22257 /* The next row should by default use the same value of the
22258 reversed_p flag as this one. set_iterator_to_next decides when
22259 it's a new paragraph, and PRODUCE_GLYPHS recomputes the value of
22260 the flag accordingly. */
22261 if (it
->glyph_row
< MATRIX_BOTTOM_TEXT_ROW (it
->w
->desired_matrix
, it
->w
))
22262 it
->glyph_row
->reversed_p
= row
->reversed_p
;
22263 it
->start
= row
->end
;
22264 return MATRIX_ROW_DISPLAYS_TEXT_P (row
);
22266 #undef RECORD_MAX_MIN_POS
22269 DEFUN ("current-bidi-paragraph-direction", Fcurrent_bidi_paragraph_direction
,
22270 Scurrent_bidi_paragraph_direction
, 0, 1, 0,
22271 doc
: /* Return paragraph direction at point in BUFFER.
22272 Value is either `left-to-right' or `right-to-left'.
22273 If BUFFER is omitted or nil, it defaults to the current buffer.
22275 Paragraph direction determines how the text in the paragraph is displayed.
22276 In left-to-right paragraphs, text begins at the left margin of the window
22277 and the reading direction is generally left to right. In right-to-left
22278 paragraphs, text begins at the right margin and is read from right to left.
22280 See also `bidi-paragraph-direction'. */)
22281 (Lisp_Object buffer
)
22283 struct buffer
*buf
= current_buffer
;
22284 struct buffer
*old
= buf
;
22286 if (! NILP (buffer
))
22288 CHECK_BUFFER (buffer
);
22289 buf
= XBUFFER (buffer
);
22292 if (NILP (BVAR (buf
, bidi_display_reordering
))
22293 || NILP (BVAR (buf
, enable_multibyte_characters
))
22294 /* When we are loading loadup.el, the character property tables
22295 needed for bidi iteration are not yet available. */
22296 || redisplay__inhibit_bidi
)
22297 return Qleft_to_right
;
22298 else if (!NILP (BVAR (buf
, bidi_paragraph_direction
)))
22299 return BVAR (buf
, bidi_paragraph_direction
);
22302 /* Determine the direction from buffer text. We could try to
22303 use current_matrix if it is up to date, but this seems fast
22304 enough as it is. */
22305 struct bidi_it itb
;
22306 ptrdiff_t pos
= BUF_PT (buf
);
22307 ptrdiff_t bytepos
= BUF_PT_BYTE (buf
);
22309 void *itb_data
= bidi_shelve_cache ();
22311 set_buffer_temp (buf
);
22312 /* bidi_paragraph_init finds the base direction of the paragraph
22313 by searching forward from paragraph start. We need the base
22314 direction of the current or _previous_ paragraph, so we need
22315 to make sure we are within that paragraph. To that end, find
22316 the previous non-empty line. */
22317 if (pos
>= ZV
&& pos
> BEGV
)
22318 DEC_BOTH (pos
, bytepos
);
22319 AUTO_STRING (trailing_white_space
, "[\f\t ]*\n");
22320 if (fast_looking_at (trailing_white_space
,
22321 pos
, bytepos
, ZV
, ZV_BYTE
, Qnil
) > 0)
22323 while ((c
= FETCH_BYTE (bytepos
)) == '\n'
22324 || c
== ' ' || c
== '\t' || c
== '\f')
22326 if (bytepos
<= BEGV_BYTE
)
22331 while (!CHAR_HEAD_P (FETCH_BYTE (bytepos
)))
22334 bidi_init_it (pos
, bytepos
, FRAME_WINDOW_P (SELECTED_FRAME ()), &itb
);
22335 itb
.paragraph_dir
= NEUTRAL_DIR
;
22336 itb
.string
.s
= NULL
;
22337 itb
.string
.lstring
= Qnil
;
22338 itb
.string
.bufpos
= 0;
22339 itb
.string
.from_disp_str
= false;
22340 itb
.string
.unibyte
= false;
22341 /* We have no window to use here for ignoring window-specific
22342 overlays. Using NULL for window pointer will cause
22343 compute_display_string_pos to use the current buffer. */
22345 bidi_paragraph_init (NEUTRAL_DIR
, &itb
, true);
22346 bidi_unshelve_cache (itb_data
, false);
22347 set_buffer_temp (old
);
22348 switch (itb
.paragraph_dir
)
22351 return Qleft_to_right
;
22354 return Qright_to_left
;
22362 DEFUN ("bidi-find-overridden-directionality",
22363 Fbidi_find_overridden_directionality
,
22364 Sbidi_find_overridden_directionality
, 2, 3, 0,
22365 doc
: /* Return position between FROM and TO where directionality was overridden.
22367 This function returns the first character position in the specified
22368 region of OBJECT where there is a character whose `bidi-class' property
22369 is `L', but which was forced to display as `R' by a directional
22370 override, and likewise with characters whose `bidi-class' is `R'
22371 or `AL' that were forced to display as `L'.
22373 If no such character is found, the function returns nil.
22375 OBJECT is a Lisp string or buffer to search for overridden
22376 directionality, and defaults to the current buffer if nil or omitted.
22377 OBJECT can also be a window, in which case the function will search
22378 the buffer displayed in that window. Passing the window instead of
22379 a buffer is preferable when the buffer is displayed in some window,
22380 because this function will then be able to correctly account for
22381 window-specific overlays, which can affect the results.
22383 Strong directional characters `L', `R', and `AL' can have their
22384 intrinsic directionality overridden by directional override
22385 control characters RLO (u+202e) and LRO (u+202d). See the
22386 function `get-char-code-property' for a way to inquire about
22387 the `bidi-class' property of a character. */)
22388 (Lisp_Object from
, Lisp_Object to
, Lisp_Object object
)
22390 struct buffer
*buf
= current_buffer
;
22391 struct buffer
*old
= buf
;
22392 struct window
*w
= NULL
;
22393 bool frame_window_p
= FRAME_WINDOW_P (SELECTED_FRAME ());
22394 struct bidi_it itb
;
22395 ptrdiff_t from_pos
, to_pos
, from_bpos
;
22398 if (!NILP (object
))
22400 if (BUFFERP (object
))
22401 buf
= XBUFFER (object
);
22402 else if (WINDOWP (object
))
22404 w
= decode_live_window (object
);
22405 buf
= XBUFFER (w
->contents
);
22406 frame_window_p
= FRAME_WINDOW_P (XFRAME (w
->frame
));
22409 CHECK_STRING (object
);
22412 if (STRINGP (object
))
22414 /* Characters in unibyte strings are always treated by bidi.c as
22416 if (!STRING_MULTIBYTE (object
)
22417 /* When we are loading loadup.el, the character property
22418 tables needed for bidi iteration are not yet
22420 || redisplay__inhibit_bidi
)
22423 validate_subarray (object
, from
, to
, SCHARS (object
), &from_pos
, &to_pos
);
22424 if (from_pos
>= SCHARS (object
))
22427 /* Set up the bidi iterator. */
22428 itb_data
= bidi_shelve_cache ();
22429 itb
.paragraph_dir
= NEUTRAL_DIR
;
22430 itb
.string
.lstring
= object
;
22431 itb
.string
.s
= NULL
;
22432 itb
.string
.schars
= SCHARS (object
);
22433 itb
.string
.bufpos
= 0;
22434 itb
.string
.from_disp_str
= false;
22435 itb
.string
.unibyte
= false;
22437 bidi_init_it (0, 0, frame_window_p
, &itb
);
22441 /* Nothing this fancy can happen in unibyte buffers, or in a
22442 buffer that disabled reordering, or if FROM is at EOB. */
22443 if (NILP (BVAR (buf
, bidi_display_reordering
))
22444 || NILP (BVAR (buf
, enable_multibyte_characters
))
22445 /* When we are loading loadup.el, the character property
22446 tables needed for bidi iteration are not yet
22448 || redisplay__inhibit_bidi
)
22451 set_buffer_temp (buf
);
22452 validate_region (&from
, &to
);
22453 from_pos
= XINT (from
);
22454 to_pos
= XINT (to
);
22455 if (from_pos
>= ZV
)
22458 /* Set up the bidi iterator. */
22459 itb_data
= bidi_shelve_cache ();
22460 from_bpos
= CHAR_TO_BYTE (from_pos
);
22461 if (from_pos
== BEGV
)
22463 itb
.charpos
= BEGV
;
22464 itb
.bytepos
= BEGV_BYTE
;
22466 else if (FETCH_CHAR (from_bpos
- 1) == '\n')
22468 itb
.charpos
= from_pos
;
22469 itb
.bytepos
= from_bpos
;
22472 itb
.charpos
= find_newline_no_quit (from_pos
, CHAR_TO_BYTE (from_pos
),
22474 itb
.paragraph_dir
= NEUTRAL_DIR
;
22475 itb
.string
.s
= NULL
;
22476 itb
.string
.lstring
= Qnil
;
22477 itb
.string
.bufpos
= 0;
22478 itb
.string
.from_disp_str
= false;
22479 itb
.string
.unibyte
= false;
22481 bidi_init_it (itb
.charpos
, itb
.bytepos
, frame_window_p
, &itb
);
22486 /* For the purposes of this function, the actual base direction of
22487 the paragraph doesn't matter, so just set it to L2R. */
22488 bidi_paragraph_init (L2R
, &itb
, false);
22489 while ((found
= bidi_find_first_overridden (&itb
)) < from_pos
)
22491 } while (found
== ZV
&& itb
.ch
== '\n' && itb
.charpos
< to_pos
);
22493 bidi_unshelve_cache (itb_data
, false);
22494 set_buffer_temp (old
);
22496 return (from_pos
<= found
&& found
< to_pos
) ? make_number (found
) : Qnil
;
22499 DEFUN ("move-point-visually", Fmove_point_visually
,
22500 Smove_point_visually
, 1, 1, 0,
22501 doc
: /* Move point in the visual order in the specified DIRECTION.
22502 DIRECTION can be 1, meaning move to the right, or -1, which moves to the
22505 Value is the new character position of point. */)
22506 (Lisp_Object direction
)
22508 struct window
*w
= XWINDOW (selected_window
);
22509 struct buffer
*b
= XBUFFER (w
->contents
);
22510 struct glyph_row
*row
;
22512 Lisp_Object paragraph_dir
;
22514 #define ROW_GLYPH_NEWLINE_P(ROW,GLYPH) \
22515 (!(ROW)->continued_p \
22516 && NILP ((GLYPH)->object) \
22517 && (GLYPH)->type == CHAR_GLYPH \
22518 && (GLYPH)->u.ch == ' ' \
22519 && (GLYPH)->charpos >= 0 \
22520 && !(GLYPH)->avoid_cursor_p)
22522 CHECK_NUMBER (direction
);
22523 dir
= XINT (direction
);
22529 /* If current matrix is up-to-date, we can use the information
22530 recorded in the glyphs, at least as long as the goal is on the
22532 if (w
->window_end_valid
22533 && !windows_or_buffers_changed
22535 && !b
->clip_changed
22536 && !b
->prevent_redisplay_optimizations_p
22537 && !window_outdated (w
)
22538 /* We rely below on the cursor coordinates to be up to date, but
22539 we cannot trust them if some command moved point since the
22540 last complete redisplay. */
22541 && w
->last_point
== BUF_PT (b
)
22542 && w
->cursor
.vpos
>= 0
22543 && w
->cursor
.vpos
< w
->current_matrix
->nrows
22544 && (row
= MATRIX_ROW (w
->current_matrix
, w
->cursor
.vpos
))->enabled_p
)
22546 struct glyph
*g
= row
->glyphs
[TEXT_AREA
];
22547 struct glyph
*e
= dir
> 0 ? g
+ row
->used
[TEXT_AREA
] : g
- 1;
22548 struct glyph
*gpt
= g
+ w
->cursor
.hpos
;
22550 for (g
= gpt
+ dir
; (dir
> 0 ? g
< e
: g
> e
); g
+= dir
)
22552 if (BUFFERP (g
->object
) && g
->charpos
!= PT
)
22554 SET_PT (g
->charpos
);
22555 w
->cursor
.vpos
= -1;
22556 return make_number (PT
);
22558 else if (!NILP (g
->object
) && !EQ (g
->object
, gpt
->object
))
22562 if (BUFFERP (gpt
->object
))
22565 if ((gpt
->resolved_level
- row
->reversed_p
) % 2 == 0)
22566 new_pos
+= (row
->reversed_p
? -dir
: dir
);
22568 new_pos
-= (row
->reversed_p
? -dir
: dir
);
22569 new_pos
= clip_to_bounds (BEGV
, new_pos
, ZV
);
22570 /* If we didn't move, we've hit BEGV or ZV, so we
22571 need to signal a suitable error. */
22575 else if (BUFFERP (g
->object
))
22576 new_pos
= g
->charpos
;
22580 w
->cursor
.vpos
= -1;
22581 return make_number (PT
);
22583 else if (ROW_GLYPH_NEWLINE_P (row
, g
))
22585 /* Glyphs inserted at the end of a non-empty line for
22586 positioning the cursor have zero charpos, so we must
22587 deduce the value of point by other means. */
22588 if (g
->charpos
> 0)
22589 SET_PT (g
->charpos
);
22590 else if (row
->ends_at_zv_p
&& PT
!= ZV
)
22592 else if (PT
!= MATRIX_ROW_END_CHARPOS (row
) - 1)
22593 SET_PT (MATRIX_ROW_END_CHARPOS (row
) - 1);
22596 w
->cursor
.vpos
= -1;
22597 return make_number (PT
);
22600 if (g
== e
|| NILP (g
->object
))
22602 if (row
->truncated_on_left_p
|| row
->truncated_on_right_p
)
22603 goto simulate_display
;
22604 if (!row
->reversed_p
)
22608 if (!(MATRIX_FIRST_TEXT_ROW (w
->current_matrix
) <= row
22609 && row
< MATRIX_BOTTOM_TEXT_ROW (w
->current_matrix
, w
)))
22610 goto simulate_display
;
22614 if (row
->reversed_p
&& !row
->continued_p
)
22616 SET_PT (MATRIX_ROW_END_CHARPOS (row
) - 1);
22617 w
->cursor
.vpos
= -1;
22618 return make_number (PT
);
22620 g
= row
->glyphs
[TEXT_AREA
];
22621 e
= g
+ row
->used
[TEXT_AREA
];
22622 for ( ; g
< e
; g
++)
22624 if (BUFFERP (g
->object
)
22625 /* Empty lines have only one glyph, which stands
22626 for the newline, and whose charpos is the
22627 buffer position of the newline. */
22628 || ROW_GLYPH_NEWLINE_P (row
, g
)
22629 /* When the buffer ends in a newline, the line at
22630 EOB also has one glyph, but its charpos is -1. */
22631 || (row
->ends_at_zv_p
22632 && !row
->reversed_p
22633 && NILP (g
->object
)
22634 && g
->type
== CHAR_GLYPH
22635 && g
->u
.ch
== ' '))
22637 if (g
->charpos
> 0)
22638 SET_PT (g
->charpos
);
22639 else if (!row
->reversed_p
22640 && row
->ends_at_zv_p
22645 w
->cursor
.vpos
= -1;
22646 return make_number (PT
);
22652 if (!row
->reversed_p
&& !row
->continued_p
)
22654 SET_PT (MATRIX_ROW_END_CHARPOS (row
) - 1);
22655 w
->cursor
.vpos
= -1;
22656 return make_number (PT
);
22658 e
= row
->glyphs
[TEXT_AREA
];
22659 g
= e
+ row
->used
[TEXT_AREA
] - 1;
22660 for ( ; g
>= e
; g
--)
22662 if (BUFFERP (g
->object
)
22663 || (ROW_GLYPH_NEWLINE_P (row
, g
)
22665 /* Empty R2L lines on GUI frames have the buffer
22666 position of the newline stored in the stretch
22668 || g
->type
== STRETCH_GLYPH
22669 || (row
->ends_at_zv_p
22671 && NILP (g
->object
)
22672 && g
->type
== CHAR_GLYPH
22673 && g
->u
.ch
== ' '))
22675 if (g
->charpos
> 0)
22676 SET_PT (g
->charpos
);
22677 else if (row
->reversed_p
22678 && row
->ends_at_zv_p
22683 w
->cursor
.vpos
= -1;
22684 return make_number (PT
);
22693 /* If we wind up here, we failed to move by using the glyphs, so we
22694 need to simulate display instead. */
22697 paragraph_dir
= Fcurrent_bidi_paragraph_direction (w
->contents
);
22699 paragraph_dir
= Qleft_to_right
;
22700 if (EQ (paragraph_dir
, Qright_to_left
))
22702 if (PT
<= BEGV
&& dir
< 0)
22703 xsignal0 (Qbeginning_of_buffer
);
22704 else if (PT
>= ZV
&& dir
> 0)
22705 xsignal0 (Qend_of_buffer
);
22708 struct text_pos pt
;
22710 int pt_x
, target_x
, pixel_width
, pt_vpos
;
22712 bool overshoot_expected
= false;
22713 bool target_is_eol_p
= false;
22715 /* Setup the arena. */
22716 SET_TEXT_POS (pt
, PT
, PT_BYTE
);
22717 start_display (&it
, w
, pt
);
22718 /* When lines are truncated, we could be called with point
22719 outside of the windows edges, in which case move_it_*
22720 functions either prematurely stop at window's edge or jump to
22721 the next screen line, whereas we rely below on our ability to
22722 reach point, in order to start from its X coordinate. So we
22723 need to disregard the window's horizontal extent in that case. */
22724 if (it
.line_wrap
== TRUNCATE
)
22725 it
.last_visible_x
= DISP_INFINITY
;
22727 if (it
.cmp_it
.id
< 0
22728 && it
.method
== GET_FROM_STRING
22729 && it
.area
== TEXT_AREA
22730 && it
.string_from_display_prop_p
22731 && (it
.sp
> 0 && it
.stack
[it
.sp
- 1].method
== GET_FROM_BUFFER
))
22732 overshoot_expected
= true;
22734 /* Find the X coordinate of point. We start from the beginning
22735 of this or previous line to make sure we are before point in
22736 the logical order (since the move_it_* functions can only
22739 reseat_at_previous_visible_line_start (&it
);
22740 it
.current_x
= it
.hpos
= it
.current_y
= it
.vpos
= 0;
22741 if (IT_CHARPOS (it
) != PT
)
22743 move_it_to (&it
, overshoot_expected
? PT
- 1 : PT
,
22744 -1, -1, -1, MOVE_TO_POS
);
22745 /* If we missed point because the character there is
22746 displayed out of a display vector that has more than one
22747 glyph, retry expecting overshoot. */
22748 if (it
.method
== GET_FROM_DISPLAY_VECTOR
22749 && it
.current
.dpvec_index
> 0
22750 && !overshoot_expected
)
22752 overshoot_expected
= true;
22755 else if (IT_CHARPOS (it
) != PT
&& !overshoot_expected
)
22756 move_it_in_display_line (&it
, PT
, -1, MOVE_TO_POS
);
22758 pt_x
= it
.current_x
;
22760 if (dir
> 0 || overshoot_expected
)
22762 struct glyph_row
*row
= it
.glyph_row
;
22764 /* When point is at beginning of line, we don't have
22765 information about the glyph there loaded into struct
22766 it. Calling get_next_display_element fixes that. */
22768 get_next_display_element (&it
);
22769 at_eol_p
= ITERATOR_AT_END_OF_LINE_P (&it
);
22770 it
.glyph_row
= NULL
;
22771 PRODUCE_GLYPHS (&it
); /* compute it.pixel_width */
22772 it
.glyph_row
= row
;
22773 /* PRODUCE_GLYPHS advances it.current_x, so we must restore
22774 it, lest it will become out of sync with it's buffer
22776 it
.current_x
= pt_x
;
22779 at_eol_p
= ITERATOR_AT_END_OF_LINE_P (&it
);
22780 pixel_width
= it
.pixel_width
;
22781 if (overshoot_expected
&& at_eol_p
)
22783 else if (pixel_width
<= 0)
22786 /* If there's a display string (or something similar) at point,
22787 we are actually at the glyph to the left of point, so we need
22788 to correct the X coordinate. */
22789 if (overshoot_expected
)
22792 pt_x
+= pixel_width
* it
.bidi_it
.scan_dir
;
22794 pt_x
+= pixel_width
;
22797 /* Compute target X coordinate, either to the left or to the
22798 right of point. On TTY frames, all characters have the same
22799 pixel width of 1, so we can use that. On GUI frames we don't
22800 have an easy way of getting at the pixel width of the
22801 character to the left of point, so we use a different method
22802 of getting to that place. */
22804 target_x
= pt_x
+ pixel_width
;
22806 target_x
= pt_x
- (!FRAME_WINDOW_P (it
.f
)) * pixel_width
;
22808 /* Target X coordinate could be one line above or below the line
22809 of point, in which case we need to adjust the target X
22810 coordinate. Also, if moving to the left, we need to begin at
22811 the left edge of the point's screen line. */
22816 start_display (&it
, w
, pt
);
22817 if (it
.line_wrap
== TRUNCATE
)
22818 it
.last_visible_x
= DISP_INFINITY
;
22819 reseat_at_previous_visible_line_start (&it
);
22820 it
.current_x
= it
.current_y
= it
.hpos
= 0;
22822 move_it_by_lines (&it
, pt_vpos
);
22826 move_it_by_lines (&it
, -1);
22827 target_x
= it
.last_visible_x
- !FRAME_WINDOW_P (it
.f
);
22828 target_is_eol_p
= true;
22829 /* Under word-wrap, we don't know the x coordinate of
22830 the last character displayed on the previous line,
22831 which immediately precedes the wrap point. To find
22832 out its x coordinate, we try moving to the right
22833 margin of the window, which will stop at the wrap
22834 point, and then reset target_x to point at the
22835 character that precedes the wrap point. This is not
22836 needed on GUI frames, because (see below) there we
22837 move from the left margin one grapheme cluster at a
22838 time, and stop when we hit the wrap point. */
22839 if (!FRAME_WINDOW_P (it
.f
) && it
.line_wrap
== WORD_WRAP
)
22841 void *it_data
= NULL
;
22844 SAVE_IT (it2
, it
, it_data
);
22845 move_it_in_display_line_to (&it
, ZV
, target_x
,
22846 MOVE_TO_POS
| MOVE_TO_X
);
22847 /* If we arrived at target_x, that _is_ the last
22848 character on the previous line. */
22849 if (it
.current_x
!= target_x
)
22850 target_x
= it
.current_x
- 1;
22851 RESTORE_IT (&it
, &it2
, it_data
);
22858 || (target_x
>= it
.last_visible_x
22859 && it
.line_wrap
!= TRUNCATE
))
22862 move_it_by_lines (&it
, 0);
22863 move_it_by_lines (&it
, 1);
22868 /* Move to the target X coordinate. */
22869 /* On GUI frames, as we don't know the X coordinate of the
22870 character to the left of point, moving point to the left
22871 requires walking, one grapheme cluster at a time, until we
22872 find ourself at a place immediately to the left of the
22873 character at point. */
22874 if (FRAME_WINDOW_P (it
.f
) && dir
< 0)
22876 struct text_pos new_pos
;
22877 enum move_it_result rc
= MOVE_X_REACHED
;
22879 if (it
.current_x
== 0)
22880 get_next_display_element (&it
);
22881 if (it
.what
== IT_COMPOSITION
)
22883 new_pos
.charpos
= it
.cmp_it
.charpos
;
22884 new_pos
.bytepos
= -1;
22887 new_pos
= it
.current
.pos
;
22889 while (it
.current_x
+ it
.pixel_width
<= target_x
22890 && (rc
== MOVE_X_REACHED
22891 /* Under word-wrap, move_it_in_display_line_to
22892 stops at correct coordinates, but sometimes
22893 returns MOVE_POS_MATCH_OR_ZV. */
22894 || (it
.line_wrap
== WORD_WRAP
22895 && rc
== MOVE_POS_MATCH_OR_ZV
)))
22897 int new_x
= it
.current_x
+ it
.pixel_width
;
22899 /* For composed characters, we want the position of the
22900 first character in the grapheme cluster (usually, the
22901 composition's base character), whereas it.current
22902 might give us the position of the _last_ one, e.g. if
22903 the composition is rendered in reverse due to bidi
22905 if (it
.what
== IT_COMPOSITION
)
22907 new_pos
.charpos
= it
.cmp_it
.charpos
;
22908 new_pos
.bytepos
= -1;
22911 new_pos
= it
.current
.pos
;
22912 if (new_x
== it
.current_x
)
22914 rc
= move_it_in_display_line_to (&it
, ZV
, new_x
,
22915 MOVE_TO_POS
| MOVE_TO_X
);
22916 if (ITERATOR_AT_END_OF_LINE_P (&it
) && !target_is_eol_p
)
22919 /* The previous position we saw in the loop is the one we
22921 if (new_pos
.bytepos
== -1)
22922 new_pos
.bytepos
= CHAR_TO_BYTE (new_pos
.charpos
);
22923 it
.current
.pos
= new_pos
;
22925 else if (it
.current_x
!= target_x
)
22926 move_it_in_display_line_to (&it
, ZV
, target_x
, MOVE_TO_POS
| MOVE_TO_X
);
22928 /* If we ended up in a display string that covers point, move to
22929 buffer position to the right in the visual order. */
22932 while (IT_CHARPOS (it
) == PT
)
22934 set_iterator_to_next (&it
, false);
22935 if (!get_next_display_element (&it
))
22940 /* Move point to that position. */
22941 SET_PT_BOTH (IT_CHARPOS (it
), IT_BYTEPOS (it
));
22944 return make_number (PT
);
22946 #undef ROW_GLYPH_NEWLINE_P
22949 DEFUN ("bidi-resolved-levels", Fbidi_resolved_levels
,
22950 Sbidi_resolved_levels
, 0, 1, 0,
22951 doc
: /* Return the resolved bidirectional levels of characters at VPOS.
22953 The resolved levels are produced by the Emacs bidi reordering engine
22954 that implements the UBA, the Unicode Bidirectional Algorithm. Please
22955 read the Unicode Standard Annex 9 (UAX#9) for background information
22956 about these levels.
22958 VPOS is the zero-based number of the current window's screen line
22959 for which to produce the resolved levels. If VPOS is nil or omitted,
22960 it defaults to the screen line of point. If the window displays a
22961 header line, VPOS of zero will report on the header line, and first
22962 line of text in the window will have VPOS of 1.
22964 Value is an array of resolved levels, indexed by glyph number.
22965 Glyphs are numbered from zero starting from the beginning of the
22966 screen line, i.e. the left edge of the window for left-to-right lines
22967 and from the right edge for right-to-left lines. The resolved levels
22968 are produced only for the window's text area; text in display margins
22971 If the selected window's display is not up-to-date, or if the specified
22972 screen line does not display text, this function returns nil. It is
22973 highly recommended to bind this function to some simple key, like F8,
22974 in order to avoid these problems.
22976 This function exists mainly for testing the correctness of the
22977 Emacs UBA implementation, in particular with the test suite. */)
22980 struct window
*w
= XWINDOW (selected_window
);
22981 struct buffer
*b
= XBUFFER (w
->contents
);
22983 struct glyph_row
*row
;
22987 int d1
, d2
, d3
, d4
, d5
;
22989 pos_visible_p (w
, PT
, &d1
, &d2
, &d3
, &d4
, &d5
, &nrow
);
22993 CHECK_NUMBER_COERCE_MARKER (vpos
);
22994 nrow
= XINT (vpos
);
22997 /* We require up-to-date glyph matrix for this window. */
22998 if (w
->window_end_valid
22999 && !windows_or_buffers_changed
23001 && !b
->clip_changed
23002 && !b
->prevent_redisplay_optimizations_p
23003 && !window_outdated (w
)
23005 && nrow
< w
->current_matrix
->nrows
23006 && (row
= MATRIX_ROW (w
->current_matrix
, nrow
))->enabled_p
23007 && MATRIX_ROW_DISPLAYS_TEXT_P (row
))
23009 struct glyph
*g
, *e
, *g1
;
23011 Lisp_Object levels
;
23013 if (!row
->reversed_p
) /* Left-to-right glyph row. */
23015 g
= g1
= row
->glyphs
[TEXT_AREA
];
23016 e
= g
+ row
->used
[TEXT_AREA
];
23018 /* Skip over glyphs at the start of the row that was
23019 generated by redisplay for its own needs. */
23021 && NILP (g
->object
)
23026 /* Count the "interesting" glyphs in this row. */
23027 for (nglyphs
= 0; g
< e
&& !NILP (g
->object
); g
++)
23030 /* Create and fill the array. */
23031 levels
= make_uninit_vector (nglyphs
);
23032 for (i
= 0; g1
< g
; i
++, g1
++)
23033 ASET (levels
, i
, make_number (g1
->resolved_level
));
23035 else /* Right-to-left glyph row. */
23037 g
= row
->glyphs
[TEXT_AREA
] + row
->used
[TEXT_AREA
] - 1;
23038 e
= row
->glyphs
[TEXT_AREA
] - 1;
23040 && NILP (g
->object
)
23044 for (nglyphs
= 0; g
> e
&& !NILP (g
->object
); g
--)
23046 levels
= make_uninit_vector (nglyphs
);
23047 for (i
= 0; g1
> g
; i
++, g1
--)
23048 ASET (levels
, i
, make_number (g1
->resolved_level
));
23058 /***********************************************************************
23060 ***********************************************************************/
23062 /* Redisplay the menu bar in the frame for window W.
23064 The menu bar of X frames that don't have X toolkit support is
23065 displayed in a special window W->frame->menu_bar_window.
23067 The menu bar of terminal frames is treated specially as far as
23068 glyph matrices are concerned. Menu bar lines are not part of
23069 windows, so the update is done directly on the frame matrix rows
23070 for the menu bar. */
23073 display_menu_bar (struct window
*w
)
23075 struct frame
*f
= XFRAME (WINDOW_FRAME (w
));
23080 /* Don't do all this for graphical frames. */
23082 if (FRAME_W32_P (f
))
23085 #if defined (USE_X_TOOLKIT) || defined (USE_GTK)
23091 if (FRAME_NS_P (f
))
23093 #endif /* HAVE_NS */
23095 #if defined (USE_X_TOOLKIT) || defined (USE_GTK)
23096 eassert (!FRAME_WINDOW_P (f
));
23097 init_iterator (&it
, w
, -1, -1, f
->desired_matrix
->rows
, MENU_FACE_ID
);
23098 it
.first_visible_x
= 0;
23099 it
.last_visible_x
= FRAME_PIXEL_WIDTH (f
);
23100 #elif defined (HAVE_X_WINDOWS) /* X without toolkit. */
23101 if (FRAME_WINDOW_P (f
))
23103 /* Menu bar lines are displayed in the desired matrix of the
23104 dummy window menu_bar_window. */
23105 struct window
*menu_w
;
23106 menu_w
= XWINDOW (f
->menu_bar_window
);
23107 init_iterator (&it
, menu_w
, -1, -1, menu_w
->desired_matrix
->rows
,
23109 it
.first_visible_x
= 0;
23110 it
.last_visible_x
= FRAME_PIXEL_WIDTH (f
);
23113 #endif /* not USE_X_TOOLKIT and not USE_GTK */
23115 /* This is a TTY frame, i.e. character hpos/vpos are used as
23117 init_iterator (&it
, w
, -1, -1, f
->desired_matrix
->rows
,
23119 it
.first_visible_x
= 0;
23120 it
.last_visible_x
= FRAME_COLS (f
);
23123 /* FIXME: This should be controlled by a user option. See the
23124 comments in redisplay_tool_bar and display_mode_line about
23126 it
.paragraph_embedding
= L2R
;
23128 /* Clear all rows of the menu bar. */
23129 for (i
= 0; i
< FRAME_MENU_BAR_LINES (f
); ++i
)
23131 struct glyph_row
*row
= it
.glyph_row
+ i
;
23132 clear_glyph_row (row
);
23133 row
->enabled_p
= true;
23134 row
->full_width_p
= true;
23135 row
->reversed_p
= false;
23138 /* Display all items of the menu bar. */
23139 items
= FRAME_MENU_BAR_ITEMS (it
.f
);
23140 for (i
= 0; i
< ASIZE (items
); i
+= 4)
23142 Lisp_Object string
;
23144 /* Stop at nil string. */
23145 string
= AREF (items
, i
+ 1);
23149 /* Remember where item was displayed. */
23150 ASET (items
, i
+ 3, make_number (it
.hpos
));
23152 /* Display the item, pad with one space. */
23153 if (it
.current_x
< it
.last_visible_x
)
23154 display_string (NULL
, string
, Qnil
, 0, 0, &it
,
23155 SCHARS (string
) + 1, 0, 0, -1);
23158 /* Fill out the line with spaces. */
23159 if (it
.current_x
< it
.last_visible_x
)
23160 display_string ("", Qnil
, Qnil
, 0, 0, &it
, -1, 0, 0, -1);
23162 /* Compute the total height of the lines. */
23163 compute_line_metrics (&it
);
23166 /* Deep copy of a glyph row, including the glyphs. */
23168 deep_copy_glyph_row (struct glyph_row
*to
, struct glyph_row
*from
)
23170 struct glyph
*pointers
[1 + LAST_AREA
];
23171 int to_used
= to
->used
[TEXT_AREA
];
23173 /* Save glyph pointers of TO. */
23174 memcpy (pointers
, to
->glyphs
, sizeof to
->glyphs
);
23176 /* Do a structure assignment. */
23179 /* Restore original glyph pointers of TO. */
23180 memcpy (to
->glyphs
, pointers
, sizeof to
->glyphs
);
23182 /* Copy the glyphs. */
23183 memcpy (to
->glyphs
[TEXT_AREA
], from
->glyphs
[TEXT_AREA
],
23184 min (from
->used
[TEXT_AREA
], to_used
) * sizeof (struct glyph
));
23186 /* If we filled only part of the TO row, fill the rest with
23187 space_glyph (which will display as empty space). */
23188 if (to_used
> from
->used
[TEXT_AREA
])
23189 fill_up_frame_row_with_spaces (to
, to_used
);
23192 /* Display one menu item on a TTY, by overwriting the glyphs in the
23193 frame F's desired glyph matrix with glyphs produced from the menu
23194 item text. Called from term.c to display TTY drop-down menus one
23197 ITEM_TEXT is the menu item text as a C string.
23199 FACE_ID is the face ID to be used for this menu item. FACE_ID
23200 could specify one of 3 faces: a face for an enabled item, a face
23201 for a disabled item, or a face for a selected item.
23203 X and Y are coordinates of the first glyph in the frame's desired
23204 matrix to be overwritten by the menu item. Since this is a TTY, Y
23205 is the zero-based number of the glyph row and X is the zero-based
23206 glyph number in the row, starting from left, where to start
23207 displaying the item.
23209 SUBMENU means this menu item drops down a submenu, which
23210 should be indicated by displaying a proper visual cue after the
23214 display_tty_menu_item (const char *item_text
, int width
, int face_id
,
23215 int x
, int y
, bool submenu
)
23218 struct frame
*f
= SELECTED_FRAME ();
23219 struct window
*w
= XWINDOW (f
->selected_window
);
23220 struct glyph_row
*row
;
23221 size_t item_len
= strlen (item_text
);
23223 eassert (FRAME_TERMCAP_P (f
));
23225 /* Don't write beyond the matrix's last row. This can happen for
23226 TTY screens that are not high enough to show the entire menu.
23227 (This is actually a bit of defensive programming, as
23228 tty_menu_display already limits the number of menu items to one
23229 less than the number of screen lines.) */
23230 if (y
>= f
->desired_matrix
->nrows
)
23233 init_iterator (&it
, w
, -1, -1, f
->desired_matrix
->rows
+ y
, MENU_FACE_ID
);
23234 it
.first_visible_x
= 0;
23235 it
.last_visible_x
= FRAME_COLS (f
) - 1;
23236 row
= it
.glyph_row
;
23237 /* Start with the row contents from the current matrix. */
23238 deep_copy_glyph_row (row
, f
->current_matrix
->rows
+ y
);
23239 bool saved_width
= row
->full_width_p
;
23240 row
->full_width_p
= true;
23241 bool saved_reversed
= row
->reversed_p
;
23242 row
->reversed_p
= false;
23243 row
->enabled_p
= true;
23245 /* Arrange for the menu item glyphs to start at (X,Y) and have the
23247 eassert (x
< f
->desired_matrix
->matrix_w
);
23248 it
.current_x
= it
.hpos
= x
;
23249 it
.current_y
= it
.vpos
= y
;
23250 int saved_used
= row
->used
[TEXT_AREA
];
23251 bool saved_truncated
= row
->truncated_on_right_p
;
23252 row
->used
[TEXT_AREA
] = x
;
23253 it
.face_id
= face_id
;
23254 it
.line_wrap
= TRUNCATE
;
23256 /* FIXME: This should be controlled by a user option. See the
23257 comments in redisplay_tool_bar and display_mode_line about this.
23258 Also, if paragraph_embedding could ever be R2L, changes will be
23259 needed to avoid shifting to the right the row characters in
23260 term.c:append_glyph. */
23261 it
.paragraph_embedding
= L2R
;
23263 /* Pad with a space on the left. */
23264 display_string (" ", Qnil
, Qnil
, 0, 0, &it
, 1, 0, FRAME_COLS (f
) - 1, -1);
23266 /* Display the menu item, pad with spaces to WIDTH. */
23269 display_string (item_text
, Qnil
, Qnil
, 0, 0, &it
,
23270 item_len
, 0, FRAME_COLS (f
) - 1, -1);
23272 /* Indicate with " >" that there's a submenu. */
23273 display_string (" >", Qnil
, Qnil
, 0, 0, &it
, width
, 0,
23274 FRAME_COLS (f
) - 1, -1);
23277 display_string (item_text
, Qnil
, Qnil
, 0, 0, &it
,
23278 width
, 0, FRAME_COLS (f
) - 1, -1);
23280 row
->used
[TEXT_AREA
] = max (saved_used
, row
->used
[TEXT_AREA
]);
23281 row
->truncated_on_right_p
= saved_truncated
;
23282 row
->hash
= row_hash (row
);
23283 row
->full_width_p
= saved_width
;
23284 row
->reversed_p
= saved_reversed
;
23287 /***********************************************************************
23289 ***********************************************************************/
23291 /* Redisplay mode lines in the window tree whose root is WINDOW.
23292 If FORCE, redisplay mode lines unconditionally.
23293 Otherwise, redisplay only mode lines that are garbaged. Value is
23294 the number of windows whose mode lines were redisplayed. */
23297 redisplay_mode_lines (Lisp_Object window
, bool force
)
23301 while (!NILP (window
))
23303 struct window
*w
= XWINDOW (window
);
23305 if (WINDOWP (w
->contents
))
23306 nwindows
+= redisplay_mode_lines (w
->contents
, force
);
23308 || FRAME_GARBAGED_P (XFRAME (w
->frame
))
23309 || !MATRIX_MODE_LINE_ROW (w
->current_matrix
)->enabled_p
)
23311 struct text_pos lpoint
;
23312 struct buffer
*old
= current_buffer
;
23314 /* Set the window's buffer for the mode line display. */
23315 SET_TEXT_POS (lpoint
, PT
, PT_BYTE
);
23316 set_buffer_internal_1 (XBUFFER (w
->contents
));
23318 /* Point refers normally to the selected window. For any
23319 other window, set up appropriate value. */
23320 if (!EQ (window
, selected_window
))
23322 struct text_pos pt
;
23324 CLIP_TEXT_POS_FROM_MARKER (pt
, w
->pointm
);
23325 TEMP_SET_PT_BOTH (CHARPOS (pt
), BYTEPOS (pt
));
23328 /* Display mode lines. */
23329 clear_glyph_matrix (w
->desired_matrix
);
23330 if (display_mode_lines (w
))
23333 /* Restore old settings. */
23334 set_buffer_internal_1 (old
);
23335 TEMP_SET_PT_BOTH (CHARPOS (lpoint
), BYTEPOS (lpoint
));
23345 /* Display the mode and/or header line of window W. Value is the
23346 sum number of mode lines and header lines displayed. */
23349 display_mode_lines (struct window
*w
)
23351 Lisp_Object old_selected_window
= selected_window
;
23352 Lisp_Object old_selected_frame
= selected_frame
;
23353 Lisp_Object new_frame
= w
->frame
;
23354 Lisp_Object old_frame_selected_window
= XFRAME (new_frame
)->selected_window
;
23357 if (window_wants_mode_line (w
))
23359 Lisp_Object window
;
23360 Lisp_Object default_help
23361 = buffer_local_value (Qmode_line_default_help_echo
, w
->contents
);
23363 /* Set up mode line help echo. Do this before selecting w so it
23364 can reasonably tell whether a mouse click will select w. */
23365 XSETWINDOW (window
, w
);
23366 if (FUNCTIONP (default_help
))
23367 wset_mode_line_help_echo (w
, safe_call1 (default_help
, window
));
23368 else if (STRINGP (default_help
))
23369 wset_mode_line_help_echo (w
, default_help
);
23371 wset_mode_line_help_echo (w
, Qnil
);
23374 selected_frame
= new_frame
;
23375 /* FIXME: If we were to allow the mode-line's computation changing the buffer
23376 or window's point, then we'd need select_window_1 here as well. */
23377 XSETWINDOW (selected_window
, w
);
23378 XFRAME (new_frame
)->selected_window
= selected_window
;
23380 /* These will be set while the mode line specs are processed. */
23381 line_number_displayed
= false;
23382 w
->column_number_displayed
= -1;
23384 if (window_wants_mode_line (w
))
23386 Lisp_Object window_mode_line_format
23387 = window_parameter (w
, Qmode_line_format
);
23388 struct window
*sel_w
= XWINDOW (old_selected_window
);
23390 /* Select mode line face based on the real selected window. */
23391 display_mode_line (w
, CURRENT_MODE_LINE_FACE_ID_3 (sel_w
, sel_w
, w
),
23392 NILP (window_mode_line_format
)
23393 ? BVAR (current_buffer
, mode_line_format
)
23394 : window_mode_line_format
);
23398 if (window_wants_header_line (w
))
23400 Lisp_Object window_header_line_format
23401 = window_parameter (w
, Qheader_line_format
);
23403 display_mode_line (w
, HEADER_LINE_FACE_ID
,
23404 NILP (window_header_line_format
)
23405 ? BVAR (current_buffer
, header_line_format
)
23406 : window_header_line_format
);
23410 XFRAME (new_frame
)->selected_window
= old_frame_selected_window
;
23411 selected_frame
= old_selected_frame
;
23412 selected_window
= old_selected_window
;
23414 w
->must_be_updated_p
= true;
23419 /* Display mode or header line of window W. FACE_ID specifies which
23420 line to display; it is either MODE_LINE_FACE_ID or
23421 HEADER_LINE_FACE_ID. FORMAT is the mode/header line format to
23422 display. Value is the pixel height of the mode/header line
23426 display_mode_line (struct window
*w
, enum face_id face_id
, Lisp_Object format
)
23430 ptrdiff_t count
= SPECPDL_INDEX ();
23432 init_iterator (&it
, w
, -1, -1, NULL
, face_id
);
23433 /* Don't extend on a previously drawn mode-line.
23434 This may happen if called from pos_visible_p. */
23435 it
.glyph_row
->enabled_p
= false;
23436 prepare_desired_row (w
, it
.glyph_row
, true);
23438 it
.glyph_row
->mode_line_p
= true;
23440 /* FIXME: This should be controlled by a user option. But
23441 supporting such an option is not trivial, since the mode line is
23442 made up of many separate strings. */
23443 it
.paragraph_embedding
= L2R
;
23445 record_unwind_protect (unwind_format_mode_line
,
23446 format_mode_line_unwind_data (NULL
, NULL
,
23449 mode_line_target
= MODE_LINE_DISPLAY
;
23451 /* Temporarily make frame's keyboard the current kboard so that
23452 kboard-local variables in the mode_line_format will get the right
23454 push_kboard (FRAME_KBOARD (it
.f
));
23455 record_unwind_save_match_data ();
23456 display_mode_element (&it
, 0, 0, 0, format
, Qnil
, false);
23459 unbind_to (count
, Qnil
);
23461 /* Fill up with spaces. */
23462 display_string (" ", Qnil
, Qnil
, 0, 0, &it
, 10000, -1, -1, 0);
23464 compute_line_metrics (&it
);
23465 it
.glyph_row
->full_width_p
= true;
23466 it
.glyph_row
->continued_p
= false;
23467 it
.glyph_row
->truncated_on_left_p
= false;
23468 it
.glyph_row
->truncated_on_right_p
= false;
23470 /* Make a 3D mode-line have a shadow at its right end. */
23471 face
= FACE_FROM_ID (it
.f
, face_id
);
23472 extend_face_to_end_of_line (&it
);
23473 if (face
->box
!= FACE_NO_BOX
)
23475 struct glyph
*last
= (it
.glyph_row
->glyphs
[TEXT_AREA
]
23476 + it
.glyph_row
->used
[TEXT_AREA
] - 1);
23477 last
->right_box_line_p
= true;
23480 return it
.glyph_row
->height
;
23483 /* Move element ELT in LIST to the front of LIST.
23484 Return the updated list. */
23487 move_elt_to_front (Lisp_Object elt
, Lisp_Object list
)
23489 register Lisp_Object tail
, prev
;
23490 register Lisp_Object tem
;
23494 while (CONSP (tail
))
23500 /* Splice out the link TAIL. */
23502 list
= XCDR (tail
);
23504 Fsetcdr (prev
, XCDR (tail
));
23506 /* Now make it the first. */
23507 Fsetcdr (tail
, list
);
23512 tail
= XCDR (tail
);
23516 /* Not found--return unchanged LIST. */
23520 /* Contribute ELT to the mode line for window IT->w. How it
23521 translates into text depends on its data type.
23523 IT describes the display environment in which we display, as usual.
23525 DEPTH is the depth in recursion. It is used to prevent
23526 infinite recursion here.
23528 FIELD_WIDTH is the number of characters the display of ELT should
23529 occupy in the mode line, and PRECISION is the maximum number of
23530 characters to display from ELT's representation. See
23531 display_string for details.
23533 Returns the hpos of the end of the text generated by ELT.
23535 PROPS is a property list to add to any string we encounter.
23537 If RISKY, remove (disregard) any properties in any string
23538 we encounter, and ignore :eval and :propertize.
23540 The global variable `mode_line_target' determines whether the
23541 output is passed to `store_mode_line_noprop',
23542 `store_mode_line_string', or `display_string'. */
23545 display_mode_element (struct it
*it
, int depth
, int field_width
, int precision
,
23546 Lisp_Object elt
, Lisp_Object props
, bool risky
)
23548 int n
= 0, field
, prec
;
23549 bool literal
= false;
23553 elt
= build_string ("*too-deep*");
23557 switch (XTYPE (elt
))
23561 /* A string: output it and check for %-constructs within it. */
23563 ptrdiff_t offset
= 0;
23565 if (SCHARS (elt
) > 0
23566 && (!NILP (props
) || risky
))
23568 Lisp_Object oprops
, aelt
;
23569 oprops
= Ftext_properties_at (make_number (0), elt
);
23571 /* If the starting string's properties are not what
23572 we want, translate the string. Also, if the string
23573 is risky, do that anyway. */
23575 if (NILP (Fequal (props
, oprops
)) || risky
)
23577 /* If the starting string has properties,
23578 merge the specified ones onto the existing ones. */
23579 if (! NILP (oprops
) && !risky
)
23583 oprops
= Fcopy_sequence (oprops
);
23585 while (CONSP (tem
))
23587 oprops
= Fplist_put (oprops
, XCAR (tem
),
23588 XCAR (XCDR (tem
)));
23589 tem
= XCDR (XCDR (tem
));
23594 aelt
= Fassoc (elt
, mode_line_proptrans_alist
, Qnil
);
23595 if (! NILP (aelt
) && !NILP (Fequal (props
, XCDR (aelt
))))
23597 /* AELT is what we want. Move it to the front
23598 without consing. */
23600 mode_line_proptrans_alist
23601 = move_elt_to_front (aelt
, mode_line_proptrans_alist
);
23607 /* If AELT has the wrong props, it is useless.
23608 so get rid of it. */
23610 mode_line_proptrans_alist
23611 = Fdelq (aelt
, mode_line_proptrans_alist
);
23613 elt
= Fcopy_sequence (elt
);
23614 Fset_text_properties (make_number (0), Flength (elt
),
23616 /* Add this item to mode_line_proptrans_alist. */
23617 mode_line_proptrans_alist
23618 = Fcons (Fcons (elt
, props
),
23619 mode_line_proptrans_alist
);
23620 /* Truncate mode_line_proptrans_alist
23621 to at most 50 elements. */
23622 tem
= Fnthcdr (make_number (50),
23623 mode_line_proptrans_alist
);
23625 XSETCDR (tem
, Qnil
);
23634 prec
= precision
- n
;
23635 switch (mode_line_target
)
23637 case MODE_LINE_NOPROP
:
23638 case MODE_LINE_TITLE
:
23639 n
+= store_mode_line_noprop (SSDATA (elt
), -1, prec
);
23641 case MODE_LINE_STRING
:
23642 n
+= store_mode_line_string (NULL
, elt
, true, 0, prec
, Qnil
);
23644 case MODE_LINE_DISPLAY
:
23645 n
+= display_string (NULL
, elt
, Qnil
, 0, 0, it
,
23646 0, prec
, 0, STRING_MULTIBYTE (elt
));
23653 /* Handle the non-literal case. */
23655 while ((precision
<= 0 || n
< precision
)
23656 && SREF (elt
, offset
) != 0
23657 && (mode_line_target
!= MODE_LINE_DISPLAY
23658 || it
->current_x
< it
->last_visible_x
))
23660 ptrdiff_t last_offset
= offset
;
23662 /* Advance to end of string or next format specifier. */
23663 while ((c
= SREF (elt
, offset
++)) != '\0' && c
!= '%')
23666 if (offset
- 1 != last_offset
)
23668 ptrdiff_t nchars
, nbytes
;
23670 /* Output to end of string or up to '%'. Field width
23671 is length of string. Don't output more than
23672 PRECISION allows us. */
23675 prec
= c_string_width (SDATA (elt
) + last_offset
,
23676 offset
- last_offset
, precision
- n
,
23679 switch (mode_line_target
)
23681 case MODE_LINE_NOPROP
:
23682 case MODE_LINE_TITLE
:
23683 n
+= store_mode_line_noprop (SSDATA (elt
) + last_offset
, 0, prec
);
23685 case MODE_LINE_STRING
:
23687 ptrdiff_t bytepos
= last_offset
;
23688 ptrdiff_t charpos
= string_byte_to_char (elt
, bytepos
);
23689 ptrdiff_t endpos
= (precision
<= 0
23690 ? string_byte_to_char (elt
, offset
)
23691 : charpos
+ nchars
);
23692 Lisp_Object mode_string
23693 = Fsubstring (elt
, make_number (charpos
),
23694 make_number (endpos
));
23695 n
+= store_mode_line_string (NULL
, mode_string
, false,
23699 case MODE_LINE_DISPLAY
:
23701 ptrdiff_t bytepos
= last_offset
;
23702 ptrdiff_t charpos
= string_byte_to_char (elt
, bytepos
);
23704 if (precision
<= 0)
23705 nchars
= string_byte_to_char (elt
, offset
) - charpos
;
23706 n
+= display_string (NULL
, elt
, Qnil
, 0, charpos
,
23708 STRING_MULTIBYTE (elt
));
23713 else /* c == '%' */
23715 ptrdiff_t percent_position
= offset
;
23717 /* Get the specified minimum width. Zero means
23720 while ((c
= SREF (elt
, offset
++)) >= '0' && c
<= '9')
23721 field
= field
* 10 + c
- '0';
23723 /* Don't pad beyond the total padding allowed. */
23724 if (field_width
- n
> 0 && field
> field_width
- n
)
23725 field
= field_width
- n
;
23727 /* Note that either PRECISION <= 0 or N < PRECISION. */
23728 prec
= precision
- n
;
23731 n
+= display_mode_element (it
, depth
, field
, prec
,
23732 Vglobal_mode_string
, props
,
23737 ptrdiff_t bytepos
, charpos
;
23739 Lisp_Object string
;
23741 bytepos
= percent_position
;
23742 charpos
= (STRING_MULTIBYTE (elt
)
23743 ? string_byte_to_char (elt
, bytepos
)
23745 spec
= decode_mode_spec (it
->w
, c
, field
, &string
);
23746 multibyte
= STRINGP (string
) && STRING_MULTIBYTE (string
);
23748 switch (mode_line_target
)
23750 case MODE_LINE_NOPROP
:
23751 case MODE_LINE_TITLE
:
23752 n
+= store_mode_line_noprop (spec
, field
, prec
);
23754 case MODE_LINE_STRING
:
23756 Lisp_Object tem
= build_string (spec
);
23757 props
= Ftext_properties_at (make_number (charpos
), elt
);
23758 /* Should only keep face property in props */
23759 n
+= store_mode_line_string (NULL
, tem
, false,
23760 field
, prec
, props
);
23763 case MODE_LINE_DISPLAY
:
23765 int nglyphs_before
, nwritten
;
23767 nglyphs_before
= it
->glyph_row
->used
[TEXT_AREA
];
23768 nwritten
= display_string (spec
, string
, elt
,
23773 /* Assign to the glyphs written above the
23774 string where the `%x' came from, position
23778 struct glyph
*glyph
23779 = (it
->glyph_row
->glyphs
[TEXT_AREA
]
23783 for (i
= 0; i
< nwritten
; ++i
)
23785 glyph
[i
].object
= elt
;
23786 glyph
[i
].charpos
= charpos
;
23803 /* A symbol: process the value of the symbol recursively
23804 as if it appeared here directly. Avoid error if symbol void.
23805 Special case: if value of symbol is a string, output the string
23808 register Lisp_Object tem
;
23810 /* If the variable is not marked as risky to set
23811 then its contents are risky to use. */
23812 if (NILP (Fget (elt
, Qrisky_local_variable
)))
23815 tem
= Fboundp (elt
);
23818 tem
= Fsymbol_value (elt
);
23819 /* If value is a string, output that string literally:
23820 don't check for % within it. */
23824 if (!EQ (tem
, elt
))
23826 /* Give up right away for nil or t. */
23836 register Lisp_Object car
, tem
;
23838 /* A cons cell: five distinct cases.
23839 If first element is :eval or :propertize, do something special.
23840 If first element is a string or a cons, process all the elements
23841 and effectively concatenate them.
23842 If first element is a negative number, truncate displaying cdr to
23843 at most that many characters. If positive, pad (with spaces)
23844 to at least that many characters.
23845 If first element is a symbol, process the cadr or caddr recursively
23846 according to whether the symbol's value is non-nil or nil. */
23848 if (EQ (car
, QCeval
))
23850 /* An element of the form (:eval FORM) means evaluate FORM
23851 and use the result as mode line elements. */
23856 if (CONSP (XCDR (elt
)))
23859 spec
= safe__eval (true, XCAR (XCDR (elt
)));
23860 /* The :eval form could delete the frame stored in the
23861 iterator, which will cause a crash if we try to
23862 access faces and other fields (e.g., FRAME_KBOARD)
23863 on that frame. This is a nonsensical thing to do,
23864 and signaling an error from redisplay might be
23865 dangerous, but we cannot continue with an invalid frame. */
23866 if (!FRAME_LIVE_P (it
->f
))
23867 signal_error (":eval deleted the frame being displayed", elt
);
23868 n
+= display_mode_element (it
, depth
, field_width
- n
,
23869 precision
- n
, spec
, props
,
23873 else if (EQ (car
, QCpropertize
))
23875 /* An element of the form (:propertize ELT PROPS...)
23876 means display ELT but applying properties PROPS. */
23881 if (CONSP (XCDR (elt
)))
23882 n
+= display_mode_element (it
, depth
, field_width
- n
,
23883 precision
- n
, XCAR (XCDR (elt
)),
23884 XCDR (XCDR (elt
)), risky
);
23886 else if (SYMBOLP (car
))
23888 tem
= Fboundp (car
);
23892 /* elt is now the cdr, and we know it is a cons cell.
23893 Use its car if CAR has a non-nil value. */
23896 tem
= Fsymbol_value (car
);
23903 /* Symbol's value is nil (or symbol is unbound)
23904 Get the cddr of the original list
23905 and if possible find the caddr and use that. */
23909 else if (!CONSP (elt
))
23914 else if (INTEGERP (car
))
23916 register int lim
= XINT (car
);
23920 /* Negative int means reduce maximum width. */
23921 if (precision
<= 0)
23924 precision
= min (precision
, -lim
);
23928 /* Padding specified. Don't let it be more than
23929 current maximum. */
23931 lim
= min (precision
, lim
);
23933 /* If that's more padding than already wanted, queue it.
23934 But don't reduce padding already specified even if
23935 that is beyond the current truncation point. */
23936 field_width
= max (lim
, field_width
);
23940 else if (STRINGP (car
) || CONSP (car
))
23941 FOR_EACH_TAIL_SAFE (elt
)
23943 if (0 < precision
&& precision
<= n
)
23945 n
+= display_mode_element (it
, depth
,
23946 /* Pad after only the last
23948 (! CONSP (XCDR (elt
))
23951 precision
- n
, XCAR (elt
),
23959 elt
= build_string ("*invalid*");
23963 /* Pad to FIELD_WIDTH. */
23964 if (field_width
> 0 && n
< field_width
)
23966 switch (mode_line_target
)
23968 case MODE_LINE_NOPROP
:
23969 case MODE_LINE_TITLE
:
23970 n
+= store_mode_line_noprop ("", field_width
- n
, 0);
23972 case MODE_LINE_STRING
:
23973 n
+= store_mode_line_string ("", Qnil
, false, field_width
- n
, 0,
23976 case MODE_LINE_DISPLAY
:
23977 n
+= display_string ("", Qnil
, Qnil
, 0, 0, it
, field_width
- n
,
23986 /* Store a mode-line string element in mode_line_string_list.
23988 If STRING is non-null, display that C string. Otherwise, the Lisp
23989 string LISP_STRING is displayed.
23991 FIELD_WIDTH is the minimum number of output glyphs to produce.
23992 If STRING has fewer characters than FIELD_WIDTH, pad to the right
23993 with spaces. FIELD_WIDTH <= 0 means don't pad.
23995 PRECISION is the maximum number of characters to output from
23996 STRING. PRECISION <= 0 means don't truncate the string.
23998 If COPY_STRING, make a copy of LISP_STRING before adding
23999 properties to the string.
24001 PROPS are the properties to add to the string.
24002 The mode_line_string_face face property is always added to the string.
24006 store_mode_line_string (const char *string
, Lisp_Object lisp_string
,
24008 int field_width
, int precision
, Lisp_Object props
)
24013 if (string
!= NULL
)
24015 len
= strlen (string
);
24016 if (precision
> 0 && len
> precision
)
24018 lisp_string
= make_string (string
, len
);
24020 props
= mode_line_string_face_prop
;
24021 else if (!NILP (mode_line_string_face
))
24023 Lisp_Object face
= Fplist_get (props
, Qface
);
24024 props
= Fcopy_sequence (props
);
24026 face
= mode_line_string_face
;
24028 face
= list2 (face
, mode_line_string_face
);
24029 props
= Fplist_put (props
, Qface
, face
);
24031 Fadd_text_properties (make_number (0), make_number (len
),
24032 props
, lisp_string
);
24036 len
= XFASTINT (Flength (lisp_string
));
24037 if (precision
> 0 && len
> precision
)
24040 lisp_string
= Fsubstring (lisp_string
, make_number (0), make_number (len
));
24043 if (!NILP (mode_line_string_face
))
24047 props
= Ftext_properties_at (make_number (0), lisp_string
);
24048 face
= Fplist_get (props
, Qface
);
24050 face
= mode_line_string_face
;
24052 face
= list2 (face
, mode_line_string_face
);
24053 props
= list2 (Qface
, face
);
24055 lisp_string
= Fcopy_sequence (lisp_string
);
24058 Fadd_text_properties (make_number (0), make_number (len
),
24059 props
, lisp_string
);
24064 mode_line_string_list
= Fcons (lisp_string
, mode_line_string_list
);
24068 if (field_width
> len
)
24070 field_width
-= len
;
24071 lisp_string
= Fmake_string (make_number (field_width
), make_number (' '),
24074 Fadd_text_properties (make_number (0), make_number (field_width
),
24075 props
, lisp_string
);
24076 mode_line_string_list
= Fcons (lisp_string
, mode_line_string_list
);
24084 DEFUN ("format-mode-line", Fformat_mode_line
, Sformat_mode_line
,
24086 doc
: /* Format a string out of a mode line format specification.
24087 First arg FORMAT specifies the mode line format (see `mode-line-format'
24088 for details) to use.
24090 By default, the format is evaluated for the currently selected window.
24092 Optional second arg FACE specifies the face property to put on all
24093 characters for which no face is specified. The value nil means the
24094 default face. The value t means whatever face the window's mode line
24095 currently uses (either `mode-line' or `mode-line-inactive',
24096 depending on whether the window is the selected window or not).
24097 An integer value means the value string has no text
24100 Optional third and fourth args WINDOW and BUFFER specify the window
24101 and buffer to use as the context for the formatting (defaults
24102 are the selected window and the WINDOW's buffer). */)
24103 (Lisp_Object format
, Lisp_Object face
,
24104 Lisp_Object window
, Lisp_Object buffer
)
24109 struct buffer
*old_buffer
= NULL
;
24111 bool no_props
= INTEGERP (face
);
24112 ptrdiff_t count
= SPECPDL_INDEX ();
24114 int string_start
= 0;
24116 w
= decode_any_window (window
);
24117 XSETWINDOW (window
, w
);
24120 buffer
= w
->contents
;
24121 CHECK_BUFFER (buffer
);
24123 /* Make formatting the modeline a non-op when noninteractive, otherwise
24124 there will be problems later caused by a partially initialized frame. */
24125 if (NILP (format
) || noninteractive
)
24126 return empty_unibyte_string
;
24131 face_id
= (NILP (face
) || EQ (face
, Qdefault
)) ? DEFAULT_FACE_ID
24132 : EQ (face
, Qt
) ? (EQ (window
, selected_window
)
24133 ? MODE_LINE_FACE_ID
: MODE_LINE_INACTIVE_FACE_ID
)
24134 : EQ (face
, Qmode_line
) ? MODE_LINE_FACE_ID
24135 : EQ (face
, Qmode_line_inactive
) ? MODE_LINE_INACTIVE_FACE_ID
24136 : EQ (face
, Qheader_line
) ? HEADER_LINE_FACE_ID
24137 : EQ (face
, Qtool_bar
) ? TOOL_BAR_FACE_ID
24140 old_buffer
= current_buffer
;
24142 /* Save things including mode_line_proptrans_alist,
24143 and set that to nil so that we don't alter the outer value. */
24144 record_unwind_protect (unwind_format_mode_line
,
24145 format_mode_line_unwind_data
24146 (XFRAME (WINDOW_FRAME (w
)),
24147 old_buffer
, selected_window
, true));
24148 mode_line_proptrans_alist
= Qnil
;
24150 Fselect_window (window
, Qt
);
24151 set_buffer_internal_1 (XBUFFER (buffer
));
24153 init_iterator (&it
, w
, -1, -1, NULL
, face_id
);
24157 mode_line_target
= MODE_LINE_NOPROP
;
24158 mode_line_string_face_prop
= Qnil
;
24159 mode_line_string_list
= Qnil
;
24160 string_start
= MODE_LINE_NOPROP_LEN (0);
24164 mode_line_target
= MODE_LINE_STRING
;
24165 mode_line_string_list
= Qnil
;
24166 mode_line_string_face
= face
;
24167 mode_line_string_face_prop
24168 = NILP (face
) ? Qnil
: list2 (Qface
, face
);
24171 push_kboard (FRAME_KBOARD (it
.f
));
24172 display_mode_element (&it
, 0, 0, 0, format
, Qnil
, false);
24177 len
= MODE_LINE_NOPROP_LEN (string_start
);
24178 str
= make_string (mode_line_noprop_buf
+ string_start
, len
);
24182 mode_line_string_list
= Fnreverse (mode_line_string_list
);
24183 str
= Fmapconcat (Qidentity
, mode_line_string_list
,
24184 empty_unibyte_string
);
24187 unbind_to (count
, Qnil
);
24191 /* Write a null-terminated, right justified decimal representation of
24192 the positive integer D to BUF using a minimal field width WIDTH. */
24195 pint2str (register char *buf
, register int width
, register ptrdiff_t d
)
24197 register char *p
= buf
;
24205 *p
++ = d
% 10 + '0';
24210 for (width
-= (int) (p
- buf
); width
> 0; --width
)
24221 /* Write a null-terminated, right justified decimal and "human
24222 readable" representation of the nonnegative integer D to BUF using
24223 a minimal field width WIDTH. D should be smaller than 999.5e24. */
24225 static const char power_letter
[] =
24239 pint2hrstr (char *buf
, int width
, ptrdiff_t d
)
24241 /* We aim to represent the nonnegative integer D as
24242 QUOTIENT.TENTHS * 10 ^ (3 * EXPONENT). */
24243 ptrdiff_t quotient
= d
;
24245 /* -1 means: do not use TENTHS. */
24249 /* Length of QUOTIENT.TENTHS as a string. */
24255 if (quotient
>= 1000)
24257 /* Scale to the appropriate EXPONENT. */
24260 remainder
= quotient
% 1000;
24264 while (quotient
>= 1000);
24266 /* Round to nearest and decide whether to use TENTHS or not. */
24269 tenths
= remainder
/ 100;
24270 if (remainder
% 100 >= 50)
24277 if (quotient
== 10)
24285 if (remainder
>= 500)
24287 if (quotient
< 999)
24298 /* Calculate the LENGTH of QUOTIENT.TENTHS as a string. */
24299 if (tenths
== -1 && quotient
<= 99)
24306 p
= psuffix
= buf
+ max (width
, length
);
24308 /* Print EXPONENT. */
24309 *psuffix
++ = power_letter
[exponent
];
24312 /* Print TENTHS. */
24315 *--p
= '0' + tenths
;
24319 /* Print QUOTIENT. */
24322 int digit
= quotient
% 10;
24323 *--p
= '0' + digit
;
24325 while ((quotient
/= 10) != 0);
24327 /* Print leading spaces. */
24332 /* Set a mnemonic character for coding_system (Lisp symbol) in BUF.
24333 If EOL_FLAG, set also a mnemonic character for end-of-line
24334 type of CODING_SYSTEM. Return updated pointer into BUF. */
24336 static unsigned char invalid_eol_type
[] = "(*invalid*)";
24339 decode_mode_spec_coding (Lisp_Object coding_system
, char *buf
, bool eol_flag
)
24342 bool multibyte
= !NILP (BVAR (current_buffer
, enable_multibyte_characters
));
24343 const unsigned char *eol_str
;
24345 /* The EOL conversion we are using. */
24346 Lisp_Object eoltype
;
24348 val
= CODING_SYSTEM_SPEC (coding_system
);
24351 if (!VECTORP (val
)) /* Not yet decided. */
24353 *buf
++ = multibyte
? '-' : ' ';
24355 eoltype
= eol_mnemonic_undecided
;
24356 /* Don't mention EOL conversion if it isn't decided. */
24361 Lisp_Object eolvalue
;
24363 attrs
= AREF (val
, 0);
24364 eolvalue
= AREF (val
, 2);
24367 ? XFASTINT (CODING_ATTR_MNEMONIC (attrs
))
24372 /* The EOL conversion that is normal on this system. */
24374 if (NILP (eolvalue
)) /* Not yet decided. */
24375 eoltype
= eol_mnemonic_undecided
;
24376 else if (VECTORP (eolvalue
)) /* Not yet decided. */
24377 eoltype
= eol_mnemonic_undecided
;
24378 else /* eolvalue is Qunix, Qdos, or Qmac. */
24379 eoltype
= (EQ (eolvalue
, Qunix
)
24380 ? eol_mnemonic_unix
24381 : EQ (eolvalue
, Qdos
)
24382 ? eol_mnemonic_dos
: eol_mnemonic_mac
);
24388 /* Mention the EOL conversion if it is not the usual one. */
24389 if (STRINGP (eoltype
))
24391 eol_str
= SDATA (eoltype
);
24392 eol_str_len
= SBYTES (eoltype
);
24394 else if (CHARACTERP (eoltype
))
24396 int c
= XFASTINT (eoltype
);
24397 return buf
+ CHAR_STRING (c
, (unsigned char *) buf
);
24401 eol_str
= invalid_eol_type
;
24402 eol_str_len
= sizeof (invalid_eol_type
) - 1;
24404 memcpy (buf
, eol_str
, eol_str_len
);
24405 buf
+= eol_str_len
;
24411 /* Return the approximate percentage N is of D (rounding upward), or 99,
24412 whichever is less. Assume 0 < D and 0 <= N <= D * INT_MAX / 100. */
24415 percent99 (ptrdiff_t n
, ptrdiff_t d
)
24417 int percent
= (d
- 1 + 100.0 * n
) / d
;
24418 return min (percent
, 99);
24421 /* Return a string for the output of a mode line %-spec for window W,
24422 generated by character C. FIELD_WIDTH > 0 means pad the string
24423 returned with spaces to that value. Return a Lisp string in
24424 *STRING if the resulting string is taken from that Lisp string.
24426 Note we operate on the current buffer for most purposes. */
24428 static char lots_of_dashes
[] = "--------------------------------------------------------------------------------------------------------------------------------------------";
24430 static const char *
24431 decode_mode_spec (struct window
*w
, register int c
, int field_width
,
24432 Lisp_Object
*string
)
24435 struct frame
*f
= XFRAME (WINDOW_FRAME (w
));
24436 char *decode_mode_spec_buf
= f
->decode_mode_spec_buffer
;
24437 /* We are going to use f->decode_mode_spec_buffer as the buffer to
24438 produce strings from numerical values, so limit preposterously
24439 large values of FIELD_WIDTH to avoid overrunning the buffer's
24440 end. The size of the buffer is enough for FRAME_MESSAGE_BUF_SIZE
24441 bytes plus the terminating null. */
24442 int width
= min (field_width
, FRAME_MESSAGE_BUF_SIZE (f
));
24443 struct buffer
*b
= current_buffer
;
24451 if (!NILP (BVAR (b
, read_only
)))
24453 if (BUF_MODIFF (b
) > BUF_SAVE_MODIFF (b
))
24458 /* This differs from %* only for a modified read-only buffer. */
24459 if (BUF_MODIFF (b
) > BUF_SAVE_MODIFF (b
))
24461 if (!NILP (BVAR (b
, read_only
)))
24466 /* This differs from %* in ignoring read-only-ness. */
24467 if (BUF_MODIFF (b
) > BUF_SAVE_MODIFF (b
))
24479 if (command_loop_level
> 5)
24481 p
= decode_mode_spec_buf
;
24482 for (i
= 0; i
< command_loop_level
; i
++)
24485 return decode_mode_spec_buf
;
24493 if (command_loop_level
> 5)
24495 p
= decode_mode_spec_buf
;
24496 for (i
= 0; i
< command_loop_level
; i
++)
24499 return decode_mode_spec_buf
;
24506 /* Let lots_of_dashes be a string of infinite length. */
24507 if (mode_line_target
== MODE_LINE_NOPROP
24508 || mode_line_target
== MODE_LINE_STRING
)
24510 if (field_width
<= 0
24511 || field_width
> sizeof (lots_of_dashes
))
24513 for (i
= 0; i
< FRAME_MESSAGE_BUF_SIZE (f
) - 1; ++i
)
24514 decode_mode_spec_buf
[i
] = '-';
24515 decode_mode_spec_buf
[i
] = '\0';
24516 return decode_mode_spec_buf
;
24519 return lots_of_dashes
;
24523 obj
= BVAR (b
, name
);
24528 /* %c, %C, and %l are ignored in `frame-title-format'.
24529 (In redisplay_internal, the frame title is drawn _before_ the
24530 windows are updated, so the stuff which depends on actual
24531 window contents (such as %l) may fail to render properly, or
24532 even crash emacs.) */
24533 if (mode_line_target
== MODE_LINE_TITLE
)
24537 ptrdiff_t col
= current_column ();
24538 int disp_col
= (c
== 'C') ? col
+ 1 : col
;
24539 w
->column_number_displayed
= col
;
24540 pint2str (decode_mode_spec_buf
, width
, disp_col
);
24541 return decode_mode_spec_buf
;
24545 #if !defined SYSTEM_MALLOC && !defined HYBRID_MALLOC
24547 if (NILP (Vmemory_full
))
24550 return "!MEM FULL! ";
24557 /* %F displays the frame name. */
24558 if (!NILP (f
->title
))
24559 return SSDATA (f
->title
);
24560 if (f
->explicit_name
|| ! FRAME_WINDOW_P (f
))
24561 return SSDATA (f
->name
);
24565 obj
= BVAR (b
, filename
);
24570 ptrdiff_t size
= ZV
- BEGV
;
24571 pint2str (decode_mode_spec_buf
, width
, size
);
24572 return decode_mode_spec_buf
;
24577 ptrdiff_t size
= ZV
- BEGV
;
24578 pint2hrstr (decode_mode_spec_buf
, width
, size
);
24579 return decode_mode_spec_buf
;
24584 ptrdiff_t startpos
, startpos_byte
, line
, linepos
, linepos_byte
;
24585 ptrdiff_t topline
, nlines
, height
;
24588 /* %c, %C, and %l are ignored in `frame-title-format'. */
24589 if (mode_line_target
== MODE_LINE_TITLE
)
24592 startpos
= marker_position (w
->start
);
24593 startpos_byte
= marker_byte_position (w
->start
);
24594 height
= WINDOW_TOTAL_LINES (w
);
24596 /* If we decided that this buffer isn't suitable for line numbers,
24597 don't forget that too fast. */
24598 if (w
->base_line_pos
== -1)
24601 /* If the buffer is very big, don't waste time. */
24602 if (INTEGERP (Vline_number_display_limit
)
24603 && BUF_ZV (b
) - BUF_BEGV (b
) > XINT (Vline_number_display_limit
))
24605 w
->base_line_pos
= 0;
24606 w
->base_line_number
= 0;
24610 if (w
->base_line_number
> 0
24611 && w
->base_line_pos
> 0
24612 && w
->base_line_pos
<= startpos
)
24614 line
= w
->base_line_number
;
24615 linepos
= w
->base_line_pos
;
24616 linepos_byte
= buf_charpos_to_bytepos (b
, linepos
);
24621 linepos
= BUF_BEGV (b
);
24622 linepos_byte
= BUF_BEGV_BYTE (b
);
24625 /* Count lines from base line to window start position. */
24626 nlines
= display_count_lines (linepos_byte
,
24630 topline
= nlines
+ line
;
24632 /* Determine a new base line, if the old one is too close
24633 or too far away, or if we did not have one.
24634 "Too close" means it's plausible a scroll-down would
24635 go back past it. */
24636 if (startpos
== BUF_BEGV (b
))
24638 w
->base_line_number
= topline
;
24639 w
->base_line_pos
= BUF_BEGV (b
);
24641 else if (nlines
< height
+ 25 || nlines
> height
* 3 + 50
24642 || linepos
== BUF_BEGV (b
))
24644 ptrdiff_t limit
= BUF_BEGV (b
);
24645 ptrdiff_t limit_byte
= BUF_BEGV_BYTE (b
);
24646 ptrdiff_t position
;
24647 ptrdiff_t distance
=
24648 (height
* 2 + 30) * line_number_display_limit_width
;
24650 if (startpos
- distance
> limit
)
24652 limit
= startpos
- distance
;
24653 limit_byte
= CHAR_TO_BYTE (limit
);
24656 nlines
= display_count_lines (startpos_byte
,
24658 - (height
* 2 + 30),
24660 /* If we couldn't find the lines we wanted within
24661 line_number_display_limit_width chars per line,
24662 give up on line numbers for this window. */
24663 if (position
== limit_byte
&& limit
== startpos
- distance
)
24665 w
->base_line_pos
= -1;
24666 w
->base_line_number
= 0;
24670 w
->base_line_number
= topline
- nlines
;
24671 w
->base_line_pos
= BYTE_TO_CHAR (position
);
24674 /* Now count lines from the start pos to point. */
24675 nlines
= display_count_lines (startpos_byte
,
24676 PT_BYTE
, PT
, &junk
);
24678 /* Record that we did display the line number. */
24679 line_number_displayed
= true;
24681 /* Make the string to show. */
24682 pint2str (decode_mode_spec_buf
, width
, topline
+ nlines
);
24683 return decode_mode_spec_buf
;
24686 char *p
= decode_mode_spec_buf
;
24687 int pad
= width
- 2;
24693 return decode_mode_spec_buf
;
24699 obj
= BVAR (b
, mode_name
);
24703 if (BUF_BEGV (b
) > BUF_BEG (b
) || BUF_ZV (b
) < BUF_Z (b
))
24707 /* Display the "degree of travel" of the window through the buffer. */
24710 ptrdiff_t toppos
= marker_position (w
->start
);
24711 ptrdiff_t botpos
= BUF_Z (b
) - w
->window_end_pos
;
24712 ptrdiff_t begv
= BUF_BEGV (b
);
24713 ptrdiff_t zv
= BUF_ZV (b
);
24716 return toppos
<= begv
? "All" : "Bottom";
24717 else if (toppos
<= begv
)
24721 sprintf (decode_mode_spec_buf
, "%2d%%",
24722 percent99 (toppos
- begv
, (toppos
- begv
) + (zv
- botpos
)));
24723 return decode_mode_spec_buf
;
24727 /* Display percentage of buffer above the top of the screen. */
24730 ptrdiff_t pos
= marker_position (w
->start
);
24731 ptrdiff_t begv
= BUF_BEGV (b
);
24732 ptrdiff_t zv
= BUF_ZV (b
);
24734 if (w
->window_end_pos
<= BUF_Z (b
) - zv
)
24735 return pos
<= begv
? "All" : "Bottom";
24736 else if (pos
<= begv
)
24740 sprintf (decode_mode_spec_buf
, "%2d%%",
24741 percent99 (pos
- begv
, zv
- begv
));
24742 return decode_mode_spec_buf
;
24746 /* Display percentage of size above the bottom of the screen. */
24749 ptrdiff_t toppos
= marker_position (w
->start
);
24750 ptrdiff_t botpos
= BUF_Z (b
) - w
->window_end_pos
;
24751 ptrdiff_t begv
= BUF_BEGV (b
);
24752 ptrdiff_t zv
= BUF_ZV (b
);
24755 return toppos
<= begv
? "All" : "Bottom";
24758 sprintf (decode_mode_spec_buf
,
24759 &"Top%2d%%"[begv
< toppos
? sizeof "Top" - 1 : 0],
24760 percent99 (botpos
- begv
, zv
- begv
));
24761 return decode_mode_spec_buf
;
24765 /* Display percentage offsets of top and bottom of the window,
24766 using "All" (but not "Top" or "Bottom") where appropriate. */
24769 ptrdiff_t toppos
= marker_position (w
->start
);
24770 ptrdiff_t botpos
= BUF_Z (b
) - w
->window_end_pos
;
24771 ptrdiff_t begv
= BUF_BEGV (b
);
24772 ptrdiff_t zv
= BUF_ZV (b
);
24773 int top_perc
, bot_perc
;
24775 if ((toppos
<= begv
) && (zv
<= botpos
))
24778 top_perc
= toppos
<= begv
? 0 : percent99 (toppos
- begv
, zv
- begv
);
24779 bot_perc
= zv
<= botpos
? 100 : percent99 (botpos
- begv
, zv
- begv
);
24781 if (top_perc
== bot_perc
)
24782 sprintf (decode_mode_spec_buf
, "%d%%", top_perc
);
24784 sprintf (decode_mode_spec_buf
, "%d-%d%%", top_perc
, bot_perc
);
24786 return decode_mode_spec_buf
;
24790 /* status of process */
24791 obj
= Fget_buffer_process (Fcurrent_buffer ());
24793 return "no process";
24795 obj
= Fsymbol_name (Fprocess_status (obj
));
24801 ptrdiff_t count
= inhibit_garbage_collection ();
24802 Lisp_Object curdir
= BVAR (current_buffer
, directory
);
24803 Lisp_Object val
= Qnil
;
24805 if (STRINGP (curdir
))
24806 val
= call1 (intern ("file-remote-p"), curdir
);
24808 unbind_to (count
, Qnil
);
24817 /* coding-system (not including end-of-line format) */
24819 /* coding-system (including end-of-line type) */
24821 bool eol_flag
= (c
== 'Z');
24822 char *p
= decode_mode_spec_buf
;
24824 if (! FRAME_WINDOW_P (f
))
24826 /* No need to mention EOL here--the terminal never needs
24827 to do EOL conversion. */
24828 p
= decode_mode_spec_coding (CODING_ID_NAME
24829 (FRAME_KEYBOARD_CODING (f
)->id
),
24831 p
= decode_mode_spec_coding (CODING_ID_NAME
24832 (FRAME_TERMINAL_CODING (f
)->id
),
24835 p
= decode_mode_spec_coding (BVAR (b
, buffer_file_coding_system
),
24838 #if false /* This proves to be annoying; I think we can do without. -- rms. */
24839 #ifdef subprocesses
24840 obj
= Fget_buffer_process (Fcurrent_buffer ());
24841 if (PROCESSP (obj
))
24843 p
= decode_mode_spec_coding
24844 (XPROCESS (obj
)->decode_coding_system
, p
, eol_flag
);
24845 p
= decode_mode_spec_coding
24846 (XPROCESS (obj
)->encode_coding_system
, p
, eol_flag
);
24848 #endif /* subprocesses */
24851 return decode_mode_spec_buf
;
24858 return SSDATA (obj
);
24865 /* Count up to COUNT lines starting from START_BYTE. COUNT negative
24866 means count lines back from START_BYTE. But don't go beyond
24867 LIMIT_BYTE. Return the number of lines thus found (always
24870 Set *BYTE_POS_PTR to the byte position where we stopped. This is
24871 either the position COUNT lines after/before START_BYTE, if we
24872 found COUNT lines, or LIMIT_BYTE if we hit the limit before finding
24876 display_count_lines (ptrdiff_t start_byte
,
24877 ptrdiff_t limit_byte
, ptrdiff_t count
,
24878 ptrdiff_t *byte_pos_ptr
)
24880 register unsigned char *cursor
;
24881 unsigned char *base
;
24883 register ptrdiff_t ceiling
;
24884 register unsigned char *ceiling_addr
;
24885 ptrdiff_t orig_count
= count
;
24887 /* If we are not in selective display mode,
24888 check only for newlines. */
24889 bool selective_display
24890 = (!NILP (BVAR (current_buffer
, selective_display
))
24891 && !INTEGERP (BVAR (current_buffer
, selective_display
)));
24895 while (start_byte
< limit_byte
)
24897 ceiling
= BUFFER_CEILING_OF (start_byte
);
24898 ceiling
= min (limit_byte
- 1, ceiling
);
24899 ceiling_addr
= BYTE_POS_ADDR (ceiling
) + 1;
24900 base
= (cursor
= BYTE_POS_ADDR (start_byte
));
24904 if (selective_display
)
24906 while (*cursor
!= '\n' && *cursor
!= 015
24907 && ++cursor
!= ceiling_addr
)
24909 if (cursor
== ceiling_addr
)
24914 cursor
= memchr (cursor
, '\n', ceiling_addr
- cursor
);
24923 start_byte
+= cursor
- base
;
24924 *byte_pos_ptr
= start_byte
;
24928 while (cursor
< ceiling_addr
);
24930 start_byte
+= ceiling_addr
- base
;
24935 while (start_byte
> limit_byte
)
24937 ceiling
= BUFFER_FLOOR_OF (start_byte
- 1);
24938 ceiling
= max (limit_byte
, ceiling
);
24939 ceiling_addr
= BYTE_POS_ADDR (ceiling
);
24940 base
= (cursor
= BYTE_POS_ADDR (start_byte
- 1) + 1);
24943 if (selective_display
)
24945 while (--cursor
>= ceiling_addr
24946 && *cursor
!= '\n' && *cursor
!= 015)
24948 if (cursor
< ceiling_addr
)
24953 cursor
= memrchr (ceiling_addr
, '\n', cursor
- ceiling_addr
);
24960 start_byte
+= cursor
- base
+ 1;
24961 *byte_pos_ptr
= start_byte
;
24962 /* When scanning backwards, we should
24963 not count the newline posterior to which we stop. */
24964 return - orig_count
- 1;
24967 start_byte
+= ceiling_addr
- base
;
24971 *byte_pos_ptr
= limit_byte
;
24974 return - orig_count
+ count
;
24975 return orig_count
- count
;
24981 /***********************************************************************
24983 ***********************************************************************/
24985 /* Display a NUL-terminated string, starting with index START.
24987 If STRING is non-null, display that C string. Otherwise, the Lisp
24988 string LISP_STRING is displayed. There's a case that STRING is
24989 non-null and LISP_STRING is not nil. It means STRING is a string
24990 data of LISP_STRING. In that case, we display LISP_STRING while
24991 ignoring its text properties.
24993 If FACE_STRING is not nil, FACE_STRING_POS is a position in
24994 FACE_STRING. Display STRING or LISP_STRING with the face at
24995 FACE_STRING_POS in FACE_STRING:
24997 Display the string in the environment given by IT, but use the
24998 standard display table, temporarily.
25000 FIELD_WIDTH is the minimum number of output glyphs to produce.
25001 If STRING has fewer characters than FIELD_WIDTH, pad to the right
25002 with spaces. If STRING has more characters, more than FIELD_WIDTH
25003 glyphs will be produced. FIELD_WIDTH <= 0 means don't pad.
25005 PRECISION is the maximum number of characters to output from
25006 STRING. PRECISION < 0 means don't truncate the string.
25008 This is roughly equivalent to printf format specifiers:
25010 FIELD_WIDTH PRECISION PRINTF
25011 ----------------------------------------
25017 MULTIBYTE zero means do not display multibyte chars, > 0 means do
25018 display them, and < 0 means obey the current buffer's value of
25019 enable_multibyte_characters.
25021 Value is the number of columns displayed. */
25024 display_string (const char *string
, Lisp_Object lisp_string
, Lisp_Object face_string
,
25025 ptrdiff_t face_string_pos
, ptrdiff_t start
, struct it
*it
,
25026 int field_width
, int precision
, int max_x
, int multibyte
)
25028 int hpos_at_start
= it
->hpos
;
25029 int saved_face_id
= it
->face_id
;
25030 struct glyph_row
*row
= it
->glyph_row
;
25031 ptrdiff_t it_charpos
;
25033 /* Initialize the iterator IT for iteration over STRING beginning
25034 with index START. */
25035 reseat_to_string (it
, NILP (lisp_string
) ? string
: NULL
, lisp_string
, start
,
25036 precision
, field_width
, multibyte
);
25037 if (string
&& STRINGP (lisp_string
))
25038 /* LISP_STRING is the one returned by decode_mode_spec. We should
25039 ignore its text properties. */
25040 it
->stop_charpos
= it
->end_charpos
;
25042 /* If displaying STRING, set up the face of the iterator from
25043 FACE_STRING, if that's given. */
25044 if (STRINGP (face_string
))
25050 = face_at_string_position (it
->w
, face_string
, face_string_pos
,
25051 0, &endptr
, it
->base_face_id
, false);
25052 face
= FACE_FROM_ID (it
->f
, it
->face_id
);
25053 it
->face_box_p
= face
->box
!= FACE_NO_BOX
;
25056 /* Set max_x to the maximum allowed X position. Don't let it go
25057 beyond the right edge of the window. */
25059 max_x
= it
->last_visible_x
;
25061 max_x
= min (max_x
, it
->last_visible_x
);
25063 /* Skip over display elements that are not visible. because IT->w is
25065 if (it
->current_x
< it
->first_visible_x
)
25066 move_it_in_display_line_to (it
, 100000, it
->first_visible_x
,
25067 MOVE_TO_POS
| MOVE_TO_X
);
25069 row
->ascent
= it
->max_ascent
;
25070 row
->height
= it
->max_ascent
+ it
->max_descent
;
25071 row
->phys_ascent
= it
->max_phys_ascent
;
25072 row
->phys_height
= it
->max_phys_ascent
+ it
->max_phys_descent
;
25073 row
->extra_line_spacing
= it
->max_extra_line_spacing
;
25075 if (STRINGP (it
->string
))
25076 it_charpos
= IT_STRING_CHARPOS (*it
);
25078 it_charpos
= IT_CHARPOS (*it
);
25080 /* This condition is for the case that we are called with current_x
25081 past last_visible_x. */
25082 while (it
->current_x
< max_x
)
25084 int x_before
, x
, n_glyphs_before
, i
, nglyphs
;
25086 /* Get the next display element. */
25087 if (!get_next_display_element (it
))
25090 /* Produce glyphs. */
25091 x_before
= it
->current_x
;
25092 n_glyphs_before
= row
->used
[TEXT_AREA
];
25093 PRODUCE_GLYPHS (it
);
25095 nglyphs
= row
->used
[TEXT_AREA
] - n_glyphs_before
;
25098 while (i
< nglyphs
)
25100 struct glyph
*glyph
= row
->glyphs
[TEXT_AREA
] + n_glyphs_before
+ i
;
25102 if (it
->line_wrap
!= TRUNCATE
25103 && x
+ glyph
->pixel_width
> max_x
)
25105 /* End of continued line or max_x reached. */
25106 if (CHAR_GLYPH_PADDING_P (*glyph
))
25108 /* A wide character is unbreakable. */
25109 if (row
->reversed_p
)
25110 unproduce_glyphs (it
, row
->used
[TEXT_AREA
]
25111 - n_glyphs_before
);
25112 row
->used
[TEXT_AREA
] = n_glyphs_before
;
25113 it
->current_x
= x_before
;
25117 if (row
->reversed_p
)
25118 unproduce_glyphs (it
, row
->used
[TEXT_AREA
]
25119 - (n_glyphs_before
+ i
));
25120 row
->used
[TEXT_AREA
] = n_glyphs_before
+ i
;
25125 else if (x
+ glyph
->pixel_width
>= it
->first_visible_x
)
25127 /* Glyph is at least partially visible. */
25129 if (x
< it
->first_visible_x
)
25130 row
->x
= x
- it
->first_visible_x
;
25134 /* Glyph is off the left margin of the display area.
25135 Should not happen. */
25139 row
->ascent
= max (row
->ascent
, it
->max_ascent
);
25140 row
->height
= max (row
->height
, it
->max_ascent
+ it
->max_descent
);
25141 row
->phys_ascent
= max (row
->phys_ascent
, it
->max_phys_ascent
);
25142 row
->phys_height
= max (row
->phys_height
,
25143 it
->max_phys_ascent
+ it
->max_phys_descent
);
25144 row
->extra_line_spacing
= max (row
->extra_line_spacing
,
25145 it
->max_extra_line_spacing
);
25146 x
+= glyph
->pixel_width
;
25150 /* Stop if max_x reached. */
25154 /* Stop at line ends. */
25155 if (ITERATOR_AT_END_OF_LINE_P (it
))
25157 it
->continuation_lines_width
= 0;
25161 set_iterator_to_next (it
, true);
25162 if (STRINGP (it
->string
))
25163 it_charpos
= IT_STRING_CHARPOS (*it
);
25165 it_charpos
= IT_CHARPOS (*it
);
25167 /* Stop if truncating at the right edge. */
25168 if (it
->line_wrap
== TRUNCATE
25169 && it
->current_x
>= it
->last_visible_x
)
25171 /* Add truncation mark, but don't do it if the line is
25172 truncated at a padding space. */
25173 if (it_charpos
< it
->string_nchars
)
25175 if (!FRAME_WINDOW_P (it
->f
))
25179 if (it
->current_x
> it
->last_visible_x
)
25181 if (!row
->reversed_p
)
25183 for (ii
= row
->used
[TEXT_AREA
] - 1; ii
> 0; --ii
)
25184 if (!CHAR_GLYPH_PADDING_P (row
->glyphs
[TEXT_AREA
][ii
]))
25189 for (ii
= 0; ii
< row
->used
[TEXT_AREA
]; ii
++)
25190 if (!CHAR_GLYPH_PADDING_P (row
->glyphs
[TEXT_AREA
][ii
]))
25192 unproduce_glyphs (it
, ii
+ 1);
25193 ii
= row
->used
[TEXT_AREA
] - (ii
+ 1);
25195 for (n
= row
->used
[TEXT_AREA
]; ii
< n
; ++ii
)
25197 row
->used
[TEXT_AREA
] = ii
;
25198 produce_special_glyphs (it
, IT_TRUNCATION
);
25201 produce_special_glyphs (it
, IT_TRUNCATION
);
25203 row
->truncated_on_right_p
= true;
25209 /* Maybe insert a truncation at the left. */
25210 if (it
->first_visible_x
25213 if (!FRAME_WINDOW_P (it
->f
)
25214 || (row
->reversed_p
25215 ? WINDOW_RIGHT_FRINGE_WIDTH (it
->w
)
25216 : WINDOW_LEFT_FRINGE_WIDTH (it
->w
)) == 0)
25217 insert_left_trunc_glyphs (it
);
25218 row
->truncated_on_left_p
= true;
25221 it
->face_id
= saved_face_id
;
25223 /* Value is number of columns displayed. */
25224 return it
->hpos
- hpos_at_start
;
25229 /* This is like a combination of memq and assq. Return 1/2 if PROPVAL
25230 appears as an element of LIST or as the car of an element of LIST.
25231 If PROPVAL is a list, compare each element against LIST in that
25232 way, and return 1/2 if any element of PROPVAL is found in LIST.
25233 Otherwise return 0. This function cannot quit.
25234 The return value is 2 if the text is invisible but with an ellipsis
25235 and 1 if it's invisible and without an ellipsis. */
25238 invisible_prop (Lisp_Object propval
, Lisp_Object list
)
25240 Lisp_Object tail
, proptail
;
25242 for (tail
= list
; CONSP (tail
); tail
= XCDR (tail
))
25244 register Lisp_Object tem
;
25246 if (EQ (propval
, tem
))
25248 if (CONSP (tem
) && EQ (propval
, XCAR (tem
)))
25249 return NILP (XCDR (tem
)) ? 1 : 2;
25252 if (CONSP (propval
))
25254 for (proptail
= propval
; CONSP (proptail
); proptail
= XCDR (proptail
))
25256 Lisp_Object propelt
;
25257 propelt
= XCAR (proptail
);
25258 for (tail
= list
; CONSP (tail
); tail
= XCDR (tail
))
25260 register Lisp_Object tem
;
25262 if (EQ (propelt
, tem
))
25264 if (CONSP (tem
) && EQ (propelt
, XCAR (tem
)))
25265 return NILP (XCDR (tem
)) ? 1 : 2;
25273 DEFUN ("invisible-p", Finvisible_p
, Sinvisible_p
, 1, 1, 0,
25274 doc
: /* Non-nil if text properties at POS cause text there to be currently invisible.
25275 POS should be a marker or a buffer position; the value of the `invisible'
25276 property at that position in the current buffer is examined.
25277 POS can also be the actual value of the `invisible' text or overlay
25278 property of the text of interest, in which case the value itself is
25281 The non-nil value returned can be t for currently invisible text that is
25282 entirely hidden on display, or some other non-nil, non-t value if the
25283 text is replaced by an ellipsis.
25285 Note that whether text with `invisible' property is actually hidden on
25286 display may depend on `buffer-invisibility-spec', which see. */)
25290 = (NATNUMP (pos
) || MARKERP (pos
)
25291 ? Fget_char_property (pos
, Qinvisible
, Qnil
)
25293 int invis
= TEXT_PROP_MEANS_INVISIBLE (prop
);
25294 return (invis
== 0 ? Qnil
25296 : make_number (invis
));
25299 /* Calculate a width or height in pixels from a specification using
25300 the following elements:
25303 NUM - a (fractional) multiple of the default font width/height
25304 (NUM) - specifies exactly NUM pixels
25305 UNIT - a fixed number of pixels, see below.
25306 ELEMENT - size of a display element in pixels, see below.
25307 (NUM . SPEC) - equals NUM * SPEC
25308 (+ SPEC SPEC ...) - add pixel values
25309 (- SPEC SPEC ...) - subtract pixel values
25310 (- SPEC) - negate pixel value
25313 INT or FLOAT - a number constant
25314 SYMBOL - use symbol's (buffer local) variable binding.
25317 in - pixels per inch *)
25318 mm - pixels per 1/1000 meter *)
25319 cm - pixels per 1/100 meter *)
25320 width - width of current font in pixels.
25321 height - height of current font in pixels.
25323 *) using the ratio(s) defined in display-pixels-per-inch.
25327 left-fringe - left fringe width in pixels
25328 right-fringe - right fringe width in pixels
25330 left-margin - left margin width in pixels
25331 right-margin - right margin width in pixels
25333 scroll-bar - scroll-bar area width in pixels
25337 Pixels corresponding to 5 inches:
25340 Total width of non-text areas on left side of window (if scroll-bar is on left):
25341 '(space :width (+ left-fringe left-margin scroll-bar))
25343 Align to first text column (in header line):
25344 '(space :align-to 0)
25346 Align to middle of text area minus half the width of variable `my-image'
25347 containing a loaded image:
25348 '(space :align-to (0.5 . (- text my-image)))
25350 Width of left margin minus width of 1 character in the default font:
25351 '(space :width (- left-margin 1))
25353 Width of left margin minus width of 2 characters in the current font:
25354 '(space :width (- left-margin (2 . width)))
25356 Center 1 character over left-margin (in header line):
25357 '(space :align-to (+ left-margin (0.5 . left-margin) -0.5))
25359 Different ways to express width of left fringe plus left margin minus one pixel:
25360 '(space :width (- (+ left-fringe left-margin) (1)))
25361 '(space :width (+ left-fringe left-margin (- (1))))
25362 '(space :width (+ left-fringe left-margin (-1)))
25364 If ALIGN_TO is NULL, returns the result in *RES. If ALIGN_TO is
25365 non-NULL, the value of *ALIGN_TO is a window-relative pixel
25366 coordinate, and *RES is the additional pixel width from that point
25367 till the end of the stretch glyph.
25369 WIDTH_P non-zero means take the width dimension or X coordinate of
25370 the object specified by PROP, WIDTH_P zero means take the height
25371 dimension or the Y coordinate. (Therefore, if ALIGN_TO is
25372 non-NULL, WIDTH_P should be non-zero.)
25374 FONT is the font of the face of the surrounding text.
25376 The return value is non-zero if width or height were successfully
25377 calculated, i.e. if PROP is a valid spec. */
25380 calc_pixel_width_or_height (double *res
, struct it
*it
, Lisp_Object prop
,
25381 struct font
*font
, bool width_p
, int *align_to
)
25385 # define OK_PIXELS(val) (*res = (val), true)
25386 # define OK_ALIGN_TO(val) (*align_to = (val), true)
25389 return OK_PIXELS (0);
25391 eassert (FRAME_LIVE_P (it
->f
));
25393 if (SYMBOLP (prop
))
25395 if (SCHARS (SYMBOL_NAME (prop
)) == 2)
25397 char *unit
= SSDATA (SYMBOL_NAME (prop
));
25399 /* The UNIT expression, e.g. as part of (NUM . UNIT). */
25400 if (unit
[0] == 'i' && unit
[1] == 'n')
25402 else if (unit
[0] == 'm' && unit
[1] == 'm')
25404 else if (unit
[0] == 'c' && unit
[1] == 'm')
25410 double ppi
= (width_p
? FRAME_RES_X (it
->f
)
25411 : FRAME_RES_Y (it
->f
));
25414 return OK_PIXELS (ppi
/ pixels
);
25419 #ifdef HAVE_WINDOW_SYSTEM
25420 /* 'height': the height of FONT. */
25421 if (EQ (prop
, Qheight
))
25422 return OK_PIXELS (font
25423 ? normal_char_height (font
, -1)
25424 : FRAME_LINE_HEIGHT (it
->f
));
25425 /* 'width': the width of FONT. */
25426 if (EQ (prop
, Qwidth
))
25427 return OK_PIXELS (font
25428 ? FONT_WIDTH (font
)
25429 : FRAME_COLUMN_WIDTH (it
->f
));
25431 if (EQ (prop
, Qheight
) || EQ (prop
, Qwidth
))
25432 return OK_PIXELS (1);
25435 /* 'text': the width or height of the text area. */
25436 if (EQ (prop
, Qtext
))
25437 return OK_PIXELS (width_p
25438 ? (window_box_width (it
->w
, TEXT_AREA
)
25439 - it
->lnum_pixel_width
)
25440 : WINDOW_BOX_HEIGHT_NO_MODE_LINE (it
->w
));
25442 /* ':align_to'. First time we compute the value, window
25443 elements are interpreted as the position of the element's
25445 if (align_to
&& *align_to
< 0)
25448 /* 'left': left edge of the text area. */
25449 if (EQ (prop
, Qleft
))
25450 return OK_ALIGN_TO (window_box_left_offset (it
->w
, TEXT_AREA
)
25451 + it
->lnum_pixel_width
);
25452 /* 'right': right edge of the text area. */
25453 if (EQ (prop
, Qright
))
25454 return OK_ALIGN_TO (window_box_right_offset (it
->w
, TEXT_AREA
));
25455 /* 'center': the center of the text area. */
25456 if (EQ (prop
, Qcenter
))
25457 return OK_ALIGN_TO (window_box_left_offset (it
->w
, TEXT_AREA
)
25458 + it
->lnum_pixel_width
25459 + window_box_width (it
->w
, TEXT_AREA
) / 2);
25460 /* 'left-fringe': left edge of the left fringe. */
25461 if (EQ (prop
, Qleft_fringe
))
25462 return OK_ALIGN_TO (WINDOW_HAS_FRINGES_OUTSIDE_MARGINS (it
->w
)
25463 ? WINDOW_LEFT_SCROLL_BAR_AREA_WIDTH (it
->w
)
25464 : window_box_right_offset (it
->w
, LEFT_MARGIN_AREA
));
25465 /* 'right-fringe': left edge of the right fringe. */
25466 if (EQ (prop
, Qright_fringe
))
25467 return OK_ALIGN_TO (WINDOW_HAS_FRINGES_OUTSIDE_MARGINS (it
->w
)
25468 ? window_box_right_offset (it
->w
, RIGHT_MARGIN_AREA
)
25469 : window_box_right_offset (it
->w
, TEXT_AREA
));
25470 /* 'left-margin': left edge of the left display margin. */
25471 if (EQ (prop
, Qleft_margin
))
25472 return OK_ALIGN_TO (window_box_left_offset (it
->w
, LEFT_MARGIN_AREA
));
25473 /* 'right-margin': left edge of the right display margin. */
25474 if (EQ (prop
, Qright_margin
))
25475 return OK_ALIGN_TO (window_box_left_offset (it
->w
, RIGHT_MARGIN_AREA
));
25476 /* 'scroll-bar': left edge of the vertical scroll bar. */
25477 if (EQ (prop
, Qscroll_bar
))
25478 return OK_ALIGN_TO (WINDOW_HAS_VERTICAL_SCROLL_BAR_ON_LEFT (it
->w
)
25480 : (window_box_right_offset (it
->w
, RIGHT_MARGIN_AREA
)
25481 + (WINDOW_HAS_FRINGES_OUTSIDE_MARGINS (it
->w
)
25482 ? WINDOW_RIGHT_FRINGE_WIDTH (it
->w
)
25487 /* Otherwise, the elements stand for their width. */
25488 if (EQ (prop
, Qleft_fringe
))
25489 return OK_PIXELS (WINDOW_LEFT_FRINGE_WIDTH (it
->w
));
25490 if (EQ (prop
, Qright_fringe
))
25491 return OK_PIXELS (WINDOW_RIGHT_FRINGE_WIDTH (it
->w
));
25492 if (EQ (prop
, Qleft_margin
))
25493 return OK_PIXELS (WINDOW_LEFT_MARGIN_WIDTH (it
->w
));
25494 if (EQ (prop
, Qright_margin
))
25495 return OK_PIXELS (WINDOW_RIGHT_MARGIN_WIDTH (it
->w
));
25496 if (EQ (prop
, Qscroll_bar
))
25497 return OK_PIXELS (WINDOW_SCROLL_BAR_AREA_WIDTH (it
->w
));
25500 prop
= buffer_local_value (prop
, it
->w
->contents
);
25501 if (EQ (prop
, Qunbound
))
25505 if (NUMBERP (prop
))
25507 int base_unit
= (width_p
25508 ? FRAME_COLUMN_WIDTH (it
->f
)
25509 : FRAME_LINE_HEIGHT (it
->f
));
25510 if (width_p
&& align_to
&& *align_to
< 0)
25511 return OK_PIXELS (XFLOATINT (prop
) * base_unit
+ it
->lnum_pixel_width
);
25512 return OK_PIXELS (XFLOATINT (prop
) * base_unit
);
25517 Lisp_Object car
= XCAR (prop
);
25518 Lisp_Object cdr
= XCDR (prop
);
25522 #ifdef HAVE_WINDOW_SYSTEM
25523 /* '(image PROPS...)': width or height of the specified image. */
25524 if (FRAME_WINDOW_P (it
->f
)
25525 && valid_image_p (prop
))
25527 ptrdiff_t id
= lookup_image (it
->f
, prop
);
25528 struct image
*img
= IMAGE_FROM_ID (it
->f
, id
);
25530 return OK_PIXELS (width_p
? img
->width
: img
->height
);
25532 /* '(xwidget PROPS...)': dimensions of the specified xwidget. */
25533 if (FRAME_WINDOW_P (it
->f
) && valid_xwidget_spec_p (prop
))
25535 /* TODO: Don't return dummy size. */
25536 return OK_PIXELS (100);
25539 /* '(+ EXPR...)' or '(- EXPR...)' add or subtract
25540 recursively calculated values. */
25541 if (EQ (car
, Qplus
) || EQ (car
, Qminus
))
25547 while (CONSP (cdr
))
25549 if (!calc_pixel_width_or_height (&px
, it
, XCAR (cdr
),
25550 font
, width_p
, align_to
))
25553 pixels
= (EQ (car
, Qplus
) ? px
: -px
), first
= false;
25558 if (EQ (car
, Qminus
))
25560 return OK_PIXELS (pixels
);
25563 car
= buffer_local_value (car
, it
->w
->contents
);
25564 if (EQ (car
, Qunbound
))
25568 /* '(NUM)': absolute number of pixels. */
25573 width_p
&& align_to
&& *align_to
< 0 ? it
->lnum_pixel_width
: 0;
25574 pixels
= XFLOATINT (car
);
25576 return OK_PIXELS (pixels
+ offset
);
25577 if (calc_pixel_width_or_height (&fact
, it
, cdr
,
25578 font
, width_p
, align_to
))
25579 return OK_PIXELS (pixels
* fact
+ offset
);
25590 get_font_ascent_descent (struct font
*font
, int *ascent
, int *descent
)
25592 #ifdef HAVE_WINDOW_SYSTEM
25593 normal_char_ascent_descent (font
, -1, ascent
, descent
);
25601 /***********************************************************************
25603 ***********************************************************************/
25605 #ifdef HAVE_WINDOW_SYSTEM
25610 dump_glyph_string (struct glyph_string
*s
)
25612 fprintf (stderr
, "glyph string\n");
25613 fprintf (stderr
, " x, y, w, h = %d, %d, %d, %d\n",
25614 s
->x
, s
->y
, s
->width
, s
->height
);
25615 fprintf (stderr
, " ybase = %d\n", s
->ybase
);
25616 fprintf (stderr
, " hl = %u\n", s
->hl
);
25617 fprintf (stderr
, " left overhang = %d, right = %d\n",
25618 s
->left_overhang
, s
->right_overhang
);
25619 fprintf (stderr
, " nchars = %d\n", s
->nchars
);
25620 fprintf (stderr
, " extends to end of line = %d\n",
25621 s
->extends_to_end_of_line_p
);
25622 fprintf (stderr
, " font height = %d\n", FONT_HEIGHT (s
->font
));
25623 fprintf (stderr
, " bg width = %d\n", s
->background_width
);
25626 #endif /* GLYPH_DEBUG */
25628 /* Initialize glyph string S. CHAR2B is a suitably allocated vector
25629 of XChar2b structures for S; it can't be allocated in
25630 init_glyph_string because it must be allocated via `alloca'. W
25631 is the window on which S is drawn. ROW and AREA are the glyph row
25632 and area within the row from which S is constructed. START is the
25633 index of the first glyph structure covered by S. HL is a
25634 face-override for drawing S. */
25637 #define OPTIONAL_HDC(hdc) HDC hdc,
25638 #define DECLARE_HDC(hdc) HDC hdc;
25639 #define ALLOCATE_HDC(hdc, f) hdc = get_frame_dc ((f))
25640 #define RELEASE_HDC(hdc, f) release_frame_dc ((f), (hdc))
25643 #ifndef OPTIONAL_HDC
25644 #define OPTIONAL_HDC(hdc)
25645 #define DECLARE_HDC(hdc)
25646 #define ALLOCATE_HDC(hdc, f)
25647 #define RELEASE_HDC(hdc, f)
25651 init_glyph_string (struct glyph_string
*s
,
25653 XChar2b
*char2b
, struct window
*w
, struct glyph_row
*row
,
25654 enum glyph_row_area area
, int start
, enum draw_glyphs_face hl
)
25656 memset (s
, 0, sizeof *s
);
25658 s
->f
= XFRAME (w
->frame
);
25662 s
->display
= FRAME_X_DISPLAY (s
->f
);
25663 s
->char2b
= char2b
;
25667 s
->first_glyph
= row
->glyphs
[area
] + start
;
25668 s
->height
= row
->height
;
25669 s
->y
= WINDOW_TO_FRAME_PIXEL_Y (w
, row
->y
);
25670 s
->ybase
= s
->y
+ row
->ascent
;
25674 /* Append the list of glyph strings with head H and tail T to the list
25675 with head *HEAD and tail *TAIL. Set *HEAD and *TAIL to the result. */
25678 append_glyph_string_lists (struct glyph_string
**head
, struct glyph_string
**tail
,
25679 struct glyph_string
*h
, struct glyph_string
*t
)
25693 /* Prepend the list of glyph strings with head H and tail T to the
25694 list with head *HEAD and tail *TAIL. Set *HEAD and *TAIL to the
25698 prepend_glyph_string_lists (struct glyph_string
**head
, struct glyph_string
**tail
,
25699 struct glyph_string
*h
, struct glyph_string
*t
)
25713 /* Append glyph string S to the list with head *HEAD and tail *TAIL.
25714 Set *HEAD and *TAIL to the resulting list. */
25717 append_glyph_string (struct glyph_string
**head
, struct glyph_string
**tail
,
25718 struct glyph_string
*s
)
25720 s
->next
= s
->prev
= NULL
;
25721 append_glyph_string_lists (head
, tail
, s
, s
);
25725 /* Get face and two-byte form of character C in face FACE_ID on frame F.
25726 The encoding of C is returned in *CHAR2B. DISPLAY_P means
25727 make sure that X resources for the face returned are allocated.
25728 Value is a pointer to a realized face that is ready for display if
25731 static struct face
*
25732 get_char_face_and_encoding (struct frame
*f
, int c
, int face_id
,
25733 XChar2b
*char2b
, bool display_p
)
25735 struct face
*face
= FACE_FROM_ID (f
, face_id
);
25740 code
= face
->font
->driver
->encode_char (face
->font
, c
);
25742 if (code
== FONT_INVALID_CODE
)
25745 STORE_XCHAR2B (char2b
, (code
>> 8), (code
& 0xFF));
25747 /* Make sure X resources of the face are allocated. */
25748 #ifdef HAVE_X_WINDOWS
25752 eassert (face
!= NULL
);
25753 prepare_face_for_display (f
, face
);
25760 /* Get face and two-byte form of character glyph GLYPH on frame F.
25761 The encoding of GLYPH->u.ch is returned in *CHAR2B. Value is
25762 a pointer to a realized face that is ready for display. */
25764 static struct face
*
25765 get_glyph_face_and_encoding (struct frame
*f
, struct glyph
*glyph
,
25771 eassert (glyph
->type
== CHAR_GLYPH
);
25772 face
= FACE_FROM_ID (f
, glyph
->face_id
);
25774 /* Make sure X resources of the face are allocated. */
25775 prepare_face_for_display (f
, face
);
25779 if (CHAR_BYTE8_P (glyph
->u
.ch
))
25780 code
= CHAR_TO_BYTE8 (glyph
->u
.ch
);
25782 code
= face
->font
->driver
->encode_char (face
->font
, glyph
->u
.ch
);
25784 if (code
== FONT_INVALID_CODE
)
25788 STORE_XCHAR2B (char2b
, (code
>> 8), (code
& 0xFF));
25793 /* Get glyph code of character C in FONT in the two-byte form CHAR2B.
25794 Return true iff FONT has a glyph for C. */
25797 get_char_glyph_code (int c
, struct font
*font
, XChar2b
*char2b
)
25801 if (CHAR_BYTE8_P (c
))
25802 code
= CHAR_TO_BYTE8 (c
);
25804 code
= font
->driver
->encode_char (font
, c
);
25806 if (code
== FONT_INVALID_CODE
)
25808 STORE_XCHAR2B (char2b
, (code
>> 8), (code
& 0xFF));
25813 /* Fill glyph string S with composition components specified by S->cmp.
25815 BASE_FACE is the base face of the composition.
25816 S->cmp_from is the index of the first component for S.
25818 OVERLAPS non-zero means S should draw the foreground only, and use
25819 its physical height for clipping. See also draw_glyphs.
25821 Value is the index of a component not in S. */
25824 fill_composite_glyph_string (struct glyph_string
*s
, struct face
*base_face
,
25828 /* For all glyphs of this composition, starting at the offset
25829 S->cmp_from, until we reach the end of the definition or encounter a
25830 glyph that requires the different face, add it to S. */
25835 s
->for_overlaps
= overlaps
;
25838 for (i
= s
->cmp_from
; i
< s
->cmp
->glyph_len
; i
++)
25840 int c
= COMPOSITION_GLYPH (s
->cmp
, i
);
25842 /* TAB in a composition means display glyphs with padding space
25843 on the left or right. */
25846 int face_id
= FACE_FOR_CHAR (s
->f
, base_face
->ascii_face
, c
,
25849 face
= get_char_face_and_encoding (s
->f
, c
, face_id
,
25850 s
->char2b
+ i
, true);
25856 s
->font
= s
->face
->font
;
25858 else if (s
->face
!= face
)
25866 if (s
->face
== NULL
)
25868 s
->face
= base_face
->ascii_face
;
25869 s
->font
= s
->face
->font
;
25872 /* All glyph strings for the same composition has the same width,
25873 i.e. the width set for the first component of the composition. */
25874 s
->width
= s
->first_glyph
->pixel_width
;
25876 /* If the specified font could not be loaded, use the frame's
25877 default font, but record the fact that we couldn't load it in
25878 the glyph string so that we can draw rectangles for the
25879 characters of the glyph string. */
25880 if (s
->font
== NULL
)
25882 s
->font_not_found_p
= true;
25883 s
->font
= FRAME_FONT (s
->f
);
25886 /* Adjust base line for subscript/superscript text. */
25887 s
->ybase
+= s
->first_glyph
->voffset
;
25893 fill_gstring_glyph_string (struct glyph_string
*s
, int face_id
,
25894 int start
, int end
, int overlaps
)
25896 struct glyph
*glyph
, *last
;
25897 Lisp_Object lgstring
;
25900 s
->for_overlaps
= overlaps
;
25901 glyph
= s
->row
->glyphs
[s
->area
] + start
;
25902 last
= s
->row
->glyphs
[s
->area
] + end
;
25903 s
->cmp_id
= glyph
->u
.cmp
.id
;
25904 s
->cmp_from
= glyph
->slice
.cmp
.from
;
25905 s
->cmp_to
= glyph
->slice
.cmp
.to
+ 1;
25906 s
->face
= FACE_FROM_ID (s
->f
, face_id
);
25907 lgstring
= composition_gstring_from_id (s
->cmp_id
);
25908 s
->font
= XFONT_OBJECT (LGSTRING_FONT (lgstring
));
25910 while (glyph
< last
25911 && glyph
->u
.cmp
.automatic
25912 && glyph
->u
.cmp
.id
== s
->cmp_id
25913 && s
->cmp_to
== glyph
->slice
.cmp
.from
)
25914 s
->cmp_to
= (glyph
++)->slice
.cmp
.to
+ 1;
25916 for (i
= s
->cmp_from
; i
< s
->cmp_to
; i
++)
25918 Lisp_Object lglyph
= LGSTRING_GLYPH (lgstring
, i
);
25919 unsigned code
= LGLYPH_CODE (lglyph
);
25921 STORE_XCHAR2B ((s
->char2b
+ i
), code
>> 8, code
& 0xFF);
25923 s
->width
= composition_gstring_width (lgstring
, s
->cmp_from
, s
->cmp_to
, NULL
);
25924 return glyph
- s
->row
->glyphs
[s
->area
];
25928 /* Fill glyph string S from a sequence glyphs for glyphless characters.
25929 See the comment of fill_glyph_string for arguments.
25930 Value is the index of the first glyph not in S. */
25934 fill_glyphless_glyph_string (struct glyph_string
*s
, int face_id
,
25935 int start
, int end
, int overlaps
)
25937 struct glyph
*glyph
, *last
;
25940 eassert (s
->first_glyph
->type
== GLYPHLESS_GLYPH
);
25941 s
->for_overlaps
= overlaps
;
25942 glyph
= s
->row
->glyphs
[s
->area
] + start
;
25943 last
= s
->row
->glyphs
[s
->area
] + end
;
25944 voffset
= glyph
->voffset
;
25945 s
->face
= FACE_FROM_ID (s
->f
, face_id
);
25946 s
->font
= s
->face
->font
? s
->face
->font
: FRAME_FONT (s
->f
);
25948 s
->width
= glyph
->pixel_width
;
25950 while (glyph
< last
25951 && glyph
->type
== GLYPHLESS_GLYPH
25952 && glyph
->voffset
== voffset
25953 && glyph
->face_id
== face_id
)
25956 s
->width
+= glyph
->pixel_width
;
25959 s
->ybase
+= voffset
;
25960 return glyph
- s
->row
->glyphs
[s
->area
];
25964 /* Fill glyph string S from a sequence of character glyphs.
25966 FACE_ID is the face id of the string. START is the index of the
25967 first glyph to consider, END is the index of the last + 1.
25968 OVERLAPS non-zero means S should draw the foreground only, and use
25969 its physical height for clipping. See also draw_glyphs.
25971 Value is the index of the first glyph not in S. */
25974 fill_glyph_string (struct glyph_string
*s
, int face_id
,
25975 int start
, int end
, int overlaps
)
25977 struct glyph
*glyph
, *last
;
25979 bool glyph_not_available_p
;
25981 eassert (s
->f
== XFRAME (s
->w
->frame
));
25982 eassert (s
->nchars
== 0);
25983 eassert (start
>= 0 && end
> start
);
25985 s
->for_overlaps
= overlaps
;
25986 glyph
= s
->row
->glyphs
[s
->area
] + start
;
25987 last
= s
->row
->glyphs
[s
->area
] + end
;
25988 voffset
= glyph
->voffset
;
25989 s
->padding_p
= glyph
->padding_p
;
25990 glyph_not_available_p
= glyph
->glyph_not_available_p
;
25992 while (glyph
< last
25993 && glyph
->type
== CHAR_GLYPH
25994 && glyph
->voffset
== voffset
25995 /* Same face id implies same font, nowadays. */
25996 && glyph
->face_id
== face_id
25997 && glyph
->glyph_not_available_p
== glyph_not_available_p
)
25999 s
->face
= get_glyph_face_and_encoding (s
->f
, glyph
,
26000 s
->char2b
+ s
->nchars
);
26002 eassert (s
->nchars
<= end
- start
);
26003 s
->width
+= glyph
->pixel_width
;
26004 if (glyph
++->padding_p
!= s
->padding_p
)
26008 s
->font
= s
->face
->font
;
26010 /* If the specified font could not be loaded, use the frame's font,
26011 but record the fact that we couldn't load it in
26012 S->font_not_found_p so that we can draw rectangles for the
26013 characters of the glyph string. */
26014 if (s
->font
== NULL
|| glyph_not_available_p
)
26016 s
->font_not_found_p
= true;
26017 s
->font
= FRAME_FONT (s
->f
);
26020 /* Adjust base line for subscript/superscript text. */
26021 s
->ybase
+= voffset
;
26023 eassert (s
->face
&& s
->face
->gc
);
26024 return glyph
- s
->row
->glyphs
[s
->area
];
26028 /* Fill glyph string S from image glyph S->first_glyph. */
26031 fill_image_glyph_string (struct glyph_string
*s
)
26033 eassert (s
->first_glyph
->type
== IMAGE_GLYPH
);
26034 s
->img
= IMAGE_FROM_ID (s
->f
, s
->first_glyph
->u
.img_id
);
26036 s
->slice
= s
->first_glyph
->slice
.img
;
26037 s
->face
= FACE_FROM_ID (s
->f
, s
->first_glyph
->face_id
);
26038 s
->font
= s
->face
->font
;
26039 s
->width
= s
->first_glyph
->pixel_width
;
26041 /* Adjust base line for subscript/superscript text. */
26042 s
->ybase
+= s
->first_glyph
->voffset
;
26046 #ifdef HAVE_XWIDGETS
26048 fill_xwidget_glyph_string (struct glyph_string
*s
)
26050 eassert (s
->first_glyph
->type
== XWIDGET_GLYPH
);
26051 s
->face
= FACE_FROM_ID (s
->f
, s
->first_glyph
->face_id
);
26052 s
->font
= s
->face
->font
;
26053 s
->width
= s
->first_glyph
->pixel_width
;
26054 s
->ybase
+= s
->first_glyph
->voffset
;
26055 s
->xwidget
= s
->first_glyph
->u
.xwidget
;
26058 /* Fill glyph string S from a sequence of stretch glyphs.
26060 START is the index of the first glyph to consider,
26061 END is the index of the last + 1.
26063 Value is the index of the first glyph not in S. */
26066 fill_stretch_glyph_string (struct glyph_string
*s
, int start
, int end
)
26068 struct glyph
*glyph
, *last
;
26069 int voffset
, face_id
;
26071 eassert (s
->first_glyph
->type
== STRETCH_GLYPH
);
26073 glyph
= s
->row
->glyphs
[s
->area
] + start
;
26074 last
= s
->row
->glyphs
[s
->area
] + end
;
26075 face_id
= glyph
->face_id
;
26076 s
->face
= FACE_FROM_ID (s
->f
, face_id
);
26077 s
->font
= s
->face
->font
;
26078 s
->width
= glyph
->pixel_width
;
26080 voffset
= glyph
->voffset
;
26084 && glyph
->type
== STRETCH_GLYPH
26085 && glyph
->voffset
== voffset
26086 && glyph
->face_id
== face_id
);
26088 s
->width
+= glyph
->pixel_width
;
26090 /* Adjust base line for subscript/superscript text. */
26091 s
->ybase
+= voffset
;
26093 /* The case that face->gc == 0 is handled when drawing the glyph
26094 string by calling prepare_face_for_display. */
26096 return glyph
- s
->row
->glyphs
[s
->area
];
26099 static struct font_metrics
*
26100 get_per_char_metric (struct font
*font
, XChar2b
*char2b
)
26102 static struct font_metrics metrics
;
26107 code
= (XCHAR2B_BYTE1 (char2b
) << 8) | XCHAR2B_BYTE2 (char2b
);
26108 if (code
== FONT_INVALID_CODE
)
26110 font
->driver
->text_extents (font
, &code
, 1, &metrics
);
26114 /* A subroutine that computes "normal" values of ASCENT and DESCENT
26115 for FONT. Values are taken from font-global ones, except for fonts
26116 that claim preposterously large values, but whose glyphs actually
26117 have reasonable dimensions. C is the character to use for metrics
26118 if the font-global values are too large; if C is negative, the
26119 function selects a default character. */
26121 normal_char_ascent_descent (struct font
*font
, int c
, int *ascent
, int *descent
)
26123 *ascent
= FONT_BASE (font
);
26124 *descent
= FONT_DESCENT (font
);
26126 if (FONT_TOO_HIGH (font
))
26130 /* Get metrics of C, defaulting to a reasonably sized ASCII
26132 if (get_char_glyph_code (c
>= 0 ? c
: '{', font
, &char2b
))
26134 struct font_metrics
*pcm
= get_per_char_metric (font
, &char2b
);
26136 if (!(pcm
->width
== 0 && pcm
->rbearing
== 0 && pcm
->lbearing
== 0))
26138 /* We add 1 pixel to character dimensions as heuristics
26139 that produces nicer display, e.g. when the face has
26140 the box attribute. */
26141 *ascent
= pcm
->ascent
+ 1;
26142 *descent
= pcm
->descent
+ 1;
26148 /* A subroutine that computes a reasonable "normal character height"
26149 for fonts that claim preposterously large vertical dimensions, but
26150 whose glyphs are actually reasonably sized. C is the character
26151 whose metrics to use for those fonts, or -1 for default
26154 normal_char_height (struct font
*font
, int c
)
26156 int ascent
, descent
;
26158 normal_char_ascent_descent (font
, c
, &ascent
, &descent
);
26160 return ascent
+ descent
;
26164 Set *LEFT and *RIGHT to the left and right overhang of GLYPH on
26165 frame F. Overhangs of glyphs other than type CHAR_GLYPH are
26166 assumed to be zero. */
26169 x_get_glyph_overhangs (struct glyph
*glyph
, struct frame
*f
, int *left
, int *right
)
26171 *left
= *right
= 0;
26173 if (glyph
->type
== CHAR_GLYPH
)
26176 struct face
*face
= get_glyph_face_and_encoding (f
, glyph
, &char2b
);
26179 struct font_metrics
*pcm
= get_per_char_metric (face
->font
, &char2b
);
26182 if (pcm
->rbearing
> pcm
->width
)
26183 *right
= pcm
->rbearing
- pcm
->width
;
26184 if (pcm
->lbearing
< 0)
26185 *left
= -pcm
->lbearing
;
26189 else if (glyph
->type
== COMPOSITE_GLYPH
)
26191 if (! glyph
->u
.cmp
.automatic
)
26193 struct composition
*cmp
= composition_table
[glyph
->u
.cmp
.id
];
26195 if (cmp
->rbearing
> cmp
->pixel_width
)
26196 *right
= cmp
->rbearing
- cmp
->pixel_width
;
26197 if (cmp
->lbearing
< 0)
26198 *left
= - cmp
->lbearing
;
26202 Lisp_Object gstring
= composition_gstring_from_id (glyph
->u
.cmp
.id
);
26203 struct font_metrics metrics
;
26205 composition_gstring_width (gstring
, glyph
->slice
.cmp
.from
,
26206 glyph
->slice
.cmp
.to
+ 1, &metrics
);
26207 if (metrics
.rbearing
> metrics
.width
)
26208 *right
= metrics
.rbearing
- metrics
.width
;
26209 if (metrics
.lbearing
< 0)
26210 *left
= - metrics
.lbearing
;
26216 /* Return the index of the first glyph preceding glyph string S that
26217 is overwritten by S because of S's left overhang. Value is -1
26218 if no glyphs are overwritten. */
26221 left_overwritten (struct glyph_string
*s
)
26225 if (s
->left_overhang
)
26228 struct glyph
*glyphs
= s
->row
->glyphs
[s
->area
];
26229 int first
= s
->first_glyph
- glyphs
;
26231 for (i
= first
- 1; i
>= 0 && x
> -s
->left_overhang
; --i
)
26232 x
-= glyphs
[i
].pixel_width
;
26243 /* Return the index of the first glyph preceding glyph string S that
26244 is overwriting S because of its right overhang. Value is -1 if no
26245 glyph in front of S overwrites S. */
26248 left_overwriting (struct glyph_string
*s
)
26251 struct glyph
*glyphs
= s
->row
->glyphs
[s
->area
];
26252 int first
= s
->first_glyph
- glyphs
;
26256 for (i
= first
- 1; i
>= 0; --i
)
26259 x_get_glyph_overhangs (glyphs
+ i
, s
->f
, &left
, &right
);
26262 x
-= glyphs
[i
].pixel_width
;
26269 /* Return the index of the last glyph following glyph string S that is
26270 overwritten by S because of S's right overhang. Value is -1 if
26271 no such glyph is found. */
26274 right_overwritten (struct glyph_string
*s
)
26278 if (s
->right_overhang
)
26281 struct glyph
*glyphs
= s
->row
->glyphs
[s
->area
];
26282 int first
= (s
->first_glyph
- glyphs
26283 + (s
->first_glyph
->type
== COMPOSITE_GLYPH
? 1 : s
->nchars
));
26284 int end
= s
->row
->used
[s
->area
];
26286 for (i
= first
; i
< end
&& s
->right_overhang
> x
; ++i
)
26287 x
+= glyphs
[i
].pixel_width
;
26296 /* Return the index of the last glyph following glyph string S that
26297 overwrites S because of its left overhang. Value is negative
26298 if no such glyph is found. */
26301 right_overwriting (struct glyph_string
*s
)
26304 int end
= s
->row
->used
[s
->area
];
26305 struct glyph
*glyphs
= s
->row
->glyphs
[s
->area
];
26306 int first
= (s
->first_glyph
- glyphs
26307 + (s
->first_glyph
->type
== COMPOSITE_GLYPH
? 1 : s
->nchars
));
26311 for (i
= first
; i
< end
; ++i
)
26314 x_get_glyph_overhangs (glyphs
+ i
, s
->f
, &left
, &right
);
26317 x
+= glyphs
[i
].pixel_width
;
26324 /* Set background width of glyph string S. START is the index of the
26325 first glyph following S. LAST_X is the right-most x-position + 1
26326 in the drawing area. */
26329 set_glyph_string_background_width (struct glyph_string
*s
, int start
, int last_x
)
26331 /* If the face of this glyph string has to be drawn to the end of
26332 the drawing area, set S->extends_to_end_of_line_p. */
26334 if (start
== s
->row
->used
[s
->area
]
26335 && ((s
->row
->fill_line_p
26336 && (s
->hl
== DRAW_NORMAL_TEXT
26337 || s
->hl
== DRAW_IMAGE_RAISED
26338 || s
->hl
== DRAW_IMAGE_SUNKEN
))
26339 || s
->hl
== DRAW_MOUSE_FACE
))
26340 s
->extends_to_end_of_line_p
= true;
26342 /* If S extends its face to the end of the line, set its
26343 background_width to the distance to the right edge of the drawing
26345 if (s
->extends_to_end_of_line_p
)
26346 s
->background_width
= last_x
- s
->x
+ 1;
26348 s
->background_width
= s
->width
;
26352 /* Return glyph string that shares background with glyph string S and
26353 whose `background_width' member has been set. */
26355 static struct glyph_string
*
26356 glyph_string_containing_background_width (struct glyph_string
*s
)
26359 while (s
->cmp_from
)
26366 /* Compute overhangs and x-positions for glyph string S and its
26367 predecessors, or successors. X is the starting x-position for S.
26368 BACKWARD_P means process predecessors. */
26371 compute_overhangs_and_x (struct glyph_string
*s
, int x
, bool backward_p
)
26377 if (FRAME_RIF (s
->f
)->compute_glyph_string_overhangs
)
26378 FRAME_RIF (s
->f
)->compute_glyph_string_overhangs (s
);
26379 if (!s
->cmp
|| s
->cmp_to
== s
->cmp
->glyph_len
)
26389 if (FRAME_RIF (s
->f
)->compute_glyph_string_overhangs
)
26390 FRAME_RIF (s
->f
)->compute_glyph_string_overhangs (s
);
26392 if (!s
->cmp
|| s
->cmp_to
== s
->cmp
->glyph_len
)
26401 /* The following macros are only called from draw_glyphs below.
26402 They reference the following parameters of that function directly:
26403 `w', `row', `area', and `overlap_p'
26404 as well as the following local variables:
26405 `s', `f', and `hdc' (in W32) */
26408 /* On W32, silently add local `hdc' variable to argument list of
26409 init_glyph_string. */
26410 #define INIT_GLYPH_STRING(s, char2b, w, row, area, start, hl) \
26411 init_glyph_string (s, hdc, char2b, w, row, area, start, hl)
26413 #define INIT_GLYPH_STRING(s, char2b, w, row, area, start, hl) \
26414 init_glyph_string (s, char2b, w, row, area, start, hl)
26417 /* Add a glyph string for a stretch glyph to the list of strings
26418 between HEAD and TAIL. START is the index of the stretch glyph in
26419 row area AREA of glyph row ROW. END is the index of the last glyph
26420 in that glyph row area. X is the current output position assigned
26421 to the new glyph string constructed. HL overrides that face of the
26422 glyph; e.g. it is DRAW_CURSOR if a cursor has to be drawn. LAST_X
26423 is the right-most x-position of the drawing area. */
26425 /* SunOS 4 bundled cc, barfed on continuations in the arg lists here
26426 and below -- keep them on one line. */
26427 #define BUILD_STRETCH_GLYPH_STRING(START, END, HEAD, TAIL, HL, X, LAST_X) \
26430 s = alloca (sizeof *s); \
26431 INIT_GLYPH_STRING (s, NULL, w, row, area, START, HL); \
26432 START = fill_stretch_glyph_string (s, START, END); \
26433 append_glyph_string (&HEAD, &TAIL, s); \
26439 /* Add a glyph string for an image glyph to the list of strings
26440 between HEAD and TAIL. START is the index of the image glyph in
26441 row area AREA of glyph row ROW. END is the index of the last glyph
26442 in that glyph row area. X is the current output position assigned
26443 to the new glyph string constructed. HL overrides that face of the
26444 glyph; e.g. it is DRAW_CURSOR if a cursor has to be drawn. LAST_X
26445 is the right-most x-position of the drawing area. */
26447 #define BUILD_IMAGE_GLYPH_STRING(START, END, HEAD, TAIL, HL, X, LAST_X) \
26450 s = alloca (sizeof *s); \
26451 INIT_GLYPH_STRING (s, NULL, w, row, area, START, HL); \
26452 fill_image_glyph_string (s); \
26453 append_glyph_string (&HEAD, &TAIL, s); \
26459 #ifndef HAVE_XWIDGETS
26460 # define BUILD_XWIDGET_GLYPH_STRING(START, END, HEAD, TAIL, HL, X, LAST_X) \
26463 # define BUILD_XWIDGET_GLYPH_STRING(START, END, HEAD, TAIL, HL, X, LAST_X) \
26466 s = alloca (sizeof *s); \
26467 INIT_GLYPH_STRING (s, NULL, w, row, area, START, HL); \
26468 fill_xwidget_glyph_string (s); \
26469 append_glyph_string (&(HEAD), &(TAIL), s); \
26476 /* Add a glyph string for a sequence of character glyphs to the list
26477 of strings between HEAD and TAIL. START is the index of the first
26478 glyph in row area AREA of glyph row ROW that is part of the new
26479 glyph string. END is the index of the last glyph in that glyph row
26480 area. X is the current output position assigned to the new glyph
26481 string constructed. HL overrides that face of the glyph; e.g. it
26482 is DRAW_CURSOR if a cursor has to be drawn. LAST_X is the
26483 right-most x-position of the drawing area. */
26485 #define BUILD_CHAR_GLYPH_STRINGS(START, END, HEAD, TAIL, HL, X, LAST_X) \
26491 face_id = (row)->glyphs[area][START].face_id; \
26493 s = alloca (sizeof *s); \
26494 SAFE_NALLOCA (char2b, 1, (END) - (START)); \
26495 INIT_GLYPH_STRING (s, char2b, w, row, area, START, HL); \
26496 append_glyph_string (&HEAD, &TAIL, s); \
26498 START = fill_glyph_string (s, face_id, START, END, overlaps); \
26503 /* Add a glyph string for a composite sequence to the list of strings
26504 between HEAD and TAIL. START is the index of the first glyph in
26505 row area AREA of glyph row ROW that is part of the new glyph
26506 string. END is the index of the last glyph in that glyph row area.
26507 X is the current output position assigned to the new glyph string
26508 constructed. HL overrides that face of the glyph; e.g. it is
26509 DRAW_CURSOR if a cursor has to be drawn. LAST_X is the right-most
26510 x-position of the drawing area. */
26512 #define BUILD_COMPOSITE_GLYPH_STRING(START, END, HEAD, TAIL, HL, X, LAST_X) \
26514 int face_id = (row)->glyphs[area][START].face_id; \
26515 struct face *base_face = FACE_FROM_ID (f, face_id); \
26516 ptrdiff_t cmp_id = (row)->glyphs[area][START].u.cmp.id; \
26517 struct composition *cmp = composition_table[cmp_id]; \
26519 struct glyph_string *first_s = NULL; \
26522 SAFE_NALLOCA (char2b, 1, cmp->glyph_len); \
26524 /* Make glyph_strings for each glyph sequence that is drawable by \
26525 the same face, and append them to HEAD/TAIL. */ \
26526 for (n = 0; n < cmp->glyph_len;) \
26528 s = alloca (sizeof *s); \
26529 INIT_GLYPH_STRING (s, char2b, w, row, area, START, HL); \
26530 append_glyph_string (&(HEAD), &(TAIL), s); \
26536 n = fill_composite_glyph_string (s, base_face, overlaps); \
26544 /* Add a glyph string for a glyph-string sequence to the list of strings
26545 between HEAD and TAIL. */
26547 #define BUILD_GSTRING_GLYPH_STRING(START, END, HEAD, TAIL, HL, X, LAST_X) \
26551 Lisp_Object gstring; \
26553 face_id = (row)->glyphs[area][START].face_id; \
26554 gstring = (composition_gstring_from_id \
26555 ((row)->glyphs[area][START].u.cmp.id)); \
26556 s = alloca (sizeof *s); \
26557 SAFE_NALLOCA (char2b, 1, LGSTRING_GLYPH_LEN (gstring)); \
26558 INIT_GLYPH_STRING (s, char2b, w, row, area, START, HL); \
26559 append_glyph_string (&(HEAD), &(TAIL), s); \
26561 START = fill_gstring_glyph_string (s, face_id, START, END, overlaps); \
26565 /* Add a glyph string for a sequence of glyphless character's glyphs
26566 to the list of strings between HEAD and TAIL. The meanings of
26567 arguments are the same as those of BUILD_CHAR_GLYPH_STRINGS. */
26569 #define BUILD_GLYPHLESS_GLYPH_STRING(START, END, HEAD, TAIL, HL, X, LAST_X) \
26574 face_id = (row)->glyphs[area][START].face_id; \
26576 s = alloca (sizeof *s); \
26577 INIT_GLYPH_STRING (s, NULL, w, row, area, START, HL); \
26578 append_glyph_string (&HEAD, &TAIL, s); \
26580 START = fill_glyphless_glyph_string (s, face_id, START, END, \
26586 /* Build a list of glyph strings between HEAD and TAIL for the glyphs
26587 of AREA of glyph row ROW on window W between indices START and END.
26588 HL overrides the face for drawing glyph strings, e.g. it is
26589 DRAW_CURSOR to draw a cursor. X and LAST_X are start and end
26590 x-positions of the drawing area.
26592 This is an ugly monster macro construct because we must use alloca
26593 to allocate glyph strings (because draw_glyphs can be called
26594 asynchronously). */
26596 #define BUILD_GLYPH_STRINGS_1(START, END, HEAD, TAIL, HL, X, LAST_X) \
26599 HEAD = TAIL = NULL; \
26600 while (START < END) \
26602 struct glyph *first_glyph = (row)->glyphs[area] + START; \
26603 switch (first_glyph->type) \
26606 BUILD_CHAR_GLYPH_STRINGS (START, END, HEAD, TAIL, \
26610 case COMPOSITE_GLYPH: \
26611 if (first_glyph->u.cmp.automatic) \
26612 BUILD_GSTRING_GLYPH_STRING (START, END, HEAD, TAIL, \
26615 BUILD_COMPOSITE_GLYPH_STRING (START, END, HEAD, TAIL, \
26619 case STRETCH_GLYPH: \
26620 BUILD_STRETCH_GLYPH_STRING (START, END, HEAD, TAIL, \
26624 case IMAGE_GLYPH: \
26625 BUILD_IMAGE_GLYPH_STRING (START, END, HEAD, TAIL, \
26629 #define BUILD_GLYPH_STRINGS_XW(START, END, HEAD, TAIL, HL, X, LAST_X) \
26630 case XWIDGET_GLYPH: \
26631 BUILD_XWIDGET_GLYPH_STRING (START, END, HEAD, TAIL, \
26635 #define BUILD_GLYPH_STRINGS_2(START, END, HEAD, TAIL, HL, X, LAST_X) \
26636 case GLYPHLESS_GLYPH: \
26637 BUILD_GLYPHLESS_GLYPH_STRING (START, END, HEAD, TAIL, \
26647 set_glyph_string_background_width (s, START, LAST_X); \
26654 #define BUILD_GLYPH_STRINGS(START, END, HEAD, TAIL, HL, X, LAST_X) \
26655 BUILD_GLYPH_STRINGS_1(START, END, HEAD, TAIL, HL, X, LAST_X) \
26656 BUILD_GLYPH_STRINGS_XW(START, END, HEAD, TAIL, HL, X, LAST_X) \
26657 BUILD_GLYPH_STRINGS_2(START, END, HEAD, TAIL, HL, X, LAST_X)
26660 /* Draw glyphs between START and END in AREA of ROW on window W,
26661 starting at x-position X. X is relative to AREA in W. HL is a
26662 face-override with the following meaning:
26664 DRAW_NORMAL_TEXT draw normally
26665 DRAW_CURSOR draw in cursor face
26666 DRAW_MOUSE_FACE draw in mouse face.
26667 DRAW_INVERSE_VIDEO draw in mode line face
26668 DRAW_IMAGE_SUNKEN draw an image with a sunken relief around it
26669 DRAW_IMAGE_RAISED draw an image with a raised relief around it
26671 If OVERLAPS is non-zero, draw only the foreground of characters and
26672 clip to the physical height of ROW. Non-zero value also defines
26673 the overlapping part to be drawn:
26675 OVERLAPS_PRED overlap with preceding rows
26676 OVERLAPS_SUCC overlap with succeeding rows
26677 OVERLAPS_BOTH overlap with both preceding/succeeding rows
26678 OVERLAPS_ERASED_CURSOR overlap with erased cursor area
26680 Value is the x-position reached, relative to AREA of W. */
26683 draw_glyphs (struct window
*w
, int x
, struct glyph_row
*row
,
26684 enum glyph_row_area area
, ptrdiff_t start
, ptrdiff_t end
,
26685 enum draw_glyphs_face hl
, int overlaps
)
26687 struct glyph_string
*head
, *tail
;
26688 struct glyph_string
*s
;
26689 struct glyph_string
*clip_head
= NULL
, *clip_tail
= NULL
;
26690 int i
, j
, x_reached
, last_x
, area_left
= 0;
26691 struct frame
*f
= XFRAME (WINDOW_FRAME (w
));
26694 ALLOCATE_HDC (hdc
, f
);
26696 /* Let's rather be paranoid than getting a SEGV. */
26697 end
= min (end
, row
->used
[area
]);
26698 start
= clip_to_bounds (0, start
, end
);
26700 /* Translate X to frame coordinates. Set last_x to the right
26701 end of the drawing area. */
26702 if (row
->full_width_p
)
26704 /* X is relative to the left edge of W, without scroll bars
26706 area_left
= WINDOW_LEFT_EDGE_X (w
);
26707 last_x
= (WINDOW_LEFT_EDGE_X (w
) + WINDOW_PIXEL_WIDTH (w
)
26708 - (row
->mode_line_p
? WINDOW_RIGHT_DIVIDER_WIDTH (w
) : 0));
26712 area_left
= window_box_left (w
, area
);
26713 last_x
= area_left
+ window_box_width (w
, area
);
26717 /* Build a doubly-linked list of glyph_string structures between
26718 head and tail from what we have to draw. Note that the macro
26719 BUILD_GLYPH_STRINGS will modify its start parameter. That's
26720 the reason we use a separate variable `i'. */
26723 BUILD_GLYPH_STRINGS (i
, end
, head
, tail
, hl
, x
, last_x
);
26726 s
= glyph_string_containing_background_width (tail
);
26727 x_reached
= s
->x
+ s
->background_width
;
26732 /* If there are any glyphs with lbearing < 0 or rbearing > width in
26733 the row, redraw some glyphs in front or following the glyph
26734 strings built above. */
26735 if (head
&& !overlaps
&& row
->contains_overlapping_glyphs_p
)
26737 struct glyph_string
*h
, *t
;
26738 Mouse_HLInfo
*hlinfo
= MOUSE_HL_INFO (f
);
26739 int mouse_beg_col UNINIT
, mouse_end_col UNINIT
;
26740 bool check_mouse_face
= false;
26743 /* If mouse highlighting is on, we may need to draw adjacent
26744 glyphs using mouse-face highlighting. */
26745 if (area
== TEXT_AREA
&& row
->mouse_face_p
26746 && hlinfo
->mouse_face_beg_row
>= 0
26747 && hlinfo
->mouse_face_end_row
>= 0)
26749 ptrdiff_t row_vpos
= MATRIX_ROW_VPOS (row
, w
->current_matrix
);
26751 if (row_vpos
>= hlinfo
->mouse_face_beg_row
26752 && row_vpos
<= hlinfo
->mouse_face_end_row
)
26754 check_mouse_face
= true;
26755 mouse_beg_col
= (row_vpos
== hlinfo
->mouse_face_beg_row
)
26756 ? hlinfo
->mouse_face_beg_col
: 0;
26757 mouse_end_col
= (row_vpos
== hlinfo
->mouse_face_end_row
)
26758 ? hlinfo
->mouse_face_end_col
26759 : row
->used
[TEXT_AREA
];
26763 /* Compute overhangs for all glyph strings. */
26764 if (FRAME_RIF (f
)->compute_glyph_string_overhangs
)
26765 for (s
= head
; s
; s
= s
->next
)
26766 FRAME_RIF (f
)->compute_glyph_string_overhangs (s
);
26768 /* Prepend glyph strings for glyphs in front of the first glyph
26769 string that are overwritten because of the first glyph
26770 string's left overhang. The background of all strings
26771 prepended must be drawn because the first glyph string
26773 i
= left_overwritten (head
);
26776 enum draw_glyphs_face overlap_hl
;
26778 /* If this row contains mouse highlighting, attempt to draw
26779 the overlapped glyphs with the correct highlight. This
26780 code fails if the overlap encompasses more than one glyph
26781 and mouse-highlight spans only some of these glyphs.
26782 However, making it work perfectly involves a lot more
26783 code, and I don't know if the pathological case occurs in
26784 practice, so we'll stick to this for now. --- cyd */
26785 if (check_mouse_face
26786 && mouse_beg_col
< start
&& mouse_end_col
> i
)
26787 overlap_hl
= DRAW_MOUSE_FACE
;
26789 overlap_hl
= DRAW_NORMAL_TEXT
;
26791 if (hl
!= overlap_hl
)
26794 BUILD_GLYPH_STRINGS (j
, start
, h
, t
,
26795 overlap_hl
, dummy_x
, last_x
);
26797 compute_overhangs_and_x (t
, head
->x
, true);
26798 prepend_glyph_string_lists (&head
, &tail
, h
, t
);
26799 if (clip_head
== NULL
)
26803 /* Prepend glyph strings for glyphs in front of the first glyph
26804 string that overwrite that glyph string because of their
26805 right overhang. For these strings, only the foreground must
26806 be drawn, because it draws over the glyph string at `head'.
26807 The background must not be drawn because this would overwrite
26808 right overhangs of preceding glyphs for which no glyph
26810 i
= left_overwriting (head
);
26813 enum draw_glyphs_face overlap_hl
;
26815 if (check_mouse_face
26816 && mouse_beg_col
< start
&& mouse_end_col
> i
)
26817 overlap_hl
= DRAW_MOUSE_FACE
;
26819 overlap_hl
= DRAW_NORMAL_TEXT
;
26821 if (hl
== overlap_hl
|| clip_head
== NULL
)
26823 BUILD_GLYPH_STRINGS (i
, start
, h
, t
,
26824 overlap_hl
, dummy_x
, last_x
);
26825 for (s
= h
; s
; s
= s
->next
)
26826 s
->background_filled_p
= true;
26827 compute_overhangs_and_x (t
, head
->x
, true);
26828 prepend_glyph_string_lists (&head
, &tail
, h
, t
);
26831 /* Append glyphs strings for glyphs following the last glyph
26832 string tail that are overwritten by tail. The background of
26833 these strings has to be drawn because tail's foreground draws
26835 i
= right_overwritten (tail
);
26838 enum draw_glyphs_face overlap_hl
;
26840 if (check_mouse_face
26841 && mouse_beg_col
< i
&& mouse_end_col
> end
)
26842 overlap_hl
= DRAW_MOUSE_FACE
;
26844 overlap_hl
= DRAW_NORMAL_TEXT
;
26846 if (hl
!= overlap_hl
)
26848 BUILD_GLYPH_STRINGS (end
, i
, h
, t
,
26849 overlap_hl
, x
, last_x
);
26850 /* Because BUILD_GLYPH_STRINGS updates the first argument,
26851 we don't have `end = i;' here. */
26852 compute_overhangs_and_x (h
, tail
->x
+ tail
->width
, false);
26853 append_glyph_string_lists (&head
, &tail
, h
, t
);
26854 if (clip_tail
== NULL
)
26858 /* Append glyph strings for glyphs following the last glyph
26859 string tail that overwrite tail. The foreground of such
26860 glyphs has to be drawn because it writes into the background
26861 of tail. The background must not be drawn because it could
26862 paint over the foreground of following glyphs. */
26863 i
= right_overwriting (tail
);
26866 enum draw_glyphs_face overlap_hl
;
26867 if (check_mouse_face
26868 && mouse_beg_col
< i
&& mouse_end_col
> end
)
26869 overlap_hl
= DRAW_MOUSE_FACE
;
26871 overlap_hl
= DRAW_NORMAL_TEXT
;
26873 if (hl
== overlap_hl
|| clip_tail
== NULL
)
26875 i
++; /* We must include the Ith glyph. */
26876 BUILD_GLYPH_STRINGS (end
, i
, h
, t
,
26877 overlap_hl
, x
, last_x
);
26878 for (s
= h
; s
; s
= s
->next
)
26879 s
->background_filled_p
= true;
26880 compute_overhangs_and_x (h
, tail
->x
+ tail
->width
, false);
26881 append_glyph_string_lists (&head
, &tail
, h
, t
);
26883 tail
= glyph_string_containing_background_width (tail
);
26885 clip_tail
= glyph_string_containing_background_width (clip_tail
);
26886 if (clip_head
|| clip_tail
)
26887 for (s
= head
; s
; s
= s
->next
)
26889 s
->clip_head
= clip_head
;
26890 s
->clip_tail
= clip_tail
;
26894 /* Draw all strings. */
26895 for (s
= head
; s
; s
= s
->next
)
26896 FRAME_RIF (f
)->draw_glyph_string (s
);
26899 /* When focus a sole frame and move horizontally, this clears on_p
26900 causing a failure to erase prev cursor position. */
26901 if (area
== TEXT_AREA
26902 && !row
->full_width_p
26903 /* When drawing overlapping rows, only the glyph strings'
26904 foreground is drawn, which doesn't erase a cursor
26908 int x0
= clip_head
? clip_head
->x
: (head
? head
->x
: x
);
26909 int x1
= (clip_tail
? clip_tail
->x
+ clip_tail
->background_width
26910 : (tail
? tail
->x
+ tail
->background_width
: x
));
26914 notice_overwritten_cursor (w
, TEXT_AREA
, x0
, x1
,
26915 row
->y
, MATRIX_ROW_BOTTOM_Y (row
));
26919 /* Value is the x-position up to which drawn, relative to AREA of W.
26920 This doesn't include parts drawn because of overhangs. */
26921 if (row
->full_width_p
)
26922 x_reached
= FRAME_TO_WINDOW_PIXEL_X (w
, x_reached
);
26924 x_reached
-= area_left
;
26926 RELEASE_HDC (hdc
, f
);
26932 /* Find the first glyph in the run of underlined glyphs preceding the
26933 beginning of glyph string S, and return its font (which could be
26934 NULL). This is needed because that font determines the underline
26935 position and thickness for the entire run of the underlined glyphs.
26936 This function is called from the draw_glyph_string method of GUI
26937 frame's redisplay interface (RIF) when it needs to draw in an
26938 underlined face. */
26940 font_for_underline_metrics (struct glyph_string
*s
)
26942 struct glyph
*g0
= s
->row
->glyphs
[s
->area
], *g
;
26944 for (g
= s
->first_glyph
- 1; g
>= g0
; g
--)
26946 struct face
*prev_face
= FACE_FROM_ID (s
->f
, g
->face_id
);
26947 if (!(prev_face
&& prev_face
->underline_p
))
26951 /* If preceding glyphs are not underlined, use the font of S. */
26952 if (g
== s
->first_glyph
- 1)
26956 /* Otherwise use the font of the last glyph we saw in the above
26957 loop whose face had the underline_p flag set. */
26958 return FACE_FROM_ID (s
->f
, g
[1].face_id
)->font
;
26962 /* Expand row matrix if too narrow. Don't expand if area
26965 #define IT_EXPAND_MATRIX_WIDTH(it, area) \
26967 if (!it->f->fonts_changed \
26968 && (it->glyph_row->glyphs[area] \
26969 < it->glyph_row->glyphs[area + 1])) \
26971 it->w->ncols_scale_factor++; \
26972 it->f->fonts_changed = true; \
26976 /* Store one glyph for IT->char_to_display in IT->glyph_row.
26977 Called from x_produce_glyphs when IT->glyph_row is non-null. */
26980 append_glyph (struct it
*it
)
26982 struct glyph
*glyph
;
26983 enum glyph_row_area area
= it
->area
;
26985 eassert (it
->glyph_row
);
26986 eassert (it
->char_to_display
!= '\n' && it
->char_to_display
!= '\t');
26988 glyph
= it
->glyph_row
->glyphs
[area
] + it
->glyph_row
->used
[area
];
26989 if (glyph
< it
->glyph_row
->glyphs
[area
+ 1])
26991 /* If the glyph row is reversed, we need to prepend the glyph
26992 rather than append it. */
26993 if (it
->glyph_row
->reversed_p
&& area
== TEXT_AREA
)
26997 /* Make room for the additional glyph. */
26998 for (g
= glyph
- 1; g
>= it
->glyph_row
->glyphs
[area
]; g
--)
27000 glyph
= it
->glyph_row
->glyphs
[area
];
27002 glyph
->charpos
= CHARPOS (it
->position
);
27003 glyph
->object
= it
->object
;
27004 if (it
->pixel_width
> 0)
27006 eassert (it
->pixel_width
<= SHRT_MAX
);
27007 glyph
->pixel_width
= it
->pixel_width
;
27008 glyph
->padding_p
= false;
27012 /* Assure at least 1-pixel width. Otherwise, cursor can't
27013 be displayed correctly. */
27014 glyph
->pixel_width
= 1;
27015 glyph
->padding_p
= true;
27017 glyph
->ascent
= it
->ascent
;
27018 glyph
->descent
= it
->descent
;
27019 glyph
->voffset
= it
->voffset
;
27020 glyph
->type
= CHAR_GLYPH
;
27021 glyph
->avoid_cursor_p
= it
->avoid_cursor_p
;
27022 glyph
->multibyte_p
= it
->multibyte_p
;
27023 if (it
->glyph_row
->reversed_p
&& area
== TEXT_AREA
)
27025 /* In R2L rows, the left and the right box edges need to be
27026 drawn in reverse direction. */
27027 glyph
->right_box_line_p
= it
->start_of_box_run_p
;
27028 glyph
->left_box_line_p
= it
->end_of_box_run_p
;
27032 glyph
->left_box_line_p
= it
->start_of_box_run_p
;
27033 glyph
->right_box_line_p
= it
->end_of_box_run_p
;
27035 glyph
->overlaps_vertically_p
= (it
->phys_ascent
> it
->ascent
27036 || it
->phys_descent
> it
->descent
);
27037 glyph
->glyph_not_available_p
= it
->glyph_not_available_p
;
27038 glyph
->face_id
= it
->face_id
;
27039 glyph
->u
.ch
= it
->char_to_display
;
27040 glyph
->slice
.img
= null_glyph_slice
;
27041 glyph
->font_type
= FONT_TYPE_UNKNOWN
;
27044 glyph
->resolved_level
= it
->bidi_it
.resolved_level
;
27045 eassert ((it
->bidi_it
.type
& 7) == it
->bidi_it
.type
);
27046 glyph
->bidi_type
= it
->bidi_it
.type
;
27050 glyph
->resolved_level
= 0;
27051 glyph
->bidi_type
= UNKNOWN_BT
;
27053 ++it
->glyph_row
->used
[area
];
27056 IT_EXPAND_MATRIX_WIDTH (it
, area
);
27059 /* Store one glyph for the composition IT->cmp_it.id in
27060 IT->glyph_row. Called from x_produce_glyphs when IT->glyph_row is
27064 append_composite_glyph (struct it
*it
)
27066 struct glyph
*glyph
;
27067 enum glyph_row_area area
= it
->area
;
27069 eassert (it
->glyph_row
);
27071 glyph
= it
->glyph_row
->glyphs
[area
] + it
->glyph_row
->used
[area
];
27072 if (glyph
< it
->glyph_row
->glyphs
[area
+ 1])
27074 /* If the glyph row is reversed, we need to prepend the glyph
27075 rather than append it. */
27076 if (it
->glyph_row
->reversed_p
&& it
->area
== TEXT_AREA
)
27080 /* Make room for the new glyph. */
27081 for (g
= glyph
- 1; g
>= it
->glyph_row
->glyphs
[it
->area
]; g
--)
27083 glyph
= it
->glyph_row
->glyphs
[it
->area
];
27085 glyph
->charpos
= it
->cmp_it
.charpos
;
27086 glyph
->object
= it
->object
;
27087 eassert (it
->pixel_width
<= SHRT_MAX
);
27088 glyph
->pixel_width
= it
->pixel_width
;
27089 glyph
->ascent
= it
->ascent
;
27090 glyph
->descent
= it
->descent
;
27091 glyph
->voffset
= it
->voffset
;
27092 glyph
->type
= COMPOSITE_GLYPH
;
27093 if (it
->cmp_it
.ch
< 0)
27095 glyph
->u
.cmp
.automatic
= false;
27096 glyph
->u
.cmp
.id
= it
->cmp_it
.id
;
27097 glyph
->slice
.cmp
.from
= glyph
->slice
.cmp
.to
= 0;
27101 glyph
->u
.cmp
.automatic
= true;
27102 glyph
->u
.cmp
.id
= it
->cmp_it
.id
;
27103 glyph
->slice
.cmp
.from
= it
->cmp_it
.from
;
27104 glyph
->slice
.cmp
.to
= it
->cmp_it
.to
- 1;
27106 glyph
->avoid_cursor_p
= it
->avoid_cursor_p
;
27107 glyph
->multibyte_p
= it
->multibyte_p
;
27108 if (it
->glyph_row
->reversed_p
&& area
== TEXT_AREA
)
27110 /* In R2L rows, the left and the right box edges need to be
27111 drawn in reverse direction. */
27112 glyph
->right_box_line_p
= it
->start_of_box_run_p
;
27113 glyph
->left_box_line_p
= it
->end_of_box_run_p
;
27117 glyph
->left_box_line_p
= it
->start_of_box_run_p
;
27118 glyph
->right_box_line_p
= it
->end_of_box_run_p
;
27120 glyph
->overlaps_vertically_p
= (it
->phys_ascent
> it
->ascent
27121 || it
->phys_descent
> it
->descent
);
27122 glyph
->padding_p
= false;
27123 glyph
->glyph_not_available_p
= false;
27124 glyph
->face_id
= it
->face_id
;
27125 glyph
->font_type
= FONT_TYPE_UNKNOWN
;
27128 glyph
->resolved_level
= it
->bidi_it
.resolved_level
;
27129 eassert ((it
->bidi_it
.type
& 7) == it
->bidi_it
.type
);
27130 glyph
->bidi_type
= it
->bidi_it
.type
;
27132 ++it
->glyph_row
->used
[area
];
27135 IT_EXPAND_MATRIX_WIDTH (it
, area
);
27139 /* Change IT->ascent and IT->height according to the setting of
27143 take_vertical_position_into_account (struct it
*it
)
27147 if (it
->voffset
< 0)
27148 /* Increase the ascent so that we can display the text higher
27150 it
->ascent
-= it
->voffset
;
27152 /* Increase the descent so that we can display the text lower
27154 it
->descent
+= it
->voffset
;
27159 /* Produce glyphs/get display metrics for the image IT is loaded with.
27160 See the description of struct display_iterator in dispextern.h for
27161 an overview of struct display_iterator. */
27164 produce_image_glyph (struct it
*it
)
27168 int glyph_ascent
, crop
;
27169 struct glyph_slice slice
;
27171 eassert (it
->what
== IT_IMAGE
);
27173 face
= FACE_FROM_ID (it
->f
, it
->face_id
);
27174 /* Make sure X resources of the face is loaded. */
27175 prepare_face_for_display (it
->f
, face
);
27177 if (it
->image_id
< 0)
27179 /* Fringe bitmap. */
27180 it
->ascent
= it
->phys_ascent
= 0;
27181 it
->descent
= it
->phys_descent
= 0;
27182 it
->pixel_width
= 0;
27187 img
= IMAGE_FROM_ID (it
->f
, it
->image_id
);
27188 /* Make sure X resources of the image is loaded. */
27189 prepare_image_for_display (it
->f
, img
);
27191 slice
.x
= slice
.y
= 0;
27192 slice
.width
= img
->width
;
27193 slice
.height
= img
->height
;
27195 if (INTEGERP (it
->slice
.x
))
27196 slice
.x
= XINT (it
->slice
.x
);
27197 else if (FLOATP (it
->slice
.x
))
27198 slice
.x
= XFLOAT_DATA (it
->slice
.x
) * img
->width
;
27200 if (INTEGERP (it
->slice
.y
))
27201 slice
.y
= XINT (it
->slice
.y
);
27202 else if (FLOATP (it
->slice
.y
))
27203 slice
.y
= XFLOAT_DATA (it
->slice
.y
) * img
->height
;
27205 if (INTEGERP (it
->slice
.width
))
27206 slice
.width
= XINT (it
->slice
.width
);
27207 else if (FLOATP (it
->slice
.width
))
27208 slice
.width
= XFLOAT_DATA (it
->slice
.width
) * img
->width
;
27210 if (INTEGERP (it
->slice
.height
))
27211 slice
.height
= XINT (it
->slice
.height
);
27212 else if (FLOATP (it
->slice
.height
))
27213 slice
.height
= XFLOAT_DATA (it
->slice
.height
) * img
->height
;
27215 if (slice
.x
>= img
->width
)
27216 slice
.x
= img
->width
;
27217 if (slice
.y
>= img
->height
)
27218 slice
.y
= img
->height
;
27219 if (slice
.x
+ slice
.width
>= img
->width
)
27220 slice
.width
= img
->width
- slice
.x
;
27221 if (slice
.y
+ slice
.height
> img
->height
)
27222 slice
.height
= img
->height
- slice
.y
;
27224 if (slice
.width
== 0 || slice
.height
== 0)
27227 it
->ascent
= it
->phys_ascent
= glyph_ascent
= image_ascent (img
, face
, &slice
);
27229 it
->descent
= slice
.height
- glyph_ascent
;
27231 it
->descent
+= img
->vmargin
;
27232 if (slice
.y
+ slice
.height
== img
->height
)
27233 it
->descent
+= img
->vmargin
;
27234 it
->phys_descent
= it
->descent
;
27236 it
->pixel_width
= slice
.width
;
27238 it
->pixel_width
+= img
->hmargin
;
27239 if (slice
.x
+ slice
.width
== img
->width
)
27240 it
->pixel_width
+= img
->hmargin
;
27242 /* It's quite possible for images to have an ascent greater than
27243 their height, so don't get confused in that case. */
27244 if (it
->descent
< 0)
27249 if (face
->box
!= FACE_NO_BOX
)
27251 if (face
->box_line_width
> 0)
27254 it
->ascent
+= face
->box_line_width
;
27255 if (slice
.y
+ slice
.height
== img
->height
)
27256 it
->descent
+= face
->box_line_width
;
27259 if (it
->start_of_box_run_p
&& slice
.x
== 0)
27260 it
->pixel_width
+= eabs (face
->box_line_width
);
27261 if (it
->end_of_box_run_p
&& slice
.x
+ slice
.width
== img
->width
)
27262 it
->pixel_width
+= eabs (face
->box_line_width
);
27265 take_vertical_position_into_account (it
);
27267 /* Automatically crop wide image glyphs at right edge so we can
27268 draw the cursor on same display row. */
27269 if ((crop
= it
->pixel_width
- (it
->last_visible_x
- it
->current_x
), crop
> 0)
27270 && (it
->hpos
== 0 || it
->pixel_width
> it
->last_visible_x
/ 4))
27272 it
->pixel_width
-= crop
;
27273 slice
.width
-= crop
;
27278 struct glyph
*glyph
;
27279 enum glyph_row_area area
= it
->area
;
27281 glyph
= it
->glyph_row
->glyphs
[area
] + it
->glyph_row
->used
[area
];
27282 if (it
->glyph_row
->reversed_p
)
27286 /* Make room for the new glyph. */
27287 for (g
= glyph
- 1; g
>= it
->glyph_row
->glyphs
[it
->area
]; g
--)
27289 glyph
= it
->glyph_row
->glyphs
[it
->area
];
27291 if (glyph
< it
->glyph_row
->glyphs
[area
+ 1])
27293 glyph
->charpos
= CHARPOS (it
->position
);
27294 glyph
->object
= it
->object
;
27295 glyph
->pixel_width
= clip_to_bounds (-1, it
->pixel_width
, SHRT_MAX
);
27296 glyph
->ascent
= glyph_ascent
;
27297 glyph
->descent
= it
->descent
;
27298 glyph
->voffset
= it
->voffset
;
27299 glyph
->type
= IMAGE_GLYPH
;
27300 glyph
->avoid_cursor_p
= it
->avoid_cursor_p
;
27301 glyph
->multibyte_p
= it
->multibyte_p
;
27302 if (it
->glyph_row
->reversed_p
&& area
== TEXT_AREA
)
27304 /* In R2L rows, the left and the right box edges need to be
27305 drawn in reverse direction. */
27306 glyph
->right_box_line_p
= it
->start_of_box_run_p
;
27307 glyph
->left_box_line_p
= it
->end_of_box_run_p
;
27311 glyph
->left_box_line_p
= it
->start_of_box_run_p
;
27312 glyph
->right_box_line_p
= it
->end_of_box_run_p
;
27314 glyph
->overlaps_vertically_p
= false;
27315 glyph
->padding_p
= false;
27316 glyph
->glyph_not_available_p
= false;
27317 glyph
->face_id
= it
->face_id
;
27318 glyph
->u
.img_id
= img
->id
;
27319 glyph
->slice
.img
= slice
;
27320 glyph
->font_type
= FONT_TYPE_UNKNOWN
;
27323 glyph
->resolved_level
= it
->bidi_it
.resolved_level
;
27324 eassert ((it
->bidi_it
.type
& 7) == it
->bidi_it
.type
);
27325 glyph
->bidi_type
= it
->bidi_it
.type
;
27327 ++it
->glyph_row
->used
[area
];
27330 IT_EXPAND_MATRIX_WIDTH (it
, area
);
27335 produce_xwidget_glyph (struct it
*it
)
27337 #ifdef HAVE_XWIDGETS
27338 struct xwidget
*xw
;
27339 int glyph_ascent
, crop
;
27340 eassert (it
->what
== IT_XWIDGET
);
27342 struct face
*face
= FACE_FROM_ID (it
->f
, it
->face_id
);
27343 /* Make sure X resources of the face is loaded. */
27344 prepare_face_for_display (it
->f
, face
);
27347 it
->ascent
= it
->phys_ascent
= glyph_ascent
= xw
->height
/2;
27348 it
->descent
= xw
->height
/2;
27349 it
->phys_descent
= it
->descent
;
27350 it
->pixel_width
= xw
->width
;
27351 /* It's quite possible for images to have an ascent greater than
27352 their height, so don't get confused in that case. */
27353 if (it
->descent
< 0)
27358 if (face
->box
!= FACE_NO_BOX
)
27360 if (face
->box_line_width
> 0)
27362 it
->ascent
+= face
->box_line_width
;
27363 it
->descent
+= face
->box_line_width
;
27366 if (it
->start_of_box_run_p
)
27367 it
->pixel_width
+= eabs (face
->box_line_width
);
27368 it
->pixel_width
+= eabs (face
->box_line_width
);
27371 take_vertical_position_into_account (it
);
27373 /* Automatically crop wide image glyphs at right edge so we can
27374 draw the cursor on same display row. */
27375 crop
= it
->pixel_width
- (it
->last_visible_x
- it
->current_x
);
27376 if (crop
> 0 && (it
->hpos
== 0 || it
->pixel_width
> it
->last_visible_x
/ 4))
27377 it
->pixel_width
-= crop
;
27381 enum glyph_row_area area
= it
->area
;
27382 struct glyph
*glyph
27383 = it
->glyph_row
->glyphs
[area
] + it
->glyph_row
->used
[area
];
27385 if (it
->glyph_row
->reversed_p
)
27389 /* Make room for the new glyph. */
27390 for (g
= glyph
- 1; g
>= it
->glyph_row
->glyphs
[it
->area
]; g
--)
27392 glyph
= it
->glyph_row
->glyphs
[it
->area
];
27394 if (glyph
< it
->glyph_row
->glyphs
[area
+ 1])
27396 glyph
->charpos
= CHARPOS (it
->position
);
27397 glyph
->object
= it
->object
;
27398 glyph
->pixel_width
= clip_to_bounds (-1, it
->pixel_width
, SHRT_MAX
);
27399 glyph
->ascent
= glyph_ascent
;
27400 glyph
->descent
= it
->descent
;
27401 glyph
->voffset
= it
->voffset
;
27402 glyph
->type
= XWIDGET_GLYPH
;
27403 glyph
->avoid_cursor_p
= it
->avoid_cursor_p
;
27404 glyph
->multibyte_p
= it
->multibyte_p
;
27405 if (it
->glyph_row
->reversed_p
&& area
== TEXT_AREA
)
27407 /* In R2L rows, the left and the right box edges need to be
27408 drawn in reverse direction. */
27409 glyph
->right_box_line_p
= it
->start_of_box_run_p
;
27410 glyph
->left_box_line_p
= it
->end_of_box_run_p
;
27414 glyph
->left_box_line_p
= it
->start_of_box_run_p
;
27415 glyph
->right_box_line_p
= it
->end_of_box_run_p
;
27417 glyph
->overlaps_vertically_p
= 0;
27418 glyph
->padding_p
= 0;
27419 glyph
->glyph_not_available_p
= 0;
27420 glyph
->face_id
= it
->face_id
;
27421 glyph
->u
.xwidget
= it
->xwidget
;
27422 glyph
->font_type
= FONT_TYPE_UNKNOWN
;
27425 glyph
->resolved_level
= it
->bidi_it
.resolved_level
;
27426 eassert ((it
->bidi_it
.type
& 7) == it
->bidi_it
.type
);
27427 glyph
->bidi_type
= it
->bidi_it
.type
;
27429 ++it
->glyph_row
->used
[area
];
27432 IT_EXPAND_MATRIX_WIDTH (it
, area
);
27437 /* Append a stretch glyph to IT->glyph_row. OBJECT is the source
27438 of the glyph, WIDTH and HEIGHT are the width and height of the
27439 stretch. ASCENT is the ascent of the glyph (0 <= ASCENT <= HEIGHT). */
27442 append_stretch_glyph (struct it
*it
, Lisp_Object object
,
27443 int width
, int height
, int ascent
)
27445 struct glyph
*glyph
;
27446 enum glyph_row_area area
= it
->area
;
27448 eassert (ascent
>= 0 && ascent
<= height
);
27450 glyph
= it
->glyph_row
->glyphs
[area
] + it
->glyph_row
->used
[area
];
27451 if (glyph
< it
->glyph_row
->glyphs
[area
+ 1])
27453 /* If the glyph row is reversed, we need to prepend the glyph
27454 rather than append it. */
27455 if (it
->glyph_row
->reversed_p
&& area
== TEXT_AREA
)
27459 /* Make room for the additional glyph. */
27460 for (g
= glyph
- 1; g
>= it
->glyph_row
->glyphs
[area
]; g
--)
27462 glyph
= it
->glyph_row
->glyphs
[area
];
27464 /* Decrease the width of the first glyph of the row that
27465 begins before first_visible_x (e.g., due to hscroll).
27466 This is so the overall width of the row becomes smaller
27467 by the scroll amount, and the stretch glyph appended by
27468 extend_face_to_end_of_line will be wider, to shift the
27469 row glyphs to the right. (In L2R rows, the corresponding
27470 left-shift effect is accomplished by setting row->x to a
27471 negative value, which won't work with R2L rows.)
27473 This must leave us with a positive value of WIDTH, since
27474 otherwise the call to move_it_in_display_line_to at the
27475 beginning of display_line would have got past the entire
27476 first glyph, and then it->current_x would have been
27477 greater or equal to it->first_visible_x. */
27478 if (it
->current_x
< it
->first_visible_x
)
27479 width
-= it
->first_visible_x
- it
->current_x
;
27480 eassert (width
> 0);
27482 glyph
->charpos
= CHARPOS (it
->position
);
27483 glyph
->object
= object
;
27484 /* FIXME: It would be better to use TYPE_MAX here, but
27485 __typeof__ is not portable enough... */
27486 glyph
->pixel_width
= clip_to_bounds (-1, width
, SHRT_MAX
);
27487 glyph
->ascent
= ascent
;
27488 glyph
->descent
= height
- ascent
;
27489 glyph
->voffset
= it
->voffset
;
27490 glyph
->type
= STRETCH_GLYPH
;
27491 glyph
->avoid_cursor_p
= it
->avoid_cursor_p
;
27492 glyph
->multibyte_p
= it
->multibyte_p
;
27493 if (it
->glyph_row
->reversed_p
&& area
== TEXT_AREA
)
27495 /* In R2L rows, the left and the right box edges need to be
27496 drawn in reverse direction. */
27497 glyph
->right_box_line_p
= it
->start_of_box_run_p
;
27498 glyph
->left_box_line_p
= it
->end_of_box_run_p
;
27502 glyph
->left_box_line_p
= it
->start_of_box_run_p
;
27503 glyph
->right_box_line_p
= it
->end_of_box_run_p
;
27505 glyph
->overlaps_vertically_p
= false;
27506 glyph
->padding_p
= false;
27507 glyph
->glyph_not_available_p
= false;
27508 glyph
->face_id
= it
->face_id
;
27509 glyph
->u
.stretch
.ascent
= ascent
;
27510 glyph
->u
.stretch
.height
= height
;
27511 glyph
->slice
.img
= null_glyph_slice
;
27512 glyph
->font_type
= FONT_TYPE_UNKNOWN
;
27515 glyph
->resolved_level
= it
->bidi_it
.resolved_level
;
27516 eassert ((it
->bidi_it
.type
& 7) == it
->bidi_it
.type
);
27517 glyph
->bidi_type
= it
->bidi_it
.type
;
27521 glyph
->resolved_level
= 0;
27522 glyph
->bidi_type
= UNKNOWN_BT
;
27524 ++it
->glyph_row
->used
[area
];
27527 IT_EXPAND_MATRIX_WIDTH (it
, area
);
27530 #endif /* HAVE_WINDOW_SYSTEM */
27532 /* Produce a stretch glyph for iterator IT. IT->object is the value
27533 of the glyph property displayed. The value must be a list
27534 `(space KEYWORD VALUE ...)' with the following KEYWORD/VALUE pairs
27537 1. `:width WIDTH' specifies that the space should be WIDTH *
27538 canonical char width wide. WIDTH may be an integer or floating
27541 2. `:relative-width FACTOR' specifies that the width of the stretch
27542 should be computed from the width of the first character having the
27543 `glyph' property, and should be FACTOR times that width.
27545 3. `:align-to HPOS' specifies that the space should be wide enough
27546 to reach HPOS, a value in canonical character units.
27548 Exactly one of the above pairs must be present.
27550 4. `:height HEIGHT' specifies that the height of the stretch produced
27551 should be HEIGHT, measured in canonical character units.
27553 5. `:relative-height FACTOR' specifies that the height of the
27554 stretch should be FACTOR times the height of the characters having
27555 the glyph property.
27557 Either none or exactly one of 4 or 5 must be present.
27559 6. `:ascent ASCENT' specifies that ASCENT percent of the height
27560 of the stretch should be used for the ascent of the stretch.
27561 ASCENT must be in the range 0 <= ASCENT <= 100. */
27564 produce_stretch_glyph (struct it
*it
)
27566 /* (space :width WIDTH :height HEIGHT ...) */
27567 Lisp_Object prop
, plist
;
27568 int width
= 0, height
= 0, align_to
= -1;
27569 bool zero_width_ok_p
= false;
27571 struct font
*font
= NULL
;
27573 #ifdef HAVE_WINDOW_SYSTEM
27575 bool zero_height_ok_p
= false;
27577 if (FRAME_WINDOW_P (it
->f
))
27579 struct face
*face
= FACE_FROM_ID (it
->f
, it
->face_id
);
27580 font
= face
->font
? face
->font
: FRAME_FONT (it
->f
);
27581 prepare_face_for_display (it
->f
, face
);
27585 /* List should start with `space'. */
27586 eassert (CONSP (it
->object
) && EQ (XCAR (it
->object
), Qspace
));
27587 plist
= XCDR (it
->object
);
27589 /* Compute the width of the stretch. */
27590 if ((prop
= Fplist_get (plist
, QCwidth
), !NILP (prop
))
27591 && calc_pixel_width_or_height (&tem
, it
, prop
, font
, true, 0))
27593 /* Absolute width `:width WIDTH' specified and valid. */
27594 zero_width_ok_p
= true;
27597 else if (prop
= Fplist_get (plist
, QCrelative_width
), NUMVAL (prop
) > 0)
27599 /* Relative width `:relative-width FACTOR' specified and valid.
27600 Compute the width of the characters having the `glyph'
27603 unsigned char *p
= BYTE_POS_ADDR (IT_BYTEPOS (*it
));
27606 if (it
->multibyte_p
)
27607 it2
.c
= it2
.char_to_display
= STRING_CHAR_AND_LENGTH (p
, it2
.len
);
27610 it2
.c
= it2
.char_to_display
= *p
, it2
.len
= 1;
27611 if (! ASCII_CHAR_P (it2
.c
))
27612 it2
.char_to_display
= BYTE8_TO_CHAR (it2
.c
);
27615 it2
.glyph_row
= NULL
;
27616 it2
.what
= IT_CHARACTER
;
27617 PRODUCE_GLYPHS (&it2
);
27618 width
= NUMVAL (prop
) * it2
.pixel_width
;
27620 else if ((prop
= Fplist_get (plist
, QCalign_to
), !NILP (prop
))
27621 && calc_pixel_width_or_height (&tem
, it
, prop
, font
, true,
27624 if (it
->glyph_row
== NULL
|| !it
->glyph_row
->mode_line_p
)
27625 align_to
= (align_to
< 0
27627 : align_to
- window_box_left_offset (it
->w
, TEXT_AREA
));
27628 else if (align_to
< 0)
27629 align_to
= window_box_left_offset (it
->w
, TEXT_AREA
);
27630 width
= max (0, (int)tem
+ align_to
- it
->current_x
);
27631 zero_width_ok_p
= true;
27634 /* Nothing specified -> width defaults to canonical char width. */
27635 width
= FRAME_COLUMN_WIDTH (it
->f
);
27637 if (width
<= 0 && (width
< 0 || !zero_width_ok_p
))
27640 #ifdef HAVE_WINDOW_SYSTEM
27641 /* Compute height. */
27642 if (FRAME_WINDOW_P (it
->f
))
27644 int default_height
= normal_char_height (font
, ' ');
27646 if ((prop
= Fplist_get (plist
, QCheight
), !NILP (prop
))
27647 && calc_pixel_width_or_height (&tem
, it
, prop
, font
, false, 0))
27650 zero_height_ok_p
= true;
27652 else if (prop
= Fplist_get (plist
, QCrelative_height
),
27654 height
= default_height
* NUMVAL (prop
);
27656 height
= default_height
;
27658 if (height
<= 0 && (height
< 0 || !zero_height_ok_p
))
27661 /* Compute percentage of height used for ascent. If
27662 `:ascent ASCENT' is present and valid, use that. Otherwise,
27663 derive the ascent from the font in use. */
27664 if (prop
= Fplist_get (plist
, QCascent
),
27665 NUMVAL (prop
) > 0 && NUMVAL (prop
) <= 100)
27666 ascent
= height
* NUMVAL (prop
) / 100.0;
27667 else if (!NILP (prop
)
27668 && calc_pixel_width_or_height (&tem
, it
, prop
, font
, false, 0))
27669 ascent
= min (max (0, (int)tem
), height
);
27671 ascent
= (height
* FONT_BASE (font
)) / FONT_HEIGHT (font
);
27674 #endif /* HAVE_WINDOW_SYSTEM */
27677 if (width
> 0 && it
->line_wrap
!= TRUNCATE
27678 && it
->current_x
+ width
> it
->last_visible_x
)
27680 width
= it
->last_visible_x
- it
->current_x
;
27681 #ifdef HAVE_WINDOW_SYSTEM
27682 /* Subtract one more pixel from the stretch width, but only on
27683 GUI frames, since on a TTY each glyph is one "pixel" wide. */
27684 width
-= FRAME_WINDOW_P (it
->f
);
27688 if (width
> 0 && height
> 0 && it
->glyph_row
)
27690 Lisp_Object o_object
= it
->object
;
27691 Lisp_Object object
= it
->stack
[it
->sp
- 1].string
;
27694 if (!STRINGP (object
))
27695 object
= it
->w
->contents
;
27696 #ifdef HAVE_WINDOW_SYSTEM
27697 if (FRAME_WINDOW_P (it
->f
))
27698 append_stretch_glyph (it
, object
, width
, height
, ascent
);
27702 it
->object
= object
;
27703 it
->char_to_display
= ' ';
27704 it
->pixel_width
= it
->len
= 1;
27706 tty_append_glyph (it
);
27707 it
->object
= o_object
;
27711 it
->pixel_width
= width
;
27712 #ifdef HAVE_WINDOW_SYSTEM
27713 if (FRAME_WINDOW_P (it
->f
))
27715 it
->ascent
= it
->phys_ascent
= ascent
;
27716 it
->descent
= it
->phys_descent
= height
- it
->ascent
;
27717 it
->nglyphs
= width
> 0 && height
> 0;
27718 take_vertical_position_into_account (it
);
27722 it
->nglyphs
= width
;
27725 /* Get information about special display element WHAT in an
27726 environment described by IT. WHAT is one of IT_TRUNCATION or
27727 IT_CONTINUATION. Maybe produce glyphs for WHAT if IT has a
27728 non-null glyph_row member. This function ensures that fields like
27729 face_id, c, len of IT are left untouched. */
27732 produce_special_glyphs (struct it
*it
, enum display_element_type what
)
27739 temp_it
.object
= Qnil
;
27740 memset (&temp_it
.current
, 0, sizeof temp_it
.current
);
27742 if (what
== IT_CONTINUATION
)
27744 /* Continuation glyph. For R2L lines, we mirror it by hand. */
27745 if (it
->bidi_it
.paragraph_dir
== R2L
)
27746 SET_GLYPH_FROM_CHAR (glyph
, '/');
27748 SET_GLYPH_FROM_CHAR (glyph
, '\\');
27750 && (gc
= DISP_CONTINUE_GLYPH (it
->dp
), GLYPH_CODE_P (gc
)))
27752 /* FIXME: Should we mirror GC for R2L lines? */
27753 SET_GLYPH_FROM_GLYPH_CODE (glyph
, gc
);
27754 spec_glyph_lookup_face (XWINDOW (it
->window
), &glyph
);
27757 else if (what
== IT_TRUNCATION
)
27759 /* Truncation glyph. */
27760 SET_GLYPH_FROM_CHAR (glyph
, '$');
27762 && (gc
= DISP_TRUNC_GLYPH (it
->dp
), GLYPH_CODE_P (gc
)))
27764 /* FIXME: Should we mirror GC for R2L lines? */
27765 SET_GLYPH_FROM_GLYPH_CODE (glyph
, gc
);
27766 spec_glyph_lookup_face (XWINDOW (it
->window
), &glyph
);
27772 #ifdef HAVE_WINDOW_SYSTEM
27773 /* On a GUI frame, when the right fringe (left fringe for R2L rows)
27774 is turned off, we precede the truncation/continuation glyphs by a
27775 stretch glyph whose width is computed such that these special
27776 glyphs are aligned at the window margin, even when very different
27777 fonts are used in different glyph rows. */
27778 if (FRAME_WINDOW_P (temp_it
.f
)
27779 /* init_iterator calls this with it->glyph_row == NULL, and it
27780 wants only the pixel width of the truncation/continuation
27782 && temp_it
.glyph_row
27783 /* insert_left_trunc_glyphs calls us at the beginning of the
27784 row, and it has its own calculation of the stretch glyph
27786 && temp_it
.glyph_row
->used
[TEXT_AREA
] > 0
27787 && (temp_it
.glyph_row
->reversed_p
27788 ? WINDOW_LEFT_FRINGE_WIDTH (temp_it
.w
)
27789 : WINDOW_RIGHT_FRINGE_WIDTH (temp_it
.w
)) == 0)
27791 int stretch_width
= temp_it
.last_visible_x
- temp_it
.current_x
;
27793 if (stretch_width
> 0)
27795 struct face
*face
= FACE_FROM_ID (temp_it
.f
, temp_it
.face_id
);
27796 struct font
*font
=
27797 face
->font
? face
->font
: FRAME_FONT (temp_it
.f
);
27798 int stretch_ascent
=
27799 (((temp_it
.ascent
+ temp_it
.descent
)
27800 * FONT_BASE (font
)) / FONT_HEIGHT (font
));
27802 append_stretch_glyph (&temp_it
, Qnil
, stretch_width
,
27803 temp_it
.ascent
+ temp_it
.descent
,
27810 temp_it
.what
= IT_CHARACTER
;
27811 temp_it
.c
= temp_it
.char_to_display
= GLYPH_CHAR (glyph
);
27812 temp_it
.face_id
= GLYPH_FACE (glyph
);
27813 temp_it
.len
= CHAR_BYTES (temp_it
.c
);
27815 PRODUCE_GLYPHS (&temp_it
);
27816 it
->pixel_width
= temp_it
.pixel_width
;
27817 it
->nglyphs
= temp_it
.nglyphs
;
27820 #ifdef HAVE_WINDOW_SYSTEM
27822 /* Calculate line-height and line-spacing properties.
27823 An integer value specifies explicit pixel value.
27824 A float value specifies relative value to current face height.
27825 A cons (float . face-name) specifies relative value to
27826 height of specified face font.
27828 Returns height in pixels, or nil. */
27831 calc_line_height_property (struct it
*it
, Lisp_Object val
, struct font
*font
,
27832 int boff
, bool override
)
27834 Lisp_Object face_name
= Qnil
;
27835 int ascent
, descent
, height
;
27837 if (NILP (val
) || INTEGERP (val
) || (override
&& EQ (val
, Qt
)))
27842 face_name
= XCAR (val
);
27844 if (!NUMBERP (val
))
27845 val
= make_number (1);
27846 if (NILP (face_name
))
27848 height
= it
->ascent
+ it
->descent
;
27853 if (NILP (face_name
))
27855 font
= FRAME_FONT (it
->f
);
27856 boff
= FRAME_BASELINE_OFFSET (it
->f
);
27858 else if (EQ (face_name
, Qt
))
27867 face_id
= lookup_named_face (it
->w
, it
->f
, face_name
, false);
27868 face
= FACE_FROM_ID_OR_NULL (it
->f
, face_id
);
27869 if (face
== NULL
|| ((font
= face
->font
) == NULL
))
27870 return make_number (-1);
27871 boff
= font
->baseline_offset
;
27872 if (font
->vertical_centering
)
27873 boff
= VCENTER_BASELINE_OFFSET (font
, it
->f
) - boff
;
27876 normal_char_ascent_descent (font
, -1, &ascent
, &descent
);
27880 it
->override_ascent
= ascent
;
27881 it
->override_descent
= descent
;
27882 it
->override_boff
= boff
;
27885 height
= ascent
+ descent
;
27889 height
= (int)(XFLOAT_DATA (val
) * height
);
27890 else if (INTEGERP (val
))
27891 height
*= XINT (val
);
27893 return make_number (height
);
27897 /* Append a glyph for a glyphless character to IT->glyph_row. FACE_ID
27898 is a face ID to be used for the glyph. FOR_NO_FONT is true if
27899 and only if this is for a character for which no font was found.
27901 If the display method (it->glyphless_method) is
27902 GLYPHLESS_DISPLAY_ACRONYM or GLYPHLESS_DISPLAY_HEX_CODE, LEN is a
27903 length of the acronym or the hexadecimal string, UPPER_XOFF and
27904 UPPER_YOFF are pixel offsets for the upper part of the string,
27905 LOWER_XOFF and LOWER_YOFF are for the lower part.
27907 For the other display methods, LEN through LOWER_YOFF are zero. */
27910 append_glyphless_glyph (struct it
*it
, int face_id
, bool for_no_font
, int len
,
27911 short upper_xoff
, short upper_yoff
,
27912 short lower_xoff
, short lower_yoff
)
27914 struct glyph
*glyph
;
27915 enum glyph_row_area area
= it
->area
;
27917 glyph
= it
->glyph_row
->glyphs
[area
] + it
->glyph_row
->used
[area
];
27918 if (glyph
< it
->glyph_row
->glyphs
[area
+ 1])
27920 /* If the glyph row is reversed, we need to prepend the glyph
27921 rather than append it. */
27922 if (it
->glyph_row
->reversed_p
&& area
== TEXT_AREA
)
27926 /* Make room for the additional glyph. */
27927 for (g
= glyph
- 1; g
>= it
->glyph_row
->glyphs
[area
]; g
--)
27929 glyph
= it
->glyph_row
->glyphs
[area
];
27931 glyph
->charpos
= CHARPOS (it
->position
);
27932 glyph
->object
= it
->object
;
27933 eassert (it
->pixel_width
<= SHRT_MAX
);
27934 glyph
->pixel_width
= it
->pixel_width
;
27935 glyph
->ascent
= it
->ascent
;
27936 glyph
->descent
= it
->descent
;
27937 glyph
->voffset
= it
->voffset
;
27938 glyph
->type
= GLYPHLESS_GLYPH
;
27939 glyph
->u
.glyphless
.method
= it
->glyphless_method
;
27940 glyph
->u
.glyphless
.for_no_font
= for_no_font
;
27941 glyph
->u
.glyphless
.len
= len
;
27942 glyph
->u
.glyphless
.ch
= it
->c
;
27943 glyph
->slice
.glyphless
.upper_xoff
= upper_xoff
;
27944 glyph
->slice
.glyphless
.upper_yoff
= upper_yoff
;
27945 glyph
->slice
.glyphless
.lower_xoff
= lower_xoff
;
27946 glyph
->slice
.glyphless
.lower_yoff
= lower_yoff
;
27947 glyph
->avoid_cursor_p
= it
->avoid_cursor_p
;
27948 glyph
->multibyte_p
= it
->multibyte_p
;
27949 if (it
->glyph_row
->reversed_p
&& area
== TEXT_AREA
)
27951 /* In R2L rows, the left and the right box edges need to be
27952 drawn in reverse direction. */
27953 glyph
->right_box_line_p
= it
->start_of_box_run_p
;
27954 glyph
->left_box_line_p
= it
->end_of_box_run_p
;
27958 glyph
->left_box_line_p
= it
->start_of_box_run_p
;
27959 glyph
->right_box_line_p
= it
->end_of_box_run_p
;
27961 glyph
->overlaps_vertically_p
= (it
->phys_ascent
> it
->ascent
27962 || it
->phys_descent
> it
->descent
);
27963 glyph
->padding_p
= false;
27964 glyph
->glyph_not_available_p
= false;
27965 glyph
->face_id
= face_id
;
27966 glyph
->font_type
= FONT_TYPE_UNKNOWN
;
27969 glyph
->resolved_level
= it
->bidi_it
.resolved_level
;
27970 eassert ((it
->bidi_it
.type
& 7) == it
->bidi_it
.type
);
27971 glyph
->bidi_type
= it
->bidi_it
.type
;
27973 ++it
->glyph_row
->used
[area
];
27976 IT_EXPAND_MATRIX_WIDTH (it
, area
);
27980 /* Produce a glyph for a glyphless character for iterator IT.
27981 IT->glyphless_method specifies which method to use for displaying
27982 the character. See the description of enum
27983 glyphless_display_method in dispextern.h for the detail.
27985 FOR_NO_FONT is true if and only if this is for a character for
27986 which no font was found. ACRONYM, if non-nil, is an acronym string
27987 for the character. */
27990 produce_glyphless_glyph (struct it
*it
, bool for_no_font
, Lisp_Object acronym
)
27995 int base_width
, base_height
, width
, height
;
27996 short upper_xoff
, upper_yoff
, lower_xoff
, lower_yoff
;
27999 /* Get the metrics of the base font. We always refer to the current
28001 face
= FACE_FROM_ID (it
->f
, it
->face_id
)->ascii_face
;
28002 font
= face
->font
? face
->font
: FRAME_FONT (it
->f
);
28003 normal_char_ascent_descent (font
, -1, &it
->ascent
, &it
->descent
);
28004 it
->ascent
+= font
->baseline_offset
;
28005 it
->descent
-= font
->baseline_offset
;
28006 base_height
= it
->ascent
+ it
->descent
;
28007 base_width
= font
->average_width
;
28009 face_id
= merge_glyphless_glyph_face (it
);
28011 if (it
->glyphless_method
== GLYPHLESS_DISPLAY_THIN_SPACE
)
28013 it
->pixel_width
= THIN_SPACE_WIDTH
;
28015 upper_xoff
= upper_yoff
= lower_xoff
= lower_yoff
= 0;
28017 else if (it
->glyphless_method
== GLYPHLESS_DISPLAY_EMPTY_BOX
)
28019 width
= CHARACTER_WIDTH (it
->c
);
28022 else if (width
> 4)
28024 it
->pixel_width
= base_width
* width
;
28026 upper_xoff
= upper_yoff
= lower_xoff
= lower_yoff
= 0;
28032 unsigned int code
[6];
28034 int ascent
, descent
;
28035 struct font_metrics metrics_upper
, metrics_lower
;
28037 face
= FACE_FROM_ID (it
->f
, face_id
);
28038 font
= face
->font
? face
->font
: FRAME_FONT (it
->f
);
28039 prepare_face_for_display (it
->f
, face
);
28041 if (it
->glyphless_method
== GLYPHLESS_DISPLAY_ACRONYM
)
28043 if (! STRINGP (acronym
) && CHAR_TABLE_P (Vglyphless_char_display
))
28044 acronym
= CHAR_TABLE_REF (Vglyphless_char_display
, it
->c
);
28045 if (CONSP (acronym
))
28046 acronym
= XCAR (acronym
);
28047 str
= STRINGP (acronym
) ? SSDATA (acronym
) : "";
28051 eassert (it
->glyphless_method
== GLYPHLESS_DISPLAY_HEX_CODE
);
28052 sprintf (buf
, "%0*X", it
->c
< 0x10000 ? 4 : 6, it
->c
+ 0u);
28055 for (len
= 0; str
[len
] && ASCII_CHAR_P (str
[len
]) && len
< 6; len
++)
28056 code
[len
] = font
->driver
->encode_char (font
, str
[len
]);
28057 upper_len
= (len
+ 1) / 2;
28058 font
->driver
->text_extents (font
, code
, upper_len
,
28060 font
->driver
->text_extents (font
, code
+ upper_len
, len
- upper_len
,
28065 /* +4 is for vertical bars of a box plus 1-pixel spaces at both side. */
28066 width
= max (metrics_upper
.width
, metrics_lower
.width
) + 4;
28067 upper_xoff
= upper_yoff
= 2; /* the typical case */
28068 if (base_width
>= width
)
28070 /* Align the upper to the left, the lower to the right. */
28071 it
->pixel_width
= base_width
;
28072 lower_xoff
= base_width
- 2 - metrics_lower
.width
;
28076 /* Center the shorter one. */
28077 it
->pixel_width
= width
;
28078 if (metrics_upper
.width
>= metrics_lower
.width
)
28079 lower_xoff
= (width
- metrics_lower
.width
) / 2;
28082 /* FIXME: This code doesn't look right. It formerly was
28083 missing the "lower_xoff = 0;", which couldn't have
28084 been right since it left lower_xoff uninitialized. */
28086 upper_xoff
= (width
- metrics_upper
.width
) / 2;
28090 /* +5 is for horizontal bars of a box plus 1-pixel spaces at
28091 top, bottom, and between upper and lower strings. */
28092 height
= (metrics_upper
.ascent
+ metrics_upper
.descent
28093 + metrics_lower
.ascent
+ metrics_lower
.descent
) + 5;
28094 /* Center vertically.
28095 H:base_height, D:base_descent
28096 h:height, ld:lower_descent, la:lower_ascent, ud:upper_descent
28098 ascent = - (D - H/2 - h/2 + 1); "+ 1" for rounding up
28099 descent = D - H/2 + h/2;
28100 lower_yoff = descent - 2 - ld;
28101 upper_yoff = lower_yoff - la - 1 - ud; */
28102 ascent
= - (it
->descent
- (base_height
+ height
+ 1) / 2);
28103 descent
= it
->descent
- (base_height
- height
) / 2;
28104 lower_yoff
= descent
- 2 - metrics_lower
.descent
;
28105 upper_yoff
= (lower_yoff
- metrics_lower
.ascent
- 1
28106 - metrics_upper
.descent
);
28107 /* Don't make the height shorter than the base height. */
28108 if (height
> base_height
)
28110 it
->ascent
= ascent
;
28111 it
->descent
= descent
;
28115 it
->phys_ascent
= it
->ascent
;
28116 it
->phys_descent
= it
->descent
;
28118 append_glyphless_glyph (it
, face_id
, for_no_font
, len
,
28119 upper_xoff
, upper_yoff
,
28120 lower_xoff
, lower_yoff
);
28122 take_vertical_position_into_account (it
);
28127 Produce glyphs/get display metrics for the display element IT is
28128 loaded with. See the description of struct it in dispextern.h
28129 for an overview of struct it. */
28132 x_produce_glyphs (struct it
*it
)
28134 int extra_line_spacing
= it
->extra_line_spacing
;
28136 it
->glyph_not_available_p
= false;
28138 if (it
->what
== IT_CHARACTER
)
28141 struct face
*face
= FACE_FROM_ID (it
->f
, it
->face_id
);
28142 struct font
*font
= face
->font
;
28143 struct font_metrics
*pcm
= NULL
;
28144 int boff
; /* Baseline offset. */
28148 /* When no suitable font is found, display this character by
28149 the method specified in the first extra slot of
28150 Vglyphless_char_display. */
28151 Lisp_Object acronym
= lookup_glyphless_char_display (-1, it
);
28153 eassert (it
->what
== IT_GLYPHLESS
);
28154 produce_glyphless_glyph (it
, true,
28155 STRINGP (acronym
) ? acronym
: Qnil
);
28159 boff
= font
->baseline_offset
;
28160 if (font
->vertical_centering
)
28161 boff
= VCENTER_BASELINE_OFFSET (font
, it
->f
) - boff
;
28163 if (it
->char_to_display
!= '\n' && it
->char_to_display
!= '\t')
28167 if (it
->override_ascent
>= 0)
28169 it
->ascent
= it
->override_ascent
;
28170 it
->descent
= it
->override_descent
;
28171 boff
= it
->override_boff
;
28175 it
->ascent
= FONT_BASE (font
) + boff
;
28176 it
->descent
= FONT_DESCENT (font
) - boff
;
28179 if (get_char_glyph_code (it
->char_to_display
, font
, &char2b
))
28181 pcm
= get_per_char_metric (font
, &char2b
);
28182 if (pcm
->width
== 0
28183 && pcm
->rbearing
== 0 && pcm
->lbearing
== 0)
28189 it
->phys_ascent
= pcm
->ascent
+ boff
;
28190 it
->phys_descent
= pcm
->descent
- boff
;
28191 it
->pixel_width
= pcm
->width
;
28192 /* Don't use font-global values for ascent and descent
28193 if they result in an exceedingly large line height. */
28194 if (it
->override_ascent
< 0)
28196 if (FONT_TOO_HIGH (font
))
28198 it
->ascent
= it
->phys_ascent
;
28199 it
->descent
= it
->phys_descent
;
28200 /* These limitations are enforced by an
28201 assertion near the end of this function. */
28202 if (it
->ascent
< 0)
28204 if (it
->descent
< 0)
28211 it
->glyph_not_available_p
= true;
28212 it
->phys_ascent
= it
->ascent
;
28213 it
->phys_descent
= it
->descent
;
28214 it
->pixel_width
= font
->space_width
;
28217 if (it
->constrain_row_ascent_descent_p
)
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 extra_line_spacing
= 0;
28234 /* If this is a space inside a region of text with
28235 `space-width' property, change its width. */
28237 = it
->char_to_display
== ' ' && !NILP (it
->space_width
);
28239 it
->pixel_width
*= XFLOATINT (it
->space_width
);
28241 /* If face has a box, add the box thickness to the character
28242 height. If character has a box line to the left and/or
28243 right, add the box line width to the character's width. */
28244 if (face
->box
!= FACE_NO_BOX
)
28246 int thick
= face
->box_line_width
;
28250 it
->ascent
+= thick
;
28251 it
->descent
+= thick
;
28256 if (it
->start_of_box_run_p
)
28257 it
->pixel_width
+= thick
;
28258 if (it
->end_of_box_run_p
)
28259 it
->pixel_width
+= thick
;
28262 /* If face has an overline, add the height of the overline
28263 (1 pixel) and a 1 pixel margin to the character height. */
28264 if (face
->overline_p
)
28265 it
->ascent
+= overline_margin
;
28267 if (it
->constrain_row_ascent_descent_p
)
28269 if (it
->ascent
> it
->max_ascent
)
28270 it
->ascent
= it
->max_ascent
;
28271 if (it
->descent
> it
->max_descent
)
28272 it
->descent
= it
->max_descent
;
28275 take_vertical_position_into_account (it
);
28277 /* If we have to actually produce glyphs, do it. */
28282 /* Translate a space with a `space-width' property
28283 into a stretch glyph. */
28284 int ascent
= (((it
->ascent
+ it
->descent
) * FONT_BASE (font
))
28285 / FONT_HEIGHT (font
));
28286 append_stretch_glyph (it
, it
->object
, it
->pixel_width
,
28287 it
->ascent
+ it
->descent
, ascent
);
28292 /* If characters with lbearing or rbearing are displayed
28293 in this line, record that fact in a flag of the
28294 glyph row. This is used to optimize X output code. */
28295 if (pcm
&& (pcm
->lbearing
< 0 || pcm
->rbearing
> pcm
->width
))
28296 it
->glyph_row
->contains_overlapping_glyphs_p
= true;
28298 if (! stretched_p
&& it
->pixel_width
== 0)
28299 /* We assure that all visible glyphs have at least 1-pixel
28301 it
->pixel_width
= 1;
28303 else if (it
->char_to_display
== '\n')
28305 /* A newline has no width, but we need the height of the
28306 line. But if previous part of the line sets a height,
28307 don't increase that height. */
28309 Lisp_Object height
;
28310 Lisp_Object total_height
= Qnil
;
28312 it
->override_ascent
= -1;
28313 it
->pixel_width
= 0;
28316 height
= get_it_property (it
, Qline_height
);
28317 /* Split (line-height total-height) list. */
28319 && CONSP (XCDR (height
))
28320 && NILP (XCDR (XCDR (height
))))
28322 total_height
= XCAR (XCDR (height
));
28323 height
= XCAR (height
);
28325 height
= calc_line_height_property (it
, height
, font
, boff
, true);
28327 if (it
->override_ascent
>= 0)
28329 it
->ascent
= it
->override_ascent
;
28330 it
->descent
= it
->override_descent
;
28331 boff
= it
->override_boff
;
28335 if (FONT_TOO_HIGH (font
))
28337 it
->ascent
= font
->pixel_size
+ boff
- 1;
28338 it
->descent
= -boff
+ 1;
28339 if (it
->descent
< 0)
28344 it
->ascent
= FONT_BASE (font
) + boff
;
28345 it
->descent
= FONT_DESCENT (font
) - boff
;
28349 if (EQ (height
, Qt
))
28351 if (it
->descent
> it
->max_descent
)
28353 it
->ascent
+= it
->descent
- it
->max_descent
;
28354 it
->descent
= it
->max_descent
;
28356 if (it
->ascent
> it
->max_ascent
)
28358 it
->descent
= min (it
->max_descent
, it
->descent
+ it
->ascent
- it
->max_ascent
);
28359 it
->ascent
= it
->max_ascent
;
28361 it
->phys_ascent
= min (it
->phys_ascent
, it
->ascent
);
28362 it
->phys_descent
= min (it
->phys_descent
, it
->descent
);
28363 it
->constrain_row_ascent_descent_p
= true;
28364 extra_line_spacing
= 0;
28368 Lisp_Object spacing
;
28370 it
->phys_ascent
= it
->ascent
;
28371 it
->phys_descent
= it
->descent
;
28373 if ((it
->max_ascent
> 0 || it
->max_descent
> 0)
28374 && face
->box
!= FACE_NO_BOX
28375 && face
->box_line_width
> 0)
28377 it
->ascent
+= face
->box_line_width
;
28378 it
->descent
+= face
->box_line_width
;
28381 && XINT (height
) > it
->ascent
+ it
->descent
)
28382 it
->ascent
= XINT (height
) - it
->descent
;
28384 if (!NILP (total_height
))
28385 spacing
= calc_line_height_property (it
, total_height
, font
,
28389 spacing
= get_it_property (it
, Qline_spacing
);
28390 spacing
= calc_line_height_property (it
, spacing
, font
,
28393 if (INTEGERP (spacing
))
28395 extra_line_spacing
= XINT (spacing
);
28396 if (!NILP (total_height
))
28397 extra_line_spacing
-= (it
->phys_ascent
+ it
->phys_descent
);
28401 else /* i.e. (it->char_to_display == '\t') */
28403 if (font
->space_width
> 0)
28405 int tab_width
= it
->tab_width
* font
->space_width
;
28406 int x
= it
->current_x
+ it
->continuation_lines_width
;
28408 /* Adjust for line numbers, if needed. */
28409 if (!NILP (Vdisplay_line_numbers
) && it
->line_number_produced_p
)
28411 x
-= it
->lnum_pixel_width
;
28412 /* Restore the original TAB width, if required. */
28413 if (x
+ it
->tab_offset
>= it
->first_visible_x
)
28414 x
+= it
->tab_offset
;
28417 int next_tab_x
= ((1 + x
+ tab_width
- 1) / tab_width
) * tab_width
;
28419 /* If the distance from the current position to the next tab
28420 stop is less than a space character width, use the
28421 tab stop after that. */
28422 if (next_tab_x
- x
< font
->space_width
)
28423 next_tab_x
+= tab_width
;
28424 if (!NILP (Vdisplay_line_numbers
) && it
->line_number_produced_p
)
28426 next_tab_x
+= it
->lnum_pixel_width
;
28427 /* If the line is hscrolled, and the TAB starts before
28428 the first visible pixel, simulate negative row->x. */
28429 if (x
< it
->first_visible_x
)
28431 next_tab_x
-= it
->first_visible_x
- x
;
28432 it
->tab_offset
= it
->first_visible_x
- x
;
28435 next_tab_x
-= it
->tab_offset
;
28438 it
->pixel_width
= next_tab_x
- x0
;
28440 if (FONT_TOO_HIGH (font
))
28442 if (get_char_glyph_code (' ', font
, &char2b
))
28444 pcm
= get_per_char_metric (font
, &char2b
);
28445 if (pcm
->width
== 0
28446 && pcm
->rbearing
== 0 && pcm
->lbearing
== 0)
28452 it
->ascent
= pcm
->ascent
+ boff
;
28453 it
->descent
= pcm
->descent
- boff
;
28457 it
->ascent
= font
->pixel_size
+ boff
- 1;
28458 it
->descent
= -boff
+ 1;
28460 if (it
->ascent
< 0)
28462 if (it
->descent
< 0)
28467 it
->ascent
= FONT_BASE (font
) + boff
;
28468 it
->descent
= FONT_DESCENT (font
) - boff
;
28470 it
->phys_ascent
= it
->ascent
;
28471 it
->phys_descent
= it
->descent
;
28475 append_stretch_glyph (it
, it
->object
, it
->pixel_width
,
28476 it
->ascent
+ it
->descent
, it
->ascent
);
28481 it
->pixel_width
= 0;
28486 if (FONT_TOO_HIGH (font
))
28488 int font_ascent
, font_descent
;
28490 /* For very large fonts, where we ignore the declared font
28491 dimensions, and go by per-character metrics instead,
28492 don't let the row ascent and descent values (and the row
28493 height computed from them) be smaller than the "normal"
28494 character metrics. This avoids unpleasant effects
28495 whereby lines on display would change their height
28496 depending on which characters are shown. */
28497 normal_char_ascent_descent (font
, -1, &font_ascent
, &font_descent
);
28498 it
->max_ascent
= max (it
->max_ascent
, font_ascent
);
28499 it
->max_descent
= max (it
->max_descent
, font_descent
);
28502 else if (it
->what
== IT_COMPOSITION
&& it
->cmp_it
.ch
< 0)
28504 /* A static composition.
28506 Note: A composition is represented as one glyph in the
28507 glyph matrix. There are no padding glyphs.
28509 Important note: pixel_width, ascent, and descent are the
28510 values of what is drawn by draw_glyphs (i.e. the values of
28511 the overall glyphs composed). */
28512 struct face
*face
= FACE_FROM_ID (it
->f
, it
->face_id
);
28513 int boff
; /* baseline offset */
28514 struct composition
*cmp
= composition_table
[it
->cmp_it
.id
];
28515 int glyph_len
= cmp
->glyph_len
;
28516 struct font
*font
= face
->font
;
28520 /* If we have not yet calculated pixel size data of glyphs of
28521 the composition for the current face font, calculate them
28522 now. Theoretically, we have to check all fonts for the
28523 glyphs, but that requires much time and memory space. So,
28524 here we check only the font of the first glyph. This may
28525 lead to incorrect display, but it's very rare, and C-l
28526 (recenter-top-bottom) can correct the display anyway. */
28527 if (! cmp
->font
|| cmp
->font
!= font
)
28529 /* Ascent and descent of the font of the first character
28530 of this composition (adjusted by baseline offset).
28531 Ascent and descent of overall glyphs should not be less
28532 than these, respectively. */
28533 int font_ascent
, font_descent
, font_height
;
28534 /* Bounding box of the overall glyphs. */
28535 int leftmost
, rightmost
, lowest
, highest
;
28536 int lbearing
, rbearing
;
28537 int i
, width
, ascent
, descent
;
28540 struct font_metrics
*pcm
;
28543 eassume (0 < glyph_len
); /* See Bug#8512. */
28545 c
= COMPOSITION_GLYPH (cmp
, glyph_len
- 1);
28546 while (c
== '\t' && 0 < --glyph_len
);
28548 bool right_padded
= glyph_len
< cmp
->glyph_len
;
28549 for (i
= 0; i
< glyph_len
; i
++)
28551 c
= COMPOSITION_GLYPH (cmp
, i
);
28554 cmp
->offsets
[i
* 2] = cmp
->offsets
[i
* 2 + 1] = 0;
28556 bool left_padded
= i
> 0;
28558 pos
= (STRINGP (it
->string
) ? IT_STRING_CHARPOS (*it
)
28559 : IT_CHARPOS (*it
));
28560 /* If no suitable font is found, use the default font. */
28561 bool font_not_found_p
= font
== NULL
;
28562 if (font_not_found_p
)
28564 face
= face
->ascii_face
;
28567 boff
= font
->baseline_offset
;
28568 if (font
->vertical_centering
)
28569 boff
= VCENTER_BASELINE_OFFSET (font
, it
->f
) - boff
;
28570 normal_char_ascent_descent (font
, -1, &font_ascent
, &font_descent
);
28571 font_ascent
+= boff
;
28572 font_descent
-= boff
;
28573 font_height
= font_ascent
+ font_descent
;
28578 if (! font_not_found_p
)
28580 get_char_face_and_encoding (it
->f
, c
, it
->face_id
,
28582 pcm
= get_per_char_metric (font
, &char2b
);
28585 /* Initialize the bounding box. */
28588 width
= cmp
->glyph_len
> 0 ? pcm
->width
: 0;
28589 ascent
= pcm
->ascent
;
28590 descent
= pcm
->descent
;
28591 lbearing
= pcm
->lbearing
;
28592 rbearing
= pcm
->rbearing
;
28596 width
= cmp
->glyph_len
> 0 ? font
->space_width
: 0;
28597 ascent
= FONT_BASE (font
);
28598 descent
= FONT_DESCENT (font
);
28605 lowest
= - descent
+ boff
;
28606 highest
= ascent
+ boff
;
28608 if (! font_not_found_p
28609 && font
->default_ascent
28610 && CHAR_TABLE_P (Vuse_default_ascent
)
28611 && !NILP (Faref (Vuse_default_ascent
,
28612 make_number (it
->char_to_display
))))
28613 highest
= font
->default_ascent
+ boff
;
28615 /* Draw the first glyph at the normal position. It may be
28616 shifted to right later if some other glyphs are drawn
28618 cmp
->offsets
[i
* 2] = 0;
28619 cmp
->offsets
[i
* 2 + 1] = boff
;
28620 cmp
->lbearing
= lbearing
;
28621 cmp
->rbearing
= rbearing
;
28623 /* Set cmp->offsets for the remaining glyphs. */
28624 for (i
++; i
< glyph_len
; i
++)
28626 int left
, right
, btm
, top
;
28627 int ch
= COMPOSITION_GLYPH (cmp
, i
);
28629 struct face
*this_face
;
28633 face_id
= FACE_FOR_CHAR (it
->f
, face
, ch
, pos
, it
->string
);
28634 this_face
= FACE_FROM_ID (it
->f
, face_id
);
28635 font
= this_face
->font
;
28641 get_char_face_and_encoding (it
->f
, ch
, face_id
,
28643 pcm
= get_per_char_metric (font
, &char2b
);
28646 cmp
->offsets
[i
* 2] = cmp
->offsets
[i
* 2 + 1] = 0;
28649 width
= pcm
->width
;
28650 ascent
= pcm
->ascent
;
28651 descent
= pcm
->descent
;
28652 lbearing
= pcm
->lbearing
;
28653 rbearing
= pcm
->rbearing
;
28654 if (cmp
->method
!= COMPOSITION_WITH_RULE_ALTCHARS
)
28656 /* Relative composition with or without
28657 alternate chars. */
28658 left
= (leftmost
+ rightmost
- width
) / 2;
28659 btm
= - descent
+ boff
;
28660 if (font
->relative_compose
28661 && (! CHAR_TABLE_P (Vignore_relative_composition
)
28662 || NILP (Faref (Vignore_relative_composition
,
28663 make_number (ch
)))))
28666 if (- descent
>= font
->relative_compose
)
28667 /* One extra pixel between two glyphs. */
28669 else if (ascent
<= 0)
28670 /* One extra pixel between two glyphs. */
28671 btm
= lowest
- 1 - ascent
- descent
;
28676 /* A composition rule is specified by an integer
28677 value that encodes global and new reference
28678 points (GREF and NREF). GREF and NREF are
28679 specified by numbers as below:
28681 0---1---2 -- ascent
28685 9--10--11 -- center
28687 ---3---4---5--- baseline
28689 6---7---8 -- descent
28691 int rule
= COMPOSITION_RULE (cmp
, i
);
28692 int gref
, nref
, grefx
, grefy
, nrefx
, nrefy
, xoff
, yoff
;
28694 COMPOSITION_DECODE_RULE (rule
, gref
, nref
, xoff
, yoff
);
28695 grefx
= gref
% 3, nrefx
= nref
% 3;
28696 grefy
= gref
/ 3, nrefy
= nref
/ 3;
28698 xoff
= font_height
* (xoff
- 128) / 256;
28700 yoff
= font_height
* (yoff
- 128) / 256;
28703 + grefx
* (rightmost
- leftmost
) / 2
28704 - nrefx
* width
/ 2
28707 btm
= ((grefy
== 0 ? highest
28709 : grefy
== 2 ? lowest
28710 : (highest
+ lowest
) / 2)
28711 - (nrefy
== 0 ? ascent
+ descent
28712 : nrefy
== 1 ? descent
- boff
28714 : (ascent
+ descent
) / 2)
28718 cmp
->offsets
[i
* 2] = left
;
28719 cmp
->offsets
[i
* 2 + 1] = btm
+ descent
;
28721 /* Update the bounding box of the overall glyphs. */
28724 right
= left
+ width
;
28725 if (left
< leftmost
)
28727 if (right
> rightmost
)
28730 top
= btm
+ descent
+ ascent
;
28736 if (cmp
->lbearing
> left
+ lbearing
)
28737 cmp
->lbearing
= left
+ lbearing
;
28738 if (cmp
->rbearing
< left
+ rbearing
)
28739 cmp
->rbearing
= left
+ rbearing
;
28743 /* If there are glyphs whose x-offsets are negative,
28744 shift all glyphs to the right and make all x-offsets
28748 for (i
= 0; i
< cmp
->glyph_len
; i
++)
28749 cmp
->offsets
[i
* 2] -= leftmost
;
28750 rightmost
-= leftmost
;
28751 cmp
->lbearing
-= leftmost
;
28752 cmp
->rbearing
-= leftmost
;
28755 if (left_padded
&& cmp
->lbearing
< 0)
28757 for (i
= 0; i
< cmp
->glyph_len
; i
++)
28758 cmp
->offsets
[i
* 2] -= cmp
->lbearing
;
28759 rightmost
-= cmp
->lbearing
;
28760 cmp
->rbearing
-= cmp
->lbearing
;
28763 if (right_padded
&& rightmost
< cmp
->rbearing
)
28765 rightmost
= cmp
->rbearing
;
28768 cmp
->pixel_width
= rightmost
;
28769 cmp
->ascent
= highest
;
28770 cmp
->descent
= - lowest
;
28771 if (cmp
->ascent
< font_ascent
)
28772 cmp
->ascent
= font_ascent
;
28773 if (cmp
->descent
< font_descent
)
28774 cmp
->descent
= font_descent
;
28778 && (cmp
->lbearing
< 0
28779 || cmp
->rbearing
> cmp
->pixel_width
))
28780 it
->glyph_row
->contains_overlapping_glyphs_p
= true;
28782 it
->pixel_width
= cmp
->pixel_width
;
28783 it
->ascent
= it
->phys_ascent
= cmp
->ascent
;
28784 it
->descent
= it
->phys_descent
= cmp
->descent
;
28785 if (face
->box
!= FACE_NO_BOX
)
28787 int thick
= face
->box_line_width
;
28791 it
->ascent
+= thick
;
28792 it
->descent
+= thick
;
28797 if (it
->start_of_box_run_p
)
28798 it
->pixel_width
+= thick
;
28799 if (it
->end_of_box_run_p
)
28800 it
->pixel_width
+= thick
;
28803 /* If face has an overline, add the height of the overline
28804 (1 pixel) and a 1 pixel margin to the character height. */
28805 if (face
->overline_p
)
28806 it
->ascent
+= overline_margin
;
28808 take_vertical_position_into_account (it
);
28809 if (it
->ascent
< 0)
28811 if (it
->descent
< 0)
28814 if (it
->glyph_row
&& cmp
->glyph_len
> 0)
28815 append_composite_glyph (it
);
28817 else if (it
->what
== IT_COMPOSITION
)
28819 /* A dynamic (automatic) composition. */
28820 struct face
*face
= FACE_FROM_ID (it
->f
, it
->face_id
);
28821 Lisp_Object gstring
;
28822 struct font_metrics metrics
;
28826 gstring
= composition_gstring_from_id (it
->cmp_it
.id
);
28828 = composition_gstring_width (gstring
, it
->cmp_it
.from
, it
->cmp_it
.to
,
28831 && (metrics
.lbearing
< 0 || metrics
.rbearing
> metrics
.width
))
28832 it
->glyph_row
->contains_overlapping_glyphs_p
= true;
28833 it
->ascent
= it
->phys_ascent
= metrics
.ascent
;
28834 it
->descent
= it
->phys_descent
= metrics
.descent
;
28835 if (face
->box
!= FACE_NO_BOX
)
28837 int thick
= face
->box_line_width
;
28841 it
->ascent
+= thick
;
28842 it
->descent
+= thick
;
28847 if (it
->start_of_box_run_p
)
28848 it
->pixel_width
+= thick
;
28849 if (it
->end_of_box_run_p
)
28850 it
->pixel_width
+= thick
;
28852 /* If face has an overline, add the height of the overline
28853 (1 pixel) and a 1 pixel margin to the character height. */
28854 if (face
->overline_p
)
28855 it
->ascent
+= overline_margin
;
28856 take_vertical_position_into_account (it
);
28857 if (it
->ascent
< 0)
28859 if (it
->descent
< 0)
28863 append_composite_glyph (it
);
28865 else if (it
->what
== IT_GLYPHLESS
)
28866 produce_glyphless_glyph (it
, false, Qnil
);
28867 else if (it
->what
== IT_IMAGE
)
28868 produce_image_glyph (it
);
28869 else if (it
->what
== IT_STRETCH
)
28870 produce_stretch_glyph (it
);
28871 else if (it
->what
== IT_XWIDGET
)
28872 produce_xwidget_glyph (it
);
28875 /* Accumulate dimensions. Note: can't assume that it->descent > 0
28876 because this isn't true for images with `:ascent 100'. */
28877 eassert (it
->ascent
>= 0 && it
->descent
>= 0);
28878 if (it
->area
== TEXT_AREA
)
28879 it
->current_x
+= it
->pixel_width
;
28881 if (extra_line_spacing
> 0)
28883 it
->descent
+= extra_line_spacing
;
28884 if (extra_line_spacing
> it
->max_extra_line_spacing
)
28885 it
->max_extra_line_spacing
= extra_line_spacing
;
28888 it
->max_ascent
= max (it
->max_ascent
, it
->ascent
);
28889 it
->max_descent
= max (it
->max_descent
, it
->descent
);
28890 it
->max_phys_ascent
= max (it
->max_phys_ascent
, it
->phys_ascent
);
28891 it
->max_phys_descent
= max (it
->max_phys_descent
, it
->phys_descent
);
28895 Output LEN glyphs starting at START at the nominal cursor position.
28896 Advance the nominal cursor over the text. UPDATED_ROW is the glyph row
28897 being updated, and UPDATED_AREA is the area of that row being updated. */
28900 x_write_glyphs (struct window
*w
, struct glyph_row
*updated_row
,
28901 struct glyph
*start
, enum glyph_row_area updated_area
, int len
)
28903 int x
, hpos
, chpos
= w
->phys_cursor
.hpos
;
28905 eassert (updated_row
);
28906 /* When the window is hscrolled, cursor hpos can legitimately be out
28907 of bounds, but we draw the cursor at the corresponding window
28908 margin in that case. */
28909 if (!updated_row
->reversed_p
&& chpos
< 0)
28911 if (updated_row
->reversed_p
&& chpos
>= updated_row
->used
[TEXT_AREA
])
28912 chpos
= updated_row
->used
[TEXT_AREA
] - 1;
28916 /* Write glyphs. */
28918 hpos
= start
- updated_row
->glyphs
[updated_area
];
28919 x
= draw_glyphs (w
, w
->output_cursor
.x
,
28920 updated_row
, updated_area
,
28922 DRAW_NORMAL_TEXT
, 0);
28924 /* Invalidate old phys cursor if the glyph at its hpos is redrawn. */
28925 if (updated_area
== TEXT_AREA
28926 && w
->phys_cursor_on_p
28927 && w
->phys_cursor
.vpos
== w
->output_cursor
.vpos
28929 && chpos
< hpos
+ len
)
28930 w
->phys_cursor_on_p
= false;
28934 /* Advance the output cursor. */
28935 w
->output_cursor
.hpos
+= len
;
28936 w
->output_cursor
.x
= x
;
28941 Insert LEN glyphs from START at the nominal cursor position. */
28944 x_insert_glyphs (struct window
*w
, struct glyph_row
*updated_row
,
28945 struct glyph
*start
, enum glyph_row_area updated_area
, int len
)
28948 int line_height
, shift_by_width
, shifted_region_width
;
28949 struct glyph_row
*row
;
28950 struct glyph
*glyph
;
28951 int frame_x
, frame_y
;
28954 eassert (updated_row
);
28956 f
= XFRAME (WINDOW_FRAME (w
));
28958 /* Get the height of the line we are in. */
28960 line_height
= row
->height
;
28962 /* Get the width of the glyphs to insert. */
28963 shift_by_width
= 0;
28964 for (glyph
= start
; glyph
< start
+ len
; ++glyph
)
28965 shift_by_width
+= glyph
->pixel_width
;
28967 /* Get the width of the region to shift right. */
28968 shifted_region_width
= (window_box_width (w
, updated_area
)
28969 - w
->output_cursor
.x
28973 frame_x
= window_box_left (w
, updated_area
) + w
->output_cursor
.x
;
28974 frame_y
= WINDOW_TO_FRAME_PIXEL_Y (w
, w
->output_cursor
.y
);
28976 FRAME_RIF (f
)->shift_glyphs_for_insert (f
, frame_x
, frame_y
, shifted_region_width
,
28977 line_height
, shift_by_width
);
28979 /* Write the glyphs. */
28980 hpos
= start
- row
->glyphs
[updated_area
];
28981 draw_glyphs (w
, w
->output_cursor
.x
, row
, updated_area
,
28983 DRAW_NORMAL_TEXT
, 0);
28985 /* Advance the output cursor. */
28986 w
->output_cursor
.hpos
+= len
;
28987 w
->output_cursor
.x
+= shift_by_width
;
28993 Erase the current text line from the nominal cursor position
28994 (inclusive) to pixel column TO_X (exclusive). The idea is that
28995 everything from TO_X onward is already erased.
28997 TO_X is a pixel position relative to UPDATED_AREA of currently
28998 updated window W. TO_X == -1 means clear to the end of this area. */
29001 x_clear_end_of_line (struct window
*w
, struct glyph_row
*updated_row
,
29002 enum glyph_row_area updated_area
, int to_x
)
29005 int max_x
, min_y
, max_y
;
29006 int from_x
, from_y
, to_y
;
29008 eassert (updated_row
);
29009 f
= XFRAME (w
->frame
);
29011 if (updated_row
->full_width_p
)
29012 max_x
= (WINDOW_PIXEL_WIDTH (w
)
29013 - (updated_row
->mode_line_p
? WINDOW_RIGHT_DIVIDER_WIDTH (w
) : 0));
29015 max_x
= window_box_width (w
, updated_area
);
29016 max_y
= window_text_bottom_y (w
);
29018 /* TO_X == 0 means don't do anything. TO_X < 0 means clear to end
29019 of window. For TO_X > 0, truncate to end of drawing area. */
29025 to_x
= min (to_x
, max_x
);
29027 to_y
= min (max_y
, w
->output_cursor
.y
+ updated_row
->height
);
29029 /* Notice if the cursor will be cleared by this operation. */
29030 if (!updated_row
->full_width_p
)
29031 notice_overwritten_cursor (w
, updated_area
,
29032 w
->output_cursor
.x
, -1,
29034 MATRIX_ROW_BOTTOM_Y (updated_row
));
29036 from_x
= w
->output_cursor
.x
;
29038 /* Translate to frame coordinates. */
29039 if (updated_row
->full_width_p
)
29041 from_x
= WINDOW_TO_FRAME_PIXEL_X (w
, from_x
);
29042 to_x
= WINDOW_TO_FRAME_PIXEL_X (w
, to_x
);
29046 int area_left
= window_box_left (w
, updated_area
);
29047 from_x
+= area_left
;
29051 min_y
= WINDOW_HEADER_LINE_HEIGHT (w
);
29052 from_y
= WINDOW_TO_FRAME_PIXEL_Y (w
, max (min_y
, w
->output_cursor
.y
));
29053 to_y
= WINDOW_TO_FRAME_PIXEL_Y (w
, to_y
);
29055 /* Prevent inadvertently clearing to end of the X window. */
29056 if (to_x
> from_x
&& to_y
> from_y
)
29059 FRAME_RIF (f
)->clear_frame_area (f
, from_x
, from_y
,
29060 to_x
- from_x
, to_y
- from_y
);
29065 #endif /* HAVE_WINDOW_SYSTEM */
29069 /***********************************************************************
29071 ***********************************************************************/
29073 /* Value is the internal representation of the specified cursor type
29074 ARG. If type is BAR_CURSOR, return in *WIDTH the specified width
29075 of the bar cursor. */
29077 static enum text_cursor_kinds
29078 get_specified_cursor_type (Lisp_Object arg
, int *width
)
29080 enum text_cursor_kinds type
;
29085 if (EQ (arg
, Qbox
))
29086 return FILLED_BOX_CURSOR
;
29088 if (EQ (arg
, Qhollow
))
29089 return HOLLOW_BOX_CURSOR
;
29091 if (EQ (arg
, Qbar
))
29098 && EQ (XCAR (arg
), Qbar
)
29099 && RANGED_INTEGERP (0, XCDR (arg
), INT_MAX
))
29101 *width
= XINT (XCDR (arg
));
29105 if (EQ (arg
, Qhbar
))
29108 return HBAR_CURSOR
;
29112 && EQ (XCAR (arg
), Qhbar
)
29113 && RANGED_INTEGERP (0, XCDR (arg
), INT_MAX
))
29115 *width
= XINT (XCDR (arg
));
29116 return HBAR_CURSOR
;
29119 /* Treat anything unknown as "hollow box cursor".
29120 It was bad to signal an error; people have trouble fixing
29121 .Xdefaults with Emacs, when it has something bad in it. */
29122 type
= HOLLOW_BOX_CURSOR
;
29127 /* Set the default cursor types for specified frame. */
29129 set_frame_cursor_types (struct frame
*f
, Lisp_Object arg
)
29134 FRAME_DESIRED_CURSOR (f
) = get_specified_cursor_type (arg
, &width
);
29135 FRAME_CURSOR_WIDTH (f
) = width
;
29137 /* By default, set up the blink-off state depending on the on-state. */
29139 tem
= Fassoc (arg
, Vblink_cursor_alist
, Qnil
);
29142 FRAME_BLINK_OFF_CURSOR (f
)
29143 = get_specified_cursor_type (XCDR (tem
), &width
);
29144 FRAME_BLINK_OFF_CURSOR_WIDTH (f
) = width
;
29147 FRAME_BLINK_OFF_CURSOR (f
) = DEFAULT_CURSOR
;
29149 /* Make sure the cursor gets redrawn. */
29150 f
->cursor_type_changed
= true;
29154 #ifdef HAVE_WINDOW_SYSTEM
29156 /* Return the cursor we want to be displayed in window W. Return
29157 width of bar/hbar cursor through WIDTH arg. Return with
29158 ACTIVE_CURSOR arg set to true if cursor in window W is `active'
29159 (i.e. if the `system caret' should track this cursor).
29161 In a mini-buffer window, we want the cursor only to appear if we
29162 are reading input from this window. For the selected window, we
29163 want the cursor type given by the frame parameter or buffer local
29164 setting of cursor-type. If explicitly marked off, draw no cursor.
29165 In all other cases, we want a hollow box cursor. */
29167 static enum text_cursor_kinds
29168 get_window_cursor_type (struct window
*w
, struct glyph
*glyph
, int *width
,
29169 bool *active_cursor
)
29171 struct frame
*f
= XFRAME (w
->frame
);
29172 struct buffer
*b
= XBUFFER (w
->contents
);
29173 int cursor_type
= DEFAULT_CURSOR
;
29174 Lisp_Object alt_cursor
;
29175 bool non_selected
= false;
29177 *active_cursor
= true;
29180 if (cursor_in_echo_area
29181 && FRAME_HAS_MINIBUF_P (f
)
29182 && EQ (FRAME_MINIBUF_WINDOW (f
), echo_area_window
))
29184 if (w
== XWINDOW (echo_area_window
))
29186 if (EQ (BVAR (b
, cursor_type
), Qt
) || NILP (BVAR (b
, cursor_type
)))
29188 *width
= FRAME_CURSOR_WIDTH (f
);
29189 return FRAME_DESIRED_CURSOR (f
);
29192 return get_specified_cursor_type (BVAR (b
, cursor_type
), width
);
29195 *active_cursor
= false;
29196 non_selected
= true;
29199 /* Detect a nonselected window or nonselected frame. */
29200 else if (w
!= XWINDOW (f
->selected_window
)
29201 || f
!= FRAME_DISPLAY_INFO (f
)->x_highlight_frame
)
29203 *active_cursor
= false;
29205 if (MINI_WINDOW_P (w
) && minibuf_level
== 0)
29208 non_selected
= true;
29211 /* Never display a cursor in a window in which cursor-type is nil. */
29212 if (NILP (BVAR (b
, cursor_type
)))
29215 /* Get the normal cursor type for this window. */
29216 if (EQ (BVAR (b
, cursor_type
), Qt
))
29218 cursor_type
= FRAME_DESIRED_CURSOR (f
);
29219 *width
= FRAME_CURSOR_WIDTH (f
);
29222 cursor_type
= get_specified_cursor_type (BVAR (b
, cursor_type
), width
);
29224 /* Use cursor-in-non-selected-windows instead
29225 for non-selected window or frame. */
29228 alt_cursor
= BVAR (b
, cursor_in_non_selected_windows
);
29229 if (!EQ (Qt
, alt_cursor
))
29230 return get_specified_cursor_type (alt_cursor
, width
);
29231 /* t means modify the normal cursor type. */
29232 if (cursor_type
== FILLED_BOX_CURSOR
)
29233 cursor_type
= HOLLOW_BOX_CURSOR
;
29234 else if (cursor_type
== BAR_CURSOR
&& *width
> 1)
29236 return cursor_type
;
29239 /* Use normal cursor if not blinked off. */
29240 if (!w
->cursor_off_p
)
29242 if (glyph
!= NULL
&& glyph
->type
== XWIDGET_GLYPH
)
29244 if (glyph
!= NULL
&& glyph
->type
== IMAGE_GLYPH
)
29246 if (cursor_type
== FILLED_BOX_CURSOR
)
29248 /* Using a block cursor on large images can be very annoying.
29249 So use a hollow cursor for "large" images.
29250 If image is not transparent (no mask), also use hollow cursor. */
29251 struct image
*img
= IMAGE_OPT_FROM_ID (f
, glyph
->u
.img_id
);
29252 if (img
!= NULL
&& IMAGEP (img
->spec
))
29254 /* Arbitrarily, interpret "Large" as >32x32 and >NxN
29255 where N = size of default frame font size.
29256 This should cover most of the "tiny" icons people may use. */
29258 || img
->width
> max (32, WINDOW_FRAME_COLUMN_WIDTH (w
))
29259 || img
->height
> max (32, WINDOW_FRAME_LINE_HEIGHT (w
)))
29260 cursor_type
= HOLLOW_BOX_CURSOR
;
29263 else if (cursor_type
!= NO_CURSOR
)
29265 /* Display current only supports BOX and HOLLOW cursors for images.
29266 So for now, unconditionally use a HOLLOW cursor when cursor is
29267 not a solid box cursor. */
29268 cursor_type
= HOLLOW_BOX_CURSOR
;
29271 return cursor_type
;
29274 /* Cursor is blinked off, so determine how to "toggle" it. */
29276 /* First look for an entry matching the buffer's cursor-type in blink-cursor-alist. */
29277 if ((alt_cursor
= Fassoc (BVAR (b
, cursor_type
), Vblink_cursor_alist
, Qnil
), !NILP (alt_cursor
)))
29278 return get_specified_cursor_type (XCDR (alt_cursor
), width
);
29280 /* Then see if frame has specified a specific blink off cursor type. */
29281 if (FRAME_BLINK_OFF_CURSOR (f
) != DEFAULT_CURSOR
)
29283 *width
= FRAME_BLINK_OFF_CURSOR_WIDTH (f
);
29284 return FRAME_BLINK_OFF_CURSOR (f
);
29288 /* Some people liked having a permanently visible blinking cursor,
29289 while others had very strong opinions against it. So it was
29290 decided to remove it. KFS 2003-09-03 */
29292 /* Finally perform built-in cursor blinking:
29293 filled box <-> hollow box
29294 wide [h]bar <-> narrow [h]bar
29295 narrow [h]bar <-> no cursor
29296 other type <-> no cursor */
29298 if (cursor_type
== FILLED_BOX_CURSOR
)
29299 return HOLLOW_BOX_CURSOR
;
29301 if ((cursor_type
== BAR_CURSOR
|| cursor_type
== HBAR_CURSOR
) && *width
> 1)
29304 return cursor_type
;
29312 /* Notice when the text cursor of window W has been completely
29313 overwritten by a drawing operation that outputs glyphs in AREA
29314 starting at X0 and ending at X1 in the line starting at Y0 and
29315 ending at Y1. X coordinates are area-relative. X1 < 0 means all
29316 the rest of the line after X0 has been written. Y coordinates
29317 are window-relative. */
29320 notice_overwritten_cursor (struct window
*w
, enum glyph_row_area area
,
29321 int x0
, int x1
, int y0
, int y1
)
29323 int cx0
, cx1
, cy0
, cy1
;
29324 struct glyph_row
*row
;
29326 if (!w
->phys_cursor_on_p
)
29328 if (area
!= TEXT_AREA
)
29331 if (w
->phys_cursor
.vpos
< 0
29332 || w
->phys_cursor
.vpos
>= w
->current_matrix
->nrows
29333 || (row
= w
->current_matrix
->rows
+ w
->phys_cursor
.vpos
,
29334 !(row
->enabled_p
&& MATRIX_ROW_DISPLAYS_TEXT_P (row
))))
29337 if (row
->cursor_in_fringe_p
)
29339 row
->cursor_in_fringe_p
= false;
29340 draw_fringe_bitmap (w
, row
, row
->reversed_p
);
29341 w
->phys_cursor_on_p
= false;
29345 cx0
= w
->phys_cursor
.x
;
29346 cx1
= cx0
+ w
->phys_cursor_width
;
29347 if (x0
> cx0
|| (x1
>= 0 && x1
< cx1
))
29350 /* The cursor image will be completely removed from the
29351 screen if the output area intersects the cursor area in
29352 y-direction. When we draw in [y0 y1[, and some part of
29353 the cursor is at y < y0, that part must have been drawn
29354 before. When scrolling, the cursor is erased before
29355 actually scrolling, so we don't come here. When not
29356 scrolling, the rows above the old cursor row must have
29357 changed, and in this case these rows must have written
29358 over the cursor image.
29360 Likewise if part of the cursor is below y1, with the
29361 exception of the cursor being in the first blank row at
29362 the buffer and window end because update_text_area
29363 doesn't draw that row. (Except when it does, but
29364 that's handled in update_text_area.) */
29366 cy0
= w
->phys_cursor
.y
;
29367 cy1
= cy0
+ w
->phys_cursor_height
;
29368 if ((y0
< cy0
|| y0
>= cy1
) && (y1
<= cy0
|| y1
>= cy1
))
29371 w
->phys_cursor_on_p
= false;
29374 #endif /* HAVE_WINDOW_SYSTEM */
29377 /************************************************************************
29379 ************************************************************************/
29381 #ifdef HAVE_WINDOW_SYSTEM
29384 Fix the display of area AREA of overlapping row ROW in window W
29385 with respect to the overlapping part OVERLAPS. */
29388 x_fix_overlapping_area (struct window
*w
, struct glyph_row
*row
,
29389 enum glyph_row_area area
, int overlaps
)
29396 for (i
= 0; i
< row
->used
[area
];)
29398 if (row
->glyphs
[area
][i
].overlaps_vertically_p
)
29400 int start
= i
, start_x
= x
;
29404 x
+= row
->glyphs
[area
][i
].pixel_width
;
29407 while (i
< row
->used
[area
]
29408 && row
->glyphs
[area
][i
].overlaps_vertically_p
);
29410 draw_glyphs (w
, start_x
, row
, area
,
29412 DRAW_NORMAL_TEXT
, overlaps
);
29416 x
+= row
->glyphs
[area
][i
].pixel_width
;
29426 Draw the cursor glyph of window W in glyph row ROW. See the
29427 comment of draw_glyphs for the meaning of HL. */
29430 draw_phys_cursor_glyph (struct window
*w
, struct glyph_row
*row
,
29431 enum draw_glyphs_face hl
)
29433 /* If cursor hpos is out of bounds, don't draw garbage. This can
29434 happen in mini-buffer windows when switching between echo area
29435 glyphs and mini-buffer. */
29436 if ((row
->reversed_p
29437 ? (w
->phys_cursor
.hpos
>= 0)
29438 : (w
->phys_cursor
.hpos
< row
->used
[TEXT_AREA
])))
29440 bool on_p
= w
->phys_cursor_on_p
;
29442 int hpos
= w
->phys_cursor
.hpos
;
29444 /* When the window is hscrolled, cursor hpos can legitimately be
29445 out of bounds, but we draw the cursor at the corresponding
29446 window margin in that case. */
29447 if (!row
->reversed_p
&& hpos
< 0)
29449 if (row
->reversed_p
&& hpos
>= row
->used
[TEXT_AREA
])
29450 hpos
= row
->used
[TEXT_AREA
] - 1;
29452 x1
= draw_glyphs (w
, w
->phys_cursor
.x
, row
, TEXT_AREA
, hpos
, hpos
+ 1,
29454 w
->phys_cursor_on_p
= on_p
;
29456 if (hl
== DRAW_CURSOR
)
29457 w
->phys_cursor_width
= x1
- w
->phys_cursor
.x
;
29458 /* When we erase the cursor, and ROW is overlapped by other
29459 rows, make sure that these overlapping parts of other rows
29461 else if (hl
== DRAW_NORMAL_TEXT
&& row
->overlapped_p
)
29463 w
->phys_cursor_width
= x1
- w
->phys_cursor
.x
;
29465 if (row
> w
->current_matrix
->rows
29466 && MATRIX_ROW_OVERLAPS_SUCC_P (row
- 1))
29467 x_fix_overlapping_area (w
, row
- 1, TEXT_AREA
,
29468 OVERLAPS_ERASED_CURSOR
);
29470 if (MATRIX_ROW_BOTTOM_Y (row
) < window_text_bottom_y (w
)
29471 && MATRIX_ROW_OVERLAPS_PRED_P (row
+ 1))
29472 x_fix_overlapping_area (w
, row
+ 1, TEXT_AREA
,
29473 OVERLAPS_ERASED_CURSOR
);
29479 /* Erase the image of a cursor of window W from the screen. */
29482 erase_phys_cursor (struct window
*w
)
29484 struct frame
*f
= XFRAME (w
->frame
);
29485 Mouse_HLInfo
*hlinfo
= MOUSE_HL_INFO (f
);
29486 int hpos
= w
->phys_cursor
.hpos
;
29487 int vpos
= w
->phys_cursor
.vpos
;
29488 bool mouse_face_here_p
= false;
29489 struct glyph_matrix
*active_glyphs
= w
->current_matrix
;
29490 struct glyph_row
*cursor_row
;
29491 struct glyph
*cursor_glyph
;
29492 enum draw_glyphs_face hl
;
29494 /* No cursor displayed or row invalidated => nothing to do on the
29496 if (w
->phys_cursor_type
== NO_CURSOR
)
29497 goto mark_cursor_off
;
29499 /* VPOS >= active_glyphs->nrows means that window has been resized.
29500 Don't bother to erase the cursor. */
29501 if (vpos
>= active_glyphs
->nrows
)
29502 goto mark_cursor_off
;
29504 /* If row containing cursor is marked invalid, there is nothing we
29506 cursor_row
= MATRIX_ROW (active_glyphs
, vpos
);
29507 if (!cursor_row
->enabled_p
)
29508 goto mark_cursor_off
;
29510 /* If line spacing is > 0, old cursor may only be partially visible in
29511 window after split-window. So adjust visible height. */
29512 cursor_row
->visible_height
= min (cursor_row
->visible_height
,
29513 window_text_bottom_y (w
) - cursor_row
->y
);
29515 /* If row is completely invisible, don't attempt to delete a cursor which
29516 isn't there. This can happen if cursor is at top of a window, and
29517 we switch to a buffer with a header line in that window. */
29518 if (cursor_row
->visible_height
<= 0)
29519 goto mark_cursor_off
;
29521 /* If cursor is in the fringe, erase by drawing actual bitmap there. */
29522 if (cursor_row
->cursor_in_fringe_p
)
29524 cursor_row
->cursor_in_fringe_p
= false;
29525 draw_fringe_bitmap (w
, cursor_row
, cursor_row
->reversed_p
);
29526 goto mark_cursor_off
;
29529 /* This can happen when the new row is shorter than the old one.
29530 In this case, either draw_glyphs or clear_end_of_line
29531 should have cleared the cursor. Note that we wouldn't be
29532 able to erase the cursor in this case because we don't have a
29533 cursor glyph at hand. */
29534 if ((cursor_row
->reversed_p
29535 ? (w
->phys_cursor
.hpos
< 0)
29536 : (w
->phys_cursor
.hpos
>= cursor_row
->used
[TEXT_AREA
])))
29537 goto mark_cursor_off
;
29539 /* When the window is hscrolled, cursor hpos can legitimately be out
29540 of bounds, but we draw the cursor at the corresponding window
29541 margin in that case. */
29542 if (!cursor_row
->reversed_p
&& hpos
< 0)
29544 if (cursor_row
->reversed_p
&& hpos
>= cursor_row
->used
[TEXT_AREA
])
29545 hpos
= cursor_row
->used
[TEXT_AREA
] - 1;
29547 /* If the cursor is in the mouse face area, redisplay that when
29548 we clear the cursor. */
29549 if (! NILP (hlinfo
->mouse_face_window
)
29550 && coords_in_mouse_face_p (w
, hpos
, vpos
)
29551 /* Don't redraw the cursor's spot in mouse face if it is at the
29552 end of a line (on a newline). The cursor appears there, but
29553 mouse highlighting does not. */
29554 && cursor_row
->used
[TEXT_AREA
] > hpos
&& hpos
>= 0)
29555 mouse_face_here_p
= true;
29557 /* Maybe clear the display under the cursor. */
29558 if (w
->phys_cursor_type
== HOLLOW_BOX_CURSOR
)
29561 int header_line_height
= WINDOW_HEADER_LINE_HEIGHT (w
);
29564 cursor_glyph
= get_phys_cursor_glyph (w
);
29565 if (cursor_glyph
== NULL
)
29566 goto mark_cursor_off
;
29568 width
= cursor_glyph
->pixel_width
;
29569 x
= w
->phys_cursor
.x
;
29575 width
= min (width
, window_box_width (w
, TEXT_AREA
) - x
);
29576 y
= WINDOW_TO_FRAME_PIXEL_Y (w
, max (header_line_height
, cursor_row
->y
));
29577 x
= WINDOW_TEXT_TO_FRAME_PIXEL_X (w
, x
);
29580 FRAME_RIF (f
)->clear_frame_area (f
, x
, y
, width
, cursor_row
->visible_height
);
29583 /* Erase the cursor by redrawing the character underneath it. */
29584 if (mouse_face_here_p
)
29585 hl
= DRAW_MOUSE_FACE
;
29587 hl
= DRAW_NORMAL_TEXT
;
29588 draw_phys_cursor_glyph (w
, cursor_row
, hl
);
29591 w
->phys_cursor_on_p
= false;
29592 w
->phys_cursor_type
= NO_CURSOR
;
29596 /* Display or clear cursor of window W. If !ON, clear the cursor.
29597 If ON, display the cursor; where to put the cursor is specified by
29598 HPOS, VPOS, X and Y. */
29601 display_and_set_cursor (struct window
*w
, bool on
,
29602 int hpos
, int vpos
, int x
, int y
)
29604 struct frame
*f
= XFRAME (w
->frame
);
29605 int new_cursor_type
;
29606 int new_cursor_width
;
29607 bool active_cursor
;
29608 struct glyph_row
*glyph_row
;
29609 struct glyph
*glyph
;
29611 /* This is pointless on invisible frames, and dangerous on garbaged
29612 windows and frames; in the latter case, the frame or window may
29613 be in the midst of changing its size, and x and y may be off the
29615 if (! FRAME_VISIBLE_P (f
)
29616 || vpos
>= w
->current_matrix
->nrows
29617 || hpos
>= w
->current_matrix
->matrix_w
)
29620 /* If cursor is off and we want it off, return quickly. */
29621 if (!on
&& !w
->phys_cursor_on_p
)
29624 glyph_row
= MATRIX_ROW (w
->current_matrix
, vpos
);
29625 /* If cursor row is not enabled, we don't really know where to
29626 display the cursor. */
29627 if (!glyph_row
->enabled_p
)
29629 w
->phys_cursor_on_p
= false;
29633 /* A frame might be marked garbaged even though its cursor position
29634 is correct, and will not change upon subsequent redisplay. This
29635 happens in some rare situations, like toggling the sort order in
29636 Dired windows. We've already established that VPOS is valid, so
29637 it shouldn't do any harm to record the cursor position, as we are
29638 going to return without acting on it anyway. Otherwise, expose
29639 events might come in and call update_window_cursor, which will
29640 blindly use outdated values in w->phys_cursor. */
29641 if (FRAME_GARBAGED_P (f
))
29645 w
->phys_cursor
.x
= x
;
29646 w
->phys_cursor
.y
= glyph_row
->y
;
29647 w
->phys_cursor
.hpos
= hpos
;
29648 w
->phys_cursor
.vpos
= vpos
;
29654 if (0 <= hpos
&& hpos
< glyph_row
->used
[TEXT_AREA
])
29655 glyph
= glyph_row
->glyphs
[TEXT_AREA
] + hpos
;
29657 eassert (input_blocked_p ());
29659 /* Set new_cursor_type to the cursor we want to be displayed. */
29660 new_cursor_type
= get_window_cursor_type (w
, glyph
,
29661 &new_cursor_width
, &active_cursor
);
29663 /* If cursor is currently being shown and we don't want it to be or
29664 it is in the wrong place, or the cursor type is not what we want,
29666 if (w
->phys_cursor_on_p
29668 || w
->phys_cursor
.x
!= x
29669 || w
->phys_cursor
.y
!= y
29670 /* HPOS can be negative in R2L rows whose
29671 exact_window_width_line_p flag is set (i.e. their newline
29672 would "overflow into the fringe"). */
29674 || new_cursor_type
!= w
->phys_cursor_type
29675 || ((new_cursor_type
== BAR_CURSOR
|| new_cursor_type
== HBAR_CURSOR
)
29676 && new_cursor_width
!= w
->phys_cursor_width
)))
29677 erase_phys_cursor (w
);
29679 /* Don't check phys_cursor_on_p here because that flag is only set
29680 to false in some cases where we know that the cursor has been
29681 completely erased, to avoid the extra work of erasing the cursor
29682 twice. In other words, phys_cursor_on_p can be true and the cursor
29683 still not be visible, or it has only been partly erased. */
29686 w
->phys_cursor_ascent
= glyph_row
->ascent
;
29687 w
->phys_cursor_height
= glyph_row
->height
;
29689 /* Set phys_cursor_.* before x_draw_.* is called because some
29690 of them may need the information. */
29691 w
->phys_cursor
.x
= x
;
29692 w
->phys_cursor
.y
= glyph_row
->y
;
29693 w
->phys_cursor
.hpos
= hpos
;
29694 w
->phys_cursor
.vpos
= vpos
;
29697 FRAME_RIF (f
)->draw_window_cursor (w
, glyph_row
, x
, y
,
29698 new_cursor_type
, new_cursor_width
,
29699 on
, active_cursor
);
29703 /* Switch the display of W's cursor on or off, according to the value
29707 update_window_cursor (struct window
*w
, bool on
)
29709 /* Don't update cursor in windows whose frame is in the process
29710 of being deleted. */
29711 if (w
->current_matrix
)
29713 int hpos
= w
->phys_cursor
.hpos
;
29714 int vpos
= w
->phys_cursor
.vpos
;
29715 struct glyph_row
*row
;
29717 if (vpos
>= w
->current_matrix
->nrows
29718 || hpos
>= w
->current_matrix
->matrix_w
)
29721 row
= MATRIX_ROW (w
->current_matrix
, vpos
);
29723 /* When the window is hscrolled, cursor hpos can legitimately be
29724 out of bounds, but we draw the cursor at the corresponding
29725 window margin in that case. */
29726 if (!row
->reversed_p
&& hpos
< 0)
29728 if (row
->reversed_p
&& hpos
>= row
->used
[TEXT_AREA
])
29729 hpos
= row
->used
[TEXT_AREA
] - 1;
29732 display_and_set_cursor (w
, on
, hpos
, vpos
,
29733 w
->phys_cursor
.x
, w
->phys_cursor
.y
);
29739 /* Call update_window_cursor with parameter ON_P on all leaf windows
29740 in the window tree rooted at W. */
29743 update_cursor_in_window_tree (struct window
*w
, bool on_p
)
29747 if (WINDOWP (w
->contents
))
29748 update_cursor_in_window_tree (XWINDOW (w
->contents
), on_p
);
29750 update_window_cursor (w
, on_p
);
29752 w
= NILP (w
->next
) ? 0 : XWINDOW (w
->next
);
29758 Display the cursor on window W, or clear it, according to ON_P.
29759 Don't change the cursor's position. */
29762 x_update_cursor (struct frame
*f
, bool on_p
)
29764 update_cursor_in_window_tree (XWINDOW (f
->root_window
), on_p
);
29769 Clear the cursor of window W to background color, and mark the
29770 cursor as not shown. This is used when the text where the cursor
29771 is about to be rewritten. */
29774 x_clear_cursor (struct window
*w
)
29776 if (FRAME_VISIBLE_P (XFRAME (w
->frame
)) && w
->phys_cursor_on_p
)
29777 update_window_cursor (w
, false);
29780 #endif /* HAVE_WINDOW_SYSTEM */
29782 /* Implementation of draw_row_with_mouse_face for GUI sessions, GPM,
29785 draw_row_with_mouse_face (struct window
*w
, int start_x
, struct glyph_row
*row
,
29786 int start_hpos
, int end_hpos
,
29787 enum draw_glyphs_face draw
)
29789 #ifdef HAVE_WINDOW_SYSTEM
29790 if (FRAME_WINDOW_P (XFRAME (w
->frame
)))
29792 draw_glyphs (w
, start_x
, row
, TEXT_AREA
, start_hpos
, end_hpos
, draw
, 0);
29796 #if defined (HAVE_GPM) || defined (MSDOS) || defined (WINDOWSNT)
29797 tty_draw_row_with_mouse_face (w
, row
, start_hpos
, end_hpos
, draw
);
29801 /* Display the active region described by mouse_face_* according to DRAW. */
29804 show_mouse_face (Mouse_HLInfo
*hlinfo
, enum draw_glyphs_face draw
)
29806 struct window
*w
= XWINDOW (hlinfo
->mouse_face_window
);
29807 struct frame
*f
= XFRAME (WINDOW_FRAME (w
));
29809 if (/* If window is in the process of being destroyed, don't bother
29811 w
->current_matrix
!= NULL
29812 /* Don't update mouse highlight if hidden. */
29813 && (draw
!= DRAW_MOUSE_FACE
|| !hlinfo
->mouse_face_hidden
)
29814 /* Recognize when we are called to operate on rows that don't exist
29815 anymore. This can happen when a window is split. */
29816 && hlinfo
->mouse_face_end_row
< w
->current_matrix
->nrows
)
29818 bool phys_cursor_on_p
= w
->phys_cursor_on_p
;
29819 struct glyph_row
*row
, *first
, *last
;
29821 first
= MATRIX_ROW (w
->current_matrix
, hlinfo
->mouse_face_beg_row
);
29822 last
= MATRIX_ROW (w
->current_matrix
, hlinfo
->mouse_face_end_row
);
29824 for (row
= first
; row
<= last
&& row
->enabled_p
; ++row
)
29826 int start_hpos
, end_hpos
, start_x
;
29828 /* For all but the first row, the highlight starts at column 0. */
29831 /* R2L rows have BEG and END in reversed order, but the
29832 screen drawing geometry is always left to right. So
29833 we need to mirror the beginning and end of the
29834 highlighted area in R2L rows. */
29835 if (!row
->reversed_p
)
29837 start_hpos
= hlinfo
->mouse_face_beg_col
;
29838 start_x
= hlinfo
->mouse_face_beg_x
;
29840 else if (row
== last
)
29842 start_hpos
= hlinfo
->mouse_face_end_col
;
29843 start_x
= hlinfo
->mouse_face_end_x
;
29851 else if (row
->reversed_p
&& row
== last
)
29853 start_hpos
= hlinfo
->mouse_face_end_col
;
29854 start_x
= hlinfo
->mouse_face_end_x
;
29864 if (!row
->reversed_p
)
29865 end_hpos
= hlinfo
->mouse_face_end_col
;
29866 else if (row
== first
)
29867 end_hpos
= hlinfo
->mouse_face_beg_col
;
29870 end_hpos
= row
->used
[TEXT_AREA
];
29871 if (draw
== DRAW_NORMAL_TEXT
)
29872 row
->fill_line_p
= true; /* Clear to end of line. */
29875 else if (row
->reversed_p
&& row
== first
)
29876 end_hpos
= hlinfo
->mouse_face_beg_col
;
29879 end_hpos
= row
->used
[TEXT_AREA
];
29880 if (draw
== DRAW_NORMAL_TEXT
)
29881 row
->fill_line_p
= true; /* Clear to end of line. */
29884 if (end_hpos
> start_hpos
)
29886 draw_row_with_mouse_face (w
, start_x
, row
,
29887 start_hpos
, end_hpos
, draw
);
29890 = draw
== DRAW_MOUSE_FACE
|| draw
== DRAW_IMAGE_RAISED
;
29894 /* When we've written over the cursor, arrange for it to
29895 be displayed again. */
29896 if (FRAME_WINDOW_P (f
)
29897 && phys_cursor_on_p
&& !w
->phys_cursor_on_p
)
29899 #ifdef HAVE_WINDOW_SYSTEM
29900 int hpos
= w
->phys_cursor
.hpos
;
29902 /* When the window is hscrolled, cursor hpos can legitimately be
29903 out of bounds, but we draw the cursor at the corresponding
29904 window margin in that case. */
29905 if (!row
->reversed_p
&& hpos
< 0)
29907 if (row
->reversed_p
&& hpos
>= row
->used
[TEXT_AREA
])
29908 hpos
= row
->used
[TEXT_AREA
] - 1;
29911 display_and_set_cursor (w
, true, hpos
, w
->phys_cursor
.vpos
,
29912 w
->phys_cursor
.x
, w
->phys_cursor
.y
);
29914 #endif /* HAVE_WINDOW_SYSTEM */
29918 #ifdef HAVE_WINDOW_SYSTEM
29919 /* Change the mouse cursor. */
29920 if (FRAME_WINDOW_P (f
) && NILP (do_mouse_tracking
))
29922 #if ! defined (USE_GTK) && ! defined (HAVE_NS)
29923 if (draw
== DRAW_NORMAL_TEXT
29924 && !EQ (hlinfo
->mouse_face_window
, f
->tool_bar_window
))
29925 FRAME_RIF (f
)->define_frame_cursor (f
, FRAME_X_OUTPUT (f
)->text_cursor
);
29928 if (draw
== DRAW_MOUSE_FACE
)
29929 FRAME_RIF (f
)->define_frame_cursor (f
, FRAME_X_OUTPUT (f
)->hand_cursor
);
29931 FRAME_RIF (f
)->define_frame_cursor (f
, FRAME_X_OUTPUT (f
)->nontext_cursor
);
29933 #endif /* HAVE_WINDOW_SYSTEM */
29937 Clear out the mouse-highlighted active region.
29938 Redraw it un-highlighted first. Value is true if mouse
29939 face was actually drawn unhighlighted. */
29942 clear_mouse_face (Mouse_HLInfo
*hlinfo
)
29945 = !hlinfo
->mouse_face_hidden
&& !NILP (hlinfo
->mouse_face_window
);
29947 show_mouse_face (hlinfo
, DRAW_NORMAL_TEXT
);
29948 hlinfo
->mouse_face_beg_row
= hlinfo
->mouse_face_beg_col
= -1;
29949 hlinfo
->mouse_face_end_row
= hlinfo
->mouse_face_end_col
= -1;
29950 hlinfo
->mouse_face_window
= Qnil
;
29951 hlinfo
->mouse_face_overlay
= Qnil
;
29955 /* Return true if the coordinates HPOS and VPOS on windows W are
29956 within the mouse face on that window. */
29958 coords_in_mouse_face_p (struct window
*w
, int hpos
, int vpos
)
29960 Mouse_HLInfo
*hlinfo
= MOUSE_HL_INFO (XFRAME (w
->frame
));
29962 /* Quickly resolve the easy cases. */
29963 if (!(WINDOWP (hlinfo
->mouse_face_window
)
29964 && XWINDOW (hlinfo
->mouse_face_window
) == w
))
29966 if (vpos
< hlinfo
->mouse_face_beg_row
29967 || vpos
> hlinfo
->mouse_face_end_row
)
29969 if (vpos
> hlinfo
->mouse_face_beg_row
29970 && vpos
< hlinfo
->mouse_face_end_row
)
29973 if (!MATRIX_ROW (w
->current_matrix
, vpos
)->reversed_p
)
29975 if (hlinfo
->mouse_face_beg_row
== hlinfo
->mouse_face_end_row
)
29977 if (hlinfo
->mouse_face_beg_col
<= hpos
&& hpos
< hlinfo
->mouse_face_end_col
)
29980 else if ((vpos
== hlinfo
->mouse_face_beg_row
29981 && hpos
>= hlinfo
->mouse_face_beg_col
)
29982 || (vpos
== hlinfo
->mouse_face_end_row
29983 && hpos
< hlinfo
->mouse_face_end_col
))
29988 if (hlinfo
->mouse_face_beg_row
== hlinfo
->mouse_face_end_row
)
29990 if (hlinfo
->mouse_face_end_col
< hpos
&& hpos
<= hlinfo
->mouse_face_beg_col
)
29993 else if ((vpos
== hlinfo
->mouse_face_beg_row
29994 && hpos
<= hlinfo
->mouse_face_beg_col
)
29995 || (vpos
== hlinfo
->mouse_face_end_row
29996 && hpos
> hlinfo
->mouse_face_end_col
))
30004 True if physical cursor of window W is within mouse face. */
30007 cursor_in_mouse_face_p (struct window
*w
)
30009 int hpos
= w
->phys_cursor
.hpos
;
30010 int vpos
= w
->phys_cursor
.vpos
;
30011 struct glyph_row
*row
= MATRIX_ROW (w
->current_matrix
, vpos
);
30013 /* When the window is hscrolled, cursor hpos can legitimately be out
30014 of bounds, but we draw the cursor at the corresponding window
30015 margin in that case. */
30016 if (!row
->reversed_p
&& hpos
< 0)
30018 if (row
->reversed_p
&& hpos
>= row
->used
[TEXT_AREA
])
30019 hpos
= row
->used
[TEXT_AREA
] - 1;
30021 return coords_in_mouse_face_p (w
, hpos
, vpos
);
30026 /* Find the glyph rows START_ROW and END_ROW of window W that display
30027 characters between buffer positions START_CHARPOS and END_CHARPOS
30028 (excluding END_CHARPOS). DISP_STRING is a display string that
30029 covers these buffer positions. This is similar to
30030 row_containing_pos, but is more accurate when bidi reordering makes
30031 buffer positions change non-linearly with glyph rows. */
30033 rows_from_pos_range (struct window
*w
,
30034 ptrdiff_t start_charpos
, ptrdiff_t end_charpos
,
30035 Lisp_Object disp_string
,
30036 struct glyph_row
**start
, struct glyph_row
**end
)
30038 struct glyph_row
*first
= MATRIX_FIRST_TEXT_ROW (w
->current_matrix
);
30039 int last_y
= window_text_bottom_y (w
);
30040 struct glyph_row
*row
;
30045 while (!first
->enabled_p
30046 && first
< MATRIX_BOTTOM_TEXT_ROW (w
->current_matrix
, w
))
30049 /* Find the START row. */
30051 row
->enabled_p
&& MATRIX_ROW_BOTTOM_Y (row
) <= last_y
;
30054 /* A row can potentially be the START row if the range of the
30055 characters it displays intersects the range
30056 [START_CHARPOS..END_CHARPOS). */
30057 if (! ((start_charpos
< MATRIX_ROW_START_CHARPOS (row
)
30058 && end_charpos
< MATRIX_ROW_START_CHARPOS (row
))
30059 /* See the commentary in row_containing_pos, for the
30060 explanation of the complicated way to check whether
30061 some position is beyond the end of the characters
30062 displayed by a row. */
30063 || ((start_charpos
> MATRIX_ROW_END_CHARPOS (row
)
30064 || (start_charpos
== MATRIX_ROW_END_CHARPOS (row
)
30065 && !row
->ends_at_zv_p
30066 && !MATRIX_ROW_ENDS_IN_MIDDLE_OF_CHAR_P (row
)))
30067 && (end_charpos
> MATRIX_ROW_END_CHARPOS (row
)
30068 || (end_charpos
== MATRIX_ROW_END_CHARPOS (row
)
30069 && !row
->ends_at_zv_p
30070 && !MATRIX_ROW_ENDS_IN_MIDDLE_OF_CHAR_P (row
))))))
30072 /* Found a candidate row. Now make sure at least one of the
30073 glyphs it displays has a charpos from the range
30074 [START_CHARPOS..END_CHARPOS).
30076 This is not obvious because bidi reordering could make
30077 buffer positions of a row be 1,2,3,102,101,100, and if we
30078 want to highlight characters in [50..60), we don't want
30079 this row, even though [50..60) does intersect [1..103),
30080 the range of character positions given by the row's start
30081 and end positions. */
30082 struct glyph
*g
= row
->glyphs
[TEXT_AREA
];
30083 struct glyph
*e
= g
+ row
->used
[TEXT_AREA
];
30087 if (((BUFFERP (g
->object
) || NILP (g
->object
))
30088 && start_charpos
<= g
->charpos
&& g
->charpos
< end_charpos
)
30089 /* A glyph that comes from DISP_STRING is by
30090 definition to be highlighted. */
30091 || EQ (g
->object
, disp_string
))
30100 /* Find the END row. */
30102 /* If the last row is partially visible, start looking for END
30103 from that row, instead of starting from FIRST. */
30104 && !(row
->enabled_p
30105 && row
->y
< last_y
&& MATRIX_ROW_BOTTOM_Y (row
) > last_y
))
30107 for ( ; row
->enabled_p
&& MATRIX_ROW_BOTTOM_Y (row
) <= last_y
; row
++)
30109 struct glyph_row
*next
= row
+ 1;
30110 ptrdiff_t next_start
= MATRIX_ROW_START_CHARPOS (next
);
30112 if (!next
->enabled_p
30113 || next
>= MATRIX_BOTTOM_TEXT_ROW (w
->current_matrix
, w
)
30114 /* The first row >= START whose range of displayed characters
30115 does NOT intersect the range [START_CHARPOS..END_CHARPOS]
30116 is the row END + 1. */
30117 || (start_charpos
< next_start
30118 && end_charpos
< next_start
)
30119 || ((start_charpos
> MATRIX_ROW_END_CHARPOS (next
)
30120 || (start_charpos
== MATRIX_ROW_END_CHARPOS (next
)
30121 && !next
->ends_at_zv_p
30122 && !MATRIX_ROW_ENDS_IN_MIDDLE_OF_CHAR_P (next
)))
30123 && (end_charpos
> MATRIX_ROW_END_CHARPOS (next
)
30124 || (end_charpos
== MATRIX_ROW_END_CHARPOS (next
)
30125 && !next
->ends_at_zv_p
30126 && !MATRIX_ROW_ENDS_IN_MIDDLE_OF_CHAR_P (next
)))))
30133 /* If the next row's edges intersect [START_CHARPOS..END_CHARPOS],
30134 but none of the characters it displays are in the range, it is
30136 struct glyph
*g
= next
->glyphs
[TEXT_AREA
];
30137 struct glyph
*s
= g
;
30138 struct glyph
*e
= g
+ next
->used
[TEXT_AREA
];
30142 if (((BUFFERP (g
->object
) || NILP (g
->object
))
30143 && ((start_charpos
<= g
->charpos
&& g
->charpos
< end_charpos
)
30144 /* If the buffer position of the first glyph in
30145 the row is equal to END_CHARPOS, it means
30146 the last character to be highlighted is the
30147 newline of ROW, and we must consider NEXT as
30149 || (((!next
->reversed_p
&& g
== s
)
30150 || (next
->reversed_p
&& g
== e
- 1))
30151 && (g
->charpos
== end_charpos
30152 /* Special case for when NEXT is an
30153 empty line at ZV. */
30154 || (g
->charpos
== -1
30155 && !row
->ends_at_zv_p
30156 && next_start
== end_charpos
)))))
30157 /* A glyph that comes from DISP_STRING is by
30158 definition to be highlighted. */
30159 || EQ (g
->object
, disp_string
))
30168 /* The first row that ends at ZV must be the last to be
30170 else if (next
->ends_at_zv_p
)
30179 /* This function sets the mouse_face_* elements of HLINFO, assuming
30180 the mouse cursor is on a glyph with buffer charpos MOUSE_CHARPOS in
30181 window WINDOW. START_CHARPOS and END_CHARPOS are buffer positions
30182 for the overlay or run of text properties specifying the mouse
30183 face. BEFORE_STRING and AFTER_STRING, if non-nil, are a
30184 before-string and after-string that must also be highlighted.
30185 DISP_STRING, if non-nil, is a display string that may cover some
30186 or all of the highlighted text. */
30189 mouse_face_from_buffer_pos (Lisp_Object window
,
30190 Mouse_HLInfo
*hlinfo
,
30191 ptrdiff_t mouse_charpos
,
30192 ptrdiff_t start_charpos
,
30193 ptrdiff_t end_charpos
,
30194 Lisp_Object before_string
,
30195 Lisp_Object after_string
,
30196 Lisp_Object disp_string
)
30198 struct window
*w
= XWINDOW (window
);
30199 struct glyph_row
*first
= MATRIX_FIRST_TEXT_ROW (w
->current_matrix
);
30200 struct glyph_row
*r1
, *r2
;
30201 struct glyph
*glyph
, *end
;
30202 ptrdiff_t ignore
, pos
;
30205 eassert (NILP (disp_string
) || STRINGP (disp_string
));
30206 eassert (NILP (before_string
) || STRINGP (before_string
));
30207 eassert (NILP (after_string
) || STRINGP (after_string
));
30209 /* Find the rows corresponding to START_CHARPOS and END_CHARPOS. */
30210 rows_from_pos_range (w
, start_charpos
, end_charpos
, disp_string
, &r1
, &r2
);
30212 r1
= MATRIX_ROW (w
->current_matrix
, w
->window_end_vpos
);
30213 /* If the before-string or display-string contains newlines,
30214 rows_from_pos_range skips to its last row. Move back. */
30215 if (!NILP (before_string
) || !NILP (disp_string
))
30217 struct glyph_row
*prev
;
30218 while ((prev
= r1
- 1, prev
>= first
)
30219 && MATRIX_ROW_END_CHARPOS (prev
) == start_charpos
30220 && prev
->used
[TEXT_AREA
] > 0)
30222 struct glyph
*beg
= prev
->glyphs
[TEXT_AREA
];
30223 glyph
= beg
+ prev
->used
[TEXT_AREA
];
30224 while (--glyph
>= beg
&& NILP (glyph
->object
));
30226 || !(EQ (glyph
->object
, before_string
)
30227 || EQ (glyph
->object
, disp_string
)))
30234 r2
= MATRIX_ROW (w
->current_matrix
, w
->window_end_vpos
);
30235 hlinfo
->mouse_face_past_end
= true;
30237 else if (!NILP (after_string
))
30239 /* If the after-string has newlines, advance to its last row. */
30240 struct glyph_row
*next
;
30241 struct glyph_row
*last
30242 = MATRIX_ROW (w
->current_matrix
, w
->window_end_vpos
);
30244 for (next
= r2
+ 1;
30246 && next
->used
[TEXT_AREA
] > 0
30247 && EQ (next
->glyphs
[TEXT_AREA
]->object
, after_string
);
30251 /* The rest of the display engine assumes that mouse_face_beg_row is
30252 either above mouse_face_end_row or identical to it. But with
30253 bidi-reordered continued lines, the row for START_CHARPOS could
30254 be below the row for END_CHARPOS. If so, swap the rows and store
30255 them in correct order. */
30258 struct glyph_row
*tem
= r2
;
30264 hlinfo
->mouse_face_beg_row
= MATRIX_ROW_VPOS (r1
, w
->current_matrix
);
30265 hlinfo
->mouse_face_end_row
= MATRIX_ROW_VPOS (r2
, w
->current_matrix
);
30267 /* For a bidi-reordered row, the positions of BEFORE_STRING,
30268 AFTER_STRING, DISP_STRING, START_CHARPOS, and END_CHARPOS
30269 could be anywhere in the row and in any order. The strategy
30270 below is to find the leftmost and the rightmost glyph that
30271 belongs to either of these 3 strings, or whose position is
30272 between START_CHARPOS and END_CHARPOS, and highlight all the
30273 glyphs between those two. This may cover more than just the text
30274 between START_CHARPOS and END_CHARPOS if the range of characters
30275 strides the bidi level boundary, e.g. if the beginning is in R2L
30276 text while the end is in L2R text or vice versa. */
30277 if (!r1
->reversed_p
)
30279 /* This row is in a left to right paragraph. Scan it left to
30281 glyph
= r1
->glyphs
[TEXT_AREA
];
30282 end
= glyph
+ r1
->used
[TEXT_AREA
];
30285 /* Skip truncation glyphs at the start of the glyph row. */
30286 if (MATRIX_ROW_DISPLAYS_TEXT_P (r1
))
30288 && NILP (glyph
->object
)
30289 && glyph
->charpos
< 0;
30291 x
+= glyph
->pixel_width
;
30293 /* Scan the glyph row, looking for BEFORE_STRING, AFTER_STRING,
30294 or DISP_STRING, and the first glyph from buffer whose
30295 position is between START_CHARPOS and END_CHARPOS. */
30297 && !NILP (glyph
->object
)
30298 && !EQ (glyph
->object
, disp_string
)
30299 && !(BUFFERP (glyph
->object
)
30300 && (glyph
->charpos
>= start_charpos
30301 && glyph
->charpos
< end_charpos
));
30304 /* BEFORE_STRING or AFTER_STRING are only relevant if they
30305 are present at buffer positions between START_CHARPOS and
30306 END_CHARPOS, or if they come from an overlay. */
30307 if (EQ (glyph
->object
, before_string
))
30309 pos
= string_buffer_position (before_string
,
30311 /* If pos == 0, it means before_string came from an
30312 overlay, not from a buffer position. */
30313 if (!pos
|| (pos
>= start_charpos
&& pos
< end_charpos
))
30316 else if (EQ (glyph
->object
, after_string
))
30318 pos
= string_buffer_position (after_string
, end_charpos
);
30319 if (!pos
|| (pos
>= start_charpos
&& pos
< end_charpos
))
30322 x
+= glyph
->pixel_width
;
30324 hlinfo
->mouse_face_beg_x
= x
;
30325 hlinfo
->mouse_face_beg_col
= glyph
- r1
->glyphs
[TEXT_AREA
];
30329 /* This row is in a right to left paragraph. Scan it right to
30333 end
= r1
->glyphs
[TEXT_AREA
] - 1;
30334 glyph
= end
+ r1
->used
[TEXT_AREA
];
30336 /* Skip truncation glyphs at the start of the glyph row. */
30337 if (MATRIX_ROW_DISPLAYS_TEXT_P (r1
))
30339 && NILP (glyph
->object
)
30340 && glyph
->charpos
< 0;
30344 /* Scan the glyph row, looking for BEFORE_STRING, AFTER_STRING,
30345 or DISP_STRING, and the first glyph from buffer whose
30346 position is between START_CHARPOS and END_CHARPOS. */
30348 && !NILP (glyph
->object
)
30349 && !EQ (glyph
->object
, disp_string
)
30350 && !(BUFFERP (glyph
->object
)
30351 && (glyph
->charpos
>= start_charpos
30352 && glyph
->charpos
< end_charpos
));
30355 /* BEFORE_STRING or AFTER_STRING are only relevant if they
30356 are present at buffer positions between START_CHARPOS and
30357 END_CHARPOS, or if they come from an overlay. */
30358 if (EQ (glyph
->object
, before_string
))
30360 pos
= string_buffer_position (before_string
, start_charpos
);
30361 /* If pos == 0, it means before_string came from an
30362 overlay, not from a buffer position. */
30363 if (!pos
|| (pos
>= start_charpos
&& pos
< end_charpos
))
30366 else if (EQ (glyph
->object
, after_string
))
30368 pos
= string_buffer_position (after_string
, end_charpos
);
30369 if (!pos
|| (pos
>= start_charpos
&& pos
< end_charpos
))
30374 glyph
++; /* first glyph to the right of the highlighted area */
30375 for (g
= r1
->glyphs
[TEXT_AREA
], x
= r1
->x
; g
< glyph
; g
++)
30376 x
+= g
->pixel_width
;
30377 hlinfo
->mouse_face_beg_x
= x
;
30378 hlinfo
->mouse_face_beg_col
= glyph
- r1
->glyphs
[TEXT_AREA
];
30381 /* If the highlight ends in a different row, compute GLYPH and END
30382 for the end row. Otherwise, reuse the values computed above for
30383 the row where the highlight begins. */
30386 if (!r2
->reversed_p
)
30388 glyph
= r2
->glyphs
[TEXT_AREA
];
30389 end
= glyph
+ r2
->used
[TEXT_AREA
];
30394 end
= r2
->glyphs
[TEXT_AREA
] - 1;
30395 glyph
= end
+ r2
->used
[TEXT_AREA
];
30399 if (!r2
->reversed_p
)
30401 /* Skip truncation and continuation glyphs near the end of the
30402 row, and also blanks and stretch glyphs inserted by
30403 extend_face_to_end_of_line. */
30405 && NILP ((end
- 1)->object
))
30407 /* Scan the rest of the glyph row from the end, looking for the
30408 first glyph that comes from BEFORE_STRING, AFTER_STRING, or
30409 DISP_STRING, or whose position is between START_CHARPOS
30413 && !NILP (end
->object
)
30414 && !EQ (end
->object
, disp_string
)
30415 && !(BUFFERP (end
->object
)
30416 && (end
->charpos
>= start_charpos
30417 && end
->charpos
< end_charpos
));
30420 /* BEFORE_STRING or AFTER_STRING are only relevant if they
30421 are present at buffer positions between START_CHARPOS and
30422 END_CHARPOS, or if they come from an overlay. */
30423 if (EQ (end
->object
, before_string
))
30425 pos
= string_buffer_position (before_string
, start_charpos
);
30426 if (!pos
|| (pos
>= start_charpos
&& pos
< end_charpos
))
30429 else if (EQ (end
->object
, after_string
))
30431 pos
= string_buffer_position (after_string
, end_charpos
);
30432 if (!pos
|| (pos
>= start_charpos
&& pos
< end_charpos
))
30436 /* Find the X coordinate of the last glyph to be highlighted. */
30437 for (; glyph
<= end
; ++glyph
)
30438 x
+= glyph
->pixel_width
;
30440 hlinfo
->mouse_face_end_x
= x
;
30441 hlinfo
->mouse_face_end_col
= glyph
- r2
->glyphs
[TEXT_AREA
];
30445 /* Skip truncation and continuation glyphs near the end of the
30446 row, and also blanks and stretch glyphs inserted by
30447 extend_face_to_end_of_line. */
30451 && NILP (end
->object
))
30453 x
+= end
->pixel_width
;
30456 /* Scan the rest of the glyph row from the end, looking for the
30457 first glyph that comes from BEFORE_STRING, AFTER_STRING, or
30458 DISP_STRING, or whose position is between START_CHARPOS
30462 && !NILP (end
->object
)
30463 && !EQ (end
->object
, disp_string
)
30464 && !(BUFFERP (end
->object
)
30465 && (end
->charpos
>= start_charpos
30466 && end
->charpos
< end_charpos
));
30469 /* BEFORE_STRING or AFTER_STRING are only relevant if they
30470 are present at buffer positions between START_CHARPOS and
30471 END_CHARPOS, or if they come from an overlay. */
30472 if (EQ (end
->object
, before_string
))
30474 pos
= string_buffer_position (before_string
, start_charpos
);
30475 if (!pos
|| (pos
>= start_charpos
&& pos
< end_charpos
))
30478 else if (EQ (end
->object
, after_string
))
30480 pos
= string_buffer_position (after_string
, end_charpos
);
30481 if (!pos
|| (pos
>= start_charpos
&& pos
< end_charpos
))
30484 x
+= end
->pixel_width
;
30486 /* If we exited the above loop because we arrived at the last
30487 glyph of the row, and its buffer position is still not in
30488 range, it means the last character in range is the preceding
30489 newline. Bump the end column and x values to get past the
30492 && BUFFERP (end
->object
)
30493 && (end
->charpos
< start_charpos
30494 || end
->charpos
>= end_charpos
))
30496 x
+= end
->pixel_width
;
30499 hlinfo
->mouse_face_end_x
= x
;
30500 hlinfo
->mouse_face_end_col
= end
- r2
->glyphs
[TEXT_AREA
];
30503 hlinfo
->mouse_face_window
= window
;
30504 hlinfo
->mouse_face_face_id
30505 = face_at_buffer_position (w
, mouse_charpos
, &ignore
,
30507 !hlinfo
->mouse_face_hidden
, -1);
30508 show_mouse_face (hlinfo
, DRAW_MOUSE_FACE
);
30511 /* The following function is not used anymore (replaced with
30512 mouse_face_from_string_pos), but I leave it here for the time
30513 being, in case someone would. */
30515 #if false /* not used */
30517 /* Find the position of the glyph for position POS in OBJECT in
30518 window W's current matrix, and return in *X, *Y the pixel
30519 coordinates, and return in *HPOS, *VPOS the column/row of the glyph.
30521 RIGHT_P means return the position of the right edge of the glyph.
30522 !RIGHT_P means return the left edge position.
30524 If no glyph for POS exists in the matrix, return the position of
30525 the glyph with the next smaller position that is in the matrix, if
30526 RIGHT_P is false. If RIGHT_P, and no glyph for POS
30527 exists in the matrix, return the position of the glyph with the
30528 next larger position in OBJECT.
30530 Value is true if a glyph was found. */
30533 fast_find_string_pos (struct window
*w
, ptrdiff_t pos
, Lisp_Object object
,
30534 int *hpos
, int *vpos
, int *x
, int *y
, bool right_p
)
30536 int yb
= window_text_bottom_y (w
);
30537 struct glyph_row
*r
;
30538 struct glyph
*best_glyph
= NULL
;
30539 struct glyph_row
*best_row
= NULL
;
30542 for (r
= MATRIX_FIRST_TEXT_ROW (w
->current_matrix
);
30543 r
->enabled_p
&& r
->y
< yb
;
30546 struct glyph
*g
= r
->glyphs
[TEXT_AREA
];
30547 struct glyph
*e
= g
+ r
->used
[TEXT_AREA
];
30550 for (gx
= r
->x
; g
< e
; gx
+= g
->pixel_width
, ++g
)
30551 if (EQ (g
->object
, object
))
30553 if (g
->charpos
== pos
)
30560 else if (best_glyph
== NULL
30561 || ((eabs (g
->charpos
- pos
)
30562 < eabs (best_glyph
->charpos
- pos
))
30565 : g
->charpos
> pos
)))
30579 *hpos
= best_glyph
- best_row
->glyphs
[TEXT_AREA
];
30583 *x
+= best_glyph
->pixel_width
;
30588 *vpos
= MATRIX_ROW_VPOS (best_row
, w
->current_matrix
);
30591 return best_glyph
!= NULL
;
30593 #endif /* not used */
30595 /* Find the positions of the first and the last glyphs in window W's
30596 current matrix that occlude positions [STARTPOS..ENDPOS) in OBJECT
30597 (assumed to be a string), and return in HLINFO's mouse_face_*
30598 members the pixel and column/row coordinates of those glyphs. */
30601 mouse_face_from_string_pos (struct window
*w
, Mouse_HLInfo
*hlinfo
,
30602 Lisp_Object object
,
30603 ptrdiff_t startpos
, ptrdiff_t endpos
)
30605 int yb
= window_text_bottom_y (w
);
30606 struct glyph_row
*r
;
30607 struct glyph
*g
, *e
;
30609 bool found
= false;
30611 /* Find the glyph row with at least one position in the range
30612 [STARTPOS..ENDPOS), and the first glyph in that row whose
30613 position belongs to that range. */
30614 for (r
= MATRIX_FIRST_TEXT_ROW (w
->current_matrix
);
30615 r
->enabled_p
&& r
->y
< yb
;
30618 if (!r
->reversed_p
)
30620 g
= r
->glyphs
[TEXT_AREA
];
30621 e
= g
+ r
->used
[TEXT_AREA
];
30622 for (gx
= r
->x
; g
< e
; gx
+= g
->pixel_width
, ++g
)
30623 if (EQ (g
->object
, object
)
30624 && startpos
<= g
->charpos
&& g
->charpos
< endpos
)
30626 hlinfo
->mouse_face_beg_row
30627 = MATRIX_ROW_VPOS (r
, w
->current_matrix
);
30628 hlinfo
->mouse_face_beg_col
= g
- r
->glyphs
[TEXT_AREA
];
30629 hlinfo
->mouse_face_beg_x
= gx
;
30638 e
= r
->glyphs
[TEXT_AREA
];
30639 g
= e
+ r
->used
[TEXT_AREA
];
30640 for ( ; g
> e
; --g
)
30641 if (EQ ((g
-1)->object
, object
)
30642 && startpos
<= (g
-1)->charpos
&& (g
-1)->charpos
< endpos
)
30644 hlinfo
->mouse_face_beg_row
30645 = MATRIX_ROW_VPOS (r
, w
->current_matrix
);
30646 hlinfo
->mouse_face_beg_col
= g
- r
->glyphs
[TEXT_AREA
];
30647 for (gx
= r
->x
, g1
= r
->glyphs
[TEXT_AREA
]; g1
< g
; ++g1
)
30648 gx
+= g1
->pixel_width
;
30649 hlinfo
->mouse_face_beg_x
= gx
;
30661 /* Starting with the next row, look for the first row which does NOT
30662 include any glyphs whose positions are in the range. */
30663 for (++r
; r
->enabled_p
&& r
->y
< yb
; ++r
)
30665 g
= r
->glyphs
[TEXT_AREA
];
30666 e
= g
+ r
->used
[TEXT_AREA
];
30668 for ( ; g
< e
; ++g
)
30669 if (EQ (g
->object
, object
)
30670 && startpos
<= g
->charpos
&& g
->charpos
< endpos
)
30679 /* The highlighted region ends on the previous row. */
30682 /* Set the end row. */
30683 hlinfo
->mouse_face_end_row
= MATRIX_ROW_VPOS (r
, w
->current_matrix
);
30685 /* Compute and set the end column and the end column's horizontal
30686 pixel coordinate. */
30687 if (!r
->reversed_p
)
30689 g
= r
->glyphs
[TEXT_AREA
];
30690 e
= g
+ r
->used
[TEXT_AREA
];
30691 for ( ; e
> g
; --e
)
30692 if (EQ ((e
-1)->object
, object
)
30693 && startpos
<= (e
-1)->charpos
&& (e
-1)->charpos
< endpos
)
30695 hlinfo
->mouse_face_end_col
= e
- g
;
30697 for (gx
= r
->x
; g
< e
; ++g
)
30698 gx
+= g
->pixel_width
;
30699 hlinfo
->mouse_face_end_x
= gx
;
30703 e
= r
->glyphs
[TEXT_AREA
];
30704 g
= e
+ r
->used
[TEXT_AREA
];
30705 for (gx
= r
->x
; e
< g
; ++e
)
30707 if (EQ (e
->object
, object
)
30708 && startpos
<= e
->charpos
&& e
->charpos
< endpos
)
30710 gx
+= e
->pixel_width
;
30712 hlinfo
->mouse_face_end_col
= e
- r
->glyphs
[TEXT_AREA
];
30713 hlinfo
->mouse_face_end_x
= gx
;
30717 #ifdef HAVE_WINDOW_SYSTEM
30719 /* See if position X, Y is within a hot-spot of an image. */
30722 on_hot_spot_p (Lisp_Object hot_spot
, int x
, int y
)
30724 if (!CONSP (hot_spot
))
30727 if (EQ (XCAR (hot_spot
), Qrect
))
30729 /* CDR is (Top-Left . Bottom-Right) = ((x0 . y0) . (x1 . y1)) */
30730 Lisp_Object rect
= XCDR (hot_spot
);
30734 if (!CONSP (XCAR (rect
)))
30736 if (!CONSP (XCDR (rect
)))
30738 if (!(tem
= XCAR (XCAR (rect
)), INTEGERP (tem
) && x
>= XINT (tem
)))
30740 if (!(tem
= XCDR (XCAR (rect
)), INTEGERP (tem
) && y
>= XINT (tem
)))
30742 if (!(tem
= XCAR (XCDR (rect
)), INTEGERP (tem
) && x
<= XINT (tem
)))
30744 if (!(tem
= XCDR (XCDR (rect
)), INTEGERP (tem
) && y
<= XINT (tem
)))
30748 else if (EQ (XCAR (hot_spot
), Qcircle
))
30750 /* CDR is (Center . Radius) = ((x0 . y0) . r) */
30751 Lisp_Object circ
= XCDR (hot_spot
);
30752 Lisp_Object lr
, lx0
, ly0
;
30754 && CONSP (XCAR (circ
))
30755 && (lr
= XCDR (circ
), NUMBERP (lr
))
30756 && (lx0
= XCAR (XCAR (circ
)), INTEGERP (lx0
))
30757 && (ly0
= XCDR (XCAR (circ
)), INTEGERP (ly0
)))
30759 double r
= XFLOATINT (lr
);
30760 double dx
= XINT (lx0
) - x
;
30761 double dy
= XINT (ly0
) - y
;
30762 return (dx
* dx
+ dy
* dy
<= r
* r
);
30765 else if (EQ (XCAR (hot_spot
), Qpoly
))
30767 /* CDR is [x0 y0 x1 y1 x2 y2 ...x(n-1) y(n-1)] */
30768 if (VECTORP (XCDR (hot_spot
)))
30770 struct Lisp_Vector
*v
= XVECTOR (XCDR (hot_spot
));
30771 Lisp_Object
*poly
= v
->contents
;
30772 ptrdiff_t n
= v
->header
.size
;
30774 bool inside
= false;
30775 Lisp_Object lx
, ly
;
30778 /* Need an even number of coordinates, and at least 3 edges. */
30779 if (n
< 6 || n
& 1)
30782 /* Count edge segments intersecting line from (X,Y) to (X,infinity).
30783 If count is odd, we are inside polygon. Pixels on edges
30784 may or may not be included depending on actual geometry of the
30786 if ((lx
= poly
[n
-2], !INTEGERP (lx
))
30787 || (ly
= poly
[n
-1], !INTEGERP (lx
)))
30789 x0
= XINT (lx
), y0
= XINT (ly
);
30790 for (i
= 0; i
< n
; i
+= 2)
30792 int x1
= x0
, y1
= y0
;
30793 if ((lx
= poly
[i
], !INTEGERP (lx
))
30794 || (ly
= poly
[i
+1], !INTEGERP (ly
)))
30796 x0
= XINT (lx
), y0
= XINT (ly
);
30798 /* Does this segment cross the X line? */
30806 if (y
> y0
&& y
> y1
)
30808 if (y
< y0
+ ((y1
- y0
) * (x
- x0
)) / (x1
- x0
))
30818 find_hot_spot (Lisp_Object map
, int x
, int y
)
30820 while (CONSP (map
))
30822 if (CONSP (XCAR (map
))
30823 && on_hot_spot_p (XCAR (XCAR (map
)), x
, y
))
30831 DEFUN ("lookup-image-map", Flookup_image_map
, Slookup_image_map
,
30833 doc
: /* Lookup in image map MAP coordinates X and Y.
30834 An image map is an alist where each element has the format (AREA ID PLIST).
30835 An AREA is specified as either a rectangle, a circle, or a polygon:
30836 A rectangle is a cons (rect . ((x0 . y0) . (x1 . y1))) specifying the
30837 pixel coordinates of the upper left and bottom right corners.
30838 A circle is a cons (circle . ((x0 . y0) . r)) specifying the center
30839 and the radius of the circle; r may be a float or integer.
30840 A polygon is a cons (poly . [x0 y0 x1 y1 ...]) where each pair in the
30841 vector describes one corner in the polygon.
30842 Returns the alist element for the first matching AREA in MAP. */)
30843 (Lisp_Object map
, Lisp_Object x
, Lisp_Object y
)
30851 return find_hot_spot (map
,
30852 clip_to_bounds (INT_MIN
, XINT (x
), INT_MAX
),
30853 clip_to_bounds (INT_MIN
, XINT (y
), INT_MAX
));
30855 #endif /* HAVE_WINDOW_SYSTEM */
30858 /* Display frame CURSOR, optionally using shape defined by POINTER. */
30860 define_frame_cursor1 (struct frame
*f
, Cursor cursor
, Lisp_Object pointer
)
30862 #ifdef HAVE_WINDOW_SYSTEM
30863 if (!FRAME_WINDOW_P (f
))
30866 /* Do not change cursor shape while dragging mouse. */
30867 if (EQ (do_mouse_tracking
, Qdragging
))
30870 if (!NILP (pointer
))
30872 if (EQ (pointer
, Qarrow
))
30873 cursor
= FRAME_X_OUTPUT (f
)->nontext_cursor
;
30874 else if (EQ (pointer
, Qhand
))
30875 cursor
= FRAME_X_OUTPUT (f
)->hand_cursor
;
30876 else if (EQ (pointer
, Qtext
))
30877 cursor
= FRAME_X_OUTPUT (f
)->text_cursor
;
30878 else if (EQ (pointer
, intern ("hdrag")))
30879 cursor
= FRAME_X_OUTPUT (f
)->horizontal_drag_cursor
;
30880 else if (EQ (pointer
, intern ("nhdrag")))
30881 cursor
= FRAME_X_OUTPUT (f
)->vertical_drag_cursor
;
30882 # ifdef HAVE_X_WINDOWS
30883 else if (EQ (pointer
, intern ("vdrag")))
30884 cursor
= FRAME_DISPLAY_INFO (f
)->vertical_scroll_bar_cursor
;
30886 else if (EQ (pointer
, intern ("hourglass")))
30887 cursor
= FRAME_X_OUTPUT (f
)->hourglass_cursor
;
30888 else if (EQ (pointer
, Qmodeline
))
30889 cursor
= FRAME_X_OUTPUT (f
)->modeline_cursor
;
30891 cursor
= FRAME_X_OUTPUT (f
)->nontext_cursor
;
30894 if (cursor
!= No_Cursor
)
30895 FRAME_RIF (f
)->define_frame_cursor (f
, cursor
);
30899 /* Take proper action when mouse has moved to the mode or header line
30900 or marginal area AREA of window W, x-position X and y-position Y.
30901 X is relative to the start of the text display area of W, so the
30902 width of bitmap areas and scroll bars must be subtracted to get a
30903 position relative to the start of the mode line. */
30906 note_mode_line_or_margin_highlight (Lisp_Object window
, int x
, int y
,
30907 enum window_part area
)
30909 struct window
*w
= XWINDOW (window
);
30910 struct frame
*f
= XFRAME (w
->frame
);
30911 Mouse_HLInfo
*hlinfo
= MOUSE_HL_INFO (f
);
30912 Cursor cursor
= No_Cursor
;
30913 Lisp_Object pointer
= Qnil
;
30914 int dx
, dy
, width
, height
;
30916 Lisp_Object string
, object
= Qnil
;
30917 Lisp_Object pos UNINIT
;
30918 Lisp_Object mouse_face
;
30919 int original_x_pixel
= x
;
30920 struct glyph
* glyph
= NULL
, * row_start_glyph
= NULL
;
30921 struct glyph_row
*row UNINIT
;
30923 if (area
== ON_MODE_LINE
|| area
== ON_HEADER_LINE
)
30928 /* Kludge alert: mode_line_string takes X/Y in pixels, but
30929 returns them in row/column units! */
30930 string
= mode_line_string (w
, area
, &x
, &y
, &charpos
,
30931 &object
, &dx
, &dy
, &width
, &height
);
30933 row
= (area
== ON_MODE_LINE
30934 ? MATRIX_MODE_LINE_ROW (w
->current_matrix
)
30935 : MATRIX_HEADER_LINE_ROW (w
->current_matrix
));
30937 /* Find the glyph under the mouse pointer. */
30938 if (row
->mode_line_p
&& row
->enabled_p
)
30940 glyph
= row_start_glyph
= row
->glyphs
[TEXT_AREA
];
30941 end
= glyph
+ row
->used
[TEXT_AREA
];
30943 for (x0
= original_x_pixel
;
30944 glyph
< end
&& x0
>= glyph
->pixel_width
;
30946 x0
-= glyph
->pixel_width
;
30954 x
-= WINDOW_LEFT_SCROLL_BAR_AREA_WIDTH (w
);
30955 /* Kludge alert: marginal_area_string takes X/Y in pixels, but
30956 returns them in row/column units! */
30957 string
= marginal_area_string (w
, area
, &x
, &y
, &charpos
,
30958 &object
, &dx
, &dy
, &width
, &height
);
30961 Lisp_Object help
= Qnil
;
30963 #ifdef HAVE_WINDOW_SYSTEM
30964 if (IMAGEP (object
))
30966 Lisp_Object image_map
, hotspot
;
30967 if ((image_map
= Fplist_get (XCDR (object
), QCmap
),
30969 && (hotspot
= find_hot_spot (image_map
, dx
, dy
),
30971 && (hotspot
= XCDR (hotspot
), CONSP (hotspot
)))
30975 /* Could check XCAR (hotspot) to see if we enter/leave this hot-spot.
30976 If so, we could look for mouse-enter, mouse-leave
30977 properties in PLIST (and do something...). */
30978 hotspot
= XCDR (hotspot
);
30979 if (CONSP (hotspot
)
30980 && (plist
= XCAR (hotspot
), CONSP (plist
)))
30982 pointer
= Fplist_get (plist
, Qpointer
);
30983 if (NILP (pointer
))
30985 help
= Fplist_get (plist
, Qhelp_echo
);
30988 help_echo_string
= help
;
30989 XSETWINDOW (help_echo_window
, w
);
30990 help_echo_object
= w
->contents
;
30991 help_echo_pos
= charpos
;
30995 if (NILP (pointer
))
30996 pointer
= Fplist_get (XCDR (object
), QCpointer
);
30998 #endif /* HAVE_WINDOW_SYSTEM */
31000 if (STRINGP (string
))
31001 pos
= make_number (charpos
);
31003 /* Set the help text and mouse pointer. If the mouse is on a part
31004 of the mode line without any text (e.g. past the right edge of
31005 the mode line text), use that windows's mode line help echo if it
31007 if (STRINGP (string
) || area
== ON_MODE_LINE
)
31009 /* Arrange to display the help by setting the global variables
31010 help_echo_string, help_echo_object, and help_echo_pos. */
31013 if (STRINGP (string
))
31014 help
= Fget_text_property (pos
, Qhelp_echo
, string
);
31018 help_echo_string
= help
;
31019 XSETWINDOW (help_echo_window
, w
);
31020 help_echo_object
= string
;
31021 help_echo_pos
= charpos
;
31023 else if (area
== ON_MODE_LINE
31024 && !NILP (w
->mode_line_help_echo
))
31026 help_echo_string
= w
->mode_line_help_echo
;
31027 XSETWINDOW (help_echo_window
, w
);
31028 help_echo_object
= Qnil
;
31029 help_echo_pos
= -1;
31033 #ifdef HAVE_WINDOW_SYSTEM
31034 /* Change the mouse pointer according to what is under it. */
31035 if (FRAME_WINDOW_P (f
))
31037 bool draggable
= (! WINDOW_BOTTOMMOST_P (w
)
31039 || NILP (Vresize_mini_windows
));
31041 if (STRINGP (string
))
31043 cursor
= FRAME_X_OUTPUT (f
)->nontext_cursor
;
31045 if (NILP (pointer
))
31046 pointer
= Fget_text_property (pos
, Qpointer
, string
);
31048 /* Change the mouse pointer according to what is under X/Y. */
31050 && (area
== ON_MODE_LINE
|| area
== ON_HEADER_LINE
))
31054 map
= Fget_text_property (pos
, Qlocal_map
, string
);
31055 if (!KEYMAPP (map
))
31056 map
= Fget_text_property (pos
, Qkeymap
, string
);
31057 if (!KEYMAPP (map
) && draggable
&& area
== ON_MODE_LINE
)
31058 cursor
= FRAME_X_OUTPUT (f
)->vertical_drag_cursor
;
31061 else if (draggable
&& area
== ON_MODE_LINE
)
31062 cursor
= FRAME_X_OUTPUT (f
)->vertical_drag_cursor
;
31064 cursor
= FRAME_X_OUTPUT (f
)->nontext_cursor
;
31069 /* Change the mouse face according to what is under X/Y. */
31070 bool mouse_face_shown
= false;
31072 if (STRINGP (string
))
31074 mouse_face
= Fget_text_property (pos
, Qmouse_face
, string
);
31075 if (!NILP (Vmouse_highlight
) && !NILP (mouse_face
)
31076 && ((area
== ON_MODE_LINE
) || (area
== ON_HEADER_LINE
))
31081 struct glyph
* tmp_glyph
;
31085 int total_pixel_width
;
31086 ptrdiff_t begpos
, endpos
, ignore
;
31090 b
= Fprevious_single_property_change (make_number (charpos
+ 1),
31091 Qmouse_face
, string
, Qnil
);
31097 e
= Fnext_single_property_change (pos
, Qmouse_face
, string
, Qnil
);
31099 endpos
= SCHARS (string
);
31103 /* Calculate the glyph position GPOS of GLYPH in the
31104 displayed string, relative to the beginning of the
31105 highlighted part of the string.
31107 Note: GPOS is different from CHARPOS. CHARPOS is the
31108 position of GLYPH in the internal string object. A mode
31109 line string format has structures which are converted to
31110 a flattened string by the Emacs Lisp interpreter. The
31111 internal string is an element of those structures. The
31112 displayed string is the flattened string. */
31113 tmp_glyph
= row_start_glyph
;
31114 while (tmp_glyph
< glyph
31115 && (!(EQ (tmp_glyph
->object
, glyph
->object
)
31116 && begpos
<= tmp_glyph
->charpos
31117 && tmp_glyph
->charpos
< endpos
)))
31119 gpos
= glyph
- tmp_glyph
;
31121 /* Calculate the length GSEQ_LENGTH of the glyph sequence of
31122 the highlighted part of the displayed string to which
31123 GLYPH belongs. Note: GSEQ_LENGTH is different from
31124 SCHARS (STRING), because the latter returns the length of
31125 the internal string. */
31126 for (tmp_glyph
= row
->glyphs
[TEXT_AREA
] + row
->used
[TEXT_AREA
] - 1;
31128 && (!(EQ (tmp_glyph
->object
, glyph
->object
)
31129 && begpos
<= tmp_glyph
->charpos
31130 && tmp_glyph
->charpos
< endpos
));
31133 gseq_length
= gpos
+ (tmp_glyph
- glyph
) + 1;
31135 /* Calculate the total pixel width of all the glyphs between
31136 the beginning of the highlighted area and GLYPH. */
31137 total_pixel_width
= 0;
31138 for (tmp_glyph
= glyph
- gpos
; tmp_glyph
!= glyph
; tmp_glyph
++)
31139 total_pixel_width
+= tmp_glyph
->pixel_width
;
31141 /* Pre calculation of re-rendering position. Note: X is in
31142 column units here, after the call to mode_line_string or
31143 marginal_area_string. */
31145 vpos
= (area
== ON_MODE_LINE
31146 ? (w
->current_matrix
)->nrows
- 1
31149 /* If GLYPH's position is included in the region that is
31150 already drawn in mouse face, we have nothing to do. */
31151 if ( EQ (window
, hlinfo
->mouse_face_window
)
31152 && (!row
->reversed_p
31153 ? (hlinfo
->mouse_face_beg_col
<= hpos
31154 && hpos
< hlinfo
->mouse_face_end_col
)
31155 /* In R2L rows we swap BEG and END, see below. */
31156 : (hlinfo
->mouse_face_end_col
<= hpos
31157 && hpos
< hlinfo
->mouse_face_beg_col
))
31158 && hlinfo
->mouse_face_beg_row
== vpos
)
31161 if (clear_mouse_face (hlinfo
))
31162 cursor
= No_Cursor
;
31164 if (!row
->reversed_p
)
31166 hlinfo
->mouse_face_beg_col
= hpos
;
31167 hlinfo
->mouse_face_beg_x
= original_x_pixel
31168 - (total_pixel_width
+ dx
);
31169 hlinfo
->mouse_face_end_col
= hpos
+ gseq_length
;
31170 hlinfo
->mouse_face_end_x
= 0;
31174 /* In R2L rows, show_mouse_face expects BEG and END
31175 coordinates to be swapped. */
31176 hlinfo
->mouse_face_end_col
= hpos
;
31177 hlinfo
->mouse_face_end_x
= original_x_pixel
31178 - (total_pixel_width
+ dx
);
31179 hlinfo
->mouse_face_beg_col
= hpos
+ gseq_length
;
31180 hlinfo
->mouse_face_beg_x
= 0;
31183 hlinfo
->mouse_face_beg_row
= vpos
;
31184 hlinfo
->mouse_face_end_row
= hlinfo
->mouse_face_beg_row
;
31185 hlinfo
->mouse_face_past_end
= false;
31186 hlinfo
->mouse_face_window
= window
;
31188 hlinfo
->mouse_face_face_id
= face_at_string_position (w
, string
,
31193 show_mouse_face (hlinfo
, DRAW_MOUSE_FACE
);
31194 mouse_face_shown
= true;
31196 if (NILP (pointer
))
31201 /* If mouse-face doesn't need to be shown, clear any existing
31203 if ((area
== ON_MODE_LINE
|| area
== ON_HEADER_LINE
) && !mouse_face_shown
)
31204 clear_mouse_face (hlinfo
);
31206 define_frame_cursor1 (f
, cursor
, pointer
);
31211 Take proper action when the mouse has moved to position X, Y on
31212 frame F with regards to highlighting portions of display that have
31213 mouse-face properties. Also de-highlight portions of display where
31214 the mouse was before, set the mouse pointer shape as appropriate
31215 for the mouse coordinates, and activate help echo (tooltips).
31216 X and Y can be negative or out of range. */
31219 note_mouse_highlight (struct frame
*f
, int x
, int y
)
31221 Mouse_HLInfo
*hlinfo
= MOUSE_HL_INFO (f
);
31222 enum window_part part
= ON_NOTHING
;
31223 Lisp_Object window
;
31225 Cursor cursor
= No_Cursor
;
31226 Lisp_Object pointer
= Qnil
; /* Takes precedence over cursor! */
31229 /* When a menu is active, don't highlight because this looks odd. */
31230 #if defined (USE_X_TOOLKIT) || defined (USE_GTK) || defined (HAVE_NS) || defined (MSDOS)
31231 if (popup_activated ())
31235 if (!f
->glyphs_initialized_p
31236 || f
->pointer_invisible
)
31239 hlinfo
->mouse_face_mouse_x
= x
;
31240 hlinfo
->mouse_face_mouse_y
= y
;
31241 hlinfo
->mouse_face_mouse_frame
= f
;
31243 if (hlinfo
->mouse_face_defer
)
31246 /* Which window is that in? */
31247 window
= window_from_coordinates (f
, x
, y
, &part
, true);
31249 /* If displaying active text in another window, clear that. */
31250 if (! EQ (window
, hlinfo
->mouse_face_window
)
31251 /* Also clear if we move out of text area in same window. */
31252 || (!NILP (hlinfo
->mouse_face_window
)
31255 && part
!= ON_MODE_LINE
31256 && part
!= ON_HEADER_LINE
))
31257 clear_mouse_face (hlinfo
);
31259 /* Reset help_echo_string. It will get recomputed below. */
31260 help_echo_string
= Qnil
;
31262 #ifdef HAVE_WINDOW_SYSTEM
31263 /* If the cursor is on the internal border of FRAME and FRAME's
31264 internal border is draggable, provide some visual feedback. */
31265 if (FRAME_INTERNAL_BORDER_WIDTH (f
) > 0
31266 && !NILP (get_frame_param (f
, Qdrag_internal_border
)))
31268 enum internal_border_part part
= frame_internal_border_part (f
, x
, y
);
31272 case INTERNAL_BORDER_NONE
:
31273 if (cursor
!= FRAME_X_OUTPUT (f
)->nontext_cursor
)
31274 /* Reset cursor. */
31275 cursor
= FRAME_X_OUTPUT (f
)->nontext_cursor
;
31277 case INTERNAL_BORDER_LEFT_EDGE
:
31278 cursor
= FRAME_X_OUTPUT (f
)->left_edge_cursor
;
31280 case INTERNAL_BORDER_TOP_LEFT_CORNER
:
31281 cursor
= FRAME_X_OUTPUT (f
)->top_left_corner_cursor
;
31283 case INTERNAL_BORDER_TOP_EDGE
:
31284 cursor
= FRAME_X_OUTPUT (f
)->top_edge_cursor
;
31286 case INTERNAL_BORDER_TOP_RIGHT_CORNER
:
31287 cursor
= FRAME_X_OUTPUT (f
)->top_right_corner_cursor
;
31289 case INTERNAL_BORDER_RIGHT_EDGE
:
31290 cursor
= FRAME_X_OUTPUT (f
)->right_edge_cursor
;
31292 case INTERNAL_BORDER_BOTTOM_RIGHT_CORNER
:
31293 cursor
= FRAME_X_OUTPUT (f
)->bottom_right_corner_cursor
;
31295 case INTERNAL_BORDER_BOTTOM_EDGE
:
31296 cursor
= FRAME_X_OUTPUT (f
)->bottom_edge_cursor
;
31298 case INTERNAL_BORDER_BOTTOM_LEFT_CORNER
:
31299 cursor
= FRAME_X_OUTPUT (f
)->bottom_left_corner_cursor
;
31302 /* This should not happen. */
31303 if (cursor
!= FRAME_X_OUTPUT (f
)->nontext_cursor
)
31304 cursor
= FRAME_X_OUTPUT (f
)->nontext_cursor
;
31307 if (cursor
!= FRAME_X_OUTPUT (f
)->nontext_cursor
)
31309 /* Do we really want a help echo here? */
31310 help_echo_string
= build_string ("drag-mouse-1: resize frame");
31314 #endif /* HAVE_WINDOW_SYSTEM */
31316 /* Not on a window -> return. */
31317 if (!WINDOWP (window
))
31320 /* Convert to window-relative pixel coordinates. */
31321 w
= XWINDOW (window
);
31322 frame_to_window_pixel_xy (w
, &x
, &y
);
31324 #if defined (HAVE_WINDOW_SYSTEM) && ! defined (USE_GTK) && ! defined (HAVE_NS)
31325 /* Handle tool-bar window differently since it doesn't display a
31327 if (EQ (window
, f
->tool_bar_window
))
31329 note_tool_bar_highlight (f
, x
, y
);
31334 /* Mouse is on the mode, header line or margin? */
31335 if (part
== ON_MODE_LINE
|| part
== ON_HEADER_LINE
31336 || part
== ON_LEFT_MARGIN
|| part
== ON_RIGHT_MARGIN
)
31338 note_mode_line_or_margin_highlight (window
, x
, y
, part
);
31340 #ifdef HAVE_WINDOW_SYSTEM
31341 if (part
== ON_LEFT_MARGIN
|| part
== ON_RIGHT_MARGIN
)
31343 cursor
= FRAME_X_OUTPUT (f
)->nontext_cursor
;
31344 /* Show non-text cursor (Bug#16647). */
31352 #ifdef HAVE_WINDOW_SYSTEM
31353 if (part
== ON_VERTICAL_BORDER
)
31355 cursor
= FRAME_X_OUTPUT (f
)->horizontal_drag_cursor
;
31356 help_echo_string
= build_string ("drag-mouse-1: resize");
31359 else if (part
== ON_RIGHT_DIVIDER
)
31361 cursor
= FRAME_X_OUTPUT (f
)->horizontal_drag_cursor
;
31362 help_echo_string
= build_string ("drag-mouse-1: resize");
31365 else if (part
== ON_BOTTOM_DIVIDER
)
31366 if (! WINDOW_BOTTOMMOST_P (w
)
31368 || NILP (Vresize_mini_windows
))
31370 cursor
= FRAME_X_OUTPUT (f
)->vertical_drag_cursor
;
31371 help_echo_string
= build_string ("drag-mouse-1: resize");
31375 cursor
= FRAME_X_OUTPUT (f
)->nontext_cursor
;
31376 else if (part
== ON_LEFT_FRINGE
|| part
== ON_RIGHT_FRINGE
31377 || part
== ON_VERTICAL_SCROLL_BAR
31378 || part
== ON_HORIZONTAL_SCROLL_BAR
)
31379 cursor
= FRAME_X_OUTPUT (f
)->nontext_cursor
;
31381 cursor
= FRAME_X_OUTPUT (f
)->text_cursor
;
31384 /* Are we in a window whose display is up to date?
31385 And verify the buffer's text has not changed. */
31386 b
= XBUFFER (w
->contents
);
31387 if (part
== ON_TEXT
&& w
->window_end_valid
&& !window_outdated (w
))
31389 int hpos
, vpos
, dx
, dy
, area
= LAST_AREA
;
31391 struct glyph
*glyph
;
31392 Lisp_Object object
;
31393 Lisp_Object mouse_face
= Qnil
, position
;
31394 Lisp_Object
*overlay_vec
= NULL
;
31395 ptrdiff_t i
, noverlays
;
31396 struct buffer
*obuf
;
31397 ptrdiff_t obegv
, ozv
;
31400 /* Find the glyph under X/Y. */
31401 glyph
= x_y_to_hpos_vpos (w
, x
, y
, &hpos
, &vpos
, &dx
, &dy
, &area
);
31403 #ifdef HAVE_WINDOW_SYSTEM
31404 /* Look for :pointer property on image. */
31405 if (glyph
!= NULL
&& glyph
->type
== IMAGE_GLYPH
)
31407 struct image
*img
= IMAGE_OPT_FROM_ID (f
, glyph
->u
.img_id
);
31408 if (img
!= NULL
&& IMAGEP (img
->spec
))
31410 Lisp_Object image_map
, hotspot
;
31411 if ((image_map
= Fplist_get (XCDR (img
->spec
), QCmap
),
31413 && (hotspot
= find_hot_spot (image_map
,
31414 glyph
->slice
.img
.x
+ dx
,
31415 glyph
->slice
.img
.y
+ dy
),
31417 && (hotspot
= XCDR (hotspot
), CONSP (hotspot
)))
31421 /* Could check XCAR (hotspot) to see if we enter/leave
31423 If so, we could look for mouse-enter, mouse-leave
31424 properties in PLIST (and do something...). */
31425 hotspot
= XCDR (hotspot
);
31426 if (CONSP (hotspot
)
31427 && (plist
= XCAR (hotspot
), CONSP (plist
)))
31429 pointer
= Fplist_get (plist
, Qpointer
);
31430 if (NILP (pointer
))
31432 help_echo_string
= Fplist_get (plist
, Qhelp_echo
);
31433 if (!NILP (help_echo_string
))
31435 help_echo_window
= window
;
31436 help_echo_object
= glyph
->object
;
31437 help_echo_pos
= glyph
->charpos
;
31441 if (NILP (pointer
))
31442 pointer
= Fplist_get (XCDR (img
->spec
), QCpointer
);
31445 #endif /* HAVE_WINDOW_SYSTEM */
31447 /* Clear mouse face if X/Y not over text. */
31449 || area
!= TEXT_AREA
31450 || !MATRIX_ROW_DISPLAYS_TEXT_P (MATRIX_ROW (w
->current_matrix
, vpos
))
31451 /* Glyph's OBJECT is nil for glyphs inserted by the
31452 display engine for its internal purposes, like truncation
31453 and continuation glyphs and blanks beyond the end of
31454 line's text on text terminals. If we are over such a
31455 glyph, we are not over any text. */
31456 || NILP (glyph
->object
)
31457 /* R2L rows have a stretch glyph at their front, which
31458 stands for no text, whereas L2R rows have no glyphs at
31459 all beyond the end of text. Treat such stretch glyphs
31460 like we do with NULL glyphs in L2R rows. */
31461 || (MATRIX_ROW (w
->current_matrix
, vpos
)->reversed_p
31462 && glyph
== MATRIX_ROW_GLYPH_START (w
->current_matrix
, vpos
)
31463 && glyph
->type
== STRETCH_GLYPH
31464 && glyph
->avoid_cursor_p
))
31466 if (clear_mouse_face (hlinfo
))
31467 cursor
= No_Cursor
;
31468 if (FRAME_WINDOW_P (f
) && NILP (pointer
))
31470 #ifdef HAVE_WINDOW_SYSTEM
31471 if (area
!= TEXT_AREA
)
31472 cursor
= FRAME_X_OUTPUT (f
)->nontext_cursor
;
31474 pointer
= Vvoid_text_area_pointer
;
31480 pos
= glyph
->charpos
;
31481 object
= glyph
->object
;
31482 if (!STRINGP (object
) && !BUFFERP (object
))
31485 /* If we get an out-of-range value, return now; avoid an error. */
31486 if (BUFFERP (object
) && pos
> BUF_Z (b
))
31489 /* Make the window's buffer temporarily current for
31490 overlays_at and compute_char_face. */
31491 obuf
= current_buffer
;
31492 current_buffer
= b
;
31498 /* Is this char mouse-active or does it have help-echo? */
31499 position
= make_number (pos
);
31503 if (BUFFERP (object
))
31505 /* Put all the overlays we want in a vector in overlay_vec. */
31506 GET_OVERLAYS_AT (pos
, overlay_vec
, noverlays
, NULL
, false);
31507 /* Sort overlays into increasing priority order. */
31508 noverlays
= sort_overlays (overlay_vec
, noverlays
, w
);
31513 if (NILP (Vmouse_highlight
))
31515 clear_mouse_face (hlinfo
);
31516 goto check_help_echo
;
31519 same_region
= coords_in_mouse_face_p (w
, hpos
, vpos
);
31522 cursor
= No_Cursor
;
31524 /* Check mouse-face highlighting. */
31526 /* If there exists an overlay with mouse-face overlapping
31527 the one we are currently highlighting, we have to check
31528 if we enter the overlapping overlay, and then highlight
31529 only that. Skip the check when mouse-face highlighting
31530 is currently hidden to avoid Bug#30519. */
31531 || (!hlinfo
->mouse_face_hidden
31532 && OVERLAYP (hlinfo
->mouse_face_overlay
)
31533 && mouse_face_overlay_overlaps (hlinfo
->mouse_face_overlay
)))
31535 /* Find the highest priority overlay with a mouse-face. */
31536 Lisp_Object overlay
= Qnil
;
31537 for (i
= noverlays
- 1; i
>= 0 && NILP (overlay
); --i
)
31539 mouse_face
= Foverlay_get (overlay_vec
[i
], Qmouse_face
);
31540 if (!NILP (mouse_face
))
31541 overlay
= overlay_vec
[i
];
31544 /* If we're highlighting the same overlay as before, there's
31545 no need to do that again. */
31546 if (!NILP (overlay
) && EQ (overlay
, hlinfo
->mouse_face_overlay
))
31547 goto check_help_echo
;
31549 /* Clear the display of the old active region, if any. */
31550 if (clear_mouse_face (hlinfo
))
31551 cursor
= No_Cursor
;
31553 /* Record the overlay, if any, to be highlighted. */
31554 hlinfo
->mouse_face_overlay
= overlay
;
31556 /* If no overlay applies, get a text property. */
31557 if (NILP (overlay
))
31558 mouse_face
= Fget_text_property (position
, Qmouse_face
, object
);
31560 /* Next, compute the bounds of the mouse highlighting and
31562 if (!NILP (mouse_face
) && STRINGP (object
))
31564 /* The mouse-highlighting comes from a display string
31565 with a mouse-face. */
31569 s
= Fprevious_single_property_change
31570 (make_number (pos
+ 1), Qmouse_face
, object
, Qnil
);
31571 e
= Fnext_single_property_change
31572 (position
, Qmouse_face
, object
, Qnil
);
31574 s
= make_number (0);
31576 e
= make_number (SCHARS (object
));
31577 mouse_face_from_string_pos (w
, hlinfo
, object
,
31578 XINT (s
), XINT (e
));
31579 hlinfo
->mouse_face_past_end
= false;
31580 hlinfo
->mouse_face_window
= window
;
31581 hlinfo
->mouse_face_face_id
31582 = face_at_string_position (w
, object
, pos
, 0, &ignore
,
31583 glyph
->face_id
, true);
31584 show_mouse_face (hlinfo
, DRAW_MOUSE_FACE
);
31585 cursor
= No_Cursor
;
31589 /* The mouse-highlighting, if any, comes from an overlay
31590 or text property in the buffer. */
31591 Lisp_Object buffer UNINIT
;
31592 Lisp_Object disp_string UNINIT
;
31594 if (STRINGP (object
))
31596 /* If we are on a display string with no mouse-face,
31597 check if the text under it has one. */
31598 struct glyph_row
*r
= MATRIX_ROW (w
->current_matrix
, vpos
);
31599 ptrdiff_t start
= MATRIX_ROW_START_CHARPOS (r
);
31600 pos
= string_buffer_position (object
, start
);
31603 mouse_face
= get_char_property_and_overlay
31604 (make_number (pos
), Qmouse_face
, w
->contents
, &overlay
);
31605 buffer
= w
->contents
;
31606 disp_string
= object
;
31612 disp_string
= Qnil
;
31615 if (!NILP (mouse_face
))
31617 Lisp_Object before
, after
;
31618 Lisp_Object before_string
, after_string
;
31619 /* To correctly find the limits of mouse highlight
31620 in a bidi-reordered buffer, we must not use the
31621 optimization of limiting the search in
31622 previous-single-property-change and
31623 next-single-property-change, because
31624 rows_from_pos_range needs the real start and end
31625 positions to DTRT in this case. That's because
31626 the first row visible in a window does not
31627 necessarily display the character whose position
31628 is the smallest. */
31630 = NILP (BVAR (XBUFFER (buffer
), bidi_display_reordering
))
31631 ? Fmarker_position (w
->start
)
31634 = NILP (BVAR (XBUFFER (buffer
), bidi_display_reordering
))
31635 ? make_number (BUF_Z (XBUFFER (buffer
))
31636 - w
->window_end_pos
)
31639 if (NILP (overlay
))
31641 /* Handle the text property case. */
31642 before
= Fprevious_single_property_change
31643 (make_number (pos
+ 1), Qmouse_face
, buffer
, lim1
);
31644 after
= Fnext_single_property_change
31645 (make_number (pos
), Qmouse_face
, buffer
, lim2
);
31646 before_string
= after_string
= Qnil
;
31650 /* Handle the overlay case. */
31651 before
= Foverlay_start (overlay
);
31652 after
= Foverlay_end (overlay
);
31653 before_string
= Foverlay_get (overlay
, Qbefore_string
);
31654 after_string
= Foverlay_get (overlay
, Qafter_string
);
31656 if (!STRINGP (before_string
)) before_string
= Qnil
;
31657 if (!STRINGP (after_string
)) after_string
= Qnil
;
31660 mouse_face_from_buffer_pos (window
, hlinfo
, pos
,
31663 : XFASTINT (before
),
31665 ? BUF_Z (XBUFFER (buffer
))
31666 : XFASTINT (after
),
31667 before_string
, after_string
,
31669 cursor
= No_Cursor
;
31676 /* Look for a `help-echo' property. */
31677 if (NILP (help_echo_string
)) {
31678 Lisp_Object help
, overlay
;
31680 /* Check overlays first. */
31681 help
= overlay
= Qnil
;
31682 for (i
= noverlays
- 1; i
>= 0 && NILP (help
); --i
)
31684 overlay
= overlay_vec
[i
];
31685 help
= Foverlay_get (overlay
, Qhelp_echo
);
31690 help_echo_string
= help
;
31691 help_echo_window
= window
;
31692 help_echo_object
= overlay
;
31693 help_echo_pos
= pos
;
31697 Lisp_Object obj
= glyph
->object
;
31698 ptrdiff_t charpos
= glyph
->charpos
;
31700 /* Try text properties. */
31703 && charpos
< SCHARS (obj
))
31705 help
= Fget_text_property (make_number (charpos
),
31709 /* If the string itself doesn't specify a help-echo,
31710 see if the buffer text ``under'' it does. */
31711 struct glyph_row
*r
31712 = MATRIX_ROW (w
->current_matrix
, vpos
);
31713 ptrdiff_t start
= MATRIX_ROW_START_CHARPOS (r
);
31714 ptrdiff_t p
= string_buffer_position (obj
, start
);
31717 help
= Fget_char_property (make_number (p
),
31718 Qhelp_echo
, w
->contents
);
31727 else if (BUFFERP (obj
)
31730 help
= Fget_text_property (make_number (charpos
), Qhelp_echo
,
31735 help_echo_string
= help
;
31736 help_echo_window
= window
;
31737 help_echo_object
= obj
;
31738 help_echo_pos
= charpos
;
31743 #ifdef HAVE_WINDOW_SYSTEM
31744 /* Look for a `pointer' property. */
31745 if (FRAME_WINDOW_P (f
) && NILP (pointer
))
31747 /* Check overlays first. */
31748 for (i
= noverlays
- 1; i
>= 0 && NILP (pointer
); --i
)
31749 pointer
= Foverlay_get (overlay_vec
[i
], Qpointer
);
31751 if (NILP (pointer
))
31753 Lisp_Object obj
= glyph
->object
;
31754 ptrdiff_t charpos
= glyph
->charpos
;
31756 /* Try text properties. */
31759 && charpos
< SCHARS (obj
))
31761 pointer
= Fget_text_property (make_number (charpos
),
31763 if (NILP (pointer
))
31765 /* If the string itself doesn't specify a pointer,
31766 see if the buffer text ``under'' it does. */
31767 struct glyph_row
*r
31768 = MATRIX_ROW (w
->current_matrix
, vpos
);
31769 ptrdiff_t start
= MATRIX_ROW_START_CHARPOS (r
);
31770 ptrdiff_t p
= string_buffer_position (obj
, start
);
31772 pointer
= Fget_char_property (make_number (p
),
31773 Qpointer
, w
->contents
);
31776 else if (BUFFERP (obj
)
31779 pointer
= Fget_text_property (make_number (charpos
),
31783 #endif /* HAVE_WINDOW_SYSTEM */
31787 current_buffer
= obuf
;
31792 define_frame_cursor1 (f
, cursor
, pointer
);
31797 Clear any mouse-face on window W. This function is part of the
31798 redisplay interface, and is called from try_window_id and similar
31799 functions to ensure the mouse-highlight is off. */
31802 x_clear_window_mouse_face (struct window
*w
)
31804 Mouse_HLInfo
*hlinfo
= MOUSE_HL_INFO (XFRAME (w
->frame
));
31805 Lisp_Object window
;
31808 XSETWINDOW (window
, w
);
31809 if (EQ (window
, hlinfo
->mouse_face_window
))
31810 clear_mouse_face (hlinfo
);
31816 Just discard the mouse face information for frame F, if any.
31817 This is used when the size of F is changed. */
31820 cancel_mouse_face (struct frame
*f
)
31822 Lisp_Object window
;
31823 Mouse_HLInfo
*hlinfo
= MOUSE_HL_INFO (f
);
31825 window
= hlinfo
->mouse_face_window
;
31826 if (! NILP (window
) && XFRAME (XWINDOW (window
)->frame
) == f
)
31827 reset_mouse_highlight (hlinfo
);
31832 /***********************************************************************
31834 ***********************************************************************/
31836 #ifdef HAVE_WINDOW_SYSTEM
31838 /* Redraw the part of glyph row area AREA of glyph row ROW on window W
31839 which intersects rectangle R. R is in window-relative coordinates. */
31842 expose_area (struct window
*w
, struct glyph_row
*row
, XRectangle
*r
,
31843 enum glyph_row_area area
)
31845 struct glyph
*first
= row
->glyphs
[area
];
31846 struct glyph
*end
= row
->glyphs
[area
] + row
->used
[area
];
31847 struct glyph
*last
;
31848 int first_x
, start_x
, x
;
31850 if (area
== TEXT_AREA
&& row
->fill_line_p
)
31851 /* If row extends face to end of line write the whole line. */
31852 draw_glyphs (w
, 0, row
, area
,
31853 0, row
->used
[area
],
31854 DRAW_NORMAL_TEXT
, 0);
31857 /* Set START_X to the window-relative start position for drawing glyphs of
31858 AREA. The first glyph of the text area can be partially visible.
31859 The first glyphs of other areas cannot. */
31860 start_x
= window_box_left_offset (w
, area
);
31862 if (area
== TEXT_AREA
)
31865 /* Find the first glyph that must be redrawn. */
31867 && x
+ first
->pixel_width
< r
->x
)
31869 x
+= first
->pixel_width
;
31873 /* Find the last one. */
31876 /* Use a signed int intermediate value to avoid catastrophic
31877 failures due to comparison between signed and unsigned, when
31878 x is negative (can happen for wide images that are hscrolled). */
31879 int r_end
= r
->x
+ r
->width
;
31880 while (last
< end
&& x
< r_end
)
31882 x
+= last
->pixel_width
;
31888 draw_glyphs (w
, first_x
- start_x
, row
, area
,
31889 first
- row
->glyphs
[area
], last
- row
->glyphs
[area
],
31890 DRAW_NORMAL_TEXT
, 0);
31895 /* Redraw the parts of the glyph row ROW on window W intersecting
31896 rectangle R. R is in window-relative coordinates. Value is
31897 true if mouse-face was overwritten. */
31900 expose_line (struct window
*w
, struct glyph_row
*row
, XRectangle
*r
)
31902 eassert (row
->enabled_p
);
31904 if (row
->mode_line_p
|| w
->pseudo_window_p
)
31905 draw_glyphs (w
, 0, row
, TEXT_AREA
,
31906 0, row
->used
[TEXT_AREA
],
31907 DRAW_NORMAL_TEXT
, 0);
31910 if (row
->used
[LEFT_MARGIN_AREA
])
31911 expose_area (w
, row
, r
, LEFT_MARGIN_AREA
);
31912 if (row
->used
[TEXT_AREA
])
31913 expose_area (w
, row
, r
, TEXT_AREA
);
31914 if (row
->used
[RIGHT_MARGIN_AREA
])
31915 expose_area (w
, row
, r
, RIGHT_MARGIN_AREA
);
31916 draw_row_fringe_bitmaps (w
, row
);
31919 return row
->mouse_face_p
;
31923 /* Redraw those parts of glyphs rows during expose event handling that
31924 overlap other rows. Redrawing of an exposed line writes over parts
31925 of lines overlapping that exposed line; this function fixes that.
31927 W is the window being exposed. FIRST_OVERLAPPING_ROW is the first
31928 row in W's current matrix that is exposed and overlaps other rows.
31929 LAST_OVERLAPPING_ROW is the last such row. */
31932 expose_overlaps (struct window
*w
,
31933 struct glyph_row
*first_overlapping_row
,
31934 struct glyph_row
*last_overlapping_row
,
31937 struct glyph_row
*row
;
31939 for (row
= first_overlapping_row
; row
<= last_overlapping_row
; ++row
)
31940 if (row
->overlapping_p
)
31942 eassert (row
->enabled_p
&& !row
->mode_line_p
);
31945 if (row
->used
[LEFT_MARGIN_AREA
])
31946 x_fix_overlapping_area (w
, row
, LEFT_MARGIN_AREA
, OVERLAPS_BOTH
);
31948 if (row
->used
[TEXT_AREA
])
31949 x_fix_overlapping_area (w
, row
, TEXT_AREA
, OVERLAPS_BOTH
);
31951 if (row
->used
[RIGHT_MARGIN_AREA
])
31952 x_fix_overlapping_area (w
, row
, RIGHT_MARGIN_AREA
, OVERLAPS_BOTH
);
31958 /* Return true if W's cursor intersects rectangle R. */
31961 phys_cursor_in_rect_p (struct window
*w
, XRectangle
*r
)
31963 XRectangle cr
, result
;
31964 struct glyph
*cursor_glyph
;
31965 struct glyph_row
*row
;
31967 if (w
->phys_cursor
.vpos
>= 0
31968 && w
->phys_cursor
.vpos
< w
->current_matrix
->nrows
31969 && (row
= MATRIX_ROW (w
->current_matrix
, w
->phys_cursor
.vpos
),
31971 && row
->cursor_in_fringe_p
)
31973 /* Cursor is in the fringe. */
31974 cr
.x
= window_box_right_offset (w
,
31975 (WINDOW_HAS_FRINGES_OUTSIDE_MARGINS (w
)
31976 ? RIGHT_MARGIN_AREA
31979 cr
.width
= WINDOW_RIGHT_FRINGE_WIDTH (w
);
31980 cr
.height
= row
->height
;
31981 return x_intersect_rectangles (&cr
, r
, &result
);
31984 cursor_glyph
= get_phys_cursor_glyph (w
);
31987 /* r is relative to W's box, but w->phys_cursor.x is relative
31988 to left edge of W's TEXT area. Adjust it. */
31989 cr
.x
= window_box_left_offset (w
, TEXT_AREA
) + w
->phys_cursor
.x
;
31990 cr
.y
= w
->phys_cursor
.y
;
31991 cr
.width
= cursor_glyph
->pixel_width
;
31992 cr
.height
= w
->phys_cursor_height
;
31993 /* ++KFS: W32 version used W32-specific IntersectRect here, but
31994 I assume the effect is the same -- and this is portable. */
31995 return x_intersect_rectangles (&cr
, r
, &result
);
31997 /* If we don't understand the format, pretend we're not in the hot-spot. */
32003 Draw a vertical window border to the right of window W if W doesn't
32004 have vertical scroll bars. */
32007 x_draw_vertical_border (struct window
*w
)
32009 struct frame
*f
= XFRAME (WINDOW_FRAME (w
));
32011 /* We could do better, if we knew what type of scroll-bar the adjacent
32012 windows (on either side) have... But we don't :-(
32013 However, I think this works ok. ++KFS 2003-04-25 */
32015 /* Redraw borders between horizontally adjacent windows. Don't
32016 do it for frames with vertical scroll bars because either the
32017 right scroll bar of a window, or the left scroll bar of its
32018 neighbor will suffice as a border. */
32019 if (FRAME_HAS_VERTICAL_SCROLL_BARS (f
) || FRAME_RIGHT_DIVIDER_WIDTH (f
))
32022 /* Note: It is necessary to redraw both the left and the right
32023 borders, for when only this single window W is being
32025 if (!WINDOW_RIGHTMOST_P (w
)
32026 && !WINDOW_HAS_VERTICAL_SCROLL_BAR_ON_RIGHT (w
))
32028 int x0
, x1
, y0
, y1
;
32030 window_box_edges (w
, &x0
, &y0
, &x1
, &y1
);
32033 if (WINDOW_LEFT_FRINGE_WIDTH (w
) == 0)
32036 FRAME_RIF (f
)->draw_vertical_window_border (w
, x1
, y0
, y1
);
32039 if (!WINDOW_LEFTMOST_P (w
)
32040 && !WINDOW_HAS_VERTICAL_SCROLL_BAR_ON_LEFT (w
))
32042 int x0
, x1
, y0
, y1
;
32044 window_box_edges (w
, &x0
, &y0
, &x1
, &y1
);
32047 if (WINDOW_LEFT_FRINGE_WIDTH (w
) == 0)
32050 FRAME_RIF (f
)->draw_vertical_window_border (w
, x0
, y0
, y1
);
32055 /* Draw window dividers for window W. */
32058 x_draw_right_divider (struct window
*w
)
32060 struct frame
*f
= WINDOW_XFRAME (w
);
32062 if (w
->mini
|| w
->pseudo_window_p
)
32064 else if (WINDOW_RIGHT_DIVIDER_WIDTH (w
))
32066 int x0
= WINDOW_RIGHT_EDGE_X (w
) - WINDOW_RIGHT_DIVIDER_WIDTH (w
);
32067 int x1
= WINDOW_RIGHT_EDGE_X (w
);
32068 int y0
= WINDOW_TOP_EDGE_Y (w
);
32069 int y1
= WINDOW_BOTTOM_EDGE_Y (w
);
32071 /* If W is horizontally combined and has a right sibling, don't
32072 draw over any bottom divider. */
32073 if (WINDOW_BOTTOM_DIVIDER_WIDTH (w
)
32074 && !NILP (w
->parent
)
32075 && WINDOW_HORIZONTAL_COMBINATION_P (XWINDOW (w
->parent
))
32076 && !NILP (w
->next
))
32077 y1
-= WINDOW_BOTTOM_DIVIDER_WIDTH (w
);
32079 FRAME_RIF (f
)->draw_window_divider (w
, x0
, x1
, y0
, y1
);
32084 x_draw_bottom_divider (struct window
*w
)
32086 struct frame
*f
= XFRAME (WINDOW_FRAME (w
));
32088 if (w
->mini
|| w
->pseudo_window_p
)
32090 else if (WINDOW_BOTTOM_DIVIDER_WIDTH (w
))
32092 int x0
= WINDOW_LEFT_EDGE_X (w
);
32093 int x1
= WINDOW_RIGHT_EDGE_X (w
);
32094 int y0
= WINDOW_BOTTOM_EDGE_Y (w
) - WINDOW_BOTTOM_DIVIDER_WIDTH (w
);
32095 int y1
= WINDOW_BOTTOM_EDGE_Y (w
);
32096 struct window
*p
= !NILP (w
->parent
) ? XWINDOW (w
->parent
) : NULL
;
32098 /* If W is vertically combined and has a sibling below, don't draw
32099 over any right divider. */
32100 if (WINDOW_RIGHT_DIVIDER_WIDTH (w
)
32102 && ((WINDOW_VERTICAL_COMBINATION_P (p
)
32103 && !NILP (w
->next
))
32104 || (WINDOW_HORIZONTAL_COMBINATION_P (p
)
32106 && !NILP (p
->parent
)
32107 && WINDOW_VERTICAL_COMBINATION_P (XWINDOW (p
->parent
))
32108 && !NILP (XWINDOW (p
->parent
)->next
))))
32109 x1
-= WINDOW_RIGHT_DIVIDER_WIDTH (w
);
32111 FRAME_RIF (f
)->draw_window_divider (w
, x0
, x1
, y0
, y1
);
32115 /* Redraw the part of window W intersection rectangle FR. Pixel
32116 coordinates in FR are frame-relative. Call this function with
32117 input blocked. Value is true if the exposure overwrites
32121 expose_window (struct window
*w
, XRectangle
*fr
)
32123 struct frame
*f
= XFRAME (w
->frame
);
32125 bool mouse_face_overwritten_p
= false;
32127 /* If window is not yet fully initialized, do nothing. This can
32128 happen when toolkit scroll bars are used and a window is split.
32129 Reconfiguring the scroll bar will generate an expose for a newly
32131 if (w
->current_matrix
== NULL
)
32134 /* When we're currently updating the window, display and current
32135 matrix usually don't agree. Arrange for a thorough display
32137 if (w
->must_be_updated_p
)
32139 SET_FRAME_GARBAGED (f
);
32143 /* Frame-relative pixel rectangle of W. */
32144 wr
.x
= WINDOW_LEFT_EDGE_X (w
);
32145 wr
.y
= WINDOW_TOP_EDGE_Y (w
);
32146 wr
.width
= WINDOW_PIXEL_WIDTH (w
);
32147 wr
.height
= WINDOW_PIXEL_HEIGHT (w
);
32149 if (x_intersect_rectangles (fr
, &wr
, &r
))
32151 int yb
= window_text_bottom_y (w
);
32152 struct glyph_row
*row
;
32153 struct glyph_row
*first_overlapping_row
, *last_overlapping_row
;
32155 TRACE ((stderr
, "expose_window (%d, %d, %d, %d)\n",
32156 r
.x
, r
.y
, r
.width
, r
.height
));
32158 /* Convert to window coordinates. */
32159 r
.x
-= WINDOW_LEFT_EDGE_X (w
);
32160 r
.y
-= WINDOW_TOP_EDGE_Y (w
);
32162 /* Turn off the cursor. */
32163 bool cursor_cleared_p
= (!w
->pseudo_window_p
32164 && phys_cursor_in_rect_p (w
, &r
));
32165 if (cursor_cleared_p
)
32166 x_clear_cursor (w
);
32168 /* If the row containing the cursor extends face to end of line,
32169 then expose_area might overwrite the cursor outside the
32170 rectangle and thus notice_overwritten_cursor might clear
32171 w->phys_cursor_on_p. We remember the original value and
32172 check later if it is changed. */
32173 bool phys_cursor_on_p
= w
->phys_cursor_on_p
;
32175 /* Use a signed int intermediate value to avoid catastrophic
32176 failures due to comparison between signed and unsigned, when
32177 y0 or y1 is negative (can happen for tall images). */
32178 int r_bottom
= r
.y
+ r
.height
;
32180 /* Update lines intersecting rectangle R. */
32181 first_overlapping_row
= last_overlapping_row
= NULL
;
32182 for (row
= w
->current_matrix
->rows
;
32187 int y1
= MATRIX_ROW_BOTTOM_Y (row
);
32189 if ((y0
>= r
.y
&& y0
< r_bottom
)
32190 || (y1
> r
.y
&& y1
< r_bottom
)
32191 || (r
.y
>= y0
&& r
.y
< y1
)
32192 || (r_bottom
> y0
&& r_bottom
< y1
))
32194 /* A header line may be overlapping, but there is no need
32195 to fix overlapping areas for them. KFS 2005-02-12 */
32196 if (row
->overlapping_p
&& !row
->mode_line_p
)
32198 if (first_overlapping_row
== NULL
)
32199 first_overlapping_row
= row
;
32200 last_overlapping_row
= row
;
32204 if (expose_line (w
, row
, &r
))
32205 mouse_face_overwritten_p
= true;
32208 else if (row
->overlapping_p
)
32210 /* We must redraw a row overlapping the exposed area. */
32212 ? y0
+ row
->phys_height
> r
.y
32213 : y0
+ row
->ascent
- row
->phys_ascent
< r
.y
+r
.height
)
32215 if (first_overlapping_row
== NULL
)
32216 first_overlapping_row
= row
;
32217 last_overlapping_row
= row
;
32225 /* Display the mode line if there is one. */
32226 if (window_wants_mode_line (w
)
32227 && (row
= MATRIX_MODE_LINE_ROW (w
->current_matrix
),
32229 && row
->y
< r_bottom
)
32231 if (expose_line (w
, row
, &r
))
32232 mouse_face_overwritten_p
= true;
32235 if (!w
->pseudo_window_p
)
32237 /* Fix the display of overlapping rows. */
32238 if (first_overlapping_row
)
32239 expose_overlaps (w
, first_overlapping_row
, last_overlapping_row
,
32242 /* Draw border between windows. */
32243 if (WINDOW_RIGHT_DIVIDER_WIDTH (w
))
32244 x_draw_right_divider (w
);
32246 x_draw_vertical_border (w
);
32248 if (WINDOW_BOTTOM_DIVIDER_WIDTH (w
))
32249 x_draw_bottom_divider (w
);
32251 /* Turn the cursor on again. */
32252 if (cursor_cleared_p
32253 || (phys_cursor_on_p
&& !w
->phys_cursor_on_p
))
32254 update_window_cursor (w
, true);
32258 return mouse_face_overwritten_p
;
32263 /* Redraw (parts) of all windows in the window tree rooted at W that
32264 intersect R. R contains frame pixel coordinates. Value is
32265 true if the exposure overwrites mouse-face. */
32268 expose_window_tree (struct window
*w
, XRectangle
*r
)
32270 struct frame
*f
= XFRAME (w
->frame
);
32271 bool mouse_face_overwritten_p
= false;
32273 while (w
&& !FRAME_GARBAGED_P (f
))
32275 mouse_face_overwritten_p
32276 |= (WINDOWP (w
->contents
)
32277 ? expose_window_tree (XWINDOW (w
->contents
), r
)
32278 : expose_window (w
, r
));
32280 w
= NILP (w
->next
) ? NULL
: XWINDOW (w
->next
);
32283 return mouse_face_overwritten_p
;
32288 Redisplay an exposed area of frame F. X and Y are the upper-left
32289 corner of the exposed rectangle. W and H are width and height of
32290 the exposed area. All are pixel values. W or H zero means redraw
32291 the entire frame. */
32294 expose_frame (struct frame
*f
, int x
, int y
, int w
, int h
)
32297 bool mouse_face_overwritten_p
= false;
32299 TRACE ((stderr
, "expose_frame "));
32301 /* No need to redraw if frame will be redrawn soon. */
32302 if (FRAME_GARBAGED_P (f
))
32304 TRACE ((stderr
, " garbaged\n"));
32308 /* If basic faces haven't been realized yet, there is no point in
32309 trying to redraw anything. This can happen when we get an expose
32310 event while Emacs is starting, e.g. by moving another window. */
32311 if (FRAME_FACE_CACHE (f
) == NULL
32312 || FRAME_FACE_CACHE (f
)->used
< BASIC_FACE_ID_SENTINEL
)
32314 TRACE ((stderr
, " no faces\n"));
32318 if (w
== 0 || h
== 0)
32321 r
.width
= FRAME_TEXT_WIDTH (f
);
32322 r
.height
= FRAME_TEXT_HEIGHT (f
);
32332 TRACE ((stderr
, "(%d, %d, %d, %d)\n", r
.x
, r
.y
, r
.width
, r
.height
));
32333 mouse_face_overwritten_p
= expose_window_tree (XWINDOW (f
->root_window
), &r
);
32335 #if ! defined (USE_GTK) && ! defined (HAVE_NS)
32336 if (WINDOWP (f
->tool_bar_window
))
32337 mouse_face_overwritten_p
32338 |= expose_window (XWINDOW (f
->tool_bar_window
), &r
);
32341 #ifdef HAVE_X_WINDOWS
32343 #if ! defined (USE_X_TOOLKIT) && ! defined (USE_GTK)
32344 if (WINDOWP (f
->menu_bar_window
))
32345 mouse_face_overwritten_p
32346 |= expose_window (XWINDOW (f
->menu_bar_window
), &r
);
32347 #endif /* not USE_X_TOOLKIT and not USE_GTK */
32351 /* Some window managers support a focus-follows-mouse style with
32352 delayed raising of frames. Imagine a partially obscured frame,
32353 and moving the mouse into partially obscured mouse-face on that
32354 frame. The visible part of the mouse-face will be highlighted,
32355 then the WM raises the obscured frame. With at least one WM, KDE
32356 2.1, Emacs is not getting any event for the raising of the frame
32357 (even tried with SubstructureRedirectMask), only Expose events.
32358 These expose events will draw text normally, i.e. not
32359 highlighted. Which means we must redo the highlight here.
32360 Subsume it under ``we love X''. --gerd 2001-08-15 */
32361 /* Included in Windows version because Windows most likely does not
32362 do the right thing if any third party tool offers
32363 focus-follows-mouse with delayed raise. --jason 2001-10-12 */
32364 if (mouse_face_overwritten_p
&& !FRAME_GARBAGED_P (f
))
32366 Mouse_HLInfo
*hlinfo
= MOUSE_HL_INFO (f
);
32367 if (f
== hlinfo
->mouse_face_mouse_frame
)
32369 int mouse_x
= hlinfo
->mouse_face_mouse_x
;
32370 int mouse_y
= hlinfo
->mouse_face_mouse_y
;
32371 clear_mouse_face (hlinfo
);
32372 note_mouse_highlight (f
, mouse_x
, mouse_y
);
32379 Determine the intersection of two rectangles R1 and R2. Return
32380 the intersection in *RESULT. Value is true if RESULT is not
32384 x_intersect_rectangles (XRectangle
*r1
, XRectangle
*r2
, XRectangle
*result
)
32386 XRectangle
*left
, *right
;
32387 XRectangle
*upper
, *lower
;
32388 bool intersection_p
= false;
32390 /* Rearrange so that R1 is the left-most rectangle. */
32392 left
= r1
, right
= r2
;
32394 left
= r2
, right
= r1
;
32396 /* X0 of the intersection is right.x0, if this is inside R1,
32397 otherwise there is no intersection. */
32398 if (right
->x
<= left
->x
+ left
->width
)
32400 result
->x
= right
->x
;
32402 /* The right end of the intersection is the minimum of
32403 the right ends of left and right. */
32404 result
->width
= (min (left
->x
+ left
->width
, right
->x
+ right
->width
)
32407 /* Same game for Y. */
32409 upper
= r1
, lower
= r2
;
32411 upper
= r2
, lower
= r1
;
32413 /* The upper end of the intersection is lower.y0, if this is inside
32414 of upper. Otherwise, there is no intersection. */
32415 if (lower
->y
<= upper
->y
+ upper
->height
)
32417 result
->y
= lower
->y
;
32419 /* The lower end of the intersection is the minimum of the lower
32420 ends of upper and lower. */
32421 result
->height
= (min (lower
->y
+ lower
->height
,
32422 upper
->y
+ upper
->height
)
32424 intersection_p
= true;
32428 return intersection_p
;
32431 #endif /* HAVE_WINDOW_SYSTEM */
32434 /***********************************************************************
32436 ***********************************************************************/
32439 syms_of_xdisp (void)
32441 Vwith_echo_area_save_vector
= Qnil
;
32442 staticpro (&Vwith_echo_area_save_vector
);
32444 Vmessage_stack
= Qnil
;
32445 staticpro (&Vmessage_stack
);
32447 /* Non-nil means don't actually do any redisplay. */
32448 DEFSYM (Qinhibit_redisplay
, "inhibit-redisplay");
32450 DEFSYM (Qredisplay_internal_xC_functionx
, "redisplay_internal (C function)");
32452 DEFVAR_BOOL("inhibit-message", inhibit_message
,
32453 doc
: /* Non-nil means calls to `message' are not displayed.
32454 They are still logged to the *Messages* buffer.
32456 Do NOT set this globally to a non-nil value, as doing that will
32457 disable messages everywhere, including in I-search and other
32458 places where they are necessary. This variable is intended to
32459 be let-bound around code that needs to disable messages temporarily. */);
32460 inhibit_message
= 0;
32462 message_dolog_marker1
= Fmake_marker ();
32463 staticpro (&message_dolog_marker1
);
32464 message_dolog_marker2
= Fmake_marker ();
32465 staticpro (&message_dolog_marker2
);
32466 message_dolog_marker3
= Fmake_marker ();
32467 staticpro (&message_dolog_marker3
);
32469 defsubr (&Sset_buffer_redisplay
);
32471 defsubr (&Sdump_frame_glyph_matrix
);
32472 defsubr (&Sdump_glyph_matrix
);
32473 defsubr (&Sdump_glyph_row
);
32474 defsubr (&Sdump_tool_bar_row
);
32475 defsubr (&Strace_redisplay
);
32476 defsubr (&Strace_to_stderr
);
32478 #ifdef HAVE_WINDOW_SYSTEM
32479 defsubr (&Stool_bar_height
);
32480 defsubr (&Slookup_image_map
);
32482 defsubr (&Sline_pixel_height
);
32483 defsubr (&Sformat_mode_line
);
32484 defsubr (&Sinvisible_p
);
32485 defsubr (&Scurrent_bidi_paragraph_direction
);
32486 defsubr (&Swindow_text_pixel_size
);
32487 defsubr (&Smove_point_visually
);
32488 defsubr (&Sbidi_find_overridden_directionality
);
32490 DEFSYM (Qmenu_bar_update_hook
, "menu-bar-update-hook");
32491 DEFSYM (Qoverriding_terminal_local_map
, "overriding-terminal-local-map");
32492 DEFSYM (Qoverriding_local_map
, "overriding-local-map");
32493 DEFSYM (Qwindow_scroll_functions
, "window-scroll-functions");
32494 DEFSYM (Qredisplay_end_trigger_functions
, "redisplay-end-trigger-functions");
32495 DEFSYM (Qinhibit_point_motion_hooks
, "inhibit-point-motion-hooks");
32496 DEFSYM (Qeval
, "eval");
32497 DEFSYM (QCdata
, ":data");
32499 /* Names of text properties relevant for redisplay. */
32500 DEFSYM (Qdisplay
, "display");
32501 DEFSYM (Qspace_width
, "space-width");
32502 DEFSYM (Qraise
, "raise");
32503 DEFSYM (Qslice
, "slice");
32504 DEFSYM (Qspace
, "space");
32505 DEFSYM (Qmargin
, "margin");
32506 DEFSYM (Qpointer
, "pointer");
32507 DEFSYM (Qleft_margin
, "left-margin");
32508 DEFSYM (Qright_margin
, "right-margin");
32509 DEFSYM (Qcenter
, "center");
32510 DEFSYM (Qline_height
, "line-height");
32511 DEFSYM (QCalign_to
, ":align-to");
32512 DEFSYM (QCrelative_width
, ":relative-width");
32513 DEFSYM (QCrelative_height
, ":relative-height");
32514 DEFSYM (QCeval
, ":eval");
32515 DEFSYM (QCpropertize
, ":propertize");
32516 DEFSYM (QCfile
, ":file");
32517 DEFSYM (Qfontified
, "fontified");
32518 DEFSYM (Qfontification_functions
, "fontification-functions");
32520 /* Name of the symbol which disables Lisp evaluation in 'display'
32521 properties. This is used by enriched.el. */
32522 DEFSYM (Qdisable_eval
, "disable-eval");
32524 /* Name of the face used to highlight trailing whitespace. */
32525 DEFSYM (Qtrailing_whitespace
, "trailing-whitespace");
32527 /* Names of the faces used to display line numbers. */
32528 DEFSYM (Qline_number
, "line-number");
32529 DEFSYM (Qline_number_current_line
, "line-number-current-line");
32530 /* Name of a text property which disables line-number display. */
32531 DEFSYM (Qdisplay_line_numbers_disable
, "display-line-numbers-disable");
32533 /* Name and number of the face used to highlight escape glyphs. */
32534 DEFSYM (Qescape_glyph
, "escape-glyph");
32536 /* Name and number of the face used to highlight non-breaking
32538 DEFSYM (Qnobreak_space
, "nobreak-space");
32539 DEFSYM (Qnobreak_hyphen
, "nobreak-hyphen");
32541 /* The symbol 'image' which is the car of the lists used to represent
32542 images in Lisp. Also a tool bar style. */
32543 DEFSYM (Qimage
, "image");
32545 /* Tool bar styles. */
32546 DEFSYM (Qtext
, "text");
32547 DEFSYM (Qboth
, "both");
32548 DEFSYM (Qboth_horiz
, "both-horiz");
32549 DEFSYM (Qtext_image_horiz
, "text-image-horiz");
32551 /* The image map types. */
32552 DEFSYM (QCmap
, ":map");
32553 DEFSYM (QCpointer
, ":pointer");
32554 DEFSYM (Qrect
, "rect");
32555 DEFSYM (Qcircle
, "circle");
32556 DEFSYM (Qpoly
, "poly");
32558 DEFSYM (Qinhibit_menubar_update
, "inhibit-menubar-update");
32560 DEFSYM (Qgrow_only
, "grow-only");
32561 DEFSYM (Qinhibit_eval_during_redisplay
, "inhibit-eval-during-redisplay");
32562 DEFSYM (Qposition
, "position");
32563 DEFSYM (Qbuffer_position
, "buffer-position");
32564 DEFSYM (Qobject
, "object");
32566 /* Cursor shapes. */
32567 DEFSYM (Qbar
, "bar");
32568 DEFSYM (Qhbar
, "hbar");
32569 DEFSYM (Qbox
, "box");
32570 DEFSYM (Qhollow
, "hollow");
32572 /* Pointer shapes. */
32573 DEFSYM (Qhand
, "hand");
32574 DEFSYM (Qarrow
, "arrow");
32577 DEFSYM (Qdragging
, "dragging");
32579 DEFSYM (Qinhibit_free_realized_faces
, "inhibit-free-realized-faces");
32581 list_of_error
= list1 (list2 (Qerror
, Qvoid_variable
));
32582 staticpro (&list_of_error
);
32584 /* Values of those variables at last redisplay are stored as
32585 properties on 'overlay-arrow-position' symbol. However, if
32586 Voverlay_arrow_position is a marker, last-arrow-position is its
32587 numerical position. */
32588 DEFSYM (Qlast_arrow_position
, "last-arrow-position");
32589 DEFSYM (Qlast_arrow_string
, "last-arrow-string");
32591 /* Alternative overlay-arrow-string and overlay-arrow-bitmap
32592 properties on a symbol in overlay-arrow-variable-list. */
32593 DEFSYM (Qoverlay_arrow_string
, "overlay-arrow-string");
32594 DEFSYM (Qoverlay_arrow_bitmap
, "overlay-arrow-bitmap");
32596 echo_buffer
[0] = echo_buffer
[1] = Qnil
;
32597 staticpro (&echo_buffer
[0]);
32598 staticpro (&echo_buffer
[1]);
32600 echo_area_buffer
[0] = echo_area_buffer
[1] = Qnil
;
32601 staticpro (&echo_area_buffer
[0]);
32602 staticpro (&echo_area_buffer
[1]);
32604 Vmessages_buffer_name
= build_pure_c_string ("*Messages*");
32605 staticpro (&Vmessages_buffer_name
);
32607 mode_line_proptrans_alist
= Qnil
;
32608 staticpro (&mode_line_proptrans_alist
);
32609 mode_line_string_list
= Qnil
;
32610 staticpro (&mode_line_string_list
);
32611 mode_line_string_face
= Qnil
;
32612 staticpro (&mode_line_string_face
);
32613 mode_line_string_face_prop
= Qnil
;
32614 staticpro (&mode_line_string_face_prop
);
32615 Vmode_line_unwind_vector
= Qnil
;
32616 staticpro (&Vmode_line_unwind_vector
);
32618 DEFSYM (Qmode_line_default_help_echo
, "mode-line-default-help-echo");
32620 help_echo_string
= Qnil
;
32621 staticpro (&help_echo_string
);
32622 help_echo_object
= Qnil
;
32623 staticpro (&help_echo_object
);
32624 help_echo_window
= Qnil
;
32625 staticpro (&help_echo_window
);
32626 previous_help_echo_string
= Qnil
;
32627 staticpro (&previous_help_echo_string
);
32628 help_echo_pos
= -1;
32630 DEFSYM (Qright_to_left
, "right-to-left");
32631 DEFSYM (Qleft_to_right
, "left-to-right");
32632 defsubr (&Sbidi_resolved_levels
);
32634 #ifdef HAVE_WINDOW_SYSTEM
32635 DEFVAR_BOOL ("x-stretch-cursor", x_stretch_cursor_p
,
32636 doc
: /* Non-nil means draw block cursor as wide as the glyph under it.
32637 For example, if a block cursor is over a tab, it will be drawn as
32638 wide as that tab on the display. */);
32639 x_stretch_cursor_p
= 0;
32642 DEFVAR_LISP ("show-trailing-whitespace", Vshow_trailing_whitespace
,
32643 doc
: /* Non-nil means highlight trailing whitespace.
32644 The face used for trailing whitespace is `trailing-whitespace'. */);
32645 Vshow_trailing_whitespace
= Qnil
;
32647 DEFVAR_LISP ("nobreak-char-display", Vnobreak_char_display
,
32648 doc
: /* Control highlighting of non-ASCII space and hyphen chars.
32649 If the value is t, Emacs highlights non-ASCII chars which have the
32650 same appearance as an ASCII space or hyphen, using the `nobreak-space'
32651 or `nobreak-hyphen' face respectively.
32653 U+00A0 (no-break space), U+00AD (soft hyphen), U+2010 (hyphen), and
32654 U+2011 (non-breaking hyphen) are affected.
32656 Any other non-nil value means to display these characters as an escape
32657 glyph followed by an ordinary space or hyphen.
32659 A value of nil means no special handling of these characters. */);
32660 Vnobreak_char_display
= Qt
;
32662 DEFVAR_LISP ("void-text-area-pointer", Vvoid_text_area_pointer
,
32663 doc
: /* The pointer shape to show in void text areas.
32664 A value of nil means to show the text pointer. Other options are
32665 `arrow', `text', `hand', `vdrag', `hdrag', `nhdrag', `modeline', and
32667 Vvoid_text_area_pointer
= Qarrow
;
32669 DEFVAR_LISP ("inhibit-redisplay", Vinhibit_redisplay
,
32670 doc
: /* Non-nil means don't actually do any redisplay.
32671 This is used for internal purposes. */);
32672 Vinhibit_redisplay
= Qnil
;
32674 DEFVAR_LISP ("global-mode-string", Vglobal_mode_string
,
32675 doc
: /* String (or mode line construct) included (normally) in `mode-line-format'. */);
32676 Vglobal_mode_string
= Qnil
;
32678 DEFVAR_LISP ("overlay-arrow-position", Voverlay_arrow_position
,
32679 doc
: /* Marker for where to display an arrow on top of the buffer text.
32680 This must be the beginning of a line in order to work.
32681 See also `overlay-arrow-string'. */);
32682 Voverlay_arrow_position
= Qnil
;
32684 DEFVAR_LISP ("overlay-arrow-string", Voverlay_arrow_string
,
32685 doc
: /* String to display as an arrow in non-window frames.
32686 See also `overlay-arrow-position'. */);
32687 Voverlay_arrow_string
= build_pure_c_string ("=>");
32689 DEFVAR_LISP ("overlay-arrow-variable-list", Voverlay_arrow_variable_list
,
32690 doc
: /* List of variables (symbols) which hold markers for overlay arrows.
32691 The symbols on this list are examined during redisplay to determine
32692 where to display overlay arrows. */);
32693 Voverlay_arrow_variable_list
32694 = list1 (intern_c_string ("overlay-arrow-position"));
32696 DEFVAR_INT ("scroll-step", emacs_scroll_step
,
32697 doc
: /* The number of lines to try scrolling a window by when point moves out.
32698 If that fails to bring point back on frame, point is centered instead.
32699 If this is zero, point is always centered after it moves off frame.
32700 If you want scrolling to always be a line at a time, you should set
32701 `scroll-conservatively' to a large value rather than set this to 1. */);
32703 DEFVAR_INT ("scroll-conservatively", scroll_conservatively
,
32704 doc
: /* Scroll up to this many lines, to bring point back on screen.
32705 If point moves off-screen, redisplay will scroll by up to
32706 `scroll-conservatively' lines in order to bring point just barely
32707 onto the screen again. If that cannot be done, then redisplay
32708 recenters point as usual.
32710 If the value is greater than 100, redisplay will never recenter point,
32711 but will always scroll just enough text to bring point into view, even
32712 if you move far away.
32714 A value of zero means always recenter point if it moves off screen. */);
32715 scroll_conservatively
= 0;
32717 DEFVAR_INT ("scroll-margin", scroll_margin
,
32718 doc
: /* Number of lines of margin at the top and bottom of a window.
32719 Trigger automatic scrolling whenever point gets within this many lines
32720 of the top or bottom of the window (see info node `Auto Scrolling'). */);
32723 DEFVAR_LISP ("maximum-scroll-margin", Vmaximum_scroll_margin
,
32724 doc
: /* Maximum effective value of `scroll-margin'.
32725 Given as a fraction of the current window's lines. The value should
32726 be a floating point number between 0.0 and 0.5. The effective maximum
32727 is limited to (/ (1- window-lines) 2). Non-float values for this
32728 variable are ignored and the default 0.25 is used instead. */);
32729 Vmaximum_scroll_margin
= make_float (0.25);
32731 DEFVAR_LISP ("display-pixels-per-inch", Vdisplay_pixels_per_inch
,
32732 doc
: /* Pixels per inch value for non-window system displays.
32733 Value is a number or a cons (WIDTH-DPI . HEIGHT-DPI). */);
32734 Vdisplay_pixels_per_inch
= make_float (72.0);
32737 DEFVAR_INT ("debug-end-pos", debug_end_pos
, doc
: /* Don't ask. */);
32740 DEFVAR_LISP ("truncate-partial-width-windows",
32741 Vtruncate_partial_width_windows
,
32742 doc
: /* Non-nil means truncate lines in windows narrower than the frame.
32743 For an integer value, truncate lines in each window narrower than the
32744 full frame width, provided the total window width in column units is less
32745 than that integer; otherwise, respect the value of `truncate-lines'.
32746 The total width of the window is as returned by `window-total-width', it
32747 includes the fringes, the continuation and truncation glyphs, the
32748 display margins (if any), and the scroll bar
32750 For any other non-nil value, truncate lines in all windows that do
32751 not span the full frame width.
32753 A value of nil means to respect the value of `truncate-lines'.
32755 If `word-wrap' is enabled, you might want to reduce this. */);
32756 Vtruncate_partial_width_windows
= make_number (50);
32758 DEFVAR_LISP ("line-number-display-limit", Vline_number_display_limit
,
32759 doc
: /* Maximum buffer size for which line number should be displayed.
32760 If the buffer is bigger than this, the line number does not appear
32761 in the mode line. A value of nil means no limit. */);
32762 Vline_number_display_limit
= Qnil
;
32764 DEFVAR_INT ("line-number-display-limit-width",
32765 line_number_display_limit_width
,
32766 doc
: /* Maximum line width (in characters) for line number display.
32767 If the average length of the lines near point is bigger than this, then the
32768 line number may be omitted from the mode line. */);
32769 line_number_display_limit_width
= 200;
32771 DEFVAR_BOOL ("highlight-nonselected-windows", highlight_nonselected_windows
,
32772 doc
: /* Non-nil means highlight region even in nonselected windows. */);
32773 highlight_nonselected_windows
= false;
32775 DEFVAR_BOOL ("multiple-frames", multiple_frames
,
32776 doc
: /* Non-nil if more than one frame is visible on this display.
32777 Minibuffer-only frames don't count, but iconified frames do.
32778 This variable is not guaranteed to be accurate except while processing
32779 `frame-title-format' and `icon-title-format'. */);
32781 DEFVAR_LISP ("frame-title-format", Vframe_title_format
,
32782 doc
: /* Template for displaying the title bar of visible frames.
32783 \(Assuming the window manager supports this feature.)
32785 This variable has the same structure as `mode-line-format', except that
32786 the %c, %C, and %l constructs are ignored. It is used only on frames for
32787 which no explicit name has been set (see `modify-frame-parameters'). */);
32789 DEFVAR_LISP ("icon-title-format", Vicon_title_format
,
32790 doc
: /* Template for displaying the title bar of an iconified frame.
32791 \(Assuming the window manager supports this feature.)
32792 This variable has the same structure as `mode-line-format' (which see),
32793 and is used only on frames for which no explicit name has been set
32794 \(see `modify-frame-parameters'). */);
32796 = Vframe_title_format
32797 = listn (CONSTYPE_PURE
, 3,
32798 intern_c_string ("multiple-frames"),
32799 build_pure_c_string ("%b"),
32800 listn (CONSTYPE_PURE
, 4,
32801 empty_unibyte_string
,
32802 intern_c_string ("invocation-name"),
32803 build_pure_c_string ("@"),
32804 intern_c_string ("system-name")));
32806 DEFVAR_LISP ("message-log-max", Vmessage_log_max
,
32807 doc
: /* Maximum number of lines to keep in the message log buffer.
32808 If nil, disable message logging. If t, log messages but don't truncate
32809 the buffer when it becomes large. */);
32810 Vmessage_log_max
= make_number (1000);
32812 DEFVAR_LISP ("window-scroll-functions", Vwindow_scroll_functions
,
32813 doc
: /* List of functions to call before redisplaying a window with scrolling.
32814 Each function is called with two arguments, the window and its new
32815 display-start position.
32816 These functions are called whenever the `window-start' marker is modified,
32817 either to point into another buffer (e.g. via `set-window-buffer') or another
32818 place in the same buffer.
32819 When each function is called, the `window-start' marker of its window
32820 argument has been already set to the new value, and the buffer which that
32821 window will display is set to be the current buffer.
32822 Note that the value of `window-end' is not valid when these functions are
32825 Warning: Do not use this feature to alter the way the window
32826 is scrolled. It is not designed for that, and such use probably won't
32828 Vwindow_scroll_functions
= Qnil
;
32830 DEFVAR_LISP ("redisplay-end-trigger-functions", Vredisplay_end_trigger_functions
,
32831 doc
: /* Functions called when redisplay of a window reaches the end trigger.
32832 Each function is called with two arguments, the window and the end trigger value.
32833 See `set-window-redisplay-end-trigger'. */);
32834 Vredisplay_end_trigger_functions
= Qnil
;
32836 DEFVAR_LISP ("mouse-autoselect-window", Vmouse_autoselect_window
,
32837 doc
: /* Non-nil means autoselect window with mouse pointer.
32838 If nil, do not autoselect windows.
32839 A positive number means delay autoselection by that many seconds: a
32840 window is autoselected only after the mouse has remained in that
32841 window for the duration of the delay.
32842 A negative number has a similar effect, but causes windows to be
32843 autoselected only after the mouse has stopped moving. (Because of
32844 the way Emacs compares mouse events, you will occasionally wait twice
32845 that time before the window gets selected.)
32846 Any other value means to autoselect window instantaneously when the
32847 mouse pointer enters it.
32849 Autoselection selects the minibuffer only if it is active, and never
32850 unselects the minibuffer if it is active.
32852 When customizing this variable make sure that the actual value of
32853 `focus-follows-mouse' matches the behavior of your window manager. */);
32854 Vmouse_autoselect_window
= Qnil
;
32856 DEFVAR_LISP ("auto-resize-tool-bars", Vauto_resize_tool_bars
,
32857 doc
: /* Non-nil means automatically resize tool-bars.
32858 This dynamically changes the tool-bar's height to the minimum height
32859 that is needed to make all tool-bar items visible.
32860 If value is `grow-only', the tool-bar's height is only increased
32861 automatically; to decrease the tool-bar height, use \\[recenter]. */);
32862 Vauto_resize_tool_bars
= Qt
;
32864 DEFVAR_BOOL ("auto-raise-tool-bar-buttons", auto_raise_tool_bar_buttons_p
,
32865 doc
: /* Non-nil means raise tool-bar buttons when the mouse moves over them. */);
32866 auto_raise_tool_bar_buttons_p
= true;
32868 DEFVAR_BOOL ("make-cursor-line-fully-visible", make_cursor_line_fully_visible_p
,
32869 doc
: /* Non-nil means to scroll (recenter) cursor line if it is not fully visible. */);
32870 make_cursor_line_fully_visible_p
= true;
32872 DEFVAR_LISP ("tool-bar-border", Vtool_bar_border
,
32873 doc
: /* Border below tool-bar in pixels.
32874 If an integer, use it as the height of the border.
32875 If it is one of `internal-border-width' or `border-width', use the
32876 value of the corresponding frame parameter.
32877 Otherwise, no border is added below the tool-bar. */);
32878 Vtool_bar_border
= Qinternal_border_width
;
32880 DEFVAR_LISP ("tool-bar-button-margin", Vtool_bar_button_margin
,
32881 doc
: /* Margin around tool-bar buttons in pixels.
32882 If an integer, use that for both horizontal and vertical margins.
32883 Otherwise, value should be a pair of integers `(HORZ . VERT)' with
32884 HORZ specifying the horizontal margin, and VERT specifying the
32885 vertical margin. */);
32886 Vtool_bar_button_margin
= make_number (DEFAULT_TOOL_BAR_BUTTON_MARGIN
);
32888 DEFVAR_INT ("tool-bar-button-relief", tool_bar_button_relief
,
32889 doc
: /* Relief thickness of tool-bar buttons. */);
32890 tool_bar_button_relief
= DEFAULT_TOOL_BAR_BUTTON_RELIEF
;
32892 DEFVAR_LISP ("tool-bar-style", Vtool_bar_style
,
32893 doc
: /* Tool bar style to use.
32895 image - show images only
32896 text - show text only
32897 both - show both, text below image
32898 both-horiz - show text to the right of the image
32899 text-image-horiz - show text to the left of the image
32900 any other - use system default or image if no system default.
32902 This variable only affects the GTK+ toolkit version of Emacs. */);
32903 Vtool_bar_style
= Qnil
;
32905 DEFVAR_INT ("tool-bar-max-label-size", tool_bar_max_label_size
,
32906 doc
: /* Maximum number of characters a label can have to be shown.
32907 The tool bar style must also show labels for this to have any effect, see
32908 `tool-bar-style'. */);
32909 tool_bar_max_label_size
= DEFAULT_TOOL_BAR_LABEL_SIZE
;
32911 DEFVAR_LISP ("fontification-functions", Vfontification_functions
,
32912 doc
: /* List of functions to call to fontify regions of text.
32913 Each function is called with one argument POS. Functions must
32914 fontify a region starting at POS in the current buffer, and give
32915 fontified regions the property `fontified'. */);
32916 Vfontification_functions
= Qnil
;
32917 Fmake_variable_buffer_local (Qfontification_functions
);
32919 DEFVAR_BOOL ("unibyte-display-via-language-environment",
32920 unibyte_display_via_language_environment
,
32921 doc
: /* Non-nil means display unibyte text according to language environment.
32922 Specifically, this means that raw bytes in the range 160-255 decimal
32923 are displayed by converting them to the equivalent multibyte characters
32924 according to the current language environment. As a result, they are
32925 displayed according to the current fontset.
32927 Note that this variable affects only how these bytes are displayed,
32928 but does not change the fact they are interpreted as raw bytes. */);
32929 unibyte_display_via_language_environment
= false;
32931 DEFVAR_LISP ("max-mini-window-height", Vmax_mini_window_height
,
32932 doc
: /* Maximum height for resizing mini-windows (the minibuffer and the echo area).
32933 If a float, it specifies a fraction of the mini-window frame's height.
32934 If an integer, it specifies a number of lines. */);
32935 Vmax_mini_window_height
= make_float (0.25);
32937 DEFVAR_LISP ("resize-mini-windows", Vresize_mini_windows
,
32938 doc
: /* How to resize mini-windows (the minibuffer and the echo area).
32939 A value of nil means don't automatically resize mini-windows.
32940 A value of t means resize them to fit the text displayed in them.
32941 A value of `grow-only', the default, means let mini-windows grow only;
32942 they return to their normal size when the minibuffer is closed, or the
32943 echo area becomes empty. */);
32944 /* Contrary to the doc string, we initialize this to nil, so that
32945 loading loadup.el won't try to resize windows before loading
32946 window.el, where some functions we need to call for this live.
32947 We assign the 'grow-only' value right after loading window.el
32949 Vresize_mini_windows
= Qnil
;
32951 DEFVAR_LISP ("blink-cursor-alist", Vblink_cursor_alist
,
32952 doc
: /* Alist specifying how to blink the cursor off.
32953 Each element has the form (ON-STATE . OFF-STATE). Whenever the
32954 `cursor-type' frame-parameter or variable equals ON-STATE,
32955 comparing using `equal', Emacs uses OFF-STATE to specify
32956 how to blink it off. ON-STATE and OFF-STATE are values for
32957 the `cursor-type' frame parameter.
32959 If a frame's ON-STATE has no entry in this list,
32960 the frame's other specifications determine how to blink the cursor off. */);
32961 Vblink_cursor_alist
= Qnil
;
32963 DEFVAR_LISP ("auto-hscroll-mode", automatic_hscrolling
,
32964 doc
: /* Allow or disallow automatic horizontal scrolling of windows.
32965 The value `current-line' means the line displaying point in each window
32966 is automatically scrolled horizontally to make point visible.
32967 Any other non-nil value means all the lines in a window are automatically
32968 scrolled horizontally to make point visible. */);
32969 automatic_hscrolling
= Qt
;
32970 DEFSYM (Qauto_hscroll_mode
, "auto-hscroll-mode");
32971 DEFSYM (Qcurrent_line
, "current-line");
32973 DEFVAR_INT ("hscroll-margin", hscroll_margin
,
32974 doc
: /* How many columns away from the window edge point is allowed to get
32975 before automatic hscrolling will horizontally scroll the window. */);
32976 hscroll_margin
= 5;
32978 DEFVAR_LISP ("hscroll-step", Vhscroll_step
,
32979 doc
: /* How many columns to scroll the window when point gets too close to the edge.
32980 When point is less than `hscroll-margin' columns from the window
32981 edge, automatic hscrolling will scroll the window by the amount of columns
32982 determined by this variable. If its value is a positive integer, scroll that
32983 many columns. If it's a positive floating-point number, it specifies the
32984 fraction of the window's width to scroll. If it's nil or zero, point will be
32985 centered horizontally after the scroll. Any other value, including negative
32986 numbers, are treated as if the value were zero.
32988 Automatic hscrolling always moves point outside the scroll margin, so if
32989 point was more than scroll step columns inside the margin, the window will
32990 scroll more than the value given by the scroll step.
32992 Note that the lower bound for automatic hscrolling specified by `scroll-left'
32993 and `scroll-right' overrides this variable's effect. */);
32994 Vhscroll_step
= make_number (0);
32996 DEFVAR_BOOL ("message-truncate-lines", message_truncate_lines
,
32997 doc
: /* If non-nil, messages are truncated instead of resizing the echo area.
32998 Bind this around calls to `message' to let it take effect. */);
32999 message_truncate_lines
= false;
33001 DEFVAR_LISP ("menu-bar-update-hook", Vmenu_bar_update_hook
,
33002 doc
: /* Normal hook run to update the menu bar definitions.
33003 Redisplay runs this hook before it redisplays the menu bar.
33004 This is used to update menus such as Buffers, whose contents depend on
33006 Vmenu_bar_update_hook
= Qnil
;
33008 DEFVAR_LISP ("menu-updating-frame", Vmenu_updating_frame
,
33009 doc
: /* Frame for which we are updating a menu.
33010 The enable predicate for a menu binding should check this variable. */);
33011 Vmenu_updating_frame
= Qnil
;
33013 DEFVAR_BOOL ("inhibit-menubar-update", inhibit_menubar_update
,
33014 doc
: /* Non-nil means don't update menu bars. Internal use only. */);
33015 inhibit_menubar_update
= false;
33017 DEFVAR_LISP ("wrap-prefix", Vwrap_prefix
,
33018 doc
: /* Prefix prepended to all continuation lines at display time.
33019 The value may be a string, an image, or a stretch-glyph; it is
33020 interpreted in the same way as the value of a `display' text property.
33022 This variable is overridden by any `wrap-prefix' text or overlay
33025 To add a prefix to non-continuation lines, use `line-prefix'. */);
33026 Vwrap_prefix
= Qnil
;
33027 DEFSYM (Qwrap_prefix
, "wrap-prefix");
33028 Fmake_variable_buffer_local (Qwrap_prefix
);
33030 DEFVAR_LISP ("line-prefix", Vline_prefix
,
33031 doc
: /* Prefix prepended to all non-continuation lines at display time.
33032 The value may be a string, an image, or a stretch-glyph; it is
33033 interpreted in the same way as the value of a `display' text property.
33035 This variable is overridden by any `line-prefix' text or overlay
33038 To add a prefix to continuation lines, use `wrap-prefix'. */);
33039 Vline_prefix
= Qnil
;
33040 DEFSYM (Qline_prefix
, "line-prefix");
33041 Fmake_variable_buffer_local (Qline_prefix
);
33043 DEFVAR_LISP ("display-line-numbers", Vdisplay_line_numbers
,
33044 doc
: /* Non-nil means display line numbers.
33045 If the value is t, display the absolute number of each line of a buffer
33046 shown in a window. Absolute line numbers count from the beginning of
33047 the current narrowing, or from buffer beginning. If the value is
33048 `relative', display for each line not containing the window's point its
33049 relative number instead, i.e. the number of the line relative to the
33050 line showing the window's point.
33052 In either case, line numbers are displayed at the beginning of each
33053 non-continuation line that displays buffer text, i.e. after each newline
33054 character that comes from the buffer. The value `visual' is like
33055 `relative' but counts screen lines instead of buffer lines. In practice
33056 this means that continuation lines count as well when calculating the
33057 relative number of a line.
33059 Lisp programs can disable display of a line number of a particular
33060 buffer line by putting the `display-line-numbers-disable' text property
33061 or overlay property on the first visible character of that line. */);
33062 Vdisplay_line_numbers
= Qnil
;
33063 DEFSYM (Qdisplay_line_numbers
, "display-line-numbers");
33064 Fmake_variable_buffer_local (Qdisplay_line_numbers
);
33065 DEFSYM (Qrelative
, "relative");
33066 DEFSYM (Qvisual
, "visual");
33068 DEFVAR_LISP ("display-line-numbers-width", Vdisplay_line_numbers_width
,
33069 doc
: /* Minimum width of space reserved for line number display.
33070 A positive number means reserve that many columns for line numbers,
33071 even if the actual number needs less space.
33072 The default value of nil means compute the space dynamically.
33073 Any other value is treated as nil. */);
33074 Vdisplay_line_numbers_width
= Qnil
;
33075 DEFSYM (Qdisplay_line_numbers_width
, "display-line-numbers-width");
33076 Fmake_variable_buffer_local (Qdisplay_line_numbers_width
);
33078 DEFVAR_LISP ("display-line-numbers-current-absolute",
33079 Vdisplay_line_numbers_current_absolute
,
33080 doc
: /* Non-nil means display absolute number of current line.
33081 This variable has effect only when `display-line-numbers' is
33082 either `relative' or `visual'. */);
33083 Vdisplay_line_numbers_current_absolute
= Qt
;
33085 DEFVAR_BOOL ("display-line-numbers-widen", display_line_numbers_widen
,
33086 doc
: /* Non-nil means display line numbers disregarding any narrowing. */);
33087 display_line_numbers_widen
= false;
33088 DEFSYM (Qdisplay_line_numbers_widen
, "display-line-numbers-widen");
33089 Fmake_variable_buffer_local (Qdisplay_line_numbers_widen
);
33091 DEFVAR_BOOL ("inhibit-eval-during-redisplay", inhibit_eval_during_redisplay
,
33092 doc
: /* Non-nil means don't eval Lisp during redisplay. */);
33093 inhibit_eval_during_redisplay
= false;
33095 DEFVAR_BOOL ("inhibit-free-realized-faces", inhibit_free_realized_faces
,
33096 doc
: /* Non-nil means don't free realized faces. Internal use only. */);
33097 inhibit_free_realized_faces
= false;
33099 DEFVAR_BOOL ("inhibit-bidi-mirroring", inhibit_bidi_mirroring
,
33100 doc
: /* Non-nil means don't mirror characters even when bidi context requires that.
33101 Intended for use during debugging and for testing bidi display;
33102 see biditest.el in the test suite. */);
33103 inhibit_bidi_mirroring
= false;
33106 DEFVAR_BOOL ("inhibit-try-window-id", inhibit_try_window_id
,
33107 doc
: /* Inhibit try_window_id display optimization. */);
33108 inhibit_try_window_id
= false;
33110 DEFVAR_BOOL ("inhibit-try-window-reusing", inhibit_try_window_reusing
,
33111 doc
: /* Inhibit try_window_reusing display optimization. */);
33112 inhibit_try_window_reusing
= false;
33114 DEFVAR_BOOL ("inhibit-try-cursor-movement", inhibit_try_cursor_movement
,
33115 doc
: /* Inhibit try_cursor_movement display optimization. */);
33116 inhibit_try_cursor_movement
= false;
33117 #endif /* GLYPH_DEBUG */
33119 DEFVAR_INT ("overline-margin", overline_margin
,
33120 doc
: /* Space between overline and text, in pixels.
33121 The default value is 2: the height of the overline (1 pixel) plus 1 pixel
33122 margin to the character height. */);
33123 overline_margin
= 2;
33125 DEFVAR_INT ("underline-minimum-offset",
33126 underline_minimum_offset
,
33127 doc
: /* Minimum distance between baseline and underline.
33128 This can improve legibility of underlined text at small font sizes,
33129 particularly when using variable `x-use-underline-position-properties'
33130 with fonts that specify an UNDERLINE_POSITION relatively close to the
33131 baseline. The default value is 1. */);
33132 underline_minimum_offset
= 1;
33133 DEFSYM (Qunderline_minimum_offset
, "underline-minimum-offset");
33135 DEFVAR_BOOL ("display-hourglass", display_hourglass_p
,
33136 doc
: /* Non-nil means show an hourglass pointer, when Emacs is busy.
33137 This feature only works when on a window system that can change
33138 cursor shapes. */);
33139 display_hourglass_p
= true;
33141 DEFVAR_LISP ("hourglass-delay", Vhourglass_delay
,
33142 doc
: /* Seconds to wait before displaying an hourglass pointer when Emacs is busy. */);
33143 Vhourglass_delay
= make_number (DEFAULT_HOURGLASS_DELAY
);
33145 #ifdef HAVE_WINDOW_SYSTEM
33146 hourglass_atimer
= NULL
;
33147 hourglass_shown_p
= false;
33148 #endif /* HAVE_WINDOW_SYSTEM */
33150 /* Name of the face used to display glyphless characters. */
33151 DEFSYM (Qglyphless_char
, "glyphless-char");
33153 /* Method symbols for Vglyphless_char_display. */
33154 DEFSYM (Qhex_code
, "hex-code");
33155 DEFSYM (Qempty_box
, "empty-box");
33156 DEFSYM (Qthin_space
, "thin-space");
33157 DEFSYM (Qzero_width
, "zero-width");
33159 DEFVAR_LISP ("pre-redisplay-function", Vpre_redisplay_function
,
33160 doc
: /* Function run just before redisplay.
33161 It is called with one argument, which is the set of windows that are to
33162 be redisplayed. This set can be nil (meaning, only the selected window),
33163 or t (meaning all windows). */);
33164 Vpre_redisplay_function
= intern ("ignore");
33166 /* Symbol for the purpose of Vglyphless_char_display. */
33167 DEFSYM (Qglyphless_char_display
, "glyphless-char-display");
33168 Fput (Qglyphless_char_display
, Qchar_table_extra_slots
, make_number (1));
33170 DEFVAR_LISP ("glyphless-char-display", Vglyphless_char_display
,
33171 doc
: /* Char-table defining glyphless characters.
33172 Each element, if non-nil, should be one of the following:
33173 an ASCII acronym string: display this string in a box
33174 `hex-code': display the hexadecimal code of a character in a box
33175 `empty-box': display as an empty box
33176 `thin-space': display as 1-pixel width space
33177 `zero-width': don't display
33178 An element may also be a cons cell (GRAPHICAL . TEXT), which specifies the
33179 display method for graphical terminals and text terminals respectively.
33180 GRAPHICAL and TEXT should each have one of the values listed above.
33182 The char-table has one extra slot to control the display of a character for
33183 which no font is found. This slot only takes effect on graphical terminals.
33184 Its value should be an ASCII acronym string, `hex-code', `empty-box', or
33185 `thin-space'. The default is `empty-box'.
33187 If a character has a non-nil entry in an active display table, the
33188 display table takes effect; in this case, Emacs does not consult
33189 `glyphless-char-display' at all. */);
33190 Vglyphless_char_display
= Fmake_char_table (Qglyphless_char_display
, Qnil
);
33191 Fset_char_table_extra_slot (Vglyphless_char_display
, make_number (0),
33194 DEFVAR_LISP ("debug-on-message", Vdebug_on_message
,
33195 doc
: /* If non-nil, debug if a message matching this regexp is displayed. */);
33196 Vdebug_on_message
= Qnil
;
33198 DEFVAR_LISP ("redisplay--all-windows-cause", Vredisplay__all_windows_cause
,
33200 Vredisplay__all_windows_cause
= Fmake_hash_table (0, NULL
);
33202 DEFVAR_LISP ("redisplay--mode-lines-cause", Vredisplay__mode_lines_cause
,
33204 Vredisplay__mode_lines_cause
= Fmake_hash_table (0, NULL
);
33206 DEFVAR_BOOL ("redisplay--inhibit-bidi", redisplay__inhibit_bidi
,
33207 doc
: /* Non-nil means it is not safe to attempt bidi reordering for display. */);
33208 /* Initialize to t, since we need to disable reordering until
33209 loadup.el successfully loads charprop.el. */
33210 redisplay__inhibit_bidi
= true;
33212 DEFVAR_BOOL ("display-raw-bytes-as-hex", display_raw_bytes_as_hex
,
33213 doc
: /* Non-nil means display raw bytes in hexadecimal format.
33214 The default is to use octal format (\200) whereas hexadecimal (\x80)
33215 may be more familiar to users. */);
33216 display_raw_bytes_as_hex
= false;
33221 /* Initialize this module when Emacs starts. */
33226 CHARPOS (this_line_start_pos
) = 0;
33228 if (!noninteractive
)
33230 struct window
*m
= XWINDOW (minibuf_window
);
33231 Lisp_Object frame
= m
->frame
;
33232 struct frame
*f
= XFRAME (frame
);
33233 Lisp_Object root
= FRAME_ROOT_WINDOW (f
);
33234 struct window
*r
= XWINDOW (root
);
33237 echo_area_window
= minibuf_window
;
33239 r
->top_line
= FRAME_TOP_MARGIN (f
);
33240 r
->pixel_top
= r
->top_line
* FRAME_LINE_HEIGHT (f
);
33241 r
->total_cols
= FRAME_COLS (f
);
33242 r
->pixel_width
= r
->total_cols
* FRAME_COLUMN_WIDTH (f
);
33243 r
->total_lines
= FRAME_TOTAL_LINES (f
) - 1 - FRAME_TOP_MARGIN (f
);
33244 r
->pixel_height
= r
->total_lines
* FRAME_LINE_HEIGHT (f
);
33246 m
->top_line
= FRAME_TOTAL_LINES (f
) - 1;
33247 m
->pixel_top
= m
->top_line
* FRAME_LINE_HEIGHT (f
);
33248 m
->total_cols
= FRAME_COLS (f
);
33249 m
->pixel_width
= m
->total_cols
* FRAME_COLUMN_WIDTH (f
);
33250 m
->total_lines
= 1;
33251 m
->pixel_height
= m
->total_lines
* FRAME_LINE_HEIGHT (f
);
33253 scratch_glyph_row
.glyphs
[TEXT_AREA
] = scratch_glyphs
;
33254 scratch_glyph_row
.glyphs
[TEXT_AREA
+ 1]
33255 = scratch_glyphs
+ MAX_SCRATCH_GLYPHS
;
33257 /* The default ellipsis glyphs `...'. */
33258 for (i
= 0; i
< 3; ++i
)
33259 default_invis_vector
[i
] = make_number ('.');
33263 /* Allocate the buffer for frame titles.
33264 Also used for `format-mode-line'. */
33266 mode_line_noprop_buf
= xmalloc (size
);
33267 mode_line_noprop_buf_end
= mode_line_noprop_buf
+ size
;
33268 mode_line_noprop_ptr
= mode_line_noprop_buf
;
33269 mode_line_target
= MODE_LINE_DISPLAY
;
33272 help_echo_showing_p
= false;
33275 #ifdef HAVE_WINDOW_SYSTEM
33277 /* Platform-independent portion of hourglass implementation. */
33279 /* Timer function of hourglass_atimer. */
33282 show_hourglass (struct atimer
*timer
)
33284 /* The timer implementation will cancel this timer automatically
33285 after this function has run. Set hourglass_atimer to null
33286 so that we know the timer doesn't have to be canceled. */
33287 hourglass_atimer
= NULL
;
33289 if (!hourglass_shown_p
)
33291 Lisp_Object tail
, frame
;
33295 FOR_EACH_FRAME (tail
, frame
)
33297 struct frame
*f
= XFRAME (frame
);
33299 if (FRAME_LIVE_P (f
) && FRAME_WINDOW_P (f
)
33300 && FRAME_RIF (f
)->show_hourglass
)
33301 FRAME_RIF (f
)->show_hourglass (f
);
33304 hourglass_shown_p
= true;
33309 /* Cancel a currently active hourglass timer, and start a new one. */
33312 start_hourglass (void)
33314 struct timespec delay
;
33316 cancel_hourglass ();
33318 if (INTEGERP (Vhourglass_delay
)
33319 && XINT (Vhourglass_delay
) > 0)
33320 delay
= make_timespec (min (XINT (Vhourglass_delay
),
33321 TYPE_MAXIMUM (time_t)),
33323 else if (FLOATP (Vhourglass_delay
)
33324 && XFLOAT_DATA (Vhourglass_delay
) > 0)
33325 delay
= dtotimespec (XFLOAT_DATA (Vhourglass_delay
));
33327 delay
= make_timespec (DEFAULT_HOURGLASS_DELAY
, 0);
33329 hourglass_atimer
= start_atimer (ATIMER_RELATIVE
, delay
,
33330 show_hourglass
, NULL
);
33333 /* Cancel the hourglass cursor timer if active, hide a busy cursor if
33337 cancel_hourglass (void)
33339 if (hourglass_atimer
)
33341 cancel_atimer (hourglass_atimer
);
33342 hourglass_atimer
= NULL
;
33345 if (hourglass_shown_p
)
33347 Lisp_Object tail
, frame
;
33351 FOR_EACH_FRAME (tail
, frame
)
33353 struct frame
*f
= XFRAME (frame
);
33355 if (FRAME_LIVE_P (f
) && FRAME_WINDOW_P (f
)
33356 && FRAME_RIF (f
)->hide_hourglass
)
33357 FRAME_RIF (f
)->hide_hourglass (f
);
33359 /* No cursors on non GUI frames - restore to stock arrow cursor. */
33360 else if (!FRAME_W32_P (f
))
33361 w32_arrow_cursor ();
33365 hourglass_shown_p
= false;
33370 #endif /* HAVE_WINDOW_SYSTEM */