diff options
| author | Kenichi Handa | 2010-08-31 16:49:21 +0900 |
|---|---|---|
| committer | Kenichi Handa | 2010-08-31 16:49:21 +0900 |
| commit | d419e1d94e885388b86f8753d741befa1855d333 (patch) | |
| tree | d907b7c8e384e459dbf027179d7710fba43837d0 /src | |
| parent | b295da470123c7beea983f9b500db5286fd12996 (diff) | |
| download | emacs-d419e1d94e885388b86f8753d741befa1855d333.tar.gz emacs-d419e1d94e885388b86f8753d741befa1855d333.zip | |
Fix handling of 8-bit characters in a display table.
Diffstat (limited to 'src')
| -rw-r--r-- | src/ChangeLog | 30 | ||||
| -rw-r--r-- | src/dispextern.h | 10 | ||||
| -rw-r--r-- | src/term.c | 50 | ||||
| -rw-r--r-- | src/xdisp.c | 321 |
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 @@ | |||
| 1 | 2010-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 | |||
| 1 | 2010-08-29 Kenichi Handa <handa@m17n.org> | 31 | 2010-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 | |||
| 19524 | static INLINE int | ||
| 19525 | get_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; |