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