comparison src/xdisp.c @ 11854:637c5283e74b

(zv_strings_seen): New variable. (redisplay, try_window, try_window_id): Clear zv_strings_seen. (display_text_line): Handle overlay strings.
author Karl Heuer <kwzh@gnu.org>
date Thu, 18 May 1995 22:49:59 +0000
parents 986414eefde0
children b8de94b7c91f
comparison
equal deleted inserted replaced
11853:6578a356c540 11854:637c5283e74b
119 119
120 Lisp_Object Qmenu_bar_update_hook; 120 Lisp_Object Qmenu_bar_update_hook;
121 121
122 /* Nonzero if overlay arrow has been displayed once in this window. */ 122 /* Nonzero if overlay arrow has been displayed once in this window. */
123 static int overlay_arrow_seen; 123 static int overlay_arrow_seen;
124
125 /* Nonzero if visible end of buffer has already been displayed once
126 in this window. (We need this variable in case there are overlay
127 strings that get displayed there.) */
128 static int zv_strings_seen;
124 129
125 /* Nonzero means highlight the region even in nonselected windows. */ 130 /* Nonzero means highlight the region even in nonselected windows. */
126 static int highlight_nonselected_windows; 131 static int highlight_nonselected_windows;
127 132
128 /* If cursor motion alone moves point off frame, 133 /* If cursor motion alone moves point off frame,
875 else if (XFASTINT (w->last_modified) < MODIFF 880 else if (XFASTINT (w->last_modified) < MODIFF
876 || MINI_WINDOW_P (w)) 881 || MINI_WINDOW_P (w))
877 { 882 {
878 cursor_vpos = -1; 883 cursor_vpos = -1;
879 overlay_arrow_seen = 0; 884 overlay_arrow_seen = 0;
885 zv_strings_seen = 0;
880 display_text_line (w, tlbufpos, this_line_vpos, this_line_start_hpos, 886 display_text_line (w, tlbufpos, this_line_vpos, this_line_start_hpos,
881 pos_tab_offset (w, tlbufpos)); 887 pos_tab_offset (w, tlbufpos));
882 /* If line contains point, is not continued, 888 /* If line contains point, is not continued,
883 and ends at same distance from eob as before, we win */ 889 and ends at same distance from eob as before, we win */
884 if (cursor_vpos >= 0 && this_line_bufpos 890 if (cursor_vpos >= 0 && this_line_bufpos
930 && NILP (w->region_showing) 936 && NILP (w->region_showing)
931 && !cursor_in_echo_area) 937 && !cursor_in_echo_area)
932 { 938 {
933 pos = *compute_motion (tlbufpos, 0, 939 pos = *compute_motion (tlbufpos, 0,
934 XINT (w->hscroll) ? 1 - XINT (w->hscroll) : 0, 940 XINT (w->hscroll) ? 1 - XINT (w->hscroll) : 0,
941 0,
935 PT, 2, - (1 << (SHORTBITS - 1)), 942 PT, 2, - (1 << (SHORTBITS - 1)),
936 window_internal_width (w) - 1, 943 window_internal_width (w) - 1,
937 XINT (w->hscroll), 944 XINT (w->hscroll),
938 pos_tab_offset (w, tlbufpos), w); 945 pos_tab_offset (w, tlbufpos), w);
939 if (pos.vpos < 1) 946 if (pos.vpos < 1)
1431 try_window (window, startp); 1438 try_window (window, startp);
1432 if (cursor_vpos < 0) 1439 if (cursor_vpos < 0)
1433 { 1440 {
1434 /* If point does not appear, move point so it does appear */ 1441 /* If point does not appear, move point so it does appear */
1435 pos = *compute_motion (startp, 0, 1442 pos = *compute_motion (startp, 0,
1436 ((EQ (window, minibuf_window) && startp == 1) 1443 (((EQ (window, minibuf_window)
1437 ? minibuf_prompt_width : 0) 1444 && startp == BEG)
1438 + 1445 ? minibuf_prompt_width : 0)
1439 (hscroll ? 1 - hscroll : 0), 1446 + (hscroll ? 1 - hscroll : 0)),
1440 ZV, height / 2, 1447 0,
1441 - (1 << (SHORTBITS - 1)), 1448 ZV, height / 2,
1442 width, hscroll, pos_tab_offset (w, startp), w); 1449 - (1 << (SHORTBITS - 1)),
1450 width, hscroll, pos_tab_offset (w, startp), w);
1443 BUF_PT (current_buffer) = pos.bufpos; 1451 BUF_PT (current_buffer) = pos.bufpos;
1444 if (w != XWINDOW (selected_window)) 1452 if (w != XWINDOW (selected_window))
1445 Fset_marker (w->pointm, make_number (PT), Qnil); 1453 Fset_marker (w->pointm, make_number (PT), Qnil);
1446 else 1454 else
1447 { 1455 {
1486 /* If end pos is out of date, scroll bar and percentage will be wrong */ 1494 /* If end pos is out of date, scroll bar and percentage will be wrong */
1487 && INTEGERP (w->window_end_vpos) 1495 && INTEGERP (w->window_end_vpos)
1488 && XFASTINT (w->window_end_vpos) < XFASTINT (w->height) 1496 && XFASTINT (w->window_end_vpos) < XFASTINT (w->height)
1489 && !EQ (window, minibuf_window)) 1497 && !EQ (window, minibuf_window))
1490 { 1498 {
1491 pos = *compute_motion (startp, 0, (hscroll ? 1 - hscroll : 0), 1499 pos = *compute_motion (startp, 0, (hscroll ? 1 - hscroll : 0), 0,
1492 PT, height, 0, width, hscroll, 1500 PT, height, 0, width, hscroll,
1493 pos_tab_offset (w, startp), w); 1501 pos_tab_offset (w, startp), w);
1494 1502
1495 if (pos.vpos < height) 1503 if (pos.vpos < height)
1496 { 1504 {
1613 1621
1614 pos = *vmotion (PT, - (height / 2), w); 1622 pos = *vmotion (PT, - (height / 2), w);
1615 try_window (window, pos.bufpos); 1623 try_window (window, pos.bufpos);
1616 1624
1617 startp = marker_position (w->start); 1625 startp = marker_position (w->start);
1618 w->start_at_line_beg 1626 w->start_at_line_beg
1619 = (startp == BEGV || FETCH_CHAR (startp - 1) == '\n') ? Qt : Qnil; 1627 = (startp == BEGV || FETCH_CHAR (startp - 1) == '\n') ? Qt : Qnil;
1620 1628
1621 done: 1629 done:
1622 if ((update_mode_line 1630 if ((update_mode_line
1623 /* If window not full width, must redo its mode line 1631 /* If window not full width, must redo its mode line
1705 struct position val; 1713 struct position val;
1706 1714
1707 Fset_marker (w->start, make_number (pos), Qnil); 1715 Fset_marker (w->start, make_number (pos), Qnil);
1708 cursor_vpos = -1; 1716 cursor_vpos = -1;
1709 overlay_arrow_seen = 0; 1717 overlay_arrow_seen = 0;
1718 zv_strings_seen = 0;
1710 val.hpos = XINT (w->hscroll) ? 1 - XINT (w->hscroll) : 0; 1719 val.hpos = XINT (w->hscroll) ? 1 - XINT (w->hscroll) : 0;
1711 1720
1712 while (--height >= 0) 1721 while (--height >= 0)
1713 { 1722 {
1714 val = *display_text_line (w, pos, vpos, val.hpos, tab_offset); 1723 val = *display_text_line (w, pos, vpos, val.hpos, tab_offset);
1775 int top = XFASTINT (w->top); 1784 int top = XFASTINT (w->top);
1776 int start = marker_position (w->start); 1785 int start = marker_position (w->start);
1777 int width = window_internal_width (w) - 1; 1786 int width = window_internal_width (w) - 1;
1778 int hscroll = XINT (w->hscroll); 1787 int hscroll = XINT (w->hscroll);
1779 int lmargin = hscroll > 0 ? 1 - hscroll : 0; 1788 int lmargin = hscroll > 0 ? 1 - hscroll : 0;
1789 int did_motion;
1780 register int vpos; 1790 register int vpos;
1781 register int i, tem; 1791 register int i, tem;
1782 int last_text_vpos = 0; 1792 int last_text_vpos = 0;
1783 int stop_vpos; 1793 int stop_vpos;
1784 int selective = (INTEGERP (current_buffer->selective_display) 1794 int selective = (INTEGERP (current_buffer->selective_display)
1797 1807
1798 if (beg_unchanged + BEG < start) 1808 if (beg_unchanged + BEG < start)
1799 return 0; /* Give up if changes go above top of window */ 1809 return 0; /* Give up if changes go above top of window */
1800 1810
1801 /* Find position before which nothing is changed. */ 1811 /* Find position before which nothing is changed. */
1802 bp = *compute_motion (start, 0, lmargin, 1812 bp = *compute_motion (start, 0, lmargin, 0,
1803 min (ZV, beg_unchanged + BEG), height, 0, 1813 min (ZV, beg_unchanged + BEG), height, 0,
1804 width, hscroll, pos_tab_offset (w, start), w); 1814 width, hscroll, pos_tab_offset (w, start), w);
1805 if (bp.vpos >= height) 1815 if (bp.vpos >= height)
1806 { 1816 {
1807 if (PT < bp.bufpos) 1817 if (PT < bp.bufpos)
1808 { 1818 {
1809 /* All changes are below the frame, and point is on the frame. 1819 /* All changes are below the frame, and point is on the frame.
1810 We don't need to change the frame at all. 1820 We don't need to change the frame at all.
1811 But we need to update window_end_pos to account for 1821 But we need to update window_end_pos to account for
1812 any change in buffer size. */ 1822 any change in buffer size. */
1813 bp = *compute_motion (start, 0, lmargin, 1823 bp = *compute_motion (start, 0, lmargin, 0,
1814 Z, height, 0, 1824 Z, height, 0,
1815 width, hscroll, pos_tab_offset (w, start), w); 1825 width, hscroll, pos_tab_offset (w, start), w);
1816 XSETFASTINT (w->window_end_vpos, height); 1826 XSETFASTINT (w->window_end_vpos, height);
1817 XSETFASTINT (w->window_end_pos, Z - bp.bufpos); 1827 XSETFASTINT (w->window_end_pos, Z - bp.bufpos);
1818 goto findpoint; 1828 goto findpoint;
1828 pos = bp.bufpos; 1838 pos = bp.bufpos;
1829 val.hpos = lmargin; 1839 val.hpos = lmargin;
1830 if (pos < start) 1840 if (pos < start)
1831 return -1; 1841 return -1;
1832 1842
1843 did_motion = 0;
1833 /* If about to start displaying at the beginning of a continuation line, 1844 /* If about to start displaying at the beginning of a continuation line,
1834 really start with previous frame line, in case it was not 1845 really start with previous frame line, in case it was not
1835 continued when last redisplayed */ 1846 continued when last redisplayed */
1836 if ((bp.contin && bp.bufpos - 1 == beg_unchanged && vpos > 0) 1847 if ((bp.contin && bp.bufpos - 1 == beg_unchanged && vpos > 0)
1837 || 1848 ||
1844 } 1855 }
1845 1856
1846 if (bp.contin && bp.hpos != lmargin) 1857 if (bp.contin && bp.hpos != lmargin)
1847 { 1858 {
1848 val.hpos = bp.prevhpos - width + lmargin; 1859 val.hpos = bp.prevhpos - width + lmargin;
1860 did_motion = 1;
1849 pos--; 1861 pos--;
1850 } 1862 }
1851 1863
1852 bp.vpos = vpos; 1864 bp.vpos = vpos;
1853 1865
1856 if (selective > 0) 1868 if (selective > 0)
1857 while (tem < ZV - 1 && (indented_beyond_p (tem, selective))) 1869 while (tem < ZV - 1 && (indented_beyond_p (tem, selective)))
1858 tem = find_next_newline (tem, 1); 1870 tem = find_next_newline (tem, 1);
1859 1871
1860 /* Compute the cursor position after that newline. */ 1872 /* Compute the cursor position after that newline. */
1861 ep = *compute_motion (pos, vpos, val.hpos, tem, 1873 ep = *compute_motion (pos, vpos, val.hpos, did_motion, tem,
1862 height, - (1 << (SHORTBITS - 1)), 1874 height, - (1 << (SHORTBITS - 1)),
1863 width, hscroll, pos_tab_offset (w, bp.bufpos), w); 1875 width, hscroll, pos_tab_offset (w, bp.bufpos), w);
1864 1876
1865 /* If changes reach past the text available on the frame, 1877 /* If changes reach past the text available on the frame,
1866 just display rest of frame. */ 1878 just display rest of frame. */
1880 || ep.bufpos == Z - end_unchanged)) 1892 || ep.bufpos == Z - end_unchanged))
1881 stop_vpos = ep.vpos + 1; 1893 stop_vpos = ep.vpos + 1;
1882 1894
1883 cursor_vpos = -1; 1895 cursor_vpos = -1;
1884 overlay_arrow_seen = 0; 1896 overlay_arrow_seen = 0;
1897 zv_strings_seen = 0;
1885 1898
1886 /* If changes do not reach to bottom of window, 1899 /* If changes do not reach to bottom of window,
1887 figure out how much to scroll the rest of the window */ 1900 figure out how much to scroll the rest of the window */
1888 if (stop_vpos < height) 1901 if (stop_vpos < height)
1889 { 1902 {
1890 /* Now determine how far up or down the rest of the window has moved */ 1903 /* Now determine how far up or down the rest of the window has moved */
1891 epto = pos_tab_offset (w, ep.bufpos); 1904 epto = pos_tab_offset (w, ep.bufpos);
1892 xp = *compute_motion (ep.bufpos, ep.vpos, ep.hpos, 1905 xp = *compute_motion (ep.bufpos, ep.vpos, ep.hpos, 1,
1893 Z - XFASTINT (w->window_end_pos), 1906 Z - XFASTINT (w->window_end_pos),
1894 10000, 0, width, hscroll, epto, w); 1907 10000, 0, width, hscroll, epto, w);
1895 scroll_amount = xp.vpos - XFASTINT (w->window_end_vpos); 1908 scroll_amount = xp.vpos - XFASTINT (w->window_end_vpos);
1896 1909
1897 /* Is everything on frame below the changes whitespace? 1910 /* Is everything on frame below the changes whitespace?
1911 /* Before doing any scrolling, verify that point will be on frame. */ 1924 /* Before doing any scrolling, verify that point will be on frame. */
1912 if (PT > ep.bufpos && !(PT <= xp.bufpos && xp.bufpos < height)) 1925 if (PT > ep.bufpos && !(PT <= xp.bufpos && xp.bufpos < height))
1913 { 1926 {
1914 if (PT <= xp.bufpos) 1927 if (PT <= xp.bufpos)
1915 { 1928 {
1916 pp = *compute_motion (ep.bufpos, ep.vpos, ep.hpos, 1929 pp = *compute_motion (ep.bufpos, ep.vpos, ep.hpos, 1,
1917 PT, height, - (1 << (SHORTBITS - 1)), 1930 PT, height, - (1 << (SHORTBITS - 1)),
1918 width, hscroll, epto, w); 1931 width, hscroll, epto, w);
1919 } 1932 }
1920 else 1933 else
1921 { 1934 {
1922 pp = *compute_motion (xp.bufpos, xp.vpos, xp.hpos, 1935 pp = *compute_motion (xp.bufpos, xp.vpos, xp.hpos, 1,
1923 PT, height, - (1 << (SHORTBITS - 1)), 1936 PT, height, - (1 << (SHORTBITS - 1)),
1924 width, hscroll, 1937 width, hscroll,
1925 pos_tab_offset (w, xp.bufpos), w); 1938 pos_tab_offset (w, xp.bufpos), w);
1926 } 1939 }
1927 if (pp.bufpos < PT || pp.vpos == height) 1940 if (pp.bufpos < PT || pp.vpos == height)
2120 2133
2121 /* If point was not in a line that was displayed, find it */ 2134 /* If point was not in a line that was displayed, find it */
2122 if (cursor_vpos < 0) 2135 if (cursor_vpos < 0)
2123 { 2136 {
2124 findpoint: 2137 findpoint:
2125 val = *compute_motion (start, 0, lmargin, PT, 10000, 10000, 2138 val = *compute_motion (start, 0, lmargin, 0, PT, 10000, 10000,
2126 width, hscroll, pos_tab_offset (w, start), w); 2139 width, hscroll, pos_tab_offset (w, start), w);
2127 /* Admit failure if point is off frame now */ 2140 /* Admit failure if point is off frame now */
2128 if (val.vpos >= height) 2141 if (val.vpos >= height)
2129 { 2142 {
2130 for (vpos = 0; vpos < height; vpos++) 2143 for (vpos = 0; vpos < height; vpos++)
2138 FRAME_CURSOR_X (f) = cursor_hpos; 2151 FRAME_CURSOR_X (f) = cursor_hpos;
2139 FRAME_CURSOR_Y (f) = cursor_vpos; 2152 FRAME_CURSOR_Y (f) = cursor_vpos;
2140 2153
2141 if (debug_end_pos) 2154 if (debug_end_pos)
2142 { 2155 {
2143 val = *compute_motion (start, 0, lmargin, ZV, 2156 val = *compute_motion (start, 0, lmargin, 0, ZV,
2144 height, - (1 << (SHORTBITS - 1)), 2157 height, - (1 << (SHORTBITS - 1)),
2145 width, hscroll, pos_tab_offset (w, start), w); 2158 width, hscroll, pos_tab_offset (w, start), w);
2146 if (val.vpos != XFASTINT (w->window_end_vpos)) 2159 if (val.vpos != XFASTINT (w->window_end_vpos))
2147 abort (); 2160 abort ();
2148 if (XFASTINT (w->window_end_pos) 2161 if (XFASTINT (w->window_end_pos)
2329 int taboffset; 2342 int taboffset;
2330 { 2343 {
2331 register int pos = start; 2344 register int pos = start;
2332 register int c; 2345 register int c;
2333 register GLYPH *p1; 2346 register GLYPH *p1;
2334 int end;
2335 register int pause; 2347 register int pause;
2336 register unsigned char *p; 2348 register unsigned char *p;
2337 GLYPH *endp; 2349 GLYPH *endp;
2338 register GLYPH *leftmargin; 2350 register GLYPH *leftmargin;
2339 register GLYPH *p1prev = 0; 2351 register GLYPH *p1prev;
2340 register GLYPH *p1start; 2352 register GLYPH *p1start;
2353 int prevpos;
2341 int *charstart; 2354 int *charstart;
2342 FRAME_PTR f = XFRAME (w->frame); 2355 FRAME_PTR f = XFRAME (w->frame);
2343 int tab_width = XINT (current_buffer->tab_width); 2356 int tab_width = XINT (current_buffer->tab_width);
2344 int ctl_arrow = !NILP (current_buffer->ctl_arrow); 2357 int ctl_arrow = !NILP (current_buffer->ctl_arrow);
2345 int width = window_internal_width (w) - 1; 2358 int width = window_internal_width (w) - 1;
2388 2401
2389 /* The next buffer location at which the face should change, due 2402 /* The next buffer location at which the face should change, due
2390 to overlays or text property changes. */ 2403 to overlays or text property changes. */
2391 int next_face_change; 2404 int next_face_change;
2392 2405
2393 #ifdef USE_TEXT_PROPERTIES 2406 /* The next location where the `invisible' property changes, or an
2394 /* The next location where the `invisible' property changes */ 2407 overlay starts or ends. */
2395 int next_invisible; 2408 int next_boundary;
2396 #endif 2409
2397
2398 /* The face we're currently using. */ 2410 /* The face we're currently using. */
2399 int current_face = 0; 2411 int current_face = 0;
2400 int i; 2412 int i;
2401 2413
2402 XSETFASTINT (default_invis_vector[2], '.'); 2414 XSETFASTINT (default_invis_vector[2], '.');
2424 } 2436 }
2425 else 2437 else
2426 region_beg = region_end = -1; 2438 region_beg = region_end = -1;
2427 2439
2428 if (MINI_WINDOW_P (w) 2440 if (MINI_WINDOW_P (w)
2429 && start == 1 2441 && start == BEG
2430 && vpos == XFASTINT (w->top)) 2442 && vpos == XFASTINT (w->top))
2431 { 2443 {
2432 if (! NILP (minibuf_prompt)) 2444 if (! NILP (minibuf_prompt))
2433 { 2445 {
2434 minibuf_prompt_width 2446 minibuf_prompt_width
2447 } 2459 }
2448 else 2460 else
2449 minibuf_prompt_width = 0; 2461 minibuf_prompt_width = 0;
2450 } 2462 }
2451 2463
2452 end = ZV;
2453
2454 /* If we're hscrolled at all, use compute_motion to skip over any 2464 /* If we're hscrolled at all, use compute_motion to skip over any
2455 text off the left edge of the window. compute_motion may know 2465 text off the left edge of the window. compute_motion may know
2456 tricks to do this faster than we can. */ 2466 tricks to do this faster than we can. */
2457 if (hpos < 0) 2467 if (hpos < 0)
2458 { 2468 {
2459 struct position *left_edge 2469 struct position *left_edge
2460 = compute_motion (pos, vpos, hpos, 2470 = compute_motion (pos, vpos, hpos, 0,
2461 end, vpos, 0, 2471 ZV, vpos, 0,
2462 width, hscroll, taboffset, w); 2472 width, hscroll, taboffset, w);
2463 2473
2464 /* Retrieve the buffer position and column provided by 2474 /* Retrieve the buffer position and column provided by
2465 compute_motion. We can't assume that the column will be 2475 compute_motion. We can't assume that the column will be
2466 zero, because you may have multi-column characters crossing 2476 zero, because you may have multi-column characters crossing
2502 Stop at end of buffer, before newline, 2512 Stop at end of buffer, before newline,
2503 if reach or pass continuation column, 2513 if reach or pass continuation column,
2504 or at face change. */ 2514 or at face change. */
2505 pause = pos; 2515 pause = pos;
2506 next_face_change = pos; 2516 next_face_change = pos;
2517 next_boundary = pos;
2518 p1prev = p1;
2519 prevpos = pos;
2520 while (1)
2521 {
2522 if (pos >= pause)
2523 {
2524 while (pos == next_boundary)
2525 {
2526 Lisp_Object position, limit, prop, ww;
2527
2528 /* Display the overlay strings here, unless we're at ZV
2529 and have already displayed the appropriate strings
2530 on an earlier line. */
2531 if (pos < ZV || !zv_strings_seen++)
2532 {
2533 int ovlen;
2534 char *ovstr;
2535 ovlen = overlay_strings (pos, w, &ovstr);
2536 for (; ovlen; ovlen--, ovstr++)
2537 {
2538 if (p1 >= leftmargin && p1 < endp)
2539 *p1 = MAKE_GLYPH (f, *ovstr, current_face);
2540 p1++;
2541 }
2542 }
2543
2544 /* Did we reach point? Record the cursor location. */
2545 if (pos == PT && cursor_vpos < 0)
2546 {
2547 cursor_vpos = vpos;
2548 cursor_hpos = p1 - leftmargin;
2549 }
2550
2551 if (pos >= ZV)
2552 break;
2553
2554 XSETFASTINT (position, pos);
2555 limit = Fnext_overlay_change (position);
2507 #ifdef USE_TEXT_PROPERTIES 2556 #ifdef USE_TEXT_PROPERTIES
2508 next_invisible = pos; 2557 /* This is just an estimate to give reasonable
2558 performance; nothing should go wrong if it is too small. */
2559 if (XFASTINT (limit) > pos + 50)
2560 XSETFASTINT (limit, pos + 50);
2561 limit = Fnext_single_property_change (position, Qinvisible,
2562 Fcurrent_buffer (), limit);
2509 #endif 2563 #endif
2510 while (1) 2564 next_boundary = XFASTINT (limit);
2511 { 2565 /* if the `invisible' property is set, we can skip to
2512 /* Record which glyph starts a character, 2566 the next property change. */
2513 and the character position of that character. */ 2567 XSETWINDOW (ww, w);
2514 if (p1 >= leftmargin) 2568 prop = Fget_char_property (position, Qinvisible, ww);
2515 charstart[p1 - p1start] = pos; 2569 if (TEXT_PROP_MEANS_INVISIBLE (prop))
2516 2570 {
2517 if (p1 >= endp) 2571 if (pos < PT && next_boundary >= PT)
2518 break; 2572 {
2519 2573 cursor_vpos = vpos;
2520 p1prev = p1; 2574 cursor_hpos = p1 - leftmargin;
2521 if (pos >= pause) 2575 }
2522 { 2576 pos = next_boundary;
2523 /* Did we hit the end of the visible region of the buffer? 2577 last_invis_skip = pos;
2524 Stop here. */ 2578 last_invis_prop = prop;
2525 if (pos >= end) 2579 }
2526 break; 2580 }
2527 2581
2528 /* Did we reach point? Record the cursor location. */ 2582 /* Did we reach point? Record the cursor location. */
2529 if (pos == PT && cursor_vpos < 0) 2583 if (pos == PT && cursor_vpos < 0)
2530 { 2584 {
2531 cursor_vpos = vpos; 2585 cursor_vpos = vpos;
2532 cursor_hpos = p1 - leftmargin; 2586 cursor_hpos = p1 - leftmargin;
2533 } 2587 }
2534 2588
2535 #ifdef USE_TEXT_PROPERTIES 2589 /* Did we hit the end of the visible region of the buffer?
2536 /* if the `invisible' property is set to t, we can skip to 2590 Stop here. */
2537 the next property change */ 2591 if (pos >= ZV)
2538 while (pos == next_invisible && pos < end)
2539 {
2540 Lisp_Object position, limit, endpos, prop, ww;
2541 XSETFASTINT (position, pos);
2542 XSETWINDOW (ww, w);
2543 prop = Fget_char_property (position, Qinvisible, ww);
2544 /* This is just an estimate to give reasonable
2545 performance; nothing should go wrong if it is too small. */
2546 limit = Fnext_overlay_change (position);
2547 if (XFASTINT (limit) > pos + 50)
2548 XSETFASTINT (limit, pos + 50);
2549 endpos = Fnext_single_property_change (position, Qinvisible,
2550 Fcurrent_buffer (),
2551 limit);
2552 if (INTEGERP (endpos))
2553 next_invisible = XINT (endpos);
2554 else
2555 next_invisible = end;
2556 if (TEXT_PROP_MEANS_INVISIBLE (prop))
2557 {
2558 if (pos < PT && next_invisible >= PT)
2559 {
2560 cursor_vpos = vpos;
2561 cursor_hpos = p1 - leftmargin;
2562 }
2563 pos = next_invisible;
2564 last_invis_skip = pos;
2565 last_invis_prop = prop;
2566 }
2567 }
2568 if (pos >= end)
2569 break; 2592 break;
2570 #endif
2571 2593
2572 #ifdef HAVE_FACES 2594 #ifdef HAVE_FACES
2573 /* Did we hit a face change? Figure out what face we should 2595 /* Did we hit a face change? Figure out what face we should
2574 use now. We also hit this the first time through the 2596 use now. We also hit this the first time through the
2575 loop, to see what face we should start with. */ 2597 loop, to see what face we should start with. */
2577 current_face = compute_char_face (f, w, pos, 2599 current_face = compute_char_face (f, w, pos,
2578 region_beg, region_end, 2600 region_beg, region_end,
2579 &next_face_change, pos + 50, 0); 2601 &next_face_change, pos + 50, 0);
2580 #endif 2602 #endif
2581 2603
2582 pause = end; 2604 pause = ZV;
2583 2605
2584 #ifdef USE_TEXT_PROPERTIES 2606 if (pos < next_boundary && next_boundary < pause)
2585 if (pos < next_invisible && next_invisible < pause) 2607 pause = next_boundary;
2586 pause = next_invisible;
2587 #endif
2588 if (pos < next_face_change && next_face_change < pause) 2608 if (pos < next_face_change && next_face_change < pause)
2589 pause = next_face_change; 2609 pause = next_face_change;
2590 2610
2591 /* Wouldn't you hate to read the next line to someone over 2611 /* Wouldn't you hate to read the next line to someone over
2592 the phone? */ 2612 the phone? */
2595 if (pos < GPT && GPT < pause) 2615 if (pos < GPT && GPT < pause)
2596 pause = GPT; 2616 pause = GPT;
2597 2617
2598 p = &FETCH_CHAR (pos); 2618 p = &FETCH_CHAR (pos);
2599 } 2619 }
2620
2621 /* Do nothing here for a char that's entirely off the left edge. */
2622 if (p1 >= leftmargin)
2623 {
2624 /* For all the glyphs occupied by this character, except for the
2625 first, store -1 in charstarts. */
2626 if (p1 != p1prev)
2627 {
2628 int *p2x = &charstart[(p1prev < leftmargin
2629 ? leftmargin : p1prev)
2630 - p1start];
2631 int *p2 = &charstart[(p1 < endp ? p1 : endp) - p1start];
2632
2633 if (p2x < p2)
2634 *p2x++ = prevpos;
2635 while (p2x < p2)
2636 *p2x++ = -1;
2637 }
2638 }
2639
2640 if (p1 >= endp)
2641 break;
2642
2643 p1prev = p1;
2644
2600 c = *p++; 2645 c = *p++;
2601 /* Let a display table override all standard display methods. */ 2646 /* Let a display table override all standard display methods. */
2602 if (dp != 0 && VECTORP (DISP_CHAR_VECTOR (dp, c))) 2647 if (dp != 0 && VECTORP (DISP_CHAR_VECTOR (dp, c)))
2603 { 2648 {
2604 p1 = copy_part_of_rope (f, p1, leftmargin, 2649 p1 = copy_part_of_rope (f, p1, leftmargin,
2616 { 2661 {
2617 invis = 0; 2662 invis = 0;
2618 if (last_invis_skip == pos 2663 if (last_invis_skip == pos
2619 && TEXT_PROP_MEANS_INVISIBLE_WITH_ELLIPSIS (last_invis_prop)) 2664 && TEXT_PROP_MEANS_INVISIBLE_WITH_ELLIPSIS (last_invis_prop))
2620 invis = 1; 2665 invis = 1;
2621 while (pos + 1 < end 2666 while (pos + 1 < ZV
2622 && selective > 0 2667 && selective > 0
2623 && indented_beyond_p (pos + 1, selective)) 2668 && indented_beyond_p (pos + 1, selective))
2624 { 2669 {
2625 invis = 1; 2670 invis = 1;
2626 pos = find_next_newline (pos + 1, 1); 2671 pos = find_next_newline (pos + 1, 1);
2712 if (p1 >= leftmargin && p1 < endp) 2757 if (p1 >= leftmargin && p1 < endp)
2713 *p1 = MAKE_GLYPH (f, (7 & c) + '0', current_face); 2758 *p1 = MAKE_GLYPH (f, (7 & c) + '0', current_face);
2714 p1++; 2759 p1++;
2715 } 2760 }
2716 2761
2717 /* Do nothing here for a char that's entirely off the left edge. */ 2762 prevpos = pos;
2718 if (p1 >= leftmargin)
2719 {
2720 /* For all the glyphs occupied by this character, except for the
2721 first, store -1 in charstarts. */
2722 if (p1 != p1prev)
2723 {
2724 int *p2x = &charstart[p1prev - p1start];
2725 int *p2 = &charstart[(p1 < endp ? p1 : endp) - p1start];
2726
2727 /* The window's left column should always
2728 contain a character position.
2729 And don't clobber anything to the left of that. */
2730 if (p1prev < leftmargin)
2731 {
2732 p2x = charstart + (leftmargin - p1start);
2733 *p2x = pos;
2734 }
2735
2736 /* This loop skips over the char p2x initially points to. */
2737 while (++p2x < p2)
2738 *p2x = -1;
2739 }
2740 }
2741
2742 pos++; 2763 pos++;
2743 } 2764 }
2744 2765
2745 val.hpos = - XINT (w->hscroll); 2766 val.hpos = - XINT (w->hscroll);
2746 if (val.hpos) 2767 if (val.hpos)