176 |
#include "termchar.h" |
#include "termchar.h" |
177 |
#include "dispextern.h" |
#include "dispextern.h" |
178 |
#include "buffer.h" |
#include "buffer.h" |
179 |
|
#include "character.h" |
180 |
#include "charset.h" |
#include "charset.h" |
181 |
#include "indent.h" |
#include "indent.h" |
182 |
#include "commands.h" |
#include "commands.h" |
675 |
static enum prop_handled handle_composition_prop P_ ((struct it *)); |
static enum prop_handled handle_composition_prop P_ ((struct it *)); |
676 |
static enum prop_handled handle_overlay_change P_ ((struct it *)); |
static enum prop_handled handle_overlay_change P_ ((struct it *)); |
677 |
static enum prop_handled handle_fontified_prop P_ ((struct it *)); |
static enum prop_handled handle_fontified_prop P_ ((struct it *)); |
678 |
|
static enum prop_handled handle_auto_composed_prop P_ ((struct it *)); |
679 |
|
|
680 |
/* Properties handled by iterators. */ |
/* Properties handled by iterators. */ |
681 |
|
|
682 |
static struct props it_props[] = |
static struct props it_props[] = |
683 |
{ |
{ |
684 |
|
{&Qauto_composed, AUTO_COMPOSED_PROP_IDX, handle_auto_composed_prop}, |
685 |
{&Qfontified, FONTIFIED_PROP_IDX, handle_fontified_prop}, |
{&Qfontified, FONTIFIED_PROP_IDX, handle_fontified_prop}, |
686 |
/* Handle `face' before `display' because some sub-properties of |
/* Handle `face' before `display' because some sub-properties of |
687 |
`display' need to know the face. */ |
`display' need to know the face. */ |
3768 |
`composition' property |
`composition' property |
3769 |
***********************************************************************/ |
***********************************************************************/ |
3770 |
|
|
3771 |
|
static enum prop_handled |
3772 |
|
handle_auto_composed_prop (it) |
3773 |
|
struct it *it; |
3774 |
|
{ |
3775 |
|
enum prop_handled handled = HANDLED_NORMALLY; |
3776 |
|
|
3777 |
|
if (! NILP (Vauto_composition_function)) |
3778 |
|
{ |
3779 |
|
Lisp_Object val; |
3780 |
|
int pos; |
3781 |
|
|
3782 |
|
if (STRINGP (it->string)) |
3783 |
|
pos = IT_STRING_CHARPOS (*it); |
3784 |
|
else |
3785 |
|
pos = IT_CHARPOS (*it); |
3786 |
|
|
3787 |
|
val =Fget_char_property (make_number (pos), Qauto_composed, it->string); |
3788 |
|
if (NILP (val)) |
3789 |
|
{ |
3790 |
|
int count = SPECPDL_INDEX (); |
3791 |
|
Lisp_Object args[3]; |
3792 |
|
|
3793 |
|
args[0] = Vauto_composition_function; |
3794 |
|
specbind (Qauto_composition_function, Qnil); |
3795 |
|
args[1] = make_number (pos); |
3796 |
|
args[2] = it->string; |
3797 |
|
safe_call (3, args); |
3798 |
|
unbind_to (count, Qnil); |
3799 |
|
|
3800 |
|
val = Fget_char_property (args[1], Qauto_composed, it->string); |
3801 |
|
if (! NILP (val)) |
3802 |
|
handled = HANDLED_RECOMPUTE_PROPS; |
3803 |
|
} |
3804 |
|
} |
3805 |
|
|
3806 |
|
return handled; |
3807 |
|
} |
3808 |
|
|
3809 |
/* Set up iterator IT from `composition' property at its current |
/* Set up iterator IT from `composition' property at its current |
3810 |
position. Called from handle_stop. */ |
position. Called from handle_stop. */ |
3811 |
|
|
4766 |
else if ((it->c < ' ' |
else if ((it->c < ' ' |
4767 |
&& (it->area != TEXT_AREA |
&& (it->area != TEXT_AREA |
4768 |
|| (it->c != '\n' && it->c != '\t'))) |
|| (it->c != '\n' && it->c != '\t'))) |
4769 |
|| (it->multibyte_p |
|| (it->c != '\n' && it->c != '\t' |
4770 |
? ((it->c >= 127 |
&& (it->multibyte_p ? !CHAR_PRINTABLE_P (it->c) |
4771 |
&& it->len == 1) |
: it->c == 127))) |
|
|| !CHAR_PRINTABLE_P (it->c)) |
|
|
: (it->c >= 127 |
|
|
&& it->c == unibyte_char_to_multibyte (it->c)))) |
|
4772 |
{ |
{ |
4773 |
/* IT->c is a control character which must be displayed |
/* IT->c is a control character which must be displayed |
4774 |
either as '\003' or as `^C' where the '\\' and '^' |
either as '\003' or as `^C' where the '\\' and '^' |
4814 |
else |
else |
4815 |
escape_glyph = FAST_MAKE_GLYPH ('\\', 0); |
escape_glyph = FAST_MAKE_GLYPH ('\\', 0); |
4816 |
|
|
4817 |
if (SINGLE_BYTE_CHAR_P (it->c)) |
if (CHAR_BYTE8_P (it->c)) |
4818 |
str[0] = it->c, len = 1; |
{ |
4819 |
|
str[0] = CHAR_TO_BYTE8 (it->c); |
4820 |
|
len = 1; |
4821 |
|
} |
4822 |
|
else if (it->c < 256) |
4823 |
|
{ |
4824 |
|
str[0] = it->c; |
4825 |
|
len = 1; |
4826 |
|
} |
4827 |
else |
else |
4828 |
{ |
{ |
4829 |
len = CHAR_STRING_NO_SIGNAL (it->c, str); |
/* It's an invalid character, which |
4830 |
if (len < 0) |
shouldn't happen actually, but due to |
4831 |
{ |
bugs it may happen. Let's print the char |
4832 |
/* It's an invalid character, which |
as is, there's not much meaningful we can |
4833 |
shouldn't happen actually, but due to |
do with it. */ |
4834 |
bugs it may happen. Let's print the char |
str[0] = it->c; |
4835 |
as is, there's not much meaningful we can |
str[1] = it->c >> 8; |
4836 |
do with it. */ |
str[2] = it->c >> 16; |
4837 |
str[0] = it->c; |
str[3] = it->c >> 24; |
4838 |
str[1] = it->c >> 8; |
len = 4; |
|
str[2] = it->c >> 16; |
|
|
str[3] = it->c >> 24; |
|
|
len = 4; |
|
|
} |
|
4839 |
} |
} |
4840 |
|
|
4841 |
for (i = 0; i < len; i++) |
for (i = 0; i < len; i++) |
6250 |
for (i = 0; i < nbytes; i += char_bytes) |
for (i = 0; i < nbytes; i += char_bytes) |
6251 |
{ |
{ |
6252 |
c = string_char_and_length (m + i, nbytes - i, &char_bytes); |
c = string_char_and_length (m + i, nbytes - i, &char_bytes); |
6253 |
work[0] = (SINGLE_BYTE_CHAR_P (c) |
work[0] = (ASCII_CHAR_P (c) |
6254 |
? c |
? c |
6255 |
: multibyte_char_to_unibyte (c, Qnil)); |
: multibyte_char_to_unibyte (c, Qnil)); |
6256 |
insert_1_both (work, 1, 1, 1, 0, 0); |
insert_1_both (work, 1, 1, 1, 0, 0); |
7520 |
for (i = 0; i < nbytes; i += n) |
for (i = 0; i < nbytes; i += n) |
7521 |
{ |
{ |
7522 |
c = string_char_and_length (s + i, nbytes - i, &n); |
c = string_char_and_length (s + i, nbytes - i, &n); |
7523 |
work[0] = (SINGLE_BYTE_CHAR_P (c) |
work[0] = (ASCII_CHAR_P (c) |
7524 |
? c |
? c |
7525 |
: multibyte_char_to_unibyte (c, Qnil)); |
: multibyte_char_to_unibyte (c, Qnil)); |
7526 |
insert_1_both (work, 1, 1, 1, 0, 0); |
insert_1_both (work, 1, 1, 1, 0, 0); |
10418 |
struct Lisp_Char_Table *dp; |
struct Lisp_Char_Table *dp; |
10419 |
int c; |
int c; |
10420 |
{ |
{ |
|
int code[4], i; |
|
10421 |
Lisp_Object val; |
Lisp_Object val; |
10422 |
|
|
10423 |
if (SINGLE_BYTE_CHAR_P (c)) |
if (ASCII_CHAR_P (c)) |
10424 |
return (dp->contents[c]); |
{ |
10425 |
|
val = dp->ascii; |
10426 |
|
if (SUB_CHAR_TABLE_P (val)) |
10427 |
|
val = XSUB_CHAR_TABLE (val)->contents[c]; |
10428 |
|
} |
10429 |
|
else |
10430 |
|
{ |
10431 |
|
Lisp_Object table; |
10432 |
|
|
10433 |
SPLIT_CHAR (c, code[0], code[1], code[2]); |
XSETCHAR_TABLE (table, dp); |
10434 |
if (code[1] < 32) |
val = char_table_ref (table, c); |
10435 |
code[1] = -1; |
} |
10436 |
else if (code[2] < 32) |
if (NILP (val)) |
10437 |
code[2] = -1; |
val = dp->defalt; |
10438 |
|
return val; |
|
/* Here, the possible range of code[0] (== charset ID) is |
|
|
128..max_charset. Since the top level char table contains data |
|
|
for multibyte characters after 256th element, we must increment |
|
|
code[0] by 128 to get a correct index. */ |
|
|
code[0] += 128; |
|
|
code[3] = -1; /* anchor */ |
|
|
|
|
|
for (i = 0; code[i] >= 0; i++, dp = XCHAR_TABLE (val)) |
|
|
{ |
|
|
val = dp->contents[code[i]]; |
|
|
if (!SUB_CHAR_TABLE_P (val)) |
|
|
return (NILP (val) ? dp->defalt : val); |
|
|
} |
|
|
|
|
|
/* Here, val is a sub char table. We return the default value of |
|
|
it. */ |
|
|
return (dp->defalt); |
|
10439 |
} |
} |
10440 |
|
|
10441 |
|
|
14114 |
ASCII face. This will be automatically undone the next time |
ASCII face. This will be automatically undone the next time |
14115 |
get_next_display_element returns a multibyte character. Note |
get_next_display_element returns a multibyte character. Note |
14116 |
that the character will always be single byte in unibyte text. */ |
that the character will always be single byte in unibyte text. */ |
14117 |
if (!SINGLE_BYTE_CHAR_P (it->c)) |
if (!ASCII_CHAR_P (it->c)) |
14118 |
{ |
{ |
14119 |
it->face_id = FACE_FOR_CHAR (f, face, 0); |
it->face_id = FACE_FOR_CHAR (f, face, 0); |
14120 |
} |
} |
14222 |
&& glyph->u.ch == ' ')) |
&& glyph->u.ch == ' ')) |
14223 |
&& trailing_whitespace_p (glyph->charpos)) |
&& trailing_whitespace_p (glyph->charpos)) |
14224 |
{ |
{ |
14225 |
int face_id = lookup_named_face (f, Qtrailing_whitespace, 0); |
int face_id = lookup_named_face (f, Qtrailing_whitespace); |
14226 |
|
|
14227 |
while (glyph >= start |
while (glyph >= start |
14228 |
&& BUFFERP (glyph->object) |
&& BUFFERP (glyph->object) |
15633 |
/* The EOL conversion we are using. */ |
/* The EOL conversion we are using. */ |
15634 |
Lisp_Object eoltype; |
Lisp_Object eoltype; |
15635 |
|
|
15636 |
val = Fget (coding_system, Qcoding_system); |
val = CODING_SYSTEM_SPEC (coding_system); |
15637 |
eoltype = Qnil; |
eoltype = Qnil; |
15638 |
|
|
15639 |
if (!VECTORP (val)) /* Not yet decided. */ |
if (!VECTORP (val)) /* Not yet decided. */ |
15646 |
} |
} |
15647 |
else |
else |
15648 |
{ |
{ |
15649 |
|
Lisp_Object attrs; |
15650 |
Lisp_Object eolvalue; |
Lisp_Object eolvalue; |
15651 |
|
|
15652 |
eolvalue = Fget (coding_system, Qeol_type); |
attrs = AREF (val, 0); |
15653 |
|
eolvalue = AREF (val, 2); |
15654 |
|
|
15655 |
if (multibyte) |
if (multibyte) |
15656 |
*buf++ = XFASTINT (AREF (val, 1)); |
*buf++ = XFASTINT (CODING_ATTR_MNEMONIC (attrs)); |
15657 |
|
|
15658 |
if (eol_flag) |
if (eol_flag) |
15659 |
{ |
{ |
15663 |
eoltype = eol_mnemonic_undecided; |
eoltype = eol_mnemonic_undecided; |
15664 |
else if (VECTORP (eolvalue)) /* Not yet decided. */ |
else if (VECTORP (eolvalue)) /* Not yet decided. */ |
15665 |
eoltype = eol_mnemonic_undecided; |
eoltype = eol_mnemonic_undecided; |
15666 |
else /* INTEGERP (eolvalue) -- 0:LF, 1:CRLF, 2:CR */ |
else /* eolvalue is Qunix, Qdos, or Qmac. */ |
15667 |
eoltype = (XFASTINT (eolvalue) == 0 |
eoltype = (EQ (eolvalue, Qunix) |
15668 |
? eol_mnemonic_unix |
? eol_mnemonic_unix |
15669 |
: (XFASTINT (eolvalue) == 1 |
: (EQ (eolvalue, Qdos) == 1 |
15670 |
? eol_mnemonic_dos : eol_mnemonic_mac)); |
? eol_mnemonic_dos : eol_mnemonic_mac)); |
15671 |
} |
} |
15672 |
} |
} |
15679 |
eol_str = SDATA (eoltype); |
eol_str = SDATA (eoltype); |
15680 |
eol_str_len = SBYTES (eoltype); |
eol_str_len = SBYTES (eoltype); |
15681 |
} |
} |
15682 |
else if (INTEGERP (eoltype) |
else if (CHARACTERP (eoltype)) |
|
&& CHAR_VALID_P (XINT (eoltype), 0)) |
|
15683 |
{ |
{ |
15684 |
unsigned char *tmp = (unsigned char *) alloca (MAX_MULTIBYTE_LENGTH); |
unsigned char *tmp = (unsigned char *) alloca (MAX_MULTIBYTE_LENGTH); |
15685 |
eol_str_len = CHAR_STRING (XINT (eoltype), tmp); |
eol_str_len = CHAR_STRING (XINT (eoltype), tmp); |
16030 |
{ |
{ |
16031 |
/* No need to mention EOL here--the terminal never needs |
/* No need to mention EOL here--the terminal never needs |
16032 |
to do EOL conversion. */ |
to do EOL conversion. */ |
16033 |
p = decode_mode_spec_coding (keyboard_coding.symbol, p, 0); |
p = decode_mode_spec_coding (CODING_ID_NAME (keyboard_coding.id), |
16034 |
p = decode_mode_spec_coding (terminal_coding.symbol, p, 0); |
p, 0); |
16035 |
|
p = decode_mode_spec_coding (CODING_ID_NAME (terminal_coding.id), |
16036 |
|
p, 0); |
16037 |
} |
} |
16038 |
p = decode_mode_spec_coding (b->buffer_file_coding_system, |
p = decode_mode_spec_coding (b->buffer_file_coding_system, |
16039 |
p, eol_flag); |
p, eol_flag); |
16304 |
} |
} |
16305 |
break; |
break; |
16306 |
} |
} |
16307 |
else if (x + glyph->pixel_width > it->first_visible_x) |
else if (x + glyph->pixel_width >= it->first_visible_x) |
16308 |
{ |
{ |
16309 |
/* Glyph is at least partially visible. */ |
/* Glyph is at least partially visible. */ |
16310 |
++it->hpos; |
++it->hpos; |
16607 |
} |
} |
16608 |
else |
else |
16609 |
{ |
{ |
16610 |
int c1, c2, charset; |
struct font_info *font_info |
16611 |
|
= FONT_INFO_FROM_ID (f, face->font_info_id); |
16612 |
|
if (font_info) |
16613 |
|
{ |
16614 |
|
struct charset *charset = CHARSET_FROM_ID (font_info->charset); |
16615 |
|
unsigned code = ENCODE_CHAR (charset, glyph->u.ch); |
16616 |
|
|
16617 |
/* Split characters into bytes. If c2 is -1 afterwards, C is |
if (CHARSET_DIMENSION (charset) == 1) |
16618 |
really a one-byte character so that byte1 is zero. */ |
STORE_XCHAR2B (char2b, 0, code); |
16619 |
SPLIT_CHAR (glyph->u.ch, charset, c1, c2); |
else |
16620 |
if (c2 > 0) |
STORE_XCHAR2B (char2b, (code >> 8), (code & 0xFF)); |
|
STORE_XCHAR2B (char2b, c1, c2); |
|
|
else |
|
|
STORE_XCHAR2B (char2b, 0, c1); |
|
16621 |
|
|
16622 |
/* Maybe encode the character in *CHAR2B. */ |
/* Maybe encode the character in *CHAR2B. */ |
16623 |
if (charset != CHARSET_ASCII) |
if (CHARSET_ID (charset) != charset_ascii) |
16624 |
{ |
{ |
16625 |
struct font_info *font_info |
glyph->font_type |
16626 |
= FONT_INFO_FROM_ID (f, face->font_info_id); |
= rif->encode_char (glyph->u.ch, char2b, font_info, charset, |
16627 |
if (font_info) |
two_byte_p); |
16628 |
glyph->font_type |
} |
|
= rif->encode_char (glyph->u.ch, char2b, font_info, two_byte_p); |
|
16629 |
} |
} |
16630 |
} |
} |
16631 |
|
|
17005 |
/* Case of ASCII in a face known to fit ASCII. */ |
/* Case of ASCII in a face known to fit ASCII. */ |
17006 |
STORE_XCHAR2B (char2b, 0, c); |
STORE_XCHAR2B (char2b, 0, c); |
17007 |
} |
} |
17008 |
else |
else if (face->font != NULL) |
17009 |
{ |
{ |
17010 |
int c1, c2, charset; |
struct font_info *font_info |
17011 |
|
= FONT_INFO_FROM_ID (f, face->font_info_id); |
17012 |
|
struct charset *charset = CHARSET_FROM_ID (font_info->charset); |
17013 |
|
unsigned code = ENCODE_CHAR (charset, c); |
17014 |
|
|
17015 |
/* Split characters into bytes. If c2 is -1 afterwards, C is |
if (CHARSET_DIMENSION (charset) == 1) |
17016 |
really a one-byte character so that byte1 is zero. */ |
STORE_XCHAR2B (char2b, 0, code); |
|
SPLIT_CHAR (c, charset, c1, c2); |
|
|
if (c2 > 0) |
|
|
STORE_XCHAR2B (char2b, c1, c2); |
|
17017 |
else |
else |
17018 |
STORE_XCHAR2B (char2b, 0, c1); |
STORE_XCHAR2B (char2b, (code >> 8), (code & 0xFF)); |
17019 |
|
/* Maybe encode the character in *CHAR2B. */ |
17020 |
/* Maybe encode the character in *CHAR2B. */ |
rif->encode_char (c, char2b, font_info, charset, NULL); |
|
if (face->font != NULL) |
|
|
{ |
|
|
struct font_info *font_info |
|
|
= FONT_INFO_FROM_ID (f, face->font_info_id); |
|
|
if (font_info) |
|
|
rif->encode_char (c, char2b, font_info, 0); |
|
|
} |
|
17021 |
} |
} |
17022 |
|
|
17023 |
/* Make sure X resources of the face are allocated. */ |
/* Make sure X resources of the face are allocated. */ |
17859 |
/* Maybe translate single-byte characters to multibyte, or the |
/* Maybe translate single-byte characters to multibyte, or the |
17860 |
other way. */ |
other way. */ |
17861 |
it->char_to_display = it->c; |
it->char_to_display = it->c; |
17862 |
if (!ASCII_BYTE_P (it->c)) |
if (!ASCII_BYTE_P (it->c) |
17863 |
|
&& ! it->multibyte_p) |
17864 |
{ |
{ |
17865 |
if (unibyte_display_via_language_environment |
if (SINGLE_BYTE_CHAR_P (it->c) |
17866 |
&& SINGLE_BYTE_CHAR_P (it->c) |
&& unibyte_display_via_language_environment) |
17867 |
&& (it->c >= 0240 |
it->char_to_display = unibyte_char_to_multibyte (it->c); |
17868 |
|| !NILP (Vnonascii_translation_table))) |
if (! SINGLE_BYTE_CHAR_P (it->c)) |
|
{ |
|
|
it->char_to_display = unibyte_char_to_multibyte (it->c); |
|
|
it->multibyte_p = 1; |
|
|
it->face_id = FACE_FOR_CHAR (it->f, face, it->char_to_display); |
|
|
face = FACE_FROM_ID (it->f, it->face_id); |
|
|
} |
|
|
else if (!SINGLE_BYTE_CHAR_P (it->c) |
|
|
&& !it->multibyte_p) |
|
17869 |
{ |
{ |
17870 |
it->multibyte_p = 1; |
it->multibyte_p = 1; |
17871 |
it->face_id = FACE_FOR_CHAR (it->f, face, it->char_to_display); |
it->face_id = FACE_FOR_CHAR (it->f, face, it->char_to_display); |
18024 |
|
|
18025 |
/* If we found a font, this font should give us the right |
/* If we found a font, this font should give us the right |
18026 |
metrics. If we didn't find a font, use the frame's |
metrics. If we didn't find a font, use the frame's |
18027 |
default font and calculate the width of the character |
default font and calculate the width of the character by |
18028 |
from the charset width; this is what old redisplay code |
multiplying the width of font by the width of the |
18029 |
did. */ |
character. */ |
18030 |
|
|
18031 |
pcm = rif->per_char_metric (font, &char2b, |
pcm = rif->per_char_metric (font, &char2b, |
18032 |
FONT_TYPE_FOR_MULTIBYTE (font, it->c)); |
FONT_TYPE_FOR_MULTIBYTE (font, it->c)); |
18033 |
|
|
18034 |
if (font_not_found_p || !pcm) |
if (font_not_found_p || !pcm) |
18035 |
{ |
{ |
|
int charset = CHAR_CHARSET (it->char_to_display); |
|
|
|
|
18036 |
it->glyph_not_available_p = 1; |
it->glyph_not_available_p = 1; |
18037 |
it->pixel_width = (FRAME_COLUMN_WIDTH (it->f) |
it->pixel_width = (FRAME_COLUMN_WIDTH (it->f) |
18038 |
* CHARSET_WIDTH (charset)); |
* CHAR_WIDTH (it->char_to_display)); |
18039 |
it->phys_ascent = FONT_BASE (font) + boff; |
it->phys_ascent = FONT_BASE (font) + boff; |
18040 |
it->phys_descent = FONT_DESCENT (font) - boff; |
it->phys_descent = FONT_DESCENT (font) - boff; |
18041 |
} |
} |
18098 |
/* Maybe translate single-byte characters to multibyte. */ |
/* Maybe translate single-byte characters to multibyte. */ |
18099 |
it->char_to_display = it->c; |
it->char_to_display = it->c; |
18100 |
if (unibyte_display_via_language_environment |
if (unibyte_display_via_language_environment |
18101 |
&& SINGLE_BYTE_CHAR_P (it->c) |
&& it->c >= 0200) |
|
&& (it->c >= 0240 |
|
|
|| (it->c >= 0200 |
|
|
&& !NILP (Vnonascii_translation_table)))) |
|
18102 |
{ |
{ |
18103 |
it->char_to_display = unibyte_char_to_multibyte (it->c); |
it->char_to_display = unibyte_char_to_multibyte (it->c); |
18104 |
} |
} |