aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorKenichi Handa2006-10-16 07:26:19 +0000
committerKenichi Handa2006-10-16 07:26:19 +0000
commit83b364b4eb9cf5e5a2f16075e0089eaba9243484 (patch)
tree3ed75fe2651875a214cd07b41a7780f51d71457c /src
parentbb9c4b4f8b3dcd1b5fc96d2d0275cc532832fbd6 (diff)
downloademacs-83b364b4eb9cf5e5a2f16075e0089eaba9243484.tar.gz
emacs-83b364b4eb9cf5e5a2f16075e0089eaba9243484.zip
(handle_composition_prop): Set it->c to the first
non-TAB component. (fill_composite_glyph_string): Argument changed. (BUILD_COMPOSITE_GLYPH_STRING): Adjusted for the above change. (x_produce_glyphs): Fix handling of left/right padding.
Diffstat (limited to 'src')
-rw-r--r--src/xdisp.c713
1 files changed, 339 insertions, 374 deletions
diff --git a/src/xdisp.c b/src/xdisp.c
index fb30722d8b8..87f6c49ad36 100644
--- a/src/xdisp.c
+++ b/src/xdisp.c
@@ -4655,24 +4655,29 @@ handle_composition_prop (it)
4655 it->method = GET_FROM_COMPOSITION; 4655 it->method = GET_FROM_COMPOSITION;
4656 it->cmp_id = id; 4656 it->cmp_id = id;
4657 it->cmp_len = COMPOSITION_LENGTH (prop); 4657 it->cmp_len = COMPOSITION_LENGTH (prop);
4658 /* For a terminal, draw only the first (non-TAB) character
4659 of the components. */
4658#ifdef USE_FONT_BACKEND 4660#ifdef USE_FONT_BACKEND
4659 if (composition_table[id]->method == COMPOSITION_WITH_GLYPH_STRING) 4661 if (composition_table[id]->method == COMPOSITION_WITH_GLYPH_STRING)
4660 { 4662 {
4661 Lisp_Object lgstring = AREF (XHASH_TABLE (composition_hash_table) 4663 Lisp_Object lgstring = AREF (XHASH_TABLE (composition_hash_table)
4662 ->key_and_value, 4664 ->key_and_value,
4663 cmp->hash_index * 2); 4665 cmp->hash_index * 2);
4664 Lisp_Object font_object = LGSTRING_FONT (lgstring);
4665 struct font *font = XSAVE_VALUE (font_object)->pointer;
4666 struct face *face = FACE_FROM_ID (it->f, it->face_id);
4667 4666
4668 it->face_id = face_for_font (it->f, font, face); 4667 it->c = XINT (LGLYPH_CHAR (LGSTRING_GLYPH (lgstring, 0)));
4669 it->c = ' ';
4670 } 4668 }
4671 else 4669 else
4672#endif /* USE_FONT_BACKEND */ 4670#endif /* USE_FONT_BACKEND */
4673 /* For a terminal, draw only the first character of the 4671 {
4674 components. */ 4672 int i;
4675 it->c = COMPOSITION_GLYPH (composition_table[id], 0); 4673
4674 for (i = 0; i < cmp->glyph_len; i++)
4675 if ((it->c = COMPOSITION_GLYPH (composition_table[id], i))
4676 != '\t')
4677 break;
4678 }
4679 if (it->c == '\t')
4680 it->c = ' ';
4676 it->len = (STRINGP (it->string) 4681 it->len = (STRINGP (it->string)
4677 ? string_char_to_byte (it->string, end) 4682 ? string_char_to_byte (it->string, end)
4678 : CHAR_TO_BYTE (end)) - pos_byte; 4683 : CHAR_TO_BYTE (end)) - pos_byte;
@@ -18898,6 +18903,80 @@ append_glyph_string (head, tail, s)
18898} 18903}
18899 18904
18900 18905
18906/* Get face and two-byte form of character C in face FACE_ID on frame
18907 F. The encoding of C is returned in *CHAR2B. MULTIBYTE_P non-zero
18908 means we want to display multibyte text. DISPLAY_P non-zero means
18909 make sure that X resources for the face returned are allocated.
18910 Value is a pointer to a realized face that is ready for display if
18911 DISPLAY_P is non-zero. */
18912
18913static INLINE struct face *
18914get_char_face_and_encoding (f, c, face_id, char2b, multibyte_p, display_p)
18915 struct frame *f;
18916 int c, face_id;
18917 XChar2b *char2b;
18918 int multibyte_p, display_p;
18919{
18920 struct face *face = FACE_FROM_ID (f, face_id);
18921
18922#ifdef USE_FONT_BACKEND
18923 if (enable_font_backend)
18924 {
18925 struct font *font = (struct font *) face->font_info;
18926
18927 if (font)
18928 {
18929 unsigned code = font->driver->encode_char (font, c);
18930
18931 if (code != FONT_INVALID_CODE)
18932 STORE_XCHAR2B (char2b, (code >> 8), (code & 0xFF));
18933 else
18934 STORE_XCHAR2B (char2b, 0, 0);
18935 }
18936 }
18937 else
18938#endif /* USE_FONT_BACKEND */
18939 if (!multibyte_p)
18940 {
18941 /* Unibyte case. We don't have to encode, but we have to make
18942 sure to use a face suitable for unibyte. */
18943 STORE_XCHAR2B (char2b, 0, c);
18944 face_id = FACE_FOR_CHAR (f, face, c, -1, Qnil);
18945 face = FACE_FROM_ID (f, face_id);
18946 }
18947 else if (c < 128)
18948 {
18949 /* Case of ASCII in a face known to fit ASCII. */
18950 STORE_XCHAR2B (char2b, 0, c);
18951 }
18952 else if (face->font != NULL)
18953 {
18954 struct font_info *font_info
18955 = FONT_INFO_FROM_ID (f, face->font_info_id);
18956 struct charset *charset = CHARSET_FROM_ID (font_info->charset);
18957 unsigned code = ENCODE_CHAR (charset, c);
18958
18959 if (CHARSET_DIMENSION (charset) == 1)
18960 STORE_XCHAR2B (char2b, 0, code);
18961 else
18962 STORE_XCHAR2B (char2b, (code >> 8), (code & 0xFF));
18963 /* Maybe encode the character in *CHAR2B. */
18964 rif->encode_char (c, char2b, font_info, charset, NULL);
18965 }
18966
18967 /* Make sure X resources of the face are allocated. */
18968#ifdef HAVE_X_WINDOWS
18969 if (display_p)
18970#endif
18971 {
18972 xassert (face != NULL);
18973 PREPARE_FACE_FOR_DISPLAY (f, face);
18974 }
18975
18976 return face;
18977}
18978
18979
18901/* Get face and two-byte form of character glyph GLYPH on frame F. 18980/* Get face and two-byte form of character glyph GLYPH on frame F.
18902 The encoding of GLYPH->u.ch is returned in *CHAR2B. Value is 18981 The encoding of GLYPH->u.ch is returned in *CHAR2B. Value is
18903 a pointer to a realized face that is ready for display. */ 18982 a pointer to a realized face that is ready for display. */
@@ -18978,7 +19057,7 @@ get_glyph_face_and_encoding (f, glyph, char2b, two_byte_p)
18978 19057
18979/* Fill glyph string S with composition components specified by S->cmp. 19058/* Fill glyph string S with composition components specified by S->cmp.
18980 19059
18981 FACES is an array of faces for all components of this composition. 19060 BASE_FACE is the base face of the composition.
18982 S->gidx is the index of the first component for S. 19061 S->gidx is the index of the first component for S.
18983 19062
18984 OVERLAPS non-zero means S should draw the foreground only, and use 19063 OVERLAPS non-zero means S should draw the foreground only, and use
@@ -18987,9 +19066,9 @@ get_glyph_face_and_encoding (f, glyph, char2b, two_byte_p)
18987 Value is the index of a component not in S. */ 19066 Value is the index of a component not in S. */
18988 19067
18989static int 19068static int
18990fill_composite_glyph_string (s, faces, overlaps) 19069fill_composite_glyph_string (s, base_face, overlaps)
18991 struct glyph_string *s; 19070 struct glyph_string *s;
18992 struct face **faces; 19071 struct face *base_face;
18993 int overlaps; 19072 int overlaps;
18994{ 19073{
18995 int i; 19074 int i;
@@ -18998,18 +19077,6 @@ fill_composite_glyph_string (s, faces, overlaps)
18998 19077
18999 s->for_overlaps = overlaps; 19078 s->for_overlaps = overlaps;
19000 19079
19001 s->face = faces[s->gidx];
19002 if (s->face == NULL)
19003 {
19004 s->font = NULL;
19005 s->font_info = NULL;
19006 }
19007 else
19008 {
19009 s->font = s->face->font;
19010 s->font_info = FONT_INFO_FROM_FACE (s->f, s->face);
19011 }
19012
19013#ifdef USE_FONT_BACKEND 19080#ifdef USE_FONT_BACKEND
19014 if (enable_font_backend && s->cmp->method == COMPOSITION_WITH_GLYPH_STRING) 19081 if (enable_font_backend && s->cmp->method == COMPOSITION_WITH_GLYPH_STRING)
19015 { 19082 {
@@ -19017,6 +19084,9 @@ fill_composite_glyph_string (s, faces, overlaps)
19017 = AREF (XHASH_TABLE (composition_hash_table)->key_and_value, 19084 = AREF (XHASH_TABLE (composition_hash_table)->key_and_value,
19018 s->cmp->hash_index * 2); 19085 s->cmp->hash_index * 2);
19019 19086
19087 s->face = base_face;
19088 s->font_info = s->cmp->font;
19089 s->font = s->font_info->font;
19020 for (i = 0, s->nchars = 0; i < s->cmp->glyph_len; i++, s->nchars++) 19090 for (i = 0, s->nchars = 0; i < s->cmp->glyph_len; i++, s->nchars++)
19021 { 19091 {
19022 Lisp_Object g = LGSTRING_GLYPH (gstring, i); 19092 Lisp_Object g = LGSTRING_GLYPH (gstring, i);
@@ -19030,24 +19100,45 @@ fill_composite_glyph_string (s, faces, overlaps)
19030 s->width = s->cmp->pixel_width; 19100 s->width = s->cmp->pixel_width;
19031 } 19101 }
19032 else 19102 else
19033 {
19034#endif /* USE_FONT_BACKEND */ 19103#endif /* USE_FONT_BACKEND */
19035 /* For all glyphs of this composition, starting at the offset 19104 {
19036 S->gidx, until we reach the end of the definition or encounter a 19105 /* For all glyphs of this composition, starting at the offset
19037 glyph that requires the different face, add it to S. */ 19106 S->gidx, until we reach the end of the definition or encounter a
19038 ++s->nchars; 19107 glyph that requires the different face, add it to S. */
19039 for (i = s->gidx + 1; 19108 struct face *face;
19040 i < s->cmp->glyph_len && (faces[i] == s->face || ! faces[i] || ! s->face);
19041 ++i)
19042 ++s->nchars;
19043
19044 /* All glyph strings for the same composition has the same width,
19045 i.e. the width set for the first component of the composition. */
19046 19109
19047 s->width = s->first_glyph->pixel_width; 19110 s->face = NULL;
19048#ifdef USE_FONT_BACKEND 19111 s->font = NULL;
19112 s->font_info = NULL;
19113 for (i = s->gidx; i < s->cmp->glyph_len; i++)
19114 {
19115 int c = COMPOSITION_GLYPH (s->cmp, i);
19116
19117 if (c != '\t')
19118 {
19119 int face_id = FACE_FOR_CHAR (s->f, base_face, c, -1, Qnil);
19120
19121 face = get_char_face_and_encoding (s->f, c, face_id,
19122 s->char2b + i, 1, 1);
19123 if (face)
19124 {
19125 if (! s->face)
19126 {
19127 s->face = face;
19128 s->font = s->face->font;
19129 s->font_info = FONT_INFO_FROM_FACE (s->f, s->face);
19130 }
19131 else if (s->face != face)
19132 break;
19133 }
19134 }
19135 ++s->nchars;
19136 }
19137
19138 /* All glyph strings for the same composition has the same width,
19139 i.e. the width set for the first component of the composition. */
19140 s->width = s->first_glyph->pixel_width;
19049 } 19141 }
19050#endif /* USE_FONT_BACKEND */
19051 19142
19052 /* If the specified font could not be loaded, use the frame's 19143 /* If the specified font could not be loaded, use the frame's
19053 default font, but record the fact that we couldn't load it in 19144 default font, but record the fact that we couldn't load it in
@@ -19388,80 +19479,6 @@ right_overwriting (s)
19388} 19479}
19389 19480
19390 19481
19391/* Get face and two-byte form of character C in face FACE_ID on frame
19392 F. The encoding of C is returned in *CHAR2B. MULTIBYTE_P non-zero
19393 means we want to display multibyte text. DISPLAY_P non-zero means
19394 make sure that X resources for the face returned are allocated.
19395 Value is a pointer to a realized face that is ready for display if
19396 DISPLAY_P is non-zero. */
19397
19398static INLINE struct face *
19399get_char_face_and_encoding (f, c, face_id, char2b, multibyte_p, display_p)
19400 struct frame *f;
19401 int c, face_id;
19402 XChar2b *char2b;
19403 int multibyte_p, display_p;
19404{
19405 struct face *face = FACE_FROM_ID (f, face_id);
19406
19407#ifdef USE_FONT_BACKEND
19408 if (enable_font_backend)
19409 {
19410 struct font *font = (struct font *) face->font_info;
19411
19412 if (font)
19413 {
19414 unsigned code = font->driver->encode_char (font, c);
19415
19416 if (code != FONT_INVALID_CODE)
19417 STORE_XCHAR2B (char2b, (code >> 8), (code & 0xFF));
19418 else
19419 STORE_XCHAR2B (char2b, 0, 0);
19420 }
19421 }
19422 else
19423#endif /* USE_FONT_BACKEND */
19424 if (!multibyte_p)
19425 {
19426 /* Unibyte case. We don't have to encode, but we have to make
19427 sure to use a face suitable for unibyte. */
19428 STORE_XCHAR2B (char2b, 0, c);
19429 face_id = FACE_FOR_CHAR (f, face, c, -1, Qnil);
19430 face = FACE_FROM_ID (f, face_id);
19431 }
19432 else if (c < 128)
19433 {
19434 /* Case of ASCII in a face known to fit ASCII. */
19435 STORE_XCHAR2B (char2b, 0, c);
19436 }
19437 else if (face->font != NULL)
19438 {
19439 struct font_info *font_info
19440 = FONT_INFO_FROM_ID (f, face->font_info_id);
19441 struct charset *charset = CHARSET_FROM_ID (font_info->charset);
19442 unsigned code = ENCODE_CHAR (charset, c);
19443
19444 if (CHARSET_DIMENSION (charset) == 1)
19445 STORE_XCHAR2B (char2b, 0, code);
19446 else
19447 STORE_XCHAR2B (char2b, (code >> 8), (code & 0xFF));
19448 /* Maybe encode the character in *CHAR2B. */
19449 rif->encode_char (c, char2b, font_info, charset, NULL);
19450 }
19451
19452 /* Make sure X resources of the face are allocated. */
19453#ifdef HAVE_X_WINDOWS
19454 if (display_p)
19455#endif
19456 {
19457 xassert (face != NULL);
19458 PREPARE_FACE_FOR_DISPLAY (f, face);
19459 }
19460
19461 return face;
19462}
19463
19464
19465/* Set background width of glyph string S. START is the index of the 19482/* Set background width of glyph string S. START is the index of the
19466 first glyph following S. LAST_X is the right-most x-position + 1 19483 first glyph following S. LAST_X is the right-most x-position + 1
19467 in the drawing area. */ 19484 in the drawing area. */
@@ -19626,64 +19643,35 @@ compute_overhangs_and_x (s, x, backward_p)
19626 x-position of the drawing area. */ 19643 x-position of the drawing area. */
19627 19644
19628#define BUILD_COMPOSITE_GLYPH_STRING(START, END, HEAD, TAIL, HL, X, LAST_X) \ 19645#define BUILD_COMPOSITE_GLYPH_STRING(START, END, HEAD, TAIL, HL, X, LAST_X) \
19629 do { \ 19646 do { \
19630 int cmp_id = (row)->glyphs[area][START].u.cmp_id; \ 19647 int face_id = (row)->glyphs[area][START].face_id; \
19631 int face_id = (row)->glyphs[area][START].face_id; \ 19648 struct face *base_face = FACE_FROM_ID (f, face_id); \
19632 struct face *base_face = FACE_FROM_ID (f, face_id); \ 19649 int cmp_id = (row)->glyphs[area][START].u.cmp_id; \
19633 struct composition *cmp = composition_table[cmp_id]; \ 19650 struct composition *cmp = composition_table[cmp_id]; \
19634 int glyph_len = cmp->glyph_len; \ 19651 XChar2b *char2b; \
19635 XChar2b *char2b; \ 19652 struct glyph_string *first_s; \
19636 struct face **faces; \ 19653 int n; \
19637 struct glyph_string *first_s = NULL; \ 19654 \
19638 int n; \ 19655 char2b = (XChar2b *) alloca ((sizeof *char2b) * cmp->glyph_len); \
19639 \ 19656 base_face = base_face->ascii_face; \
19640 if (cmp->method > COMPOSITION_WITH_RULE_ALTCHARS) \ 19657 \
19641 { \ 19658 /* Make glyph_strings for each glyph sequence that is drawable by \
19642 /* This happens only when USE_FONT_BACKEND is defined. */ \ 19659 the same face, and append them to HEAD/TAIL. */ \
19643 char2b = (XChar2b *) alloca ((sizeof *char2b) * glyph_len); \ 19660 for (n = 0; n < cmp->glyph_len;) \
19644 faces = &base_face; \ 19661 { \
19645 } \ 19662 s = (struct glyph_string *) alloca (sizeof *s); \
19646 else \ 19663 INIT_GLYPH_STRING (s, char2b, w, row, area, START, HL); \
19647 { \ 19664 append_glyph_string (&(HEAD), &(TAIL), s); \
19648 base_face = base_face->ascii_face; \ 19665 s->cmp = cmp; \
19649 char2b = (XChar2b *) alloca ((sizeof *char2b) * glyph_len); \ 19666 s->gidx = n; \
19650 faces = (struct face **) alloca ((sizeof *faces) * glyph_len); \ 19667 s->x = (X); \
19651 /* At first, fill in `char2b' and `faces'. */ \ 19668 if (n == 0) \
19652 for (n = 0; n < glyph_len; n++) \ 19669 first_s = s; \
19653 { \ 19670 n = fill_composite_glyph_string (s, base_face, overlaps); \
19654 int c = COMPOSITION_GLYPH (cmp, n); \ 19671 } \
19655 \ 19672 \
19656 if (c == '\t') \ 19673 ++START; \
19657 faces[n] = NULL; \ 19674 s = first_s; \
19658 else \
19659 { \
19660 int this_face_id = FACE_FOR_CHAR (f, base_face, c, -1, Qnil); \
19661 faces[n] = FACE_FROM_ID (f, this_face_id); \
19662 get_char_face_and_encoding (f, c, this_face_id, \
19663 char2b + n, 1, 1); \
19664 } \
19665 } \
19666 } \
19667 \
19668 /* Make glyph_strings for each glyph sequence that is drawable by \
19669 the same face, and append them to HEAD/TAIL. */ \
19670 for (n = 0; n < cmp->glyph_len;) \
19671 { \
19672 s = (struct glyph_string *) alloca (sizeof *s); \
19673 INIT_GLYPH_STRING (s, char2b + n, w, row, area, START, HL); \
19674 append_glyph_string (&(HEAD), &(TAIL), s); \
19675 s->cmp = cmp; \
19676 s->gidx = n; \
19677 s->x = (X); \
19678 \
19679 if (n == 0) \
19680 first_s = s; \
19681 \
19682 n = fill_composite_glyph_string (s, faces, overlaps); \
19683 } \
19684 \
19685 ++START; \
19686 s = first_s; \
19687 } while (0) 19675 } while (0)
19688 19676
19689 19677
@@ -20557,7 +20545,7 @@ x_produce_glyphs (it)
20557 if (SINGLE_BYTE_CHAR_P (it->c) 20545 if (SINGLE_BYTE_CHAR_P (it->c)
20558 && unibyte_display_via_language_environment) 20546 && unibyte_display_via_language_environment)
20559 it->char_to_display = unibyte_char_to_multibyte (it->c); 20547 it->char_to_display = unibyte_char_to_multibyte (it->c);
20560 if (! SINGLE_BYTE_CHAR_P (it->c)) 20548 if (! SINGLE_BYTE_CHAR_P (it->char_to_display))
20561 { 20549 {
20562 it->multibyte_p = 1; 20550 it->multibyte_p = 1;
20563 it->face_id = FACE_FOR_CHAR (it->f, face, it->char_to_display, 20551 it->face_id = FACE_FOR_CHAR (it->f, face, it->char_to_display,
@@ -20883,63 +20871,25 @@ x_produce_glyphs (it)
20883 else if (it->what == IT_COMPOSITION) 20871 else if (it->what == IT_COMPOSITION)
20884 { 20872 {
20885 /* Note: A composition is represented as one glyph in the 20873 /* Note: A composition is represented as one glyph in the
20886 glyph matrix. There are no padding glyphs. */ 20874 glyph matrix. There are no padding glyphs.
20887 XChar2b char2b; 20875
20888 XFontStruct *font; 20876 Important is that pixel_width, ascent, and descent are the
20877 values of what is drawn by draw_glyphs (i.e. the values of
20878 the overall glyphs composed). */
20889 struct face *face = FACE_FROM_ID (it->f, it->face_id); 20879 struct face *face = FACE_FROM_ID (it->f, it->face_id);
20890 XCharStruct *pcm;
20891 int font_not_found_p;
20892 struct font_info *font_info;
20893 int boff; /* baseline offset */ 20880 int boff; /* baseline offset */
20894 struct composition *cmp = composition_table[it->cmp_id]; 20881 struct composition *cmp = composition_table[it->cmp_id];
20895 int pos;
20896 20882
20897 /* Maybe translate single-byte characters to multibyte. */ 20883 it->nglyphs = 1;
20898 it->char_to_display = it->c;
20899 if (unibyte_display_via_language_environment
20900 && it->c >= 0200)
20901 {
20902 it->char_to_display = unibyte_char_to_multibyte (it->c);
20903 }
20904 20884
20905#ifdef USE_FONT_BACKEND 20885#ifdef USE_FONT_BACKEND
20906 if (cmp->method != COMPOSITION_WITH_GLYPH_STRING) 20886 if (cmp->method == COMPOSITION_WITH_GLYPH_STRING)
20907 { 20887 {
20908#endif /* USE_FONT_BACKEND */ 20888 if (! cmp->font)
20909 /* Get face and font to use. Encode IT->char_to_display. */ 20889 font_prepare_composition (cmp);
20910 pos = STRINGP (it->string) ? IT_STRING_CHARPOS (*it) : IT_CHARPOS (*it);
20911 it->face_id = FACE_FOR_CHAR (it->f, face, it->char_to_display,
20912 pos, it->string);
20913 face = FACE_FROM_ID (it->f, it->face_id);
20914 get_char_face_and_encoding (it->f, it->char_to_display, it->face_id,
20915 &char2b, it->multibyte_p, 0);
20916 font = face->font;
20917
20918 /* When no suitable font found, use the default font. */
20919 font_not_found_p = font == NULL;
20920 if (font_not_found_p)
20921 {
20922 font = FRAME_FONT (it->f);
20923 boff = FRAME_BASELINE_OFFSET (it->f);
20924 font_info = NULL;
20925 } 20890 }
20926 else 20891 else
20927 { 20892#endif /* USE_FONT_BACKEND */
20928 font_info = FONT_INFO_FROM_FACE (it->f, face);
20929 boff = font_info->baseline_offset;
20930 if (font_info->vertical_centering)
20931 boff = VCENTER_BASELINE_OFFSET (font, it->f) - boff;
20932 }
20933#ifdef USE_FONT_BACKEND
20934 }
20935#endif
20936
20937 /* There are no padding glyphs, so there is only one glyph to
20938 produce for the composition. Important is that pixel_width,
20939 ascent and descent are the values of what is drawn by
20940 draw_glyphs (i.e. the values of the overall glyphs composed). */
20941 it->nglyphs = 1;
20942
20943 /* If we have not yet calculated pixel size data of glyphs of 20893 /* If we have not yet calculated pixel size data of glyphs of
20944 the composition for the current face font, calculate them 20894 the composition for the current face font, calculate them
20945 now. Theoretically, we have to check all fonts for the 20895 now. Theoretically, we have to check all fonts for the
@@ -20947,49 +20897,79 @@ x_produce_glyphs (it)
20947 here we check only the font of the first glyph. This leads 20897 here we check only the font of the first glyph. This leads
20948 to incorrect display, but it's very rare, and C-l (recenter) 20898 to incorrect display, but it's very rare, and C-l (recenter)
20949 can correct the display anyway. */ 20899 can correct the display anyway. */
20950 if (cmp->glyph_len == 0) 20900 if (! cmp->font)
20951 { 20901 {
20952 cmp->lbearing = cmp->rbearing = 0; 20902 /* Ascent and descent of the font of the first character
20953 cmp->pixel_width = cmp->ascent = cmp->descent = 0; 20903 of this composition (adjusted by baseline offset).
20954 } 20904 Ascent and descent of overall glyphs should not be less
20955#ifdef USE_FONT_BACKEND 20905 than them respectively. */
20956 else if (cmp->method == COMPOSITION_WITH_GLYPH_STRING) 20906 int font_ascent, font_descent, font_height;
20957 {
20958 if (! cmp->font)
20959 font_prepare_composition (cmp);
20960 }
20961#endif /* USE_FONT_BACKEND */
20962 else if (cmp->font != (void *) font)
20963 {
20964 /* Ascent and descent of the font of the first character of
20965 this composition (adjusted by baseline offset). Ascent
20966 and descent of overall glyphs should not be less than
20967 them respectively. */
20968 int font_ascent = FONT_BASE (font) + boff;
20969 int font_descent = FONT_DESCENT (font) - boff;
20970 int font_height = FONT_HEIGHT (font);
20971 /* Bounding box of the overall glyphs. */ 20907 /* Bounding box of the overall glyphs. */
20972 int leftmost, rightmost, lowest, highest; 20908 int leftmost, rightmost, lowest, highest;
20973 int lbearing, rbearing; 20909 int lbearing, rbearing;
20974 int i, width, ascent, descent; 20910 int i, width, ascent, descent;
20975 int fully_padded = 0; 20911 int left_padded = 0, right_padded = 0;
20912 int glyph_len = cmp->glyph_len;
20913 int face_id;
20914 int c;
20915 XChar2b char2b;
20916 XFontStruct *font;
20917 XCharStruct *pcm;
20918 int font_not_found_p;
20919 struct font_info *font_info;
20920 int pos;
20921
20922 for (glyph_len = cmp->glyph_len; glyph_len > 0; glyph_len--)
20923 if ((c = COMPOSITION_GLYPH (cmp, glyph_len - 1)) != '\t')
20924 break;
20925 if (glyph_len < cmp->glyph_len)
20926 right_padded = 1;
20927 for (i = 0; i < glyph_len; i++)
20928 {
20929 if ((c = COMPOSITION_GLYPH (cmp, i)) != '\t')
20930 break;
20931 cmp->offsets[i * 2] = cmp->offsets[i * 2 + 1] = 0;
20932 }
20933 if (i > 0)
20934 left_padded = 1;
20935
20936 /* Get the font of the first non-TAB component. */
20937 pos = (STRINGP (it->string) ? IT_STRING_CHARPOS (*it)
20938 : IT_CHARPOS (*it));
20939 face_id = FACE_FOR_CHAR (it->f, face, c, pos, it->string);
20940 font = FACE_FROM_ID (it->f, face_id)->font;
20941 /* When no suitable font found, use the default font. */
20942 font_not_found_p = font == NULL;
20943 if (font_not_found_p)
20944 font = FACE_FROM_ID (it->f, it->face_id)->font;
20945 font_info
20946 = FONT_INFO_FROM_FACE (it->f, FACE_FROM_ID (it->f, face_id));
20947 boff = font_info->baseline_offset;
20948 if (font_info->vertical_centering)
20949 boff = VCENTER_BASELINE_OFFSET (font, it->f) - boff;
20950 font_ascent = FONT_BASE (font) + boff;
20951 font_descent = FONT_DESCENT (font) - boff;
20952 font_height = FONT_HEIGHT (font);
20976 20953
20977 cmp->font = (void *) font; 20954 cmp->font = (void *) font;
20978 20955
20956 pcm = NULL;
20957 if (! font_not_found_p)
20958 {
20959 get_char_face_and_encoding (it->f, c, face_id,
20960 &char2b, it->multibyte_p, 0);
20961 pcm = get_per_char_metric (font, font_info, &char2b,
20962 FONT_TYPE_FOR_MULTIBYTE (font, c));
20963 }
20964
20979 /* Initialize the bounding box. */ 20965 /* Initialize the bounding box. */
20980 if (font_info 20966 if (pcm)
20981 && (pcm = get_per_char_metric (font, font_info, &char2b,
20982 FONT_TYPE_FOR_MULTIBYTE (font, it->c))))
20983 { 20967 {
20984 width = pcm->width; 20968 width = pcm->width;
20985 ascent = pcm->ascent; 20969 ascent = pcm->ascent;
20986 descent = pcm->descent; 20970 descent = pcm->descent;
20987 lbearing = pcm->lbearing; 20971 lbearing = pcm->lbearing;
20988 if (lbearing > 0)
20989 lbearing = 0;
20990 rbearing = pcm->rbearing; 20972 rbearing = pcm->rbearing;
20991 if (rbearing < width)
20992 rbearing = width;
20993 } 20973 }
20994 else 20974 else
20995 { 20975 {
@@ -21001,11 +20981,11 @@ x_produce_glyphs (it)
21001 } 20981 }
21002 20982
21003 rightmost = width; 20983 rightmost = width;
20984 leftmost = 0;
21004 lowest = - descent + boff; 20985 lowest = - descent + boff;
21005 highest = ascent + boff; 20986 highest = ascent + boff;
21006 leftmost = 0;
21007 20987
21008 if (font_info 20988 if (! font_not_found_p
21009 && font_info->default_ascent 20989 && font_info->default_ascent
21010 && CHAR_TABLE_P (Vuse_default_ascent) 20990 && CHAR_TABLE_P (Vuse_default_ascent)
21011 && !NILP (Faref (Vuse_default_ascent, 20991 && !NILP (Faref (Vuse_default_ascent,
@@ -21013,157 +20993,138 @@ x_produce_glyphs (it)
21013 highest = font_info->default_ascent + boff; 20993 highest = font_info->default_ascent + boff;
21014 20994
21015 /* Draw the first glyph at the normal position. It may be 20995 /* Draw the first glyph at the normal position. It may be
21016 shifted to right later if some other glyphs are drawn at 20996 shifted to right later if some other glyphs are drawn
21017 the left. */ 20997 at the left. */
21018 cmp->offsets[0] = 0; 20998 cmp->offsets[i * 2] = 0;
21019 cmp->offsets[1] = boff; 20999 cmp->offsets[i * 2 + 1] = boff;
21020 cmp->lbearing = lbearing; 21000 cmp->lbearing = lbearing;
21021 cmp->rbearing = rbearing; 21001 cmp->rbearing = rbearing;
21022 21002
21023 /* Set cmp->offsets for the remaining glyphs. */ 21003 /* Set cmp->offsets for the remaining glyphs. */
21024 for (i = 1; i < cmp->glyph_len; i++) 21004 for (i++; i < glyph_len; i++)
21025 { 21005 {
21026 int left, right, btm, top; 21006 int left, right, btm, top;
21027 int ch = COMPOSITION_GLYPH (cmp, i); 21007 int ch = COMPOSITION_GLYPH (cmp, i);
21028 int face_id; 21008 int face_id;
21009 struct face *this_face;
21010 int this_boff;
21029 21011
21030 if (ch == '\t') 21012 if (ch == '\t')
21031 { 21013 ch = ' ';
21032 fully_padded = 1;
21033 cmp->offsets[i * 2] = 0;
21034 cmp->offsets[i * 2 + 1] = boff;
21035 continue;
21036 }
21037
21038 face_id = FACE_FOR_CHAR (it->f, face, ch, pos, it->string); 21014 face_id = FACE_FOR_CHAR (it->f, face, ch, pos, it->string);
21039 face = FACE_FROM_ID (it->f, face_id); 21015 this_face = FACE_FROM_ID (it->f, face_id);
21040 get_char_face_and_encoding (it->f, ch, face->id, 21016 font = this_face->font;
21041 &char2b, it->multibyte_p, 0); 21017
21042 font = face->font;
21043 if (font == NULL) 21018 if (font == NULL)
21044 { 21019 pcm = NULL;
21045 font = FRAME_FONT (it->f);
21046 boff = FRAME_BASELINE_OFFSET (it->f);
21047 font_info = NULL;
21048 }
21049 else 21020 else
21050 { 21021 {
21051 font_info 21022 font_info = FONT_INFO_FROM_FACE (it->f, this_face);
21052 = FONT_INFO_FROM_FACE (it->f, face); 21023 this_boff = font_info->baseline_offset;
21053 boff = font_info->baseline_offset;
21054 if (font_info->vertical_centering) 21024 if (font_info->vertical_centering)
21055 boff = VCENTER_BASELINE_OFFSET (font, it->f) - boff; 21025 this_boff = VCENTER_BASELINE_OFFSET (font, it->f) - boff;
21026 get_char_face_and_encoding (it->f, ch, face_id,
21027 &char2b, it->multibyte_p, 0);
21028 pcm = get_per_char_metric (font, font_info, &char2b,
21029 FONT_TYPE_FOR_MULTIBYTE (font,
21030 ch));
21056 } 21031 }
21057 21032 if (! pcm)
21058 if (font_info 21033 cmp->offsets[i * 2] = cmp->offsets[i * 2 + 1] = 0;
21059 && (pcm = get_per_char_metric (font, font_info, &char2b, 21034 else
21060 FONT_TYPE_FOR_MULTIBYTE (font, ch))))
21061 { 21035 {
21062 width = pcm->width; 21036 width = pcm->width;
21063 ascent = pcm->ascent; 21037 ascent = pcm->ascent;
21064 descent = pcm->descent; 21038 descent = pcm->descent;
21065 lbearing = pcm->lbearing; 21039 lbearing = pcm->lbearing;
21066 if (lbearing > 0)
21067 lbearing = 0;
21068 rbearing = pcm->rbearing; 21040 rbearing = pcm->rbearing;
21069 if (rbearing < width) 21041 if (cmp->method != COMPOSITION_WITH_RULE_ALTCHARS)
21070 rbearing = width;
21071 }
21072 else
21073 {
21074 width = FONT_WIDTH (font);
21075 ascent = 1;
21076 descent = 0;
21077 lbearing = 0;
21078 rbearing = width;
21079 }
21080
21081 if (cmp->method != COMPOSITION_WITH_RULE_ALTCHARS)
21082 {
21083 /* Relative composition with or without
21084 alternate chars. */
21085 left = (leftmost + rightmost - width) / 2;
21086 btm = - descent + boff;
21087 if (font_info && font_info->relative_compose
21088 && (! CHAR_TABLE_P (Vignore_relative_composition)
21089 || NILP (Faref (Vignore_relative_composition,
21090 make_number (ch)))))
21091 { 21042 {
21043 /* Relative composition with or without
21044 alternate chars. */
21045 left = (leftmost + rightmost - width) / 2;
21046 btm = - descent + boff;
21047 if (font_info->relative_compose
21048 && (! CHAR_TABLE_P (Vignore_relative_composition)
21049 || NILP (Faref (Vignore_relative_composition,
21050 make_number (ch)))))
21051 {
21092 21052
21093 if (- descent >= font_info->relative_compose) 21053 if (- descent >= font_info->relative_compose)
21094 /* One extra pixel between two glyphs. */ 21054 /* One extra pixel between two glyphs. */
21095 btm = highest + 1; 21055 btm = highest + 1;
21096 else if (ascent <= 0) 21056 else if (ascent <= 0)
21097 /* One extra pixel between two glyphs. */ 21057 /* One extra pixel between two glyphs. */
21098 btm = lowest - 1 - ascent - descent; 21058 btm = lowest - 1 - ascent - descent;
21059 }
21099 } 21060 }
21100 } 21061 else
21101 else 21062 {
21102 { 21063 /* A composition rule is specified by an integer
21103 /* A composition rule is specified by an integer 21064 value that encodes global and new reference
21104 value that encodes global and new reference 21065 points (GREF and NREF). GREF and NREF are
21105 points (GREF and NREF). GREF and NREF are 21066 specified by numbers as below:
21106 specified by numbers as below: 21067
21107 21068 0---1---2 -- ascent
21108 0---1---2 -- ascent 21069 | |
21109 | | 21070 | |
21110 | | 21071 | |
21111 | | 21072 9--10--11 -- center
21112 9--10--11 -- center 21073 | |
21113 | | 21074 ---3---4---5--- baseline
21114 ---3---4---5--- baseline 21075 | |
21115 | | 21076 6---7---8 -- descent
21116 6---7---8 -- descent 21077 */
21117 */ 21078 int rule = COMPOSITION_RULE (cmp, i);
21118 int rule = COMPOSITION_RULE (cmp, i); 21079 int gref, nref, grefx, grefy, nrefx, nrefy, xoff, yoff;
21119 int gref, nref, grefx, grefy, nrefx, nrefy, xoff, yoff; 21080
21120 21081 COMPOSITION_DECODE_RULE (rule, gref, nref, xoff, yoff);
21121 COMPOSITION_DECODE_RULE (rule, gref, nref, xoff, yoff); 21082 grefx = gref % 3, nrefx = nref % 3;
21122 grefx = gref % 3, nrefx = nref % 3; 21083 grefy = gref / 3, nrefy = nref / 3;
21123 grefy = gref / 3, nrefy = nref / 3; 21084 if (xoff)
21124 if (xoff) 21085 xoff = font_height * (xoff - 128) / 256;
21125 xoff = font_height * (xoff - 128) / 256; 21086 if (yoff)
21126 if (yoff) 21087 yoff = font_height * (yoff - 128) / 256;
21127 yoff = font_height * (yoff - 128) / 256; 21088
21128 21089 left = (leftmost
21129 left = (leftmost 21090 + grefx * (rightmost - leftmost) / 2
21130 + grefx * (rightmost - leftmost) / 2 21091 - nrefx * width / 2
21131 - nrefx * width / 2 21092 + xoff);
21132 + xoff);
21133 21093
21134 btm = ((grefy == 0 ? highest 21094 btm = ((grefy == 0 ? highest
21135 : grefy == 1 ? 0 21095 : grefy == 1 ? 0
21136 : grefy == 2 ? lowest 21096 : grefy == 2 ? lowest
21137 : (highest + lowest) / 2) 21097 : (highest + lowest) / 2)
21138 - (nrefy == 0 ? ascent + descent 21098 - (nrefy == 0 ? ascent + descent
21139 : nrefy == 1 ? descent - boff 21099 : nrefy == 1 ? descent - boff
21140 : nrefy == 2 ? 0 21100 : nrefy == 2 ? 0
21141 : (ascent + descent) / 2) 21101 : (ascent + descent) / 2)
21142 + yoff); 21102 + yoff);
21143 } 21103 }
21144 21104
21145 cmp->offsets[i * 2] = left; 21105 cmp->offsets[i * 2] = left;
21146 cmp->offsets[i * 2 + 1] = btm + descent; 21106 cmp->offsets[i * 2 + 1] = btm + descent;
21147 21107
21148 /* Update the bounding box of the overall glyphs. */ 21108 /* Update the bounding box of the overall glyphs. */
21149 if (width > 0) 21109 if (width > 0)
21150 { 21110 {
21151 right = left + width; 21111 right = left + width;
21152 if (left < leftmost) 21112 if (left < leftmost)
21153 leftmost = left; 21113 leftmost = left;
21154 if (right > rightmost) 21114 if (right > rightmost)
21155 rightmost = right; 21115 rightmost = right;
21116 }
21117 top = btm + descent + ascent;
21118 if (top > highest)
21119 highest = top;
21120 if (btm < lowest)
21121 lowest = btm;
21122
21123 if (cmp->lbearing > left + lbearing)
21124 cmp->lbearing = left + lbearing;
21125 if (cmp->rbearing < left + rbearing)
21126 cmp->rbearing = left + rbearing;
21156 } 21127 }
21157 top = btm + descent + ascent;
21158 if (top > highest)
21159 highest = top;
21160 if (btm < lowest)
21161 lowest = btm;
21162
21163 if (cmp->lbearing > left + lbearing)
21164 cmp->lbearing = left + lbearing;
21165 if (cmp->rbearing < left + rbearing)
21166 cmp->rbearing = left + rbearing;
21167 } 21128 }
21168 21129
21169 /* If there are glyphs whose x-offsets are negative, 21130 /* If there are glyphs whose x-offsets are negative,
@@ -21178,13 +21139,17 @@ x_produce_glyphs (it)
21178 cmp->rbearing -= leftmost; 21139 cmp->rbearing -= leftmost;
21179 } 21140 }
21180 21141
21181 if (fully_padded) 21142 if (left_padded && cmp->lbearing < 0)
21182 { 21143 {
21183 for (i = 0; i < cmp->glyph_len; i++) 21144 for (i = 0; i < cmp->glyph_len; i++)
21184 cmp->offsets[i * 2] -= cmp->lbearing; 21145 cmp->offsets[i * 2] -= cmp->lbearing;
21185 rightmost = cmp->rbearing - cmp->lbearing; 21146 rightmost -= cmp->lbearing;
21147 cmp->rbearing -= cmp->lbearing;
21186 cmp->lbearing = 0; 21148 cmp->lbearing = 0;
21187 cmp->rbearing = rightmost; 21149 }
21150 if (right_padded && rightmost < cmp->rbearing)
21151 {
21152 rightmost = cmp->rbearing;
21188 } 21153 }
21189 21154
21190 cmp->pixel_width = rightmost; 21155 cmp->pixel_width = rightmost;