comparison src/redisplay.c @ 4187:26dccfc8fa60

[xemacs-hg @ 2007-09-26 13:27:59 by didierv] More fixes about face indexes
author didierv
date Wed, 26 Sep 2007 13:28:01 +0000
parents 98af8a976fc3
children 62d532188a28
comparison
equal deleted inserted replaced
4186:05dd0ed58262 4187:26dccfc8fa60
159 scrolling, where a certain number of columns 159 scrolling, where a certain number of columns
160 (those off the left side of the screen) need 160 (those off the left side of the screen) need
161 to be skipped before anything is displayed. */ 161 to be skipped before anything is displayed. */
162 Bytexpos byte_start_col_enabled; 162 Bytexpos byte_start_col_enabled;
163 int start_col_xoffset; /* Number of pixels that still need to 163 int start_col_xoffset; /* Number of pixels that still need to
164 be skipped. This is used for 164 be skipped. This is used for
165 horizontal scrolling of glyphs, where we want 165 horizontal scrolling of glyphs, where we want
166 to be able to scroll over part of the glyph. */ 166 to be able to scroll over part of the glyph. */
167 167
168 int hscroll_glyph_width_adjust; /* how much the width of the hscroll 168 int hscroll_glyph_width_adjust; /* how much the width of the hscroll
169 glyph differs from space_width (w). 169 glyph differs from space_width (w).
170 0 if no hscroll glyph was used, 170 0 if no hscroll glyph was used,
171 i.e. the window is not scrolled 171 i.e. the window is not scrolled
196 generating a formatted string in the modeline. */ 196 generating a formatted string in the modeline. */
197 int is_modeline; /* Non-zero if we're generating the modeline. */ 197 int is_modeline; /* Non-zero if we're generating the modeline. */
198 Charcount modeline_charpos; /* Number of chars used in result_str so far; 198 Charcount modeline_charpos; /* Number of chars used in result_str so far;
199 corresponds to bytepos. */ 199 corresponds to bytepos. */
200 Bytecount bytepos; /* Number of bytes used in result_str so far. 200 Bytecount bytepos; /* Number of bytes used in result_str so far.
201 We don't actually copy the bytes into result_str 201 We don't actually copy the bytes into result_str
202 until the end because we don't know how big the 202 until the end because we don't know how big the
203 string is going to be until then. */ 203 string is going to be until then. */
204 } pos_data; 204 } pos_data;
205 205
206 enum prop_type 206 enum prop_type
256 } p_blank; 256 } p_blank;
257 257
258 struct 258 struct
259 { 259 {
260 /* Not used as yet, but could be used to wrap rather than clip glyphs. */ 260 /* Not used as yet, but could be used to wrap rather than clip glyphs. */
261 int width; 261 int width;
262 Lisp_Object glyph; 262 Lisp_Object glyph;
263 } p_glyph; 263 } p_glyph;
264 264
265 } data; 265 } data;
266 }; 266 };
299 static void update_line_start_cache (struct window *w, Charbpos from, 299 static void update_line_start_cache (struct window *w, Charbpos from,
300 Charbpos to, Charbpos point, 300 Charbpos to, Charbpos point,
301 int no_regen); 301 int no_regen);
302 static int point_visible (struct window *w, Charbpos point, int type); 302 static int point_visible (struct window *w, Charbpos point, int type);
303 static void calculate_yoffset (struct display_line *dl, 303 static void calculate_yoffset (struct display_line *dl,
304 struct display_block *fixup); 304 struct display_block *fixup);
305 static void calculate_baseline (pos_data *data); 305 static void calculate_baseline (pos_data *data);
306 306
307 #ifdef ERROR_CHECK_DISPLAY 307 #ifdef ERROR_CHECK_DISPLAY
308 static void sledgehammer_check_redisplay_structs (void); 308 static void sledgehammer_check_redisplay_structs (void);
309 #endif /* ERROR_CHECK_DISPLAY */ 309 #endif /* ERROR_CHECK_DISPLAY */
318 #define REDISPLAY_PREEMPTION_CHECK \ 318 #define REDISPLAY_PREEMPTION_CHECK \
319 ((void) \ 319 ((void) \
320 (preempted = \ 320 (preempted = \
321 (!disable_preemption && \ 321 (!disable_preemption && \
322 ((preemption_count < max_preempts) || !NILP (Vexecuting_macro)) && \ 322 ((preemption_count < max_preempts) || !NILP (Vexecuting_macro)) && \
323 (!INTERACTIVE || \ 323 (!INTERACTIVE || \
324 detect_input_pending (QUEUED_EVENTS_REQUIRED_FOR_PREEMPTION))))) 324 detect_input_pending (QUEUED_EVENTS_REQUIRED_FOR_PREEMPTION)))))
325 325
326 /* 326 /*
327 * Redisplay global variables. 327 * Redisplay global variables.
328 */ 328 */
711 if (Dynarr_at (dl->display_blocks, elt).type == type) 711 if (Dynarr_at (dl->display_blocks, elt).type == type)
712 return Dynarr_atp (dl->display_blocks, elt); 712 return Dynarr_atp (dl->display_blocks, elt);
713 } 713 }
714 714
715 /* There isn't an active block of the desired type, but there 715 /* There isn't an active block of the desired type, but there
716 might still be allocated blocks we need to reuse. */ 716 might still be allocated blocks we need to reuse. */
717 if (elt < Dynarr_largest (dl->display_blocks)) 717 if (elt < Dynarr_largest (dl->display_blocks))
718 { 718 {
719 struct display_block *dbp = Dynarr_atp (dl->display_blocks, elt); 719 struct display_block *dbp = Dynarr_atp (dl->display_blocks, elt);
720 720
721 /* "add" the block to the list */ 721 /* "add" the block to the list */
727 } 727 }
728 } 728 }
729 else 729 else
730 { 730 {
731 /* This line doesn't have any display blocks, so initialize the display 731 /* This line doesn't have any display blocks, so initialize the display
732 bock array. */ 732 bock array. */
733 dl->display_blocks = Dynarr_new (display_block); 733 dl->display_blocks = Dynarr_new (display_block);
734 } 734 }
735 735
736 /* The line doesn't have a block of the desired type so go ahead and create 736 /* The line doesn't have a block of the desired type so go ahead and create
737 one and add it to the line. */ 737 one and add it to the line. */
845 int i; 845 int i;
846 for (i=0; i<Dynarr_length (fixup->runes); i++) 846 for (i=0; i<Dynarr_length (fixup->runes); i++)
847 { 847 {
848 struct rune *r = Dynarr_atp (fixup->runes,i); 848 struct rune *r = Dynarr_atp (fixup->runes,i);
849 if (r->type == RUNE_DGLYPH) 849 if (r->type == RUNE_DGLYPH)
850 { 850 {
851 if (r->object.dglyph.ascent < dl->ascent) 851 if (r->object.dglyph.ascent < dl->ascent)
852 r->object.dglyph.yoffset = dl->ascent - r->object.dglyph.ascent + 852 r->object.dglyph.yoffset = dl->ascent - r->object.dglyph.ascent +
853 r->object.dglyph.descent; 853 r->object.dglyph.descent;
854 } 854 }
855 } 855 }
856 } 856 }
857 857
858 /* Calculate the textual baseline (the ascent and descent values for the 858 /* Calculate the textual baseline (the ascent and descent values for the
859 display_line as a whole). 859 display_line as a whole).
895 /* Blank line: baseline is default font's baseline. */ 895 /* Blank line: baseline is default font's baseline. */
896 896
897 if (!data->new_ascent && !data->new_descent) 897 if (!data->new_ascent && !data->new_descent)
898 { 898 {
899 /* We've got a blank line so initialize these values from the default 899 /* We've got a blank line so initialize these values from the default
900 face. */ 900 face. */
901 default_face_font_info (data->window, &data->new_ascent, 901 default_face_font_info (data->window, &data->new_ascent,
902 &data->new_descent, 0, 0, 0); 902 &data->new_descent, 0, 0, 0);
903 } 903 }
904 904
905 /* No automatically positioned glyphs? Return at once. */ 905 /* No automatically positioned glyphs? Return at once. */
906 if (!data->need_baseline_computation) 906 if (!data->need_baseline_computation)
907 return; 907 return;
908 908
909 /* Is the tallest glyph on the line automatically positioned? 909 /* Is the tallest glyph on the line automatically positioned?
911 and there's enough room for it anyway, we need do no more work. */ 911 and there's enough room for it anyway, we need do no more work. */
912 if (data->max_pixmap_height > data->new_ascent + data->new_descent) 912 if (data->max_pixmap_height > data->new_ascent + data->new_descent)
913 { 913 {
914 int default_font_ascent, default_font_descent, default_font_height; 914 int default_font_ascent, default_font_descent, default_font_height;
915 int scaled_default_font_ascent, scaled_default_font_descent; 915 int scaled_default_font_ascent, scaled_default_font_descent;
916 916
917 default_face_font_info (data->window, &default_font_ascent, 917 default_face_font_info (data->window, &default_font_ascent,
918 &default_font_descent, &default_font_height, 918 &default_font_descent, &default_font_height,
919 0, 0); 919 0, 0);
920 920
921 scaled_default_font_ascent = data->max_pixmap_height * 921 scaled_default_font_ascent = data->max_pixmap_height *
922 default_font_ascent / default_font_height; 922 default_font_ascent / default_font_height;
923 923
924 data->new_ascent = max (data->new_ascent, scaled_default_font_ascent); 924 data->new_ascent = max (data->new_ascent, scaled_default_font_ascent);
925 925
926 /* The ascent may have expanded now. Do we still need to grow the descent, 926 /* The ascent may have expanded now. Do we still need to grow the descent,
927 or are things big enough? 927 or are things big enough?
928 928
929 The +1 caters for the baseline row itself. */ 929 The +1 caters for the baseline row itself. */
930 if (data->max_pixmap_height > data->new_ascent + data->new_descent) 930 if (data->max_pixmap_height > data->new_ascent + data->new_descent)
931 { 931 {
932 scaled_default_font_descent = (data->max_pixmap_height * 932 scaled_default_font_descent = (data->max_pixmap_height *
933 default_font_descent / default_font_height) + 1; 933 default_font_descent / default_font_height) + 1;
934 934
935 data->new_descent = max (data->new_descent, scaled_default_font_descent); 935 data->new_descent = max (data->new_descent, scaled_default_font_descent);
936 } 936 }
937 } 937 }
938 } 938 }
939 939
940 /* Given a display line and a starting position, ensure that the 940 /* Given a display line and a starting position, ensure that the
941 contents of the display line accurately represent the visual 941 contents of the display line accurately represent the visual
1125 if (!fi->proportional_p || data->font_is_bogus) 1125 if (!fi->proportional_p || data->font_is_bogus)
1126 { 1126 {
1127 Ichar ch = data->font_is_bogus ? '~' : data->ch; 1127 Ichar ch = data->font_is_bogus ? '~' : data->ch;
1128 1128
1129 data->last_char_width = 1129 data->last_char_width =
1130 redisplay_text_width_ichar_string (XWINDOW (data->window), 1130 redisplay_text_width_ichar_string (XWINDOW (data->window),
1131 data->findex, &ch, 1); 1131 data->findex, &ch, 1);
1132 } 1132 }
1133 else 1133 else
1134 data->last_char_width = -1; 1134 data->last_char_width = -1;
1135 1135
1300 { 1300 {
1301 /* assert (w != NULL) */ 1301 /* assert (w != NULL) */
1302 prop_block_dynarr *retval; 1302 prop_block_dynarr *retval;
1303 1303
1304 /* If we have still not fully scrolled horizontally, subtract 1304 /* If we have still not fully scrolled horizontally, subtract
1305 the width of this tab and return. */ 1305 the width of this tab and return. */
1306 if (char_tab_width < data->start_col) 1306 if (char_tab_width < data->start_col)
1307 { 1307 {
1308 data->start_col -= char_tab_width; 1308 data->start_col -= char_tab_width;
1309 return NULL; 1309 return NULL;
1310 } 1310 }
1628 /* Else blow it off because someone added a bad entry and we 1628 /* Else blow it off because someone added a bad entry and we
1629 don't have any safe way of signaling an error. Hey, this 1629 don't have any safe way of signaling an error. Hey, this
1630 comment sounds familiar. */ 1630 comment sounds familiar. */
1631 1631
1632 /* #### Still need to add any remaining elements to the 1632 /* #### Still need to add any remaining elements to the
1633 propagation information. */ 1633 propagation information. */
1634 if (prop) 1634 if (prop)
1635 return prop; 1635 return prop;
1636 } 1636 }
1637 } 1637 }
1638 else 1638 else
1720 { 1720 {
1721 struct buffer *buf = 1721 struct buffer *buf =
1722 XBUFFER (WINDOW_BUFFER (XWINDOW (data->window))); 1722 XBUFFER (WINDOW_BUFFER (XWINDOW (data->window)));
1723 /* #### Chuck fix this shit or I'm gonna scream! */ 1723 /* #### Chuck fix this shit or I'm gonna scream! */
1724 if (byte_old_charpos > BYTE_BUF_BEGV (buf)) 1724 if (byte_old_charpos > BYTE_BUF_BEGV (buf))
1725 data->byte_charpos = prev_bytebpos (buf, byte_old_charpos); 1725 data->byte_charpos = prev_bytebpos (buf, byte_old_charpos);
1726 else 1726 else
1727 /* #### is this correct? Does anyone know? 1727 /* #### is this correct? Does anyone know?
1728 Does anyone care? Is this a cheesy hack or what? */ 1728 Does anyone care? Is this a cheesy hack or what? */
1729 data->byte_charpos = BYTE_BUF_BEGV (buf) - 1; 1729 data->byte_charpos = BYTE_BUF_BEGV (buf) - 1;
1730 } 1730 }
1731 } 1731 }
1732 break; 1732 break;
1733 case PROP_BLANK: 1733 case PROP_BLANK:
1734 { 1734 {
1745 1745
1746 if (data->pixpos + data->blank_width > data->max_pixpos) 1746 if (data->pixpos + data->blank_width > data->max_pixpos)
1747 data->blank_width = data->max_pixpos - data->pixpos; 1747 data->blank_width = data->max_pixpos - data->pixpos;
1748 1748
1749 /* We pass a bogus value of char_tab_width. It shouldn't 1749 /* We pass a bogus value of char_tab_width. It shouldn't
1750 matter because unless something is really screwed up 1750 matter because unless something is really screwed up
1751 this call won't cause that arg to be used. */ 1751 this call won't cause that arg to be used. */
1752 add_failed = add_blank_rune (data, XWINDOW (data->window), 0); 1752 add_failed = add_blank_rune (data, XWINDOW (data->window), 0);
1753 1753
1754 /* This can happen in the case where we have a tab which 1754 /* This can happen in the case where we have a tab which
1755 is wider than the window. */ 1755 is wider than the window. */
1756 if (data->blank_width != pb->data.p_blank.width) 1756 if (data->blank_width != pb->data.p_blank.width)
1757 { 1757 {
1758 pb->data.p_blank.width -= data->blank_width; 1758 pb->data.p_blank.width -= data->blank_width;
1759 add_failed = ADD_FAILED; 1759 add_failed = ADD_FAILED;
1760 } 1760 }
1839 if (data->start_col || data->start_col_xoffset) 1839 if (data->start_col || data->start_col_xoffset)
1840 { 1840 {
1841 int glyph_char_width = width / space_width (w); 1841 int glyph_char_width = width / space_width (w);
1842 1842
1843 /* If we still have not fully scrolled horizontally after 1843 /* If we still have not fully scrolled horizontally after
1844 taking into account the width of the glyph, subtract its 1844 taking into account the width of the glyph, subtract its
1845 width and return. */ 1845 width and return. */
1846 if (glyph_char_width < data->start_col) 1846 if (glyph_char_width < data->start_col)
1847 { 1847 {
1848 data->start_col -= glyph_char_width; 1848 data->start_col -= glyph_char_width;
1849 return NULL; 1849 return NULL;
1850 } 1850 }
1877 Otherwise we will loop until the bottom of the window 1877 Otherwise we will loop until the bottom of the window
1878 continually failing to add this glyph because it is wider 1878 continually failing to add this glyph because it is wider
1879 than the window. We could alternatively just completely 1879 than the window. We could alternatively just completely
1880 ignore the glyph and proceed from there but I think that 1880 ignore the glyph and proceed from there but I think that
1881 this is a better solution. 1881 this is a better solution.
1882 1882
1883 This does, however, create a different problem in that we 1883 This does, however, create a different problem in that we
1884 can end up adding the object to every single line, never 1884 can end up adding the object to every single line, never
1885 getting any further - for instance an extent with a long 1885 getting any further - for instance an extent with a long
1886 start-glyph that covers multitple following 1886 start-glyph that covers multitple following
1887 characters. */ 1887 characters. */
1899 if (data->ch == '\n') 1899 if (data->ch == '\n')
1900 data->max_pixpos += data->end_glyph_width; 1900 data->max_pixpos += data->end_glyph_width;
1901 width = data->max_pixpos - data->pixpos; 1901 width = data->max_pixpos - data->pixpos;
1902 /* Add the glyph we are displaying, but clipping, to the 1902 /* Add the glyph we are displaying, but clipping, to the
1903 propagation data so that we don't try and do it 1903 propagation data so that we don't try and do it
1904 again. */ 1904 again. */
1905 retval = Dynarr_new (prop_block); 1905 retval = Dynarr_new (prop_block);
1906 pb.type = PROP_GLYPH; 1906 pb.type = PROP_GLYPH;
1907 pb.data.p_glyph.glyph = gb->glyph; 1907 pb.data.p_glyph.glyph = gb->glyph;
1908 pb.data.p_glyph.width = width; 1908 pb.data.p_glyph.width = width;
1909 Dynarr_add (retval, pb); 1909 Dynarr_add (retval, pb);
1954 pix_descent = height - pix_ascent; 1954 pix_descent = height - pix_ascent;
1955 1955
1956 data->new_ascent = max (data->new_ascent, pix_ascent); 1956 data->new_ascent = max (data->new_ascent, pix_ascent);
1957 data->new_descent = max (data->new_descent, pix_descent); 1957 data->new_descent = max (data->new_descent, pix_descent);
1958 data->max_pixmap_height = max (data->max_pixmap_height, height); 1958 data->max_pixmap_height = max (data->max_pixmap_height, height);
1959 1959
1960 rb.object.dglyph.descent = pix_descent; 1960 rb.object.dglyph.descent = pix_descent;
1961 } 1961 }
1962 1962
1963 /* Otherwise something is screwed up. */ 1963 /* Otherwise something is screwed up. */
1964 else 1964 else
1999 if (data->byte_endpos) 1999 if (data->byte_endpos)
2000 /* #### is this necessary at all? */ 2000 /* #### is this necessary at all? */
2001 rb.endpos = bytebpos_to_charbpos (XBUFFER (WINDOW_BUFFER (w)), 2001 rb.endpos = bytebpos_to_charbpos (XBUFFER (WINDOW_BUFFER (w)),
2002 data->byte_endpos); 2002 data->byte_endpos);
2003 else 2003 else
2004 rb.endpos = 0; 2004 rb.endpos = 0;
2005 rb.type = RUNE_DGLYPH; 2005 rb.type = RUNE_DGLYPH;
2006 rb.object.dglyph.glyph = gb->glyph; 2006 rb.object.dglyph.glyph = gb->glyph;
2007 rb.object.dglyph.extent = gb->extent; 2007 rb.object.dglyph.extent = gb->extent;
2008 rb.object.dglyph.xoffset = xoffset; 2008 rb.object.dglyph.xoffset = xoffset;
2009 rb.object.dglyph.ascent = ascent; 2009 rb.object.dglyph.ascent = ascent;
2272 data.byte_charpos--; 2272 data.byte_charpos--;
2273 goto done; 2273 goto done;
2274 } 2274 }
2275 2275
2276 /* If selective display was an integer and we aren't working on 2276 /* If selective display was an integer and we aren't working on
2277 a continuation line then find the next line we are actually 2277 a continuation line then find the next line we are actually
2278 supposed to display. */ 2278 supposed to display. */
2279 if (selective > 0 2279 if (selective > 0
2280 && (data.byte_charpos == BYTE_BUF_BEGV (b) 2280 && (data.byte_charpos == BYTE_BUF_BEGV (b)
2281 || BUF_FETCH_CHAR (b, prev_bytebpos (b, data.byte_charpos)) == '\n')) 2281 || BUF_FETCH_CHAR (b, prev_bytebpos (b, data.byte_charpos)) == '\n'))
2282 { 2282 {
2283 while (byte_spaces_at_point (b, data.byte_charpos) >= selective) 2283 while (byte_spaces_at_point (b, data.byte_charpos) >= selective)
2302 propagation data then we are clipping the glyph and there 2302 propagation data then we are clipping the glyph and there
2303 can be no propagation data before that point. The theory 2303 can be no propagation data before that point. The theory
2304 works because we always recalculate the extent-fragments 2304 works because we always recalculate the extent-fragments
2305 for propagated data, we never actually propagate the 2305 for propagated data, we never actually propagate the
2306 fragments that still need to be displayed. */ 2306 fragments that still need to be displayed. */
2307 if (*prop && Dynarr_atp (*prop, 0)->type == PROP_GLYPH) 2307 if (*prop && Dynarr_atp (*prop, 0)->type == PROP_GLYPH)
2308 { 2308 {
2309 last_glyph = Dynarr_atp (*prop, 0)->data.p_glyph.glyph; 2309 last_glyph = Dynarr_atp (*prop, 0)->data.p_glyph.glyph;
2310 Dynarr_free (*prop); 2310 Dynarr_free (*prop);
2311 *prop = 0; 2311 *prop = 0;
2312 } 2312 }
2321 no_more_frags = 1; 2321 no_more_frags = 1;
2322 } 2322 }
2323 initial = 0; 2323 initial = 0;
2324 2324
2325 /* Determine what is next to be displayed. We first handle any 2325 /* Determine what is next to be displayed. We first handle any
2326 glyphs returned by glyphs_at_charbpos. If there are no glyphs to 2326 glyphs returned by glyphs_at_charbpos. If there are no glyphs to
2327 display then we determine what to do based on the character at the 2327 display then we determine what to do based on the character at the
2328 current buffer position. */ 2328 current buffer position. */
2329 2329
2330 /* If the current position is covered by an invisible extent, do 2330 /* If the current position is covered by an invisible extent, do
2331 nothing (except maybe add some ellipses). 2331 nothing (except maybe add some ellipses).
2332 2332
2333 #### The behavior of begin and end-glyphs at the edge of an 2333 #### The behavior of begin and end-glyphs at the edge of an
2334 invisible extent should be investigated further. This is 2334 invisible extent should be investigated further. This is
2335 fairly low priority though. */ 2335 fairly low priority though. */
2336 if (data.ef->invisible) 2336 if (data.ef->invisible)
2363 if (*prop) 2363 if (*prop)
2364 goto done; 2364 goto done;
2365 } 2365 }
2366 2366
2367 /* If point is in an invisible region we place it on the 2367 /* If point is in an invisible region we place it on the
2368 next visible character. */ 2368 next visible character. */
2369 if (data.cursor_type == CURSOR_ON 2369 if (data.cursor_type == CURSOR_ON
2370 && data.byte_charpos == data.byte_cursor_charpos) 2370 && data.byte_charpos == data.byte_cursor_charpos)
2371 { 2371 {
2372 data.cursor_type = NEXT_CURSOR; 2372 data.cursor_type = NEXT_CURSOR;
2373 } 2373 }
2412 { 2412 {
2413 glyph_block_dynarr* tmpglyphs = 0; 2413 glyph_block_dynarr* tmpglyphs = 0;
2414 /* #### I think this is safe, but could be wrong. */ 2414 /* #### I think this is safe, but could be wrong. */
2415 data.ch = BYTE_BUF_FETCH_CHAR (b, data.byte_charpos); 2415 data.ch = BYTE_BUF_FETCH_CHAR (b, data.byte_charpos);
2416 2416
2417 if (Dynarr_length (data.ef->end_glyphs) > 0) 2417 if (Dynarr_length (data.ef->end_glyphs) > 0)
2418 { 2418 {
2419 *prop = add_glyph_runes (&data, END_GLYPHS); 2419 *prop = add_glyph_runes (&data, END_GLYPHS);
2420 tmpglyphs = data.ef->end_glyphs; 2420 tmpglyphs = data.ef->end_glyphs;
2421 } 2421 }
2422 2422
2423 /* If there are begin glyphs, add them to the line. */ 2423 /* If there are begin glyphs, add them to the line. */
2424 if (!*prop && Dynarr_length (data.ef->begin_glyphs) > 0) 2424 if (!*prop && Dynarr_length (data.ef->begin_glyphs) > 0)
2425 { 2425 {
2426 *prop = add_glyph_runes (&data, BEGIN_GLYPHS); 2426 *prop = add_glyph_runes (&data, BEGIN_GLYPHS);
2427 tmpglyphs = data.ef->begin_glyphs; 2427 tmpglyphs = data.ef->begin_glyphs;
2428 } 2428 }
2429 2429
2430 if (*prop) 2430 if (*prop)
2431 { 2431 {
2432 /* If we just clipped a glyph and we are at the end of a 2432 /* If we just clipped a glyph and we are at the end of a
2433 line and there are more glyphs to display then do 2433 line and there are more glyphs to display then do
2434 appropriate processing to not get a continuation 2434 appropriate processing to not get a continuation
2435 glyph. */ 2435 glyph. */
2436 if (*prop != ADD_FAILED 2436 if (*prop != ADD_FAILED
2437 && Dynarr_atp (*prop, 0)->type == PROP_GLYPH 2437 && Dynarr_atp (*prop, 0)->type == PROP_GLYPH
2438 && data.ch == '\n') 2438 && data.ch == '\n')
2439 { 2439 {
2440 /* If there are no more glyphs then do the normal 2440 /* If there are no more glyphs then do the normal
2441 processing. 2441 processing.
2442 2442
2443 #### This doesn't actually work if the same glyph is 2443 #### This doesn't actually work if the same glyph is
2444 present more than once in the block. To solve 2444 present more than once in the block. To solve
2445 this we would have to carry the index around 2445 this we would have to carry the index around
2446 which might be problematic since the fragment is 2446 which might be problematic since the fragment is
2475 data.ch = BYTE_BUF_FETCH_CHAR (b, data.byte_charpos); 2475 data.ch = BYTE_BUF_FETCH_CHAR (b, data.byte_charpos);
2476 if (!NILP (face_dt) || !NILP (window_dt)) 2476 if (!NILP (face_dt) || !NILP (window_dt))
2477 entry = display_table_entry (data.ch, face_dt, window_dt); 2477 entry = display_table_entry (data.ch, face_dt, window_dt);
2478 2478
2479 /* If there is a display table entry for it, hand it off to 2479 /* If there is a display table entry for it, hand it off to
2480 add_disp_table_entry_runes and let it worry about it. */ 2480 add_disp_table_entry_runes and let it worry about it. */
2481 if (!NILP (entry) && !EQ (entry, make_char (data.ch))) 2481 if (!NILP (entry) && !EQ (entry, make_char (data.ch)))
2482 { 2482 {
2483 *prop = add_disp_table_entry_runes (&data, entry); 2483 *prop = add_disp_table_entry_runes (&data, entry);
2484 2484
2485 if (*prop) 2485 if (*prop)
2486 goto done; 2486 goto done;
2487 } 2487 }
2488 2488
2489 /* Check if we have hit a newline character. If so, add a marker 2489 /* Check if we have hit a newline character. If so, add a marker
2490 to the line and end this loop. */ 2490 to the line and end this loop. */
2491 else if (data.ch == '\n') 2491 else if (data.ch == '\n')
2492 { 2492 {
2493 /* We aren't going to be adding an end glyph so give its 2493 /* We aren't going to be adding an end glyph so give its
2494 space back in order to make sure that the cursor can 2494 space back in order to make sure that the cursor can
2495 fit. */ 2495 fit. */
2496 data.max_pixpos += data.end_glyph_width; 2496 data.max_pixpos += data.end_glyph_width;
2497 2497
2498 if (selective > 0 2498 if (selective > 0
2499 && (byte_spaces_at_point 2499 && (byte_spaces_at_point
2500 (b, next_bytebpos (b, data.byte_charpos)) 2500 (b, next_bytebpos (b, data.byte_charpos))
2518 data.blank_width = DEVMETH (d, eol_cursor_width, ()); 2518 data.blank_width = DEVMETH (d, eol_cursor_width, ());
2519 *prop = add_ichar_rune (&data); 2519 *prop = add_ichar_rune (&data);
2520 } 2520 }
2521 2521
2522 /* We need to set data.byte_charpos to the start of the 2522 /* We need to set data.byte_charpos to the start of the
2523 next visible region in order to make this line 2523 next visible region in order to make this line
2524 appear to contain all of the invisible area. 2524 appear to contain all of the invisible area.
2525 Otherwise, the line cache won't work 2525 Otherwise, the line cache won't work
2526 correctly. */ 2526 correctly. */
2527 INC_BYTEBPOS (b, data.byte_charpos); 2527 INC_BYTEBPOS (b, data.byte_charpos);
2528 while (byte_spaces_at_point (b, data.byte_charpos) >= selective) 2528 while (byte_spaces_at_point (b, data.byte_charpos) >= selective)
2529 { 2529 {
2530 data.byte_charpos = 2530 data.byte_charpos =
2531 byte_find_next_newline_no_quit (b, data.byte_charpos, 1); 2531 byte_find_next_newline_no_quit (b, data.byte_charpos, 1);
2547 2547
2548 goto done; 2548 goto done;
2549 } 2549 }
2550 2550
2551 /* If the current character is ^M, and selective display is 2551 /* If the current character is ^M, and selective display is
2552 enabled, then add the invisible-text-glyph if 2552 enabled, then add the invisible-text-glyph if
2553 selective-display-ellipses is set. In any case, this 2553 selective-display-ellipses is set. In any case, this
2554 line is done. */ 2554 line is done. */
2555 else if (data.ch == (('M' & 037)) && selective == -1) 2555 else if (data.ch == (('M' & 037)) && selective == -1)
2556 { 2556 {
2557 Bytebpos byte_next_charpos; 2557 Bytebpos byte_next_charpos;
2558 2558
2559 /* Find the buffer position at the end of the line. */ 2559 /* Find the buffer position at the end of the line. */
2562 if (BYTE_BUF_FETCH_CHAR (b, prev_bytebpos (b, byte_next_charpos)) 2562 if (BYTE_BUF_FETCH_CHAR (b, prev_bytebpos (b, byte_next_charpos))
2563 == '\n') 2563 == '\n')
2564 DEC_BYTEBPOS (b, byte_next_charpos); 2564 DEC_BYTEBPOS (b, byte_next_charpos);
2565 2565
2566 /* If the cursor is somewhere in the elided text make 2566 /* If the cursor is somewhere in the elided text make
2567 sure that the cursor gets drawn appropriately. */ 2567 sure that the cursor gets drawn appropriately. */
2568 if (data.cursor_type == CURSOR_ON 2568 if (data.cursor_type == CURSOR_ON
2569 && (data.byte_cursor_charpos >= data.byte_charpos && 2569 && (data.byte_cursor_charpos >= data.byte_charpos &&
2570 data.byte_cursor_charpos < byte_next_charpos)) 2570 data.byte_cursor_charpos < byte_next_charpos))
2571 { 2571 {
2572 data.cursor_type = NEXT_CURSOR; 2572 data.cursor_type = NEXT_CURSOR;
2573 } 2573 }
2574 2574
2575 /* We won't be adding a truncation or continuation glyph 2575 /* We won't be adding a truncation or continuation glyph
2576 so give up the room allocated for them. */ 2576 so give up the room allocated for them. */
2577 data.max_pixpos += data.end_glyph_width; 2577 data.max_pixpos += data.end_glyph_width;
2578 2578
2579 if (!NILP (b->selective_display_ellipses)) 2579 if (!NILP (b->selective_display_ellipses))
2580 { 2580 {
2581 /* We don't propagate anything from the invisible 2581 /* We don't propagate anything from the invisible
2582 text glyph if it fails to fit. This is 2582 text glyph if it fails to fit. This is
2583 intentional. */ 2583 intentional. */
2584 struct glyph_block gb; 2584 struct glyph_block gb;
2585 2585
2586 gb.extent = Qnil; 2586 gb.extent = Qnil;
2587 gb.glyph = Vinvisible_text_glyph; 2587 gb.glyph = Vinvisible_text_glyph;
2588 add_glyph_rune (&data, &gb, BEGIN_GLYPHS, 1, 2588 add_glyph_rune (&data, &gb, BEGIN_GLYPHS, 1,
2589 GLYPH_CACHEL (w, INVIS_GLYPH_INDEX)); 2589 GLYPH_CACHEL (w, INVIS_GLYPH_INDEX));
2590 } 2590 }
2591 2591
2592 /* Set the buffer position to the end of the line. We 2592 /* Set the buffer position to the end of the line. We
2593 need to do this before potentially adding a newline 2593 need to do this before potentially adding a newline
2594 so that the cursor flag will get set correctly (if 2594 so that the cursor flag will get set correctly (if
2595 needed). */ 2595 needed). */
2596 data.byte_charpos = byte_next_charpos; 2596 data.byte_charpos = byte_next_charpos;
2597 2597
2598 if (NILP (b->selective_display_ellipses) 2598 if (NILP (b->selective_display_ellipses)
2599 || data.byte_cursor_charpos == byte_next_charpos) 2599 || data.byte_cursor_charpos == byte_next_charpos)
2600 { 2600 {
2601 /* We have to at least add a newline character so 2601 /* We have to at least add a newline character so
2602 that the cursor shows up properly. */ 2602 that the cursor shows up properly. */
2603 data.ch = '\n'; 2603 data.ch = '\n';
2604 data.blank_width = DEVMETH (d, eol_cursor_width, ()); 2604 data.blank_width = DEVMETH (d, eol_cursor_width, ());
2605 data.findex = DEFAULT_INDEX; 2605 data.findex = DEFAULT_INDEX;
2606 data.start_col = 0; 2606 data.start_col = 0;
2607 data.start_col_xoffset = 0; 2607 data.start_col_xoffset = 0;
2609 2609
2610 add_ichar_rune (&data); 2610 add_ichar_rune (&data);
2611 } 2611 }
2612 2612
2613 /* This had better be a newline but doing it this way 2613 /* This had better be a newline but doing it this way
2614 we'll see obvious incorrect results if it isn't. No 2614 we'll see obvious incorrect results if it isn't. No
2615 need to abort here. */ 2615 need to abort here. */
2616 data.ch = BYTE_BUF_FETCH_CHAR (b, data.byte_charpos); 2616 data.ch = BYTE_BUF_FETCH_CHAR (b, data.byte_charpos);
2617 2617
2618 goto done; 2618 goto done;
2619 } 2619 }
2620 2620
2621 /* If the current character is considered to be printable, then 2621 /* If the current character is considered to be printable, then
2622 just add it. */ 2622 just add it. */
2623 else if (data.ch >= printable_min) 2623 else if (data.ch >= printable_min)
2624 { 2624 {
2625 *prop = add_ichar_rune (&data); 2625 *prop = add_ichar_rune (&data);
2626 if (*prop) 2626 if (*prop)
2627 goto done; 2627 goto done;
2628 } 2628 }
2629 2629
2630 /* If the current character is a tab, determine the next tab 2630 /* If the current character is a tab, determine the next tab
2631 starting position and add a blank rune which extends from the 2631 starting position and add a blank rune which extends from the
2632 current pixel position to that starting position. */ 2632 current pixel position to that starting position. */
2633 else if (data.ch == '\t') 2633 else if (data.ch == '\t')
2634 { 2634 {
2635 int tab_start_pixpos = data.pixpos; 2635 int tab_start_pixpos = data.pixpos;
2636 int next_tab_start; 2636 int next_tab_start;
2637 int char_tab_width; 2637 int char_tab_width;
2655 (next_tab_start - tab_start_pixpos) / space_width (w); 2655 (next_tab_start - tab_start_pixpos) / space_width (w);
2656 2656
2657 *prop = add_blank_rune (&data, w, char_tab_width); 2657 *prop = add_blank_rune (&data, w, char_tab_width);
2658 2658
2659 /* add_blank_rune is only supposed to be called with 2659 /* add_blank_rune is only supposed to be called with
2660 sizes guaranteed to fit in the available space. */ 2660 sizes guaranteed to fit in the available space. */
2661 assert (!(*prop)); 2661 assert (!(*prop));
2662 2662
2663 if (prop_width) 2663 if (prop_width)
2664 { 2664 {
2665 struct prop_block pb; 2665 struct prop_block pb;
2673 goto done; 2673 goto done;
2674 } 2674 }
2675 } 2675 }
2676 2676
2677 /* If character is a control character, pass it off to 2677 /* If character is a control character, pass it off to
2678 add_control_char_runes. 2678 add_control_char_runes.
2679 2679
2680 The is_*() routines have undefined results on 2680 The is_*() routines have undefined results on
2681 arguments outside of the range [-1, 255]. (This 2681 arguments outside of the range [-1, 255]. (This
2682 often bites people who carelessly use `char' instead 2682 often bites people who carelessly use `char' instead
2683 of `unsigned char'.) 2683 of `unsigned char'.)
2689 if (*prop) 2689 if (*prop)
2690 goto done; 2690 goto done;
2691 } 2691 }
2692 2692
2693 /* If the character is above the ASCII range and we have not 2693 /* If the character is above the ASCII range and we have not
2694 already handled it, then print it as an octal number. */ 2694 already handled it, then print it as an octal number. */
2695 else if (data.ch >= 0200) 2695 else if (data.ch >= 0200)
2696 { 2696 {
2697 *prop = add_octal_runes (&data); 2697 *prop = add_octal_runes (&data);
2698 2698
2699 if (*prop) 2699 if (*prop)
2700 goto done; 2700 goto done;
2701 } 2701 }
2702 2702
2703 /* Assume the current character is considered to be printable, 2703 /* Assume the current character is considered to be printable,
2704 then just add it. */ 2704 then just add it. */
2705 else 2705 else
2706 { 2706 {
2707 *prop = add_ichar_rune (&data); 2707 *prop = add_ichar_rune (&data);
2708 if (*prop) 2708 if (*prop)
2709 goto done; 2709 goto done;
2727 you should be able to say '(if (*prop))'. That should also 2727 you should be able to say '(if (*prop))'. That should also
2728 make it possible to eliminate the data.byte_charpos < BYTE_BUF_ZV (b) 2728 make it possible to eliminate the data.byte_charpos < BYTE_BUF_ZV (b)
2729 check. */ 2729 check. */
2730 2730
2731 /* The common case is that the line ended because we hit a newline. 2731 /* The common case is that the line ended because we hit a newline.
2732 In that case, the next character is just the next buffer 2732 In that case, the next character is just the next buffer
2733 position. */ 2733 position. */
2734 if (data.ch == '\n') 2734 if (data.ch == '\n')
2735 { 2735 {
2736 /* If data.start_col_enabled is still true, then the window is 2736 /* If data.start_col_enabled is still true, then the window is
2737 scrolled far enough so that nothing on this line is visible. 2737 scrolled far enough so that nothing on this line is visible.
2738 We need to stick a truncation glyph at the beginning of the 2738 We need to stick a truncation glyph at the beginning of the
2739 line in that case unless the line is completely blank. */ 2739 line in that case unless the line is completely blank. */
2740 if (data.byte_start_col_enabled) 2740 if (data.byte_start_col_enabled)
2741 { 2741 {
2742 if (data.cursor_type == CURSOR_ON) 2742 if (data.cursor_type == CURSOR_ON)
2743 { 2743 {
2744 if (data.byte_cursor_charpos >= byte_start_pos 2744 if (data.byte_cursor_charpos >= byte_start_pos
2759 GLYPH_CACHEL (w, HSCROLL_GLYPH_INDEX)); 2759 GLYPH_CACHEL (w, HSCROLL_GLYPH_INDEX));
2760 } 2760 }
2761 else 2761 else
2762 { 2762 {
2763 /* This duplicates code down below to add a newline to 2763 /* This duplicates code down below to add a newline to
2764 the end of an otherwise empty line.*/ 2764 the end of an otherwise empty line.*/
2765 data.ch = '\n'; 2765 data.ch = '\n';
2766 data.blank_width = DEVMETH (d, eol_cursor_width, ()); 2766 data.blank_width = DEVMETH (d, eol_cursor_width, ());
2767 2767
2768 add_ichar_rune (&data); 2768 add_ichar_rune (&data);
2769 } 2769 }
2771 2771
2772 INC_BYTEBPOS (b, data.byte_charpos); 2772 INC_BYTEBPOS (b, data.byte_charpos);
2773 } 2773 }
2774 2774
2775 /* Otherwise we have a buffer line which cannot fit on one display 2775 /* Otherwise we have a buffer line which cannot fit on one display
2776 line. */ 2776 line. */
2777 else 2777 else
2778 { 2778 {
2779 struct glyph_block gb; 2779 struct glyph_block gb;
2780 struct glyph_cachel *cachel; 2780 struct glyph_cachel *cachel;
2781 2781
2782 /* If the line is to be truncated then we actually have to look 2782 /* If the line is to be truncated then we actually have to look
2783 for the next newline. We also add the end-of-line glyph which 2783 for the next newline. We also add the end-of-line glyph which
2784 we know will fit because we adjusted the right border before 2784 we know will fit because we adjusted the right border before
2785 we starting laying out the line. */ 2785 we starting laying out the line. */
2786 data.max_pixpos += data.end_glyph_width; 2786 data.max_pixpos += data.end_glyph_width;
2787 data.findex = DEFAULT_INDEX; 2787 data.findex = DEFAULT_INDEX;
2788 gb.extent = Qnil; 2788 gb.extent = Qnil;
2789 2789
2790 if (truncate_win) 2790 if (truncate_win)
2793 2793
2794 /* Now find the start of the next line. */ 2794 /* Now find the start of the next line. */
2795 byte_pos = byte_find_next_newline_no_quit (b, data.byte_charpos, 1); 2795 byte_pos = byte_find_next_newline_no_quit (b, data.byte_charpos, 1);
2796 2796
2797 /* If the cursor is past the truncation line then we 2797 /* If the cursor is past the truncation line then we
2798 make it appear on the truncation glyph. If we've hit 2798 make it appear on the truncation glyph. If we've hit
2799 the end of the buffer then we also make the cursor 2799 the end of the buffer then we also make the cursor
2800 appear unless eob is immediately preceded by a 2800 appear unless eob is immediately preceded by a
2801 newline. In that case the cursor should actually 2801 newline. In that case the cursor should actually
2802 appear on the next line. */ 2802 appear on the next line. */
2803 if (data.cursor_type == CURSOR_ON 2803 if (data.cursor_type == CURSOR_ON
2804 && data.byte_cursor_charpos >= data.byte_charpos 2804 && data.byte_cursor_charpos >= data.byte_charpos
2805 && (data.byte_cursor_charpos < byte_pos || 2805 && (data.byte_cursor_charpos < byte_pos ||
2806 (byte_pos == BYTE_BUF_ZV (b) 2806 (byte_pos == BYTE_BUF_ZV (b)
2807 && (byte_pos == BYTE_BUF_BEGV (b) 2807 && (byte_pos == BYTE_BUF_BEGV (b)
2837 } 2837 }
2838 else if ((active_minibuffer || !NILP (synch_minibuffers_value)) 2838 else if ((active_minibuffer || !NILP (synch_minibuffers_value))
2839 && (!echo_area_active (f) || data.byte_charpos == BYTE_BUF_ZV (b))) 2839 && (!echo_area_active (f) || data.byte_charpos == BYTE_BUF_ZV (b)))
2840 { 2840 {
2841 /* We need to add a marker to the end of the line since there is no 2841 /* We need to add a marker to the end of the line since there is no
2842 newline character in order for the cursor to get drawn. We label 2842 newline character in order for the cursor to get drawn. We label
2843 it as a newline so that it gets handled correctly by the 2843 it as a newline so that it gets handled correctly by the
2844 whitespace routines below. */ 2844 whitespace routines below. */
2845 2845
2846 data.ch = '\n'; 2846 data.ch = '\n';
2847 data.blank_width = DEVMETH (d, eol_cursor_width, ()); 2847 data.blank_width = DEVMETH (d, eol_cursor_width, ());
2848 data.findex = DEFAULT_INDEX; 2848 data.findex = DEFAULT_INDEX;
2849 data.start_col = 0; 2849 data.start_col = 0;
3024 3024
3025 gb.glyph = Voverlay_arrow_string; 3025 gb.glyph = Voverlay_arrow_string;
3026 gb.extent = Qnil; 3026 gb.extent = Qnil;
3027 add_glyph_rune (&data, &gb, BEGIN_GLYPHS, 0, 0); 3027 add_glyph_rune (&data, &gb, BEGIN_GLYPHS, 0, 0);
3028 } 3028 }
3029 3029
3030 if (data.max_pixmap_height) 3030 if (data.max_pixmap_height)
3031 { 3031 {
3032 int height = data.new_ascent + data.new_descent; 3032 int height = data.new_ascent + data.new_descent;
3033 int pix_ascent, pix_descent; 3033 int pix_ascent, pix_descent;
3034 3034
3035 pix_descent = data.max_pixmap_height * data.new_descent / height; 3035 pix_descent = data.max_pixmap_height * data.new_descent / height;
3036 pix_ascent = data.max_pixmap_height - pix_descent; 3036 pix_ascent = data.max_pixmap_height - pix_descent;
3037 calculate_baseline (&data); 3037 calculate_baseline (&data);
3038 3038
3039 data.new_ascent = max (data.new_ascent, pix_ascent); 3039 data.new_ascent = max (data.new_ascent, pix_ascent);
3269 while (!done && marker < Dynarr_length (ib)) 3269 while (!done && marker < Dynarr_length (ib))
3270 { 3270 {
3271 int width = Dynarr_atp (ib, marker)->width; 3271 int width = Dynarr_atp (ib, marker)->width;
3272 3272
3273 /* If everything now fits in the available inside margin 3273 /* If everything now fits in the available inside margin
3274 space, we're done. */ 3274 space, we're done. */
3275 if (used_in <= avail_in) 3275 if (used_in <= avail_in)
3276 done = 1; 3276 done = 1;
3277 else 3277 else
3278 { 3278 {
3279 /* Otherwise see if we have room to move a glyph to the 3279 /* Otherwise see if we have room to move a glyph to the
3280 outside. */ 3280 outside. */
3281 if (used_out + width <= avail_out) 3281 if (used_out + width <= avail_out)
3282 { 3282 {
3283 used_out += width; 3283 used_out += width;
3284 used_in -= width; 3284 used_in -= width;
3285 } 3285 }
3375 if (out_cnt || in_out_cnt || white_out_cnt) 3375 if (out_cnt || in_out_cnt || white_out_cnt)
3376 { 3376 {
3377 odb = get_display_block_from_line (dl, LEFT_OUTSIDE_MARGIN); 3377 odb = get_display_block_from_line (dl, LEFT_OUTSIDE_MARGIN);
3378 odb->start_pos = dl->bounds.left_out; 3378 odb->start_pos = dl->bounds.left_out;
3379 /* #### We should stop adding a blank to account for the space 3379 /* #### We should stop adding a blank to account for the space
3380 between the end of the glyphs and the margin and instead set 3380 between the end of the glyphs and the margin and instead set
3381 this accordingly. */ 3381 this accordingly. */
3382 odb->end_pos = dl->bounds.left_in; 3382 odb->end_pos = dl->bounds.left_in;
3383 Dynarr_reset (odb->runes); 3383 Dynarr_reset (odb->runes);
3384 } 3384 }
3385 else 3385 else
3386 odb = 0; 3386 odb = 0;
3583 while (!done && marker < Dynarr_length (ib)) 3583 while (!done && marker < Dynarr_length (ib))
3584 { 3584 {
3585 int width = Dynarr_atp (ib, marker)->width; 3585 int width = Dynarr_atp (ib, marker)->width;
3586 3586
3587 /* If everything now fits in the available inside margin 3587 /* If everything now fits in the available inside margin
3588 space, we're done. */ 3588 space, we're done. */
3589 if (used_in <= avail_in) 3589 if (used_in <= avail_in)
3590 done = 1; 3590 done = 1;
3591 else 3591 else
3592 { 3592 {
3593 /* Otherwise see if we have room to move a glyph to the 3593 /* Otherwise see if we have room to move a glyph to the
3594 outside. */ 3594 outside. */
3595 if (used_out + width <= avail_out) 3595 if (used_out + width <= avail_out)
3596 { 3596 {
3597 used_out += width; 3597 used_out += width;
3598 used_in -= width; 3598 used_in -= width;
3599 } 3599 }
3686 to the appropriate display blocks. */ 3686 to the appropriate display blocks. */
3687 if (out_cnt || in_out_cnt || white_out_cnt) 3687 if (out_cnt || in_out_cnt || white_out_cnt)
3688 { 3688 {
3689 odb = get_display_block_from_line (dl, RIGHT_OUTSIDE_MARGIN); 3689 odb = get_display_block_from_line (dl, RIGHT_OUTSIDE_MARGIN);
3690 /* #### See comments before odb->start_pos init in 3690 /* #### See comments before odb->start_pos init in
3691 create_left_glyph_block */ 3691 create_left_glyph_block */
3692 odb->start_pos = dl->bounds.right_in; 3692 odb->start_pos = dl->bounds.right_in;
3693 odb->end_pos = dl->bounds.right_out; 3693 odb->end_pos = dl->bounds.right_out;
3694 Dynarr_reset (odb->runes); 3694 Dynarr_reset (odb->runes);
3695 } 3695 }
3696 else 3696 else
3699 if (in_in_cnt || white_in_cnt) 3699 if (in_in_cnt || white_in_cnt)
3700 { 3700 {
3701 idb = get_display_block_from_line (dl, RIGHT_INSIDE_MARGIN); 3701 idb = get_display_block_from_line (dl, RIGHT_INSIDE_MARGIN);
3702 idb->start_pos = dl->bounds.right_white; 3702 idb->start_pos = dl->bounds.right_white;
3703 /* #### See comments before odb->start_pos init in 3703 /* #### See comments before odb->start_pos init in
3704 create_left_glyph_block */ 3704 create_left_glyph_block */
3705 idb->end_pos = dl->bounds.right_in; 3705 idb->end_pos = dl->bounds.right_in;
3706 Dynarr_reset (idb->runes); 3706 Dynarr_reset (idb->runes);
3707 } 3707 }
3708 else 3708 else
3709 idb = 0; 3709 idb = 0;
3783 /***************************************************************************/ 3783 /***************************************************************************/
3784 3784
3785 /* This function is also used in frame.c by `generate_title_string' */ 3785 /* This function is also used in frame.c by `generate_title_string' */
3786 void 3786 void
3787 generate_formatted_string_db (Lisp_Object format_str, Lisp_Object result_str, 3787 generate_formatted_string_db (Lisp_Object format_str, Lisp_Object result_str,
3788 struct window *w, struct display_line *dl, 3788 struct window *w, struct display_line *dl,
3789 struct display_block *db, face_index findex, 3789 struct display_block *db, face_index findex,
3790 int min_pixpos, int max_pixpos, int type) 3790 int min_pixpos, int max_pixpos, int type)
3791 { 3791 {
3792 struct frame *f = XFRAME (w->frame); 3792 struct frame *f = XFRAME (w->frame);
3793 struct device *d = XDEVICE (f->device); 3793 struct device *d = XDEVICE (f->device);
3794 3794
3795 pos_data data; 3795 pos_data data;
3819 we're building a modeline, so the offset starts at the modeline 3819 we're building a modeline, so the offset starts at the modeline
3820 horizontal scrolling amount */ 3820 horizontal scrolling amount */
3821 if (! NILP (result_str)) 3821 if (! NILP (result_str))
3822 offset = w->modeline_hscroll; 3822 offset = w->modeline_hscroll;
3823 generate_fstring_runes (w, &data, 0, 0, -1, format_str, 0, 3823 generate_fstring_runes (w, &data, 0, 0, -1, format_str, 0,
3824 max_pixpos - min_pixpos, findex, type, &offset, 3824 max_pixpos - min_pixpos, findex, type, &offset,
3825 Qnil); 3825 Qnil);
3826 3826
3827 if (Dynarr_length (db->runes)) 3827 if (Dynarr_length (db->runes))
3828 { 3828 {
3829 struct rune *rb = 3829 struct rune *rb =
3830 Dynarr_atp (db->runes, Dynarr_length (db->runes) - 1); 3830 Dynarr_atp (db->runes, Dynarr_length (db->runes) - 1);
3831 c_pixpos = rb->xpos + rb->width; 3831 c_pixpos = rb->xpos + rb->width;
3832 } 3832 }
3833 else 3833 else
3834 c_pixpos = min_pixpos; 3834 c_pixpos = min_pixpos;
3835 3835
3857 in_modeline_generation = 1; 3857 in_modeline_generation = 1;
3858 3858
3859 sledgehammer_check_ascii_begin (result_str); 3859 sledgehammer_check_ascii_begin (result_str);
3860 detach_all_extents (result_str); 3860 detach_all_extents (result_str);
3861 resize_string (result_str, -1, 3861 resize_string (result_str, -1,
3862 data.bytepos - XSTRING_LENGTH (result_str)); 3862 data.bytepos - XSTRING_LENGTH (result_str));
3863 3863
3864 strdata = XSTRING_DATA (result_str); 3864 strdata = XSTRING_DATA (result_str);
3865 3865
3866 for (elt = 0, len = 0; elt < Dynarr_length (db->runes); elt++) 3866 for (elt = 0, len = 0; elt < Dynarr_length (db->runes); elt++)
3867 { 3867 {
3868 if (Dynarr_atp (db->runes, elt)->type == RUNE_CHAR) 3868 if (Dynarr_atp (db->runes, elt)->type == RUNE_CHAR)
3869 { 3869 {
3870 len += (set_itext_ichar 3870 len += (set_itext_ichar
3871 (strdata + len, Dynarr_atp (db->runes, 3871 (strdata + len, Dynarr_atp (db->runes,
3872 elt)->object.chr.ch)); 3872 elt)->object.chr.ch));
3873 } 3873 }
3874 } 3874 }
3875 3875
3876 init_string_ascii_begin (result_str); 3876 init_string_ascii_begin (result_str);
3877 bump_string_modiff (result_str); 3877 bump_string_modiff (result_str);
3878 sledgehammer_check_ascii_begin (result_str); 3878 sledgehammer_check_ascii_begin (result_str);
3879 3879
3880 for (elt = 0; elt < Dynarr_length (formatted_string_extent_dynarr); 3880 for (elt = 0; elt < Dynarr_length (formatted_string_extent_dynarr);
3881 elt++) 3881 elt++)
3882 { 3882 {
3883 Lisp_Object extent = Qnil; 3883 Lisp_Object extent = Qnil;
3884 Lisp_Object child; 3884 Lisp_Object child;
3885 3885
3886 extent = wrap_extent (Dynarr_at (formatted_string_extent_dynarr, elt)); 3886 extent = wrap_extent (Dynarr_at (formatted_string_extent_dynarr, elt));
3887 child = Fgethash (extent, buf->modeline_extent_table, Qnil); 3887 child = Fgethash (extent, buf->modeline_extent_table, Qnil);
3888 if (NILP (child)) 3888 if (NILP (child))
3889 { 3889 {
3890 child = Fmake_extent (Qnil, Qnil, result_str); 3890 child = Fmake_extent (Qnil, Qnil, result_str);
3891 Fputhash (extent, child, buf->modeline_extent_table); 3891 Fputhash (extent, child, buf->modeline_extent_table);
3892 } 3892 }
3893 Fset_extent_parent (child, extent); 3893 Fset_extent_parent (child, extent);
3894 set_extent_endpoints 3894 set_extent_endpoints
3895 (XEXTENT (child), 3895 (XEXTENT (child),
3896 Dynarr_at (formatted_string_extent_start_dynarr, elt), 3896 Dynarr_at (formatted_string_extent_start_dynarr, elt),
3897 Dynarr_at (formatted_string_extent_end_dynarr, elt), 3897 Dynarr_at (formatted_string_extent_end_dynarr, elt),
3898 result_str); 3898 result_str);
3899 } 3899 }
3900 3900
3901 in_modeline_generation = 0; 3901 in_modeline_generation = 0;
3902 } 3902 }
3903 } 3903 }
3904 3904
3997 dl->ypos = WINDOW_BOTTOM (w) - dl->descent - ypos_adj; 3997 dl->ypos = WINDOW_BOTTOM (w) - dl->descent - ypos_adj;
3998 } 3998 }
3999 3999
4000 static Charcount 4000 static Charcount
4001 add_string_to_fstring_db_runes (pos_data *data, const Ibyte *str, 4001 add_string_to_fstring_db_runes (pos_data *data, const Ibyte *str,
4002 Charcount pos, Charcount min_pos, 4002 Charcount pos, Charcount min_pos,
4003 Charcount max_pos) 4003 Charcount max_pos)
4004 { 4004 {
4005 /* This function has been Mule-ized. */ 4005 /* This function has been Mule-ized. */
4006 Charcount end; 4006 Charcount end;
4007 const Ibyte *cur_pos = str; 4007 const Ibyte *cur_pos = str;
4010 data->blank_width = space_width (XWINDOW (data->window)); 4010 data->blank_width = space_width (XWINDOW (data->window));
4011 while (Dynarr_length (db->runes) < pos) 4011 while (Dynarr_length (db->runes) < pos)
4012 add_blank_rune (data, NULL, 0); 4012 add_blank_rune (data, NULL, 0);
4013 4013
4014 end = (Dynarr_length (db->runes) + 4014 end = (Dynarr_length (db->runes) +
4015 bytecount_to_charcount (str, strlen ((const char *) str))); 4015 bytecount_to_charcount (str, strlen ((const char *) str)));
4016 if (max_pos != -1) 4016 if (max_pos != -1)
4017 end = min (max_pos, end); 4017 end = min (max_pos, end);
4018 4018
4019 while (pos < end && *cur_pos) 4019 while (pos < end && *cur_pos)
4020 { 4020 {
4023 4023
4024 data->ch = itext_ichar (cur_pos); 4024 data->ch = itext_ichar (cur_pos);
4025 succeeded = (add_ichar_rune (data) != ADD_FAILED); 4025 succeeded = (add_ichar_rune (data) != ADD_FAILED);
4026 INC_IBYTEPTR (cur_pos); 4026 INC_IBYTEPTR (cur_pos);
4027 if (succeeded) 4027 if (succeeded)
4028 { 4028 {
4029 pos++; 4029 pos++;
4030 data->modeline_charpos++; 4030 data->modeline_charpos++;
4031 data->bytepos += cur_pos - old_cur_pos; 4031 data->bytepos += cur_pos - old_cur_pos;
4032 } 4032 }
4033 } 4033 }
4034 4034
4035 while (Dynarr_length (db->runes) < min_pos && 4035 while (Dynarr_length (db->runes) < min_pos &&
4036 (data->pixpos + data->blank_width <= data->max_pixpos)) 4036 (data->pixpos + data->blank_width <= data->max_pixpos))
4037 add_blank_rune (data, NULL, 0); 4037 add_blank_rune (data, NULL, 0);
4038 4038
4039 return Dynarr_length (db->runes); 4039 return Dynarr_length (db->runes);
4040 } 4040 }
4041 4041
4042 /* #### Urk! Should also handle begin-glyphs and end-glyphs in 4042 /* #### Urk! Should also handle begin-glyphs and end-glyphs in
4043 modeline extents. */ 4043 modeline extents. */
4044 static Charcount 4044 static Charcount
4045 add_glyph_to_fstring_db_runes (pos_data *data, Lisp_Object glyph, 4045 add_glyph_to_fstring_db_runes (pos_data *data, Lisp_Object glyph,
4046 Charcount pos, Charcount UNUSED (min_pos), 4046 Charcount pos, Charcount UNUSED (min_pos),
4047 Charcount max_pos, Lisp_Object extent) 4047 Charcount max_pos, Lisp_Object extent)
4048 { 4048 {
4049 /* This function has been Mule-ized. */ 4049 /* This function has been Mule-ized. */
4050 Charcount end; 4050 Charcount end;
4051 struct display_block *db = data->db; 4051 struct display_block *db = data->db;
4063 gb.extent = extent; 4063 gb.extent = extent;
4064 add_glyph_rune (data, &gb, BEGIN_GLYPHS, 0, 0); 4064 add_glyph_rune (data, &gb, BEGIN_GLYPHS, 0, 0);
4065 pos++; 4065 pos++;
4066 4066
4067 while (Dynarr_length (db->runes) < pos && 4067 while (Dynarr_length (db->runes) < pos &&
4068 (data->pixpos + data->blank_width <= data->max_pixpos)) 4068 (data->pixpos + data->blank_width <= data->max_pixpos))
4069 add_blank_rune (data, NULL, 0); 4069 add_blank_rune (data, NULL, 0);
4070 4070
4071 return Dynarr_length (db->runes); 4071 return Dynarr_length (db->runes);
4072 } 4072 }
4073 4073
4083 not in terms of columns. This is necessary to make the formatting 4083 not in terms of columns. This is necessary to make the formatting
4084 work correctly when proportional width fonts are used in the 4084 work correctly when proportional width fonts are used in the
4085 modeline. */ 4085 modeline. */
4086 static Charcount 4086 static Charcount
4087 generate_fstring_runes (struct window *w, pos_data *data, Charcount pos, 4087 generate_fstring_runes (struct window *w, pos_data *data, Charcount pos,
4088 Charcount min_pos, Charcount max_pos, 4088 Charcount min_pos, Charcount max_pos,
4089 Lisp_Object elt, int depth, int max_pixsize, 4089 Lisp_Object elt, int depth, int max_pixsize,
4090 face_index findex, int type, Charcount *offset, 4090 face_index findex, int type, Charcount *offset,
4091 Lisp_Object cur_ext) 4091 Lisp_Object cur_ext)
4092 { 4092 {
4093 /* This function has been Mule-ized. */ 4093 /* This function has been Mule-ized. */
4094 /* #### The other losing things in this function are: 4094 /* #### The other losing things in this function are:
4095 4095
4096 -- C zero-terminated-string lossage. 4096 -- C zero-terminated-string lossage.
4097 -- Non-printable characters should be converted into something 4097 -- Non-printable characters should be converted into something
4098 appropriate (e.g. ^F) instead of blindly being printed anyway. 4098 appropriate (e.g. ^F) instead of blindly being printed anyway.
4099 */ 4099 */
4100 4100
4101 tail_recurse: 4101 tail_recurse:
4102 if (depth > 10) 4102 if (depth > 10)
4103 goto invalid; 4103 goto invalid;
4105 depth++; 4105 depth++;
4106 4106
4107 if (STRINGP (elt)) 4107 if (STRINGP (elt))
4108 { 4108 {
4109 /* A string. Add to the display line and check for %-constructs 4109 /* A string. Add to the display line and check for %-constructs
4110 within it. */ 4110 within it. */
4111 4111
4112 Ibyte *this_str = XSTRING_DATA (elt); 4112 Ibyte *this_str = XSTRING_DATA (elt);
4113 4113
4114 while ((pos < max_pos || max_pos == -1) && *this_str) 4114 while ((pos < max_pos || max_pos == -1) && *this_str)
4115 { 4115 {
4116 Ibyte *last = this_str; 4116 Ibyte *last = this_str;
4117 4117
4118 while (*this_str && *this_str != '%') 4118 while (*this_str && *this_str != '%')
4119 this_str++; 4119 this_str++;
4120 4120
4121 if (this_str != last) 4121 if (this_str != last)
4122 { 4122 {
4123 /* No %-construct */ 4123 /* No %-construct */
4124 Charcount size = 4124 Charcount size =
4125 bytecount_to_charcount (last, this_str - last); 4125 bytecount_to_charcount (last, this_str - last);
4126 4126
4127 if (size <= *offset) 4127 if (size <= *offset)
4128 *offset -= size; 4128 *offset -= size;
4129 else 4129 else
4134 4134
4135 pos = add_string_to_fstring_db_runes (data, tmp_last, 4135 pos = add_string_to_fstring_db_runes (data, tmp_last,
4136 pos, pos, tmp_max); 4136 pos, pos, tmp_max);
4137 *offset = 0; 4137 *offset = 0;
4138 } 4138 }
4139 } 4139 }
4140 else /* *this_str == '%' */ 4140 else /* *this_str == '%' */
4141 { 4141 {
4142 Charcount spec_width = 0; 4142 Charcount spec_width = 0;
4143 4143
4144 this_str++; /* skip over '%' */ 4144 this_str++; /* skip over '%' */
4145 4145
4146 /* We can't allow -ve args due to the "%-" construct. 4146 /* We can't allow -ve args due to the "%-" construct.
4147 * Argument specifies minwidth but not maxwidth 4147 * Argument specifies minwidth but not maxwidth
4148 * (maxwidth can be specified by 4148 * (maxwidth can be specified by
4149 * (<negative-number> . <stuff>) modeline elements) 4149 * (<negative-number> . <stuff>) modeline elements)
4150 */ 4150 */
4151 while (isdigit (*this_str)) 4151 while (isdigit (*this_str))
4152 { 4152 {
4153 spec_width = spec_width * 10 + (*this_str - '0'); 4153 spec_width = spec_width * 10 + (*this_str - '0');
4154 this_str++; 4154 this_str++;
4155 } 4155 }
4156 spec_width += pos; 4156 spec_width += pos;
4157 4157
4158 if (*this_str == 'M') 4158 if (*this_str == 'M')
4159 { 4159 {
4160 pos = generate_fstring_runes (w, data, pos, spec_width, 4160 pos = generate_fstring_runes (w, data, pos, spec_width,
4161 max_pos, Vglobal_mode_string, 4161 max_pos, Vglobal_mode_string,
4162 depth, max_pixsize, findex, 4162 depth, max_pixsize, findex,
4163 type, offset, cur_ext); 4163 type, offset, cur_ext);
4164 } 4164 }
4165 else if (*this_str == '-') 4165 else if (*this_str == '-')
4166 { 4166 {
4167 Charcount num_to_add; 4167 Charcount num_to_add;
4168 4168
4169 if (max_pixsize < 0) 4169 if (max_pixsize < 0)
4170 num_to_add = 0; 4170 num_to_add = 0;
4171 else if (max_pos != -1) 4171 else if (max_pos != -1)
4172 num_to_add = max_pos - pos; 4172 num_to_add = max_pos - pos;
4173 else 4173 else
4174 { 4174 {
4175 int cur_pixsize; 4175 int cur_pixsize;
4176 int dash_pixsize; 4176 int dash_pixsize;
4177 Ibyte ch = '-'; 4177 Ibyte ch = '-';
4178 SET_CURRENT_MODE_CHARS_PIXSIZE; 4178 SET_CURRENT_MODE_CHARS_PIXSIZE;
4179 4179
4180 dash_pixsize = 4180 dash_pixsize =
4181 redisplay_text_width_string (w, findex, &ch, Qnil, 0, 4181 redisplay_text_width_string (w, findex, &ch, Qnil, 0,
4182 1); 4182 1);
4183 4183
4184 if (dash_pixsize == 0) 4184 if (dash_pixsize == 0)
4185 num_to_add = 0; 4185 num_to_add = 0;
4186 else { 4186 else {
4187 num_to_add = (max_pixsize - cur_pixsize) / dash_pixsize; 4187 num_to_add = (max_pixsize - cur_pixsize) / dash_pixsize;
4188 num_to_add++; 4188 num_to_add++;
4189 } 4189 }
4190 } 4190 }
4191 4191
4192 while (num_to_add--) 4192 while (num_to_add--)
4193 pos = add_string_to_fstring_db_runes 4193 pos = add_string_to_fstring_db_runes
4194 (data, (const Ibyte *) "-", pos, pos, max_pos); 4194 (data, (const Ibyte *) "-", pos, pos, max_pos);
4195 } 4195 }
4196 else if (*this_str != 0) 4196 else if (*this_str != 0)
4197 { 4197 {
4198 Ichar ch = itext_ichar (this_str); 4198 Ichar ch = itext_ichar (this_str);
4199 Ibyte *str; 4199 Ibyte *str;
4200 Charcount size; 4200 Charcount size;
4201 4201
4202 decode_mode_spec (w, ch, type); 4202 decode_mode_spec (w, ch, type);
4203 4203
4204 str = Dynarr_atp (mode_spec_ibyte_string, 0); 4204 str = Dynarr_atp (mode_spec_ibyte_string, 0);
4205 size = bytecount_to_charcount 4205 size = bytecount_to_charcount
4206 /* Skip the null character added by `decode_mode_spec' */ 4206 /* Skip the null character added by `decode_mode_spec' */
4207 (str, Dynarr_length (mode_spec_ibyte_string)) - 1; 4207 (str, Dynarr_length (mode_spec_ibyte_string)) - 1;
4208 4208
4209 if (size <= *offset) 4209 if (size <= *offset)
4218 pos = add_string_to_fstring_db_runes (data, tmp_str, 4218 pos = add_string_to_fstring_db_runes (data, tmp_str,
4219 pos, pos, 4219 pos, pos,
4220 max_pos); 4220 max_pos);
4221 *offset = 0; 4221 *offset = 0;
4222 } 4222 }
4223 } 4223 }
4224 4224
4225 /* NOT this_str++. There could be any sort of character at 4225 /* NOT this_str++. There could be any sort of character at
4226 the current position. */ 4226 the current position. */
4227 INC_IBYTEPTR (this_str); 4227 INC_IBYTEPTR (this_str);
4228 } 4228 }
4229 4229
4230 if (max_pixsize > 0) 4230 if (max_pixsize > 0)
4231 { 4231 {
4232 int cur_pixsize; 4232 int cur_pixsize;
4233 SET_CURRENT_MODE_CHARS_PIXSIZE; 4233 SET_CURRENT_MODE_CHARS_PIXSIZE;
4234 4234
4235 if (cur_pixsize >= max_pixsize) 4235 if (cur_pixsize >= max_pixsize)
4236 break; 4236 break;
4237 } 4237 }
4238 } 4238 }
4239 } 4239 }
4240 else if (SYMBOLP (elt)) 4240 else if (SYMBOLP (elt))
4241 { 4241 {
4242 /* A symbol: process the value of the symbol recursively 4242 /* A symbol: process the value of the symbol recursively
4243 as if it appeared here directly. */ 4243 as if it appeared here directly. */
4244 Lisp_Object tem = symbol_value_in_buffer (elt, w->buffer); 4244 Lisp_Object tem = symbol_value_in_buffer (elt, w->buffer);
4245 4245
4246 if (!UNBOUNDP (tem)) 4246 if (!UNBOUNDP (tem))
4247 { 4247 {
4248 /* If value is a string, output that string literally: 4248 /* If value is a string, output that string literally:
4249 don't check for % within it. */ 4249 don't check for % within it. */
4250 if (STRINGP (tem)) 4250 if (STRINGP (tem))
4251 { 4251 {
4252 Ibyte *str = XSTRING_DATA (tem); 4252 Ibyte *str = XSTRING_DATA (tem);
4253 Charcount size = string_char_length (tem); 4253 Charcount size = string_char_length (tem);
4254 4254
4255 if (size <= *offset) 4255 if (size <= *offset)
4256 *offset -= size; 4256 *offset -= size;
4263 above. -- dv */ 4263 above. -- dv */
4264 pos = add_string_to_fstring_db_runes (data, tmp_str, pos, 4264 pos = add_string_to_fstring_db_runes (data, tmp_str, pos,
4265 min_pos, max_pos); 4265 min_pos, max_pos);
4266 *offset = 0; 4266 *offset = 0;
4267 } 4267 }
4268 } 4268 }
4269 /* Give up right away for nil or t. */ 4269 /* Give up right away for nil or t. */
4270 else if (!EQ (tem, elt)) 4270 else if (!EQ (tem, elt))
4271 { 4271 {
4272 elt = tem; 4272 elt = tem;
4273 goto tail_recurse; 4273 goto tail_recurse;
4274 } 4274 }
4275 } 4275 }
4276 } 4276 }
4277 else if (GENERIC_SPECIFIERP (elt)) 4277 else if (GENERIC_SPECIFIERP (elt))
4278 { 4278 {
4279 Lisp_Object window, tem; 4279 Lisp_Object window, tem;
4280 window = wrap_window (w); 4280 window = wrap_window (w);
4339 elt = XCAR (elt); 4339 elt = XCAR (elt);
4340 goto tail_recurse; 4340 goto tail_recurse;
4341 } 4341 }
4342 } 4342 }
4343 else if (INTP (car)) 4343 else if (INTP (car))
4344 { 4344 {
4345 Charcount lim = XINT (car); 4345 Charcount lim = XINT (car);
4346 4346
4347 elt = XCDR (elt); 4347 elt = XCDR (elt);
4348 4348
4349 if (lim < 0) 4349 if (lim < 0)
4350 { 4350 {
4351 /* Negative int means reduce maximum width. 4351 /* Negative int means reduce maximum width.
4352 * DO NOT change MIN_PIXPOS here! 4352 * DO NOT change MIN_PIXPOS here!
4353 * (20 -10 . foo) should truncate foo to 10 col 4353 * (20 -10 . foo) should truncate foo to 10 col
4354 * and then pad to 20. 4354 * and then pad to 20.
4355 */ 4355 */
4356 if (max_pos == -1) 4356 if (max_pos == -1)
4357 max_pos = pos - lim; 4357 max_pos = pos - lim;
4358 else 4358 else
4359 max_pos = min (max_pos, pos - lim); 4359 max_pos = min (max_pos, pos - lim);
4360 } 4360 }
4361 else if (lim > 0) 4361 else if (lim > 0)
4362 { 4362 {
4363 /* Padding specified. Don't let it be more than 4363 /* Padding specified. Don't let it be more than
4364 * current maximum. 4364 * current maximum.
4365 */ 4365 */
4366 lim += pos; 4366 lim += pos;
4367 if (max_pos != -1 && lim > max_pos) 4367 if (max_pos != -1 && lim > max_pos)
4368 lim = max_pos; 4368 lim = max_pos;
4369 /* If that's more padding than already wanted, queue it. 4369 /* If that's more padding than already wanted, queue it.
4370 * But don't reduce padding already specified even if 4370 * But don't reduce padding already specified even if
4371 * that is beyond the current truncation point. 4371 * that is beyond the current truncation point.
4372 */ 4372 */
4373 if (lim > min_pos) 4373 if (lim > min_pos)
4374 min_pos = lim; 4374 min_pos = lim;
4375 } 4375 }
4376 goto tail_recurse; 4376 goto tail_recurse;
4377 } 4377 }
4378 else if (STRINGP (car) || CONSP (car)) 4378 else if (STRINGP (car) || CONSP (car))
4379 { 4379 {
4380 int limit = 50; 4380 int limit = 50;
4381 4381
4382 /* LIMIT is to protect against circular lists. */ 4382 /* LIMIT is to protect against circular lists. */
4383 while (CONSP (elt) && --limit > 0 4383 while (CONSP (elt) && --limit > 0
4384 && (pos < max_pos || max_pos == -1)) 4384 && (pos < max_pos || max_pos == -1))
4385 { 4385 {
4386 pos = generate_fstring_runes (w, data, pos, pos, max_pos, 4386 pos = generate_fstring_runes (w, data, pos, pos, max_pos,
4387 XCAR (elt), depth, max_pixsize, 4387 XCAR (elt), depth, max_pixsize,
4388 findex, type, offset, cur_ext); 4388 findex, type, offset, cur_ext);
4389 elt = XCDR (elt); 4389 elt = XCDR (elt);
4390 } 4390 }
4391 } 4391 }
4392 else if (EXTENTP (car)) 4392 else if (EXTENTP (car))
4393 { 4393 {
4394 struct extent *ext = XEXTENT (car); 4394 struct extent *ext = XEXTENT (car);
4395 4395
4396 if (EXTENT_LIVE_P (ext)) 4396 if (EXTENT_LIVE_P (ext))
4397 { 4397 {
4398 face_index old_findex = data->findex; 4398 face_index old_findex = data->findex;
4399 Lisp_Object face; 4399 Lisp_Object face;
4400 Lisp_Object font_inst; 4400 Lisp_Object font_inst;
4401 face_index new_findex; 4401 face_index new_findex;
4402 Bytecount start = data->bytepos; 4402 Bytecount start = data->bytepos;
4403 4403
4404 face = extent_face (ext); 4404 face = extent_face (ext);
4405 if (FACEP (face)) 4405 if (FACEP (face))
4406 { 4406 {
4407 /* #### needs to merge faces, sigh */ 4407 /* #### needs to merge faces, sigh */
4408 /* #### needs to handle list of faces */ 4408 /* #### needs to handle list of faces */
4409 new_findex = get_builtin_face_cache_index (w, face); 4409 new_findex = get_builtin_face_cache_index (w, face);
4410 /* !!#### not right; needs to compute the max height of 4410 /* !!#### not right; needs to compute the max height of
4411 all the charsets */ 4411 all the charsets */
4412 font_inst = WINDOW_FACE_CACHEL_FONT (w, new_findex, 4412 font_inst = WINDOW_FACE_CACHEL_FONT (w, new_findex,
4413 Vcharset_ascii); 4413 Vcharset_ascii);
4414 4414
4415 data->dl->ascent = max (data->dl->ascent, 4415 data->dl->ascent = max (data->dl->ascent,
4416 XFONT_INSTANCE (font_inst)->ascent); 4416 XFONT_INSTANCE (font_inst)->ascent);
4417 data->dl->descent = max (data->dl->descent, 4417 data->dl->descent = max (data->dl->descent,
4418 XFONT_INSTANCE (font_inst)-> 4418 XFONT_INSTANCE (font_inst)->
4419 descent); 4419 descent);
4420 } 4420 }
4421 else 4421 else
4422 new_findex = old_findex; 4422 new_findex = old_findex;
4423 4423
4424 data->findex = new_findex; 4424 data->findex = new_findex;
4425 pos = generate_fstring_runes (w, data, pos, pos, max_pos, 4425 pos = generate_fstring_runes (w, data, pos, pos, max_pos,
4426 XCDR (elt), depth - 1, 4426 XCDR (elt), depth - 1,
4427 max_pixsize, new_findex, type, 4427 max_pixsize, new_findex, type,
4428 offset, car); 4428 offset, car);
4429 data->findex = old_findex; 4429 data->findex = old_findex;
4430 Dynarr_add (formatted_string_extent_dynarr, ext); 4430 Dynarr_add (formatted_string_extent_dynarr, ext);
4431 Dynarr_add (formatted_string_extent_start_dynarr, start); 4431 Dynarr_add (formatted_string_extent_start_dynarr, start);
4432 Dynarr_add (formatted_string_extent_end_dynarr, data->bytepos); 4432 Dynarr_add (formatted_string_extent_end_dynarr, data->bytepos);
4433 } 4433 }
4434 } 4434 }
4435 } 4435 }
4436 else if (GLYPHP (elt)) 4436 else if (GLYPHP (elt))
4437 { 4437 {
4438 /* Glyphs are considered as one character with respect to the modeline 4438 /* Glyphs are considered as one character with respect to the modeline
4439 horizontal scrolling facility. -- dv */ 4439 horizontal scrolling facility. -- dv */
4518 display_line_dynarr *dla; 4518 display_line_dynarr *dla;
4519 4519
4520 dla = window_display_lines (w, type); 4520 dla = window_display_lines (w, type);
4521 4521
4522 /* We don't care if there is a display line which is not 4522 /* We don't care if there is a display line which is not
4523 currently a modeline because it is definitely going to become 4523 currently a modeline because it is definitely going to become
4524 one if we have gotten to this point. */ 4524 one if we have gotten to this point. */
4525 if (Dynarr_length (dla) == 0) 4525 if (Dynarr_length (dla) == 0)
4526 { 4526 {
4527 if (Dynarr_largest (dla) > 0) 4527 if (Dynarr_largest (dla) > 0)
4528 Dynarr_increment (dla); 4528 Dynarr_increment (dla);
4529 else 4529 else
4533 Dynarr_add (dla, modeline); 4533 Dynarr_add (dla, modeline);
4534 } 4534 }
4535 } 4535 }
4536 4536
4537 /* If we're adding a new place marker go ahead and generate the 4537 /* If we're adding a new place marker go ahead and generate the
4538 modeline so that it is available for use by 4538 modeline so that it is available for use by
4539 window_modeline_height. */ 4539 window_modeline_height. */
4540 generate_modeline (w, Dynarr_atp (dla, 0), type); 4540 generate_modeline (w, Dynarr_atp (dla, 0), type);
4541 } 4541 }
4542 4542
4543 return need_modeline; 4543 return need_modeline;
4544 } 4544 }
4651 #### ...not yet implemented... Also, we extend the concept of 4651 #### ...not yet implemented... Also, we extend the concept of
4652 "mapping" to include a printf-like spec. Thus you can make all 4652 "mapping" to include a printf-like spec. Thus you can make all
4653 extended characters show up as hex with a display table like 4653 extended characters show up as hex with a display table like
4654 this: 4654 this:
4655 4655
4656 #s(range-table data ((256 524288) (format "%x"))) 4656 #s(range-table data ((256 524288) (format "%x")))
4657 4657
4658 Since more than one display table is possible, you have 4658 Since more than one display table is possible, you have
4659 great flexibility in mapping ranges of characters. */ 4659 great flexibility in mapping ranges of characters. */
4660 Ichar printable_min = b ? (CHAR_OR_CHAR_INTP (b->ctl_arrow) 4660 Ichar printable_min = b ? (CHAR_OR_CHAR_INTP (b->ctl_arrow)
4661 ? XCHAR_OR_CHAR_INT (b->ctl_arrow) 4661 ? XCHAR_OR_CHAR_INT (b->ctl_arrow)
4678 4678
4679 dl->used_prop_data = 0; 4679 dl->used_prop_data = 0;
4680 dl->num_chars = 0; 4680 dl->num_chars = 0;
4681 dl->line_continuation = 0; 4681 dl->line_continuation = 0;
4682 4682
4683 /* set up faces to use for clearing areas, used by 4683 /* Set up faces to use for clearing areas, used by output_display_line. */
4684 output_display_line */
4685 dl->default_findex = default_face; 4684 dl->default_findex = default_face;
4686 if (default_face) 4685 if (default_face > DEFAULT_INDEX)
4687 { 4686 {
4688 dl->left_margin_findex = default_face; 4687 dl->left_margin_findex = default_face;
4689 dl->right_margin_findex = default_face; 4688 dl->right_margin_findex = default_face;
4690 } 4689 }
4691 else 4690 else
4772 /* Check for face changes. */ 4771 /* Check for face changes. */
4773 if (initial || (!no_more_frags && data.byte_charpos == data.ef->end)) 4772 if (initial || (!no_more_frags && data.byte_charpos == data.ef->end))
4774 { 4773 {
4775 Lisp_Object last_glyph = Qnil; 4774 Lisp_Object last_glyph = Qnil;
4776 /* Deal with clipped glyphs that we have already displayed. */ 4775 /* Deal with clipped glyphs that we have already displayed. */
4777 if (*prop && Dynarr_atp (*prop, 0)->type == PROP_GLYPH) 4776 if (*prop && Dynarr_atp (*prop, 0)->type == PROP_GLYPH)
4778 { 4777 {
4779 last_glyph = Dynarr_atp (*prop, 0)->data.p_glyph.glyph; 4778 last_glyph = Dynarr_atp (*prop, 0)->data.p_glyph.glyph;
4780 Dynarr_free (*prop); 4779 Dynarr_free (*prop);
4781 *prop = 0; 4780 *prop = 0;
4782 } 4781 }
4783 /* Now compute the face and begin/end-glyph information. */ 4782 /* Now compute the face and begin/end-glyph information. */
4784 data.findex = 4783 data.findex =
4785 /* Remember that the extent-fragment routines deal in 4784 /* Remember that the extent-fragment routines deal in
4786 Bytexpos's. */ 4785 Bytexpos's. */
4787 extent_fragment_update (w, data.ef, data.byte_charpos, last_glyph); 4786 extent_fragment_update (w, data.ef, data.byte_charpos, last_glyph);
4788 /* This is somewhat cheesy but the alternative is to 4787 /* This is somewhat cheesy but the alternative is to
4789 propagate default_face into extent_fragment_update. */ 4788 propagate default_face into extent_fragment_update. */
4790 if (data.findex == DEFAULT_INDEX) 4789 if (data.findex == DEFAULT_INDEX)
4791 data.findex = default_face; 4790 data.findex = default_face;
4792 4791
4793 get_display_tables (w, data.findex, &face_dt, &window_dt); 4792 get_display_tables (w, data.findex, &face_dt, &window_dt);
4794 4793
4796 no_more_frags = 1; 4795 no_more_frags = 1;
4797 } 4796 }
4798 initial = 0; 4797 initial = 0;
4799 4798
4800 /* Determine what is next to be displayed. We first handle any 4799 /* Determine what is next to be displayed. We first handle any
4801 glyphs returned by glyphs_at_charbpos. If there are no glyphs to 4800 glyphs returned by glyphs_at_charbpos. If there are no glyphs to
4802 display then we determine what to do based on the character at the 4801 display then we determine what to do based on the character at the
4803 current buffer position. */ 4802 current buffer position. */
4804 4803
4805 /* If the current position is covered by an invisible extent, do 4804 /* If the current position is covered by an invisible extent, do
4806 nothing (except maybe add some ellipses). 4805 nothing (except maybe add some ellipses).
4807 4806
4808 #### The behavior of begin and end-glyphs at the edge of an 4807 #### The behavior of begin and end-glyphs at the edge of an
4809 invisible extent should be investigated further. This is 4808 invisible extent should be investigated further. This is
4810 fairly low priority though. */ 4809 fairly low priority though. */
4811 if (data.ef->invisible) 4810 if (data.ef->invisible)
4848 else 4847 else
4849 INC_BYTECOUNT (XSTRING_DATA (disp_string), data.byte_charpos); 4848 INC_BYTECOUNT (XSTRING_DATA (disp_string), data.byte_charpos);
4850 } 4849 }
4851 4850
4852 /* If there is propagation data, then it represents the current 4851 /* If there is propagation data, then it represents the current
4853 buffer position being displayed. Add them and advance the 4852 buffer position being displayed. Add them and advance the
4854 position counter. This might also add the minibuffer 4853 position counter. This might also add the minibuffer
4855 prompt. */ 4854 prompt. */
4856 else if (*prop) 4855 else if (*prop)
4857 { 4856 {
4858 dl->used_prop_data = 1; 4857 dl->used_prop_data = 1;
4859 *prop = add_propagation_runes (prop, &data); 4858 *prop = add_propagation_runes (prop, &data);
4860 4859
4908 data.ch = string_ichar (disp_string, data.byte_charpos); 4907 data.ch = string_ichar (disp_string, data.byte_charpos);
4909 if (!NILP (face_dt) || !NILP (window_dt)) 4908 if (!NILP (face_dt) || !NILP (window_dt))
4910 entry = display_table_entry (data.ch, face_dt, window_dt); 4909 entry = display_table_entry (data.ch, face_dt, window_dt);
4911 4910
4912 /* If there is a display table entry for it, hand it off to 4911 /* If there is a display table entry for it, hand it off to
4913 add_disp_table_entry_runes and let it worry about it. */ 4912 add_disp_table_entry_runes and let it worry about it. */
4914 if (!NILP (entry) && !EQ (entry, make_char (data.ch))) 4913 if (!NILP (entry) && !EQ (entry, make_char (data.ch)))
4915 { 4914 {
4916 *prop = add_disp_table_entry_runes (&data, entry); 4915 *prop = add_disp_table_entry_runes (&data, entry);
4917 4916
4918 if (*prop) 4917 if (*prop)
4919 goto done; 4918 goto done;
4920 } 4919 }
4921 4920
4922 /* Check if we have hit a newline character. If so, add a marker 4921 /* Check if we have hit a newline character. If so, add a marker
4923 to the line and end this loop. */ 4922 to the line and end this loop. */
4924 else if (data.ch == '\n') 4923 else if (data.ch == '\n')
4925 { 4924 {
4926 /* We aren't going to be adding an end glyph so give its 4925 /* We aren't going to be adding an end glyph so give its
4927 space back in order to make sure that the cursor can 4926 space back in order to make sure that the cursor can
4928 fit. */ 4927 fit. */
4929 data.max_pixpos += data.end_glyph_width; 4928 data.max_pixpos += data.end_glyph_width;
4930 goto done; 4929 goto done;
4931 } 4930 }
4932 4931
4933 /* If the current character is considered to be printable, then 4932 /* If the current character is considered to be printable, then
4934 just add it. */ 4933 just add it. */
4935 else if (data.ch >= printable_min) 4934 else if (data.ch >= printable_min)
4936 { 4935 {
4937 *prop = add_ichar_rune (&data); 4936 *prop = add_ichar_rune (&data);
4938 if (*prop) 4937 if (*prop)
4939 goto done; 4938 goto done;
4940 } 4939 }
4941 4940
4942 /* If the current character is a tab, determine the next tab 4941 /* If the current character is a tab, determine the next tab
4943 starting position and add a blank rune which extends from the 4942 starting position and add a blank rune which extends from the
4944 current pixel position to that starting position. */ 4943 current pixel position to that starting position. */
4945 else if (data.ch == '\t') 4944 else if (data.ch == '\t')
4946 { 4945 {
4947 int tab_start_pixpos = data.pixpos; 4946 int tab_start_pixpos = data.pixpos;
4948 int next_tab_start; 4947 int next_tab_start;
4949 int char_tab_width; 4948 int char_tab_width;
4984 goto done; 4983 goto done;
4985 } 4984 }
4986 } 4985 }
4987 4986
4988 /* If character is a control character, pass it off to 4987 /* If character is a control character, pass it off to
4989 add_control_char_runes. 4988 add_control_char_runes.
4990 4989
4991 The is_*() routines have undefined results on 4990 The is_*() routines have undefined results on
4992 arguments outside of the range [-1, 255]. (This 4991 arguments outside of the range [-1, 255]. (This
4993 often bites people who carelessly use `char' instead 4992 often bites people who carelessly use `char' instead
4994 of `unsigned char'.) 4993 of `unsigned char'.)
5000 if (*prop) 4999 if (*prop)
5001 goto done; 5000 goto done;
5002 } 5001 }
5003 5002
5004 /* If the character is above the ASCII range and we have not 5003 /* If the character is above the ASCII range and we have not
5005 already handled it, then print it as an octal number. */ 5004 already handled it, then print it as an octal number. */
5006 else if (data.ch >= 0200) 5005 else if (data.ch >= 0200)
5007 { 5006 {
5008 *prop = add_octal_runes (&data); 5007 *prop = add_octal_runes (&data);
5009 5008
5010 if (*prop) 5009 if (*prop)
5011 goto done; 5010 goto done;
5012 } 5011 }
5013 5012
5014 /* Assume the current character is considered to be printable, 5013 /* Assume the current character is considered to be printable,
5015 then just add it. */ 5014 then just add it. */
5016 else 5015 else
5017 { 5016 {
5018 *prop = add_ichar_rune (&data); 5017 *prop = add_ichar_rune (&data);
5019 if (*prop) 5018 if (*prop)
5020 goto done; 5019 goto done;
5037 you should be able to say '(if (*prop))'. That should also 5036 you should be able to say '(if (*prop))'. That should also
5038 make it possible to eliminate the data.byte_charpos < BYTE_BUF_ZV (b) 5037 make it possible to eliminate the data.byte_charpos < BYTE_BUF_ZV (b)
5039 check. */ 5038 check. */
5040 5039
5041 /* The common case is that the line ended because we hit a newline. 5040 /* The common case is that the line ended because we hit a newline.
5042 In that case, the next character is just the next buffer 5041 In that case, the next character is just the next buffer
5043 position. */ 5042 position. */
5044 if (data.ch == '\n') 5043 if (data.ch == '\n')
5045 { 5044 {
5046 INC_BYTECOUNT (XSTRING_DATA (disp_string), data.byte_charpos); 5045 INC_BYTECOUNT (XSTRING_DATA (disp_string), data.byte_charpos);
5047 } 5046 }
5048 5047
5049 /* Otherwise we have a buffer line which cannot fit on one display 5048 /* Otherwise we have a buffer line which cannot fit on one display
5050 line. */ 5049 line. */
5051 else 5050 else
5052 { 5051 {
5053 struct glyph_block gb; 5052 struct glyph_block gb;
5054 struct glyph_cachel *cachel; 5053 struct glyph_cachel *cachel;
5055 5054
5056 /* If the line is to be truncated then we actually have to look 5055 /* If the line is to be truncated then we actually have to look
5057 for the next newline. We also add the end-of-line glyph which 5056 for the next newline. We also add the end-of-line glyph which
5058 we know will fit because we adjusted the right border before 5057 we know will fit because we adjusted the right border before
5059 we starting laying out the line. */ 5058 we starting laying out the line. */
5060 data.max_pixpos += data.end_glyph_width; 5059 data.max_pixpos += data.end_glyph_width;
5061 data.findex = default_face; 5060 data.findex = default_face;
5062 gb.extent = Qnil; 5061 gb.extent = Qnil;
5063 5062
5064 if (truncate_win) 5063 if (truncate_win)
5367 Dynarr_lock (dla); 5366 Dynarr_lock (dla);
5368 next_pos = generate_string_display_line (w, disp_string, dlp, start_pos, 5367 next_pos = generate_string_display_line (w, disp_string, dlp, start_pos,
5369 &prop, default_face); 5368 &prop, default_face);
5370 Dynarr_unlock (dla); 5369 Dynarr_unlock (dla);
5371 /* we need to make sure that we continue along the line if there 5370 /* we need to make sure that we continue along the line if there
5372 is more left to display otherwise we just end up redisplaying 5371 is more left to display otherwise we just end up redisplaying
5373 the same chunk over and over again. */ 5372 the same chunk over and over again. */
5374 if (next_pos == start_pos && next_pos < s_zv) 5373 if (next_pos == start_pos && next_pos < s_zv)
5375 start_pos++; 5374 start_pos++;
5376 else 5375 else
5377 start_pos = next_pos; 5376 start_pos = next_pos;
5378 5377
5545 5544
5546 dlp->ypos = (ypos + dlp->ascent) - yclip; 5545 dlp->ypos = (ypos + dlp->ascent) - yclip;
5547 ypos = dlp->ypos + dlp->descent; 5546 ypos = dlp->ypos + dlp->descent;
5548 5547
5549 /* See if we've been asked to start midway through a line, for 5548 /* See if we've been asked to start midway through a line, for
5550 partial display line scrolling. */ 5549 partial display line scrolling. */
5551 if (yclip) 5550 if (yclip)
5552 { 5551 {
5553 dlp->top_clip = yclip; 5552 dlp->top_clip = yclip;
5554 yclip = 0; 5553 yclip = 0;
5555 } 5554 }
5577 dlp->clip = 0; 5576 dlp->clip = 0;
5578 5577
5579 if (dlp->cursor_elt != -1) 5578 if (dlp->cursor_elt != -1)
5580 { 5579 {
5581 /* #### This check is steaming crap. Have to get things 5580 /* #### This check is steaming crap. Have to get things
5582 fixed so when create_text_block hits EOB, we're done, 5581 fixed so when create_text_block hits EOB, we're done,
5583 period. */ 5582 period. */
5584 if (w->last_point_x[type] == -1) 5583 if (w->last_point_x[type] == -1)
5585 { 5584 {
5586 w->last_point_x[type] = dlp->cursor_elt; 5585 w->last_point_x[type] = dlp->cursor_elt;
5587 w->last_point_y[type] = Dynarr_length (dla); 5586 w->last_point_y[type] = Dynarr_length (dla);
5588 } 5587 }
5589 else 5588 else
5590 { 5589 {
5591 /* #### This means that we've added a cursor at EOB 5590 /* #### This means that we've added a cursor at EOB
5592 twice. Yuck oh yuck. */ 5591 twice. Yuck oh yuck. */
5593 struct display_block *db; 5592 struct display_block *db;
5594 5593
5595 Dynarr_lock (dla); 5594 Dynarr_lock (dla);
5596 db = get_display_block_from_line (dlp, TEXT); 5595 db = get_display_block_from_line (dlp, TEXT);
5597 Dynarr_unlock (dla); 5596 Dynarr_unlock (dla);
5633 w->window_end_pos[type] = BUF_Z (b) - w->window_end_pos[type]; 5632 w->window_end_pos[type] = BUF_Z (b) - w->window_end_pos[type];
5634 5633
5635 if (need_modeline) 5634 if (need_modeline)
5636 { 5635 {
5637 /* We know that this is the right thing to use because we put it 5636 /* We know that this is the right thing to use because we put it
5638 there when we first started working in this function. */ 5637 there when we first started working in this function. */
5639 generate_modeline (w, Dynarr_atp (dla, 0), type); 5638 generate_modeline (w, Dynarr_atp (dla, 0), type);
5640 } 5639 }
5641 5640
5642 if (depth >= 0) 5641 if (depth >= 0)
5643 exit_redisplay_critical_section (depth); 5642 exit_redisplay_critical_section (depth);
5727 { 5726 {
5728 5727
5729 if (redisplay_move_cursor (w, pointm, WINDOW_TTY_P (w))) 5728 if (redisplay_move_cursor (w, pointm, WINDOW_TTY_P (w)))
5730 { 5729 {
5731 /* Always regenerate the modeline in case it is 5730 /* Always regenerate the modeline in case it is
5732 displaying the current line or column. */ 5731 displaying the current line or column. */
5733 regenerate_modeline (w); 5732 regenerate_modeline (w);
5734 success = 1; 5733 success = 1;
5735 } 5734 }
5736 } 5735 }
5737 else if (w != XWINDOW (FRAME_SELECTED_WINDOW (sel_f))) 5736 else if (w != XWINDOW (FRAME_SELECTED_WINDOW (sel_f)))
5812 initial_size = Dynarr_length (db->runes); 5811 initial_size = Dynarr_length (db->runes);
5813 old_start = ddl->charpos + ddl->offset; 5812 old_start = ddl->charpos + ddl->offset;
5814 old_end = ddl->end_charpos + ddl->offset; 5813 old_end = ddl->end_charpos + ddl->offset;
5815 5814
5816 /* If this is the first line being updated and it used 5815 /* If this is the first line being updated and it used
5817 propagation data, fail. Otherwise we'll be okay because 5816 propagation data, fail. Otherwise we'll be okay because
5818 we'll have the necessary propagation data. */ 5817 we'll have the necessary propagation data. */
5819 if (line == first_line && ddl->used_prop_data) 5818 if (line == first_line && ddl->used_prop_data)
5820 return 0; 5819 return 0;
5821 5820
5822 generate_display_line (w, ddl, 0, ddl->charpos + ddl->offset, 5821 generate_display_line (w, ddl, 0, ddl->charpos + ddl->offset,
5823 &prop, DESIRED_DISP); 5822 &prop, DESIRED_DISP);
5824 ddl->offset = 0; 5823 ddl->offset = 0;
5825 5824
5826 /* #### If there is propagated stuff the fail. We could 5825 /* #### If there is propagated stuff the fail. We could
5827 probably actually deal with this if the line had propagated 5826 probably actually deal with this if the line had propagated
5828 information when originally created by a full 5827 information when originally created by a full
5829 regeneration. */ 5828 regeneration. */
5830 if (prop) 5829 if (prop)
5831 { 5830 {
5832 Dynarr_free (prop); 5831 Dynarr_free (prop);
5833 return 0; 5832 return 0;
5834 } 5833 }
5835 5834
5836 /* If any line position parameters have changed or a 5835 /* If any line position parameters have changed or a
5837 cursor has disappeared or disappeared, fail. */ 5836 cursor has disappeared or disappeared, fail. */
5838 db = get_display_block_from_line (ddl, TEXT); 5837 db = get_display_block_from_line (ddl, TEXT);
5839 if (cdl->ypos != ddl->ypos 5838 if (cdl->ypos != ddl->ypos
5840 || cdl->ascent != ddl->ascent 5839 || cdl->ascent != ddl->ascent
5841 || cdl->descent != ddl->descent 5840 || cdl->descent != ddl->descent
5842 || cdl->top_clip != ddl->top_clip 5841 || cdl->top_clip != ddl->top_clip
5856 } 5855 }
5857 5856
5858 last_line = line; 5857 last_line = line;
5859 5858
5860 /* If the extent changes end on the line we just updated then 5859 /* If the extent changes end on the line we just updated then
5861 we're done. Otherwise go on to the next line. */ 5860 we're done. Otherwise go on to the next line. */
5862 if (end_unchanged <= ddl->end_charpos) 5861 if (end_unchanged <= ddl->end_charpos)
5863 break; 5862 break;
5864 else 5863 else
5865 line++; 5864 line++;
5866 } 5865 }
5973 generate_display_line (w, ddl, 0, ddl->charpos + ddl->offset, 5972 generate_display_line (w, ddl, 0, ddl->charpos + ddl->offset,
5974 &prop, DESIRED_DISP); 5973 &prop, DESIRED_DISP);
5975 ddl->offset = 0; 5974 ddl->offset = 0;
5976 5975
5977 /* If there is propagated stuff then it is pretty much a 5976 /* If there is propagated stuff then it is pretty much a
5978 guarantee that more than just the one line is affected. */ 5977 guarantee that more than just the one line is affected. */
5979 if (prop) 5978 if (prop)
5980 { 5979 {
5981 Dynarr_free (prop); 5980 Dynarr_free (prop);
5982 return 0; 5981 return 0;
5983 } 5982 }
5985 /* If the line continues to next display line, fail. */ 5984 /* If the line continues to next display line, fail. */
5986 if (ddl->line_continuation) 5985 if (ddl->line_continuation)
5987 return 0; 5986 return 0;
5988 5987
5989 /* If any line position parameters have changed or a 5988 /* If any line position parameters have changed or a
5990 cursor has disappeared or disappeared, fail. */ 5989 cursor has disappeared or disappeared, fail. */
5991 if (cdl->ypos != ddl->ypos 5990 if (cdl->ypos != ddl->ypos
5992 || cdl->ascent != ddl->ascent 5991 || cdl->ascent != ddl->ascent
5993 || cdl->descent != ddl->descent 5992 || cdl->descent != ddl->descent
5994 || cdl->top_clip != ddl->top_clip 5993 || cdl->top_clip != ddl->top_clip
5995 || (cdl->cursor_elt != -1 && ddl->cursor_elt == -1) 5994 || (cdl->cursor_elt != -1 && ddl->cursor_elt == -1)
5997 { 5996 {
5998 return 0; 5997 return 0;
5999 } 5998 }
6000 5999
6001 /* If the changed area also ends on this line, then we may be in 6000 /* If the changed area also ends on this line, then we may be in
6002 business. Update everything and return success. */ 6001 business. Update everything and return success. */
6003 if (end_unchanged >= ddl->charpos && end_unchanged <= ddl->end_charpos) 6002 if (end_unchanged >= ddl->charpos && end_unchanged <= ddl->end_charpos)
6004 { 6003 {
6005 w->last_modified[DESIRED_DISP] = make_int (BUF_MODIFF (b)); 6004 w->last_modified[DESIRED_DISP] = make_int (BUF_MODIFF (b));
6006 w->last_facechange[DESIRED_DISP] = make_int (BUF_FACECHANGE (b)); 6005 w->last_facechange[DESIRED_DISP] = make_int (BUF_FACECHANGE (b));
6007 Fset_marker (w->last_start[DESIRED_DISP], make_int (startp), 6006 Fset_marker (w->last_start[DESIRED_DISP], make_int (startp),
6017 6016
6018 redisplay_update_line (w, line, line, 1); 6017 redisplay_update_line (w, line, line, 1);
6019 regenerate_modeline (w); 6018 regenerate_modeline (w);
6020 6019
6021 /* #### For now we just flush the cache until this has been 6020 /* #### For now we just flush the cache until this has been
6022 tested. After that is done, this should correct the 6021 tested. After that is done, this should correct the
6023 cache directly. */ 6022 cache directly. */
6024 Dynarr_reset (w->line_start_cache); 6023 Dynarr_reset (w->line_start_cache);
6025 6024
6026 /* Adjust the extent changed boundaries to remove any 6025 /* Adjust the extent changed boundaries to remove any
6027 overlap with the buffer changes since we've just 6026 overlap with the buffer changes since we've just
6028 successfully updated that area. */ 6027 successfully updated that area. */
6029 if (extent_beg_unchanged != -1 6028 if (extent_beg_unchanged != -1
6030 && extent_beg_unchanged >= beg_unchanged 6029 && extent_beg_unchanged >= beg_unchanged
6031 && extent_beg_unchanged < end_unchanged) 6030 && extent_beg_unchanged < end_unchanged)
6032 extent_beg_unchanged = end_unchanged; 6031 extent_beg_unchanged = end_unchanged;
6033 6032
6038 6037
6039 if (extent_end_unchanged <= extent_beg_unchanged) 6038 if (extent_end_unchanged <= extent_beg_unchanged)
6040 extent_beg_unchanged = extent_end_unchanged = -1; 6039 extent_beg_unchanged = extent_end_unchanged = -1;
6041 6040
6042 /* This could lead to odd results if it fails, but since the 6041 /* This could lead to odd results if it fails, but since the
6043 buffer changes update succeeded this probably will to. 6042 buffer changes update succeeded this probably will to.
6044 We already know that the extent changes start at or after 6043 We already know that the extent changes start at or after
6045 the line because we checked before entering the loop. */ 6044 the line because we checked before entering the loop. */
6046 if (extent_beg_unchanged != -1 6045 if (extent_beg_unchanged != -1
6047 && extent_end_unchanged != -1 6046 && extent_end_unchanged != -1
6048 && ((extent_beg_unchanged < ddl->charpos) 6047 && ((extent_beg_unchanged < ddl->charpos)
6049 || (extent_end_unchanged > ddl->end_charpos))) 6048 || (extent_end_unchanged > ddl->end_charpos)))
6050 return regenerate_window_extents_only_changed (w, startp, pointm, 6049 return regenerate_window_extents_only_changed (w, startp, pointm,
6251 b = XBUFFER (w->buffer); 6250 b = XBUFFER (w->buffer);
6252 6251
6253 if (echo_active) 6252 if (echo_active)
6254 { 6253 {
6255 old_pointm = selected_globally 6254 old_pointm = selected_globally
6256 ? BUF_PT (b) 6255 ? BUF_PT (b)
6257 : marker_position (w->pointm[CURRENT_DISP]); 6256 : marker_position (w->pointm[CURRENT_DISP]);
6258 pointm = 1; 6257 pointm = 1;
6259 } 6258 }
6260 else 6259 else
6261 { 6260 {
6262 if (selected_globally) 6261 if (selected_globally)
6341 6340
6342 Fset_marker (w->pointm[DESIRED_DISP], make_int (pointm), 6341 Fset_marker (w->pointm[DESIRED_DISP], make_int (pointm),
6343 the_buffer); 6342 the_buffer);
6344 6343
6345 /* #### BUFU amounts of overkill just to get the cursor 6344 /* #### BUFU amounts of overkill just to get the cursor
6346 location marked properly. FIX ME FIX ME FIX ME */ 6345 location marked properly. FIX ME FIX ME FIX ME */
6347 regenerate_window (w, startp, pointm, DESIRED_DISP); 6346 regenerate_window (w, startp, pointm, DESIRED_DISP);
6348 } 6347 }
6349 6348
6350 goto regeneration_done; 6349 goto regeneration_done;
6351 } 6350 }
6354 need to make sure that point is still visible. */ 6353 need to make sure that point is still visible. */
6355 if (XINT (w->last_modified[CURRENT_DISP]) >= BUF_MODIFF (b) 6354 if (XINT (w->last_modified[CURRENT_DISP]) >= BUF_MODIFF (b)
6356 && XINT (w->last_facechange[CURRENT_DISP]) >= BUF_FACECHANGE (b) 6355 && XINT (w->last_facechange[CURRENT_DISP]) >= BUF_FACECHANGE (b)
6357 && pointm >= startp 6356 && pointm >= startp
6358 /* This check is to make sure we restore the minibuffer after a 6357 /* This check is to make sure we restore the minibuffer after a
6359 temporary change to the echo area. */ 6358 temporary change to the echo area. */
6360 && !(MINI_WINDOW_P (w) && f->buffers_changed) 6359 && !(MINI_WINDOW_P (w) && f->buffers_changed)
6361 && !f->frame_changed 6360 && !f->frame_changed
6362 && !truncation_changed 6361 && !truncation_changed
6363 /* check whether start is really at the beginning of a line GE */ 6362 /* check whether start is really at the beginning of a line GE */
6364 && (!w->start_at_line_beg || beginning_of_line_p (b, startp)) 6363 && (!w->start_at_line_beg || beginning_of_line_p (b, startp))
6386 goto regeneration_done; 6385 goto regeneration_done;
6387 } 6386 }
6388 else 6387 else
6389 { 6388 {
6390 /* If the new point is visible in the redisplay structures, 6389 /* If the new point is visible in the redisplay structures,
6391 then let the output update routines handle it, otherwise 6390 then let the output update routines handle it, otherwise
6392 do things the hard way. */ 6391 do things the hard way. */
6393 if (!w->windows_changed 6392 if (!w->windows_changed
6394 && !f->clip_changed 6393 && !f->clip_changed
6395 && !f->extents_changed 6394 && !f->extents_changed
6396 && !f->faces_changed 6395 && !f->faces_changed
6397 && !f->glyphs_changed 6396 && !f->glyphs_changed
6404 && w->last_point_y[CURRENT_DISP] != -1) 6403 && w->last_point_y[CURRENT_DISP] != -1)
6405 { 6404 {
6406 if (redisplay_move_cursor (w, pointm, FRAME_TTY_P (f))) 6405 if (redisplay_move_cursor (w, pointm, FRAME_TTY_P (f)))
6407 { 6406 {
6408 /* Always regenerate in case it is displaying 6407 /* Always regenerate in case it is displaying
6409 the current line or column. */ 6408 the current line or column. */
6410 regenerate_modeline (w); 6409 regenerate_modeline (w);
6411 6410
6412 skip_output = 1; 6411 skip_output = 1;
6413 goto regeneration_done; 6412 goto regeneration_done;
6414 } 6413 }
6422 goto regeneration_done; 6421 goto regeneration_done;
6423 } 6422 }
6424 } 6423 }
6425 6424
6426 /* If we weren't able to take the shortcut method, then use 6425 /* If we weren't able to take the shortcut method, then use
6427 the brute force method. */ 6426 the brute force method. */
6428 regenerate_window (w, startp, pointm, DESIRED_DISP); 6427 regenerate_window (w, startp, pointm, DESIRED_DISP);
6429 6428
6430 if (point_visible (w, pointm, DESIRED_DISP)) 6429 if (point_visible (w, pointm, DESIRED_DISP))
6431 goto regeneration_done; 6430 goto regeneration_done;
6432 } 6431 }
6711 { 6710 {
6712 /* we used to have a function to do this for only one frame, and 6711 /* we used to have a function to do this for only one frame, and
6713 it was typical to call it at the end of a critical section 6712 it was typical to call it at the end of a critical section
6714 (which occurs once per frame); but what then happens if multiple 6713 (which occurs once per frame); but what then happens if multiple
6715 frames have frame changes held up? 6714 frames have frame changes held up?
6716 6715
6717 This means we are O(N^2) over frames. I seriously doubt it matters. 6716 This means we are O(N^2) over frames. I seriously doubt it matters.
6718 --ben */ 6717 --ben */
6719 Lisp_Object frmcons, devcons, concons; 6718 Lisp_Object frmcons, devcons, concons;
6720 6719
6721 FRAME_LOOP_NO_BREAK (frmcons, devcons, concons) 6720 FRAME_LOOP_NO_BREAK (frmcons, devcons, concons)
6722 { 6721 {
6723 struct frame *f = XFRAME (XCAR (frmcons)); 6722 struct frame *f = XFRAME (XCAR (frmcons));
6724 if (f->size_change_pending) 6723 if (f->size_change_pending)
6725 change_frame_size (f, f->new_height, f->new_width, 0); 6724 change_frame_size (f, f->new_height, f->new_width, 0);
7029 if (preempted) 7028 if (preempted)
7030 return 1; 7029 return 1;
7031 } 7030 }
7032 7031
7033 /* If the frame redisplay did not get preempted, then this flag 7032 /* If the frame redisplay did not get preempted, then this flag
7034 should have gotten set to 0. It might be possible for that 7033 should have gotten set to 0. It might be possible for that
7035 not to happen if a size change event were to occur at an odd 7034 not to happen if a size change event were to occur at an odd
7036 time. To make sure we don't miss anything we simply don't 7035 time. To make sure we don't miss anything we simply don't
7037 reset the top level flags until the condition ends up being 7036 reset the top level flags until the condition ends up being
7038 in the right state. */ 7037 in the right state. */
7039 if (f->size_changed) 7038 if (f->size_changed)
7040 size_change_failed = 1; 7039 size_change_failed = 1;
7041 } 7040 }
7042 7041
7043 DEVICE_FRAME_LOOP (frmcons, d) 7042 DEVICE_FRAME_LOOP (frmcons, d)
7161 { 7160 {
7162 if (last_display_warning_tick != display_warning_tick && 7161 if (last_display_warning_tick != display_warning_tick &&
7163 !inhibit_warning_display) 7162 !inhibit_warning_display)
7164 { 7163 {
7165 /* If an error occurs during this function, oh well. 7164 /* If an error occurs during this function, oh well.
7166 If we report another warning, we could get stuck in an 7165 If we report another warning, we could get stuck in an
7167 infinite loop reporting warnings. */ 7166 infinite loop reporting warnings. */
7168 call0_trapping_problems 7167 call0_trapping_problems
7169 (0, Qdisplay_warning_buffer, 7168 (0, Qdisplay_warning_buffer,
7170 INHIBIT_EXISTING_PERMANENT_DISPLAY_OBJECT_DELETION); 7169 INHIBIT_EXISTING_PERMANENT_DISPLAY_OBJECT_DELETION);
7171 last_display_warning_tick = display_warning_tick; 7170 last_display_warning_tick = display_warning_tick;
7251 break; 7250 break;
7252 7251
7253 /* print the current column */ 7252 /* print the current column */
7254 case 'c': 7253 case 'c':
7255 { 7254 {
7256 Charbpos pt = (w == XWINDOW (Fselected_window (Qnil))) 7255 Charbpos pt = (w == XWINDOW (Fselected_window (Qnil)))
7257 ? BUF_PT (b) 7256 ? BUF_PT (b)
7258 : marker_position (w->pointm[type]); 7257 : marker_position (w->pointm[type]);
7259 int col = column_at_point (b, pt, 1) + !!column_number_start_at_one; 7258 int col = column_at_point (b, pt, 1) + !!column_number_start_at_one;
7260 char buf[DECIMAL_PRINT_SIZE (long)]; 7259 char buf[DECIMAL_PRINT_SIZE (long)];
7261 7260
7262 long_to_string (buf, col); 7261 long_to_string (buf, col);
7263 7262
7267 goto decode_mode_spec_done; 7266 goto decode_mode_spec_done;
7268 } 7267 }
7269 /* print the file coding system */ 7268 /* print the file coding system */
7270 case 'C': 7269 case 'C':
7271 { 7270 {
7272 Lisp_Object codesys = b->buffer_file_coding_system; 7271 Lisp_Object codesys = b->buffer_file_coding_system;
7273 /* Be very careful here not to get an error. */ 7272 /* Be very careful here not to get an error. */
7274 if (NILP (codesys) || SYMBOLP (codesys) || CODING_SYSTEMP (codesys)) 7273 if (NILP (codesys) || SYMBOLP (codesys) || CODING_SYSTEMP (codesys))
7275 { 7274 {
7276 codesys = find_coding_system_for_text_file (codesys, 0); 7275 codesys = find_coding_system_for_text_file (codesys, 0);
7277 if (CODING_SYSTEMP (codesys)) 7276 if (CODING_SYSTEMP (codesys))
7278 obj = XCODING_SYSTEM_MNEMONIC (codesys); 7277 obj = XCODING_SYSTEM_MNEMONIC (codesys);
7279 } 7278 }
7280 } 7279 }
7281 break; 7280 break;
7282 7281
7283 /* print the current line number */ 7282 /* print the current line number */
7284 case 'l': 7283 case 'l':
7321 ? "*" 7320 ? "*"
7322 : "-")); 7321 : "-"));
7323 break; 7322 break;
7324 7323
7325 /* print * or hyphen -- XEmacs change to allow a buffer to be 7324 /* print * or hyphen -- XEmacs change to allow a buffer to be
7326 read-only but still indicate whether it is modified. */ 7325 read-only but still indicate whether it is modified. */
7327 case '+': 7326 case '+':
7328 str = ((BUF_MODIFF (b) > BUF_SAVE_MODIFF (b)) 7327 str = ((BUF_MODIFF (b) > BUF_SAVE_MODIFF (b))
7329 ? "*" 7328 ? "*"
7330 : (!NILP (b->read_only) 7329 : (!NILP (b->read_only)
7331 ? "%" 7330 ? "%"
7332 : "-")); 7331 : "-"));
7333 break; 7332 break;
7334 7333
7335 /* #### defined in 19.29 decode_mode_spec, but not in 7334 /* #### defined in 19.29 decode_mode_spec, but not in
7336 modeline-format doc string. */ 7335 modeline-format doc string. */
7337 /* This differs from %* in that it ignores read-only-ness. */ 7336 /* This differs from %* in that it ignores read-only-ness. */
7338 case '&': 7337 case '&':
7339 str = ((BUF_MODIFF (b) > BUF_SAVE_MODIFF (b)) 7338 str = ((BUF_MODIFF (b) > BUF_SAVE_MODIFF (b))
7340 ? "*" 7339 ? "*"
7341 : "-"); 7340 : "-");
7377 else if (pos <= BUF_BEGV (b)) 7376 else if (pos <= BUF_BEGV (b))
7378 str = "Top"; 7377 str = "Top";
7379 else 7378 else
7380 { 7379 {
7381 /* This hard limit is ok since the string it will hold has a 7380 /* This hard limit is ok since the string it will hold has a
7382 fixed maximum length of 3. But just to be safe... */ 7381 fixed maximum length of 3. But just to be safe... */
7383 char buf[10]; 7382 char buf[10];
7384 Charcount chars = pos - BUF_BEGV (b); 7383 Charcount chars = pos - BUF_BEGV (b);
7385 Charcount total = BUF_ZV (b) - BUF_BEGV (b); 7384 Charcount total = BUF_ZV (b) - BUF_BEGV (b);
7386 7385
7387 /* Avoid overflow on big buffers */ 7386 /* Avoid overflow on big buffers */
7388 int percent = total > LONG_MAX/200 ? 7387 int percent = total > LONG_MAX/200 ?
7389 (chars + total/200) / (total / 100) : 7388 (chars + total/200) / (total / 100) :
7390 (chars * 100 + total/2) / total; 7389 (chars * 100 + total/2) / total;
7391 7390
7392 /* We can't normally display a 3-digit number, so get us a 7391 /* We can't normally display a 3-digit number, so get us a
7393 2-digit number that is close. */ 7392 2-digit number that is close. */
7394 if (percent == 100) 7393 if (percent == 100)
7395 percent = 99; 7394 percent = 99;
7396 7395
7397 sprintf (buf, "%d%%", percent); 7396 sprintf (buf, "%d%%", percent);
7398 Dynarr_add_many (mode_spec_ibyte_string, (Ibyte *) buf, 7397 Dynarr_add_many (mode_spec_ibyte_string, (Ibyte *) buf,
7409 { 7408 {
7410 Charbpos toppos = marker_position (w->start[type]); 7409 Charbpos toppos = marker_position (w->start[type]);
7411 Charbpos botpos = BUF_Z (b) - w->window_end_pos[type]; 7410 Charbpos botpos = BUF_Z (b) - w->window_end_pos[type];
7412 7411
7413 /* botpos is only accurate as of the last redisplay, so we can 7412 /* botpos is only accurate as of the last redisplay, so we can
7414 only treat it as a hint. In particular, after erase-buffer, 7413 only treat it as a hint. In particular, after erase-buffer,
7415 botpos may be negative. */ 7414 botpos may be negative. */
7416 if (botpos < toppos) 7415 if (botpos < toppos)
7417 botpos = toppos; 7416 botpos = toppos;
7418 7417
7419 if (botpos >= BUF_ZV (b)) 7418 if (botpos >= BUF_ZV (b))
7420 { 7419 {
7424 str = "Bottom"; 7423 str = "Bottom";
7425 } 7424 }
7426 else 7425 else
7427 { 7426 {
7428 /* This hard limit is ok since the string it will hold has a 7427 /* This hard limit is ok since the string it will hold has a
7429 fixed maximum length of around 6. But just to be safe... */ 7428 fixed maximum length of around 6. But just to be safe... */
7430 char buf[10]; 7429 char buf[10];
7431 Charcount chars = botpos - BUF_BEGV (b); 7430 Charcount chars = botpos - BUF_BEGV (b);
7432 Charcount total = BUF_ZV (b) - BUF_BEGV (b); 7431 Charcount total = BUF_ZV (b) - BUF_BEGV (b);
7433 7432
7434 /* Avoid overflow on big buffers */ 7433 /* Avoid overflow on big buffers */
7435 int percent = total > LONG_MAX/200 ? 7434 int percent = total > LONG_MAX/200 ?
7436 (chars + total/200) / (total / 100) : 7435 (chars + total/200) / (total / 100) :
7437 (chars * 100 + total/2) / max (total, 1); 7436 (chars * 100 + total/2) / max (total, 1);
7438 7437
7439 /* We can't normally display a 3-digit number, so get us a 7438 /* We can't normally display a 3-digit number, so get us a
7440 2-digit number that is close. */ 7439 2-digit number that is close. */
7441 if (percent == 100) 7440 if (percent == 100)
7442 percent = 99; 7441 percent = 99;
7443 7442
7444 if (toppos <= BUF_BEGV (b)) 7443 if (toppos <= BUF_BEGV (b))
7445 sprintf (buf, "Top%d%%", percent); 7444 sprintf (buf, "Top%d%%", percent);
7518 int block; 7517 int block;
7519 7518
7520 if (dl->display_blocks) 7519 if (dl->display_blocks)
7521 { 7520 {
7522 for (block = 0; block < Dynarr_largest (dl->display_blocks); block++) 7521 for (block = 0; block < Dynarr_largest (dl->display_blocks); block++)
7523 { 7522 {
7524 struct display_block *db = Dynarr_atp (dl->display_blocks, block); 7523 struct display_block *db = Dynarr_atp (dl->display_blocks, block);
7525 7524
7526 Dynarr_free (db->runes); 7525 Dynarr_free (db->runes);
7527 } 7526 }
7528 7527
7686 struct frame *f = XFRAME (w->frame); 7685 struct frame *f = XFRAME (w->frame);
7687 7686
7688 if (!w->line_cache_validation_override) 7687 if (!w->line_cache_validation_override)
7689 { 7688 {
7690 /* f->extents_changed used to be in here because extent face and 7689 /* f->extents_changed used to be in here because extent face and
7691 size changes can cause text shifting. However, the extent 7690 size changes can cause text shifting. However, the extent
7692 covering the region is constantly having its face set and 7691 covering the region is constantly having its face set and
7693 priority altered by the mouse code. This means that the line 7692 priority altered by the mouse code. This means that the line
7694 start cache is constantly being invalidated. This is bad 7693 start cache is constantly being invalidated. This is bad
7695 since the mouse code also triggers heavy usage of the cache. 7694 since the mouse code also triggers heavy usage of the cache.
7696 Since it is an unlikely that f->extents being changed 7695 Since it is an unlikely that f->extents being changed
7697 indicates that the cache really needs to be updated and if it 7696 indicates that the cache really needs to be updated and if it
7698 does redisplay will catch it pretty quickly we no longer 7697 does redisplay will catch it pretty quickly we no longer
7699 invalidate the cache if it is set. This greatly speeds up 7698 invalidate the cache if it is set. This greatly speeds up
7700 dragging out regions with the mouse. */ 7699 dragging out regions with the mouse. */
7701 if (XINT (w->line_cache_last_updated) < BUF_MODIFF (b) 7700 if (XINT (w->line_cache_last_updated) < BUF_MODIFF (b)
7702 || f->faces_changed 7701 || f->faces_changed
7703 || f->clip_changed) 7702 || f->clip_changed)
7704 { 7703 {
7705 Dynarr_reset (w->line_start_cache); 7704 Dynarr_reset (w->line_start_cache);
7767 { 7766 {
7768 int loop; 7767 int loop;
7769 int win_char_height = window_char_height (w, 1); 7768 int win_char_height = window_char_height (w, 1);
7770 7769
7771 /* Occasionally we get here with a 0 height 7770 /* Occasionally we get here with a 0 height
7772 window. find_next_newline_no_quit will abort if we pass it a 7771 window. find_next_newline_no_quit will abort if we pass it a
7773 count of 0 so handle that case. */ 7772 count of 0 so handle that case. */
7774 if (!win_char_height) 7773 if (!win_char_height)
7775 win_char_height = 1; 7774 win_char_height = 1;
7776 7775
7777 if (!Dynarr_length (cache)) 7776 if (!Dynarr_length (cache))
7778 { 7777 {
7981 7980
7982 start_elt = point_in_line_start_cache (w, old_startp, 7981 start_elt = point_in_line_start_cache (w, old_startp,
7983 window_char_height (w, 0)); 7982 window_char_height (w, 0));
7984 7983
7985 /* We've already actually processed old_startp, so increment 7984 /* We've already actually processed old_startp, so increment
7986 immediately. */ 7985 immediately. */
7987 start_elt++; 7986 start_elt++;
7988 7987
7989 /* If this happens we didn't add any extra elements. Bummer. */ 7988 /* If this happens we didn't add any extra elements. Bummer. */
7990 if (start_elt == Dynarr_length (w->line_start_cache)) 7989 if (start_elt == Dynarr_length (w->line_start_cache))
7991 { 7990 {
8030 #### With a little work this could probably be reworked as just a 8029 #### With a little work this could probably be reworked as just a
8031 call to start_with_line_at_pixpos. */ 8030 call to start_with_line_at_pixpos. */
8032 8031
8033 static Charbpos 8032 static Charbpos
8034 start_end_of_last_line (struct window *w, Charbpos startp, int end, 8033 start_end_of_last_line (struct window *w, Charbpos startp, int end,
8035 int may_error) 8034 int may_error)
8036 { 8035 {
8037 struct buffer *b = XBUFFER (w->buffer); 8036 struct buffer *b = XBUFFER (w->buffer);
8038 line_start_cache_dynarr *cache = w->line_start_cache; 8037 line_start_cache_dynarr *cache = w->line_start_cache;
8039 int pixpos = 0; 8038 int pixpos = 0;
8040 int bottom = WINDOW_TEXT_HEIGHT (w); 8039 int bottom = WINDOW_TEXT_HEIGHT (w);
8166 cur_pos = Dynarr_atp (w->line_start_cache, cur_elt)->start; 8165 cur_pos = Dynarr_atp (w->line_start_cache, cur_elt)->start;
8167 8166
8168 pixheight -= Dynarr_atp (w->line_start_cache, cur_elt)->height; 8167 pixheight -= Dynarr_atp (w->line_start_cache, cur_elt)->height;
8169 8168
8170 /* Do not take into account the value of vertical_clip here. 8169 /* Do not take into account the value of vertical_clip here.
8171 That is the responsibility of the calling functions. */ 8170 That is the responsibility of the calling functions. */
8172 if (pixheight < 0) 8171 if (pixheight < 0)
8173 { 8172 {
8174 w->line_cache_validation_override--; 8173 w->line_cache_validation_override--;
8175 if (-pixheight > point_line_height) 8174 if (-pixheight > point_line_height)
8176 /* We can't make the target line cover pixpos, so put it 8175 /* We can't make the target line cover pixpos, so put it
8246 return Dynarr_atp (w->line_start_cache, cur_elt)->start; 8245 return Dynarr_atp (w->line_start_cache, cur_elt)->start;
8247 } 8246 }
8248 else 8247 else
8249 { 8248 {
8250 /* The calculated value of pixpos is correct for the bottom line 8249 /* The calculated value of pixpos is correct for the bottom line
8251 or what we want when line is -1. Therefore we subtract one 8250 or what we want when line is -1. Therefore we subtract one
8252 because we have already handled one line. */ 8251 because we have already handled one line. */
8253 int new_line = -line - 1; 8252 int new_line = -line - 1;
8254 int cur_elt = point_in_line_start_cache (w, point, new_line); 8253 int cur_elt = point_in_line_start_cache (w, point, new_line);
8255 int pixpos = WINDOW_TEXT_BOTTOM (w); 8254 int pixpos = WINDOW_TEXT_BOTTOM (w);
8256 Charbpos retval, search_point; 8255 Charbpos retval, search_point;
8257 8256
8258 /* If scroll_on_clipped_lines is false, the last "visible" line of 8257 /* If scroll_on_clipped_lines is false, the last "visible" line of
8259 the window covers the pixel at WINDOW_TEXT_BOTTOM (w) - 1. 8258 the window covers the pixel at WINDOW_TEXT_BOTTOM (w) - 1.
8260 If s_o_c_l is true, then we don't want to count a clipped 8259 If s_o_c_l is true, then we don't want to count a clipped
8261 line, so back up from the bottom by the height of the line 8260 line, so back up from the bottom by the height of the line
8262 containing point. */ 8261 containing point. */
8263 if (scroll_on_clipped_lines) 8262 if (scroll_on_clipped_lines)
8264 pixpos -= Dynarr_atp (w->line_start_cache, cur_elt)->height; 8263 pixpos -= Dynarr_atp (w->line_start_cache, cur_elt)->height;
8265 else 8264 else
8266 pixpos -= 1; 8265 pixpos -= 1;
8267 8266
8374 start = Dynarr_atp (internal_cache, 0)->start; 8373 start = Dynarr_atp (internal_cache, 0)->start;
8375 end = 8374 end =
8376 Dynarr_atp (internal_cache, Dynarr_length (internal_cache) - 1)->end; 8375 Dynarr_atp (internal_cache, Dynarr_length (internal_cache) - 1)->end;
8377 8376
8378 /* We aren't allowed to generate additional information to fill in 8377 /* We aren't allowed to generate additional information to fill in
8379 gaps, so if the DESIRED structs don't overlap the cache, reset the 8378 gaps, so if the DESIRED structs don't overlap the cache, reset the
8380 cache. */ 8379 cache. */
8381 if (Dynarr_length (cache)) 8380 if (Dynarr_length (cache))
8382 { 8381 {
8383 if (end < low_bound || start > high_bound) 8382 if (end < low_bound || start > high_bound)
8384 Dynarr_reset (cache); 8383 Dynarr_reset (cache);
8385 8384
8386 /* #### What should really happen if what we are doing is 8385 /* #### What should really happen if what we are doing is
8387 extending a line (the last line)? */ 8386 extending a line (the last line)? */
8388 if (Dynarr_length (cache) == 1 8387 if (Dynarr_length (cache) == 1
8389 && Dynarr_length (internal_cache) == 1) 8388 && Dynarr_length (internal_cache) == 1)
8390 Dynarr_reset (cache); 8389 Dynarr_reset (cache);
8391 } 8390 }
8392 8391
8397 w->line_cache_validation_override--; 8396 w->line_cache_validation_override--;
8398 return; 8397 return;
8399 } 8398 }
8400 8399
8401 /* An extra check just in case the calling function didn't pass in 8400 /* An extra check just in case the calling function didn't pass in
8402 the bounds of the DESIRED structs in the first place. */ 8401 the bounds of the DESIRED structs in the first place. */
8403 if (start >= low_bound && end <= high_bound) 8402 if (start >= low_bound && end <= high_bound)
8404 { 8403 {
8405 w->line_cache_validation_override--; 8404 w->line_cache_validation_override--;
8406 return; 8405 return;
8407 } 8406 }
8408 8407
8409 /* At this point we know that the internal cache partially overlaps 8408 /* At this point we know that the internal cache partially overlaps
8410 the main cache. */ 8409 the main cache. */
8411 if (start < low_bound) 8410 if (start < low_bound)
8412 { 8411 {
8413 int ic_elt = Dynarr_length (internal_cache) - 1; 8412 int ic_elt = Dynarr_length (internal_cache) - 1;
8414 while (ic_elt >= 0) 8413 while (ic_elt >= 0)
8415 { 8414 {
8468 int old_lb = low_bound; 8467 int old_lb = low_bound;
8469 8468
8470 while (startp < old_lb || low_bound == -1) 8469 while (startp < old_lb || low_bound == -1)
8471 { 8470 {
8472 int ic_elt; 8471 int ic_elt;
8473 Charbpos new_startp; 8472 Charbpos new_startp;
8474 8473
8475 regenerate_window (w, startp, point, CMOTION_DISP); 8474 regenerate_window (w, startp, point, CMOTION_DISP);
8476 update_internal_cache_list (w, CMOTION_DISP); 8475 update_internal_cache_list (w, CMOTION_DISP);
8477 8476
8478 /* If this assert is triggered then regenerate_window failed 8477 /* If this assert is triggered then regenerate_window failed
8479 to layout a single line. This is not possible since we 8478 to layout a single line. This is not possible since we
8480 force at least a single line to be layout for CMOTION_DISP */ 8479 force at least a single line to be layout for CMOTION_DISP */
8481 assert (Dynarr_length (internal_cache)); 8480 assert (Dynarr_length (internal_cache));
8482 assert (startp == Dynarr_atp (internal_cache, 0)->start); 8481 assert (startp == Dynarr_atp (internal_cache, 0)->start);
8483 8482
8484 ic_elt = Dynarr_length (internal_cache) - 1; 8483 ic_elt = Dynarr_length (internal_cache) - 1;
8494 } 8493 }
8495 assert (ic_elt >= 0); 8494 assert (ic_elt >= 0);
8496 8495
8497 new_startp = Dynarr_atp (internal_cache, ic_elt)->end + 1; 8496 new_startp = Dynarr_atp (internal_cache, ic_elt)->end + 1;
8498 8497
8499 /* 8498 /*
8500 * Handle invisible text properly: 8499 * Handle invisible text properly:
8501 * If the last line we're inserting has the same end as the 8500 * If the last line we're inserting has the same end as the
8502 * line before which it will be added, merge the two lines. 8501 * line before which it will be added, merge the two lines.
8503 */ 8502 */
8504 if (Dynarr_length (cache) && 8503 if (Dynarr_length (cache) &&
8505 Dynarr_atp (internal_cache, ic_elt)->end == 8504 Dynarr_atp (internal_cache, ic_elt)->end ==
8506 Dynarr_atp (cache, marker)->end) 8505 Dynarr_atp (cache, marker)->end)
8507 { 8506 {
8508 Dynarr_atp (cache, marker)->start 8507 Dynarr_atp (cache, marker)->start
8509 = Dynarr_atp (internal_cache, ic_elt)->start; 8508 = Dynarr_atp (internal_cache, ic_elt)->start;
8510 Dynarr_atp (cache, marker)->height 8509 Dynarr_atp (cache, marker)->height
8511 = Dynarr_atp (internal_cache, ic_elt)->height; 8510 = Dynarr_atp (internal_cache, ic_elt)->height;
8512 ic_elt--; 8511 ic_elt--;
8513 } 8512 }
8514 8513
8515 if (ic_elt >= 0) /* we still have lines to add.. */ 8514 if (ic_elt >= 0) /* we still have lines to add.. */
8516 { 8515 {
8517 Dynarr_insert_many (cache, Dynarr_atp (internal_cache, 0), 8516 Dynarr_insert_many (cache, Dynarr_atp (internal_cache, 0),
8518 ic_elt + 1, marker); 8517 ic_elt + 1, marker);
8519 marker += (ic_elt + 1); 8518 marker += (ic_elt + 1);
8520 } 8519 }
8521 8520
8522 if (startp < low_bound || low_bound == -1) 8521 if (startp < low_bound || low_bound == -1)
8523 low_bound = startp; 8522 low_bound = startp;
8524 startp = new_startp; 8523 startp = new_startp;
8525 if (startp > BUF_ZV (b)) 8524 if (startp > BUF_ZV (b))
8981 8980
8982 /* Check if the window is a minibuffer but isn't active. */ 8981 /* Check if the window is a minibuffer but isn't active. */
8983 if (MINI_WINDOW_P (*w) && !minibuf_level) 8982 if (MINI_WINDOW_P (*w) && !minibuf_level)
8984 { 8983 {
8985 /* Must reset the window value since some callers will ignore 8984 /* Must reset the window value since some callers will ignore
8986 the return value if it is set. */ 8985 the return value if it is set. */
8987 *w = 0; 8986 *w = 0;
8988 UPDATE_CACHE_RETURN; 8987 UPDATE_CACHE_RETURN;
8989 } 8988 }
8990 8989
8991 /* See if the point is over window vertical divider */ 8990 /* See if the point is over window vertical divider */
9085 { 9084 {
9086 if (x_coord < dl->bounds.left_in 9085 if (x_coord < dl->bounds.left_in
9087 || x_coord >= dl->bounds.right_in) 9086 || x_coord >= dl->bounds.right_in)
9088 { 9087 {
9089 /* If we are over the outside margins then we 9088 /* If we are over the outside margins then we
9090 know the loop over the text block isn't going 9089 know the loop over the text block isn't going
9091 to accomplish anything. So we go ahead and 9090 to accomplish anything. So we go ahead and
9092 set what information we can right here and 9091 set what information we can right here and
9093 return. */ 9092 return. */
9094 (*row)--; 9093 (*row)--;
9095 *obj_y = y_coord - (dl->ypos - dl->ascent); 9094 *obj_y = y_coord - (dl->ypos - dl->ascent);
9096 get_position_object (dl, obj1, obj2, x_coord, 9095 get_position_object (dl, obj1, obj2, x_coord,
9097 &low_x_coord, &high_x_coord); 9096 &low_x_coord, &high_x_coord);
9098 9097
9145 9144
9146 elt++; 9145 elt++;
9147 } 9146 }
9148 9147
9149 /* In this case we failed to find a non-glyph 9148 /* In this case we failed to find a non-glyph
9150 character so we return the last position 9149 character so we return the last position
9151 displayed on the line. */ 9150 displayed on the line. */
9152 if (elt == Dynarr_length (db->runes)) 9151 if (elt == Dynarr_length (db->runes))
9153 { 9152 {
9154 if (dl->modeline) 9153 if (dl->modeline)
9155 *modeline_closest = dl->end_charpos + dl->offset; 9154 *modeline_closest = dl->end_charpos + dl->offset;
9156 else 9155 else
9195 || (rb->type == RUNE_CHAR 9194 || (rb->type == RUNE_CHAR
9196 && rb->object.chr.ch == '\n')) 9195 && rb->object.chr.ch == '\n'))
9197 { 9196 {
9198 (*row)--; 9197 (*row)--;
9199 /* At this point we may have glyphs in the right 9198 /* At this point we may have glyphs in the right
9200 inside margin. */ 9199 inside margin. */
9201 if (check_margin_glyphs) 9200 if (check_margin_glyphs)
9202 get_position_object (dl, obj1, obj2, x_coord, 9201 get_position_object (dl, obj1, obj2, x_coord,
9203 &low_x_coord, &high_x_coord); 9202 &low_x_coord, &high_x_coord);
9204 UPDATE_CACHE_RETURN; 9203 UPDATE_CACHE_RETURN;
9205 } 9204 }
9224 9223
9225 *obj_x = x_coord - rb->xpos; 9224 *obj_x = x_coord - rb->xpos;
9226 *obj_y = y_coord - (dl->ypos - dl->ascent); 9225 *obj_y = y_coord - (dl->ypos - dl->ascent);
9227 9226
9228 /* At this point we may have glyphs in the left 9227 /* At this point we may have glyphs in the left
9229 inside margin. */ 9228 inside margin. */
9230 if (check_margin_glyphs) 9229 if (check_margin_glyphs)
9231 get_position_object (dl, obj1, obj2, x_coord, 0, 0); 9230 get_position_object (dl, obj1, obj2, x_coord, 0, 0);
9232 9231
9233 if (position == OVER_NOTHING && !really_over_nothing) 9232 if (position == OVER_NOTHING && !really_over_nothing)
9234 position = OVER_TEXT; 9233 position = OVER_TEXT;
9685 { 9684 {
9686 int i, j; 9685 int i, j;
9687 display_line_dynarr *dl; 9686 display_line_dynarr *dl;
9688 9687
9689 dl = window_display_lines (w, CURRENT_DISP); 9688 dl = window_display_lines (w, CURRENT_DISP);
9690 9689
9691 for (i = 0; i < Dynarr_largest (dl); i++) 9690 for (i = 0; i < Dynarr_largest (dl); i++)
9692 for (j = i + 1; j < Dynarr_largest (dl); j++) 9691 for (j = i + 1; j < Dynarr_largest (dl); j++)
9693 assert (Dynarr_atp (dl, i)->display_blocks != 9692 assert (Dynarr_atp (dl, i)->display_blocks !=
9694 Dynarr_atp (dl, j)->display_blocks); 9693 Dynarr_atp (dl, j)->display_blocks);
9695 9694