comparison src/xterm.c @ 26879:b4de7fa9866e

(x_append_glyph): Setup members of struct glyph properly for composition. (x_append_composite_glyph): New function. (VCENTER_BASELINE_OFFSET): New macro. (x_produce_glyphs): If it->what == IT_COMPOSITION, setup members of struct it for the composition. Cache pixel offsets in the struct composition. Delete codes for a composite character. Handle Vignore_relative_composition in composition code. (struct glyph_string): Delete member cmpcharp, add new member cmp. (x_set_cursor_gc): Check s->cmp, not s->cmpcharp. (x_compute_glyph_string_overhangs): Likewise. (x_get_glyph_overhangs): Delete codes for a composite character. (x_right_overwritten): Check s->cmp, not s->cmpcharp. (x_draw_glyph_string_background): Likewise. Delete codes for checking s->gidx for a composition. (x_draw_glyph_string_foreground): Delete code for a composite character. (x_draw_composite_glyph_string_foreground): New function. (x_draw_glyph_string_box): Check s->cmp, not s->cmpcharp. (x_draw_glyph_string): Handle the case of COMPOSITE_GLYPH. (struct work): Deleted. (x_fill_composite_glyph_string): Argument changed. Mostly rewritten for that. (x_fill_glyph_string): Don't check CHARSET_COMPOSITION. (BUILD_CHAR_GLYPH_STRINGS): Don't handle composition here. (BUILD_COMPOSITE_GLYPH_STRING): New macro. (BUILD_GLYPH_STRINGS): For composition, call BUILD_COMPOSITE_GLYPH_STRING. (x_new_font): Initialize f->output_data.x->baseline_offset, not f->output_data.x->font_baseline.
author Kenichi Handa <handa@m17n.org>
date Wed, 15 Dec 1999 00:27:21 +0000
parents 4189345a1b5d
children 3470e4fea708
comparison
equal deleted inserted replaced
26878:0020f5359d09 26879:b4de7fa9866e
1094 static struct face *x_get_char_face_and_encoding P_ ((struct frame *, int, 1094 static struct face *x_get_char_face_and_encoding P_ ((struct frame *, int,
1095 int, XChar2b *, int)); 1095 int, XChar2b *, int));
1096 static XCharStruct *x_per_char_metric P_ ((XFontStruct *, XChar2b *)); 1096 static XCharStruct *x_per_char_metric P_ ((XFontStruct *, XChar2b *));
1097 static void x_encode_char P_ ((int, XChar2b *, struct font_info *)); 1097 static void x_encode_char P_ ((int, XChar2b *, struct font_info *));
1098 static void x_append_glyph P_ ((struct it *)); 1098 static void x_append_glyph P_ ((struct it *));
1099 static void x_append_composite_glyph P_ ((struct it *));
1099 static void x_append_stretch_glyph P_ ((struct it *it, Lisp_Object, 1100 static void x_append_stretch_glyph P_ ((struct it *it, Lisp_Object,
1100 int, int, double)); 1101 int, int, double));
1101 static void x_produce_glyphs P_ ((struct it *)); 1102 static void x_produce_glyphs P_ ((struct it *));
1102 static void x_produce_image_glyph P_ ((struct it *it)); 1103 static void x_produce_image_glyph P_ ((struct it *it));
1103 1104
1308 else 1309 else
1309 char2b->byte1 = 0, char2b->byte2 = c1; 1310 char2b->byte1 = 0, char2b->byte2 = c1;
1310 1311
1311 /* Get the face for displaying C. If `face' is not suitable for 1312 /* Get the face for displaying C. If `face' is not suitable for
1312 charset, get the one that fits. (This can happen for the 1313 charset, get the one that fits. (This can happen for the
1313 translations of composite characters where the glyph 1314 translations of a composition where the glyph
1314 specifies a face for ASCII, but translations have a different 1315 specifies a face for the first component, but the other
1315 charset.) */ 1316 components have a different charset.) */
1316 if (!FACE_SUITABLE_FOR_CHARSET_P (face, charset)) 1317 if (!FACE_SUITABLE_FOR_CHARSET_P (face, charset))
1317 { 1318 {
1318 face_id = FACE_FOR_CHARSET (f, face_id, charset); 1319 face_id = FACE_FOR_CHARSET (f, face_id, charset);
1319 face = FACE_FROM_ID (f, face_id); 1320 face = FACE_FROM_ID (f, face_id);
1320 } 1321 }
1442 || it->phys_descent > it->descent); 1443 || it->phys_descent > it->descent);
1443 ++it->glyph_row->used[area]; 1444 ++it->glyph_row->used[area];
1444 } 1445 }
1445 } 1446 }
1446 1447
1448 /* Store one glyph for the composition IT->cmp_id in IT->glyph_row.
1449 Called from x_produce_glyphs when IT->glyph_row is non-null. */
1450
1451 static INLINE void
1452 x_append_composite_glyph (it)
1453 struct it *it;
1454 {
1455 struct glyph *glyph;
1456 enum glyph_row_area area = it->area;
1457
1458 xassert (it->glyph_row);
1459
1460 glyph = it->glyph_row->glyphs[area] + it->glyph_row->used[area];
1461 if (glyph < it->glyph_row->glyphs[area + 1])
1462 {
1463 /* Play it safe. If sub-structures of the glyph are not all the
1464 same size, it otherwise be that some bits stay set. This
1465 would prevent a comparison with GLYPH_EQUAL_P. */
1466 glyph->u.val = 0;
1467
1468 glyph->type = COMPOSITE_GLYPH;
1469 glyph->pixel_width = it->pixel_width;
1470 glyph->u.cmp.id = it->cmp_id;
1471 glyph->u.cmp.face_id = it->face_id;
1472 glyph->charpos = CHARPOS (it->position);
1473 glyph->object = it->object;
1474 glyph->left_box_line_p = it->start_of_box_run_p;
1475 glyph->right_box_line_p = it->end_of_box_run_p;
1476 glyph->voffset = it->voffset;
1477 glyph->multibyte_p = it->multibyte_p;
1478 glyph->overlaps_vertically_p = (it->phys_ascent > it->ascent
1479 || it->phys_descent > it->descent);
1480 ++it->glyph_row->used[area];
1481 }
1482 }
1483
1447 1484
1448 /* Change IT->ascent and IT->height according to the setting of 1485 /* Change IT->ascent and IT->height according to the setting of
1449 IT->voffset. */ 1486 IT->voffset. */
1450 1487
1451 static INLINE void 1488 static INLINE void
1707 } 1744 }
1708 1745
1709 take_vertical_position_into_account (it); 1746 take_vertical_position_into_account (it);
1710 } 1747 }
1711 1748
1749 /* Return proper value to be used as baseline offset of font that has
1750 ASCENT and DESCENT to draw characters by the font at the vertical
1751 center of the line of frame F.
1752
1753 Here, out task is to find the value of BOFF in the following figure;
1754
1755 -------------------------+-----------+-
1756 -+-+---------+-+ | |
1757 | | | | | |
1758 | | | | F_ASCENT F_HEIGHT
1759 | | | ASCENT | |
1760 HEIGHT | | | | |
1761 | | |-|-+------+-----------|------- baseline
1762 | | | | BOFF | |
1763 | |---------|-+-+ | |
1764 | | | DESCENT | |
1765 -+-+---------+-+ F_DESCENT |
1766 -------------------------+-----------+-
1767
1768 -BOFF + DESCENT + (F_HEIGHT - HEIGHT) / 2 = F_DESCENT
1769 BOFF = DESCENT + (F_HEIGHT - HEIGHT) / 2 - F_DESCENT
1770 DESCENT = FONT->descent
1771 HEIGHT = FONT_HEIGHT (FONT)
1772 F_DESCENT = (F->output_data.x->font->descent
1773 - F->output_data.x->baseline_offset)
1774 F_HEIGHT = FRAME_LINE_HEIGHT (F)
1775 */
1776
1777 #define VCENTER_BASELINE_OFFSET(FONT, F) \
1778 ((FONT)->descent \
1779 + (FRAME_LINE_HEIGHT ((F)) - FONT_HEIGHT ((FONT))) / 2 \
1780 - ((F)->output_data.x->font->descent - (F)->output_data.x->baseline_offset))
1712 1781
1713 /* Produce glyphs/get display metrics for the display element IT is 1782 /* Produce glyphs/get display metrics for the display element IT is
1714 loaded with. See the description of struct display_iterator in 1783 loaded with. See the description of struct display_iterator in
1715 dispextern.h for an overview of struct display_iterator. */ 1784 dispextern.h for an overview of struct display_iterator. */
1716 1785
1723 XChar2b char2b; 1792 XChar2b char2b;
1724 XFontStruct *font; 1793 XFontStruct *font;
1725 struct face *face; 1794 struct face *face;
1726 XCharStruct *pcm; 1795 XCharStruct *pcm;
1727 int font_not_found_p; 1796 int font_not_found_p;
1797 struct font_info *font_info;
1798 int boff; /* baseline offset */
1728 1799
1729 /* Maybe translate single-byte characters to multibyte. */ 1800 /* Maybe translate single-byte characters to multibyte. */
1730 it->char_to_display = it->c; 1801 it->char_to_display = it->c;
1731 if (unibyte_display_via_language_environment 1802 if (unibyte_display_via_language_environment
1732 && SINGLE_BYTE_CHAR_P (it->c) 1803 && SINGLE_BYTE_CHAR_P (it->c)
1745 font = face->font; 1816 font = face->font;
1746 1817
1747 /* When no suitable font found, use the default font. */ 1818 /* When no suitable font found, use the default font. */
1748 font_not_found_p = font == NULL; 1819 font_not_found_p = font == NULL;
1749 if (font_not_found_p) 1820 if (font_not_found_p)
1750 font = FRAME_FONT (it->f); 1821 {
1822 font = FRAME_FONT (it->f);
1823 boff = it->f->output_data.x->baseline_offset;
1824 font_info = NULL;
1825 }
1826 else
1827 {
1828 font_info = FONT_INFO_FROM_ID (it->f, face->font_info_id);
1829 boff = font_info->baseline_offset;
1830 if (font_info->vertical_centering)
1831 boff = VCENTER_BASELINE_OFFSET (font, it->f) - boff;
1832 }
1751 1833
1752 if (it->char_to_display >= ' ' 1834 if (it->char_to_display >= ' '
1753 && (!it->multibyte_p || it->char_to_display < 128)) 1835 && (!it->multibyte_p || it->char_to_display < 128))
1754 { 1836 {
1755 /* Either unibyte or ASCII. */ 1837 /* Either unibyte or ASCII. */
1756 int stretched_p; 1838 int stretched_p;
1757 1839
1758 it->nglyphs = 1; 1840 it->nglyphs = 1;
1759 1841
1760 pcm = x_per_char_metric (font, &char2b); 1842 pcm = x_per_char_metric (font, &char2b);
1761 it->ascent = font->ascent; 1843 it->ascent = font->ascent + boff;
1762 it->descent = font->descent; 1844 it->descent = font->descent - boff;
1763 it->phys_ascent = pcm->ascent; 1845 it->phys_ascent = pcm->ascent + boff;
1764 it->phys_descent = pcm->descent; 1846 it->phys_descent = pcm->descent - boff;
1765 it->pixel_width = pcm->width; 1847 it->pixel_width = pcm->width;
1766 1848
1767 /* If this is a space inside a region of text with 1849 /* If this is a space inside a region of text with
1768 `space-width' property, change its width. */ 1850 `space-width' property, change its width. */
1769 stretched_p = it->char_to_display == ' ' && !NILP (it->space_width); 1851 stretched_p = it->char_to_display == ' ' && !NILP (it->space_width);
1818 else if (it->char_to_display == '\n') 1900 else if (it->char_to_display == '\n')
1819 { 1901 {
1820 /* A newline has no width but we need the height of the line. */ 1902 /* A newline has no width but we need the height of the line. */
1821 it->pixel_width = 0; 1903 it->pixel_width = 0;
1822 it->nglyphs = 0; 1904 it->nglyphs = 0;
1823 it->ascent = it->phys_ascent = font->ascent; 1905 it->ascent = it->phys_ascent = font->ascent + boff;
1824 it->descent = it->phys_descent = font->descent; 1906 it->descent = it->phys_descent = font->descent - boff;
1825 1907
1826 if (face->box != FACE_NO_BOX) 1908 if (face->box != FACE_NO_BOX)
1827 { 1909 {
1828 int thick = face->box_line_width; 1910 int thick = face->box_line_width;
1829 it->ascent += thick; 1911 it->ascent += thick;
1838 + it->continuation_lines_width); 1920 + it->continuation_lines_width);
1839 int next_tab_x = ((1 + x + tab_width - 1) / tab_width) * tab_width; 1921 int next_tab_x = ((1 + x + tab_width - 1) / tab_width) * tab_width;
1840 1922
1841 it->pixel_width = next_tab_x - x; 1923 it->pixel_width = next_tab_x - x;
1842 it->nglyphs = 1; 1924 it->nglyphs = 1;
1843 it->ascent = it->phys_ascent = font->ascent; 1925 it->ascent = it->phys_ascent = font->ascent + boff;
1844 it->descent = it->phys_descent = font->descent; 1926 it->descent = it->phys_descent = font->descent - boff;
1845 1927
1846 if (it->glyph_row) 1928 if (it->glyph_row)
1847 { 1929 {
1848 double ascent = (double) it->ascent / (it->ascent + it->descent); 1930 double ascent = (double) it->ascent / (it->ascent + it->descent);
1849 x_append_stretch_glyph (it, it->object, it->pixel_width, 1931 x_append_stretch_glyph (it, it->object, it->pixel_width,
1852 } 1934 }
1853 else 1935 else
1854 { 1936 {
1855 /* A multi-byte character. Assume that the display width of the 1937 /* A multi-byte character. Assume that the display width of the
1856 character is the width of the character multiplied by the 1938 character is the width of the character multiplied by the
1857 width of the font. There has to be better support for 1939 width of the font. */
1858 variable sizes in cmpchar_info to do anything better than 1940
1859 that. 1941 /* If we found a font, this font should give us the right
1860 1942 metrics. If we didn't find a font, use the frame's
1861 Note: composite characters are represented as one glyph in 1943 default font and calculate the width of the character
1862 the glyph matrix. There are no padding glyphs. */ 1944 from the charset width; this is what old redisplay code
1863 if (it->charset == CHARSET_COMPOSITION) 1945 did. */
1864 { 1946 pcm = x_per_char_metric (font, &char2b);
1865 struct cmpchar_info *cmpcharp; 1947 it->pixel_width = pcm->width;
1866 int idx; 1948 if (font_not_found_p)
1867 1949 it->pixel_width *= CHARSET_WIDTH (it->charset);
1868 idx = COMPOSITE_CHAR_ID (it->char_to_display); 1950 it->nglyphs = 1;
1869 cmpcharp = cmpchar_table[idx]; 1951 it->ascent = font->ascent + boff;
1870 it->pixel_width = font->max_bounds.width * cmpcharp->width; 1952 it->descent = font->descent - boff;
1871 1953 it->phys_ascent = pcm->ascent + boff;
1872 /* There are no padding glyphs, so there is only one glyph 1954 it->phys_descent = pcm->descent - boff;
1873 to produce for the composite char. Important is that 1955 if (it->glyph_row
1874 pixel_width, ascent and descent are the values of what is 1956 && (pcm->lbearing < 0
1875 drawn by draw_glyphs. */ 1957 || pcm->rbearing > pcm->width))
1876 it->nglyphs = 1; 1958 it->glyph_row->contains_overlapping_glyphs_p = 1;
1877
1878 /* These settings may not be correct. We must have more
1879 information in cmpcharp to do the correct setting. */
1880 it->ascent = font->ascent;
1881 it->descent = font->descent;
1882 it->phys_ascent = font->max_bounds.ascent;
1883 it->phys_descent = font->max_bounds.descent;
1884 }
1885 else
1886 {
1887 /* If we found a font, this font should give us the right
1888 metrics. If we didn't find a font, use the frame's
1889 default font and calculate the width of the character
1890 from the charset width; this is what old redisplay code
1891 did. */
1892 pcm = x_per_char_metric (font, &char2b);
1893 it->pixel_width = pcm->width;
1894 if (font_not_found_p)
1895 it->pixel_width *= CHARSET_WIDTH (it->charset);
1896 it->nglyphs = 1;
1897 it->ascent = font->ascent;
1898 it->descent = font->descent;
1899 it->phys_ascent = pcm->ascent;
1900 it->phys_descent = pcm->descent;
1901 if (it->glyph_row
1902 && (pcm->lbearing < 0
1903 || pcm->rbearing > pcm->width))
1904 it->glyph_row->contains_overlapping_glyphs_p = 1;
1905 }
1906 1959
1907 if (face->box != FACE_NO_BOX) 1960 if (face->box != FACE_NO_BOX)
1908 { 1961 {
1909 int thick = face->box_line_width; 1962 int thick = face->box_line_width;
1910 it->ascent += thick; 1963 it->ascent += thick;
1925 1978
1926 if (it->glyph_row) 1979 if (it->glyph_row)
1927 x_append_glyph (it); 1980 x_append_glyph (it);
1928 } 1981 }
1929 } 1982 }
1983 else if (it->what == IT_COMPOSITION)
1984 {
1985 /* Note: A composition is represented as one glyph in the
1986 glyph matrix. There are no padding glyphs. */
1987 XChar2b char2b;
1988 XFontStruct *font;
1989 struct face *face;
1990 XCharStruct *pcm;
1991 int font_not_found_p;
1992 struct font_info *font_info;
1993 int boff; /* baseline offset */
1994 struct composition *cmp = composition_table[it->cmp_id];
1995
1996 /* Maybe translate single-byte characters to multibyte. */
1997 it->char_to_display = it->c;
1998 if (unibyte_display_via_language_environment
1999 && SINGLE_BYTE_CHAR_P (it->c)
2000 && (it->c >= 0240
2001 || (it->c >= 0200
2002 && !NILP (Vnonascii_translation_table))))
2003 {
2004 it->char_to_display = unibyte_char_to_multibyte (it->c);
2005 it->charset = CHAR_CHARSET (it->char_to_display);
2006 }
2007
2008 /* Get face and font to use. Encode IT->char_to_display. */
2009 face = x_get_char_face_and_encoding (it->f, it->char_to_display,
2010 it->face_id, &char2b,
2011 it->multibyte_p);
2012 font = face->font;
2013
2014 /* When no suitable font found, use the default font. */
2015 font_not_found_p = font == NULL;
2016 if (font_not_found_p)
2017 {
2018 font = FRAME_FONT (it->f);
2019 boff = it->f->output_data.x->baseline_offset;
2020 font_info = NULL;
2021 }
2022 else
2023 {
2024 font_info = FONT_INFO_FROM_ID (it->f, face->font_info_id);
2025 boff = font_info->baseline_offset;
2026 if (font_info->vertical_centering)
2027 boff = VCENTER_BASELINE_OFFSET (font, it->f) - boff;
2028 }
2029
2030 /* There are no padding glyphs, so there is only one glyph to
2031 produce for the composition. Important is that pixel_width,
2032 ascent and descent are the values of what is drawn by
2033 draw_glyphs (i.e. the values of the overall glyphs composed). */
2034 it->nglyphs = 1;
2035
2036 /* If we have not yet calculated pixel size data of glyphs of
2037 the composition for the current face font, calculate them
2038 now. Theoretically, we have to check all fonts for the
2039 glyphs, but that requires much time and memory space. So,
2040 here we check only the font of the first glyph. This leads
2041 to incorrect display very rarely, and C-l (recenter) can
2042 correct the display anyway. */
2043 if (cmp->font != (void *) font)
2044 {
2045 /* Ascent and descent of the font of the first character of
2046 this composition (adjusted by baseline offset). Ascent
2047 and descent of overall glyphs should not be less than
2048 them respectively. */
2049 int font_ascent = font->ascent + boff;
2050 int font_descent = font->descent - boff;
2051 /* Bounding box of the overall glyphs. */
2052 int leftmost, rightmost, lowest, highest;
2053 int i;
2054
2055 cmp->font = (void *) font;
2056
2057 /* Initialize the bounding box. */
2058 pcm = x_per_char_metric (font, &char2b);
2059 leftmost = 0;
2060 rightmost = pcm->width;
2061 lowest = - pcm->descent + boff;
2062 highest = pcm->ascent + boff;
2063 if (font_info
2064 && font_info->default_ascent
2065 && CHAR_TABLE_P (Vuse_default_ascent)
2066 && !NILP (Faref (Vuse_default_ascent,
2067 make_number (it->char_to_display))))
2068 highest = font_info->default_ascent + boff;
2069
2070 /* Draw the first glyph at the normal position. It may be
2071 shifted to right later if some other glyphs are drawn at
2072 the left. */
2073 cmp->offsets[0] = 0;
2074 cmp->offsets[1] = boff;
2075
2076 /* Set cmp->offsets for the remaining glyphs. */
2077 for (i = 1; i < cmp->glyph_len; i++)
2078 {
2079 int left, right, btm, top;
2080 int ch = COMPOSITION_GLYPH (cmp, i);
2081
2082 face = x_get_char_face_and_encoding (it->f, ch,
2083 it->face_id, &char2b,
2084 it->multibyte_p);
2085 font = face->font;
2086 if (font == NULL)
2087 {
2088 font = FRAME_FONT (it->f);
2089 boff = it->f->output_data.x->baseline_offset;
2090 font_info = NULL;
2091 }
2092 else
2093 {
2094 font_info
2095 = FONT_INFO_FROM_ID (it->f, face->font_info_id);
2096 boff = font_info->baseline_offset;
2097 if (font_info->vertical_centering)
2098 boff = VCENTER_BASELINE_OFFSET (font, it->f) - boff;
2099 }
2100
2101 pcm = x_per_char_metric (font, &char2b);
2102
2103 if (cmp->method != COMPOSITION_WITH_RULE_ALTCHARS)
2104 {
2105 /* Relative composition with or without
2106 alternate chars. */
2107 left = (leftmost + rightmost - pcm->width) / 2;
2108 btm = - pcm->descent + boff;
2109 if (font_info && font_info->relative_compose
2110 && (! CHAR_TABLE_P (Vignore_relative_composition)
2111 || NILP (Faref (Vignore_relative_composition,
2112 make_number (ch)))))
2113 {
2114
2115 if (- pcm->descent
2116 >= font_info->relative_compose)
2117 /* One extra pixel between two glyphs. */
2118 btm = highest + 1;
2119 else if (pcm->ascent <= 0)
2120 /* One extra pixel between two glyphs. */
2121 btm = lowest - 1 - pcm->ascent - pcm->descent;
2122 }
2123 }
2124 else
2125 {
2126 /* A composition rule is specified by an integer
2127 value that encodes global and new reference
2128 points (GREF and NREF). GREF and NREF are
2129 specified by numbers as below:
2130
2131 0---1---2 -- ascent
2132 | |
2133 | |
2134 | |
2135 9--10--11 -- center
2136 | |
2137 ---3---4---5--- baseline
2138 | |
2139 6---7---8 -- descent
2140 */
2141 int rule = COMPOSITION_RULE (cmp, i);
2142 int gref, nref, grefx, grefy, nrefx, nrefy;
2143
2144 COMPOSITION_DECODE_RULE (rule, gref, nref);
2145 grefx = gref % 3, nrefx = nref % 3;
2146 grefy = gref / 3, nrefy = nref / 3;
2147
2148 left = (leftmost
2149 + grefx * (rightmost - leftmost) / 2
2150 - nrefx * pcm->width / 2);
2151 btm = ((grefy == 0 ? highest
2152 : grefy == 1 ? 0
2153 : grefy == 2 ? lowest
2154 : (highest + lowest) / 2)
2155 - (nrefy == 0 ? pcm->ascent + pcm->descent
2156 : nrefy == 1 ? pcm->descent - boff
2157 : nrefy == 2 ? 0
2158 : (pcm->ascent + pcm->descent) / 2));
2159 }
2160
2161 cmp->offsets[i * 2] = left;
2162 cmp->offsets[i * 2 + 1] = btm + pcm->descent;
2163
2164 /* Update the bounding box of the overall glyphs. */
2165 right = left + pcm->width;
2166 top = btm + pcm->descent + pcm->ascent;
2167 if (left < leftmost)
2168 leftmost = left;
2169 if (right > rightmost)
2170 rightmost = right;
2171 if (top > highest)
2172 highest = top;
2173 if (btm < lowest)
2174 lowest = btm;
2175 }
2176
2177 /* If there are glyphs whose x-offsets are negative,
2178 shift all glyphs to the right and make all x-offsets
2179 non-negative. */
2180 if (leftmost < 0)
2181 {
2182 for (i = 0; i < cmp->glyph_len; i++)
2183 cmp->offsets[i * 2] -= leftmost;
2184 rightmost -= leftmost;
2185 }
2186
2187 cmp->pixel_width = rightmost;
2188 cmp->ascent = highest;
2189 cmp->descent = - lowest;
2190 if (cmp->ascent < font_ascent)
2191 cmp->ascent = font_ascent;
2192 if (cmp->descent < font_descent)
2193 cmp->descent = font_descent;
2194 }
2195
2196 it->pixel_width = cmp->pixel_width;
2197 it->ascent = it->phys_ascent = cmp->ascent;
2198 it->descent = it->phys_descent = cmp->descent;
2199
2200 if (face->box != FACE_NO_BOX)
2201 {
2202 int thick = face->box_line_width;
2203 it->ascent += thick;
2204 it->descent += thick;
2205
2206 if (it->start_of_box_run_p)
2207 it->pixel_width += thick;
2208 if (it->end_of_box_run_p)
2209 it->pixel_width += thick;
2210 }
2211
2212 /* If face has an overline, add the height of the overline
2213 (1 pixel) and a 1 pixel margin to the character height. */
2214 if (face->overline_p)
2215 it->ascent += 2;
2216
2217 take_vertical_position_into_account (it);
2218
2219 if (it->glyph_row)
2220 x_append_composite_glyph (it);
2221 }
1930 else if (it->what == IT_IMAGE) 2222 else if (it->what == IT_IMAGE)
1931 x_produce_image_glyph (it); 2223 x_produce_image_glyph (it);
1932 else if (it->what == IT_STRETCH) 2224 else if (it->what == IT_STRETCH)
1933 x_produce_stretch_glyph (it); 2225 x_produce_stretch_glyph (it);
1934 2226
2041 XFontStruct *font; 2333 XFontStruct *font;
2042 2334
2043 /* Font info for this string. */ 2335 /* Font info for this string. */
2044 struct font_info *font_info; 2336 struct font_info *font_info;
2045 2337
2046 /* Non-null means this string describes (part of) a composite 2338 /* Non-null means this string describes (part of) a composition.
2047 character. All characters from char2b are drawn at the same 2339 All characters from char2b are drawn composed. */
2048 x-origin in that case. */ 2340 struct composition *cmp;
2049 struct cmpchar_info *cmpcharp;
2050 2341
2051 /* Index of this glyph string's first character in the glyph 2342 /* Index of this glyph string's first character in the glyph
2052 definition of cmpcharp. If this is zero, this glyph string 2343 definition of CMP. If this is zero, this glyph string describes
2053 describes the first character of a composite character. */ 2344 the first character of a composition. */
2054 int gidx; 2345 int gidx;
2055 2346
2056 /* 1 means this glyph strings face has to be drawn to the right end 2347 /* 1 means this glyph strings face has to be drawn to the right end
2057 of the window's drawing area. */ 2348 of the window's drawing area. */
2058 unsigned extends_to_end_of_line_p : 1; 2349 unsigned extends_to_end_of_line_p : 1;
2144 static void x_set_glyph_string_clipping P_ ((struct glyph_string *)); 2435 static void x_set_glyph_string_clipping P_ ((struct glyph_string *));
2145 static void x_set_glyph_string_gc P_ ((struct glyph_string *)); 2436 static void x_set_glyph_string_gc P_ ((struct glyph_string *));
2146 static void x_draw_glyph_string_background P_ ((struct glyph_string *, 2437 static void x_draw_glyph_string_background P_ ((struct glyph_string *,
2147 int)); 2438 int));
2148 static void x_draw_glyph_string_foreground P_ ((struct glyph_string *)); 2439 static void x_draw_glyph_string_foreground P_ ((struct glyph_string *));
2440 static void x_draw_composite_glyph_string_foreground P_ ((struct glyph_string *));
2149 static void x_draw_glyph_string_box P_ ((struct glyph_string *)); 2441 static void x_draw_glyph_string_box P_ ((struct glyph_string *));
2150 static void x_draw_glyph_string P_ ((struct glyph_string *)); 2442 static void x_draw_glyph_string P_ ((struct glyph_string *));
2151 static void x_compute_glyph_string_overhangs P_ ((struct glyph_string *)); 2443 static void x_compute_glyph_string_overhangs P_ ((struct glyph_string *));
2152 static void x_set_cursor_gc P_ ((struct glyph_string *)); 2444 static void x_set_cursor_gc P_ ((struct glyph_string *));
2153 static void x_set_mode_line_face_gc P_ ((struct glyph_string *)); 2445 static void x_set_mode_line_face_gc P_ ((struct glyph_string *));
2237 struct glyph_string *s; 2529 struct glyph_string *s;
2238 { 2530 {
2239 if (s->font == FRAME_FONT (s->f) 2531 if (s->font == FRAME_FONT (s->f)
2240 && s->face->background == FRAME_BACKGROUND_PIXEL (s->f) 2532 && s->face->background == FRAME_BACKGROUND_PIXEL (s->f)
2241 && s->face->foreground == FRAME_FOREGROUND_PIXEL (s->f) 2533 && s->face->foreground == FRAME_FOREGROUND_PIXEL (s->f)
2242 && !s->cmpcharp) 2534 && !s->cmp)
2243 s->gc = s->f->output_data.x->cursor_gc; 2535 s->gc = s->f->output_data.x->cursor_gc;
2244 else 2536 else
2245 { 2537 {
2246 /* Cursor on non-default face: must merge. */ 2538 /* Cursor on non-default face: must merge. */
2247 XGCValues xgcv; 2539 XGCValues xgcv;
2464 XSetClipRectangles (s->display, s->gc, 0, 0, &r, 1, Unsorted); 2756 XSetClipRectangles (s->display, s->gc, 0, 0, &r, 1, Unsorted);
2465 } 2757 }
2466 2758
2467 2759
2468 /* Compute left and right overhang of glyph string S. If S is a glyph 2760 /* Compute left and right overhang of glyph string S. If S is a glyph
2469 string for a composite character, assume overhangs don't exist. */ 2761 string for a composition, assume overhangs don't exist. */
2470 2762
2471 static INLINE void 2763 static INLINE void
2472 x_compute_glyph_string_overhangs (s) 2764 x_compute_glyph_string_overhangs (s)
2473 struct glyph_string *s; 2765 struct glyph_string *s;
2474 { 2766 {
2475 if (s->cmpcharp == NULL 2767 if (s->cmp == NULL
2476 && s->first_glyph->type == CHAR_GLYPH) 2768 && s->first_glyph->type == CHAR_GLYPH)
2477 { 2769 {
2478 XCharStruct cs; 2770 XCharStruct cs;
2479 int direction, font_ascent, font_descent; 2771 int direction, font_ascent, font_descent;
2480 XTextExtents16 (s->font, s->char2b, s->nchars, &direction, 2772 XTextExtents16 (s->font, s->char2b, s->nchars, &direction,
2517 } 2809 }
2518 } 2810 }
2519 2811
2520 2812
2521 /* Set *LEFT and *RIGHT to the left and right overhang of GLYPH on 2813 /* Set *LEFT and *RIGHT to the left and right overhang of GLYPH on
2522 frame F. Overhangs of glyphs other than type CHAR_GLYPH or of 2814 frame F. Overhangs of glyphs other than type CHAR_GLYPH are
2523 character glyphs for composite characters are assumed to be zero. */ 2815 assumed to be zero. */
2524 2816
2525 static void 2817 static void
2526 x_get_glyph_overhangs (glyph, f, left, right) 2818 x_get_glyph_overhangs (glyph, f, left, right)
2527 struct glyph *glyph; 2819 struct glyph *glyph;
2528 struct frame *f; 2820 struct frame *f;
2530 { 2822 {
2531 int c; 2823 int c;
2532 2824
2533 *left = *right = 0; 2825 *left = *right = 0;
2534 2826
2535 if (glyph->type == CHAR_GLYPH 2827 if (glyph->type == CHAR_GLYPH)
2536 && (c = glyph->u.ch.code,
2537 CHAR_CHARSET (c) != CHARSET_COMPOSITION))
2538 { 2828 {
2539 XFontStruct *font; 2829 XFontStruct *font;
2540 struct face *face; 2830 struct face *face;
2541 struct font_info *font_info; 2831 struct font_info *font_info;
2542 XChar2b char2b; 2832 XChar2b char2b;
2624 2914
2625 if (s->right_overhang) 2915 if (s->right_overhang)
2626 { 2916 {
2627 int x = 0, i; 2917 int x = 0, i;
2628 struct glyph *glyphs = s->row->glyphs[s->area]; 2918 struct glyph *glyphs = s->row->glyphs[s->area];
2629 int first = (s->first_glyph - glyphs) + (s->cmpcharp ? 1 : s->nchars); 2919 int first = (s->first_glyph - glyphs) + (s->cmp ? 1 : s->nchars);
2630 int end = s->row->used[s->area]; 2920 int end = s->row->used[s->area];
2631 2921
2632 for (i = first; i < end && s->right_overhang > x; ++i) 2922 for (i = first; i < end && s->right_overhang > x; ++i)
2633 x += glyphs[i].pixel_width; 2923 x += glyphs[i].pixel_width;
2634 2924
2648 struct glyph_string *s; 2938 struct glyph_string *s;
2649 { 2939 {
2650 int i, k, x; 2940 int i, k, x;
2651 int end = s->row->used[s->area]; 2941 int end = s->row->used[s->area];
2652 struct glyph *glyphs = s->row->glyphs[s->area]; 2942 struct glyph *glyphs = s->row->glyphs[s->area];
2653 int first = (s->first_glyph - glyphs) + (s->cmpcharp ? 1 : s->nchars); 2943 int first = (s->first_glyph - glyphs) + (s->cmp ? 1 : s->nchars);
2654 2944
2655 k = -1; 2945 k = -1;
2656 x = 0; 2946 x = 0;
2657 for (i = first; i < end; ++i) 2947 for (i = first; i < end; ++i)
2658 { 2948 {
2683 2973
2684 2974
2685 /* Draw the background of glyph_string S. If S->background_filled_p 2975 /* Draw the background of glyph_string S. If S->background_filled_p
2686 is non-zero don't draw it. FORCE_P non-zero means draw the 2976 is non-zero don't draw it. FORCE_P non-zero means draw the
2687 background even if it wouldn't be drawn normally. This is used 2977 background even if it wouldn't be drawn normally. This is used
2688 when a string preceding S draws into the background of S. */ 2978 when a string preceding S draws into the background of S, or S
2979 contains the first component of a composition. */
2689 2980
2690 static void 2981 static void
2691 x_draw_glyph_string_background (s, force_p) 2982 x_draw_glyph_string_background (s, force_p)
2692 struct glyph_string *s; 2983 struct glyph_string *s;
2693 int force_p; 2984 int force_p;
2694 { 2985 {
2695 /* Nothing to do if background has already been drawn or if it 2986 /* Nothing to do if background has already been drawn or if it
2696 shouldn't be drawn in the first place. */ 2987 shouldn't be drawn in the first place. */
2697 if (!s->background_filled_p) 2988 if (!s->background_filled_p)
2698 { 2989 {
2699 if (s->cmpcharp 2990 if (s->stippled_p)
2700 && s->gidx > 0
2701 && !s->font_not_found_p
2702 && !s->extends_to_end_of_line_p)
2703 {
2704 /* Don't draw background for glyphs of a composite
2705 characters, except for the first one. */
2706 s->background_filled_p = 1;
2707 }
2708 else if (s->stippled_p)
2709 { 2991 {
2710 /* Fill background with a stipple pattern. */ 2992 /* Fill background with a stipple pattern. */
2711 XSetFillStyle (s->display, s->gc, FillOpaqueStippled); 2993 XSetFillStyle (s->display, s->gc, FillOpaqueStippled);
2712 XFillRectangle (s->display, s->window, s->gc, s->x, 2994 XFillRectangle (s->display, s->window, s->gc, s->x,
2713 s->y + s->face->box_line_width, 2995 s->y + s->face->box_line_width,
2717 s->background_filled_p = 1; 2999 s->background_filled_p = 1;
2718 } 3000 }
2719 else if (FONT_HEIGHT (s->font) < s->height - 2 * s->face->box_line_width 3001 else if (FONT_HEIGHT (s->font) < s->height - 2 * s->face->box_line_width
2720 || s->font_not_found_p 3002 || s->font_not_found_p
2721 || s->extends_to_end_of_line_p 3003 || s->extends_to_end_of_line_p
2722 || s->cmpcharp
2723 || force_p) 3004 || force_p)
2724 { 3005 {
2725 x_clear_glyph_string_rect (s, s->x, s->y + s->face->box_line_width, 3006 x_clear_glyph_string_rect (s, s->x, s->y + s->face->box_line_width,
2726 s->background_width, 3007 s->background_width,
2727 s->height - 2 * s->face->box_line_width); 3008 s->height - 2 * s->face->box_line_width);
2745 && s->first_glyph->left_box_line_p) 3026 && s->first_glyph->left_box_line_p)
2746 x = s->x + s->face->box_line_width; 3027 x = s->x + s->face->box_line_width;
2747 else 3028 else
2748 x = s->x; 3029 x = s->x;
2749 3030
2750 if (s->cmpcharp == NULL) 3031 /* Draw characters of S as rectangles if S's font could not be
2751 { 3032 loaded. */
2752 /* Not a composite character. Draw characters of S as 3033 if (s->font_not_found_p)
2753 rectangles if S's font could not be loaded. */ 3034 {
2754 if (s->font_not_found_p) 3035 for (i = 0; i < s->nchars; ++i)
2755 { 3036 {
2756 for (i = 0; i < s->nchars; ++i) 3037 struct glyph *g = s->first_glyph + i;
2757 { 3038 XDrawRectangle (s->display, s->window,
2758 struct glyph *g = s->first_glyph + i; 3039 s->gc, x, s->y, g->pixel_width - 1,
2759 XDrawRectangle (s->display, s->window, 3040 s->height - 1);
2760 s->gc, x, s->y, g->pixel_width - 1, 3041 x += g->pixel_width;
2761 s->height - 1); 3042 }
2762 x += g->pixel_width; 3043 }
2763 } 3044 else
3045 {
3046 char *char1b = (char *) s->char2b;
3047 int boff = s->font_info->baseline_offset;
3048
3049 if (s->font_info->vertical_centering)
3050 boff = VCENTER_BASELINE_OFFSET (s->font, s->f) - boff;
3051
3052 /* If we can use 8-bit functions, condense S->char2b. */
3053 if (!s->two_byte_p)
3054 for (i = 0; i < s->nchars; ++i)
3055 char1b[i] = s->char2b[i].byte2;
3056
3057 /* Draw text with XDrawString if background has already been
3058 filled. Otherwise, use XDrawImageString. (Note that
3059 XDrawImageString is usually faster than XDrawString.) Always
3060 use XDrawImageString when drawing the cursor so that there is
3061 no chance that characters under a box cursor are invisible. */
3062 if (s->for_overlaps_p
3063 || (s->background_filled_p && s->hl != DRAW_CURSOR))
3064 {
3065 /* Draw characters with 16-bit or 8-bit functions. */
3066 if (s->two_byte_p)
3067 XDrawString16 (s->display, s->window, s->gc, x,
3068 s->ybase - boff, s->char2b, s->nchars);
3069 else
3070 XDrawString (s->display, s->window, s->gc, x,
3071 s->ybase - boff, char1b, s->nchars);
2764 } 3072 }
2765 else 3073 else
2766 { 3074 {
2767 char *char1b = (char *) s->char2b; 3075 if (s->two_byte_p)
2768 3076 XDrawImageString16 (s->display, s->window, s->gc, x,
2769 /* If we can use 8-bit functions, condense S->char2b. */ 3077 s->ybase - boff, s->char2b, s->nchars);
2770 if (!s->two_byte_p)
2771 for (i = 0; i < s->nchars; ++i)
2772 char1b[i] = s->char2b[i].byte2;
2773
2774 /* Draw text with XDrawString if background has already been
2775 filled. Otherwise, use XDrawImageString. (Note that
2776 XDrawImageString is usually faster than XDrawString.)
2777 Always use XDrawImageString when drawing the cursor so
2778 that there is no chance that characters under a box
2779 cursor are invisible. */
2780 if (s->for_overlaps_p
2781 || (s->background_filled_p && s->hl != DRAW_CURSOR))
2782 {
2783 /* Draw characters with 16-bit or 8-bit functions. */
2784 if (s->two_byte_p)
2785 XDrawString16 (s->display, s->window, s->gc, x, s->ybase,
2786 s->char2b, s->nchars);
2787 else
2788 XDrawString (s->display, s->window, s->gc, x, s->ybase,
2789 char1b, s->nchars);
2790 }
2791 else 3078 else
2792 { 3079 XDrawImageString (s->display, s->window, s->gc, x,
2793 if (s->two_byte_p) 3080 s->ybase - boff, char1b, s->nchars);
2794 XDrawImageString16 (s->display, s->window, s->gc,
2795 x, s->ybase, s->char2b, s->nchars);
2796 else
2797 XDrawImageString (s->display, s->window, s->gc,
2798 x, s->ybase, char1b, s->nchars);
2799 }
2800 } 3081 }
2801 } 3082 }
3083 }
3084
3085 /* Draw the foreground of composite glyph string S. */
3086
3087 static void
3088 x_draw_composite_glyph_string_foreground (s)
3089 struct glyph_string *s;
3090 {
3091 int i, x;
3092
3093 /* If first glyph of S has a left box line, start drawing the text
3094 of S to the right of that box line. */
3095 if (s->face->box != FACE_NO_BOX
3096 && s->first_glyph->left_box_line_p)
3097 x = s->x + s->face->box_line_width;
2802 else 3098 else
2803 { 3099 x = s->x;
2804 /* S is a glyph string for a composite character. S->gidx is the 3100
2805 index of the first character drawn in the vector 3101 /* S is a glyph string for a composition. S->gidx is the index of
2806 S->cmpcharp->glyph. S->gidx == 0 means we are drawing the 3102 the first character drawn for glyphs of this composition.
2807 very first component character of a composite char. */ 3103 S->gidx == 0 means we are drawing the very first character of
2808 3104 this composition. */
2809 /* Draw a single rectangle for the composite character if S's 3105
2810 font could not be loaded. */ 3106 /* Draw a rectangle for the composition if the font for the very
2811 if (s->font_not_found_p && s->gidx == 0) 3107 first character of the composition could not be loaded. */
3108 if (s->font_not_found_p)
3109 {
3110 if (s->gidx == 0)
2812 XDrawRectangle (s->display, s->window, s->gc, x, s->y, 3111 XDrawRectangle (s->display, s->window, s->gc, x, s->y,
2813 s->width - 1, s->height - 1); 3112 s->width - 1, s->height - 1);
2814 else 3113 }
2815 { 3114 else
2816 XCharStruct *pcm; 3115 {
2817 int relative_compose, default_ascent, i; 3116 for (i = 0; i < s->nchars; i++, ++s->gidx)
2818 int highest = 0, lowest = 0; 3117 XDrawString16 (s->display, s->window, s->gc,
2819 3118 x + s->cmp->offsets[s->gidx * 2],
2820 /* The value of font_info my be null if we couldn't find it 3119 s->ybase - s->cmp->offsets[s->gidx * 2 + 1],
2821 in x_get_char_face_and_encoding. */ 3120 s->char2b + i, 1);
2822 if (s->cmpcharp->cmp_rule == NULL && s->font_info)
2823 {
2824 relative_compose = s->font_info->relative_compose;
2825 default_ascent = s->font_info->default_ascent;
2826 }
2827 else
2828 relative_compose = default_ascent = 0;
2829
2830 if ((s->cmpcharp->cmp_rule || relative_compose)
2831 && s->gidx == 0)
2832 {
2833 /* This is the first character. Initialize variables.
2834 Highest is the highest position of glyphs ever
2835 written, lowest the lowest position. */
2836 int x_offset = 0;
2837 int first_ch = s->first_glyph->u.ch.code;
2838
2839 if (default_ascent
2840 && CHAR_TABLE_P (Vuse_default_ascent)
2841 && !NILP (Faref (Vuse_default_ascent, first_ch)))
2842 {
2843 highest = default_ascent;
2844 lowest = 0;
2845 }
2846 else
2847 {
2848 pcm = PER_CHAR_METRIC (s->font, s->char2b);
2849 highest = pcm->ascent + 1;
2850 lowest = - pcm->descent;
2851 }
2852
2853 if (s->cmpcharp->cmp_rule)
2854 x_offset = (s->cmpcharp->col_offset[0]
2855 * FONT_WIDTH (s->f->output_data.x->font));
2856
2857 /* Draw the first character at the normal position. */
2858 XDrawString16 (s->display, s->window, s->gc,
2859 x + x_offset,
2860 s->ybase, s->char2b, 1);
2861 i = 1;
2862 ++s->gidx;
2863 }
2864 else
2865 i = 0;
2866
2867 for (; i < s->nchars; i++, ++s->gidx)
2868 {
2869 int x_offset = 0, y_offset = 0;
2870
2871 if (relative_compose)
2872 {
2873 pcm = PER_CHAR_METRIC (s->font, s->char2b + i);
2874 if (NILP (Vignore_relative_composition)
2875 || NILP (Faref (Vignore_relative_composition,
2876 make_number (s->cmpcharp->glyph[s->gidx]))))
2877 {
2878 if (- pcm->descent >= relative_compose)
2879 {
2880 /* Draw above the current glyphs. */
2881 y_offset = highest + pcm->descent;
2882 highest += pcm->ascent + pcm->descent;
2883 }
2884 else if (pcm->ascent <= 0)
2885 {
2886 /* Draw beneath the current glyphs. */
2887 y_offset = lowest - pcm->ascent;
2888 lowest -= pcm->ascent + pcm->descent;
2889 }
2890 }
2891 else
2892 {
2893 /* Draw the glyph at normal position. If
2894 it sticks out of HIGHEST or LOWEST,
2895 update them appropriately. */
2896 if (pcm->ascent > highest)
2897 highest = pcm->ascent;
2898 else if (- pcm->descent < lowest)
2899 lowest = - pcm->descent;
2900 }
2901 }
2902 else if (s->cmpcharp->cmp_rule)
2903 {
2904 int gref = (s->cmpcharp->cmp_rule[s->gidx] - 0xA0) / 9;
2905 int nref = (s->cmpcharp->cmp_rule[s->gidx] - 0xA0) % 9;
2906 int bottom, top;
2907
2908 /* Re-encode GREF and NREF so that they specify
2909 only Y-axis information:
2910 0:top, 1:base, 2:bottom, 3:center */
2911 gref = gref / 3 + (gref == 4) * 2;
2912 nref = nref / 3 + (nref == 4) * 2;
2913
2914 pcm = PER_CHAR_METRIC (s->font, s->char2b + i);
2915 bottom = ((gref == 0 ? highest : gref == 1 ? 0
2916 : gref == 2 ? lowest
2917 : (highest + lowest) / 2)
2918 - (nref == 0 ? pcm->ascent + pcm->descent
2919 : nref == 1 ? pcm->descent : nref == 2 ? 0
2920 : (pcm->ascent + pcm->descent) / 2));
2921 top = bottom + (pcm->ascent + pcm->descent);
2922 if (top > highest)
2923 highest = top;
2924 if (bottom < lowest)
2925 lowest = bottom;
2926 y_offset = bottom + pcm->descent;
2927 x_offset = (s->cmpcharp->col_offset[s->gidx]
2928 * FONT_WIDTH (FRAME_FONT (s->f)));
2929 }
2930
2931 XDrawString16 (s->display, s->window, s->gc,
2932 x + x_offset, s->ybase - y_offset,
2933 s->char2b + i, 1);
2934 }
2935 }
2936 } 3121 }
2937 } 3122 }
2938 3123
2939 3124
2940 #ifdef USE_X_TOOLKIT 3125 #ifdef USE_X_TOOLKIT
3313 if (FRAME_HAS_VERTICAL_SCROLL_BARS_ON_RIGHT (s->f)) 3498 if (FRAME_HAS_VERTICAL_SCROLL_BARS_ON_RIGHT (s->f))
3314 last_x += FRAME_SCROLL_BAR_WIDTH (s->f) * CANON_X_UNIT (s->f); 3499 last_x += FRAME_SCROLL_BAR_WIDTH (s->f) * CANON_X_UNIT (s->f);
3315 } 3500 }
3316 3501
3317 /* The glyph that may have a right box line. */ 3502 /* The glyph that may have a right box line. */
3318 last_glyph = (s->cmpcharp || s->img 3503 last_glyph = (s->cmp || s->img
3319 ? s->first_glyph 3504 ? s->first_glyph
3320 : s->first_glyph + s->nchars - 1); 3505 : s->first_glyph + s->nchars - 1);
3321 3506
3322 width = s->face->box_line_width; 3507 width = s->face->box_line_width;
3323 raised_p = s->face->box == FACE_RAISED_BOX; 3508 raised_p = s->face->box == FACE_RAISED_BOX;
3772 else 3957 else
3773 x_draw_glyph_string_background (s, 0); 3958 x_draw_glyph_string_background (s, 0);
3774 x_draw_glyph_string_foreground (s); 3959 x_draw_glyph_string_foreground (s);
3775 break; 3960 break;
3776 3961
3962 case COMPOSITE_GLYPH:
3963 if (s->for_overlaps_p || s->gidx > 0)
3964 s->background_filled_p = 1;
3965 else
3966 x_draw_glyph_string_background (s, 1);
3967 x_draw_composite_glyph_string_foreground (s);
3968 break;
3969
3777 default: 3970 default:
3778 abort (); 3971 abort ();
3779 } 3972 }
3780 3973
3781 if (!s->for_overlaps_p) 3974 if (!s->for_overlaps_p)
3851 /* Reset clipping. */ 4044 /* Reset clipping. */
3852 XSetClipMask (s->display, s->gc, None); 4045 XSetClipMask (s->display, s->gc, None);
3853 } 4046 }
3854 4047
3855 4048
3856 /* A work-list entry used during the construction of glyph_string 4049 static int x_fill_composite_glyph_string P_ ((struct glyph_string *,
3857 structures for a composite character. */ 4050 struct face **, int));
3858 4051
3859 struct work 4052
3860 { 4053 /* Load glyph string S with a composition components specified by S->cmp.
3861 /* Pointer to composite char info defining has the composite 4054 FACES is an array of faces for all components of this composition.
3862 character is drawn. */ 4055 S->gidx is the index of the first component for S.
3863 struct cmpchar_info *cmpcharp; 4056 OVERLAPS_P non-zero means S should draw the foreground only, and
3864 4057 use its lines physical height for clipping.
3865 /* Start index in compcharp->glyph[]. */ 4058
3866 int gidx; 4059 Value is the index of a component not in S. */
3867 4060
3868 /* Next in stack. */ 4061 static int
3869 struct work *next; 4062 x_fill_composite_glyph_string (s, faces, overlaps_p)
3870 };
3871
3872
3873 static void x_fill_composite_glyph_string P_ ((struct glyph_string *,
3874 int, struct work **,
3875 struct work **, int));
3876
3877
3878 /* Load glyph string S with information from the top of *STACK for a
3879 composite character. FACE_ID is the id of the face in which S is
3880 drawn. *NEW is a pointer to a struct work not on the stack, that
3881 can be used if this function needs to push a new structure on the
3882 stack. If it uses it, *NEW is set to null. OVERLAPS_P non-zero
3883 means S should draw the foreground only, and use its lines physical
3884 height for clipping. */
3885
3886 static void
3887 x_fill_composite_glyph_string (s, face_id, stack, new, overlaps_p)
3888 struct glyph_string *s; 4063 struct glyph_string *s;
3889 int face_id; 4064 struct face **faces;
3890 struct work **stack, **new;
3891 int overlaps_p; 4065 int overlaps_p;
3892 { 4066 {
3893 int i, c; 4067 int i;
3894 struct work *work; 4068
3895 4069 xassert (s);
3896 xassert (s && *new && *stack); 4070
3897 4071 s->for_overlaps_p = overlaps_p;
3898 s->for_overlaps_p = 1;
3899 4072
3900 /* Pop the work stack. */ 4073 s->face = faces[s->gidx];
3901 work = *stack; 4074 s->font = s->face->font;
3902 *stack = work->next; 4075 s->font_info = FONT_INFO_FROM_ID (s->f, s->face->font_info_id);
3903 4076
3904 /* For all glyphs of cmpcharp->glyph, starting at the offset 4077 /* For all glyphs of this composition, starting at the offset
3905 work->offset, until we reach the end of the definition or 4078 S->gidx, until we reach the end of the definition or encounter a
3906 encounter another composite char, get the font and face to use, 4079 glyph that requires the different face, add it to S. */
3907 and add it to S. */ 4080 ++s->nchars;
3908 for (i = work->gidx; i < work->cmpcharp->glyph_len; ++i) 4081 for (i = s->gidx + 1; i < s->cmp->glyph_len && faces[i] == s->face; ++i)
3909 { 4082 ++s->nchars;
3910 c = FAST_GLYPH_CHAR (work->cmpcharp->glyph[i]); 4083
3911 if (CHAR_CHARSET (c) == CHARSET_COMPOSITION) 4084 /* All glyph strings for the same composition has the same width,
3912 break; 4085 i.e. the width set for the first component of the composition. */
3913 s->face = x_get_char_face_and_encoding (s->f, c, face_id, 4086
3914 s->char2b + s->nchars, 1);
3915 s->font = s->face->font;
3916 s->font_info = FONT_INFO_FROM_ID (s->f, s->face->font_info_id);
3917 ++s->nchars;
3918 }
3919
3920 /* If we find another composite char in the glyph definition of
3921 work->cmpcharp, put back the rest of the glyphs on the work
3922 stack, and make a new entry for the composite char. */
3923 if (i < work->cmpcharp->glyph_len)
3924 {
3925 /* Push back an unprocessed rest of this glyph spec. */
3926 if (i < work->cmpcharp->glyph_len - 1)
3927 {
3928 work->gidx = i + 1;
3929 work->next = *stack;
3930 *stack = work;
3931 work = *new;
3932 *new = NULL;
3933 }
3934
3935 /* Make an entry for the composite char on the work stack. */
3936 work->cmpcharp = cmpchar_table[COMPOSITE_CHAR_ID (c)];
3937 work->gidx = 0;
3938 work->next = *stack;
3939 *stack = work;
3940 }
3941
3942 /* The width of this glyph string equals the width of the first
3943 glyph. All characters are drawn at the same x-position. */
3944 s->width = s->first_glyph->pixel_width; 4087 s->width = s->first_glyph->pixel_width;
3945 4088
3946 /* If the specified font could not be loaded, use the frame's 4089 /* If the specified font could not be loaded, use the frame's
3947 default font, but record the fact that we couldn't load it in 4090 default font, but record the fact that we couldn't load it in
3948 the glyph string so that we can draw rectangles for the 4091 the glyph string so that we can draw rectangles for the
3958 4101
3959 xassert (s->face && s->face->gc); 4102 xassert (s->face && s->face->gc);
3960 4103
3961 /* This glyph string must always be drawn with 16-bit functions. */ 4104 /* This glyph string must always be drawn with 16-bit functions. */
3962 s->two_byte_p = 1; 4105 s->two_byte_p = 1;
3963 } 4106
3964 4107 return s->gidx + s->nchars;
3965 4108 }
3966 /* Load glyph string S with a sequence of non-composite characters. 4109
4110
4111 /* Load glyph string S with a sequence characters.
3967 FACE_ID is the face id of the string. START is the index of the 4112 FACE_ID is the face id of the string. START is the index of the
3968 first glyph to consider, END is the index of the last + 1. 4113 first glyph to consider, END is the index of the last + 1.
3969 OVERLAPS_P non-zero means S should draw the foreground only, and 4114 OVERLAPS_P non-zero means S should draw the foreground only, and
3970 use its lines physical height for clipping. 4115 use its lines physical height for clipping.
3971 4116
3978 int start, end, overlaps_p; 4123 int start, end, overlaps_p;
3979 { 4124 {
3980 struct glyph *glyph, *last; 4125 struct glyph *glyph, *last;
3981 int voffset; 4126 int voffset;
3982 4127
3983 xassert (s->charset != CHARSET_COMPOSITION);
3984 xassert (s->f == XFRAME (s->w->frame)); 4128 xassert (s->f == XFRAME (s->w->frame));
3985 xassert (s->nchars == 0); 4129 xassert (s->nchars == 0);
3986 xassert (start >= 0 && end > start); 4130 xassert (start >= 0 && end > start);
3987 4131
3988 s->for_overlaps_p = overlaps_p, 4132 s->for_overlaps_p = overlaps_p,
4193 \ 4337 \
4194 c = (ROW)->glyphs[AREA][START].u.ch.code; \ 4338 c = (ROW)->glyphs[AREA][START].u.ch.code; \
4195 charset = CHAR_CHARSET (c); \ 4339 charset = CHAR_CHARSET (c); \
4196 face_id = (ROW)->glyphs[AREA][START].u.ch.face_id; \ 4340 face_id = (ROW)->glyphs[AREA][START].u.ch.face_id; \
4197 \ 4341 \
4198 if (charset == CHARSET_COMPOSITION) \ 4342 s = (struct glyph_string *) alloca (sizeof *s); \
4199 { \ 4343 char2b = (XChar2b *) alloca ((END - START) * sizeof *char2b); \
4200 struct work *stack, *work, *new = NULL; \ 4344 x_init_glyph_string (s, char2b, W, ROW, AREA, START, HL); \
4201 int n = 0; \ 4345 x_append_glyph_string (&HEAD, &TAIL, s); \
4202 struct glyph_string *first_s = NULL; \ 4346 s->charset = charset; \
4203 \ 4347 s->x = (X); \
4204 /* Push an initial entry for character c on the stack. */ \ 4348 START = x_fill_glyph_string (s, face_id, START, END, \
4205 stack = NULL; \
4206 work = (struct work *) alloca (sizeof *work); \
4207 work->cmpcharp = cmpchar_table[COMPOSITE_CHAR_ID (c)]; \
4208 work->gidx = 0; \
4209 work->next = stack; \
4210 stack = work; \
4211 \
4212 /* While the stack is not empty, append glyph_strings \
4213 to head/tail for glyphs to draw. */ \
4214 while (stack) \
4215 { \
4216 s = (struct glyph_string *) alloca (sizeof *s); \
4217 char2b = (XChar2b *) alloca (stack->cmpcharp->glyph_len \
4218 * sizeof (XChar2b)); \
4219 x_init_glyph_string (s, char2b, W, ROW, AREA, START, HL); \
4220 x_append_glyph_string (&(HEAD), &(TAIL), s); \
4221 s->cmpcharp = stack->cmpcharp; \
4222 s->gidx = stack->gidx; \
4223 s->charset = charset; \
4224 s->x = (X); \
4225 \
4226 if (n == 0) \
4227 { \
4228 /* Don't draw the background except for the \
4229 first glyph string. */ \
4230 s->background_filled_p = n > 0; \
4231 first_s = s; \
4232 } \
4233 ++n; \
4234 \
4235 if (new == NULL) \
4236 new = (struct work *) alloca (sizeof *new); \
4237 x_fill_composite_glyph_string (s, face_id, &stack, \
4238 &new, OVERLAPS_P); \
4239 } \
4240 \
4241 ++START; \
4242 s = first_s; \
4243 } \
4244 else \
4245 { \
4246 s = (struct glyph_string *) alloca (sizeof *s); \
4247 char2b = (XChar2b *) alloca ((END - START) * sizeof *char2b); \
4248 x_init_glyph_string (s, char2b, W, ROW, AREA, START, HL); \
4249 x_append_glyph_string (&HEAD, &TAIL, s); \
4250 s->charset = charset; \
4251 s->x = (X); \
4252 START = x_fill_glyph_string (s, face_id, START, END, \
4253 OVERLAPS_P); \ 4349 OVERLAPS_P); \
4254 } \
4255 } \ 4350 } \
4256 while (0) 4351 while (0)
4257 4352
4353
4354 /* Add a glyph string for a composite sequence to the list of strings
4355 between HEAD and TAIL. START is the index of the first glyph in
4356 row area AREA of glyph row ROW that is part of the new glyph
4357 string. END is the index of the last glyph in that glyph row area.
4358 X is the current output position assigned to the new glyph string
4359 constructed. HL overrides that face of the glyph; e.g. it is
4360 DRAW_CURSOR if a cursor has to be drawn. LAST_X is the right-most
4361 x-position of the drawing area. */
4362
4363 #define BUILD_COMPOSITE_GLYPH_STRING(W, ROW, AREA, START, END, HEAD, \
4364 TAIL, HL, X, LAST_X, OVERLAPS_P) \
4365 do { \
4366 int cmp_id = (ROW)->glyphs[AREA][START].u.cmp.id; \
4367 int face_id = (ROW)->glyphs[AREA][START].u.cmp.face_id; \
4368 struct composition *cmp = composition_table[cmp_id]; \
4369 int glyph_len = cmp->glyph_len; \
4370 XChar2b *char2b; \
4371 struct face **faces; \
4372 struct glyph_string *first_s = NULL; \
4373 int n; \
4374 \
4375 char2b = (XChar2b *) alloca ((sizeof *char2b) * glyph_len); \
4376 faces = (struct face **) alloca ((sizeof *faces) * glyph_len); \
4377 /* At first, fill in `char2b' and `faces'. */ \
4378 for (n = 0; n < glyph_len; n++) \
4379 { \
4380 int c = FAST_GLYPH_CHAR (COMPOSITION_GLYPH (cmp, n)); \
4381 faces[n] = x_get_char_face_and_encoding (XFRAME (w->frame), c, \
4382 face_id, char2b + n, 1); \
4383 } \
4384 \
4385 /* Make glyph_strings for each glyph sequence that is drawable by \
4386 the same face, and append them to HEAD/TAIL. */ \
4387 for (n = 0; n < cmp->glyph_len;) \
4388 { \
4389 s = (struct glyph_string *) alloca (sizeof *s); \
4390 x_init_glyph_string (s, char2b + n, W, ROW, AREA, START, HL); \
4391 x_append_glyph_string (&(HEAD), &(TAIL), s); \
4392 s->cmp = cmp; \
4393 s->gidx = n; \
4394 s->charset = 0; \
4395 s->x = (X); \
4396 \
4397 if (n == 0) \
4398 first_s = s; \
4399 \
4400 n = x_fill_composite_glyph_string (s, faces, OVERLAPS_P); \
4401 } \
4402 \
4403 ++START; \
4404 s = first_s; \
4405 } while (0)
4406
4258 4407
4259 /* Build a list of glyph strings between HEAD and TAIL for the glyphs 4408 /* Build a list of glyph strings between HEAD and TAIL for the glyphs
4260 of AREA of glyph row ROW on window W between indices START and END. 4409 of AREA of glyph row ROW on window W between indices START and END.
4261 HL overrides the face for drawing glyph strings, e.g. it is 4410 HL overrides the face for drawing glyph strings, e.g. it is
4262 DRAW_CURSOR to draw a cursor. X and LAST_X are start and end 4411 DRAW_CURSOR to draw a cursor. X and LAST_X are start and end
4277 { \ 4426 { \
4278 case CHAR_GLYPH: \ 4427 case CHAR_GLYPH: \
4279 BUILD_CHAR_GLYPH_STRINGS (W, ROW, AREA, START, END, HEAD, \ 4428 BUILD_CHAR_GLYPH_STRINGS (W, ROW, AREA, START, END, HEAD, \
4280 TAIL, HL, X, LAST_X, \ 4429 TAIL, HL, X, LAST_X, \
4281 OVERLAPS_P); \ 4430 OVERLAPS_P); \
4431 break; \
4432 \
4433 case COMPOSITE_GLYPH: \
4434 BUILD_COMPOSITE_GLYPH_STRING (W, ROW, AREA, START, END, \
4435 HEAD, TAIL, HL, X, LAST_X,\
4436 OVERLAPS_P); \
4282 break; \ 4437 break; \
4283 \ 4438 \
4284 case STRETCH_GLYPH: \ 4439 case STRETCH_GLYPH: \
4285 BUILD_STRETCH_GLYPH_STRING (W, ROW, AREA, START, END, \ 4440 BUILD_STRETCH_GLYPH_STRING (W, ROW, AREA, START, END, \
4286 HEAD, TAIL, HL, X, LAST_X); \ 4441 HEAD, TAIL, HL, X, LAST_X); \
10644 10799
10645 if (!fontp) 10800 if (!fontp)
10646 return Qnil; 10801 return Qnil;
10647 10802
10648 f->output_data.x->font = (XFontStruct *) (fontp->font); 10803 f->output_data.x->font = (XFontStruct *) (fontp->font);
10649 f->output_data.x->font_baseline 10804 f->output_data.x->baseline_offset = fontp->baseline_offset;
10650 = (f->output_data.x->font->ascent + fontp->baseline_offset);
10651 f->output_data.x->fontset = -1; 10805 f->output_data.x->fontset = -1;
10652 10806
10653 /* Compute the scroll bar width in character columns. */ 10807 /* Compute the scroll bar width in character columns. */
10654 if (f->scroll_bar_pixel_width > 0) 10808 if (f->scroll_bar_pixel_width > 0)
10655 { 10809 {