diff options
| author | Kenichi Handa | 1999-12-15 00:27:21 +0000 |
|---|---|---|
| committer | Kenichi Handa | 1999-12-15 00:27:21 +0000 |
| commit | b4192550b1a21959fbe130d6cffb05fa319a711f (patch) | |
| tree | 252ef92e05f00616af101910e5ff83ed0c487886 /src | |
| parent | b6c3d034792ecdbc58adcb5e175f771580f29bfd (diff) | |
| download | emacs-b4192550b1a21959fbe130d6cffb05fa319a711f.tar.gz emacs-b4192550b1a21959fbe130d6cffb05fa319a711f.zip | |
(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.
Diffstat (limited to 'src')
| -rw-r--r-- | src/xterm.c | 944 |
1 files changed, 549 insertions, 395 deletions
diff --git a/src/xterm.c b/src/xterm.c index 270bc76c785..a144d52936b 100644 --- a/src/xterm.c +++ b/src/xterm.c | |||
| @@ -1096,6 +1096,7 @@ static struct face *x_get_char_face_and_encoding P_ ((struct frame *, 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 *)); |
| @@ -1310,9 +1311,9 @@ x_get_char_face_and_encoding (f, c, face_id, char2b, multibyte_p) | |||
| 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); |
| @@ -1444,6 +1445,42 @@ x_append_glyph (it) | |||
| 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. */ |
| @@ -1709,6 +1746,38 @@ x_produce_stretch_glyph (it) | |||
| 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 |
| @@ -1725,6 +1794,8 @@ x_produce_glyphs (it) | |||
| 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; |
| @@ -1747,7 +1818,18 @@ x_produce_glyphs (it) | |||
| 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)) |
| @@ -1758,10 +1840,10 @@ x_produce_glyphs (it) | |||
| 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 |
| @@ -1820,8 +1902,8 @@ x_produce_glyphs (it) | |||
| 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 | { |
| @@ -1840,8 +1922,8 @@ x_produce_glyphs (it) | |||
| 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 | { |
| @@ -1854,55 +1936,26 @@ x_produce_glyphs (it) | |||
| 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 | ||
| 1859 | that. | ||
| 1860 | 1940 | ||
| 1861 | Note: composite characters are represented as one glyph in | 1941 | /* If we found a font, this font should give us the right |
| 1862 | the glyph matrix. There are no padding glyphs. */ | 1942 | metrics. If we didn't find a font, use the frame's |
| 1863 | if (it->charset == CHARSET_COMPOSITION) | 1943 | default font and calculate the width of the character |
| 1864 | { | 1944 | from the charset width; this is what old redisplay code |
| 1865 | struct cmpchar_info *cmpcharp; | 1945 | did. */ |
| 1866 | int idx; | 1946 | pcm = x_per_char_metric (font, &char2b); |
| 1867 | 1947 | it->pixel_width = pcm->width; | |
| 1868 | idx = COMPOSITE_CHAR_ID (it->char_to_display); | 1948 | if (font_not_found_p) |
| 1869 | cmpcharp = cmpchar_table[idx]; | 1949 | it->pixel_width *= CHARSET_WIDTH (it->charset); |
| 1870 | it->pixel_width = font->max_bounds.width * cmpcharp->width; | 1950 | it->nglyphs = 1; |
| 1871 | 1951 | it->ascent = font->ascent + boff; | |
| 1872 | /* There are no padding glyphs, so there is only one glyph | 1952 | it->descent = font->descent - boff; |
| 1873 | to produce for the composite char. Important is that | 1953 | it->phys_ascent = pcm->ascent + boff; |
| 1874 | pixel_width, ascent and descent are the values of what is | 1954 | it->phys_descent = pcm->descent - boff; |
| 1875 | drawn by draw_glyphs. */ | 1955 | if (it->glyph_row |
| 1876 | it->nglyphs = 1; | 1956 | && (pcm->lbearing < 0 |
| 1877 | 1957 | || pcm->rbearing > pcm->width)) | |
| 1878 | /* These settings may not be correct. We must have more | 1958 | it->glyph_row->contains_overlapping_glyphs_p = 1; |
| 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 | { |
| @@ -1927,6 +1980,245 @@ x_produce_glyphs (it) | |||
| 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) |
| @@ -2043,14 +2335,13 @@ struct glyph_string | |||
| 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 |
| @@ -2146,6 +2437,7 @@ 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 *)); |
| @@ -2239,7 +2531,7 @@ x_set_cursor_gc (s) | |||
| 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 | { |
| @@ -2466,13 +2758,13 @@ x_set_glyph_string_clipping (s) | |||
| 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; |
| @@ -2519,8 +2811,8 @@ x_compute_overhangs_and_x (s, x, backward_p) | |||
| 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) |
| @@ -2532,9 +2824,7 @@ x_get_glyph_overhangs (glyph, f, left, right) | |||
| 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; |
| @@ -2626,7 +2916,7 @@ x_right_overwritten (s) | |||
| 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) |
| @@ -2650,7 +2940,7 @@ x_right_overwriting (s) | |||
| 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; |
| @@ -2685,7 +2975,8 @@ x_clear_glyph_string_rect (s, x, y, w, h) | |||
| 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) |
| @@ -2696,16 +2987,7 @@ x_draw_glyph_string_background (s, force_p) | |||
| 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); |
| @@ -2719,7 +3001,6 @@ x_draw_glyph_string_background (s, force_p) | |||
| 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, |
| @@ -2747,192 +3028,96 @@ x_draw_glyph_string_foreground (s) | |||
| 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 |
| 3032 | loaded. */ | ||
| 3033 | if (s->font_not_found_p) | ||
| 2751 | { | 3034 | { |
| 2752 | /* Not a composite character. Draw characters of S as | 3035 | for (i = 0; i < s->nchars; ++i) |
| 2753 | rectangles if S's font could not be loaded. */ | ||
| 2754 | if (s->font_not_found_p) | ||
| 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); | ||
| 2762 | x += g->pixel_width; | ||
| 2763 | } | ||
| 2764 | } | ||
| 2765 | else | ||
| 2766 | { | ||
| 2767 | char *char1b = (char *) s->char2b; | ||
| 2768 | |||
| 2769 | /* If we can use 8-bit functions, condense S->char2b. */ | ||
| 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 | ||
| 2792 | { | ||
| 2793 | if (s->two_byte_p) | ||
| 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 | } | 3042 | } |
| 2801 | } | 3043 | } |
| 2802 | else | 3044 | else |
| 2803 | { | 3045 | { |
| 2804 | /* S is a glyph string for a composite character. S->gidx is the | 3046 | char *char1b = (char *) s->char2b; |
| 2805 | index of the first character drawn in the vector | 3047 | int boff = s->font_info->baseline_offset; |
| 2806 | S->cmpcharp->glyph. S->gidx == 0 means we are drawing the | ||
| 2807 | very first component character of a composite char. */ | ||
| 2808 | 3048 | ||
| 2809 | /* Draw a single rectangle for the composite character if S's | 3049 | if (s->font_info->vertical_centering) |
| 2810 | font could not be loaded. */ | 3050 | boff = VCENTER_BASELINE_OFFSET (s->font, s->f) - boff; |
| 2811 | if (s->font_not_found_p && s->gidx == 0) | 3051 | |
| 2812 | XDrawRectangle (s->display, s->window, s->gc, x, s->y, | 3052 | /* If we can use 8-bit functions, condense S->char2b. */ |
| 2813 | s->width - 1, s->height - 1); | 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); | ||
| 3072 | } | ||
| 2814 | else | 3073 | else |
| 2815 | { | 3074 | { |
| 2816 | XCharStruct *pcm; | 3075 | if (s->two_byte_p) |
| 2817 | int relative_compose, default_ascent, i; | 3076 | XDrawImageString16 (s->display, s->window, s->gc, x, |
| 2818 | int highest = 0, lowest = 0; | 3077 | s->ybase - boff, s->char2b, s->nchars); |
| 2819 | |||
| 2820 | /* The value of font_info my be null if we couldn't find it | ||
| 2821 | in x_get_char_face_and_encoding. */ | ||
| 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 | 3078 | else |
| 2828 | relative_compose = default_ascent = 0; | 3079 | XDrawImageString (s->display, s->window, s->gc, x, |
| 3080 | s->ybase - boff, char1b, s->nchars); | ||
| 3081 | } | ||
| 3082 | } | ||
| 3083 | } | ||
| 2829 | 3084 | ||
| 2830 | if ((s->cmpcharp->cmp_rule || relative_compose) | 3085 | /* Draw the foreground of composite glyph string S. */ |
| 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 | 3086 | ||
| 2853 | if (s->cmpcharp->cmp_rule) | 3087 | static void |
| 2854 | x_offset = (s->cmpcharp->col_offset[0] | 3088 | x_draw_composite_glyph_string_foreground (s) |
| 2855 | * FONT_WIDTH (s->f->output_data.x->font)); | 3089 | struct glyph_string *s; |
| 3090 | { | ||
| 3091 | int i, x; | ||
| 2856 | 3092 | ||
| 2857 | /* Draw the first character at the normal position. */ | 3093 | /* If first glyph of S has a left box line, start drawing the text |
| 2858 | XDrawString16 (s->display, s->window, s->gc, | 3094 | of S to the right of that box line. */ |
| 2859 | x + x_offset, | 3095 | if (s->face->box != FACE_NO_BOX |
| 2860 | s->ybase, s->char2b, 1); | 3096 | && s->first_glyph->left_box_line_p) |
| 2861 | i = 1; | 3097 | x = s->x + s->face->box_line_width; |
| 2862 | ++s->gidx; | 3098 | else |
| 2863 | } | 3099 | x = s->x; |
| 2864 | else | ||
| 2865 | i = 0; | ||
| 2866 | 3100 | ||
| 2867 | for (; i < s->nchars; i++, ++s->gidx) | 3101 | /* S is a glyph string for a composition. S->gidx is the index of |
| 2868 | { | 3102 | the first character drawn for glyphs of this composition. |
| 2869 | int x_offset = 0, y_offset = 0; | 3103 | S->gidx == 0 means we are drawing the very first character of |
| 3104 | this composition. */ | ||
| 2870 | 3105 | ||
| 2871 | if (relative_compose) | 3106 | /* Draw a rectangle for the composition if the font for the very |
| 2872 | { | 3107 | first character of the composition could not be loaded. */ |
| 2873 | pcm = PER_CHAR_METRIC (s->font, s->char2b + i); | 3108 | if (s->font_not_found_p) |
| 2874 | if (NILP (Vignore_relative_composition) | 3109 | { |
| 2875 | || NILP (Faref (Vignore_relative_composition, | 3110 | if (s->gidx == 0) |
| 2876 | make_number (s->cmpcharp->glyph[s->gidx])))) | 3111 | XDrawRectangle (s->display, s->window, s->gc, x, s->y, |
| 2877 | { | 3112 | s->width - 1, s->height - 1); |
| 2878 | if (- pcm->descent >= relative_compose) | 3113 | } |
| 2879 | { | 3114 | else |
| 2880 | /* Draw above the current glyphs. */ | 3115 | { |
| 2881 | y_offset = highest + pcm->descent; | 3116 | for (i = 0; i < s->nchars; i++, ++s->gidx) |
| 2882 | highest += pcm->ascent + pcm->descent; | 3117 | XDrawString16 (s->display, s->window, s->gc, |
| 2883 | } | 3118 | x + s->cmp->offsets[s->gidx * 2], |
| 2884 | else if (pcm->ascent <= 0) | 3119 | s->ybase - s->cmp->offsets[s->gidx * 2 + 1], |
| 2885 | { | 3120 | s->char2b + i, 1); |
| 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 | ||
| @@ -3315,7 +3500,7 @@ x_draw_glyph_string_box (s) | |||
| 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 | ||
| @@ -3774,6 +3959,14 @@ x_draw_glyph_string (s) | |||
| 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 | } |
| @@ -3853,94 +4046,44 @@ x_draw_glyph_string (s) | |||
| 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 | |||
| 3859 | struct work | ||
| 3860 | { | ||
| 3861 | /* Pointer to composite char info defining has the composite | ||
| 3862 | character is drawn. */ | ||
| 3863 | struct cmpchar_info *cmpcharp; | ||
| 3864 | |||
| 3865 | /* Start index in compcharp->glyph[]. */ | ||
| 3866 | int gidx; | ||
| 3867 | 4051 | ||
| 3868 | /* Next in stack. */ | ||
| 3869 | struct work *next; | ||
| 3870 | }; | ||
| 3871 | |||
| 3872 | |||
| 3873 | static void x_fill_composite_glyph_string P_ ((struct glyph_string *, | ||
| 3874 | int, struct work **, | ||
| 3875 | struct work **, int)); | ||
| 3876 | 4052 | ||
| 4053 | /* Load glyph string S with a composition components specified by S->cmp. | ||
| 4054 | FACES is an array of faces for all components of this composition. | ||
| 4055 | S->gidx is the index of the first component for S. | ||
| 4056 | OVERLAPS_P non-zero means S should draw the foreground only, and | ||
| 4057 | use its lines physical height for clipping. | ||
| 3877 | 4058 | ||
| 3878 | /* Load glyph string S with information from the top of *STACK for a | 4059 | Value is the index of a component not in S. */ |
| 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 | 4060 | ||
| 3886 | static void | 4061 | static int |
| 3887 | x_fill_composite_glyph_string (s, face_id, stack, new, overlaps_p) | 4062 | x_fill_composite_glyph_string (s, faces, 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; | ||
| 3895 | 4068 | ||
| 3896 | xassert (s && *new && *stack); | 4069 | xassert (s); |
| 3897 | 4070 | ||
| 3898 | s->for_overlaps_p = 1; | 4071 | s->for_overlaps_p = overlaps_p; |
| 3899 | |||
| 3900 | /* Pop the work stack. */ | ||
| 3901 | work = *stack; | ||
| 3902 | *stack = work->next; | ||
| 3903 | 4072 | ||
| 3904 | /* For all glyphs of cmpcharp->glyph, starting at the offset | 4073 | s->face = faces[s->gidx]; |
| 3905 | work->offset, until we reach the end of the definition or | 4074 | s->font = s->face->font; |
| 3906 | encounter another composite char, get the font and face to use, | 4075 | s->font_info = FONT_INFO_FROM_ID (s->f, s->face->font_info_id); |
| 3907 | and add it to S. */ | ||
| 3908 | for (i = work->gidx; i < work->cmpcharp->glyph_len; ++i) | ||
| 3909 | { | ||
| 3910 | c = FAST_GLYPH_CHAR (work->cmpcharp->glyph[i]); | ||
| 3911 | if (CHAR_CHARSET (c) == CHARSET_COMPOSITION) | ||
| 3912 | break; | ||
| 3913 | s->face = x_get_char_face_and_encoding (s->f, c, face_id, | ||
| 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 | 4076 | ||
| 3920 | /* If we find another composite char in the glyph definition of | 4077 | /* For all glyphs of this composition, starting at the offset |
| 3921 | work->cmpcharp, put back the rest of the glyphs on the work | 4078 | S->gidx, until we reach the end of the definition or encounter a |
| 3922 | stack, and make a new entry for the composite char. */ | 4079 | glyph that requires the different face, add it to S. */ |
| 3923 | if (i < work->cmpcharp->glyph_len) | 4080 | ++s->nchars; |
| 3924 | { | 4081 | for (i = s->gidx + 1; i < s->cmp->glyph_len && faces[i] == s->face; ++i) |
| 3925 | /* Push back an unprocessed rest of this glyph spec. */ | 4082 | ++s->nchars; |
| 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 | 4083 | ||
| 3935 | /* Make an entry for the composite char on the work stack. */ | 4084 | /* All glyph strings for the same composition has the same width, |
| 3936 | work->cmpcharp = cmpchar_table[COMPOSITE_CHAR_ID (c)]; | 4085 | i.e. the width set for the first component of the composition. */ |
| 3937 | work->gidx = 0; | ||
| 3938 | work->next = *stack; | ||
| 3939 | *stack = work; | ||
| 3940 | } | ||
| 3941 | 4086 | ||
| 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 |
| @@ -3960,10 +4103,12 @@ x_fill_composite_glyph_string (s, face_id, stack, new, overlaps_p) | |||
| 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; |
| 4106 | |||
| 4107 | return s->gidx + s->nchars; | ||
| 3963 | } | 4108 | } |
| 3964 | 4109 | ||
| 3965 | 4110 | ||
| 3966 | /* Load glyph string S with a sequence of non-composite characters. | 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 |
| @@ -3980,7 +4125,6 @@ x_fill_glyph_string (s, face_id, start, end, overlaps_p) | |||
| 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); |
| @@ -4195,67 +4339,72 @@ x_set_glyph_string_background_width (s, start, last_x) | |||
| 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 | ||
| 4258 | 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 | |||
| 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 |
| @@ -4281,6 +4430,12 @@ x_set_glyph_string_background_width (s, start, last_x) | |||
| 4281 | OVERLAPS_P); \ | 4430 | OVERLAPS_P); \ |
| 4282 | break; \ | 4431 | break; \ |
| 4283 | \ | 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); \ | ||
| 4437 | break; \ | ||
| 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); \ |
| @@ -10646,8 +10801,7 @@ x_new_font (f, fontname) | |||
| 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. */ |