Mercurial > emacs
comparison src/macterm.c @ 50157:203d5a0f77a8
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.
author | Kim F. Storm <storm@cua.dk> |
---|---|
date | Sun, 16 Mar 2003 20:48:56 +0000 |
parents | ee703213acfa |
children | 90e10bfd8bfa |
comparison
equal
deleted
inserted
replaced
50156:8ff568a30195 | 50157:203d5a0f77a8 |
---|---|
297 | 297 |
298 #if __MRC__ | 298 #if __MRC__ |
299 QDGlobals qd; /* QuickDraw global information structure. */ | 299 QDGlobals qd; /* QuickDraw global information structure. */ |
300 #endif | 300 #endif |
301 | 301 |
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 | 302 |
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)); |
319 static void frame_to_window_pixel_xy P_ ((struct window *, int *, int *)); | 306 static void frame_to_window_pixel_xy P_ ((struct window *, int *, int *)); |
384 static void x_erase_phys_cursor P_ ((struct window *)); | 371 static void x_erase_phys_cursor P_ ((struct window *)); |
385 void x_display_and_set_cursor P_ ((struct window *, int, int, int, int, int)); | 372 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); |
402 | 384 |
403 static int is_emacs_window (WindowPtr); | 385 static int is_emacs_window (WindowPtr); |
412 /* Defined in macmenu.h. */ | 394 /* Defined in macmenu.h. */ |
413 extern void menubar_selection_callback (FRAME_PTR, int); | 395 extern void menubar_selection_callback (FRAME_PTR, int); |
414 extern void set_frame_menubar (FRAME_PTR, int, int); | 396 extern void set_frame_menubar (FRAME_PTR, int, int); |
415 | 397 |
416 /* X display function emulation */ | 398 /* X display function emulation */ |
417 | |
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 | 399 |
426 static void | 400 static void |
427 XFreePixmap (display, pixmap) | 401 XFreePixmap (display, pixmap) |
428 Display *display; | 402 Display *display; |
429 Pixmap pixmap; | 403 Pixmap pixmap; |
1537 Display Iterator | 1511 Display Iterator |
1538 ***********************************************************************/ | 1512 ***********************************************************************/ |
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 |
1559 character pointed by B which is a pointer to an XChar2b. */ | 1521 character pointed by B which is a pointer to an XChar2b. */ |
1560 | 1522 |
1636 return ((pcm == NULL | 1598 return ((pcm == NULL |
1637 || (pcm->width == 0 && (pcm->rbearing - pcm->lbearing) == 0)) | 1599 || (pcm->width == 0 && (pcm->rbearing - pcm->lbearing) == 0)) |
1638 ? NULL : pcm); | 1600 ? NULL : pcm); |
1639 } | 1601 } |
1640 | 1602 |
1641 | 1603 /* RIF: |
1642 /* Encode CHAR2B using encoding information from FONT_INFO. CHAR2B is | 1604 */ |
1605 | |
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; |
1653 | 1628 |
1654 /* FONT_INFO may define a scheme by which to encode byte1 and byte2. | 1629 /* FONT_INFO may define a scheme by which to encode byte1 and byte2. |
1700 ENCODE_SJIS (char2b->byte1, char2b->byte2, sjis1, sjis2); | 1675 ENCODE_SJIS (char2b->byte1, char2b->byte2, sjis1, sjis2); |
1701 char2b->byte1 = sjis1; | 1676 char2b->byte1 = sjis1; |
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 | 1683 |
1786 if (!glyph->multibyte_p) | 1684 return FONT_TYPE_UNKNOWN; |
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 | |
2276 /* When no suitable font found, use the default font. */ | |
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 |
2769 /* Estimate the pixel height of the mode or top line on frame F. | 1688 /* Estimate the pixel height of the mode or top line on frame F. |
2770 FACE_ID specifies what line's height to estimate. */ | 1689 FACE_ID specifies what line's height to estimate. */ |
2796 | 1715 |
2797 /*********************************************************************** | 1716 /*********************************************************************** |
2798 Glyph display | 1717 Glyph display |
2799 ***********************************************************************/ | 1718 ***********************************************************************/ |
2800 | 1719 |
2801 /* A sequence of glyphs to be drawn in the same face. | 1720 |
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 | |
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 *, |
2970 int)); | 1724 int)); |
2971 static void x_draw_glyph_string_foreground P_ ((struct glyph_string *)); | 1725 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 *, |
2985 double, int, unsigned long)); | 1735 double, int, unsigned long)); |
2986 static void x_setup_relief_colors P_ ((struct glyph_string *)); | 1736 static void x_setup_relief_colors P_ ((struct glyph_string *)); |
2987 static void x_draw_image_glyph_string P_ ((struct glyph_string *)); | 1737 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, |
2995 int, int, int, int, Rect *)); | 1744 int, int, int, int, Rect *)); |
2996 static void x_draw_box_rect P_ ((struct glyph_string *, int, int, int, int, | 1745 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 | |
3008 | |
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 | 1753 |
3062 | 1754 |
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 |
3308 x_get_glyph_string_clip_rect (s, &r); | 2000 x_get_glyph_string_clip_rect (s, &r); |
3309 mac_set_clip_rectangle (s->display, s->window, &r); | 2001 mac_set_clip_rectangle (s->display, s->window, &r); |
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 { |
3323 XCharStruct cs; | 2019 XCharStruct cs; |
3324 int direction, font_ascent, font_descent; | 2020 int direction, font_ascent, font_descent; |
3325 XTextExtents16 (s->font, s->char2b, s->nchars, &direction, | 2021 XTextExtents16 (s->font, s->char2b, s->nchars, &direction, |
3326 &font_ascent, &font_descent, &cs); | 2022 &font_ascent, &font_descent, &cs); |
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 |
3511 /* Fill rectangle X, Y, W, H with background color of glyph string S. */ | 2030 /* Fill rectangle X, Y, W, H with background color of glyph string S. */ |
3512 | 2031 |
4659 x_draw_glyph_string_box (s); | 3178 x_draw_glyph_string_box (s); |
4660 } | 3179 } |
4661 | 3180 |
4662 /* Reset clipping. */ | 3181 /* Reset clipping. */ |
4663 mac_reset_clipping (s->display, s->window); | 3182 mac_reset_clipping (s->display, s->window); |
4664 } | |
4665 | |
4666 | |
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 } | 3183 } |
5320 | 3184 |
5321 | 3185 |
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 |
8698 } | 6562 } |
8699 | 6563 |
8700 /*********************************************************************** | 6564 /*********************************************************************** |
8701 Text Cursor | 6565 Text Cursor |
8702 ***********************************************************************/ | 6566 ***********************************************************************/ |
8703 | |
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 | 6567 |
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 |
8729 mark display and alike in the clipping rectangle. | 6571 mark display and alike in the clipping rectangle. |
13268 XTcursor_to, | 11110 XTcursor_to, |
13269 x_flush, | 11111 x_flush, |
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 |
13277 mac_initialize () | 11123 mac_initialize () |
13278 { | 11124 { |