diff options
| author | Kim F. Storm | 2003-03-16 20:48:56 +0000 |
|---|---|---|
| committer | Kim F. Storm | 2003-03-16 20:48:56 +0000 |
| commit | 750fc6732fa42527ceb2f0962856ed4bae656714 (patch) | |
| tree | eebe02137d53f5acacbf705199412166fb733509 /src | |
| parent | ec480ce025f9a1668ff48e065b7d36b8ed2632d4 (diff) | |
| download | emacs-750fc6732fa42527ceb2f0962856ed4bae656714.tar.gz emacs-750fc6732fa42527ceb2f0962856ed4bae656714.zip | |
The following changes consolidate some of the gui-independent
parts of the processing and drawing of "glyph strings" from
xterm.c, w32term.c, and macterm.c into xdisp.c.
* macterm.c: Remove consolidated defines and code.
(mac_per_char_metric): New function for RIF.
(mac_encode_char): Adapted to new RIF requirements.
(mac_compute_glyph_string_overhangs): Adapt for RIF.
(x_redisplay_interface): Add new members.
Diffstat (limited to 'src')
| -rw-r--r-- | src/macterm.c | 2218 |
1 files changed, 32 insertions, 2186 deletions
diff --git a/src/macterm.c b/src/macterm.c index f6b8ed2fdc7..328464fcad6 100644 --- a/src/macterm.c +++ b/src/macterm.c | |||
| @@ -300,19 +300,6 @@ QDGlobals qd; /* QuickDraw global information structure. */ | |||
| 300 | #endif | 300 | #endif |
| 301 | 301 | ||
| 302 | 302 | ||
| 303 | /* Enumeration for overriding/changing the face to use for drawing | ||
| 304 | glyphs in x_draw_glyphs. */ | ||
| 305 | |||
| 306 | enum draw_glyphs_face | ||
| 307 | { | ||
| 308 | DRAW_NORMAL_TEXT, | ||
| 309 | DRAW_INVERSE_VIDEO, | ||
| 310 | DRAW_CURSOR, | ||
| 311 | DRAW_MOUSE_FACE, | ||
| 312 | DRAW_IMAGE_RAISED, | ||
| 313 | DRAW_IMAGE_SUNKEN | ||
| 314 | }; | ||
| 315 | |||
| 316 | struct frame * x_window_to_frame (struct mac_display_info *, WindowPtr); | 303 | struct frame * x_window_to_frame (struct mac_display_info *, WindowPtr); |
| 317 | struct mac_display_info *mac_display_info_for_display (Display *); | 304 | struct mac_display_info *mac_display_info_for_display (Display *); |
| 318 | static void x_update_window_end P_ ((struct window *, int, int)); | 305 | static void x_update_window_end P_ ((struct window *, int, int)); |
| @@ -386,16 +373,11 @@ void x_display_and_set_cursor P_ ((struct window *, int, int, int, int, int)); | |||
| 386 | static void x_clip_to_row P_ ((struct window *, struct glyph_row *, | 373 | static void x_clip_to_row P_ ((struct window *, struct glyph_row *, |
| 387 | GC, int)); | 374 | GC, int)); |
| 388 | static int x_phys_cursor_in_rect_p P_ ((struct window *, Rect *)); | 375 | static int x_phys_cursor_in_rect_p P_ ((struct window *, Rect *)); |
| 389 | static void notice_overwritten_cursor P_ ((struct window *, | ||
| 390 | enum glyph_row_area, | ||
| 391 | int, int, int, int)); | ||
| 392 | static void x_flush P_ ((struct frame *f)); | 376 | static void x_flush P_ ((struct frame *f)); |
| 393 | static void x_update_begin P_ ((struct frame *)); | 377 | static void x_update_begin P_ ((struct frame *)); |
| 394 | static void x_update_window_begin P_ ((struct window *)); | 378 | static void x_update_window_begin P_ ((struct window *)); |
| 395 | static void x_draw_vertical_border P_ ((struct window *)); | 379 | static void x_draw_vertical_border P_ ((struct window *)); |
| 396 | static void x_after_update_window_line P_ ((struct glyph_row *)); | 380 | static void x_after_update_window_line P_ ((struct glyph_row *)); |
| 397 | static INLINE void take_vertical_position_into_account P_ ((struct it *)); | ||
| 398 | static void x_produce_stretch_glyph P_ ((struct it *)); | ||
| 399 | 381 | ||
| 400 | static void activate_scroll_bars (FRAME_PTR); | 382 | static void activate_scroll_bars (FRAME_PTR); |
| 401 | static void deactivate_scroll_bars (FRAME_PTR); | 383 | static void deactivate_scroll_bars (FRAME_PTR); |
| @@ -415,14 +397,6 @@ extern void set_frame_menubar (FRAME_PTR, int, int); | |||
| 415 | 397 | ||
| 416 | /* X display function emulation */ | 398 | /* X display function emulation */ |
| 417 | 399 | ||
| 418 | /* Structure borrowed from Xlib.h to represent two-byte characters in | ||
| 419 | dumpglyphs. */ | ||
| 420 | |||
| 421 | typedef struct { | ||
| 422 | unsigned char byte1; | ||
| 423 | unsigned char byte2; | ||
| 424 | } XChar2b; | ||
| 425 | |||
| 426 | static void | 400 | static void |
| 427 | XFreePixmap (display, pixmap) | 401 | XFreePixmap (display, pixmap) |
| 428 | Display *display; | 402 | Display *display; |
| @@ -1539,20 +1513,8 @@ XTcursor_to (vpos, hpos, y, x) | |||
| 1539 | 1513 | ||
| 1540 | /* Function prototypes of this page. */ | 1514 | /* Function prototypes of this page. */ |
| 1541 | 1515 | ||
| 1542 | static struct face *x_get_glyph_face_and_encoding P_ ((struct frame *, | ||
| 1543 | struct glyph *, | ||
| 1544 | XChar2b *, | ||
| 1545 | int *)); | ||
| 1546 | static struct face *x_get_char_face_and_encoding P_ ((struct frame *, int, | ||
| 1547 | int, XChar2b *, int)); | ||
| 1548 | static XCharStruct *x_per_char_metric P_ ((XFontStruct *, XChar2b *)); | 1516 | static XCharStruct *x_per_char_metric P_ ((XFontStruct *, XChar2b *)); |
| 1549 | static void x_encode_char P_ ((int, XChar2b *, struct font_info *)); | 1517 | static int mac_encode_char P_ ((int, XChar2b *, struct font_info *, int *)); |
| 1550 | static void x_append_glyph P_ ((struct it *)); | ||
| 1551 | static void x_append_composite_glyph P_ ((struct it *)); | ||
| 1552 | static void x_append_stretch_glyph P_ ((struct it *it, Lisp_Object, | ||
| 1553 | int, int, double)); | ||
| 1554 | static void x_produce_glyphs P_ ((struct it *)); | ||
| 1555 | static void x_produce_image_glyph P_ ((struct it *it)); | ||
| 1556 | 1518 | ||
| 1557 | 1519 | ||
| 1558 | /* Return a pointer to per-char metric information in FONT of a | 1520 | /* Return a pointer to per-char metric information in FONT of a |
| @@ -1638,15 +1600,28 @@ x_per_char_metric (font, char2b) | |||
| 1638 | ? NULL : pcm); | 1600 | ? NULL : pcm); |
| 1639 | } | 1601 | } |
| 1640 | 1602 | ||
| 1603 | /* RIF: | ||
| 1604 | */ | ||
| 1641 | 1605 | ||
| 1642 | /* Encode CHAR2B using encoding information from FONT_INFO. CHAR2B is | 1606 | static XCharStruct * |
| 1607 | mac_per_char_metric (font, char2b, font_type) | ||
| 1608 | XFontStruct *font; | ||
| 1609 | XChar2b *char2b; | ||
| 1610 | int font_type; | ||
| 1611 | { | ||
| 1612 | return x_per_char_metric (font, char2b); | ||
| 1613 | } | ||
| 1614 | |||
| 1615 | /* RIF: | ||
| 1616 | Encode CHAR2B using encoding information from FONT_INFO. CHAR2B is | ||
| 1643 | the two-byte form of C. Encoding is returned in *CHAR2B. */ | 1617 | the two-byte form of C. Encoding is returned in *CHAR2B. */ |
| 1644 | 1618 | ||
| 1645 | static INLINE void | 1619 | static int |
| 1646 | x_encode_char (c, char2b, font_info) | 1620 | mac_encode_char (c, char2b, font_info, two_byte_p) |
| 1647 | int c; | 1621 | int c; |
| 1648 | XChar2b *char2b; | 1622 | XChar2b *char2b; |
| 1649 | struct font_info *font_info; | 1623 | struct font_info *font_info; |
| 1624 | int *two_byte_p; | ||
| 1650 | { | 1625 | { |
| 1651 | int charset = CHAR_CHARSET (c); | 1626 | int charset = CHAR_CHARSET (c); |
| 1652 | XFontStruct *font = font_info->font; | 1627 | XFontStruct *font = font_info->font; |
| @@ -1702,1067 +1677,11 @@ x_encode_char (c, char2b, font_info) | |||
| 1702 | char2b->byte2 = sjis2; | 1677 | char2b->byte2 = sjis2; |
| 1703 | } | 1678 | } |
| 1704 | } | 1679 | } |
| 1705 | } | ||
| 1706 | |||
| 1707 | |||
| 1708 | /* Get face and two-byte form of character C in face FACE_ID on frame | ||
| 1709 | F. The encoding of C is returned in *CHAR2B. MULTIBYTE_P non-zero | ||
| 1710 | means we want to display multibyte text. Value is a pointer to a | ||
| 1711 | realized face that is ready for display. */ | ||
| 1712 | |||
| 1713 | static INLINE struct face * | ||
| 1714 | x_get_char_face_and_encoding (f, c, face_id, char2b, multibyte_p) | ||
| 1715 | struct frame *f; | ||
| 1716 | int c, face_id; | ||
| 1717 | XChar2b *char2b; | ||
| 1718 | int multibyte_p; | ||
| 1719 | { | ||
| 1720 | struct face *face = FACE_FROM_ID (f, face_id); | ||
| 1721 | |||
| 1722 | if (!multibyte_p) | ||
| 1723 | { | ||
| 1724 | /* Unibyte case. We don't have to encode, but we have to make | ||
| 1725 | sure to use a face suitable for unibyte. */ | ||
| 1726 | char2b->byte1 = 0; | ||
| 1727 | char2b->byte2 = c; | ||
| 1728 | face_id = FACE_FOR_CHAR (f, face, c); | ||
| 1729 | face = FACE_FROM_ID (f, face_id); | ||
| 1730 | } | ||
| 1731 | else if (c < 128 && face_id < BASIC_FACE_ID_SENTINEL) | ||
| 1732 | { | ||
| 1733 | /* Case of ASCII in a face known to fit ASCII. */ | ||
| 1734 | char2b->byte1 = 0; | ||
| 1735 | char2b->byte2 = c; | ||
| 1736 | } | ||
| 1737 | else | ||
| 1738 | { | ||
| 1739 | int c1, c2, charset; | ||
| 1740 | |||
| 1741 | /* Split characters into bytes. If c2 is -1 afterwards, C is | ||
| 1742 | really a one-byte character so that byte1 is zero. */ | ||
| 1743 | SPLIT_CHAR (c, charset, c1, c2); | ||
| 1744 | if (c2 > 0) | ||
| 1745 | char2b->byte1 = c1, char2b->byte2 = c2; | ||
| 1746 | else | ||
| 1747 | char2b->byte1 = 0, char2b->byte2 = c1; | ||
| 1748 | |||
| 1749 | /* Maybe encode the character in *CHAR2B. */ | ||
| 1750 | if (face->font != NULL) | ||
| 1751 | { | ||
| 1752 | struct font_info *font_info | ||
| 1753 | = FONT_INFO_FROM_ID (f, face->font_info_id); | ||
| 1754 | if (font_info) | ||
| 1755 | x_encode_char (c, char2b, font_info); | ||
| 1756 | } | ||
| 1757 | } | ||
| 1758 | |||
| 1759 | /* Make sure X resources of the face are allocated. */ | ||
| 1760 | xassert (face != NULL); | ||
| 1761 | PREPARE_FACE_FOR_DISPLAY (f, face); | ||
| 1762 | |||
| 1763 | return face; | ||
| 1764 | } | ||
| 1765 | |||
| 1766 | |||
| 1767 | /* Get face and two-byte form of character glyph GLYPH on frame F. | ||
| 1768 | The encoding of GLYPH->u.ch is returned in *CHAR2B. Value is | ||
| 1769 | a pointer to a realized face that is ready for display. */ | ||
| 1770 | |||
| 1771 | static INLINE struct face * | ||
| 1772 | x_get_glyph_face_and_encoding (f, glyph, char2b, two_byte_p) | ||
| 1773 | struct frame *f; | ||
| 1774 | struct glyph *glyph; | ||
| 1775 | XChar2b *char2b; | ||
| 1776 | int *two_byte_p; | ||
| 1777 | { | ||
| 1778 | struct face *face; | ||
| 1779 | |||
| 1780 | xassert (glyph->type == CHAR_GLYPH); | ||
| 1781 | face = FACE_FROM_ID (f, glyph->face_id); | ||
| 1782 | 1680 | ||
| 1783 | if (two_byte_p) | 1681 | if (two_byte_p) |
| 1784 | *two_byte_p = 0; | 1682 | *two_byte_p = ((XFontStruct *) (font_info->font))->max_byte1 > 0; |
| 1785 | |||
| 1786 | if (!glyph->multibyte_p) | ||
| 1787 | { | ||
| 1788 | /* Unibyte case. We don't have to encode, but we have to make | ||
| 1789 | sure to use a face suitable for unibyte. */ | ||
| 1790 | char2b->byte1 = 0; | ||
| 1791 | char2b->byte2 = glyph->u.ch; | ||
| 1792 | } | ||
| 1793 | else if (glyph->u.ch < 128 | ||
| 1794 | && glyph->face_id < BASIC_FACE_ID_SENTINEL) | ||
| 1795 | { | ||
| 1796 | /* Case of ASCII in a face known to fit ASCII. */ | ||
| 1797 | char2b->byte1 = 0; | ||
| 1798 | char2b->byte2 = glyph->u.ch; | ||
| 1799 | } | ||
| 1800 | else | ||
| 1801 | { | ||
| 1802 | int c1, c2, charset; | ||
| 1803 | |||
| 1804 | /* Split characters into bytes. If c2 is -1 afterwards, C is | ||
| 1805 | really a one-byte character so that byte1 is zero. */ | ||
| 1806 | SPLIT_CHAR (glyph->u.ch, charset, c1, c2); | ||
| 1807 | if (c2 > 0) | ||
| 1808 | char2b->byte1 = c1, char2b->byte2 = c2; | ||
| 1809 | else | ||
| 1810 | char2b->byte1 = 0, char2b->byte2 = c1; | ||
| 1811 | |||
| 1812 | /* Maybe encode the character in *CHAR2B. */ | ||
| 1813 | if (charset != CHARSET_ASCII) | ||
| 1814 | { | ||
| 1815 | struct font_info *font_info | ||
| 1816 | = FONT_INFO_FROM_ID (f, face->font_info_id); | ||
| 1817 | if (font_info) | ||
| 1818 | { | ||
| 1819 | x_encode_char (glyph->u.ch, char2b, font_info); | ||
| 1820 | if (two_byte_p) | ||
| 1821 | *two_byte_p | ||
| 1822 | = ((XFontStruct *) (font_info->font))->max_byte1 > 0; | ||
| 1823 | } | ||
| 1824 | } | ||
| 1825 | } | ||
| 1826 | |||
| 1827 | /* Make sure X resources of the face are allocated. */ | ||
| 1828 | xassert (face != NULL); | ||
| 1829 | PREPARE_FACE_FOR_DISPLAY (f, face); | ||
| 1830 | return face; | ||
| 1831 | } | ||
| 1832 | |||
| 1833 | |||
| 1834 | /* Store one glyph for IT->char_to_display in IT->glyph_row. | ||
| 1835 | Called from x_produce_glyphs when IT->glyph_row is non-null. */ | ||
| 1836 | |||
| 1837 | static INLINE void | ||
| 1838 | x_append_glyph (it) | ||
| 1839 | struct it *it; | ||
| 1840 | { | ||
| 1841 | struct glyph *glyph; | ||
| 1842 | enum glyph_row_area area = it->area; | ||
| 1843 | |||
| 1844 | xassert (it->glyph_row); | ||
| 1845 | xassert (it->char_to_display != '\n' && it->char_to_display != '\t'); | ||
| 1846 | |||
| 1847 | glyph = it->glyph_row->glyphs[area] + it->glyph_row->used[area]; | ||
| 1848 | if (glyph < it->glyph_row->glyphs[area + 1]) | ||
| 1849 | { | ||
| 1850 | glyph->charpos = CHARPOS (it->position); | ||
| 1851 | glyph->object = it->object; | ||
| 1852 | glyph->pixel_width = it->pixel_width; | ||
| 1853 | glyph->voffset = it->voffset; | ||
| 1854 | glyph->type = CHAR_GLYPH; | ||
| 1855 | glyph->multibyte_p = it->multibyte_p; | ||
| 1856 | glyph->left_box_line_p = it->start_of_box_run_p; | ||
| 1857 | glyph->right_box_line_p = it->end_of_box_run_p; | ||
| 1858 | glyph->overlaps_vertically_p = (it->phys_ascent > it->ascent | ||
| 1859 | || it->phys_descent > it->descent); | ||
| 1860 | glyph->padding_p = 0; | ||
| 1861 | glyph->glyph_not_available_p = it->glyph_not_available_p; | ||
| 1862 | glyph->face_id = it->face_id; | ||
| 1863 | glyph->u.ch = it->char_to_display; | ||
| 1864 | ++it->glyph_row->used[area]; | ||
| 1865 | } | ||
| 1866 | } | ||
| 1867 | |||
| 1868 | /* Store one glyph for the composition IT->cmp_id in IT->glyph_row. | ||
| 1869 | Called from x_produce_glyphs when IT->glyph_row is non-null. */ | ||
| 1870 | |||
| 1871 | static INLINE void | ||
| 1872 | x_append_composite_glyph (it) | ||
| 1873 | struct it *it; | ||
| 1874 | { | ||
| 1875 | struct glyph *glyph; | ||
| 1876 | enum glyph_row_area area = it->area; | ||
| 1877 | |||
| 1878 | xassert (it->glyph_row); | ||
| 1879 | |||
| 1880 | glyph = it->glyph_row->glyphs[area] + it->glyph_row->used[area]; | ||
| 1881 | if (glyph < it->glyph_row->glyphs[area + 1]) | ||
| 1882 | { | ||
| 1883 | glyph->charpos = CHARPOS (it->position); | ||
| 1884 | glyph->object = it->object; | ||
| 1885 | glyph->pixel_width = it->pixel_width; | ||
| 1886 | glyph->voffset = it->voffset; | ||
| 1887 | glyph->type = COMPOSITE_GLYPH; | ||
| 1888 | glyph->multibyte_p = it->multibyte_p; | ||
| 1889 | glyph->left_box_line_p = it->start_of_box_run_p; | ||
| 1890 | glyph->right_box_line_p = it->end_of_box_run_p; | ||
| 1891 | glyph->overlaps_vertically_p = (it->phys_ascent > it->ascent | ||
| 1892 | || it->phys_descent > it->descent); | ||
| 1893 | glyph->padding_p = 0; | ||
| 1894 | glyph->glyph_not_available_p = 0; | ||
| 1895 | glyph->face_id = it->face_id; | ||
| 1896 | glyph->u.cmp_id = it->cmp_id; | ||
| 1897 | ++it->glyph_row->used[area]; | ||
| 1898 | } | ||
| 1899 | } | ||
| 1900 | |||
| 1901 | |||
| 1902 | /* Change IT->ascent and IT->height according to the setting of | ||
| 1903 | IT->voffset. */ | ||
| 1904 | |||
| 1905 | static INLINE void | ||
| 1906 | take_vertical_position_into_account (it) | ||
| 1907 | struct it *it; | ||
| 1908 | { | ||
| 1909 | if (it->voffset) | ||
| 1910 | { | ||
| 1911 | if (it->voffset < 0) | ||
| 1912 | /* Increase the ascent so that we can display the text higher | ||
| 1913 | in the line. */ | ||
| 1914 | it->ascent += abs (it->voffset); | ||
| 1915 | else | ||
| 1916 | /* Increase the descent so that we can display the text lower | ||
| 1917 | in the line. */ | ||
| 1918 | it->descent += it->voffset; | ||
| 1919 | } | ||
| 1920 | } | ||
| 1921 | |||
| 1922 | |||
| 1923 | /* Produce glyphs/get display metrics for the image IT is loaded with. | ||
| 1924 | See the description of struct display_iterator in dispextern.h for | ||
| 1925 | an overview of struct display_iterator. */ | ||
| 1926 | |||
| 1927 | static void | ||
| 1928 | x_produce_image_glyph (it) | ||
| 1929 | struct it *it; | ||
| 1930 | { | ||
| 1931 | struct image *img; | ||
| 1932 | struct face *face; | ||
| 1933 | |||
| 1934 | xassert (it->what == IT_IMAGE); | ||
| 1935 | |||
| 1936 | face = FACE_FROM_ID (it->f, it->face_id); | ||
| 1937 | img = IMAGE_FROM_ID (it->f, it->image_id); | ||
| 1938 | xassert (img); | ||
| 1939 | |||
| 1940 | /* Make sure X resources of the face and image are loaded. */ | ||
| 1941 | PREPARE_FACE_FOR_DISPLAY (it->f, face); | ||
| 1942 | prepare_image_for_display (it->f, img); | ||
| 1943 | |||
| 1944 | it->ascent = it->phys_ascent = image_ascent (img, face); | ||
| 1945 | it->descent = it->phys_descent = img->height + 2 * img->vmargin - it->ascent; | ||
| 1946 | it->pixel_width = img->width + 2 * img->hmargin; | ||
| 1947 | |||
| 1948 | it->nglyphs = 1; | ||
| 1949 | |||
| 1950 | if (face->box != FACE_NO_BOX) | ||
| 1951 | { | ||
| 1952 | if (face->box_line_width > 0) | ||
| 1953 | { | ||
| 1954 | it->ascent += face->box_line_width; | ||
| 1955 | it->descent += face->box_line_width; | ||
| 1956 | } | ||
| 1957 | |||
| 1958 | if (it->start_of_box_run_p) | ||
| 1959 | it->pixel_width += abs (face->box_line_width); | ||
| 1960 | if (it->end_of_box_run_p) | ||
| 1961 | it->pixel_width += abs (face->box_line_width); | ||
| 1962 | } | ||
| 1963 | |||
| 1964 | take_vertical_position_into_account (it); | ||
| 1965 | |||
| 1966 | if (it->glyph_row) | ||
| 1967 | { | ||
| 1968 | struct glyph *glyph; | ||
| 1969 | enum glyph_row_area area = it->area; | ||
| 1970 | |||
| 1971 | glyph = it->glyph_row->glyphs[area] + it->glyph_row->used[area]; | ||
| 1972 | if (glyph < it->glyph_row->glyphs[area + 1]) | ||
| 1973 | { | ||
| 1974 | glyph->charpos = CHARPOS (it->position); | ||
| 1975 | glyph->object = it->object; | ||
| 1976 | glyph->pixel_width = it->pixel_width; | ||
| 1977 | glyph->voffset = it->voffset; | ||
| 1978 | glyph->type = IMAGE_GLYPH; | ||
| 1979 | glyph->multibyte_p = it->multibyte_p; | ||
| 1980 | glyph->left_box_line_p = it->start_of_box_run_p; | ||
| 1981 | glyph->right_box_line_p = it->end_of_box_run_p; | ||
| 1982 | glyph->overlaps_vertically_p = 0; | ||
| 1983 | glyph->padding_p = 0; | ||
| 1984 | glyph->glyph_not_available_p = 0; | ||
| 1985 | glyph->face_id = it->face_id; | ||
| 1986 | glyph->u.img_id = img->id; | ||
| 1987 | ++it->glyph_row->used[area]; | ||
| 1988 | } | ||
| 1989 | } | ||
| 1990 | } | ||
| 1991 | |||
| 1992 | |||
| 1993 | /* Append a stretch glyph to IT->glyph_row. OBJECT is the source | ||
| 1994 | of the glyph, WIDTH and HEIGHT are the width and height of the | ||
| 1995 | stretch. ASCENT is the percentage/100 of HEIGHT to use for the | ||
| 1996 | ascent of the glyph (0 <= ASCENT <= 1). */ | ||
| 1997 | |||
| 1998 | static void | ||
| 1999 | x_append_stretch_glyph (it, object, width, height, ascent) | ||
| 2000 | struct it *it; | ||
| 2001 | Lisp_Object object; | ||
| 2002 | int width, height; | ||
| 2003 | double ascent; | ||
| 2004 | { | ||
| 2005 | struct glyph *glyph; | ||
| 2006 | enum glyph_row_area area = it->area; | ||
| 2007 | |||
| 2008 | xassert (ascent >= 0 && ascent <= 1); | ||
| 2009 | |||
| 2010 | glyph = it->glyph_row->glyphs[area] + it->glyph_row->used[area]; | ||
| 2011 | if (glyph < it->glyph_row->glyphs[area + 1]) | ||
| 2012 | { | ||
| 2013 | glyph->charpos = CHARPOS (it->position); | ||
| 2014 | glyph->object = object; | ||
| 2015 | glyph->pixel_width = width; | ||
| 2016 | glyph->voffset = it->voffset; | ||
| 2017 | glyph->type = STRETCH_GLYPH; | ||
| 2018 | glyph->multibyte_p = it->multibyte_p; | ||
| 2019 | glyph->left_box_line_p = it->start_of_box_run_p; | ||
| 2020 | glyph->right_box_line_p = it->end_of_box_run_p; | ||
| 2021 | glyph->overlaps_vertically_p = 0; | ||
| 2022 | glyph->padding_p = 0; | ||
| 2023 | glyph->glyph_not_available_p = 0; | ||
| 2024 | glyph->face_id = it->face_id; | ||
| 2025 | glyph->u.stretch.ascent = height * ascent; | ||
| 2026 | glyph->u.stretch.height = height; | ||
| 2027 | ++it->glyph_row->used[area]; | ||
| 2028 | } | ||
| 2029 | } | ||
| 2030 | |||
| 2031 | |||
| 2032 | /* Produce a stretch glyph for iterator IT. IT->object is the value | ||
| 2033 | of the glyph property displayed. The value must be a list | ||
| 2034 | `(space KEYWORD VALUE ...)' with the following KEYWORD/VALUE pairs | ||
| 2035 | being recognized: | ||
| 2036 | |||
| 2037 | 1. `:width WIDTH' specifies that the space should be WIDTH * | ||
| 2038 | canonical char width wide. WIDTH may be an integer or floating | ||
| 2039 | point number. | ||
| 2040 | |||
| 2041 | 2. `:relative-width FACTOR' specifies that the width of the stretch | ||
| 2042 | should be computed from the width of the first character having the | ||
| 2043 | `glyph' property, and should be FACTOR times that width. | ||
| 2044 | |||
| 2045 | 3. `:align-to HPOS' specifies that the space should be wide enough | ||
| 2046 | to reach HPOS, a value in canonical character units. | ||
| 2047 | |||
| 2048 | Exactly one of the above pairs must be present. | ||
| 2049 | |||
| 2050 | 4. `:height HEIGHT' specifies that the height of the stretch produced | ||
| 2051 | should be HEIGHT, measured in canonical character units. | ||
| 2052 | |||
| 2053 | 5. `:relative-height FACTOR' specifies that the height of the | ||
| 2054 | stretch should be FACTOR times the height of the characters having | ||
| 2055 | the glyph property. | ||
| 2056 | |||
| 2057 | Either none or exactly one of 4 or 5 must be present. | ||
| 2058 | |||
| 2059 | 6. `:ascent ASCENT' specifies that ASCENT percent of the height | ||
| 2060 | of the stretch should be used for the ascent of the stretch. | ||
| 2061 | ASCENT must be in the range 0 <= ASCENT <= 100. */ | ||
| 2062 | |||
| 2063 | #define NUMVAL(X) \ | ||
| 2064 | ((INTEGERP (X) || FLOATP (X)) \ | ||
| 2065 | ? XFLOATINT (X) \ | ||
| 2066 | : - 1) | ||
| 2067 | |||
| 2068 | |||
| 2069 | static void | ||
| 2070 | x_produce_stretch_glyph (it) | ||
| 2071 | struct it *it; | ||
| 2072 | { | ||
| 2073 | /* (space :width WIDTH :height HEIGHT. */ | ||
| 2074 | #if GLYPH_DEBUG | ||
| 2075 | extern Lisp_Object Qspace; | ||
| 2076 | #endif | ||
| 2077 | extern Lisp_Object QCwidth, QCheight, QCascent; | ||
| 2078 | extern Lisp_Object QCrelative_width, QCrelative_height; | ||
| 2079 | extern Lisp_Object QCalign_to; | ||
| 2080 | Lisp_Object prop, plist; | ||
| 2081 | double width = 0, height = 0, ascent = 0; | ||
| 2082 | struct face *face = FACE_FROM_ID (it->f, it->face_id); | ||
| 2083 | XFontStruct *font = face->font ? face->font : FRAME_FONT (it->f); | ||
| 2084 | |||
| 2085 | PREPARE_FACE_FOR_DISPLAY (it->f, face); | ||
| 2086 | |||
| 2087 | /* List should start with `space'. */ | ||
| 2088 | xassert (CONSP (it->object) && EQ (XCAR (it->object), Qspace)); | ||
| 2089 | plist = XCDR (it->object); | ||
| 2090 | |||
| 2091 | /* Compute the width of the stretch. */ | ||
| 2092 | if (prop = Fplist_get (plist, QCwidth), | ||
| 2093 | NUMVAL (prop) > 0) | ||
| 2094 | /* Absolute width `:width WIDTH' specified and valid. */ | ||
| 2095 | width = NUMVAL (prop) * CANON_X_UNIT (it->f); | ||
| 2096 | else if (prop = Fplist_get (plist, QCrelative_width), | ||
| 2097 | NUMVAL (prop) > 0) | ||
| 2098 | { | ||
| 2099 | /* Relative width `:relative-width FACTOR' specified and valid. | ||
| 2100 | Compute the width of the characters having the `glyph' | ||
| 2101 | property. */ | ||
| 2102 | struct it it2; | ||
| 2103 | unsigned char *p = BYTE_POS_ADDR (IT_BYTEPOS (*it)); | ||
| 2104 | |||
| 2105 | it2 = *it; | ||
| 2106 | if (it->multibyte_p) | ||
| 2107 | { | ||
| 2108 | int maxlen = ((IT_BYTEPOS (*it) >= GPT ? ZV : GPT) | ||
| 2109 | - IT_BYTEPOS (*it)); | ||
| 2110 | it2.c = STRING_CHAR_AND_LENGTH (p, maxlen, it2.len); | ||
| 2111 | } | ||
| 2112 | else | ||
| 2113 | it2.c = *p, it2.len = 1; | ||
| 2114 | |||
| 2115 | it2.glyph_row = NULL; | ||
| 2116 | it2.what = IT_CHARACTER; | ||
| 2117 | x_produce_glyphs (&it2); | ||
| 2118 | width = NUMVAL (prop) * it2.pixel_width; | ||
| 2119 | } | ||
| 2120 | else if (prop = Fplist_get (plist, QCalign_to), | ||
| 2121 | NUMVAL (prop) > 0) | ||
| 2122 | width = NUMVAL (prop) * CANON_X_UNIT (it->f) - it->current_x; | ||
| 2123 | else | ||
| 2124 | /* Nothing specified -> width defaults to canonical char width. */ | ||
| 2125 | width = CANON_X_UNIT (it->f); | ||
| 2126 | |||
| 2127 | /* Compute height. */ | ||
| 2128 | if (prop = Fplist_get (plist, QCheight), | ||
| 2129 | NUMVAL (prop) > 0) | ||
| 2130 | height = NUMVAL (prop) * CANON_Y_UNIT (it->f); | ||
| 2131 | else if (prop = Fplist_get (plist, QCrelative_height), | ||
| 2132 | NUMVAL (prop) > 0) | ||
| 2133 | height = FONT_HEIGHT (font) * NUMVAL (prop); | ||
| 2134 | else | ||
| 2135 | height = FONT_HEIGHT (font); | ||
| 2136 | |||
| 2137 | /* Compute percentage of height used for ascent. If | ||
| 2138 | `:ascent ASCENT' is present and valid, use that. Otherwise, | ||
| 2139 | derive the ascent from the font in use. */ | ||
| 2140 | if (prop = Fplist_get (plist, QCascent), | ||
| 2141 | NUMVAL (prop) > 0 && NUMVAL (prop) <= 100) | ||
| 2142 | ascent = NUMVAL (prop) / 100.0; | ||
| 2143 | else | ||
| 2144 | ascent = (double) FONT_BASE (font) / FONT_HEIGHT (font); | ||
| 2145 | |||
| 2146 | if (width <= 0) | ||
| 2147 | width = 1; | ||
| 2148 | if (height <= 0) | ||
| 2149 | height = 1; | ||
| 2150 | |||
| 2151 | if (it->glyph_row) | ||
| 2152 | { | ||
| 2153 | Lisp_Object object = it->stack[it->sp - 1].string; | ||
| 2154 | if (!STRINGP (object)) | ||
| 2155 | object = it->w->buffer; | ||
| 2156 | x_append_stretch_glyph (it, object, width, height, ascent); | ||
| 2157 | } | ||
| 2158 | |||
| 2159 | it->pixel_width = width; | ||
| 2160 | it->ascent = it->phys_ascent = height * ascent; | ||
| 2161 | it->descent = it->phys_descent = height - it->ascent; | ||
| 2162 | it->nglyphs = 1; | ||
| 2163 | |||
| 2164 | if (face->box != FACE_NO_BOX) | ||
| 2165 | { | ||
| 2166 | if (face->box_line_width > 0) | ||
| 2167 | { | ||
| 2168 | it->ascent += face->box_line_width; | ||
| 2169 | it->descent += face->box_line_width; | ||
| 2170 | } | ||
| 2171 | |||
| 2172 | if (it->start_of_box_run_p) | ||
| 2173 | it->pixel_width += abs (face->box_line_width); | ||
| 2174 | if (it->end_of_box_run_p) | ||
| 2175 | it->pixel_width += abs (face->box_line_width); | ||
| 2176 | } | ||
| 2177 | |||
| 2178 | take_vertical_position_into_account (it); | ||
| 2179 | } | ||
| 2180 | |||
| 2181 | /* Return proper value to be used as baseline offset of font that has | ||
| 2182 | ASCENT and DESCENT to draw characters by the font at the vertical | ||
| 2183 | center of the line of frame F. | ||
| 2184 | |||
| 2185 | Here, out task is to find the value of BOFF in the following figure; | ||
| 2186 | |||
| 2187 | -------------------------+-----------+- | ||
| 2188 | -+-+---------+-+ | | | ||
| 2189 | | | | | | | | ||
| 2190 | | | | | F_ASCENT F_HEIGHT | ||
| 2191 | | | | ASCENT | | | ||
| 2192 | HEIGHT | | | | | | ||
| 2193 | | | |-|-+------+-----------|------- baseline | ||
| 2194 | | | | | BOFF | | | ||
| 2195 | | |---------|-+-+ | | | ||
| 2196 | | | | DESCENT | | | ||
| 2197 | -+-+---------+-+ F_DESCENT | | ||
| 2198 | -------------------------+-----------+- | ||
| 2199 | |||
| 2200 | -BOFF + DESCENT + (F_HEIGHT - HEIGHT) / 2 = F_DESCENT | ||
| 2201 | BOFF = DESCENT + (F_HEIGHT - HEIGHT) / 2 - F_DESCENT | ||
| 2202 | DESCENT = FONT->descent | ||
| 2203 | HEIGHT = FONT_HEIGHT (FONT) | ||
| 2204 | F_DESCENT = (F->output_data.x->font->descent | ||
| 2205 | - F->output_data.x->baseline_offset) | ||
| 2206 | F_HEIGHT = FRAME_LINE_HEIGHT (F) | ||
| 2207 | */ | ||
| 2208 | |||
| 2209 | #define VCENTER_BASELINE_OFFSET(FONT, F) \ | ||
| 2210 | (FONT_DESCENT (FONT) \ | ||
| 2211 | + (FRAME_LINE_HEIGHT ((F)) - FONT_HEIGHT ((FONT)) \ | ||
| 2212 | + (FRAME_LINE_HEIGHT ((F)) > FONT_HEIGHT ((FONT)))) / 2 \ | ||
| 2213 | - (FONT_DESCENT (FRAME_FONT (F)) - FRAME_BASELINE_OFFSET (F))) | ||
| 2214 | |||
| 2215 | /* Produce glyphs/get display metrics for the display element IT is | ||
| 2216 | loaded with. See the description of struct display_iterator in | ||
| 2217 | dispextern.h for an overview of struct display_iterator. */ | ||
| 2218 | |||
| 2219 | static void | ||
| 2220 | x_produce_glyphs (it) | ||
| 2221 | struct it *it; | ||
| 2222 | { | ||
| 2223 | it->glyph_not_available_p = 0; | ||
| 2224 | |||
| 2225 | if (it->what == IT_CHARACTER) | ||
| 2226 | { | ||
| 2227 | XChar2b char2b; | ||
| 2228 | XFontStruct *font; | ||
| 2229 | struct face *face = FACE_FROM_ID (it->f, it->face_id); | ||
| 2230 | XCharStruct *pcm; | ||
| 2231 | int font_not_found_p; | ||
| 2232 | struct font_info *font_info; | ||
| 2233 | int boff; /* baseline offset */ | ||
| 2234 | /* We may change it->multibyte_p upon unibyte<->multibyte | ||
| 2235 | conversion. So, save the current value now and restore it | ||
| 2236 | later. | ||
| 2237 | |||
| 2238 | Note: It seems that we don't have to record multibyte_p in | ||
| 2239 | struct glyph because the character code itself tells if or | ||
| 2240 | not the character is multibyte. Thus, in the future, we must | ||
| 2241 | consider eliminating the field `multibyte_p' in the struct | ||
| 2242 | glyph. | ||
| 2243 | */ | ||
| 2244 | int saved_multibyte_p = it->multibyte_p; | ||
| 2245 | |||
| 2246 | /* Maybe translate single-byte characters to multibyte, or the | ||
| 2247 | other way. */ | ||
| 2248 | it->char_to_display = it->c; | ||
| 2249 | if (!ASCII_BYTE_P (it->c)) | ||
| 2250 | { | ||
| 2251 | if (unibyte_display_via_language_environment | ||
| 2252 | && SINGLE_BYTE_CHAR_P (it->c) | ||
| 2253 | && (it->c >= 0240 | ||
| 2254 | || !NILP (Vnonascii_translation_table))) | ||
| 2255 | { | ||
| 2256 | it->char_to_display = unibyte_char_to_multibyte (it->c); | ||
| 2257 | it->multibyte_p = 1; | ||
| 2258 | it->face_id = FACE_FOR_CHAR (it->f, face, it->char_to_display); | ||
| 2259 | face = FACE_FROM_ID (it->f, it->face_id); | ||
| 2260 | } | ||
| 2261 | else if (!SINGLE_BYTE_CHAR_P (it->c) | ||
| 2262 | && !it->multibyte_p) | ||
| 2263 | { | ||
| 2264 | it->multibyte_p = 1; | ||
| 2265 | it->face_id = FACE_FOR_CHAR (it->f, face, it->char_to_display); | ||
| 2266 | face = FACE_FROM_ID (it->f, it->face_id); | ||
| 2267 | } | ||
| 2268 | } | ||
| 2269 | |||
| 2270 | /* Get font to use. Encode IT->char_to_display. */ | ||
| 2271 | x_get_char_face_and_encoding (it->f, it->char_to_display, | ||
| 2272 | it->face_id, &char2b, | ||
| 2273 | it->multibyte_p); | ||
| 2274 | font = face->font; | ||
| 2275 | 1683 | ||
| 2276 | /* When no suitable font found, use the default font. */ | 1684 | return FONT_TYPE_UNKNOWN; |
| 2277 | font_not_found_p = font == NULL; | ||
| 2278 | if (font_not_found_p) | ||
| 2279 | { | ||
| 2280 | font = FRAME_FONT (it->f); | ||
| 2281 | boff = it->f->output_data.mac->baseline_offset; | ||
| 2282 | font_info = NULL; | ||
| 2283 | } | ||
| 2284 | else | ||
| 2285 | { | ||
| 2286 | font_info = FONT_INFO_FROM_ID (it->f, face->font_info_id); | ||
| 2287 | boff = font_info->baseline_offset; | ||
| 2288 | if (font_info->vertical_centering) | ||
| 2289 | boff = VCENTER_BASELINE_OFFSET (font, it->f) - boff; | ||
| 2290 | } | ||
| 2291 | |||
| 2292 | if (it->char_to_display >= ' ' | ||
| 2293 | && (!it->multibyte_p || it->char_to_display < 128)) | ||
| 2294 | { | ||
| 2295 | /* Either unibyte or ASCII. */ | ||
| 2296 | int stretched_p; | ||
| 2297 | |||
| 2298 | it->nglyphs = 1; | ||
| 2299 | |||
| 2300 | pcm = x_per_char_metric (font, &char2b); | ||
| 2301 | it->ascent = FONT_BASE (font) + boff; | ||
| 2302 | it->descent = FONT_DESCENT (font) - boff; | ||
| 2303 | |||
| 2304 | if (pcm) | ||
| 2305 | { | ||
| 2306 | it->phys_ascent = pcm->ascent + boff; | ||
| 2307 | it->phys_descent = pcm->descent - boff; | ||
| 2308 | it->pixel_width = pcm->width; | ||
| 2309 | } | ||
| 2310 | else | ||
| 2311 | { | ||
| 2312 | it->glyph_not_available_p = 1; | ||
| 2313 | it->phys_ascent = FONT_BASE (font) + boff; | ||
| 2314 | it->phys_descent = FONT_DESCENT (font) - boff; | ||
| 2315 | it->pixel_width = FONT_WIDTH (font); | ||
| 2316 | } | ||
| 2317 | |||
| 2318 | /* If this is a space inside a region of text with | ||
| 2319 | `space-width' property, change its width. */ | ||
| 2320 | stretched_p = it->char_to_display == ' ' && !NILP (it->space_width); | ||
| 2321 | if (stretched_p) | ||
| 2322 | it->pixel_width *= XFLOATINT (it->space_width); | ||
| 2323 | |||
| 2324 | /* If face has a box, add the box thickness to the character | ||
| 2325 | height. If character has a box line to the left and/or | ||
| 2326 | right, add the box line width to the character's width. */ | ||
| 2327 | if (face->box != FACE_NO_BOX) | ||
| 2328 | { | ||
| 2329 | int thick = face->box_line_width; | ||
| 2330 | |||
| 2331 | if (thick > 0) | ||
| 2332 | { | ||
| 2333 | it->ascent += thick; | ||
| 2334 | it->descent += thick; | ||
| 2335 | } | ||
| 2336 | else | ||
| 2337 | thick = -thick; | ||
| 2338 | |||
| 2339 | if (it->start_of_box_run_p) | ||
| 2340 | it->pixel_width += thick; | ||
| 2341 | if (it->end_of_box_run_p) | ||
| 2342 | it->pixel_width += thick; | ||
| 2343 | } | ||
| 2344 | |||
| 2345 | /* If face has an overline, add the height of the overline | ||
| 2346 | (1 pixel) and a 1 pixel margin to the character height. */ | ||
| 2347 | if (face->overline_p) | ||
| 2348 | it->ascent += 2; | ||
| 2349 | |||
| 2350 | take_vertical_position_into_account (it); | ||
| 2351 | |||
| 2352 | /* If we have to actually produce glyphs, do it. */ | ||
| 2353 | if (it->glyph_row) | ||
| 2354 | { | ||
| 2355 | if (stretched_p) | ||
| 2356 | { | ||
| 2357 | /* Translate a space with a `space-width' property | ||
| 2358 | into a stretch glyph. */ | ||
| 2359 | double ascent = (double) FONT_BASE (font) | ||
| 2360 | / FONT_HEIGHT (font); | ||
| 2361 | x_append_stretch_glyph (it, it->object, it->pixel_width, | ||
| 2362 | it->ascent + it->descent, ascent); | ||
| 2363 | } | ||
| 2364 | else | ||
| 2365 | x_append_glyph (it); | ||
| 2366 | |||
| 2367 | /* If characters with lbearing or rbearing are displayed | ||
| 2368 | in this line, record that fact in a flag of the | ||
| 2369 | glyph row. This is used to optimize X output code. */ | ||
| 2370 | if (pcm && (pcm->lbearing < 0 || pcm->rbearing > pcm->width)) | ||
| 2371 | it->glyph_row->contains_overlapping_glyphs_p = 1; | ||
| 2372 | } | ||
| 2373 | } | ||
| 2374 | else if (it->char_to_display == '\n') | ||
| 2375 | { | ||
| 2376 | /* A newline has no width but we need the height of the line. */ | ||
| 2377 | it->pixel_width = 0; | ||
| 2378 | it->nglyphs = 0; | ||
| 2379 | it->ascent = it->phys_ascent = FONT_BASE (font) + boff; | ||
| 2380 | it->descent = it->phys_descent = FONT_DESCENT (font) - boff; | ||
| 2381 | |||
| 2382 | if (face->box != FACE_NO_BOX | ||
| 2383 | && face->box_line_width > 0) | ||
| 2384 | { | ||
| 2385 | it->ascent += face->box_line_width; | ||
| 2386 | it->descent += face->box_line_width; | ||
| 2387 | } | ||
| 2388 | } | ||
| 2389 | else if (it->char_to_display == '\t') | ||
| 2390 | { | ||
| 2391 | int tab_width = it->tab_width * CANON_X_UNIT (it->f); | ||
| 2392 | int x = it->current_x + it->continuation_lines_width; | ||
| 2393 | int next_tab_x = ((1 + x + tab_width - 1) / tab_width) * tab_width; | ||
| 2394 | |||
| 2395 | /* If the distance from the current position to the next tab | ||
| 2396 | stop is less than a canonical character width, use the | ||
| 2397 | tab stop after that. */ | ||
| 2398 | if (next_tab_x - x < CANON_X_UNIT (it->f)) | ||
| 2399 | next_tab_x += tab_width; | ||
| 2400 | |||
| 2401 | it->pixel_width = next_tab_x - x; | ||
| 2402 | it->nglyphs = 1; | ||
| 2403 | it->ascent = it->phys_ascent = FONT_BASE (font) + boff; | ||
| 2404 | it->descent = it->phys_descent = FONT_DESCENT (font) - boff; | ||
| 2405 | |||
| 2406 | if (it->glyph_row) | ||
| 2407 | { | ||
| 2408 | double ascent = (double) it->ascent / (it->ascent + it->descent); | ||
| 2409 | x_append_stretch_glyph (it, it->object, it->pixel_width, | ||
| 2410 | it->ascent + it->descent, ascent); | ||
| 2411 | } | ||
| 2412 | } | ||
| 2413 | else | ||
| 2414 | { | ||
| 2415 | /* A multi-byte character. Assume that the display width of the | ||
| 2416 | character is the width of the character multiplied by the | ||
| 2417 | width of the font. */ | ||
| 2418 | |||
| 2419 | /* If we found a font, this font should give us the right | ||
| 2420 | metrics. If we didn't find a font, use the frame's | ||
| 2421 | default font and calculate the width of the character | ||
| 2422 | from the charset width; this is what old redisplay code | ||
| 2423 | did. */ | ||
| 2424 | pcm = x_per_char_metric (font, &char2b); | ||
| 2425 | if (font_not_found_p || !pcm) | ||
| 2426 | { | ||
| 2427 | int charset = CHAR_CHARSET (it->char_to_display); | ||
| 2428 | |||
| 2429 | it->glyph_not_available_p = 1; | ||
| 2430 | it->pixel_width = (FONT_WIDTH (FRAME_FONT (it->f)) | ||
| 2431 | * CHARSET_WIDTH (charset)); | ||
| 2432 | it->phys_ascent = FONT_BASE (font) + boff; | ||
| 2433 | it->phys_descent = FONT_DESCENT (font) - boff; | ||
| 2434 | } | ||
| 2435 | else | ||
| 2436 | { | ||
| 2437 | it->pixel_width = pcm->width; | ||
| 2438 | it->phys_ascent = pcm->ascent + boff; | ||
| 2439 | it->phys_descent = pcm->descent - boff; | ||
| 2440 | if (it->glyph_row | ||
| 2441 | && (pcm->lbearing < 0 | ||
| 2442 | || pcm->rbearing > pcm->width)) | ||
| 2443 | it->glyph_row->contains_overlapping_glyphs_p = 1; | ||
| 2444 | } | ||
| 2445 | it->nglyphs = 1; | ||
| 2446 | it->ascent = FONT_BASE (font) + boff; | ||
| 2447 | it->descent = FONT_DESCENT (font) - boff; | ||
| 2448 | if (face->box != FACE_NO_BOX) | ||
| 2449 | { | ||
| 2450 | int thick = face->box_line_width; | ||
| 2451 | |||
| 2452 | if (thick > 0) | ||
| 2453 | { | ||
| 2454 | it->ascent += thick; | ||
| 2455 | it->descent += thick; | ||
| 2456 | } | ||
| 2457 | else | ||
| 2458 | thick = - thick; | ||
| 2459 | |||
| 2460 | if (it->start_of_box_run_p) | ||
| 2461 | it->pixel_width += thick; | ||
| 2462 | if (it->end_of_box_run_p) | ||
| 2463 | it->pixel_width += thick; | ||
| 2464 | } | ||
| 2465 | |||
| 2466 | /* If face has an overline, add the height of the overline | ||
| 2467 | (1 pixel) and a 1 pixel margin to the character height. */ | ||
| 2468 | if (face->overline_p) | ||
| 2469 | it->ascent += 2; | ||
| 2470 | |||
| 2471 | take_vertical_position_into_account (it); | ||
| 2472 | |||
| 2473 | if (it->glyph_row) | ||
| 2474 | x_append_glyph (it); | ||
| 2475 | } | ||
| 2476 | it->multibyte_p = saved_multibyte_p; | ||
| 2477 | } | ||
| 2478 | else if (it->what == IT_COMPOSITION) | ||
| 2479 | { | ||
| 2480 | /* Note: A composition is represented as one glyph in the | ||
| 2481 | glyph matrix. There are no padding glyphs. */ | ||
| 2482 | XChar2b char2b; | ||
| 2483 | XFontStruct *font; | ||
| 2484 | struct face *face = FACE_FROM_ID (it->f, it->face_id); | ||
| 2485 | XCharStruct *pcm; | ||
| 2486 | int font_not_found_p; | ||
| 2487 | struct font_info *font_info; | ||
| 2488 | int boff; /* baseline offset */ | ||
| 2489 | struct composition *cmp = composition_table[it->cmp_id]; | ||
| 2490 | |||
| 2491 | /* Maybe translate single-byte characters to multibyte. */ | ||
| 2492 | it->char_to_display = it->c; | ||
| 2493 | if (unibyte_display_via_language_environment | ||
| 2494 | && SINGLE_BYTE_CHAR_P (it->c) | ||
| 2495 | && (it->c >= 0240 | ||
| 2496 | || (it->c >= 0200 | ||
| 2497 | && !NILP (Vnonascii_translation_table)))) | ||
| 2498 | { | ||
| 2499 | it->char_to_display = unibyte_char_to_multibyte (it->c); | ||
| 2500 | } | ||
| 2501 | |||
| 2502 | /* Get face and font to use. Encode IT->char_to_display. */ | ||
| 2503 | it->face_id = FACE_FOR_CHAR (it->f, face, it->char_to_display); | ||
| 2504 | face = FACE_FROM_ID (it->f, it->face_id); | ||
| 2505 | x_get_char_face_and_encoding (it->f, it->char_to_display, | ||
| 2506 | it->face_id, &char2b, it->multibyte_p); | ||
| 2507 | font = face->font; | ||
| 2508 | |||
| 2509 | /* When no suitable font found, use the default font. */ | ||
| 2510 | font_not_found_p = font == NULL; | ||
| 2511 | if (font_not_found_p) | ||
| 2512 | { | ||
| 2513 | font = FRAME_FONT (it->f); | ||
| 2514 | boff = it->f->output_data.mac->baseline_offset; | ||
| 2515 | font_info = NULL; | ||
| 2516 | } | ||
| 2517 | else | ||
| 2518 | { | ||
| 2519 | font_info = FONT_INFO_FROM_ID (it->f, face->font_info_id); | ||
| 2520 | boff = font_info->baseline_offset; | ||
| 2521 | if (font_info->vertical_centering) | ||
| 2522 | boff = VCENTER_BASELINE_OFFSET (font, it->f) - boff; | ||
| 2523 | } | ||
| 2524 | |||
| 2525 | /* There are no padding glyphs, so there is only one glyph to | ||
| 2526 | produce for the composition. Important is that pixel_width, | ||
| 2527 | ascent and descent are the values of what is drawn by | ||
| 2528 | draw_glyphs (i.e. the values of the overall glyphs composed). */ | ||
| 2529 | it->nglyphs = 1; | ||
| 2530 | |||
| 2531 | /* If we have not yet calculated pixel size data of glyphs of | ||
| 2532 | the composition for the current face font, calculate them | ||
| 2533 | now. Theoretically, we have to check all fonts for the | ||
| 2534 | glyphs, but that requires much time and memory space. So, | ||
| 2535 | here we check only the font of the first glyph. This leads | ||
| 2536 | to incorrect display very rarely, and C-l (recenter) can | ||
| 2537 | correct the display anyway. */ | ||
| 2538 | if (cmp->font != (void *) font) | ||
| 2539 | { | ||
| 2540 | /* Ascent and descent of the font of the first character of | ||
| 2541 | this composition (adjusted by baseline offset). Ascent | ||
| 2542 | and descent of overall glyphs should not be less than | ||
| 2543 | them respectively. */ | ||
| 2544 | int font_ascent = FONT_BASE (font) + boff; | ||
| 2545 | int font_descent = FONT_DESCENT (font) - boff; | ||
| 2546 | /* Bounding box of the overall glyphs. */ | ||
| 2547 | int leftmost, rightmost, lowest, highest; | ||
| 2548 | int i, width, ascent, descent; | ||
| 2549 | |||
| 2550 | cmp->font = (void *) font; | ||
| 2551 | |||
| 2552 | /* Initialize the bounding box. */ | ||
| 2553 | pcm = x_per_char_metric (font, &char2b); | ||
| 2554 | if (pcm) | ||
| 2555 | { | ||
| 2556 | width = pcm->width; | ||
| 2557 | ascent = pcm->ascent; | ||
| 2558 | descent = pcm->descent; | ||
| 2559 | } | ||
| 2560 | else | ||
| 2561 | { | ||
| 2562 | width = FONT_WIDTH (font); | ||
| 2563 | ascent = FONT_BASE (font); | ||
| 2564 | descent = FONT_DESCENT (font); | ||
| 2565 | } | ||
| 2566 | |||
| 2567 | rightmost = width; | ||
| 2568 | lowest = - descent + boff; | ||
| 2569 | highest = ascent + boff; | ||
| 2570 | leftmost = 0; | ||
| 2571 | |||
| 2572 | if (font_info | ||
| 2573 | && font_info->default_ascent | ||
| 2574 | && CHAR_TABLE_P (Vuse_default_ascent) | ||
| 2575 | && !NILP (Faref (Vuse_default_ascent, | ||
| 2576 | make_number (it->char_to_display)))) | ||
| 2577 | highest = font_info->default_ascent + boff; | ||
| 2578 | |||
| 2579 | /* Draw the first glyph at the normal position. It may be | ||
| 2580 | shifted to right later if some other glyphs are drawn at | ||
| 2581 | the left. */ | ||
| 2582 | cmp->offsets[0] = 0; | ||
| 2583 | cmp->offsets[1] = boff; | ||
| 2584 | |||
| 2585 | /* Set cmp->offsets for the remaining glyphs. */ | ||
| 2586 | for (i = 1; i < cmp->glyph_len; i++) | ||
| 2587 | { | ||
| 2588 | int left, right, btm, top; | ||
| 2589 | int ch = COMPOSITION_GLYPH (cmp, i); | ||
| 2590 | int face_id = FACE_FOR_CHAR (it->f, face, ch); | ||
| 2591 | |||
| 2592 | face = FACE_FROM_ID (it->f, face_id); | ||
| 2593 | x_get_char_face_and_encoding (it->f, ch, face->id, &char2b, | ||
| 2594 | it->multibyte_p); | ||
| 2595 | font = face->font; | ||
| 2596 | if (font == NULL) | ||
| 2597 | { | ||
| 2598 | font = FRAME_FONT (it->f); | ||
| 2599 | boff = it->f->output_data.mac->baseline_offset; | ||
| 2600 | font_info = NULL; | ||
| 2601 | } | ||
| 2602 | else | ||
| 2603 | { | ||
| 2604 | font_info | ||
| 2605 | = FONT_INFO_FROM_ID (it->f, face->font_info_id); | ||
| 2606 | boff = font_info->baseline_offset; | ||
| 2607 | if (font_info->vertical_centering) | ||
| 2608 | boff = VCENTER_BASELINE_OFFSET (font, it->f) - boff; | ||
| 2609 | } | ||
| 2610 | |||
| 2611 | pcm = x_per_char_metric (font, &char2b); | ||
| 2612 | if (pcm) | ||
| 2613 | { | ||
| 2614 | width = pcm->width; | ||
| 2615 | ascent = pcm->ascent; | ||
| 2616 | descent = pcm->descent; | ||
| 2617 | } | ||
| 2618 | else | ||
| 2619 | { | ||
| 2620 | width = FONT_WIDTH (font); | ||
| 2621 | ascent = 1; | ||
| 2622 | descent = 0; | ||
| 2623 | } | ||
| 2624 | |||
| 2625 | if (cmp->method != COMPOSITION_WITH_RULE_ALTCHARS) | ||
| 2626 | { | ||
| 2627 | /* Relative composition with or without | ||
| 2628 | alternate chars. */ | ||
| 2629 | left = (leftmost + rightmost - width) / 2; | ||
| 2630 | btm = - descent + boff; | ||
| 2631 | if (font_info && font_info->relative_compose | ||
| 2632 | && (! CHAR_TABLE_P (Vignore_relative_composition) | ||
| 2633 | || NILP (Faref (Vignore_relative_composition, | ||
| 2634 | make_number (ch))))) | ||
| 2635 | { | ||
| 2636 | |||
| 2637 | if (- descent >= font_info->relative_compose) | ||
| 2638 | /* One extra pixel between two glyphs. */ | ||
| 2639 | btm = highest + 1; | ||
| 2640 | else if (ascent <= 0) | ||
| 2641 | /* One extra pixel between two glyphs. */ | ||
| 2642 | btm = lowest - 1 - ascent - descent; | ||
| 2643 | } | ||
| 2644 | } | ||
| 2645 | else | ||
| 2646 | { | ||
| 2647 | /* A composition rule is specified by an integer | ||
| 2648 | value that encodes global and new reference | ||
| 2649 | points (GREF and NREF). GREF and NREF are | ||
| 2650 | specified by numbers as below: | ||
| 2651 | |||
| 2652 | 0---1---2 -- ascent | ||
| 2653 | | | | ||
| 2654 | | | | ||
| 2655 | | | | ||
| 2656 | 9--10--11 -- center | ||
| 2657 | | | | ||
| 2658 | ---3---4---5--- baseline | ||
| 2659 | | | | ||
| 2660 | 6---7---8 -- descent | ||
| 2661 | */ | ||
| 2662 | int rule = COMPOSITION_RULE (cmp, i); | ||
| 2663 | int gref, nref, grefx, grefy, nrefx, nrefy; | ||
| 2664 | |||
| 2665 | COMPOSITION_DECODE_RULE (rule, gref, nref); | ||
| 2666 | grefx = gref % 3, nrefx = nref % 3; | ||
| 2667 | grefy = gref / 3, nrefy = nref / 3; | ||
| 2668 | |||
| 2669 | left = (leftmost | ||
| 2670 | + grefx * (rightmost - leftmost) / 2 | ||
| 2671 | - nrefx * width / 2); | ||
| 2672 | btm = ((grefy == 0 ? highest | ||
| 2673 | : grefy == 1 ? 0 | ||
| 2674 | : grefy == 2 ? lowest | ||
| 2675 | : (highest + lowest) / 2) | ||
| 2676 | - (nrefy == 0 ? ascent + descent | ||
| 2677 | : nrefy == 1 ? descent - boff | ||
| 2678 | : nrefy == 2 ? 0 | ||
| 2679 | : (ascent + descent) / 2)); | ||
| 2680 | } | ||
| 2681 | |||
| 2682 | cmp->offsets[i * 2] = left; | ||
| 2683 | cmp->offsets[i * 2 + 1] = btm + descent; | ||
| 2684 | |||
| 2685 | /* Update the bounding box of the overall glyphs. */ | ||
| 2686 | right = left + width; | ||
| 2687 | top = btm + descent + ascent; | ||
| 2688 | if (left < leftmost) | ||
| 2689 | leftmost = left; | ||
| 2690 | if (right > rightmost) | ||
| 2691 | rightmost = right; | ||
| 2692 | if (top > highest) | ||
| 2693 | highest = top; | ||
| 2694 | if (btm < lowest) | ||
| 2695 | lowest = btm; | ||
| 2696 | } | ||
| 2697 | |||
| 2698 | /* If there are glyphs whose x-offsets are negative, | ||
| 2699 | shift all glyphs to the right and make all x-offsets | ||
| 2700 | non-negative. */ | ||
| 2701 | if (leftmost < 0) | ||
| 2702 | { | ||
| 2703 | for (i = 0; i < cmp->glyph_len; i++) | ||
| 2704 | cmp->offsets[i * 2] -= leftmost; | ||
| 2705 | rightmost -= leftmost; | ||
| 2706 | } | ||
| 2707 | |||
| 2708 | cmp->pixel_width = rightmost; | ||
| 2709 | cmp->ascent = highest; | ||
| 2710 | cmp->descent = - lowest; | ||
| 2711 | if (cmp->ascent < font_ascent) | ||
| 2712 | cmp->ascent = font_ascent; | ||
| 2713 | if (cmp->descent < font_descent) | ||
| 2714 | cmp->descent = font_descent; | ||
| 2715 | } | ||
| 2716 | |||
| 2717 | it->pixel_width = cmp->pixel_width; | ||
| 2718 | it->ascent = it->phys_ascent = cmp->ascent; | ||
| 2719 | it->descent = it->phys_descent = cmp->descent; | ||
| 2720 | |||
| 2721 | if (face->box != FACE_NO_BOX) | ||
| 2722 | { | ||
| 2723 | int thick = face->box_line_width; | ||
| 2724 | |||
| 2725 | if (thick > 0) | ||
| 2726 | { | ||
| 2727 | it->ascent += thick; | ||
| 2728 | it->descent += thick; | ||
| 2729 | } | ||
| 2730 | else | ||
| 2731 | thick = - thick; | ||
| 2732 | |||
| 2733 | if (it->start_of_box_run_p) | ||
| 2734 | it->pixel_width += thick; | ||
| 2735 | if (it->end_of_box_run_p) | ||
| 2736 | it->pixel_width += thick; | ||
| 2737 | } | ||
| 2738 | |||
| 2739 | /* If face has an overline, add the height of the overline | ||
| 2740 | (1 pixel) and a 1 pixel margin to the character height. */ | ||
| 2741 | if (face->overline_p) | ||
| 2742 | it->ascent += 2; | ||
| 2743 | |||
| 2744 | take_vertical_position_into_account (it); | ||
| 2745 | |||
| 2746 | if (it->glyph_row) | ||
| 2747 | x_append_composite_glyph (it); | ||
| 2748 | } | ||
| 2749 | else if (it->what == IT_IMAGE) | ||
| 2750 | x_produce_image_glyph (it); | ||
| 2751 | else if (it->what == IT_STRETCH) | ||
| 2752 | x_produce_stretch_glyph (it); | ||
| 2753 | |||
| 2754 | /* Accumulate dimensions. Note: can't assume that it->descent > 0 | ||
| 2755 | because this isn't true for images with `:ascent 100'. */ | ||
| 2756 | xassert (it->ascent >= 0 && it->descent >= 0); | ||
| 2757 | if (it->area == TEXT_AREA) | ||
| 2758 | it->current_x += it->pixel_width; | ||
| 2759 | |||
| 2760 | it->descent += it->extra_line_spacing; | ||
| 2761 | |||
| 2762 | it->max_ascent = max (it->max_ascent, it->ascent); | ||
| 2763 | it->max_descent = max (it->max_descent, it->descent); | ||
| 2764 | it->max_phys_ascent = max (it->max_phys_ascent, it->phys_ascent); | ||
| 2765 | it->max_phys_descent = max (it->max_phys_descent, it->phys_descent); | ||
| 2766 | } | 1685 | } |
| 2767 | 1686 | ||
| 2768 | 1687 | ||
| @@ -2798,172 +1717,7 @@ x_estimate_mode_line_height (f, face_id) | |||
| 2798 | Glyph display | 1717 | Glyph display |
| 2799 | ***********************************************************************/ | 1718 | ***********************************************************************/ |
| 2800 | 1719 | ||
| 2801 | /* A sequence of glyphs to be drawn in the same face. | ||
| 2802 | |||
| 2803 | This data structure is not really completely X specific, so it | ||
| 2804 | could possibly, at least partially, be useful for other systems. It | ||
| 2805 | is currently not part of the external redisplay interface because | ||
| 2806 | it's not clear what other systems will need. */ | ||
| 2807 | 1720 | ||
| 2808 | struct glyph_string | ||
| 2809 | { | ||
| 2810 | /* X-origin of the string. */ | ||
| 2811 | int x; | ||
| 2812 | |||
| 2813 | /* Y-origin and y-position of the base line of this string. */ | ||
| 2814 | int y, ybase; | ||
| 2815 | |||
| 2816 | /* The width of the string, not including a face extension. */ | ||
| 2817 | int width; | ||
| 2818 | |||
| 2819 | /* The width of the string, including a face extension. */ | ||
| 2820 | int background_width; | ||
| 2821 | |||
| 2822 | /* The height of this string. This is the height of the line this | ||
| 2823 | string is drawn in, and can be different from the height of the | ||
| 2824 | font the string is drawn in. */ | ||
| 2825 | int height; | ||
| 2826 | |||
| 2827 | /* Number of pixels this string overwrites in front of its x-origin. | ||
| 2828 | This number is zero if the string has an lbearing >= 0; it is | ||
| 2829 | -lbearing, if the string has an lbearing < 0. */ | ||
| 2830 | int left_overhang; | ||
| 2831 | |||
| 2832 | /* Number of pixels this string overwrites past its right-most | ||
| 2833 | nominal x-position, i.e. x + width. Zero if the string's | ||
| 2834 | rbearing is <= its nominal width, rbearing - width otherwise. */ | ||
| 2835 | int right_overhang; | ||
| 2836 | |||
| 2837 | /* The frame on which the glyph string is drawn. */ | ||
| 2838 | struct frame *f; | ||
| 2839 | |||
| 2840 | /* The window on which the glyph string is drawn. */ | ||
| 2841 | struct window *w; | ||
| 2842 | |||
| 2843 | /* X display and window for convenience. */ | ||
| 2844 | Display *display; | ||
| 2845 | Window window; | ||
| 2846 | |||
| 2847 | /* The glyph row for which this string was built. It determines the | ||
| 2848 | y-origin and height of the string. */ | ||
| 2849 | struct glyph_row *row; | ||
| 2850 | |||
| 2851 | /* The area within row. */ | ||
| 2852 | enum glyph_row_area area; | ||
| 2853 | |||
| 2854 | /* Characters to be drawn, and number of characters. */ | ||
| 2855 | XChar2b *char2b; | ||
| 2856 | int nchars; | ||
| 2857 | |||
| 2858 | /* A face-override for drawing cursors, mouse face and similar. */ | ||
| 2859 | enum draw_glyphs_face hl; | ||
| 2860 | |||
| 2861 | /* Face in which this string is to be drawn. */ | ||
| 2862 | struct face *face; | ||
| 2863 | |||
| 2864 | /* Font in which this string is to be drawn. */ | ||
| 2865 | XFontStruct *font; | ||
| 2866 | |||
| 2867 | /* Font info for this string. */ | ||
| 2868 | struct font_info *font_info; | ||
| 2869 | |||
| 2870 | /* Non-null means this string describes (part of) a composition. | ||
| 2871 | All characters from char2b are drawn composed. */ | ||
| 2872 | struct composition *cmp; | ||
| 2873 | |||
| 2874 | /* Index of this glyph string's first character in the glyph | ||
| 2875 | definition of CMP. If this is zero, this glyph string describes | ||
| 2876 | the first character of a composition. */ | ||
| 2877 | int gidx; | ||
| 2878 | |||
| 2879 | /* 1 means this glyph strings face has to be drawn to the right end | ||
| 2880 | of the window's drawing area. */ | ||
| 2881 | unsigned extends_to_end_of_line_p : 1; | ||
| 2882 | |||
| 2883 | /* 1 means the background of this string has been drawn. */ | ||
| 2884 | unsigned background_filled_p : 1; | ||
| 2885 | |||
| 2886 | /* 1 means glyph string must be drawn with 16-bit functions. */ | ||
| 2887 | unsigned two_byte_p : 1; | ||
| 2888 | |||
| 2889 | /* 1 means that the original font determined for drawing this glyph | ||
| 2890 | string could not be loaded. The member `font' has been set to | ||
| 2891 | the frame's default font in this case. */ | ||
| 2892 | unsigned font_not_found_p : 1; | ||
| 2893 | |||
| 2894 | /* 1 means that the face in which this glyph string is drawn has a | ||
| 2895 | stipple pattern. */ | ||
| 2896 | unsigned stippled_p : 1; | ||
| 2897 | |||
| 2898 | /* 1 means only the foreground of this glyph string must be drawn, | ||
| 2899 | and we should use the physical height of the line this glyph | ||
| 2900 | string appears in as clip rect. */ | ||
| 2901 | unsigned for_overlaps_p : 1; | ||
| 2902 | |||
| 2903 | /* The GC to use for drawing this glyph string. */ | ||
| 2904 | GC gc; | ||
| 2905 | |||
| 2906 | /* A pointer to the first glyph in the string. This glyph | ||
| 2907 | corresponds to char2b[0]. Needed to draw rectangles if | ||
| 2908 | font_not_found_p is 1. */ | ||
| 2909 | struct glyph *first_glyph; | ||
| 2910 | |||
| 2911 | /* Image, if any. */ | ||
| 2912 | struct image *img; | ||
| 2913 | |||
| 2914 | struct glyph_string *next, *prev; | ||
| 2915 | }; | ||
| 2916 | |||
| 2917 | |||
| 2918 | #if 0 | ||
| 2919 | |||
| 2920 | static void | ||
| 2921 | x_dump_glyph_string (s) | ||
| 2922 | struct glyph_string *s; | ||
| 2923 | { | ||
| 2924 | fprintf (stderr, "glyph string\n"); | ||
| 2925 | fprintf (stderr, " x, y, w, h = %d, %d, %d, %d\n", | ||
| 2926 | s->x, s->y, s->width, s->height); | ||
| 2927 | fprintf (stderr, " ybase = %d\n", s->ybase); | ||
| 2928 | fprintf (stderr, " hl = %d\n", s->hl); | ||
| 2929 | fprintf (stderr, " left overhang = %d, right = %d\n", | ||
| 2930 | s->left_overhang, s->right_overhang); | ||
| 2931 | fprintf (stderr, " nchars = %d\n", s->nchars); | ||
| 2932 | fprintf (stderr, " extends to end of line = %d\n", | ||
| 2933 | s->extends_to_end_of_line_p); | ||
| 2934 | fprintf (stderr, " font height = %d\n", FONT_HEIGHT (s->font)); | ||
| 2935 | fprintf (stderr, " bg width = %d\n", s->background_width); | ||
| 2936 | } | ||
| 2937 | |||
| 2938 | #endif /* GLYPH_DEBUG */ | ||
| 2939 | |||
| 2940 | |||
| 2941 | |||
| 2942 | static void x_append_glyph_string_lists P_ ((struct glyph_string **, | ||
| 2943 | struct glyph_string **, | ||
| 2944 | struct glyph_string *, | ||
| 2945 | struct glyph_string *)); | ||
| 2946 | static void x_prepend_glyph_string_lists P_ ((struct glyph_string **, | ||
| 2947 | struct glyph_string **, | ||
| 2948 | struct glyph_string *, | ||
| 2949 | struct glyph_string *)); | ||
| 2950 | static void x_append_glyph_string P_ ((struct glyph_string **, | ||
| 2951 | struct glyph_string **, | ||
| 2952 | struct glyph_string *)); | ||
| 2953 | static int x_left_overwritten P_ ((struct glyph_string *)); | ||
| 2954 | static int x_left_overwriting P_ ((struct glyph_string *)); | ||
| 2955 | static int x_right_overwritten P_ ((struct glyph_string *)); | ||
| 2956 | static int x_right_overwriting P_ ((struct glyph_string *)); | ||
| 2957 | static int x_fill_glyph_string P_ ((struct glyph_string *, int, int, int, | ||
| 2958 | int)); | ||
| 2959 | static void x_init_glyph_string P_ ((struct glyph_string *, | ||
| 2960 | XChar2b *, struct window *, | ||
| 2961 | struct glyph_row *, | ||
| 2962 | enum glyph_row_area, int, | ||
| 2963 | enum draw_glyphs_face)); | ||
| 2964 | static int x_draw_glyphs P_ ((struct window *, int , struct glyph_row *, | ||
| 2965 | enum glyph_row_area, int, int, | ||
| 2966 | enum draw_glyphs_face, int)); | ||
| 2967 | static void x_set_glyph_string_clipping P_ ((struct glyph_string *)); | 1721 | static void x_set_glyph_string_clipping P_ ((struct glyph_string *)); |
| 2968 | static void x_set_glyph_string_gc P_ ((struct glyph_string *)); | 1722 | static void x_set_glyph_string_gc P_ ((struct glyph_string *)); |
| 2969 | static void x_draw_glyph_string_background P_ ((struct glyph_string *, | 1723 | static void x_draw_glyph_string_background P_ ((struct glyph_string *, |
| @@ -2972,13 +1726,9 @@ static void x_draw_glyph_string_foreground P_ ((struct glyph_string *)); | |||
| 2972 | static void x_draw_composite_glyph_string_foreground P_ ((struct glyph_string *)); | 1726 | static void x_draw_composite_glyph_string_foreground P_ ((struct glyph_string *)); |
| 2973 | static void x_draw_glyph_string_box P_ ((struct glyph_string *)); | 1727 | static void x_draw_glyph_string_box P_ ((struct glyph_string *)); |
| 2974 | static void x_draw_glyph_string P_ ((struct glyph_string *)); | 1728 | static void x_draw_glyph_string P_ ((struct glyph_string *)); |
| 2975 | static void x_compute_glyph_string_overhangs P_ ((struct glyph_string *)); | ||
| 2976 | static void x_set_cursor_gc P_ ((struct glyph_string *)); | 1729 | static void x_set_cursor_gc P_ ((struct glyph_string *)); |
| 2977 | static void x_set_mode_line_face_gc P_ ((struct glyph_string *)); | 1730 | static void x_set_mode_line_face_gc P_ ((struct glyph_string *)); |
| 2978 | static void x_set_mouse_face_gc P_ ((struct glyph_string *)); | 1731 | static void x_set_mouse_face_gc P_ ((struct glyph_string *)); |
| 2979 | static void x_get_glyph_overhangs P_ ((struct glyph *, struct frame *, | ||
| 2980 | int *, int *)); | ||
| 2981 | static void x_compute_overhangs_and_x P_ ((struct glyph_string *, int, int)); | ||
| 2982 | /*static int x_alloc_lighter_color P_ ((struct frame *, Display *, Colormap, | 1732 | /*static int x_alloc_lighter_color P_ ((struct frame *, Display *, Colormap, |
| 2983 | unsigned long *, double, int));*/ | 1733 | unsigned long *, double, int));*/ |
| 2984 | static void x_setup_relief_color P_ ((struct frame *, struct relief *, | 1734 | static void x_setup_relief_color P_ ((struct frame *, struct relief *, |
| @@ -2988,7 +1738,6 @@ static void x_draw_image_glyph_string P_ ((struct glyph_string *)); | |||
| 2988 | static void x_draw_image_relief P_ ((struct glyph_string *)); | 1738 | static void x_draw_image_relief P_ ((struct glyph_string *)); |
| 2989 | static void x_draw_image_foreground P_ ((struct glyph_string *)); | 1739 | static void x_draw_image_foreground P_ ((struct glyph_string *)); |
| 2990 | static void x_draw_image_foreground_1 P_ ((struct glyph_string *, Pixmap)); | 1740 | static void x_draw_image_foreground_1 P_ ((struct glyph_string *, Pixmap)); |
| 2991 | static void x_fill_image_glyph_string P_ ((struct glyph_string *)); | ||
| 2992 | static void x_clear_glyph_string_rect P_ ((struct glyph_string *, int, | 1741 | static void x_clear_glyph_string_rect P_ ((struct glyph_string *, int, |
| 2993 | int, int, int)); | 1742 | int, int, int)); |
| 2994 | static void x_draw_relief_rect P_ ((struct frame *, int, int, int, int, | 1743 | static void x_draw_relief_rect P_ ((struct frame *, int, int, int, int, |
| @@ -2997,69 +1746,12 @@ static void x_draw_box_rect P_ ((struct glyph_string *, int, int, int, int, | |||
| 2997 | int, int, int, Rect *)); | 1746 | int, int, int, Rect *)); |
| 2998 | static void x_fix_overlapping_area P_ ((struct window *, struct glyph_row *, | 1747 | static void x_fix_overlapping_area P_ ((struct window *, struct glyph_row *, |
| 2999 | enum glyph_row_area)); | 1748 | enum glyph_row_area)); |
| 3000 | static int x_fill_stretch_glyph_string P_ ((struct glyph_string *, | ||
| 3001 | struct glyph_row *, | ||
| 3002 | enum glyph_row_area, int, int)); | ||
| 3003 | 1749 | ||
| 3004 | #if GLYPH_DEBUG | 1750 | #if GLYPH_DEBUG |
| 3005 | static void x_check_font P_ ((struct frame *, XFontStruct *)); | 1751 | static void x_check_font P_ ((struct frame *, XFontStruct *)); |
| 3006 | #endif | 1752 | #endif |
| 3007 | 1753 | ||
| 3008 | 1754 | ||
| 3009 | /* Append the list of glyph strings with head H and tail T to the list | ||
| 3010 | with head *HEAD and tail *TAIL. Set *HEAD and *TAIL to the result. */ | ||
| 3011 | |||
| 3012 | static INLINE void | ||
| 3013 | x_append_glyph_string_lists (head, tail, h, t) | ||
| 3014 | struct glyph_string **head, **tail; | ||
| 3015 | struct glyph_string *h, *t; | ||
| 3016 | { | ||
| 3017 | if (h) | ||
| 3018 | { | ||
| 3019 | if (*head) | ||
| 3020 | (*tail)->next = h; | ||
| 3021 | else | ||
| 3022 | *head = h; | ||
| 3023 | h->prev = *tail; | ||
| 3024 | *tail = t; | ||
| 3025 | } | ||
| 3026 | } | ||
| 3027 | |||
| 3028 | |||
| 3029 | /* Prepend the list of glyph strings with head H and tail T to the | ||
| 3030 | list with head *HEAD and tail *TAIL. Set *HEAD and *TAIL to the | ||
| 3031 | result. */ | ||
| 3032 | |||
| 3033 | static INLINE void | ||
| 3034 | x_prepend_glyph_string_lists (head, tail, h, t) | ||
| 3035 | struct glyph_string **head, **tail; | ||
| 3036 | struct glyph_string *h, *t; | ||
| 3037 | { | ||
| 3038 | if (h) | ||
| 3039 | { | ||
| 3040 | if (*head) | ||
| 3041 | (*head)->prev = t; | ||
| 3042 | else | ||
| 3043 | *tail = t; | ||
| 3044 | t->next = *head; | ||
| 3045 | *head = h; | ||
| 3046 | } | ||
| 3047 | } | ||
| 3048 | |||
| 3049 | |||
| 3050 | /* Append glyph string S to the list with head *HEAD and tail *TAIL. | ||
| 3051 | Set *HEAD and *TAIL to the resulting list. */ | ||
| 3052 | |||
| 3053 | static INLINE void | ||
| 3054 | x_append_glyph_string (head, tail, s) | ||
| 3055 | struct glyph_string **head, **tail; | ||
| 3056 | struct glyph_string *s; | ||
| 3057 | { | ||
| 3058 | s->next = s->prev = NULL; | ||
| 3059 | x_append_glyph_string_lists (head, tail, s, s); | ||
| 3060 | } | ||
| 3061 | |||
| 3062 | |||
| 3063 | /* Set S->gc to a suitable GC for drawing glyph string S in cursor | 1755 | /* Set S->gc to a suitable GC for drawing glyph string S in cursor |
| 3064 | face. */ | 1756 | face. */ |
| 3065 | 1757 | ||
| @@ -3310,13 +2002,17 @@ x_set_glyph_string_clipping (s) | |||
| 3310 | } | 2002 | } |
| 3311 | 2003 | ||
| 3312 | 2004 | ||
| 3313 | /* Compute left and right overhang of glyph string S. If S is a glyph | 2005 | /* RIF: |
| 2006 | Compute left and right overhang of glyph string S. If S is a glyph | ||
| 3314 | string for a composition, assume overhangs don't exist. */ | 2007 | string for a composition, assume overhangs don't exist. */ |
| 3315 | 2008 | ||
| 3316 | static INLINE void | 2009 | static void |
| 3317 | x_compute_glyph_string_overhangs (s) | 2010 | mac_compute_glyph_string_overhangs (s) |
| 3318 | struct glyph_string *s; | 2011 | struct glyph_string *s; |
| 3319 | { | 2012 | { |
| 2013 | #if 0 | ||
| 2014 | /* MAC_TODO: XTextExtents16 does nothing yet... */ | ||
| 2015 | |||
| 3320 | if (s->cmp == NULL | 2016 | if (s->cmp == NULL |
| 3321 | && s->first_glyph->type == CHAR_GLYPH) | 2017 | && s->first_glyph->type == CHAR_GLYPH) |
| 3322 | { | 2018 | { |
| @@ -3327,184 +2023,7 @@ x_compute_glyph_string_overhangs (s) | |||
| 3327 | s->right_overhang = cs.rbearing > cs.width ? cs.rbearing - cs.width : 0; | 2023 | s->right_overhang = cs.rbearing > cs.width ? cs.rbearing - cs.width : 0; |
| 3328 | s->left_overhang = cs.lbearing < 0 ? -cs.lbearing : 0; | 2024 | s->left_overhang = cs.lbearing < 0 ? -cs.lbearing : 0; |
| 3329 | } | 2025 | } |
| 3330 | } | 2026 | #endif |
| 3331 | |||
| 3332 | |||
| 3333 | /* Compute overhangs and x-positions for glyph string S and its | ||
| 3334 | predecessors, or successors. X is the starting x-position for S. | ||
| 3335 | BACKWARD_P non-zero means process predecessors. */ | ||
| 3336 | |||
| 3337 | static void | ||
| 3338 | x_compute_overhangs_and_x (s, x, backward_p) | ||
| 3339 | struct glyph_string *s; | ||
| 3340 | int x; | ||
| 3341 | int backward_p; | ||
| 3342 | { | ||
| 3343 | if (backward_p) | ||
| 3344 | { | ||
| 3345 | while (s) | ||
| 3346 | { | ||
| 3347 | x_compute_glyph_string_overhangs (s); | ||
| 3348 | x -= s->width; | ||
| 3349 | s->x = x; | ||
| 3350 | s = s->prev; | ||
| 3351 | } | ||
| 3352 | } | ||
| 3353 | else | ||
| 3354 | { | ||
| 3355 | while (s) | ||
| 3356 | { | ||
| 3357 | x_compute_glyph_string_overhangs (s); | ||
| 3358 | s->x = x; | ||
| 3359 | x += s->width; | ||
| 3360 | s = s->next; | ||
| 3361 | } | ||
| 3362 | } | ||
| 3363 | } | ||
| 3364 | |||
| 3365 | |||
| 3366 | /* Set *LEFT and *RIGHT to the left and right overhang of GLYPH on | ||
| 3367 | frame F. Overhangs of glyphs other than type CHAR_GLYPH are | ||
| 3368 | assumed to be zero. */ | ||
| 3369 | |||
| 3370 | void | ||
| 3371 | x_get_glyph_overhangs (glyph, f, left, right) | ||
| 3372 | struct glyph *glyph; | ||
| 3373 | struct frame *f; | ||
| 3374 | int *left, *right; | ||
| 3375 | { | ||
| 3376 | *left = *right = 0; | ||
| 3377 | |||
| 3378 | if (glyph->type == CHAR_GLYPH) | ||
| 3379 | { | ||
| 3380 | XFontStruct *font; | ||
| 3381 | struct face *face; | ||
| 3382 | struct font_info *font_info; | ||
| 3383 | XChar2b char2b; | ||
| 3384 | XCharStruct *pcm; | ||
| 3385 | |||
| 3386 | face = x_get_glyph_face_and_encoding (f, glyph, &char2b, NULL); | ||
| 3387 | font = face->font; | ||
| 3388 | font_info = FONT_INFO_FROM_ID (f, face->font_info_id); | ||
| 3389 | if (font | ||
| 3390 | && (pcm = x_per_char_metric (font, &char2b))) | ||
| 3391 | { | ||
| 3392 | if (pcm->rbearing > pcm->width) | ||
| 3393 | *right = pcm->rbearing - pcm->width; | ||
| 3394 | if (pcm->lbearing < 0) | ||
| 3395 | *left = -pcm->lbearing; | ||
| 3396 | } | ||
| 3397 | } | ||
| 3398 | } | ||
| 3399 | |||
| 3400 | |||
| 3401 | /* Return the index of the first glyph preceding glyph string S that | ||
| 3402 | is overwritten by S because of S's left overhang. Value is -1 | ||
| 3403 | if no glyphs are overwritten. */ | ||
| 3404 | |||
| 3405 | static int | ||
| 3406 | x_left_overwritten (s) | ||
| 3407 | struct glyph_string *s; | ||
| 3408 | { | ||
| 3409 | int k; | ||
| 3410 | |||
| 3411 | if (s->left_overhang) | ||
| 3412 | { | ||
| 3413 | int x = 0, i; | ||
| 3414 | struct glyph *glyphs = s->row->glyphs[s->area]; | ||
| 3415 | int first = s->first_glyph - glyphs; | ||
| 3416 | |||
| 3417 | for (i = first - 1; i >= 0 && x > -s->left_overhang; --i) | ||
| 3418 | x -= glyphs[i].pixel_width; | ||
| 3419 | |||
| 3420 | k = i + 1; | ||
| 3421 | } | ||
| 3422 | else | ||
| 3423 | k = -1; | ||
| 3424 | |||
| 3425 | return k; | ||
| 3426 | } | ||
| 3427 | |||
| 3428 | |||
| 3429 | /* Return the index of the first glyph preceding glyph string S that | ||
| 3430 | is overwriting S because of its right overhang. Value is -1 if no | ||
| 3431 | glyph in front of S overwrites S. */ | ||
| 3432 | |||
| 3433 | static int | ||
| 3434 | x_left_overwriting (s) | ||
| 3435 | struct glyph_string *s; | ||
| 3436 | { | ||
| 3437 | int i, k, x; | ||
| 3438 | struct glyph *glyphs = s->row->glyphs[s->area]; | ||
| 3439 | int first = s->first_glyph - glyphs; | ||
| 3440 | |||
| 3441 | k = -1; | ||
| 3442 | x = 0; | ||
| 3443 | for (i = first - 1; i >= 0; --i) | ||
| 3444 | { | ||
| 3445 | int left, right; | ||
| 3446 | x_get_glyph_overhangs (glyphs + i, s->f, &left, &right); | ||
| 3447 | if (x + right > 0) | ||
| 3448 | k = i; | ||
| 3449 | x -= glyphs[i].pixel_width; | ||
| 3450 | } | ||
| 3451 | |||
| 3452 | return k; | ||
| 3453 | } | ||
| 3454 | |||
| 3455 | |||
| 3456 | /* Return the index of the last glyph following glyph string S that is | ||
| 3457 | not overwritten by S because of S's right overhang. Value is -1 if | ||
| 3458 | no such glyph is found. */ | ||
| 3459 | |||
| 3460 | static int | ||
| 3461 | x_right_overwritten (s) | ||
| 3462 | struct glyph_string *s; | ||
| 3463 | { | ||
| 3464 | int k = -1; | ||
| 3465 | |||
| 3466 | if (s->right_overhang) | ||
| 3467 | { | ||
| 3468 | int x = 0, i; | ||
| 3469 | struct glyph *glyphs = s->row->glyphs[s->area]; | ||
| 3470 | int first = (s->first_glyph - glyphs) + (s->cmp ? 1 : s->nchars); | ||
| 3471 | int end = s->row->used[s->area]; | ||
| 3472 | |||
| 3473 | for (i = first; i < end && s->right_overhang > x; ++i) | ||
| 3474 | x += glyphs[i].pixel_width; | ||
| 3475 | |||
| 3476 | k = i; | ||
| 3477 | } | ||
| 3478 | |||
| 3479 | return k; | ||
| 3480 | } | ||
| 3481 | |||
| 3482 | |||
| 3483 | /* Return the index of the last glyph following glyph string S that | ||
| 3484 | overwrites S because of its left overhang. Value is negative | ||
| 3485 | if no such glyph is found. */ | ||
| 3486 | |||
| 3487 | static int | ||
| 3488 | x_right_overwriting (s) | ||
| 3489 | struct glyph_string *s; | ||
| 3490 | { | ||
| 3491 | int i, k, x; | ||
| 3492 | int end = s->row->used[s->area]; | ||
| 3493 | struct glyph *glyphs = s->row->glyphs[s->area]; | ||
| 3494 | int first = (s->first_glyph - glyphs) + (s->cmp ? 1 : s->nchars); | ||
| 3495 | |||
| 3496 | k = -1; | ||
| 3497 | x = 0; | ||
| 3498 | for (i = first; i < end; ++i) | ||
| 3499 | { | ||
| 3500 | int left, right; | ||
| 3501 | x_get_glyph_overhangs (glyphs + i, s->f, &left, &right); | ||
| 3502 | if (x - left < 0) | ||
| 3503 | k = i; | ||
| 3504 | x += glyphs[i].pixel_width; | ||
| 3505 | } | ||
| 3506 | |||
| 3507 | return k; | ||
| 3508 | } | 2027 | } |
| 3509 | 2028 | ||
| 3510 | 2029 | ||
| @@ -4664,661 +3183,6 @@ x_draw_glyph_string (s) | |||
| 4664 | } | 3183 | } |
| 4665 | 3184 | ||
| 4666 | 3185 | ||
| 4667 | static int x_fill_composite_glyph_string P_ ((struct glyph_string *, | ||
| 4668 | struct face **, int)); | ||
| 4669 | |||
| 4670 | |||
| 4671 | /* Fill glyph string S with composition components specified by S->cmp. | ||
| 4672 | |||
| 4673 | FACES is an array of faces for all components of this composition. | ||
| 4674 | S->gidx is the index of the first component for S. | ||
| 4675 | OVERLAPS_P non-zero means S should draw the foreground only, and | ||
| 4676 | use its physical height for clipping. | ||
| 4677 | |||
| 4678 | Value is the index of a component not in S. */ | ||
| 4679 | |||
| 4680 | static int | ||
| 4681 | x_fill_composite_glyph_string (s, faces, overlaps_p) | ||
| 4682 | struct glyph_string *s; | ||
| 4683 | struct face **faces; | ||
| 4684 | int overlaps_p; | ||
| 4685 | { | ||
| 4686 | int i; | ||
| 4687 | |||
| 4688 | xassert (s); | ||
| 4689 | |||
| 4690 | s->for_overlaps_p = overlaps_p; | ||
| 4691 | |||
| 4692 | s->face = faces[s->gidx]; | ||
| 4693 | s->font = s->face->font; | ||
| 4694 | s->font_info = FONT_INFO_FROM_ID (s->f, s->face->font_info_id); | ||
| 4695 | |||
| 4696 | /* For all glyphs of this composition, starting at the offset | ||
| 4697 | S->gidx, until we reach the end of the definition or encounter a | ||
| 4698 | glyph that requires the different face, add it to S. */ | ||
| 4699 | ++s->nchars; | ||
| 4700 | for (i = s->gidx + 1; i < s->cmp->glyph_len && faces[i] == s->face; ++i) | ||
| 4701 | ++s->nchars; | ||
| 4702 | |||
| 4703 | /* All glyph strings for the same composition has the same width, | ||
| 4704 | i.e. the width set for the first component of the composition. */ | ||
| 4705 | |||
| 4706 | s->width = s->first_glyph->pixel_width; | ||
| 4707 | |||
| 4708 | /* If the specified font could not be loaded, use the frame's | ||
| 4709 | default font, but record the fact that we couldn't load it in | ||
| 4710 | the glyph string so that we can draw rectangles for the | ||
| 4711 | characters of the glyph string. */ | ||
| 4712 | if (s->font == NULL) | ||
| 4713 | { | ||
| 4714 | s->font_not_found_p = 1; | ||
| 4715 | s->font = FRAME_FONT (s->f); | ||
| 4716 | } | ||
| 4717 | |||
| 4718 | /* Adjust base line for subscript/superscript text. */ | ||
| 4719 | s->ybase += s->first_glyph->voffset; | ||
| 4720 | |||
| 4721 | xassert (s->face && s->face->gc); | ||
| 4722 | |||
| 4723 | /* This glyph string must always be drawn with 16-bit functions. */ | ||
| 4724 | s->two_byte_p = 1; | ||
| 4725 | |||
| 4726 | return s->gidx + s->nchars; | ||
| 4727 | } | ||
| 4728 | |||
| 4729 | |||
| 4730 | /* Fill glyph string S from a sequence of character glyphs. | ||
| 4731 | |||
| 4732 | FACE_ID is the face id of the string. START is the index of the | ||
| 4733 | first glyph to consider, END is the index of the last + 1. | ||
| 4734 | OVERLAPS_P non-zero means S should draw the foreground only, and | ||
| 4735 | use its physical height for clipping. | ||
| 4736 | |||
| 4737 | Value is the index of the first glyph not in S. */ | ||
| 4738 | |||
| 4739 | static int | ||
| 4740 | x_fill_glyph_string (s, face_id, start, end, overlaps_p) | ||
| 4741 | struct glyph_string *s; | ||
| 4742 | int face_id; | ||
| 4743 | int start, end, overlaps_p; | ||
| 4744 | { | ||
| 4745 | struct glyph *glyph, *last; | ||
| 4746 | int voffset; | ||
| 4747 | int glyph_not_available_p; | ||
| 4748 | |||
| 4749 | xassert (s->f == XFRAME (s->w->frame)); | ||
| 4750 | xassert (s->nchars == 0); | ||
| 4751 | xassert (start >= 0 && end > start); | ||
| 4752 | |||
| 4753 | s->for_overlaps_p = overlaps_p; | ||
| 4754 | glyph = s->row->glyphs[s->area] + start; | ||
| 4755 | last = s->row->glyphs[s->area] + end; | ||
| 4756 | voffset = glyph->voffset; | ||
| 4757 | |||
| 4758 | glyph_not_available_p = glyph->glyph_not_available_p; | ||
| 4759 | |||
| 4760 | while (glyph < last | ||
| 4761 | && glyph->type == CHAR_GLYPH | ||
| 4762 | && glyph->voffset == voffset | ||
| 4763 | /* Same face id implies same font, nowadays. */ | ||
| 4764 | && glyph->face_id == face_id | ||
| 4765 | && glyph->glyph_not_available_p == glyph_not_available_p) | ||
| 4766 | { | ||
| 4767 | int two_byte_p; | ||
| 4768 | |||
| 4769 | s->face = x_get_glyph_face_and_encoding (s->f, glyph, | ||
| 4770 | s->char2b + s->nchars, | ||
| 4771 | &two_byte_p); | ||
| 4772 | s->two_byte_p = two_byte_p; | ||
| 4773 | ++s->nchars; | ||
| 4774 | xassert (s->nchars <= end - start); | ||
| 4775 | s->width += glyph->pixel_width; | ||
| 4776 | ++glyph; | ||
| 4777 | } | ||
| 4778 | |||
| 4779 | s->font = s->face->font; | ||
| 4780 | s->font_info = FONT_INFO_FROM_ID (s->f, s->face->font_info_id); | ||
| 4781 | |||
| 4782 | /* If the specified font could not be loaded, use the frame's font, | ||
| 4783 | but record the fact that we couldn't load it in | ||
| 4784 | S->font_not_found_p so that we can draw rectangles for the | ||
| 4785 | characters of the glyph string. */ | ||
| 4786 | if (s->font == NULL || glyph_not_available_p) | ||
| 4787 | { | ||
| 4788 | s->font_not_found_p = 1; | ||
| 4789 | s->font = FRAME_FONT (s->f); | ||
| 4790 | } | ||
| 4791 | |||
| 4792 | /* Adjust base line for subscript/superscript text. */ | ||
| 4793 | s->ybase += voffset; | ||
| 4794 | |||
| 4795 | xassert (s->face && s->face->gc); | ||
| 4796 | return glyph - s->row->glyphs[s->area]; | ||
| 4797 | } | ||
| 4798 | |||
| 4799 | |||
| 4800 | /* Fill glyph string S from image glyph S->first_glyph. */ | ||
| 4801 | |||
| 4802 | static void | ||
| 4803 | x_fill_image_glyph_string (s) | ||
| 4804 | struct glyph_string *s; | ||
| 4805 | { | ||
| 4806 | xassert (s->first_glyph->type == IMAGE_GLYPH); | ||
| 4807 | s->img = IMAGE_FROM_ID (s->f, s->first_glyph->u.img_id); | ||
| 4808 | xassert (s->img); | ||
| 4809 | s->face = FACE_FROM_ID (s->f, s->first_glyph->face_id); | ||
| 4810 | s->font = s->face->font; | ||
| 4811 | s->width = s->first_glyph->pixel_width; | ||
| 4812 | |||
| 4813 | /* Adjust base line for subscript/superscript text. */ | ||
| 4814 | s->ybase += s->first_glyph->voffset; | ||
| 4815 | } | ||
| 4816 | |||
| 4817 | |||
| 4818 | /* Fill glyph string S from a sequence of stretch glyphs. | ||
| 4819 | |||
| 4820 | ROW is the glyph row in which the glyphs are found, AREA is the | ||
| 4821 | area within the row. START is the index of the first glyph to | ||
| 4822 | consider, END is the index of the last + 1. | ||
| 4823 | |||
| 4824 | Value is the index of the first glyph not in S. */ | ||
| 4825 | |||
| 4826 | static int | ||
| 4827 | x_fill_stretch_glyph_string (s, row, area, start, end) | ||
| 4828 | struct glyph_string *s; | ||
| 4829 | struct glyph_row *row; | ||
| 4830 | enum glyph_row_area area; | ||
| 4831 | int start, end; | ||
| 4832 | { | ||
| 4833 | struct glyph *glyph, *last; | ||
| 4834 | int voffset, face_id; | ||
| 4835 | |||
| 4836 | xassert (s->first_glyph->type == STRETCH_GLYPH); | ||
| 4837 | |||
| 4838 | glyph = s->row->glyphs[s->area] + start; | ||
| 4839 | last = s->row->glyphs[s->area] + end; | ||
| 4840 | face_id = glyph->face_id; | ||
| 4841 | s->face = FACE_FROM_ID (s->f, face_id); | ||
| 4842 | s->font = s->face->font; | ||
| 4843 | s->font_info = FONT_INFO_FROM_ID (s->f, s->face->font_info_id); | ||
| 4844 | s->width = glyph->pixel_width; | ||
| 4845 | voffset = glyph->voffset; | ||
| 4846 | |||
| 4847 | for (++glyph; | ||
| 4848 | (glyph < last | ||
| 4849 | && glyph->type == STRETCH_GLYPH | ||
| 4850 | && glyph->voffset == voffset | ||
| 4851 | && glyph->face_id == face_id); | ||
| 4852 | ++glyph) | ||
| 4853 | s->width += glyph->pixel_width; | ||
| 4854 | |||
| 4855 | /* Adjust base line for subscript/superscript text. */ | ||
| 4856 | s->ybase += voffset; | ||
| 4857 | |||
| 4858 | xassert (s->face); | ||
| 4859 | return glyph - s->row->glyphs[s->area]; | ||
| 4860 | } | ||
| 4861 | |||
| 4862 | |||
| 4863 | /* Initialize glyph string S. CHAR2B is a suitably allocated vector | ||
| 4864 | of XChar2b structures for S; it can't be allocated in | ||
| 4865 | x_init_glyph_string because it must be allocated via `alloca'. W | ||
| 4866 | is the window on which S is drawn. ROW and AREA are the glyph row | ||
| 4867 | and area within the row from which S is constructed. START is the | ||
| 4868 | index of the first glyph structure covered by S. HL is a | ||
| 4869 | face-override for drawing S. */ | ||
| 4870 | |||
| 4871 | static void | ||
| 4872 | x_init_glyph_string (s, char2b, w, row, area, start, hl) | ||
| 4873 | struct glyph_string *s; | ||
| 4874 | XChar2b *char2b; | ||
| 4875 | struct window *w; | ||
| 4876 | struct glyph_row *row; | ||
| 4877 | enum glyph_row_area area; | ||
| 4878 | int start; | ||
| 4879 | enum draw_glyphs_face hl; | ||
| 4880 | { | ||
| 4881 | bzero (s, sizeof *s); | ||
| 4882 | s->w = w; | ||
| 4883 | s->f = XFRAME (w->frame); | ||
| 4884 | s->display = FRAME_MAC_DISPLAY (s->f); | ||
| 4885 | s->window = FRAME_MAC_WINDOW (s->f); | ||
| 4886 | s->char2b = char2b; | ||
| 4887 | s->hl = hl; | ||
| 4888 | s->row = row; | ||
| 4889 | s->area = area; | ||
| 4890 | s->first_glyph = row->glyphs[area] + start; | ||
| 4891 | s->height = row->height; | ||
| 4892 | s->y = WINDOW_TO_FRAME_PIXEL_Y (w, row->y); | ||
| 4893 | |||
| 4894 | /* Display the internal border below the tool-bar window. */ | ||
| 4895 | if (s->w == XWINDOW (s->f->tool_bar_window)) | ||
| 4896 | s->y -= s->f->output_data.mac->internal_border_width; | ||
| 4897 | |||
| 4898 | s->ybase = s->y + row->ascent; | ||
| 4899 | } | ||
| 4900 | |||
| 4901 | |||
| 4902 | /* Set background width of glyph string S. START is the index of the | ||
| 4903 | first glyph following S. LAST_X is the right-most x-position + 1 | ||
| 4904 | in the drawing area. */ | ||
| 4905 | |||
| 4906 | static INLINE void | ||
| 4907 | x_set_glyph_string_background_width (s, start, last_x) | ||
| 4908 | struct glyph_string *s; | ||
| 4909 | int start; | ||
| 4910 | int last_x; | ||
| 4911 | { | ||
| 4912 | /* If the face of this glyph string has to be drawn to the end of | ||
| 4913 | the drawing area, set S->extends_to_end_of_line_p. */ | ||
| 4914 | struct face *default_face = FACE_FROM_ID (s->f, DEFAULT_FACE_ID); | ||
| 4915 | |||
| 4916 | if (start == s->row->used[s->area] | ||
| 4917 | && s->area == TEXT_AREA | ||
| 4918 | && ((s->hl == DRAW_NORMAL_TEXT | ||
| 4919 | && (s->row->fill_line_p | ||
| 4920 | || s->face->background != default_face->background | ||
| 4921 | || s->face->stipple != default_face->stipple | ||
| 4922 | || s->row->mouse_face_p)) | ||
| 4923 | || s->hl == DRAW_MOUSE_FACE | ||
| 4924 | || ((s->hl == DRAW_IMAGE_RAISED || s->hl == DRAW_IMAGE_SUNKEN) | ||
| 4925 | && s->row->fill_line_p))) | ||
| 4926 | s->extends_to_end_of_line_p = 1; | ||
| 4927 | |||
| 4928 | /* If S extends its face to the end of the line, set its | ||
| 4929 | background_width to the distance to the right edge of the drawing | ||
| 4930 | area. */ | ||
| 4931 | if (s->extends_to_end_of_line_p) | ||
| 4932 | s->background_width = last_x - s->x + 1; | ||
| 4933 | else | ||
| 4934 | s->background_width = s->width; | ||
| 4935 | } | ||
| 4936 | |||
| 4937 | |||
| 4938 | /* Add a glyph string for a stretch glyph to the list of strings | ||
| 4939 | between HEAD and TAIL. START is the index of the stretch glyph in | ||
| 4940 | row area AREA of glyph row ROW. END is the index of the last glyph | ||
| 4941 | in that glyph row area. X is the current output position assigned | ||
| 4942 | to the new glyph string constructed. HL overrides that face of the | ||
| 4943 | glyph; e.g. it is DRAW_CURSOR if a cursor has to be drawn. LAST_X | ||
| 4944 | is the right-most x-position of the drawing area. */ | ||
| 4945 | |||
| 4946 | /* SunOS 4 bundled cc, barfed on continuations in the arg lists here | ||
| 4947 | and below -- keep them on one line. */ | ||
| 4948 | #define BUILD_STRETCH_GLYPH_STRING(W, ROW, AREA, START, END, HEAD, TAIL, HL, X, LAST_X) \ | ||
| 4949 | do \ | ||
| 4950 | { \ | ||
| 4951 | s = (struct glyph_string *) alloca (sizeof *s); \ | ||
| 4952 | x_init_glyph_string (s, NULL, W, ROW, AREA, START, HL); \ | ||
| 4953 | START = x_fill_stretch_glyph_string (s, ROW, AREA, START, END); \ | ||
| 4954 | x_append_glyph_string (&HEAD, &TAIL, s); \ | ||
| 4955 | s->x = (X); \ | ||
| 4956 | } \ | ||
| 4957 | while (0) | ||
| 4958 | |||
| 4959 | |||
| 4960 | /* Add a glyph string for an image glyph to the list of strings | ||
| 4961 | between HEAD and TAIL. START is the index of the image glyph in | ||
| 4962 | row area AREA of glyph row ROW. END is the index of the last glyph | ||
| 4963 | in that glyph row area. X is the current output position assigned | ||
| 4964 | to the new glyph string constructed. HL overrides that face of the | ||
| 4965 | glyph; e.g. it is DRAW_CURSOR if a cursor has to be drawn. LAST_X | ||
| 4966 | is the right-most x-position of the drawing area. */ | ||
| 4967 | |||
| 4968 | #define BUILD_IMAGE_GLYPH_STRING(W, ROW, AREA, START, END, HEAD, TAIL, HL, X, LAST_X) \ | ||
| 4969 | do \ | ||
| 4970 | { \ | ||
| 4971 | s = (struct glyph_string *) alloca (sizeof *s); \ | ||
| 4972 | x_init_glyph_string (s, NULL, W, ROW, AREA, START, HL); \ | ||
| 4973 | x_fill_image_glyph_string (s); \ | ||
| 4974 | x_append_glyph_string (&HEAD, &TAIL, s); \ | ||
| 4975 | ++START; \ | ||
| 4976 | s->x = (X); \ | ||
| 4977 | } \ | ||
| 4978 | while (0) | ||
| 4979 | |||
| 4980 | |||
| 4981 | /* Add a glyph string for a sequence of character glyphs to the list | ||
| 4982 | of strings between HEAD and TAIL. START is the index of the first | ||
| 4983 | glyph in row area AREA of glyph row ROW that is part of the new | ||
| 4984 | glyph string. END is the index of the last glyph in that glyph row | ||
| 4985 | area. X is the current output position assigned to the new glyph | ||
| 4986 | string constructed. HL overrides that face of the glyph; e.g. it | ||
| 4987 | is DRAW_CURSOR if a cursor has to be drawn. LAST_X is the | ||
| 4988 | right-most x-position of the drawing area. */ | ||
| 4989 | |||
| 4990 | #define BUILD_CHAR_GLYPH_STRINGS(W, ROW, AREA, START, END, HEAD, TAIL, HL, X, LAST_X, OVERLAPS_P) \ | ||
| 4991 | do \ | ||
| 4992 | { \ | ||
| 4993 | int c, face_id; \ | ||
| 4994 | XChar2b *char2b; \ | ||
| 4995 | \ | ||
| 4996 | c = (ROW)->glyphs[AREA][START].u.ch; \ | ||
| 4997 | face_id = (ROW)->glyphs[AREA][START].face_id; \ | ||
| 4998 | \ | ||
| 4999 | s = (struct glyph_string *) alloca (sizeof *s); \ | ||
| 5000 | char2b = (XChar2b *) alloca ((END - START) * sizeof *char2b); \ | ||
| 5001 | x_init_glyph_string (s, char2b, W, ROW, AREA, START, HL); \ | ||
| 5002 | x_append_glyph_string (&HEAD, &TAIL, s); \ | ||
| 5003 | s->x = (X); \ | ||
| 5004 | START = x_fill_glyph_string (s, face_id, START, END, \ | ||
| 5005 | OVERLAPS_P); \ | ||
| 5006 | } \ | ||
| 5007 | while (0) | ||
| 5008 | |||
| 5009 | |||
| 5010 | /* Add a glyph string for a composite sequence to the list of strings | ||
| 5011 | between HEAD and TAIL. START is the index of the first glyph in | ||
| 5012 | row area AREA of glyph row ROW that is part of the new glyph | ||
| 5013 | string. END is the index of the last glyph in that glyph row area. | ||
| 5014 | X is the current output position assigned to the new glyph string | ||
| 5015 | constructed. HL overrides that face of the glyph; e.g. it is | ||
| 5016 | DRAW_CURSOR if a cursor has to be drawn. LAST_X is the right-most | ||
| 5017 | x-position of the drawing area. */ | ||
| 5018 | |||
| 5019 | #define BUILD_COMPOSITE_GLYPH_STRING(W, ROW, AREA, START, END, HEAD, TAIL, HL, X, LAST_X, OVERLAPS_P) \ | ||
| 5020 | do { \ | ||
| 5021 | int cmp_id = (ROW)->glyphs[AREA][START].u.cmp_id; \ | ||
| 5022 | int face_id = (ROW)->glyphs[AREA][START].face_id; \ | ||
| 5023 | struct face *base_face = FACE_FROM_ID (XFRAME (w->frame), face_id); \ | ||
| 5024 | struct composition *cmp = composition_table[cmp_id]; \ | ||
| 5025 | int glyph_len = cmp->glyph_len; \ | ||
| 5026 | XChar2b *char2b; \ | ||
| 5027 | struct face **faces; \ | ||
| 5028 | struct glyph_string *first_s = NULL; \ | ||
| 5029 | int n; \ | ||
| 5030 | \ | ||
| 5031 | base_face = base_face->ascii_face; \ | ||
| 5032 | char2b = (XChar2b *) alloca ((sizeof *char2b) * glyph_len); \ | ||
| 5033 | faces = (struct face **) alloca ((sizeof *faces) * glyph_len); \ | ||
| 5034 | /* At first, fill in `char2b' and `faces'. */ \ | ||
| 5035 | for (n = 0; n < glyph_len; n++) \ | ||
| 5036 | { \ | ||
| 5037 | int c = COMPOSITION_GLYPH (cmp, n); \ | ||
| 5038 | int this_face_id = FACE_FOR_CHAR (XFRAME (w->frame), base_face, c); \ | ||
| 5039 | faces[n] = FACE_FROM_ID (XFRAME (w->frame), this_face_id); \ | ||
| 5040 | x_get_char_face_and_encoding (XFRAME (w->frame), c, \ | ||
| 5041 | this_face_id, char2b + n, 1); \ | ||
| 5042 | } \ | ||
| 5043 | \ | ||
| 5044 | /* Make glyph_strings for each glyph sequence that is drawable by \ | ||
| 5045 | the same face, and append them to HEAD/TAIL. */ \ | ||
| 5046 | for (n = 0; n < cmp->glyph_len;) \ | ||
| 5047 | { \ | ||
| 5048 | s = (struct glyph_string *) alloca (sizeof *s); \ | ||
| 5049 | x_init_glyph_string (s, char2b + n, W, ROW, AREA, START, HL); \ | ||
| 5050 | x_append_glyph_string (&(HEAD), &(TAIL), s); \ | ||
| 5051 | s->cmp = cmp; \ | ||
| 5052 | s->gidx = n; \ | ||
| 5053 | s->x = (X); \ | ||
| 5054 | \ | ||
| 5055 | if (n == 0) \ | ||
| 5056 | first_s = s; \ | ||
| 5057 | \ | ||
| 5058 | n = x_fill_composite_glyph_string (s, faces, OVERLAPS_P); \ | ||
| 5059 | } \ | ||
| 5060 | \ | ||
| 5061 | ++START; \ | ||
| 5062 | s = first_s; \ | ||
| 5063 | } while (0) | ||
| 5064 | |||
| 5065 | |||
| 5066 | /* Build a list of glyph strings between HEAD and TAIL for the glyphs | ||
| 5067 | of AREA of glyph row ROW on window W between indices START and END. | ||
| 5068 | HL overrides the face for drawing glyph strings, e.g. it is | ||
| 5069 | DRAW_CURSOR to draw a cursor. X and LAST_X are start and end | ||
| 5070 | x-positions of the drawing area. | ||
| 5071 | |||
| 5072 | This is an ugly monster macro construct because we must use alloca | ||
| 5073 | to allocate glyph strings (because x_draw_glyphs can be called | ||
| 5074 | asynchronously). */ | ||
| 5075 | |||
| 5076 | #define BUILD_GLYPH_STRINGS(W, ROW, AREA, START, END, HEAD, TAIL, HL, X, LAST_X, OVERLAPS_P) \ | ||
| 5077 | do \ | ||
| 5078 | { \ | ||
| 5079 | HEAD = TAIL = NULL; \ | ||
| 5080 | while (START < END) \ | ||
| 5081 | { \ | ||
| 5082 | struct glyph *first_glyph = (ROW)->glyphs[AREA] + START; \ | ||
| 5083 | switch (first_glyph->type) \ | ||
| 5084 | { \ | ||
| 5085 | case CHAR_GLYPH: \ | ||
| 5086 | BUILD_CHAR_GLYPH_STRINGS (W, ROW, AREA, START, END, HEAD, \ | ||
| 5087 | TAIL, HL, X, LAST_X, \ | ||
| 5088 | OVERLAPS_P); \ | ||
| 5089 | break; \ | ||
| 5090 | \ | ||
| 5091 | case COMPOSITE_GLYPH: \ | ||
| 5092 | BUILD_COMPOSITE_GLYPH_STRING (W, ROW, AREA, START, END, \ | ||
| 5093 | HEAD, TAIL, HL, X, LAST_X,\ | ||
| 5094 | OVERLAPS_P); \ | ||
| 5095 | break; \ | ||
| 5096 | \ | ||
| 5097 | case STRETCH_GLYPH: \ | ||
| 5098 | BUILD_STRETCH_GLYPH_STRING (W, ROW, AREA, START, END, \ | ||
| 5099 | HEAD, TAIL, HL, X, LAST_X); \ | ||
| 5100 | break; \ | ||
| 5101 | \ | ||
| 5102 | case IMAGE_GLYPH: \ | ||
| 5103 | BUILD_IMAGE_GLYPH_STRING (W, ROW, AREA, START, END, HEAD, \ | ||
| 5104 | TAIL, HL, X, LAST_X); \ | ||
| 5105 | break; \ | ||
| 5106 | \ | ||
| 5107 | default: \ | ||
| 5108 | abort (); \ | ||
| 5109 | } \ | ||
| 5110 | \ | ||
| 5111 | x_set_glyph_string_background_width (s, START, LAST_X); \ | ||
| 5112 | (X) += s->width; \ | ||
| 5113 | } \ | ||
| 5114 | } \ | ||
| 5115 | while (0) | ||
| 5116 | |||
| 5117 | |||
| 5118 | /* Draw glyphs between START and END in AREA of ROW on window W, | ||
| 5119 | starting at x-position X. X is relative to AREA in W. HL is a | ||
| 5120 | face-override with the following meaning: | ||
| 5121 | |||
| 5122 | DRAW_NORMAL_TEXT draw normally | ||
| 5123 | DRAW_CURSOR draw in cursor face | ||
| 5124 | DRAW_MOUSE_FACE draw in mouse face. | ||
| 5125 | DRAW_INVERSE_VIDEO draw in mode line face | ||
| 5126 | DRAW_IMAGE_SUNKEN draw an image with a sunken relief around it | ||
| 5127 | DRAW_IMAGE_RAISED draw an image with a raised relief around it | ||
| 5128 | |||
| 5129 | If OVERLAPS_P is non-zero, draw only the foreground of characters | ||
| 5130 | and clip to the physical height of ROW. | ||
| 5131 | |||
| 5132 | Value is the x-position reached, relative to AREA of W. */ | ||
| 5133 | |||
| 5134 | static int | ||
| 5135 | x_draw_glyphs (w, x, row, area, start, end, hl, overlaps_p) | ||
| 5136 | struct window *w; | ||
| 5137 | int x; | ||
| 5138 | struct glyph_row *row; | ||
| 5139 | enum glyph_row_area area; | ||
| 5140 | int start, end; | ||
| 5141 | enum draw_glyphs_face hl; | ||
| 5142 | int overlaps_p; | ||
| 5143 | { | ||
| 5144 | struct glyph_string *head, *tail; | ||
| 5145 | struct glyph_string *s; | ||
| 5146 | int last_x, area_width; | ||
| 5147 | int x_reached; | ||
| 5148 | int i, j; | ||
| 5149 | |||
| 5150 | /* Let's rather be paranoid than getting a SEGV. */ | ||
| 5151 | end = min (end, row->used[area]); | ||
| 5152 | start = max (0, start); | ||
| 5153 | start = min (end, start); | ||
| 5154 | |||
| 5155 | /* Translate X to frame coordinates. Set last_x to the right | ||
| 5156 | end of the drawing area. */ | ||
| 5157 | if (row->full_width_p) | ||
| 5158 | { | ||
| 5159 | /* X is relative to the left edge of W, without scroll bars | ||
| 5160 | or fringes. */ | ||
| 5161 | struct frame *f = XFRAME (WINDOW_FRAME (w)); | ||
| 5162 | int window_left_x = WINDOW_LEFT_MARGIN (w) * CANON_X_UNIT (f); | ||
| 5163 | |||
| 5164 | x += window_left_x; | ||
| 5165 | area_width = XFASTINT (w->width) * CANON_X_UNIT (f); | ||
| 5166 | last_x = window_left_x + area_width; | ||
| 5167 | |||
| 5168 | if (FRAME_HAS_VERTICAL_SCROLL_BARS (f)) | ||
| 5169 | { | ||
| 5170 | int width = FRAME_SCROLL_BAR_WIDTH (f) * CANON_X_UNIT (f); | ||
| 5171 | if (FRAME_HAS_VERTICAL_SCROLL_BARS_ON_RIGHT (f)) | ||
| 5172 | last_x += width; | ||
| 5173 | else | ||
| 5174 | x -= width; | ||
| 5175 | } | ||
| 5176 | |||
| 5177 | x += FRAME_INTERNAL_BORDER_WIDTH (f); | ||
| 5178 | last_x -= FRAME_INTERNAL_BORDER_WIDTH (f); | ||
| 5179 | } | ||
| 5180 | else | ||
| 5181 | { | ||
| 5182 | x = WINDOW_AREA_TO_FRAME_PIXEL_X (w, area, x); | ||
| 5183 | area_width = window_box_width (w, area); | ||
| 5184 | last_x = WINDOW_AREA_TO_FRAME_PIXEL_X (w, area, area_width); | ||
| 5185 | } | ||
| 5186 | |||
| 5187 | /* Build a doubly-linked list of glyph_string structures between | ||
| 5188 | head and tail from what we have to draw. Note that the macro | ||
| 5189 | BUILD_GLYPH_STRINGS will modify its start parameter. That's | ||
| 5190 | the reason we use a separate variable `i'. */ | ||
| 5191 | i = start; | ||
| 5192 | BUILD_GLYPH_STRINGS (w, row, area, i, end, head, tail, hl, x, last_x, | ||
| 5193 | overlaps_p); | ||
| 5194 | if (tail) | ||
| 5195 | x_reached = tail->x + tail->background_width; | ||
| 5196 | else | ||
| 5197 | x_reached = x; | ||
| 5198 | |||
| 5199 | /* If there are any glyphs with lbearing < 0 or rbearing > width in | ||
| 5200 | the row, redraw some glyphs in front or following the glyph | ||
| 5201 | strings built above. */ | ||
| 5202 | if (head && !overlaps_p && row->contains_overlapping_glyphs_p) | ||
| 5203 | { | ||
| 5204 | int dummy_x = 0; | ||
| 5205 | struct glyph_string *h, *t; | ||
| 5206 | |||
| 5207 | /* Compute overhangs for all glyph strings. */ | ||
| 5208 | for (s = head; s; s = s->next) | ||
| 5209 | x_compute_glyph_string_overhangs (s); | ||
| 5210 | |||
| 5211 | /* Prepend glyph strings for glyphs in front of the first glyph | ||
| 5212 | string that are overwritten because of the first glyph | ||
| 5213 | string's left overhang. The background of all strings | ||
| 5214 | prepended must be drawn because the first glyph string | ||
| 5215 | draws over it. */ | ||
| 5216 | i = x_left_overwritten (head); | ||
| 5217 | if (i >= 0) | ||
| 5218 | { | ||
| 5219 | j = i; | ||
| 5220 | BUILD_GLYPH_STRINGS (w, row, area, j, start, h, t, | ||
| 5221 | DRAW_NORMAL_TEXT, dummy_x, last_x, | ||
| 5222 | overlaps_p); | ||
| 5223 | start = i; | ||
| 5224 | x_compute_overhangs_and_x (t, head->x, 1); | ||
| 5225 | x_prepend_glyph_string_lists (&head, &tail, h, t); | ||
| 5226 | } | ||
| 5227 | |||
| 5228 | /* Prepend glyph strings for glyphs in front of the first glyph | ||
| 5229 | string that overwrite that glyph string because of their | ||
| 5230 | right overhang. For these strings, only the foreground must | ||
| 5231 | be drawn, because it draws over the glyph string at `head'. | ||
| 5232 | The background must not be drawn because this would overwrite | ||
| 5233 | right overhangs of preceding glyphs for which no glyph | ||
| 5234 | strings exist. */ | ||
| 5235 | i = x_left_overwriting (head); | ||
| 5236 | if (i >= 0) | ||
| 5237 | { | ||
| 5238 | BUILD_GLYPH_STRINGS (w, row, area, i, start, h, t, | ||
| 5239 | DRAW_NORMAL_TEXT, dummy_x, last_x, | ||
| 5240 | overlaps_p); | ||
| 5241 | for (s = h; s; s = s->next) | ||
| 5242 | s->background_filled_p = 1; | ||
| 5243 | x_compute_overhangs_and_x (t, head->x, 1); | ||
| 5244 | x_prepend_glyph_string_lists (&head, &tail, h, t); | ||
| 5245 | } | ||
| 5246 | |||
| 5247 | /* Append glyphs strings for glyphs following the last glyph | ||
| 5248 | string tail that are overwritten by tail. The background of | ||
| 5249 | these strings has to be drawn because tail's foreground draws | ||
| 5250 | over it. */ | ||
| 5251 | i = x_right_overwritten (tail); | ||
| 5252 | if (i >= 0) | ||
| 5253 | { | ||
| 5254 | BUILD_GLYPH_STRINGS (w, row, area, end, i, h, t, | ||
| 5255 | DRAW_NORMAL_TEXT, x, last_x, | ||
| 5256 | overlaps_p); | ||
| 5257 | x_compute_overhangs_and_x (h, tail->x + tail->width, 0); | ||
| 5258 | x_append_glyph_string_lists (&head, &tail, h, t); | ||
| 5259 | } | ||
| 5260 | |||
| 5261 | /* Append glyph strings for glyphs following the last glyph | ||
| 5262 | string tail that overwrite tail. The foreground of such | ||
| 5263 | glyphs has to be drawn because it writes into the background | ||
| 5264 | of tail. The background must not be drawn because it could | ||
| 5265 | paint over the foreground of following glyphs. */ | ||
| 5266 | i = x_right_overwriting (tail); | ||
| 5267 | if (i >= 0) | ||
| 5268 | { | ||
| 5269 | BUILD_GLYPH_STRINGS (w, row, area, end, i, h, t, | ||
| 5270 | DRAW_NORMAL_TEXT, x, last_x, | ||
| 5271 | overlaps_p); | ||
| 5272 | for (s = h; s; s = s->next) | ||
| 5273 | s->background_filled_p = 1; | ||
| 5274 | x_compute_overhangs_and_x (h, tail->x + tail->width, 0); | ||
| 5275 | x_append_glyph_string_lists (&head, &tail, h, t); | ||
| 5276 | } | ||
| 5277 | } | ||
| 5278 | |||
| 5279 | /* Draw all strings. */ | ||
| 5280 | for (s = head; s; s = s->next) | ||
| 5281 | x_draw_glyph_string (s); | ||
| 5282 | |||
| 5283 | if (area == TEXT_AREA | ||
| 5284 | && !row->full_width_p | ||
| 5285 | /* When drawing overlapping rows, only the glyph strings' | ||
| 5286 | foreground is drawn, which doesn't erase a cursor | ||
| 5287 | completely. */ | ||
| 5288 | && !overlaps_p) | ||
| 5289 | { | ||
| 5290 | int x0 = head ? head->x : x; | ||
| 5291 | int x1 = tail ? tail->x + tail->background_width : x; | ||
| 5292 | |||
| 5293 | x0 = FRAME_TO_WINDOW_PIXEL_X (w, x0); | ||
| 5294 | x1 = FRAME_TO_WINDOW_PIXEL_X (w, x1); | ||
| 5295 | |||
| 5296 | if (!row->full_width_p && XFASTINT (w->left_margin_width) != 0) | ||
| 5297 | { | ||
| 5298 | int left_area_width = window_box_width (w, LEFT_MARGIN_AREA); | ||
| 5299 | x0 -= left_area_width; | ||
| 5300 | x1 -= left_area_width; | ||
| 5301 | } | ||
| 5302 | |||
| 5303 | notice_overwritten_cursor (w, area, x0, x1, | ||
| 5304 | row->y, MATRIX_ROW_BOTTOM_Y (row)); | ||
| 5305 | } | ||
| 5306 | |||
| 5307 | /* Value is the x-position up to which drawn, relative to AREA of W. | ||
| 5308 | This doesn't include parts drawn because of overhangs. */ | ||
| 5309 | x_reached = FRAME_TO_WINDOW_PIXEL_X (w, x_reached); | ||
| 5310 | if (!row->full_width_p) | ||
| 5311 | { | ||
| 5312 | if (area > LEFT_MARGIN_AREA) | ||
| 5313 | x_reached -= window_box_width (w, LEFT_MARGIN_AREA); | ||
| 5314 | if (area > TEXT_AREA) | ||
| 5315 | x_reached -= window_box_width (w, TEXT_AREA); | ||
| 5316 | } | ||
| 5317 | |||
| 5318 | return x_reached; | ||
| 5319 | } | ||
| 5320 | |||
| 5321 | |||
| 5322 | /* Fix the display of area AREA of overlapping row ROW in window W. */ | 3186 | /* Fix the display of area AREA of overlapping row ROW in window W. */ |
| 5323 | 3187 | ||
| 5324 | static void | 3188 | static void |
| @@ -8701,28 +6565,6 @@ x_scroll_bar_report_motion (fp, bar_window, part, x, y, time) | |||
| 8701 | Text Cursor | 6565 | Text Cursor |
| 8702 | ***********************************************************************/ | 6566 | ***********************************************************************/ |
| 8703 | 6567 | ||
| 8704 | /* Notice if the text cursor of window W has been overwritten by a | ||
| 8705 | drawing operation that outputs glyphs starting at START_X and | ||
| 8706 | ending at END_X in the line given by output_cursor.vpos. | ||
| 8707 | Coordinates are area-relative. END_X < 0 means all the rest | ||
| 8708 | of the line after START_X has been written. */ | ||
| 8709 | |||
| 8710 | static void | ||
| 8711 | notice_overwritten_cursor (w, area, x0, x1, y0, y1) | ||
| 8712 | struct window *w; | ||
| 8713 | enum glyph_row_area area; | ||
| 8714 | int x0, x1, y0, y1; | ||
| 8715 | { | ||
| 8716 | if (area == TEXT_AREA | ||
| 8717 | && w->phys_cursor_on_p | ||
| 8718 | && y0 <= w->phys_cursor.y | ||
| 8719 | && y1 >= w->phys_cursor.y + w->phys_cursor_height | ||
| 8720 | && x0 <= w->phys_cursor.x | ||
| 8721 | && (x1 < 0 || x1 > w->phys_cursor.x)) | ||
| 8722 | w->phys_cursor_on_p = 0; | ||
| 8723 | } | ||
| 8724 | |||
| 8725 | |||
| 8726 | /* Set clipping for output in glyph row ROW. W is the window in which | 6568 | /* Set clipping for output in glyph row ROW. W is the window in which |
| 8727 | we operate. GC is the graphics context to set clipping in. | 6569 | we operate. GC is the graphics context to set clipping in. |
| 8728 | WHOLE_LINE_P non-zero means include the areas used for truncation | 6570 | WHOLE_LINE_P non-zero means include the areas used for truncation |
| @@ -13270,7 +11112,11 @@ static struct redisplay_interface x_redisplay_interface = | |||
| 13270 | x_clear_mouse_face, | 11112 | x_clear_mouse_face, |
| 13271 | x_get_glyph_overhangs, | 11113 | x_get_glyph_overhangs, |
| 13272 | x_fix_overlapping_area, | 11114 | x_fix_overlapping_area, |
| 13273 | x_draw_fringe_bitmap | 11115 | x_draw_fringe_bitmap, |
| 11116 | mac_per_char_metric, | ||
| 11117 | mac_encode_char, | ||
| 11118 | NULL, /* mac_compute_glyph_string_overhangs */ | ||
| 11119 | x_draw_glyph_string | ||
| 13274 | }; | 11120 | }; |
| 13275 | 11121 | ||
| 13276 | void | 11122 | void |