comparison src/redisplay.c @ 819:6504113e7c2d

[xemacs-hg @ 2002-04-25 18:03:23 by andyp] sync up windows branch from 21.4
author andyp
date Thu, 25 Apr 2002 18:04:24 +0000
parents a5954632b187
children 6728e641994e
comparison
equal deleted inserted replaced
818:accc481aef34 819:6504113e7c2d
143 scrolling, where a certain number of columns 143 scrolling, where a certain number of columns
144 (those off the left side of the screen) need 144 (those off the left side of the screen) need
145 to be skipped before anything is displayed. */ 145 to be skipped before anything is displayed. */
146 Bytebpos bi_start_col_enabled; 146 Bytebpos bi_start_col_enabled;
147 int start_col_xoffset; /* Number of pixels that still need to 147 int start_col_xoffset; /* Number of pixels that still need to
148 be skipped. This is used for 148 be skipped. This is used for
149 horizontal scrolling of glyphs, where we want 149 horizontal scrolling of glyphs, where we want
150 to be able to scroll over part of the glyph. */ 150 to be able to scroll over part of the glyph. */
151 151
152 int hscroll_glyph_width_adjust; /* how much the width of the hscroll 152 int hscroll_glyph_width_adjust; /* how much the width of the hscroll
153 glyph differs from space_width (w). 153 glyph differs from space_width (w).
154 0 if no hscroll glyph was used, 154 0 if no hscroll glyph was used,
155 i.e. the window is not scrolled 155 i.e. the window is not scrolled
159 /* Information about the face the text should be displayed in and 159 /* Information about the face the text should be displayed in and
160 any begin-glyphs and end-glyphs. */ 160 any begin-glyphs and end-glyphs. */
161 struct extent_fragment *ef; 161 struct extent_fragment *ef;
162 face_index findex; 162 face_index findex;
163 163
164 /* The height of a pixmap may either be predetermined if the user 164 /* The height of a pixmap may either be predetermined if the user has set a
165 has set a baseline value, or it may be dependent on whatever the 165 baseline value, or it may be dependent on whatever the line ascent and
166 line ascent and descent values end up being, based just on font 166 descent values end up being, based just on font and pixmap-ascent
167 information. In the first case we can immediately update the 167 information. In the first case we can immediately update the values, thus
168 values, thus their inclusion here. In the last case we cannot 168 their inclusion here. In the last case we cannot determine the actual
169 determine the actual contribution to the line height until we 169 contribution to the line height until we have finished laying out all text
170 have finished laying out all text on the line. Thus we propagate 170 on the line. Thus we propagate the max height of such pixmaps and do a
171 the max height of such pixmaps and do a final calculation after 171 final calculation (in calculate_baseline()) after all text has been added
172 all text has been added to the line. */ 172 to the line. */
173 int new_ascent; 173 int new_ascent;
174 int new_descent; 174 int new_descent;
175 int max_pixmap_height; 175 int max_pixmap_height;
176 int need_baseline_computation;
177 int end_glyph_width; /* Well, it is the kitchen sink after all ... */
176 178
177 Lisp_Object result_str; /* String where we put the result of 179 Lisp_Object result_str; /* String where we put the result of
178 generating a formatted string in the modeline. */ 180 generating a formatted string in the modeline. */
179 int is_modeline; /* Non-zero if we're generating the modeline. */ 181 int is_modeline; /* Non-zero if we're generating the modeline. */
180 Charcount modeline_charpos; /* Number of chars used in result_str so far; 182 Charcount modeline_charpos; /* Number of chars used in result_str so far;
188 enum prop_type 190 enum prop_type
189 { 191 {
190 PROP_STRING, 192 PROP_STRING,
191 PROP_CHAR, 193 PROP_CHAR,
192 PROP_MINIBUF_PROMPT, 194 PROP_MINIBUF_PROMPT,
193 PROP_BLANK 195 PROP_BLANK,
196 PROP_GLYPH
194 }; 197 };
195 198
196 /* Data that should be propagated to the next line. Either a single 199 /* Data that should be propagated to the next line. Either a single
197 Emchar or a string of Intbyte's. 200 Emchar, a string of Intbyte's or a glyph.
198 201
199 The actual data that is propagated ends up as a Dynarr of these 202 The actual data that is propagated ends up as a Dynarr of these
200 blocks. 203 blocks.
204
205 prop_blocks are used to indicate that data that was supposed to go
206 on the previous line couldn't actually be displayed. Generally this
207 shouldn't happen if we are clipping the end of lines. If we are
208 wrapping then we need to display the propagation data before moving
209 on. Its questionable whether we should wrap or clip glyphs in this
210 instance. Most e-lisp relies on clipping so we preserve this
211 behavior.
201 212
202 #### It's unclean that both Emchars and Intbytes are here. 213 #### It's unclean that both Emchars and Intbytes are here.
203 */ 214 */
204 215
205 typedef struct prop_block prop_block; 216 typedef struct prop_block prop_block;
225 struct 236 struct
226 { 237 {
227 int width; 238 int width;
228 face_index findex; 239 face_index findex;
229 } p_blank; 240 } p_blank;
241
242 struct
243 {
244 /* Not used as yet, but could be used to wrap rather than clip glyphs. */
245 int width;
246 Lisp_Object glyph;
247 } p_glyph;
248
230 } data; 249 } data;
231 }; 250 };
232 251
233 typedef struct 252 typedef struct
234 { 253 {
261 static void decode_mode_spec (struct window *w, Emchar spec, int type); 280 static void decode_mode_spec (struct window *w, Emchar spec, int type);
262 static void free_display_line (struct display_line *dl); 281 static void free_display_line (struct display_line *dl);
263 static void update_line_start_cache (struct window *w, Charbpos from, Charbpos to, 282 static void update_line_start_cache (struct window *w, Charbpos from, Charbpos to,
264 Charbpos point, int no_regen); 283 Charbpos point, int no_regen);
265 static int point_visible (struct window *w, Charbpos point, int type); 284 static int point_visible (struct window *w, Charbpos point, int type);
285 static void calculate_yoffset (struct display_line *dl,
286 struct display_block *fixup);
287 static void calculate_baseline (pos_data *data);
266 288
267 static void sledgehammer_check_redisplay_structs (void); 289 static void sledgehammer_check_redisplay_structs (void);
268 290
269 /* This used to be 10 but 30 seems to give much better performance. */ 291 /* This used to be 10 but 30 seems to give much better performance. */
270 #define INIT_MAX_PREEMPTS 30 292 #define INIT_MAX_PREEMPTS 30
676 depend on the contents of the line being displayed. */ 698 depend on the contents of the line being displayed. */
677 bounds.left_white = bounds.left_in; 699 bounds.left_white = bounds.left_in;
678 bounds.right_white = bounds.right_in; 700 bounds.right_white = bounds.right_in;
679 701
680 return bounds; 702 return bounds;
703 }
704
705 /* This takes a display_block and its containing line and corrects the yoffset
706 of each glyph in the block to cater for the ascent of the line as a
707 whole. Must be called *after* the line-ascent is known! */
708
709 static void
710 calculate_yoffset (struct display_line *dl, struct display_block *fixup)
711 {
712 int i;
713 for (i=0; i<Dynarr_length (fixup->runes); i++)
714 {
715 struct rune *r = Dynarr_atp (fixup->runes,i);
716 if (r->type == RUNE_DGLYPH)
717 {
718 if (r->object.dglyph.ascent < dl->ascent)
719 r->object.dglyph.yoffset = dl->ascent - r->object.dglyph.ascent +
720 r->object.dglyph.descent;
721 }
722 }
723 }
724
725 /* Calculate the textual baseline (the ascent and descent values for the
726 display_line as a whole).
727
728 If the baseline is completely blank, or contains no manually positioned
729 glyphs, then the textual baseline is simply the baseline of the default font.
730 (The `contains no manually positioned glyphs' part is actually done for
731 us by `add_emchar_rune'.)
732
733 If the baseline contains pixmaps, and they're all manually positioned, then
734 the textual baseline location is constrained that way, and we need do no
735 work.
736
737 If the baseline contains pixmaps, and at least one is automatically
738 positioned, then the textual ascent is the largest ascent on the line, and
739 the textual descent is the largest descent (which is how things are set up at
740 entry to this function anyway): except that if the max_ascent + max_descent
741 is too small for the height of the line (say you've adjusted the baseline of
742 a short glyph, and there's a tall one next to it), then take the ascent and
743 descent for the line individually from the largest of the explicitly set
744 ascent/descent, and the rescaled ascent/descent of the default font, scaled
745 such that the largest glyph will fit.
746
747 This means that if you have a short glyph (but taller than the default
748 font's descent) forced right under the baseline, and a really tall
749 automatically positioned glyph, that the descent for the line is just big
750 enough for the manually positioned short glyph, and the tall one uses as
751 much of that space as the default font would were it as tall as the tall
752 glyph; but that the ascent is big enough for the tall glyph to fit.
753
754 This behaviour means that under no circumstances will changing the baseline
755 of a short glyph cause a tall glyph to move around; nor will it move the
756 textual baseline more than necessary. (Changing a tall glyph's baseline
757 might move the text's baseline arbitrarily, of course.) */
758
759 static void
760 calculate_baseline (pos_data *data)
761 {
762 /* Blank line: baseline is default font's baseline. */
763
764 if (!data->new_ascent && !data->new_descent)
765 {
766 /* We've got a blank line so initialize these values from the default
767 face. */
768 default_face_font_info (data->window, &data->new_ascent,
769 &data->new_descent, 0, 0, 0);
770 }
771
772 /* No automatically positioned glyphs? Return at once. */
773 if (!data->need_baseline_computation)
774 return;
775
776 /* Is the tallest glyph on the line automatically positioned?
777 If it's manually positioned, or it's automatically positioned
778 and there's enough room for it anyway, we need do no more work. */
779 if (data->max_pixmap_height > data->new_ascent + data->new_descent)
780 {
781 int default_font_ascent, default_font_descent, default_font_height;
782 int scaled_default_font_ascent, scaled_default_font_descent;
783
784 default_face_font_info (data->window, &default_font_ascent,
785 &default_font_descent, &default_font_height,
786 0, 0);
787
788 scaled_default_font_ascent = data->max_pixmap_height *
789 default_font_ascent / default_font_height;
790
791 data->new_ascent = max (data->new_ascent, scaled_default_font_ascent);
792
793 /* The ascent may have expanded now. Do we still need to grow the descent,
794 or are things big enough?
795
796 The +1 caters for the baseline row itself. */
797 if (data->max_pixmap_height > data->new_ascent + data->new_descent)
798 {
799 scaled_default_font_descent = (data->max_pixmap_height *
800 default_font_descent / default_font_height) + 1;
801
802 data->new_descent = max (data->new_descent, scaled_default_font_descent);
803 }
804 }
681 } 805 }
682 806
683 /* Given a display line and a starting position, ensure that the 807 /* Given a display line and a starting position, ensure that the
684 contents of the display line accurately represent the visual 808 contents of the display line accurately represent the visual
685 representation of the buffer contents starting from the given 809 representation of the buffer contents starting from the given
873 redisplay_text_width_emchar_string (XWINDOW (data->window), 997 redisplay_text_width_emchar_string (XWINDOW (data->window),
874 data->findex, &ch, 1); 998 data->findex, &ch, 1);
875 } 999 }
876 else 1000 else
877 data->last_char_width = -1; 1001 data->last_char_width = -1;
1002
878 if (!no_contribute_to_line_height) 1003 if (!no_contribute_to_line_height)
879 { 1004 {
880 data->new_ascent = max (data->new_ascent, (int) fi->ascent); 1005 data->new_ascent = max (data->new_ascent, (int) fi->ascent);
881 data->new_descent = max (data->new_descent, (int) fi->descent); 1006 data->new_descent = max (data->new_descent, (int) fi->descent);
882 } 1007 }
1008
883 data->last_charset = charset; 1009 data->last_charset = charset;
884 data->last_findex = data->findex; 1010 data->last_findex = data->findex;
885 } 1011 }
886 1012
887 width = data->last_char_width; 1013 width = data->last_char_width;
1128 } while (0) 1254 } while (0)
1129 1255
1130 static prop_block_dynarr * 1256 static prop_block_dynarr *
1131 add_octal_runes (pos_data *data) 1257 add_octal_runes (pos_data *data)
1132 { 1258 {
1133 prop_block_dynarr *prop, *add_failed; 1259 prop_block_dynarr *add_failed, *prop = 0;
1134 Emchar orig_char = data->ch; 1260 Emchar orig_char = data->ch;
1135 int orig_cursor_type = data->cursor_type; 1261 int orig_cursor_type = data->cursor_type;
1136 1262
1137 /* Initialize */ 1263 /* Initialize */
1138 prop = NULL;
1139 add_failed = NULL; 1264 add_failed = NULL;
1140 1265
1141 if (data->start_col) 1266 if (data->start_col)
1142 data->start_col--; 1267 data->start_col--;
1143 1268
1193 1318
1194 data->ch = (7 & orig_char) + '0'; 1319 data->ch = (7 & orig_char) + '0';
1195 ADD_NEXT_OCTAL_RUNE_CHAR; 1320 ADD_NEXT_OCTAL_RUNE_CHAR;
1196 1321
1197 data->cursor_type = orig_cursor_type; 1322 data->cursor_type = orig_cursor_type;
1198 return prop; 1323 return NULL;
1199 } 1324 }
1200 1325
1201 #undef ADD_NEXT_OCTAL_RUNE_CHAR 1326 #undef ADD_NEXT_OCTAL_RUNE_CHAR
1202 1327
1203 /* Add runes representing a control character to a display block. */ 1328 /* Add runes representing a control character to a display block. */
1566 int ascent, descent; 1691 int ascent, descent;
1567 Lisp_Object baseline; 1692 Lisp_Object baseline;
1568 Lisp_Object face; 1693 Lisp_Object face;
1569 Lisp_Object instance; 1694 Lisp_Object instance;
1570 face_index findex; 1695 face_index findex;
1696 prop_block_dynarr *retval = 0;
1571 1697
1572 if (cachel) 1698 if (cachel)
1573 width = cachel->width; 1699 width = cachel->width;
1574 else 1700 else
1575 width = glyph_width (gb->glyph, data->window); 1701 width = glyph_width (gb->glyph, data->window);
1577 if (!width) 1703 if (!width)
1578 return NULL; 1704 return NULL;
1579 1705
1580 if (data->start_col || data->start_col_xoffset) 1706 if (data->start_col || data->start_col_xoffset)
1581 { 1707 {
1582 prop_block_dynarr *retval;
1583 int glyph_char_width = width / space_width (w); 1708 int glyph_char_width = width / space_width (w);
1584 1709
1585 /* If we still have not fully scrolled horizontally after 1710 /* If we still have not fully scrolled horizontally after
1586 taking into account the width of the glyph, subtract its 1711 taking into account the width of the glyph, subtract its
1587 width and return. */ 1712 width and return. */
1613 xoffset = 0; 1738 xoffset = 0;
1614 1739
1615 if (data->pixpos + width > data->max_pixpos) 1740 if (data->pixpos + width > data->max_pixpos)
1616 { 1741 {
1617 /* If this is the first object we are attempting to add to 1742 /* If this is the first object we are attempting to add to
1618 the line then we ignore the horizontal_clip threshold. 1743 the line then we ignore the horizontal_clip threshold.
1619 Otherwise we will loop until the bottom of the window 1744 Otherwise we will loop until the bottom of the window
1620 continually failing to add this glyph because it is wider 1745 continually failing to add this glyph because it is wider
1621 than the window. We could alternatively just completely 1746 than the window. We could alternatively just completely
1622 ignore the glyph and proceed from there but I think that 1747 ignore the glyph and proceed from there but I think that
1623 this is a better solution. */ 1748 this is a better solution.
1749
1750 This does, however, create a different problem in that we
1751 can end up adding the object to every single line, never
1752 getting any further - for instance an extent with a long
1753 start-glyph that covers multitple following
1754 characters. */
1624 if (Dynarr_length (data->db->runes) 1755 if (Dynarr_length (data->db->runes)
1625 && data->max_pixpos - data->pixpos < horizontal_clip) 1756 && data->max_pixpos - data->pixpos < horizontal_clip)
1626 return ADD_FAILED; 1757 return ADD_FAILED;
1627 else 1758 else {
1759 struct prop_block pb;
1760
1761 /* We need to account for the width of the end-of-line
1762 glyph if there is nothing more in the line to display,
1763 since we will not display it in this instance. It seems
1764 kind of gross doing it here, but otherwise we have to
1765 search the runes in create_text_block(). */
1766 if (data->ch == '\n')
1767 data->max_pixpos += data->end_glyph_width;
1628 width = data->max_pixpos - data->pixpos; 1768 width = data->max_pixpos - data->pixpos;
1769 /* Add the glyph we are displaying, but clipping, to the
1770 propagation data so that we don't try and do it
1771 again. */
1772 retval = Dynarr_new (prop_block);
1773 pb.type = PROP_GLYPH;
1774 pb.data.p_glyph.glyph = gb->glyph;
1775 pb.data.p_glyph.width = width;
1776 Dynarr_add (retval, pb);
1777 }
1629 } 1778 }
1630 1779
1631 if (cachel) 1780 if (cachel)
1632 { 1781 {
1633 ascent = cachel->ascent; 1782 ascent = cachel->ascent;
1638 ascent = glyph_ascent (gb->glyph, data->window); 1787 ascent = glyph_ascent (gb->glyph, data->window);
1639 descent = glyph_descent (gb->glyph, data->window); 1788 descent = glyph_descent (gb->glyph, data->window);
1640 } 1789 }
1641 1790
1642 baseline = glyph_baseline (gb->glyph, data->window); 1791 baseline = glyph_baseline (gb->glyph, data->window);
1792
1793 rb.object.dglyph.descent = 0; /* Gets reset lower down, if it is known. */
1643 1794
1644 if (glyph_contrib_p (gb->glyph, data->window)) 1795 if (glyph_contrib_p (gb->glyph, data->window))
1645 { 1796 {
1646 /* A pixmap that has not had a baseline explicitly set. Its 1797 /* A pixmap that has not had a baseline explicitly set. Its
1647 contribution will be determined later. */ 1798 contribution will be determined later. */
1648 if (NILP (baseline)) 1799 if (NILP (baseline))
1649 { 1800 {
1650 int height = ascent + descent; 1801 int height = ascent + descent;
1802 data->need_baseline_computation = 1;
1651 data->max_pixmap_height = max (data->max_pixmap_height, height); 1803 data->max_pixmap_height = max (data->max_pixmap_height, height);
1652 } 1804 }
1653 1805
1654 /* A string so determine contribution normally. */ 1806 /* A string so determine contribution normally. */
1655 else if (EQ (baseline, Qt)) 1807 else if (EQ (baseline, Qt))
1668 pix_ascent = height * XINT (baseline) / 100; 1820 pix_ascent = height * XINT (baseline) / 100;
1669 pix_descent = height - pix_ascent; 1821 pix_descent = height - pix_ascent;
1670 1822
1671 data->new_ascent = max (data->new_ascent, pix_ascent); 1823 data->new_ascent = max (data->new_ascent, pix_ascent);
1672 data->new_descent = max (data->new_descent, pix_descent); 1824 data->new_descent = max (data->new_descent, pix_descent);
1825 data->max_pixmap_height = max (data->max_pixmap_height, height);
1826
1827 rb.object.dglyph.descent = pix_descent;
1673 } 1828 }
1674 1829
1675 /* Otherwise something is screwed up. */ 1830 /* Otherwise something is screwed up. */
1676 else 1831 else
1677 abort (); 1832 abort ();
1699 add_intbyte_string_runes (data, XSTRING_DATA (string), 1854 add_intbyte_string_runes (data, XSTRING_DATA (string),
1700 XSTRING_LENGTH (string), 0, 1); 1855 XSTRING_LENGTH (string), 0, 1);
1701 data->findex = orig_findex; 1856 data->findex = orig_findex;
1702 data->bi_charbpos = orig_charbpos; 1857 data->bi_charbpos = orig_charbpos;
1703 data->bi_start_col_enabled = orig_start_col_enabled; 1858 data->bi_start_col_enabled = orig_start_col_enabled;
1704 return NULL; 1859 return retval;
1705 } 1860 }
1706 1861
1707 rb.findex = findex; 1862 rb.findex = findex;
1708 rb.xpos = data->pixpos; 1863 rb.xpos = data->pixpos;
1709 rb.width = width; 1864 rb.width = width;
1716 rb.endpos = 0; 1871 rb.endpos = 0;
1717 rb.type = RUNE_DGLYPH; 1872 rb.type = RUNE_DGLYPH;
1718 rb.object.dglyph.glyph = gb->glyph; 1873 rb.object.dglyph.glyph = gb->glyph;
1719 rb.object.dglyph.extent = gb->extent; 1874 rb.object.dglyph.extent = gb->extent;
1720 rb.object.dglyph.xoffset = xoffset; 1875 rb.object.dglyph.xoffset = xoffset;
1876 rb.object.dglyph.ascent = ascent;
1877 rb.object.dglyph.yoffset = 0; /* Until we know better, assume that it has
1878 a normal (textual) baseline. */
1721 1879
1722 if (allow_cursor) 1880 if (allow_cursor)
1723 { 1881 {
1724 rb.charbpos = bytebpos_to_charbpos (XBUFFER (WINDOW_BUFFER (w)), 1882 rb.charbpos = bytebpos_to_charbpos (XBUFFER (WINDOW_BUFFER (w)),
1725 data->bi_charbpos); 1883 data->bi_charbpos);
1751 rb.cursor_type = CURSOR_OFF; 1909 rb.cursor_type = CURSOR_OFF;
1752 1910
1753 Dynarr_add (data->db->runes, rb); 1911 Dynarr_add (data->db->runes, rb);
1754 data->pixpos += width; 1912 data->pixpos += width;
1755 1913
1756 return NULL; 1914 return retval;
1757 } 1915 }
1758 else 1916 else
1759 { 1917 {
1760 if (!NILP (glyph_face (gb->glyph, data->window))) 1918 if (!NILP (glyph_face (gb->glyph, data->window)))
1761 gb->findex = 1919 gb->findex =
1780 } 1938 }
1781 else 1939 else
1782 abort (); /* there are no unknown types */ 1940 abort (); /* there are no unknown types */
1783 } 1941 }
1784 1942
1785 return NULL; /* shut up compiler */ 1943 return NULL;
1786 } 1944 }
1787 1945
1788 /* Add all glyphs at position POS_TYPE that are contained in the given 1946 /* Add all glyphs at position POS_TYPE that are contained in the given
1789 data. */ 1947 data. */
1790 1948
1840 int active_minibuffer = (!MINI_WINDOW_P (w) || 1998 int active_minibuffer = (!MINI_WINDOW_P (w) ||
1841 (f == device_selected_frame (d)) || 1999 (f == device_selected_frame (d)) ||
1842 is_surrogate_for_selected_frame (f)); 2000 is_surrogate_for_selected_frame (f));
1843 2001
1844 int truncate_win = window_truncation_on (w); 2002 int truncate_win = window_truncation_on (w);
1845 int end_glyph_width;
1846 2003
1847 /* If the buffer's value of selective_display is an integer then 2004 /* If the buffer's value of selective_display is an integer then
1848 only lines that start with less than selective_display columns of 2005 only lines that start with less than selective_display columns of
1849 space will be displayed. If selective_display is t then all text 2006 space will be displayed. If selective_display is t then all text
1850 after a ^M is invisible. */ 2007 after a ^M is invisible. */
1938 2095
1939 /* Set the right boundary adjusting it to take into account any end 2096 /* Set the right boundary adjusting it to take into account any end
1940 glyph. Save the width of the end glyph for later use. */ 2097 glyph. Save the width of the end glyph for later use. */
1941 data.max_pixpos = dl->bounds.right_in; 2098 data.max_pixpos = dl->bounds.right_in;
1942 if (truncate_win) 2099 if (truncate_win)
1943 end_glyph_width = GLYPH_CACHEL_WIDTH (w, TRUN_GLYPH_INDEX); 2100 data.end_glyph_width = GLYPH_CACHEL_WIDTH (w, TRUN_GLYPH_INDEX);
1944 else 2101 else
1945 end_glyph_width = GLYPH_CACHEL_WIDTH (w, CONT_GLYPH_INDEX); 2102 data.end_glyph_width = GLYPH_CACHEL_WIDTH (w, CONT_GLYPH_INDEX);
1946 data.max_pixpos -= end_glyph_width; 2103 data.max_pixpos -= data.end_glyph_width;
1947 2104
1948 if (cursor_in_echo_area && MINI_WINDOW_P (w) && echo_area_active (f)) 2105 if (cursor_in_echo_area && MINI_WINDOW_P (w) && echo_area_active (f))
1949 { 2106 {
1950 data.bi_cursor_charbpos = BI_BUF_ZV (b); 2107 data.bi_cursor_charbpos = BI_BUF_ZV (b);
1951 data.cursor_type = CURSOR_ON; 2108 data.cursor_type = CURSOR_ON;
2034 } 2191 }
2035 2192
2036 /* Check for face changes. */ 2193 /* Check for face changes. */
2037 if (initial || (!no_more_frags && data.bi_charbpos == data.ef->end)) 2194 if (initial || (!no_more_frags && data.bi_charbpos == data.ef->end))
2038 { 2195 {
2196 Lisp_Object last_glyph = Qnil;
2197
2198 /* Deal with glyphs that we have already displayed. The
2199 theory is that if we end up with a PROP_GLYPH in the
2200 propagation data then we are clipping the glyph and there
2201 can be no propagation data before that point. The theory
2202 works because we always recalculate the extent-fragments
2203 for propagated data, we never actually propagate the
2204 fragments that still need to be displayed. */
2205 if (*prop && Dynarr_atp (*prop, 0)->type == PROP_GLYPH)
2206 {
2207 last_glyph = Dynarr_atp (*prop, 0)->data.p_glyph.glyph;
2208 Dynarr_free (*prop);
2209 *prop = 0;
2210 }
2039 /* Now compute the face and begin/end-glyph information. */ 2211 /* Now compute the face and begin/end-glyph information. */
2040 data.findex = 2212 data.findex =
2041 /* Remember that the extent-fragment routines deal in Bytebpos's. */ 2213 /* Remember that the extent-fragment routines deal in Bytebpos's. */
2042 extent_fragment_update (w, data.ef, data.bi_charbpos); 2214 extent_fragment_update (w, data.ef, data.bi_charbpos, last_glyph);
2043 2215
2044 get_display_tables (w, data.findex, &face_dt, &window_dt); 2216 get_display_tables (w, data.findex, &face_dt, &window_dt);
2045 2217
2046 if (data.bi_charbpos == data.ef->end) 2218 if (data.bi_charbpos == data.ef->end)
2047 no_more_frags = 1; 2219 no_more_frags = 1;
2107 else 2279 else
2108 INC_BYTEBPOS (b, data.bi_charbpos); 2280 INC_BYTEBPOS (b, data.bi_charbpos);
2109 } 2281 }
2110 2282
2111 /* If there is propagation data, then it represents the current 2283 /* If there is propagation data, then it represents the current
2112 buffer position being displayed. Add them and advance the 2284 buffer position being displayed. Add them and advance the
2113 position counter. This might also add the minibuffer 2285 position counter. This might also add the minibuffer
2114 prompt. */ 2286 prompt. */
2115 else if (*prop) 2287 else if (*prop)
2116 { 2288 {
2117 dl->used_prop_data = 1; 2289 dl->used_prop_data = 1;
2118 *prop = add_propagation_runes (prop, &data); 2290 *prop = add_propagation_runes (prop, &data);
2119 2291
2131 /* If there are end glyphs, add them to the line. These are 2303 /* If there are end glyphs, add them to the line. These are
2132 the end glyphs for the previous run of text. We add them 2304 the end glyphs for the previous run of text. We add them
2133 here rather than doing them at the end of handling the 2305 here rather than doing them at the end of handling the
2134 previous run so that glyphs at the beginning and end of 2306 previous run so that glyphs at the beginning and end of
2135 a line are handled correctly. */ 2307 a line are handled correctly. */
2136 else if (Dynarr_length (data.ef->end_glyphs) > 0) 2308 else if (Dynarr_length (data.ef->end_glyphs) > 0
2137 { 2309 || Dynarr_length (data.ef->begin_glyphs) > 0)
2138 *prop = add_glyph_runes (&data, END_GLYPHS); 2310 {
2139 if (*prop) 2311 glyph_block_dynarr* tmpglyphs = 0;
2140 goto done; 2312 /* #### I think this is safe, but could be wrong. */
2141 } 2313 data.ch = BI_BUF_FETCH_CHAR (b, data.bi_charbpos);
2142 2314
2143 /* If there are begin glyphs, add them to the line. */ 2315 if (Dynarr_length (data.ef->end_glyphs) > 0)
2144 else if (Dynarr_length (data.ef->begin_glyphs) > 0) 2316 {
2145 { 2317 *prop = add_glyph_runes (&data, END_GLYPHS);
2146 *prop = add_glyph_runes (&data, BEGIN_GLYPHS); 2318 tmpglyphs = data.ef->end_glyphs;
2147 if (*prop) 2319 }
2148 goto done; 2320
2321 /* If there are begin glyphs, add them to the line. */
2322 if (!*prop && Dynarr_length (data.ef->begin_glyphs) > 0)
2323 {
2324 *prop = add_glyph_runes (&data, BEGIN_GLYPHS);
2325 tmpglyphs = data.ef->begin_glyphs;
2326 }
2327
2328 if (*prop)
2329 {
2330 /* If we just clipped a glyph and we are at the end of a
2331 line and there are more glyphs to display then do
2332 appropriate processing to not get a continuation
2333 glyph. */
2334 if (*prop != ADD_FAILED
2335 && Dynarr_atp (*prop, 0)->type == PROP_GLYPH
2336 && data.ch == '\n')
2337 {
2338 /* If there are no more glyphs then do the normal
2339 processing.
2340
2341 #### This doesn't actually work if the same glyph is
2342 present more than once in the block. To solve
2343 this we would have to carry the index around
2344 which might be problematic since the fragment is
2345 recalculated for each line. */
2346 if (EQ (Dynarr_end (tmpglyphs)->glyph,
2347 Dynarr_atp (*prop, 0)->data.p_glyph.glyph))
2348 {
2349 Dynarr_free (*prop);
2350 *prop = 0;
2351 }
2352 else {
2353 data.blank_width = DEVMETH (d, eol_cursor_width, ());
2354 add_emchar_rune (&data); /* discard prop data. */
2355 goto done;
2356 }
2357 }
2358 else
2359 goto done;
2360 }
2149 } 2361 }
2150 2362
2151 /* If at end-of-buffer, we've already processed begin and 2363 /* If at end-of-buffer, we've already processed begin and
2152 end-glyphs at this point and there's no text to process, 2364 end-glyphs at this point and there's no text to process,
2153 so we're done. */ 2365 so we're done. */
2177 else if (data.ch == '\n') 2389 else if (data.ch == '\n')
2178 { 2390 {
2179 /* We aren't going to be adding an end glyph so give its 2391 /* We aren't going to be adding an end glyph so give its
2180 space back in order to make sure that the cursor can 2392 space back in order to make sure that the cursor can
2181 fit. */ 2393 fit. */
2182 data.max_pixpos += end_glyph_width; 2394 data.max_pixpos += data.end_glyph_width;
2183 2395
2184 if (selective > 0 2396 if (selective > 0
2185 && (bi_spaces_at_point 2397 && (bi_spaces_at_point
2186 (b, next_bytebpos (b, data.bi_charbpos)) 2398 (b, next_bytebpos (b, data.bi_charbpos))
2187 >= selective)) 2399 >= selective))
2258 data.cursor_type = NEXT_CURSOR; 2470 data.cursor_type = NEXT_CURSOR;
2259 } 2471 }
2260 2472
2261 /* We won't be adding a truncation or continuation glyph 2473 /* We won't be adding a truncation or continuation glyph
2262 so give up the room allocated for them. */ 2474 so give up the room allocated for them. */
2263 data.max_pixpos += end_glyph_width; 2475 data.max_pixpos += data.end_glyph_width;
2264 2476
2265 if (!NILP (b->selective_display_ellipses)) 2477 if (!NILP (b->selective_display_ellipses))
2266 { 2478 {
2267 /* We don't propagate anything from the invisible 2479 /* We don't propagate anything from the invisible
2268 text glyph if it fails to fit. This is 2480 text glyph if it fails to fit. This is
2467 2679
2468 /* If the line is to be truncated then we actually have to look 2680 /* If the line is to be truncated then we actually have to look
2469 for the next newline. We also add the end-of-line glyph which 2681 for the next newline. We also add the end-of-line glyph which
2470 we know will fit because we adjusted the right border before 2682 we know will fit because we adjusted the right border before
2471 we starting laying out the line. */ 2683 we starting laying out the line. */
2472 data.max_pixpos += end_glyph_width; 2684 data.max_pixpos += data.end_glyph_width;
2473 data.findex = DEFAULT_INDEX; 2685 data.findex = DEFAULT_INDEX;
2474 gb.extent = Qnil; 2686 gb.extent = Qnil;
2475 2687
2476 if (truncate_win) 2688 if (truncate_win)
2477 { 2689 {
2602 db->end_pos = rb->xpos + rb->width; 2814 db->end_pos = rb->xpos + rb->width;
2603 } 2815 }
2604 else 2816 else
2605 db->end_pos = dl->bounds.right_white; 2817 db->end_pos = dl->bounds.right_white;
2606 2818
2607 /* update line height parameters */ 2819 calculate_baseline (&data);
2608 if (!data.new_ascent && !data.new_descent)
2609 {
2610 /* We've got a blank line so initialize these values from the default
2611 face. */
2612 default_face_font_info (data.window, &data.new_ascent,
2613 &data.new_descent, 0, 0, 0);
2614 }
2615
2616 if (data.max_pixmap_height)
2617 {
2618 int height = data.new_ascent + data.new_descent;
2619 int pix_ascent, pix_descent;
2620
2621 pix_descent = data.max_pixmap_height * data.new_descent / height;
2622 pix_ascent = data.max_pixmap_height - pix_descent;
2623
2624 data.new_ascent = max (data.new_ascent, pix_ascent);
2625 data.new_descent = max (data.new_descent, pix_descent);
2626 }
2627 2820
2628 dl->ascent = data.new_ascent; 2821 dl->ascent = data.new_ascent;
2629 dl->descent = data.new_descent; 2822 dl->descent = data.new_descent;
2630 2823
2631 { 2824 {
2638 unsigned short descent = (unsigned short) XINT (w->minimum_line_descent); 2831 unsigned short descent = (unsigned short) XINT (w->minimum_line_descent);
2639 2832
2640 if (dl->descent < descent) 2833 if (dl->descent < descent)
2641 dl->descent = descent; 2834 dl->descent = descent;
2642 } 2835 }
2836
2837 calculate_yoffset (dl, db);
2643 2838
2644 dl->cursor_elt = data.cursor_x; 2839 dl->cursor_elt = data.cursor_x;
2645 /* #### lossage lossage lossage! Fix this shit! */ 2840 /* #### lossage lossage lossage! Fix this shit! */
2646 if (data.bi_charbpos > BI_BUF_ZV (b)) 2841 if (data.bi_charbpos > BI_BUF_ZV (b))
2647 dl->end_charbpos = BUF_ZV (b); 2842 dl->end_charbpos = BUF_ZV (b);
2727 2922
2728 gb.glyph = Voverlay_arrow_string; 2923 gb.glyph = Voverlay_arrow_string;
2729 gb.extent = Qnil; 2924 gb.extent = Qnil;
2730 add_glyph_rune (&data, &gb, BEGIN_GLYPHS, 0, 0); 2925 add_glyph_rune (&data, &gb, BEGIN_GLYPHS, 0, 0);
2731 } 2926 }
2732 2927
2733 if (data.max_pixmap_height) 2928 if (data.max_pixmap_height)
2734 { 2929 {
2735 int height = data.new_ascent + data.new_descent; 2930 int height = data.new_ascent + data.new_descent;
2736 int pix_ascent, pix_descent; 2931 int pix_ascent, pix_descent;
2737 2932
2738 pix_descent = data.max_pixmap_height * data.new_descent / height; 2933 pix_descent = data.max_pixmap_height * data.new_descent / height;
2739 pix_ascent = data.max_pixmap_height - pix_descent; 2934 pix_ascent = data.max_pixmap_height - pix_descent;
2935 calculate_baseline (&data);
2740 2936
2741 data.new_ascent = max (data.new_ascent, pix_ascent); 2937 data.new_ascent = max (data.new_ascent, pix_ascent);
2742 data.new_descent = max (data.new_descent, pix_descent); 2938 data.new_descent = max (data.new_descent, pix_descent);
2743 } 2939 }
2744 2940
2745 dl->ascent = data.new_ascent; 2941 dl->ascent = data.new_ascent;
2746 dl->descent = data.new_descent; 2942 dl->descent = data.new_descent;
2747 2943
2748 data.db->start_pos = dl->bounds.left_in; 2944 data.db->start_pos = dl->bounds.left_in;
2749 data.db->end_pos = data.pixpos; 2945 data.db->end_pos = data.pixpos;
2946
2947 calculate_yoffset (dl, data.db);
2750 2948
2751 return data.pixpos - dl->bounds.left_in; 2949 return data.pixpos - dl->bounds.left_in;
2752 } 2950 }
2753 2951
2754 /* Add a type of glyph to a margin display block. */ 2952 /* Add a type of glyph to a margin display block. */
2817 } 3015 }
2818 3016
2819 (reverse ? elt-- : elt++); 3017 (reverse ? elt-- : elt++);
2820 } 3018 }
2821 3019
2822 if (data.max_pixmap_height) 3020 calculate_baseline (&data);
2823 {
2824 int height = data.new_ascent + data.new_descent;
2825 int pix_ascent, pix_descent;
2826
2827 pix_descent = data.max_pixmap_height * data.new_descent / height;
2828 pix_ascent = data.max_pixmap_height - pix_descent;
2829 data.new_ascent = max (data.new_ascent, pix_ascent);
2830 data.new_descent = max (data.new_descent, pix_descent);
2831 }
2832 3021
2833 dl->ascent = data.new_ascent; 3022 dl->ascent = data.new_ascent;
2834 dl->descent = data.new_descent; 3023 dl->descent = data.new_descent;
3024
3025 calculate_yoffset (dl, data.db);
2835 3026
2836 return data.pixpos; 3027 return data.pixpos;
2837 } 3028 }
2838 3029
2839 /* Add a blank to a margin display block. */ 3030 /* Add a blank to a margin display block. */
4267 return 0; 4458 return 0;
4268 } 4459 }
4269 4460
4270 4461
4271 /***************************************************************************/ 4462 /***************************************************************************/
4272 /* */ 4463 /* */
4273 /* displayable string routines */ 4464 /* displayable string routines */
4274 /* */ 4465 /* */
4275 /***************************************************************************/ 4466 /***************************************************************************/
4276 4467
4277 /* Given a position for a string in a window, ensure that the given 4468 /* Given a position for a string in a window, ensure that the given
4278 display line DL accurately represents the text on a line starting 4469 display line DL accurately represents the text on a line starting
4279 at the given position. 4470 at the given position.
4310 Bytebpos bi_start_pos = string_index_char_to_byte (disp_string, start_pos); 4501 Bytebpos bi_start_pos = string_index_char_to_byte (disp_string, start_pos);
4311 4502
4312 pos_data data; 4503 pos_data data;
4313 4504
4314 int truncate_win = b ? window_truncation_on (w) : 0; 4505 int truncate_win = b ? window_truncation_on (w) : 0;
4315 int end_glyph_width = 0;
4316 4506
4317 /* We're going to ditch selective display for static text, it's an 4507 /* We're going to ditch selective display for static text, it's an
4318 FSF thing and invisible extents are the way to go here. 4508 FSF thing and invisible extents are the way to go here.
4319 Implementing it also relies on a number of buffer-specific 4509 Implementing it also relies on a number of buffer-specific
4320 functions that we don't have the luxury of being able to use 4510 functions that we don't have the luxury of being able to use
4418 data.string = disp_string; 4608 data.string = disp_string;
4419 4609
4420 /* Set the right boundary adjusting it to take into account any end 4610 /* Set the right boundary adjusting it to take into account any end
4421 glyph. Save the width of the end glyph for later use. */ 4611 glyph. Save the width of the end glyph for later use. */
4422 data.max_pixpos = dl->bounds.right_in; 4612 data.max_pixpos = dl->bounds.right_in;
4423 #if 0 4613 data.max_pixpos -= data.end_glyph_width;
4424 if (truncate_win)
4425 end_glyph_width = GLYPH_CACHEL_WIDTH (w, TRUN_GLYPH_INDEX);
4426 else
4427 end_glyph_width = GLYPH_CACHEL_WIDTH (w, CONT_GLYPH_INDEX);
4428 #endif
4429 data.max_pixpos -= end_glyph_width;
4430 4614
4431 data.cursor_type = NO_CURSOR; 4615 data.cursor_type = NO_CURSOR;
4432 data.cursor_x = -1; 4616 data.cursor_x = -1;
4433 4617
4434 data.start_col = 0; 4618 data.start_col = 0;
4480 } 4664 }
4481 4665
4482 /* Check for face changes. */ 4666 /* Check for face changes. */
4483 if (initial || (!no_more_frags && data.bi_charbpos == data.ef->end)) 4667 if (initial || (!no_more_frags && data.bi_charbpos == data.ef->end))
4484 { 4668 {
4669 Lisp_Object last_glyph = Qnil;
4670 /* Deal with clipped glyphs that we have already displayed. */
4671 if (*prop && Dynarr_atp (*prop, 0)->type == PROP_GLYPH)
4672 {
4673 last_glyph = Dynarr_atp (*prop, 0)->data.p_glyph.glyph;
4674 Dynarr_free (*prop);
4675 *prop = 0;
4676 }
4485 /* Now compute the face and begin/end-glyph information. */ 4677 /* Now compute the face and begin/end-glyph information. */
4486 data.findex = 4678 data.findex =
4487 /* Remember that the extent-fragment routines deal in 4679 /* Remember that the extent-fragment routines deal in
4488 Bytebpos's. */ 4680 Bytebpos's. */
4489 extent_fragment_update (w, data.ef, data.bi_charbpos); 4681 extent_fragment_update (w, data.ef, data.bi_charbpos, last_glyph);
4490 /* This is somewhat cheesy but the alternative is to 4682 /* This is somewhat cheesy but the alternative is to
4491 propagate default_face into extent_fragment_update. */ 4683 propagate default_face into extent_fragment_update. */
4492 if (data.findex == DEFAULT_INDEX) 4684 if (data.findex == DEFAULT_INDEX)
4493 data.findex = default_face; 4685 data.findex = default_face;
4494 4686
4576 here rather than doing them at the end of handling the 4768 here rather than doing them at the end of handling the
4577 previous run so that glyphs at the beginning and end of 4769 previous run so that glyphs at the beginning and end of
4578 a line are handled correctly. */ 4770 a line are handled correctly. */
4579 else if (Dynarr_length (data.ef->end_glyphs) > 0) 4771 else if (Dynarr_length (data.ef->end_glyphs) > 0)
4580 { 4772 {
4773 data.ch = XSTRING_CHAR (disp_string, data.bi_charbpos);
4581 *prop = add_glyph_runes (&data, END_GLYPHS); 4774 *prop = add_glyph_runes (&data, END_GLYPHS);
4582 if (*prop) 4775
4776 if (*prop) {
4583 goto done; 4777 goto done;
4778 }
4584 } 4779 }
4585 4780
4586 /* If there are begin glyphs, add them to the line. */ 4781 /* If there are begin glyphs, add them to the line. */
4587 else if (Dynarr_length (data.ef->begin_glyphs) > 0) 4782 else if (Dynarr_length (data.ef->begin_glyphs) > 0)
4588 { 4783 {
4784 data.ch = XSTRING_CHAR (disp_string, data.bi_charbpos);
4589 *prop = add_glyph_runes (&data, BEGIN_GLYPHS); 4785 *prop = add_glyph_runes (&data, BEGIN_GLYPHS);
4590 if (*prop) 4786
4787 if (*prop) {
4591 goto done; 4788 goto done;
4789 }
4592 } 4790 }
4593 4791
4594 /* If at end-of-buffer, we've already processed begin and 4792 /* If at end-of-buffer, we've already processed begin and
4595 end-glyphs at this point and there's no text to process, 4793 end-glyphs at this point and there's no text to process,
4596 so we're done. */ 4794 so we're done. */
4620 else if (data.ch == '\n') 4818 else if (data.ch == '\n')
4621 { 4819 {
4622 /* We aren't going to be adding an end glyph so give its 4820 /* We aren't going to be adding an end glyph so give its
4623 space back in order to make sure that the cursor can 4821 space back in order to make sure that the cursor can
4624 fit. */ 4822 fit. */
4625 data.max_pixpos += end_glyph_width; 4823 data.max_pixpos += data.end_glyph_width;
4626 goto done; 4824 goto done;
4627 } 4825 }
4628 4826
4629 /* If the current character is considered to be printable, then 4827 /* If the current character is considered to be printable, then
4630 just add it. */ 4828 just add it. */
4662 (next_tab_start - tab_start_pixpos) / space_width (w); 4860 (next_tab_start - tab_start_pixpos) / space_width (w);
4663 4861
4664 *prop = add_blank_rune (&data, w, char_tab_width); 4862 *prop = add_blank_rune (&data, w, char_tab_width);
4665 4863
4666 /* add_blank_rune is only supposed to be called with 4864 /* add_blank_rune is only supposed to be called with
4667 sizes guaranteed to fit in the available space. */ 4865 sizes guaranteed to fit in the available space. */
4668 assert (!(*prop)); 4866 assert (!(*prop));
4669 4867
4670 if (prop_width) 4868 if (prop_width)
4671 { 4869 {
4672 struct prop_block pb; 4870 struct prop_block pb;
4718 4916
4719 INC_CHARBYTEBPOS (XSTRING_DATA (disp_string), data.bi_charbpos); 4917 INC_CHARBYTEBPOS (XSTRING_DATA (disp_string), data.bi_charbpos);
4720 } 4918 }
4721 } 4919 }
4722 4920
4723 done: 4921 done:
4724 4922
4725 /* Determine the starting point of the next line if we did not hit the 4923 /* Determine the starting point of the next line if we did not hit the
4726 end of the buffer. */ 4924 end of the buffer. */
4727 if (data.bi_charbpos < bi_string_zv) 4925 if (data.bi_charbpos < bi_string_zv)
4728 { 4926 {
4751 4949
4752 /* If the line is to be truncated then we actually have to look 4950 /* If the line is to be truncated then we actually have to look
4753 for the next newline. We also add the end-of-line glyph which 4951 for the next newline. We also add the end-of-line glyph which
4754 we know will fit because we adjusted the right border before 4952 we know will fit because we adjusted the right border before
4755 we starting laying out the line. */ 4953 we starting laying out the line. */
4756 data.max_pixpos += end_glyph_width; 4954 data.max_pixpos += data.end_glyph_width;
4757 data.findex = default_face; 4955 data.findex = default_face;
4758 gb.extent = Qnil; 4956 gb.extent = Qnil;
4759 4957
4760 if (truncate_win) 4958 if (truncate_win)
4761 { 4959 {
4780 dl->line_continuation = 1; 4978 dl->line_continuation = 1;
4781 gb.glyph = Vcontinuation_glyph; 4979 gb.glyph = Vcontinuation_glyph;
4782 cachel = GLYPH_CACHEL (w, CONT_GLYPH_INDEX); 4980 cachel = GLYPH_CACHEL (w, CONT_GLYPH_INDEX);
4783 } 4981 }
4784 4982
4785 if (end_glyph_width) 4983 if (data.end_glyph_width)
4786 add_glyph_rune (&data, &gb, BEGIN_GLYPHS, 0, cachel); 4984 add_glyph_rune (&data, &gb, BEGIN_GLYPHS, 0, cachel);
4787 4985
4788 if (truncate_win && data.bi_charbpos == bi_string_zv) 4986 if (truncate_win && data.bi_charbpos == bi_string_zv)
4789 { 4987 {
4790 const Intbyte *endb = charptr_n_addr (XSTRING_DATA (disp_string), 4988 const Intbyte *endb = charptr_n_addr (XSTRING_DATA (disp_string),
4860 db->end_pos = rb->xpos + rb->width; 5058 db->end_pos = rb->xpos + rb->width;
4861 } 5059 }
4862 else 5060 else
4863 db->end_pos = dl->bounds.right_white; 5061 db->end_pos = dl->bounds.right_white;
4864 5062
4865 /* update line height parameters */ 5063 calculate_baseline (&data);
4866 if (!data.new_ascent && !data.new_descent)
4867 {
4868 /* We've got a blank line so initialize these values from the default
4869 face. */
4870 default_face_font_info (data.window, &data.new_ascent,
4871 &data.new_descent, 0, 0, 0);
4872 }
4873
4874 if (data.max_pixmap_height)
4875 {
4876 int height = data.new_ascent + data.new_descent;
4877 int pix_ascent, pix_descent;
4878
4879 pix_descent = data.max_pixmap_height * data.new_descent / height;
4880 pix_ascent = data.max_pixmap_height - pix_descent;
4881
4882 data.new_ascent = max (data.new_ascent, pix_ascent);
4883 data.new_descent = max (data.new_descent, pix_descent);
4884 }
4885 5064
4886 dl->ascent = data.new_ascent; 5065 dl->ascent = data.new_ascent;
4887 dl->descent = data.new_descent; 5066 dl->descent = data.new_descent;
4888 5067
4889 { 5068 {
4896 unsigned short descent = (unsigned short) XINT (w->minimum_line_descent); 5075 unsigned short descent = (unsigned short) XINT (w->minimum_line_descent);
4897 5076
4898 if (dl->descent < descent) 5077 if (dl->descent < descent)
4899 dl->descent = descent; 5078 dl->descent = descent;
4900 } 5079 }
5080
5081 calculate_yoffset (dl, db);
4901 5082
4902 dl->cursor_elt = data.cursor_x; 5083 dl->cursor_elt = data.cursor_x;
4903 /* #### lossage lossage lossage! Fix this shit! */ 5084 /* #### lossage lossage lossage! Fix this shit! */
4904 if (data.bi_charbpos > bi_string_zv) 5085 if (data.bi_charbpos > bi_string_zv)
4905 dl->end_charbpos = buffer_or_string_bytebpos_to_charbpos (disp_string, 5086 dl->end_charbpos = buffer_or_string_bytebpos_to_charbpos (disp_string,