Mercurial > emacs
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 { |