Mercurial > emacs
comparison src/xdisp.c @ 110133:0dcf6ddbe02b
merge changes in emacs-23 branch
author | Kenichi Handa <handa@m17n.org> |
---|---|
date | Wed, 01 Sep 2010 16:13:21 +0900 |
parents | 7ab569e9f738 cca2a663ef92 |
children | f67e6d84ff96 |
comparison
equal
deleted
inserted
replaced
110090:9f2296908370 | 110133:0dcf6ddbe02b |
---|---|
5760 { | 5760 { |
5761 Lisp_Object dv; | 5761 Lisp_Object dv; |
5762 struct charset *unibyte = CHARSET_FROM_ID (charset_unibyte); | 5762 struct charset *unibyte = CHARSET_FROM_ID (charset_unibyte); |
5763 enum { char_is_other = 0, char_is_nbsp, char_is_soft_hyphen } | 5763 enum { char_is_other = 0, char_is_nbsp, char_is_soft_hyphen } |
5764 nbsp_or_shy = char_is_other; | 5764 nbsp_or_shy = char_is_other; |
5765 int decoded = it->c; | 5765 int c = it->c; /* This is the character to display. */ |
5766 | |
5767 if (! it->multibyte_p && ! ASCII_CHAR_P (c)) | |
5768 { | |
5769 xassert (SINGLE_BYTE_CHAR_P (c)); | |
5770 if (unibyte_display_via_language_environment) | |
5771 { | |
5772 c = DECODE_CHAR (unibyte, c); | |
5773 if (c < 0) | |
5774 c = BYTE8_TO_CHAR (it->c); | |
5775 } | |
5776 else | |
5777 c = BYTE8_TO_CHAR (it->c); | |
5778 } | |
5766 | 5779 |
5767 if (it->dp | 5780 if (it->dp |
5768 && (dv = DISP_CHAR_VECTOR (it->dp, it->c), | 5781 && (dv = DISP_CHAR_VECTOR (it->dp, c), |
5769 VECTORP (dv))) | 5782 VECTORP (dv))) |
5770 { | 5783 { |
5771 struct Lisp_Vector *v = XVECTOR (dv); | 5784 struct Lisp_Vector *v = XVECTOR (dv); |
5772 | 5785 |
5773 /* Return the first character from the display table | 5786 /* Return the first character from the display table |
5789 set_iterator_to_next (it, 0); | 5802 set_iterator_to_next (it, 0); |
5790 } | 5803 } |
5791 goto get_next; | 5804 goto get_next; |
5792 } | 5805 } |
5793 | 5806 |
5794 if (unibyte_display_via_language_environment | 5807 if (! ASCII_CHAR_P (c) && ! NILP (Vnobreak_char_display)) |
5795 && !ASCII_CHAR_P (it->c)) | 5808 nbsp_or_shy = (c == 0xA0 ? char_is_nbsp |
5796 decoded = DECODE_CHAR (unibyte, it->c); | 5809 : c == 0xAD ? char_is_soft_hyphen |
5797 | 5810 : char_is_other); |
5798 if (it->c >= 0x80 && ! NILP (Vnobreak_char_display)) | |
5799 { | |
5800 if (it->multibyte_p) | |
5801 nbsp_or_shy = (it->c == 0xA0 ? char_is_nbsp | |
5802 : it->c == 0xAD ? char_is_soft_hyphen | |
5803 : char_is_other); | |
5804 else if (unibyte_display_via_language_environment) | |
5805 nbsp_or_shy = (decoded == 0xA0 ? char_is_nbsp | |
5806 : decoded == 0xAD ? char_is_soft_hyphen | |
5807 : char_is_other); | |
5808 } | |
5809 | 5811 |
5810 /* Translate control characters into `\003' or `^C' form. | 5812 /* Translate control characters into `\003' or `^C' form. |
5811 Control characters coming from a display table entry are | 5813 Control characters coming from a display table entry are |
5812 currently not translated because we use IT->dpvec to hold | 5814 currently not translated because we use IT->dpvec to hold |
5813 the translation. This could easily be changed but I | 5815 the translation. This could easily be changed but I |
5814 don't believe that it is worth doing. | 5816 don't believe that it is worth doing. |
5815 | 5817 |
5816 If it->multibyte_p is nonzero, non-printable non-ASCII | 5818 NBSP and SOFT-HYPEN are property translated too. |
5817 characters are also translated to octal form. | 5819 |
5818 | 5820 Non-printable characters and raw-byte characters are also |
5819 If it->multibyte_p is zero, eight-bit characters that | |
5820 don't have corresponding multibyte char code are also | |
5821 translated to octal form. */ | 5821 translated to octal form. */ |
5822 if ((it->c < ' ' | 5822 if (((c < ' ' || c == 127) /* ASCII control chars */ |
5823 ? (it->area != TEXT_AREA | 5823 ? (it->area != TEXT_AREA |
5824 /* In mode line, treat \n, \t like other crl chars. */ | 5824 /* In mode line, treat \n, \t like other crl chars. */ |
5825 || (it->c != '\t' | 5825 || (c != '\t' |
5826 && it->glyph_row | 5826 && it->glyph_row |
5827 && (it->glyph_row->mode_line_p || it->avoid_cursor_p)) | 5827 && (it->glyph_row->mode_line_p || it->avoid_cursor_p)) |
5828 || (it->c != '\n' && it->c != '\t')) | 5828 || (c != '\n' && c != '\t')) |
5829 : (nbsp_or_shy | 5829 : (nbsp_or_shy |
5830 || (it->multibyte_p | 5830 || CHAR_BYTE8_P (c) |
5831 ? ! CHAR_PRINTABLE_P (it->c) | 5831 || ! CHAR_PRINTABLE_P (c)))) |
5832 : (! unibyte_display_via_language_environment | |
5833 ? it->c >= 0x80 | |
5834 : (decoded >= 0x80 && decoded < 0xA0)))))) | |
5835 { | 5832 { |
5836 /* IT->c is a control character which must be displayed | 5833 /* C is a control character, NBSP, SOFT-HYPEN, raw-byte, |
5834 or a non-printable character which must be displayed | |
5837 either as '\003' or as `^C' where the '\\' and '^' | 5835 either as '\003' or as `^C' where the '\\' and '^' |
5838 can be defined in the display table. Fill | 5836 can be defined in the display table. Fill |
5839 IT->ctl_chars with glyphs for what we have to | 5837 IT->ctl_chars with glyphs for what we have to |
5840 display. Then, set IT->dpvec to these glyphs. */ | 5838 display. Then, set IT->dpvec to these glyphs. */ |
5841 Lisp_Object gc; | 5839 Lisp_Object gc; |
5843 int face_id, lface_id = 0 ; | 5841 int face_id, lface_id = 0 ; |
5844 int escape_glyph; | 5842 int escape_glyph; |
5845 | 5843 |
5846 /* Handle control characters with ^. */ | 5844 /* Handle control characters with ^. */ |
5847 | 5845 |
5848 if (it->c < 128 && it->ctl_arrow_p) | 5846 if (ASCII_CHAR_P (c) && it->ctl_arrow_p) |
5849 { | 5847 { |
5850 int g; | 5848 int g; |
5851 | 5849 |
5852 g = '^'; /* default glyph for Control */ | 5850 g = '^'; /* default glyph for Control */ |
5853 /* Set IT->ctl_chars[0] to the glyph for `^'. */ | 5851 /* Set IT->ctl_chars[0] to the glyph for `^'. */ |
5876 last_escape_glyph_face_id = it->face_id; | 5874 last_escape_glyph_face_id = it->face_id; |
5877 last_escape_glyph_merged_face_id = face_id; | 5875 last_escape_glyph_merged_face_id = face_id; |
5878 } | 5876 } |
5879 | 5877 |
5880 XSETINT (it->ctl_chars[0], g); | 5878 XSETINT (it->ctl_chars[0], g); |
5881 XSETINT (it->ctl_chars[1], it->c ^ 0100); | 5879 XSETINT (it->ctl_chars[1], c ^ 0100); |
5882 ctl_len = 2; | 5880 ctl_len = 2; |
5883 goto display_control; | 5881 goto display_control; |
5884 } | 5882 } |
5885 | 5883 |
5886 /* Handle non-break space in the mode where it only gets | 5884 /* Handle non-break space in the mode where it only gets |
5891 { | 5889 { |
5892 /* Merge the no-break-space face into the current face. */ | 5890 /* Merge the no-break-space face into the current face. */ |
5893 face_id = merge_faces (it->f, Qnobreak_space, 0, | 5891 face_id = merge_faces (it->f, Qnobreak_space, 0, |
5894 it->face_id); | 5892 it->face_id); |
5895 | 5893 |
5896 it->c = ' '; | 5894 c = ' '; |
5897 XSETINT (it->ctl_chars[0], ' '); | 5895 XSETINT (it->ctl_chars[0], ' '); |
5898 ctl_len = 1; | 5896 ctl_len = 1; |
5899 goto display_control; | 5897 goto display_control; |
5900 } | 5898 } |
5901 | 5899 |
5937 highlighting. */ | 5935 highlighting. */ |
5938 | 5936 |
5939 if (EQ (Vnobreak_char_display, Qt) | 5937 if (EQ (Vnobreak_char_display, Qt) |
5940 && nbsp_or_shy == char_is_soft_hyphen) | 5938 && nbsp_or_shy == char_is_soft_hyphen) |
5941 { | 5939 { |
5942 it->c = '-'; | |
5943 XSETINT (it->ctl_chars[0], '-'); | 5940 XSETINT (it->ctl_chars[0], '-'); |
5944 ctl_len = 1; | 5941 ctl_len = 1; |
5945 goto display_control; | 5942 goto display_control; |
5946 } | 5943 } |
5947 | 5944 |
5949 with the escape glyph. */ | 5946 with the escape glyph. */ |
5950 | 5947 |
5951 if (nbsp_or_shy) | 5948 if (nbsp_or_shy) |
5952 { | 5949 { |
5953 XSETINT (it->ctl_chars[0], escape_glyph); | 5950 XSETINT (it->ctl_chars[0], escape_glyph); |
5954 it->c = (nbsp_or_shy == char_is_nbsp ? ' ' : '-'); | 5951 c = (nbsp_or_shy == char_is_nbsp ? ' ' : '-'); |
5955 XSETINT (it->ctl_chars[1], it->c); | 5952 XSETINT (it->ctl_chars[1], c); |
5956 ctl_len = 2; | 5953 ctl_len = 2; |
5957 goto display_control; | 5954 goto display_control; |
5958 } | 5955 } |
5959 | 5956 |
5960 { | 5957 { |
5961 unsigned char str[MAX_MULTIBYTE_LENGTH]; | 5958 char str[10]; |
5962 int len; | 5959 int len, i; |
5963 int i; | 5960 |
5964 | 5961 if (CHAR_BYTE8_P (c)) |
5965 /* Set IT->ctl_chars[0] to the glyph for `\\'. */ | 5962 /* Display \200 instead of \17777600. */ |
5966 if (CHAR_BYTE8_P (it->c)) | 5963 c = CHAR_TO_BYTE8 (c); |
5967 { | 5964 len = sprintf (str, "%03o", c); |
5968 str[0] = CHAR_TO_BYTE8 (it->c); | 5965 |
5969 len = 1; | 5966 XSETINT (it->ctl_chars[0], escape_glyph); |
5970 } | |
5971 else if (it->c < 256) | |
5972 { | |
5973 str[0] = it->c; | |
5974 len = 1; | |
5975 } | |
5976 else | |
5977 { | |
5978 /* It's an invalid character, which shouldn't | |
5979 happen actually, but due to bugs it may | |
5980 happen. Let's print the char as is, there's | |
5981 not much meaningful we can do with it. */ | |
5982 str[0] = it->c; | |
5983 str[1] = it->c >> 8; | |
5984 str[2] = it->c >> 16; | |
5985 str[3] = it->c >> 24; | |
5986 len = 4; | |
5987 } | |
5988 | |
5989 for (i = 0; i < len; i++) | 5967 for (i = 0; i < len; i++) |
5990 { | 5968 XSETINT (it->ctl_chars[i + 1], str[i]); |
5991 int g; | 5969 ctl_len = len + 1; |
5992 XSETINT (it->ctl_chars[i * 4], escape_glyph); | |
5993 /* Insert three more glyphs into IT->ctl_chars for | |
5994 the octal display of the character. */ | |
5995 g = ((str[i] >> 6) & 7) + '0'; | |
5996 XSETINT (it->ctl_chars[i * 4 + 1], g); | |
5997 g = ((str[i] >> 3) & 7) + '0'; | |
5998 XSETINT (it->ctl_chars[i * 4 + 2], g); | |
5999 g = (str[i] & 7) + '0'; | |
6000 XSETINT (it->ctl_chars[i * 4 + 3], g); | |
6001 } | |
6002 ctl_len = len * 4; | |
6003 } | 5970 } |
6004 | 5971 |
6005 display_control: | 5972 display_control: |
6006 /* Set up IT->dpvec and return first character from it. */ | 5973 /* Set up IT->dpvec and return first character from it. */ |
6007 it->dpvec_char_len = it->len; | 5974 it->dpvec_char_len = it->len; |
6012 it->saved_face_id = it->face_id; | 5979 it->saved_face_id = it->face_id; |
6013 it->method = GET_FROM_DISPLAY_VECTOR; | 5980 it->method = GET_FROM_DISPLAY_VECTOR; |
6014 it->ellipsis_p = 0; | 5981 it->ellipsis_p = 0; |
6015 goto get_next; | 5982 goto get_next; |
6016 } | 5983 } |
5984 it->char_to_display = c; | |
5985 } | |
5986 else if (success_p) | |
5987 { | |
5988 it->char_to_display = it->c; | |
6017 } | 5989 } |
6018 } | 5990 } |
6019 | 5991 |
6020 #ifdef HAVE_WINDOW_SYSTEM | 5992 #ifdef HAVE_WINDOW_SYSTEM |
6021 /* Adjust face id for a multibyte character. There are no multibyte | 5993 /* Adjust face id for a multibyte character. There are no multibyte |
6038 { | 6010 { |
6039 int pos = (it->s ? -1 | 6011 int pos = (it->s ? -1 |
6040 : STRINGP (it->string) ? IT_STRING_CHARPOS (*it) | 6012 : STRINGP (it->string) ? IT_STRING_CHARPOS (*it) |
6041 : IT_CHARPOS (*it)); | 6013 : IT_CHARPOS (*it)); |
6042 | 6014 |
6043 it->face_id = FACE_FOR_CHAR (it->f, face, it->c, pos, it->string); | 6015 it->face_id = FACE_FOR_CHAR (it->f, face, it->char_to_display, pos, |
6016 it->string); | |
6044 } | 6017 } |
6045 } | 6018 } |
6046 #endif | 6019 #endif |
6047 | 6020 |
6048 /* Is this character the last one of a run of characters with | 6021 /* Is this character the last one of a run of characters with |
16479 { | 16452 { |
16480 Lisp_Object face, ilisp; | 16453 Lisp_Object face, ilisp; |
16481 | 16454 |
16482 /* Get the next character. */ | 16455 /* Get the next character. */ |
16483 if (multibyte_p) | 16456 if (multibyte_p) |
16484 it.c = string_char_and_length (p, &it.len); | 16457 it.c = it.char_to_display = string_char_and_length (p, &it.len); |
16485 else | 16458 else |
16486 it.c = *p, it.len = 1; | 16459 { |
16460 it.c = it.char_to_display = *p, it.len = 1; | |
16461 if (! ASCII_CHAR_P (it.c)) | |
16462 it.char_to_display = BYTE8_TO_CHAR (it.c); | |
16463 } | |
16487 p += it.len; | 16464 p += it.len; |
16488 | 16465 |
16489 /* Get its face. */ | 16466 /* Get its face. */ |
16490 ilisp = make_number (p - arrow_string); | 16467 ilisp = make_number (p - arrow_string); |
16491 face = Fget_text_property (ilisp, Qface, overlay_arrow_string); | 16468 face = Fget_text_property (ilisp, Qface, overlay_arrow_string); |
16492 it.face_id = compute_char_face (f, it.c, face); | 16469 it.face_id = compute_char_face (f, it.char_to_display, face); |
16493 | 16470 |
16494 /* Compute its width, get its glyphs. */ | 16471 /* Compute its width, get its glyphs. */ |
16495 n_glyphs_before = it.glyph_row->used[TEXT_AREA]; | 16472 n_glyphs_before = it.glyph_row->used[TEXT_AREA]; |
16496 SET_TEXT_POS (it.position, -1, -1); | 16473 SET_TEXT_POS (it.position, -1, -1); |
16497 PRODUCE_GLYPHS (&it); | 16474 PRODUCE_GLYPHS (&it); |
16719 Must save IT->c and IT->len because otherwise | 16696 Must save IT->c and IT->len because otherwise |
16720 ITERATOR_AT_END_P wouldn't work anymore after | 16697 ITERATOR_AT_END_P wouldn't work anymore after |
16721 append_space_for_newline has been called. */ | 16698 append_space_for_newline has been called. */ |
16722 enum display_element_type saved_what = it->what; | 16699 enum display_element_type saved_what = it->what; |
16723 int saved_c = it->c, saved_len = it->len; | 16700 int saved_c = it->c, saved_len = it->len; |
16701 int saved_char_to_display = it->char_to_display; | |
16724 int saved_x = it->current_x; | 16702 int saved_x = it->current_x; |
16725 int saved_face_id = it->face_id; | 16703 int saved_face_id = it->face_id; |
16726 struct text_pos saved_pos; | 16704 struct text_pos saved_pos; |
16727 Lisp_Object saved_object; | 16705 Lisp_Object saved_object; |
16728 struct face *face; | 16706 struct face *face; |
16731 saved_pos = it->position; | 16709 saved_pos = it->position; |
16732 | 16710 |
16733 it->what = IT_CHARACTER; | 16711 it->what = IT_CHARACTER; |
16734 memset (&it->position, 0, sizeof it->position); | 16712 memset (&it->position, 0, sizeof it->position); |
16735 it->object = make_number (0); | 16713 it->object = make_number (0); |
16736 it->c = ' '; | 16714 it->c = it->char_to_display = ' '; |
16737 it->len = 1; | 16715 it->len = 1; |
16738 | 16716 |
16739 if (default_face_p) | 16717 if (default_face_p) |
16740 it->face_id = DEFAULT_FACE_ID; | 16718 it->face_id = DEFAULT_FACE_ID; |
16741 else if (it->face_before_selective_p) | 16719 else if (it->face_before_selective_p) |
16752 it->position = saved_pos; | 16730 it->position = saved_pos; |
16753 it->what = saved_what; | 16731 it->what = saved_what; |
16754 it->face_id = saved_face_id; | 16732 it->face_id = saved_face_id; |
16755 it->len = saved_len; | 16733 it->len = saved_len; |
16756 it->c = saved_c; | 16734 it->c = saved_c; |
16735 it->char_to_display = saved_char_to_display; | |
16757 return 1; | 16736 return 1; |
16758 } | 16737 } |
16759 } | 16738 } |
16760 | 16739 |
16761 return 0; | 16740 return 0; |
16884 saved_pos = it->position; | 16863 saved_pos = it->position; |
16885 | 16864 |
16886 it->what = IT_CHARACTER; | 16865 it->what = IT_CHARACTER; |
16887 memset (&it->position, 0, sizeof it->position); | 16866 memset (&it->position, 0, sizeof it->position); |
16888 it->object = make_number (0); | 16867 it->object = make_number (0); |
16889 it->c = ' '; | 16868 it->c = it->char_to_display = ' '; |
16890 it->len = 1; | 16869 it->len = 1; |
16891 /* The last row's blank glyphs should get the default face, to | 16870 /* The last row's blank glyphs should get the default face, to |
16892 avoid painting the rest of the window with the region face, | 16871 avoid painting the rest of the window with the region face, |
16893 if the region ends at ZV. */ | 16872 if the region ends at ZV. */ |
16894 if (it->glyph_row->ends_at_zv_p) | 16873 if (it->glyph_row->ends_at_zv_p) |
20488 if (two_byte_p) | 20467 if (two_byte_p) |
20489 *two_byte_p = 0; | 20468 *two_byte_p = 0; |
20490 | 20469 |
20491 if (face->font) | 20470 if (face->font) |
20492 { | 20471 { |
20493 unsigned code = face->font->driver->encode_char (face->font, glyph->u.ch); | 20472 unsigned code; |
20473 | |
20474 if (CHAR_BYTE8_P (glyph->u.ch)) | |
20475 code = CHAR_TO_BYTE8 (glyph->u.ch); | |
20476 else | |
20477 code = face->font->driver->encode_char (face->font, glyph->u.ch); | |
20494 | 20478 |
20495 if (code != FONT_INVALID_CODE) | 20479 if (code != FONT_INVALID_CODE) |
20496 STORE_XCHAR2B (char2b, (code >> 8), (code & 0xFF)); | 20480 STORE_XCHAR2B (char2b, (code >> 8), (code & 0xFF)); |
20497 else | 20481 else |
20498 STORE_XCHAR2B (char2b, 0, 0); | 20482 STORE_XCHAR2B (char2b, 0, 0); |
20500 | 20484 |
20501 /* Make sure X resources of the face are allocated. */ | 20485 /* Make sure X resources of the face are allocated. */ |
20502 xassert (face != NULL); | 20486 xassert (face != NULL); |
20503 PREPARE_FACE_FOR_DISPLAY (f, face); | 20487 PREPARE_FACE_FOR_DISPLAY (f, face); |
20504 return face; | 20488 return face; |
20489 } | |
20490 | |
20491 | |
20492 /* Get glyph code of character C in FONT in the two-byte form CHAR2B. | |
20493 Retunr 1 if FONT has a glyph for C, otherwise return 0. */ | |
20494 | |
20495 static INLINE int | |
20496 get_char_glyph_code (int c, struct font *font, XChar2b *char2b) | |
20497 { | |
20498 unsigned code; | |
20499 | |
20500 if (CHAR_BYTE8_P (c)) | |
20501 code = CHAR_TO_BYTE8 (c); | |
20502 else | |
20503 code = font->driver->encode_char (font, c); | |
20504 | |
20505 if (code == FONT_INVALID_CODE) | |
20506 return 0; | |
20507 STORE_XCHAR2B (char2b, (code >> 8), (code & 0xFF)); | |
20508 return 1; | |
20505 } | 20509 } |
20506 | 20510 |
20507 | 20511 |
20508 /* Fill glyph string S with composition components specified by S->cmp. | 20512 /* Fill glyph string S with composition components specified by S->cmp. |
20509 | 20513 |
21907 it2 = *it; | 21911 it2 = *it; |
21908 if (it->multibyte_p) | 21912 if (it->multibyte_p) |
21909 { | 21913 { |
21910 int maxlen = ((IT_BYTEPOS (*it) >= GPT ? ZV : GPT) | 21914 int maxlen = ((IT_BYTEPOS (*it) >= GPT ? ZV : GPT) |
21911 - IT_BYTEPOS (*it)); | 21915 - IT_BYTEPOS (*it)); |
21912 it2.c = STRING_CHAR_AND_LENGTH (p, it2.len); | 21916 it2.c = it2.char_to_display = STRING_CHAR_AND_LENGTH (p, it2.len); |
21913 } | 21917 } |
21914 else | 21918 else |
21915 it2.c = *p, it2.len = 1; | 21919 { |
21920 it2.c = it2.char_to_display = *p, it2.len = 1; | |
21921 if (! ASCII_CHAR_P (it2.c)) | |
21922 it2.char_to_display = BYTE8_TO_CHAR (it2.c); | |
21923 } | |
21916 | 21924 |
21917 it2.glyph_row = NULL; | 21925 it2.glyph_row = NULL; |
21918 it2.what = IT_CHARACTER; | 21926 it2.what = IT_CHARACTER; |
21919 x_produce_glyphs (&it2); | 21927 x_produce_glyphs (&it2); |
21920 width = NUMVAL (prop) * it2.pixel_width; | 21928 width = NUMVAL (prop) * it2.pixel_width; |
22080 it->glyph_not_available_p = 0; | 22088 it->glyph_not_available_p = 0; |
22081 | 22089 |
22082 if (it->what == IT_CHARACTER) | 22090 if (it->what == IT_CHARACTER) |
22083 { | 22091 { |
22084 XChar2b char2b; | 22092 XChar2b char2b; |
22085 struct font *font; | |
22086 struct face *face = FACE_FROM_ID (it->f, it->face_id); | 22093 struct face *face = FACE_FROM_ID (it->f, it->face_id); |
22087 struct font_metrics *pcm; | 22094 struct font *font = face->font; |
22088 int font_not_found_p; | 22095 int font_not_found_p = font == NULL; |
22096 struct font_metrics *pcm = NULL; | |
22089 int boff; /* baseline offset */ | 22097 int boff; /* baseline offset */ |
22090 /* We may change it->multibyte_p upon unibyte<->multibyte | 22098 |
22091 conversion. So, save the current value now and restore it | |
22092 later. | |
22093 | |
22094 Note: It seems that we don't have to record multibyte_p in | |
22095 struct glyph because the character code itself tells whether | |
22096 or not the character is multibyte. Thus, in the future, we | |
22097 must consider eliminating the field `multibyte_p' in the | |
22098 struct glyph. */ | |
22099 int saved_multibyte_p = it->multibyte_p; | |
22100 | |
22101 /* Maybe translate single-byte characters to multibyte, or the | |
22102 other way. */ | |
22103 it->char_to_display = it->c; | |
22104 if (!ASCII_BYTE_P (it->c) | |
22105 && ! it->multibyte_p) | |
22106 { | |
22107 if (SINGLE_BYTE_CHAR_P (it->c) | |
22108 && unibyte_display_via_language_environment) | |
22109 { | |
22110 struct charset *unibyte = CHARSET_FROM_ID (charset_unibyte); | |
22111 | |
22112 /* get_next_display_element assures that this decoding | |
22113 never fails. */ | |
22114 it->char_to_display = DECODE_CHAR (unibyte, it->c); | |
22115 it->multibyte_p = 1; | |
22116 it->face_id = FACE_FOR_CHAR (it->f, face, it->char_to_display, | |
22117 -1, Qnil); | |
22118 face = FACE_FROM_ID (it->f, it->face_id); | |
22119 } | |
22120 } | |
22121 | |
22122 /* Get font to use. Encode IT->char_to_display. */ | |
22123 get_char_face_and_encoding (it->f, it->char_to_display, it->face_id, | |
22124 &char2b, it->multibyte_p, 0); | |
22125 font = face->font; | |
22126 | |
22127 font_not_found_p = font == NULL; | |
22128 if (font_not_found_p) | 22099 if (font_not_found_p) |
22129 { | 22100 { |
22130 /* When no suitable font found, display an empty box based | 22101 /* When no suitable font found, display an empty box based |
22131 on the metrics of the font of the default face (or what | 22102 on the metrics of the font of the default face (or what |
22132 remapped). */ | 22103 remapped). */ |
22142 boff = font->baseline_offset; | 22113 boff = font->baseline_offset; |
22143 if (font->vertical_centering) | 22114 if (font->vertical_centering) |
22144 boff = VCENTER_BASELINE_OFFSET (font, it->f) - boff; | 22115 boff = VCENTER_BASELINE_OFFSET (font, it->f) - boff; |
22145 } | 22116 } |
22146 | 22117 |
22147 if (it->char_to_display >= ' ' | 22118 if (it->char_to_display != '\n' && it->char_to_display != '\t') |
22148 && (!it->multibyte_p || it->char_to_display < 128)) | 22119 { |
22149 { | |
22150 /* Either unibyte or ASCII. */ | |
22151 int stretched_p; | 22120 int stretched_p; |
22152 | 22121 |
22153 it->nglyphs = 1; | 22122 it->nglyphs = 1; |
22154 | |
22155 pcm = get_per_char_metric (it->f, font, &char2b); | |
22156 | 22123 |
22157 if (it->override_ascent >= 0) | 22124 if (it->override_ascent >= 0) |
22158 { | 22125 { |
22159 it->ascent = it->override_ascent; | 22126 it->ascent = it->override_ascent; |
22160 it->descent = it->override_descent; | 22127 it->descent = it->override_descent; |
22164 { | 22131 { |
22165 it->ascent = FONT_BASE (font) + boff; | 22132 it->ascent = FONT_BASE (font) + boff; |
22166 it->descent = FONT_DESCENT (font) - boff; | 22133 it->descent = FONT_DESCENT (font) - boff; |
22167 } | 22134 } |
22168 | 22135 |
22136 if (! font_not_found_p | |
22137 && get_char_glyph_code (it->char_to_display, font, &char2b)) | |
22138 { | |
22139 pcm = get_per_char_metric (it->f, font, &char2b); | |
22140 if (pcm->width == 0 | |
22141 && pcm->rbearing == 0 && pcm->lbearing == 0) | |
22142 pcm = NULL; | |
22143 } | |
22144 | |
22169 if (pcm) | 22145 if (pcm) |
22170 { | 22146 { |
22171 it->phys_ascent = pcm->ascent + boff; | 22147 it->phys_ascent = pcm->ascent + boff; |
22172 it->phys_descent = pcm->descent - boff; | 22148 it->phys_descent = pcm->descent - boff; |
22173 it->pixel_width = pcm->width; | 22149 it->pixel_width = pcm->width; |
22175 else | 22151 else |
22176 { | 22152 { |
22177 it->glyph_not_available_p = 1; | 22153 it->glyph_not_available_p = 1; |
22178 it->phys_ascent = it->ascent; | 22154 it->phys_ascent = it->ascent; |
22179 it->phys_descent = it->descent; | 22155 it->phys_descent = it->descent; |
22180 it->pixel_width = FONT_WIDTH (font); | 22156 it->pixel_width = font->space_width; |
22181 } | 22157 } |
22182 | 22158 |
22183 if (it->constrain_row_ascent_descent_p) | 22159 if (it->constrain_row_ascent_descent_p) |
22184 { | 22160 { |
22185 if (it->descent > it->max_descent) | 22161 if (it->descent > it->max_descent) |
22349 if (!NILP (total_height)) | 22325 if (!NILP (total_height)) |
22350 extra_line_spacing -= (it->phys_ascent + it->phys_descent); | 22326 extra_line_spacing -= (it->phys_ascent + it->phys_descent); |
22351 } | 22327 } |
22352 } | 22328 } |
22353 } | 22329 } |
22354 else if (it->char_to_display == '\t') | 22330 else /* i.e. (it->char_to_display == '\t') */ |
22355 { | 22331 { |
22356 if (font->space_width > 0) | 22332 if (font->space_width > 0) |
22357 { | 22333 { |
22358 int tab_width = it->tab_width * font->space_width; | 22334 int tab_width = it->tab_width * font->space_width; |
22359 int x = it->current_x + it->continuation_lines_width; | 22335 int x = it->current_x + it->continuation_lines_width; |
22380 { | 22356 { |
22381 it->pixel_width = 0; | 22357 it->pixel_width = 0; |
22382 it->nglyphs = 1; | 22358 it->nglyphs = 1; |
22383 } | 22359 } |
22384 } | 22360 } |
22385 else | |
22386 { | |
22387 /* A multi-byte character. Assume that the display width of the | |
22388 character is the width of the character multiplied by the | |
22389 width of the font. */ | |
22390 | |
22391 /* If we found a font, this font should give us the right | |
22392 metrics. If we didn't find a font, use the frame's | |
22393 default font and calculate the width of the character by | |
22394 multiplying the width of font by the width of the | |
22395 character. */ | |
22396 | |
22397 pcm = get_per_char_metric (it->f, font, &char2b); | |
22398 | |
22399 if (font_not_found_p || !pcm) | |
22400 { | |
22401 int char_width = CHAR_WIDTH (it->char_to_display); | |
22402 | |
22403 if (char_width == 0) | |
22404 /* This is a non spacing character. But, as we are | |
22405 going to display an empty box, the box must occupy | |
22406 at least one column. */ | |
22407 char_width = 1; | |
22408 it->glyph_not_available_p = 1; | |
22409 it->pixel_width = font->space_width * char_width; | |
22410 it->phys_ascent = FONT_BASE (font) + boff; | |
22411 it->phys_descent = FONT_DESCENT (font) - boff; | |
22412 } | |
22413 else | |
22414 { | |
22415 it->pixel_width = pcm->width; | |
22416 it->phys_ascent = pcm->ascent + boff; | |
22417 it->phys_descent = pcm->descent - boff; | |
22418 if (it->glyph_row | |
22419 && (pcm->lbearing < 0 | |
22420 || pcm->rbearing > pcm->width)) | |
22421 it->glyph_row->contains_overlapping_glyphs_p = 1; | |
22422 } | |
22423 it->nglyphs = 1; | |
22424 it->ascent = FONT_BASE (font) + boff; | |
22425 it->descent = FONT_DESCENT (font) - boff; | |
22426 if (face->box != FACE_NO_BOX) | |
22427 { | |
22428 int thick = face->box_line_width; | |
22429 | |
22430 if (thick > 0) | |
22431 { | |
22432 it->ascent += thick; | |
22433 it->descent += thick; | |
22434 } | |
22435 else | |
22436 thick = - thick; | |
22437 | |
22438 if (it->start_of_box_run_p) | |
22439 it->pixel_width += thick; | |
22440 if (it->end_of_box_run_p) | |
22441 it->pixel_width += thick; | |
22442 } | |
22443 | |
22444 /* If face has an overline, add the height of the overline | |
22445 (1 pixel) and a 1 pixel margin to the character height. */ | |
22446 if (face->overline_p) | |
22447 it->ascent += overline_margin; | |
22448 | |
22449 take_vertical_position_into_account (it); | |
22450 | |
22451 if (it->ascent < 0) | |
22452 it->ascent = 0; | |
22453 if (it->descent < 0) | |
22454 it->descent = 0; | |
22455 | |
22456 if (it->glyph_row) | |
22457 append_glyph (it); | |
22458 if (it->pixel_width == 0) | |
22459 /* We assure that all visible glyphs have at least 1-pixel | |
22460 width. */ | |
22461 it->pixel_width = 1; | |
22462 } | |
22463 it->multibyte_p = saved_multibyte_p; | |
22464 } | 22361 } |
22465 else if (it->what == IT_COMPOSITION && it->cmp_it.ch < 0) | 22362 else if (it->what == IT_COMPOSITION && it->cmp_it.ch < 0) |
22466 { | 22363 { |
22467 /* A static composition. | 22364 /* A static composition. |
22468 | 22365 |
22554 lbearing = pcm->lbearing; | 22451 lbearing = pcm->lbearing; |
22555 rbearing = pcm->rbearing; | 22452 rbearing = pcm->rbearing; |
22556 } | 22453 } |
22557 else | 22454 else |
22558 { | 22455 { |
22559 width = FONT_WIDTH (font); | 22456 width = font->space_width; |
22560 ascent = FONT_BASE (font); | 22457 ascent = FONT_BASE (font); |
22561 descent = FONT_DESCENT (font); | 22458 descent = FONT_DESCENT (font); |
22562 lbearing = 0; | 22459 lbearing = 0; |
22563 rbearing = width; | 22460 rbearing = width; |
22564 } | 22461 } |