Mercurial > hg > xemacs-beta
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 |