aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorKenichi Handa2010-08-31 16:49:21 +0900
committerKenichi Handa2010-08-31 16:49:21 +0900
commitd419e1d94e885388b86f8753d741befa1855d333 (patch)
treed907b7c8e384e459dbf027179d7710fba43837d0 /src
parentb295da470123c7beea983f9b500db5286fd12996 (diff)
downloademacs-d419e1d94e885388b86f8753d741befa1855d333.tar.gz
emacs-d419e1d94e885388b86f8753d741befa1855d333.zip
Fix handling of 8-bit characters in a display table.
Diffstat (limited to 'src')
-rw-r--r--src/ChangeLog30
-rw-r--r--src/dispextern.h10
-rw-r--r--src/term.c50
-rw-r--r--src/xdisp.c321
4 files changed, 160 insertions, 251 deletions
diff --git a/src/ChangeLog b/src/ChangeLog
index ec9e4a4d6cc..8a0b1b094ba 100644
--- a/src/ChangeLog
+++ b/src/ChangeLog
@@ -1,3 +1,33 @@
12010-08-31 Kenichi Handa <handa@m17n.org>
2
3 * dispextern.h (FACE_FOR_CHAR): Use an ASCII face for 8-bit
4 characters.
5
6 * term.c (encode_terminal_code): Fix the previous change.
7 (produce_glyphs): Don't set it->char_to_display here. Don't
8 handle unibyte-display-via-language-environment here.
9 (produce_special_glyphs): Set temp_it.char_to_display before
10 calling produce_glyphs.
11
12 * xdisp.c (get_next_display_element): Set it->char_to_display
13 here. Convert all 8-bit bytes from unibyte buffer/string to 8-bit
14 characters.
15 (get_overlay_arrow_glyph_row): Set it.char_to_display too before
16 calling PRODUCE_GLYPHS.
17 (append_space_for_newline): Save and store it->char_to_display.
18 Set it->char_to_display before calling PRODUCE_GLYPHS.
19 (extend_face_to_end_of_line): Set it->char_to_display before
20 calling PRODUCE_GLYPHS.
21 (get_glyph_face_and_encoding): Set the glyph code an 8-bit
22 character to its byte value.
23 (get_char_glyph_code): New function.
24 (produce_stretch_glyph): Set it2.char_to_display too before
25 calling x_produce_glyphs.
26 (x_produce_glyphs): Simplify by using the same code for ASCII and
27 non-ASCII characters. Don't set it->char_to_display here. Don't
28 handle unibyte-display-via-language-environment here. For a
29 charater of no glyph, use font->space_width instead of FONT_WIDTH.
30
12010-08-29 Kenichi Handa <handa@m17n.org> 312010-08-29 Kenichi Handa <handa@m17n.org>
2 32
3 * term.c (encode_terminal_code): Encode byte chars to the 33 * term.c (encode_terminal_code): Encode byte chars to the
diff --git a/src/dispextern.h b/src/dispextern.h
index 6b73a2573ac..076d9055859 100644
--- a/src/dispextern.h
+++ b/src/dispextern.h
@@ -1694,7 +1694,7 @@ struct face_cache
1694 This macro is only meaningful for multibyte character CHAR. */ 1694 This macro is only meaningful for multibyte character CHAR. */
1695 1695
1696#define FACE_FOR_CHAR(F, FACE, CHAR, POS, OBJECT) \ 1696#define FACE_FOR_CHAR(F, FACE, CHAR, POS, OBJECT) \
1697 (ASCII_CHAR_P (CHAR) \ 1697 ((ASCII_CHAR_P (CHAR) || CHAR_BYTE8_P (CHAR)) \
1698 ? (FACE)->ascii_face->id \ 1698 ? (FACE)->ascii_face->id \
1699 : face_for_char ((F), (FACE), (CHAR), (POS), (OBJECT))) 1699 : face_for_char ((F), (FACE), (CHAR), (POS), (OBJECT)))
1700 1700
@@ -2131,9 +2131,11 @@ struct it
2131 composition. */ 2131 composition. */
2132 struct composition_it cmp_it; 2132 struct composition_it cmp_it;
2133 2133
2134 /* The character to display, possibly translated to multibyte 2134 /* The character to display, possibly translated to multibyte if
2135 if unibyte_display_via_language_environment is set. This 2135 multibyte_p is zero or unibyte_display_via_language_environment
2136 is set after produce_glyphs has been called. */ 2136 is set. This is set after get_next_display_element has been
2137 called. If we are setting it->C directly before calling
2138 PRODUCE_GLYPHS, this should be set beforehand too. */
2137 int char_to_display; 2139 int char_to_display;
2138 2140
2139 /* If what == IT_IMAGE, the id of the image to display. */ 2141 /* If what == IT_IMAGE, the id of the image to display. */
diff --git a/src/term.c b/src/term.c
index 868b596dc1a..b67d93f5b5b 100644
--- a/src/term.c
+++ b/src/term.c
@@ -695,12 +695,8 @@ encode_terminal_code (src, src_len, coding)
695 encode_terminal_src_size); 695 encode_terminal_src_size);
696 buf = encode_terminal_src + nbytes; 696 buf = encode_terminal_src + nbytes;
697 } 697 }
698 if (CHAR_BYTE8_P (c)) 698 if (CHAR_BYTE8_P (c)
699 { 699 || char_charset (c, charset_list, NULL))
700 *buf++ = CHAR_TO_BYTE8 (c);
701 nchars++;
702 }
703 else if (char_charset (c, charset_list, NULL))
704 { 700 {
705 /* Store the multibyte form of C at BUF. */ 701 /* Store the multibyte form of C at BUF. */
706 buf += CHAR_STRING (c, buf); 702 buf += CHAR_STRING (c, buf);
@@ -1610,18 +1606,15 @@ produce_glyphs (it)
1610 goto done; 1606 goto done;
1611 } 1607 }
1612 1608
1613 /* Maybe translate single-byte characters to multibyte. */ 1609 if (it->char_to_display >= 040 && it->char_to_display < 0177)
1614 it->char_to_display = it->c;
1615
1616 if (it->c >= 040 && it->c < 0177)
1617 { 1610 {
1618 it->pixel_width = it->nglyphs = 1; 1611 it->pixel_width = it->nglyphs = 1;
1619 if (it->glyph_row) 1612 if (it->glyph_row)
1620 append_glyph (it); 1613 append_glyph (it);
1621 } 1614 }
1622 else if (it->c == '\n') 1615 else if (it->char_to_display == '\n')
1623 it->pixel_width = it->nglyphs = 0; 1616 it->pixel_width = it->nglyphs = 0;
1624 else if (it->c == '\t') 1617 else if (it->char_to_display == '\t')
1625 { 1618 {
1626 int absolute_x = (it->current_x 1619 int absolute_x = (it->current_x
1627 + it->continuation_lines_width); 1620 + it->continuation_lines_width);
@@ -1652,32 +1645,19 @@ produce_glyphs (it)
1652 it->pixel_width = nspaces; 1645 it->pixel_width = nspaces;
1653 it->nglyphs = nspaces; 1646 it->nglyphs = nspaces;
1654 } 1647 }
1655 else if (CHAR_BYTE8_P (it->c)) 1648 else if (CHAR_BYTE8_P (it->char_to_display))
1656 { 1649 {
1657 if (unibyte_display_via_language_environment 1650 /* Coming here means that we must send the raw 8-bit byte as is
1658 && (it->c >= 0240)) 1651 to the terminal. Although there's no way to know how many
1659 { 1652 columns it occupies on a screen, it is a good assumption that
1660 it->char_to_display = BYTE8_TO_CHAR (it->c); 1653 a single byte code has 1-column width. */
1661 it->pixel_width = CHAR_WIDTH (it->char_to_display); 1654 it->pixel_width = it->nglyphs = 1;
1662 it->nglyphs = it->pixel_width; 1655 if (it->glyph_row)
1663 if (it->glyph_row) 1656 append_glyph (it);
1664 append_glyph (it);
1665 }
1666 else
1667 {
1668 /* Coming here means that it->c is from display table, thus
1669 we must send the raw 8-bit byte as is to the terminal.
1670 Although there's no way to know how many columns it
1671 occupies on a screen, it is a good assumption that a
1672 single byte code has 1-column width. */
1673 it->pixel_width = it->nglyphs = 1;
1674 if (it->glyph_row)
1675 append_glyph (it);
1676 }
1677 } 1657 }
1678 else 1658 else
1679 { 1659 {
1680 it->pixel_width = CHAR_WIDTH (it->c); 1660 it->pixel_width = CHAR_WIDTH (it->char_to_display);
1681 it->nglyphs = it->pixel_width; 1661 it->nglyphs = it->pixel_width;
1682 1662
1683 if (it->glyph_row) 1663 if (it->glyph_row)
@@ -1892,7 +1872,7 @@ produce_special_glyphs (it, what)
1892 else 1872 else
1893 abort (); 1873 abort ();
1894 1874
1895 temp_it.c = GLYPH_CHAR (glyph); 1875 temp_it.c = temp_it.char_to_display = GLYPH_CHAR (glyph);
1896 temp_it.face_id = GLYPH_FACE (glyph); 1876 temp_it.face_id = GLYPH_FACE (glyph);
1897 temp_it.len = CHAR_BYTES (temp_it.c); 1877 temp_it.len = CHAR_BYTES (temp_it.c);
1898 1878
diff --git a/src/xdisp.c b/src/xdisp.c
index 73ed675c4d2..59e38e440e4 100644
--- a/src/xdisp.c
+++ b/src/xdisp.c
@@ -5664,11 +5664,24 @@ get_next_display_element (it)
5664 Lisp_Object dv; 5664 Lisp_Object dv;
5665 struct charset *unibyte = CHARSET_FROM_ID (charset_unibyte); 5665 struct charset *unibyte = CHARSET_FROM_ID (charset_unibyte);
5666 enum { char_is_other = 0, char_is_nbsp, char_is_soft_hyphen } 5666 enum { char_is_other = 0, char_is_nbsp, char_is_soft_hyphen }
5667 nbsp_or_shy = char_is_other; 5667 nbsp_or_shy = char_is_other;
5668 int decoded = it->c; 5668 int c = it->c; /* This is the character to display. */
5669
5670 if (! it->multibyte_p && ! ASCII_CHAR_P (c))
5671 {
5672 xassert (SINGLE_BYTE_CHAR_P (c));
5673 if (unibyte_display_via_language_environment)
5674 {
5675 c = DECODE_CHAR (unibyte, c);
5676 if (c < 0)
5677 c = BYTE8_TO_CHAR (it->c);
5678 }
5679 else
5680 c = BYTE8_TO_CHAR (it->c);
5681 }
5669 5682
5670 if (it->dp 5683 if (it->dp
5671 && (dv = DISP_CHAR_VECTOR (it->dp, it->c), 5684 && (dv = DISP_CHAR_VECTOR (it->dp, c),
5672 VECTORP (dv))) 5685 VECTORP (dv)))
5673 { 5686 {
5674 struct Lisp_Vector *v = XVECTOR (dv); 5687 struct Lisp_Vector *v = XVECTOR (dv);
@@ -5694,21 +5707,10 @@ get_next_display_element (it)
5694 goto get_next; 5707 goto get_next;
5695 } 5708 }
5696 5709
5697 if (unibyte_display_via_language_environment 5710 if (! ASCII_CHAR_P (c) && ! NILP (Vnobreak_char_display))
5698 && !ASCII_CHAR_P (it->c)) 5711 nbsp_or_shy = (c == 0xA0 ? char_is_nbsp
5699 decoded = DECODE_CHAR (unibyte, it->c); 5712 : c == 0xAD ? char_is_soft_hyphen
5700 5713 : char_is_other);
5701 if (it->c >= 0x80 && ! NILP (Vnobreak_char_display))
5702 {
5703 if (it->multibyte_p)
5704 nbsp_or_shy = (it->c == 0xA0 ? char_is_nbsp
5705 : it->c == 0xAD ? char_is_soft_hyphen
5706 : char_is_other);
5707 else if (unibyte_display_via_language_environment)
5708 nbsp_or_shy = (decoded == 0xA0 ? char_is_nbsp
5709 : decoded == 0xAD ? char_is_soft_hyphen
5710 : char_is_other);
5711 }
5712 5714
5713 /* Translate control characters into `\003' or `^C' form. 5715 /* Translate control characters into `\003' or `^C' form.
5714 Control characters coming from a display table entry are 5716 Control characters coming from a display table entry are
@@ -5716,27 +5718,23 @@ get_next_display_element (it)
5716 the translation. This could easily be changed but I 5718 the translation. This could easily be changed but I
5717 don't believe that it is worth doing. 5719 don't believe that it is worth doing.
5718 5720
5719 If it->multibyte_p is nonzero, non-printable non-ASCII 5721 NBSP and SOFT-HYPEN are property translated too.
5720 characters are also translated to octal form.
5721 5722
5722 If it->multibyte_p is zero, eight-bit characters that 5723 Non-printable characters and raw-byte characters are also
5723 don't have corresponding multibyte char code are also
5724 translated to octal form. */ 5724 translated to octal form. */
5725 if ((it->c < ' ' 5725 if (((c < ' ' || c == 127) /* ASCII control chars */
5726 ? (it->area != TEXT_AREA 5726 ? (it->area != TEXT_AREA
5727 /* In mode line, treat \n, \t like other crl chars. */ 5727 /* In mode line, treat \n, \t like other crl chars. */
5728 || (it->c != '\t' 5728 || (c != '\t'
5729 && it->glyph_row 5729 && it->glyph_row
5730 && (it->glyph_row->mode_line_p || it->avoid_cursor_p)) 5730 && (it->glyph_row->mode_line_p || it->avoid_cursor_p))
5731 || (it->c != '\n' && it->c != '\t')) 5731 || (c != '\n' && c != '\t'))
5732 : (nbsp_or_shy 5732 : (nbsp_or_shy
5733 || (it->multibyte_p 5733 || CHAR_BYTE8_P (c)
5734 ? ! CHAR_PRINTABLE_P (it->c) 5734 || ! CHAR_PRINTABLE_P (c))))
5735 : (! unibyte_display_via_language_environment
5736 ? it->c >= 0x80
5737 : (decoded >= 0x80 && decoded < 0xA0))))))
5738 { 5735 {
5739 /* IT->c is a control character which must be displayed 5736 /* C is a control character, NBSP, SOFT-HYPEN, raw-byte,
5737 or a non-printable character which must be displayed
5740 either as '\003' or as `^C' where the '\\' and '^' 5738 either as '\003' or as `^C' where the '\\' and '^'
5741 can be defined in the display table. Fill 5739 can be defined in the display table. Fill
5742 IT->ctl_chars with glyphs for what we have to 5740 IT->ctl_chars with glyphs for what we have to
@@ -5748,7 +5746,7 @@ get_next_display_element (it)
5748 5746
5749 /* Handle control characters with ^. */ 5747 /* Handle control characters with ^. */
5750 5748
5751 if (it->c < 128 && it->ctl_arrow_p) 5749 if (ASCII_CHAR_P (c) && it->ctl_arrow_p)
5752 { 5750 {
5753 int g; 5751 int g;
5754 5752
@@ -5781,7 +5779,7 @@ get_next_display_element (it)
5781 } 5779 }
5782 5780
5783 XSETINT (it->ctl_chars[0], g); 5781 XSETINT (it->ctl_chars[0], g);
5784 XSETINT (it->ctl_chars[1], it->c ^ 0100); 5782 XSETINT (it->ctl_chars[1], c ^ 0100);
5785 ctl_len = 2; 5783 ctl_len = 2;
5786 goto display_control; 5784 goto display_control;
5787 } 5785 }
@@ -5796,7 +5794,7 @@ get_next_display_element (it)
5796 face_id = merge_faces (it->f, Qnobreak_space, 0, 5794 face_id = merge_faces (it->f, Qnobreak_space, 0,
5797 it->face_id); 5795 it->face_id);
5798 5796
5799 it->c = ' '; 5797 c = ' ';
5800 XSETINT (it->ctl_chars[0], ' '); 5798 XSETINT (it->ctl_chars[0], ' ');
5801 ctl_len = 1; 5799 ctl_len = 1;
5802 goto display_control; 5800 goto display_control;
@@ -5842,7 +5840,6 @@ get_next_display_element (it)
5842 if (EQ (Vnobreak_char_display, Qt) 5840 if (EQ (Vnobreak_char_display, Qt)
5843 && nbsp_or_shy == char_is_soft_hyphen) 5841 && nbsp_or_shy == char_is_soft_hyphen)
5844 { 5842 {
5845 it->c = '-';
5846 XSETINT (it->ctl_chars[0], '-'); 5843 XSETINT (it->ctl_chars[0], '-');
5847 ctl_len = 1; 5844 ctl_len = 1;
5848 goto display_control; 5845 goto display_control;
@@ -5854,55 +5851,25 @@ get_next_display_element (it)
5854 if (nbsp_or_shy) 5851 if (nbsp_or_shy)
5855 { 5852 {
5856 XSETINT (it->ctl_chars[0], escape_glyph); 5853 XSETINT (it->ctl_chars[0], escape_glyph);
5857 it->c = (nbsp_or_shy == char_is_nbsp ? ' ' : '-'); 5854 c = (nbsp_or_shy == char_is_nbsp ? ' ' : '-');
5858 XSETINT (it->ctl_chars[1], it->c); 5855 XSETINT (it->ctl_chars[1], c);
5859 ctl_len = 2; 5856 ctl_len = 2;
5860 goto display_control; 5857 goto display_control;
5861 } 5858 }
5862 5859
5863 { 5860 {
5864 unsigned char str[MAX_MULTIBYTE_LENGTH]; 5861 char str[10];
5865 int len; 5862 int len, i;
5866 int i;
5867 5863
5868 /* Set IT->ctl_chars[0] to the glyph for `\\'. */ 5864 if (CHAR_BYTE8_P (c))
5869 if (CHAR_BYTE8_P (it->c)) 5865 /* Display \200 instead of \17777600. */
5870 { 5866 c = CHAR_TO_BYTE8 (c);
5871 str[0] = CHAR_TO_BYTE8 (it->c); 5867 len = sprintf (str, "%03o", c);
5872 len = 1;
5873 }
5874 else if (it->c < 256)
5875 {
5876 str[0] = it->c;
5877 len = 1;
5878 }
5879 else
5880 {
5881 /* It's an invalid character, which shouldn't
5882 happen actually, but due to bugs it may
5883 happen. Let's print the char as is, there's
5884 not much meaningful we can do with it. */
5885 str[0] = it->c;
5886 str[1] = it->c >> 8;
5887 str[2] = it->c >> 16;
5888 str[3] = it->c >> 24;
5889 len = 4;
5890 }
5891 5868
5869 XSETINT (it->ctl_chars[0], escape_glyph);
5892 for (i = 0; i < len; i++) 5870 for (i = 0; i < len; i++)
5893 { 5871 XSETINT (it->ctl_chars[i + 1], str[i]);
5894 int g; 5872 ctl_len = len + 1;
5895 XSETINT (it->ctl_chars[i * 4], escape_glyph);
5896 /* Insert three more glyphs into IT->ctl_chars for
5897 the octal display of the character. */
5898 g = ((str[i] >> 6) & 7) + '0';
5899 XSETINT (it->ctl_chars[i * 4 + 1], g);
5900 g = ((str[i] >> 3) & 7) + '0';
5901 XSETINT (it->ctl_chars[i * 4 + 2], g);
5902 g = (str[i] & 7) + '0';
5903 XSETINT (it->ctl_chars[i * 4 + 3], g);
5904 }
5905 ctl_len = len * 4;
5906 } 5873 }
5907 5874
5908 display_control: 5875 display_control:
@@ -5917,6 +5884,11 @@ get_next_display_element (it)
5917 it->ellipsis_p = 0; 5884 it->ellipsis_p = 0;
5918 goto get_next; 5885 goto get_next;
5919 } 5886 }
5887 it->char_to_display = c;
5888 }
5889 else if (success_p)
5890 {
5891 it->char_to_display = it->c;
5920 } 5892 }
5921 } 5893 }
5922 5894
@@ -5943,7 +5915,8 @@ get_next_display_element (it)
5943 : STRINGP (it->string) ? IT_STRING_CHARPOS (*it) 5915 : STRINGP (it->string) ? IT_STRING_CHARPOS (*it)
5944 : IT_CHARPOS (*it)); 5916 : IT_CHARPOS (*it));
5945 5917
5946 it->face_id = FACE_FOR_CHAR (it->f, face, it->c, pos, it->string); 5918 it->face_id = FACE_FOR_CHAR (it->f, face, it->char_to_display, pos,
5919 it->string);
5947 } 5920 }
5948 } 5921 }
5949#endif 5922#endif
@@ -15871,15 +15844,19 @@ get_overlay_arrow_glyph_row (w, overlay_arrow_string)
15871 15844
15872 /* Get the next character. */ 15845 /* Get the next character. */
15873 if (multibyte_p) 15846 if (multibyte_p)
15874 it.c = string_char_and_length (p, &it.len); 15847 it.c = it.char_to_display = string_char_and_length (p, &it.len);
15875 else 15848 else
15876 it.c = *p, it.len = 1; 15849 {
15850 it.c = it.char_to_display = *p, it.len = 1;
15851 if (! ASCII_CHAR_P (it.c))
15852 it.char_to_display = BYTE8_TO_CHAR (it.c);
15853 }
15877 p += it.len; 15854 p += it.len;
15878 15855
15879 /* Get its face. */ 15856 /* Get its face. */
15880 ilisp = make_number (p - arrow_string); 15857 ilisp = make_number (p - arrow_string);
15881 face = Fget_text_property (ilisp, Qface, overlay_arrow_string); 15858 face = Fget_text_property (ilisp, Qface, overlay_arrow_string);
15882 it.face_id = compute_char_face (f, it.c, face); 15859 it.face_id = compute_char_face (f, it.char_to_display, face);
15883 15860
15884 /* Compute its width, get its glyphs. */ 15861 /* Compute its width, get its glyphs. */
15885 n_glyphs_before = it.glyph_row->used[TEXT_AREA]; 15862 n_glyphs_before = it.glyph_row->used[TEXT_AREA];
@@ -16078,6 +16055,7 @@ append_space_for_newline (it, default_face_p)
16078 append_space_for_newline has been called. */ 16055 append_space_for_newline has been called. */
16079 enum display_element_type saved_what = it->what; 16056 enum display_element_type saved_what = it->what;
16080 int saved_c = it->c, saved_len = it->len; 16057 int saved_c = it->c, saved_len = it->len;
16058 int saved_char_to_display = it->char_to_display;
16081 int saved_x = it->current_x; 16059 int saved_x = it->current_x;
16082 int saved_face_id = it->face_id; 16060 int saved_face_id = it->face_id;
16083 struct text_pos saved_pos; 16061 struct text_pos saved_pos;
@@ -16090,7 +16068,7 @@ append_space_for_newline (it, default_face_p)
16090 it->what = IT_CHARACTER; 16068 it->what = IT_CHARACTER;
16091 bzero (&it->position, sizeof it->position); 16069 bzero (&it->position, sizeof it->position);
16092 it->object = make_number (0); 16070 it->object = make_number (0);
16093 it->c = ' '; 16071 it->c = it->char_to_display = ' ';
16094 it->len = 1; 16072 it->len = 1;
16095 16073
16096 if (default_face_p) 16074 if (default_face_p)
@@ -16111,6 +16089,7 @@ append_space_for_newline (it, default_face_p)
16111 it->face_id = saved_face_id; 16089 it->face_id = saved_face_id;
16112 it->len = saved_len; 16090 it->len = saved_len;
16113 it->c = saved_c; 16091 it->c = saved_c;
16092 it->char_to_display = saved_char_to_display;
16114 return 1; 16093 return 1;
16115 } 16094 }
16116 } 16095 }
@@ -16190,7 +16169,7 @@ extend_face_to_end_of_line (it)
16190 it->what = IT_CHARACTER; 16169 it->what = IT_CHARACTER;
16191 bzero (&it->position, sizeof it->position); 16170 bzero (&it->position, sizeof it->position);
16192 it->object = make_number (0); 16171 it->object = make_number (0);
16193 it->c = ' '; 16172 it->c = it->char_to_display = ' ';
16194 it->len = 1; 16173 it->len = 1;
16195 it->face_id = face->id; 16174 it->face_id = face->id;
16196 16175
@@ -19519,7 +19498,12 @@ get_glyph_face_and_encoding (f, glyph, char2b, two_byte_p)
19519 19498
19520 if (face->font) 19499 if (face->font)
19521 { 19500 {
19522 unsigned code = face->font->driver->encode_char (face->font, glyph->u.ch); 19501 unsigned code;
19502
19503 if (CHAR_BYTE8_P (glyph->u.ch))
19504 code = CHAR_TO_BYTE8 (glyph->u.ch);
19505 else
19506 code = face->font->driver->encode_char (face->font, glyph->u.ch);
19523 19507
19524 if (code != FONT_INVALID_CODE) 19508 if (code != FONT_INVALID_CODE)
19525 STORE_XCHAR2B (char2b, (code >> 8), (code & 0xFF)); 19509 STORE_XCHAR2B (char2b, (code >> 8), (code & 0xFF));
@@ -19534,6 +19518,26 @@ get_glyph_face_and_encoding (f, glyph, char2b, two_byte_p)
19534} 19518}
19535 19519
19536 19520
19521/* Get glyph code of character C in FONT in the two-byte form CHAR2B.
19522 Retunr 1 if FONT has a glyph for C, otherwise return 0. */
19523
19524static INLINE int
19525get_char_glyph_code (int c, struct font *font, XChar2b *char2b)
19526{
19527 unsigned code;
19528
19529 if (CHAR_BYTE8_P (c))
19530 code = CHAR_TO_BYTE8 (c);
19531 else
19532 code = font->driver->encode_char (font, c);
19533
19534 if (code == FONT_INVALID_CODE)
19535 return 0;
19536 STORE_XCHAR2B (char2b, (code >> 8), (code & 0xFF));
19537 return 1;
19538}
19539
19540
19537/* Fill glyph string S with composition components specified by S->cmp. 19541/* Fill glyph string S with composition components specified by S->cmp.
19538 19542
19539 BASE_FACE is the base face of the composition. 19543 BASE_FACE is the base face of the composition.
@@ -20906,10 +20910,14 @@ produce_stretch_glyph (it)
20906 { 20910 {
20907 int maxlen = ((IT_BYTEPOS (*it) >= GPT ? ZV : GPT) 20911 int maxlen = ((IT_BYTEPOS (*it) >= GPT ? ZV : GPT)
20908 - IT_BYTEPOS (*it)); 20912 - IT_BYTEPOS (*it));
20909 it2.c = STRING_CHAR_AND_LENGTH (p, it2.len); 20913 it2.c = it2.char_to_display = STRING_CHAR_AND_LENGTH (p, it2.len);
20910 } 20914 }
20911 else 20915 else
20912 it2.c = *p, it2.len = 1; 20916 {
20917 it2.c = it2.char_to_display = *p, it2.len = 1;
20918 if (! ASCII_CHAR_P (it2.c))
20919 it2.char_to_display = BYTE8_TO_CHAR (it2.c);
20920 }
20913 20921
20914 it2.glyph_row = NULL; 20922 it2.glyph_row = NULL;
20915 it2.what = IT_CHARACTER; 20923 it2.what = IT_CHARACTER;
@@ -21083,49 +21091,12 @@ x_produce_glyphs (it)
21083 if (it->what == IT_CHARACTER) 21091 if (it->what == IT_CHARACTER)
21084 { 21092 {
21085 XChar2b char2b; 21093 XChar2b char2b;
21086 struct font *font;
21087 struct face *face = FACE_FROM_ID (it->f, it->face_id); 21094 struct face *face = FACE_FROM_ID (it->f, it->face_id);
21088 struct font_metrics *pcm; 21095 struct font *font = face->font;
21089 int font_not_found_p; 21096 int font_not_found_p = font == NULL;
21097 struct font_metrics *pcm = NULL;
21090 int boff; /* baseline offset */ 21098 int boff; /* baseline offset */
21091 /* We may change it->multibyte_p upon unibyte<->multibyte
21092 conversion. So, save the current value now and restore it
21093 later.
21094
21095 Note: It seems that we don't have to record multibyte_p in
21096 struct glyph because the character code itself tells whether
21097 or not the character is multibyte. Thus, in the future, we
21098 must consider eliminating the field `multibyte_p' in the
21099 struct glyph. */
21100 int saved_multibyte_p = it->multibyte_p;
21101
21102 /* Maybe translate single-byte characters to multibyte, or the
21103 other way. */
21104 it->char_to_display = it->c;
21105 if (!ASCII_BYTE_P (it->c)
21106 && ! it->multibyte_p)
21107 {
21108 if (SINGLE_BYTE_CHAR_P (it->c)
21109 && unibyte_display_via_language_environment)
21110 {
21111 struct charset *unibyte = CHARSET_FROM_ID (charset_unibyte);
21112
21113 /* get_next_display_element assures that this decoding
21114 never fails. */
21115 it->char_to_display = DECODE_CHAR (unibyte, it->c);
21116 it->multibyte_p = 1;
21117 it->face_id = FACE_FOR_CHAR (it->f, face, it->char_to_display,
21118 -1, Qnil);
21119 face = FACE_FROM_ID (it->f, it->face_id);
21120 }
21121 }
21122
21123 /* Get font to use. Encode IT->char_to_display. */
21124 get_char_face_and_encoding (it->f, it->char_to_display, it->face_id,
21125 &char2b, it->multibyte_p, 0);
21126 font = face->font;
21127 21099
21128 font_not_found_p = font == NULL;
21129 if (font_not_found_p) 21100 if (font_not_found_p)
21130 { 21101 {
21131 /* When no suitable font found, display an empty box based 21102 /* When no suitable font found, display an empty box based
@@ -21145,16 +21116,12 @@ x_produce_glyphs (it)
21145 boff = VCENTER_BASELINE_OFFSET (font, it->f) - boff; 21116 boff = VCENTER_BASELINE_OFFSET (font, it->f) - boff;
21146 } 21117 }
21147 21118
21148 if (it->char_to_display >= ' ' 21119 if (it->char_to_display != '\n' && it->char_to_display != '\t')
21149 && (!it->multibyte_p || it->char_to_display < 128))
21150 { 21120 {
21151 /* Either unibyte or ASCII. */
21152 int stretched_p; 21121 int stretched_p;
21153 21122
21154 it->nglyphs = 1; 21123 it->nglyphs = 1;
21155 21124
21156 pcm = get_per_char_metric (it->f, font, &char2b);
21157
21158 if (it->override_ascent >= 0) 21125 if (it->override_ascent >= 0)
21159 { 21126 {
21160 it->ascent = it->override_ascent; 21127 it->ascent = it->override_ascent;
@@ -21167,6 +21134,15 @@ x_produce_glyphs (it)
21167 it->descent = FONT_DESCENT (font) - boff; 21134 it->descent = FONT_DESCENT (font) - boff;
21168 } 21135 }
21169 21136
21137 if (! font_not_found_p
21138 && get_char_glyph_code (it->char_to_display, font, &char2b))
21139 {
21140 pcm = get_per_char_metric (it->f, font, &char2b);
21141 if (pcm->width == 0
21142 && pcm->rbearing == 0 && pcm->lbearing == 0)
21143 pcm = NULL;
21144 }
21145
21170 if (pcm) 21146 if (pcm)
21171 { 21147 {
21172 it->phys_ascent = pcm->ascent + boff; 21148 it->phys_ascent = pcm->ascent + boff;
@@ -21178,7 +21154,7 @@ x_produce_glyphs (it)
21178 it->glyph_not_available_p = 1; 21154 it->glyph_not_available_p = 1;
21179 it->phys_ascent = it->ascent; 21155 it->phys_ascent = it->ascent;
21180 it->phys_descent = it->descent; 21156 it->phys_descent = it->descent;
21181 it->pixel_width = FONT_WIDTH (font); 21157 it->pixel_width = font->space_width;
21182 } 21158 }
21183 21159
21184 if (it->constrain_row_ascent_descent_p) 21160 if (it->constrain_row_ascent_descent_p)
@@ -21352,7 +21328,7 @@ x_produce_glyphs (it)
21352 } 21328 }
21353 } 21329 }
21354 } 21330 }
21355 else if (it->char_to_display == '\t') 21331 else /* i.e. (it->char_to_display == '\t') */
21356 { 21332 {
21357 if (font->space_width > 0) 21333 if (font->space_width > 0)
21358 { 21334 {
@@ -21383,85 +21359,6 @@ x_produce_glyphs (it)
21383 it->nglyphs = 1; 21359 it->nglyphs = 1;
21384 } 21360 }
21385 } 21361 }
21386 else
21387 {
21388 /* A multi-byte character. Assume that the display width of the
21389 character is the width of the character multiplied by the
21390 width of the font. */
21391
21392 /* If we found a font, this font should give us the right
21393 metrics. If we didn't find a font, use the frame's
21394 default font and calculate the width of the character by
21395 multiplying the width of font by the width of the
21396 character. */
21397
21398 pcm = get_per_char_metric (it->f, font, &char2b);
21399
21400 if (font_not_found_p || !pcm)
21401 {
21402 int char_width = CHAR_WIDTH (it->char_to_display);
21403
21404 if (char_width == 0)
21405 /* This is a non spacing character. But, as we are
21406 going to display an empty box, the box must occupy
21407 at least one column. */
21408 char_width = 1;
21409 it->glyph_not_available_p = 1;
21410 it->pixel_width = font->space_width * char_width;
21411 it->phys_ascent = FONT_BASE (font) + boff;
21412 it->phys_descent = FONT_DESCENT (font) - boff;
21413 }
21414 else
21415 {
21416 it->pixel_width = pcm->width;
21417 it->phys_ascent = pcm->ascent + boff;
21418 it->phys_descent = pcm->descent - boff;
21419 if (it->glyph_row
21420 && (pcm->lbearing < 0
21421 || pcm->rbearing > pcm->width))
21422 it->glyph_row->contains_overlapping_glyphs_p = 1;
21423 }
21424 it->nglyphs = 1;
21425 it->ascent = FONT_BASE (font) + boff;
21426 it->descent = FONT_DESCENT (font) - boff;
21427 if (face->box != FACE_NO_BOX)
21428 {
21429 int thick = face->box_line_width;
21430
21431 if (thick > 0)
21432 {
21433 it->ascent += thick;
21434 it->descent += thick;
21435 }
21436 else
21437 thick = - thick;
21438
21439 if (it->start_of_box_run_p)
21440 it->pixel_width += thick;
21441 if (it->end_of_box_run_p)
21442 it->pixel_width += thick;
21443 }
21444
21445 /* If face has an overline, add the height of the overline
21446 (1 pixel) and a 1 pixel margin to the character height. */
21447 if (face->overline_p)
21448 it->ascent += overline_margin;
21449
21450 take_vertical_position_into_account (it);
21451
21452 if (it->ascent < 0)
21453 it->ascent = 0;
21454 if (it->descent < 0)
21455 it->descent = 0;
21456
21457 if (it->glyph_row)
21458 append_glyph (it);
21459 if (it->pixel_width == 0)
21460 /* We assure that all visible glyphs have at least 1-pixel
21461 width. */
21462 it->pixel_width = 1;
21463 }
21464 it->multibyte_p = saved_multibyte_p;
21465 } 21362 }
21466 else if (it->what == IT_COMPOSITION && it->cmp_it.ch < 0) 21363 else if (it->what == IT_COMPOSITION && it->cmp_it.ch < 0)
21467 { 21364 {
@@ -21557,7 +21454,7 @@ x_produce_glyphs (it)
21557 } 21454 }
21558 else 21455 else
21559 { 21456 {
21560 width = FONT_WIDTH (font); 21457 width = font->space_width;
21561 ascent = FONT_BASE (font); 21458 ascent = FONT_BASE (font);
21562 descent = FONT_DESCENT (font); 21459 descent = FONT_DESCENT (font);
21563 lbearing = 0; 21460 lbearing = 0;