aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorKenichi Handa2008-08-29 07:58:08 +0000
committerKenichi Handa2008-08-29 07:58:08 +0000
commit4eceb6f3b7d50ce8f02160658c2ce4a3bf3f0f0d (patch)
treeb17ae49267da648ad92b9e46871ac1ef69ebfe2d /src
parent716e6ba398bafea82008f8b0d9a4ad603e5c035c (diff)
downloademacs-4eceb6f3b7d50ce8f02160658c2ce4a3bf3f0f0d.tar.gz
emacs-4eceb6f3b7d50ce8f02160658c2ce4a3bf3f0f0d.zip
Include font.h.
(it_props): Delete the entry for Qauto_composed. (init_iterator): Initialize it->cmp_it.id to -1. (compute_stop_pos): Call composition_compute_stop_pos. (face_before_or_after_it_pos): Adjusted for the change of struct it. (handle_auto_composed_prop): Delete it. (handle_composition_prop): Handle only static composition. (next_overlay_string): Remove it->method == GET_FROM_COMPOSITION from xassert. Initialize it->cmp_it.stop_pos. (push_it): Adjusted for the change of struct it. (pop_it): Likewise. (get_next_element): Delete next_element_from_composition. (CHAR_COMPOSED_P): New macro. (get_next_display_element): For automatic composition, get a face from the font in the glyph-string. (set_iterator_to_next): For GET_FROM_BUFFER and GET_FROM_STRING, check composition by it->cmp_it.id. Delete GET_FROM_COMPOSITION case. (next_element_from_string): Check if the character at the current position is composed by CHAR_COMPOSED_P. (next_element_from_buffer): Likewise. (next_element_from_composition): Adjusted for the change of struct it. Update it->cmp_it. (dump_glyph): Adjusted for the change of struct glyph. (fill_composite_glyph_string): Adjusted for the change of struct it and struct glyph. Don't handle automatic composition here. (fill_gstring_glyph_string): New function. (x_get_glyph_overhangs): Handle automatic composition. (BUILD_COMPOSITE_GLYPH_STRING): Adjusted for the change of struct glyph. (BUILD_GSTRING_GLYPH_STRING): New macro. (BUILD_GLYPH_STRINGS): Call BUILD_GSTRING_GLYPH_STRING for automatic composition. (append_composite_glyph): Adjusted for the change of struct it and struct glyph. (x_produce_glyphs): Adjusted for the change of struct it.
Diffstat (limited to 'src')
-rw-r--r--src/xdisp.c689
1 files changed, 365 insertions, 324 deletions
diff --git a/src/xdisp.c b/src/xdisp.c
index d0b557c3595..3f73391c0aa 100644
--- a/src/xdisp.c
+++ b/src/xdisp.c
@@ -188,6 +188,7 @@ along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>. */
188#include "coding.h" 188#include "coding.h"
189#include "process.h" 189#include "process.h"
190#include "region-cache.h" 190#include "region-cache.h"
191#include "font.h"
191#include "fontset.h" 192#include "fontset.h"
192#include "blockinput.h" 193#include "blockinput.h"
193 194
@@ -767,7 +768,6 @@ static enum prop_handled handle_display_prop P_ ((struct it *));
767static enum prop_handled handle_composition_prop P_ ((struct it *)); 768static enum prop_handled handle_composition_prop P_ ((struct it *));
768static enum prop_handled handle_overlay_change P_ ((struct it *)); 769static enum prop_handled handle_overlay_change P_ ((struct it *));
769static enum prop_handled handle_fontified_prop P_ ((struct it *)); 770static enum prop_handled handle_fontified_prop P_ ((struct it *));
770static enum prop_handled handle_auto_composed_prop P_ ((struct it *));
771 771
772/* Properties handled by iterators. */ 772/* Properties handled by iterators. */
773 773
@@ -779,7 +779,6 @@ static struct props it_props[] =
779 {&Qface, FACE_PROP_IDX, handle_face_prop}, 779 {&Qface, FACE_PROP_IDX, handle_face_prop},
780 {&Qdisplay, DISPLAY_PROP_IDX, handle_display_prop}, 780 {&Qdisplay, DISPLAY_PROP_IDX, handle_display_prop},
781 {&Qinvisible, INVISIBLE_PROP_IDX, handle_invisible_prop}, 781 {&Qinvisible, INVISIBLE_PROP_IDX, handle_invisible_prop},
782 {&Qauto_composed, AUTO_COMPOSED_PROP_IDX, handle_auto_composed_prop},
783 {&Qcomposition, COMPOSITION_PROP_IDX, handle_composition_prop}, 782 {&Qcomposition, COMPOSITION_PROP_IDX, handle_composition_prop},
784 {NULL, 0, NULL} 783 {NULL, 0, NULL}
785}; 784};
@@ -2574,6 +2573,8 @@ init_iterator (it, w, charpos, bytepos, row, base_face_id)
2574 it->w = w; 2573 it->w = w;
2575 it->f = XFRAME (w->frame); 2574 it->f = XFRAME (w->frame);
2576 2575
2576 it->cmp_it.id = -1;
2577
2577 /* Extra space between lines (on window systems only). */ 2578 /* Extra space between lines (on window systems only). */
2578 if (base_face_id == DEFAULT_FACE_ID 2579 if (base_face_id == DEFAULT_FACE_ID
2579 && FRAME_WINDOW_P (it->f)) 2580 && FRAME_WINDOW_P (it->f))
@@ -3181,6 +3182,7 @@ compute_stop_pos (it)
3181{ 3182{
3182 register INTERVAL iv, next_iv; 3183 register INTERVAL iv, next_iv;
3183 Lisp_Object object, limit, position; 3184 Lisp_Object object, limit, position;
3185 EMACS_INT charpos, bytepos;
3184 3186
3185 /* If nowhere else, stop at the end. */ 3187 /* If nowhere else, stop at the end. */
3186 it->stop_charpos = it->end_charpos; 3188 it->stop_charpos = it->end_charpos;
@@ -3191,19 +3193,22 @@ compute_stop_pos (it)
3191 properties. */ 3193 properties. */
3192 object = it->string; 3194 object = it->string;
3193 limit = Qnil; 3195 limit = Qnil;
3194 position = make_number (IT_STRING_CHARPOS (*it)); 3196 charpos = IT_STRING_CHARPOS (*it);
3197 bytepos = IT_STRING_BYTEPOS (*it);
3195 } 3198 }
3196 else 3199 else
3197 { 3200 {
3198 int charpos; 3201 EMACS_INT pos;
3199 3202
3200 /* If next overlay change is in front of the current stop pos 3203 /* If next overlay change is in front of the current stop pos
3201 (which is IT->end_charpos), stop there. Note: value of 3204 (which is IT->end_charpos), stop there. Note: value of
3202 next_overlay_change is point-max if no overlay change 3205 next_overlay_change is point-max if no overlay change
3203 follows. */ 3206 follows. */
3204 charpos = next_overlay_change (IT_CHARPOS (*it)); 3207 charpos = IT_CHARPOS (*it);
3205 if (charpos < it->stop_charpos) 3208 bytepos = IT_BYTEPOS (*it);
3206 it->stop_charpos = charpos; 3209 pos = next_overlay_change (charpos);
3210 if (pos < it->stop_charpos)
3211 it->stop_charpos = pos;
3207 3212
3208 /* If showing the region, we have to stop at the region 3213 /* If showing the region, we have to stop at the region
3209 start or end because the face might change there. */ 3214 start or end because the face might change there. */
@@ -3219,12 +3224,11 @@ compute_stop_pos (it)
3219 property changes. */ 3224 property changes. */
3220 XSETBUFFER (object, current_buffer); 3225 XSETBUFFER (object, current_buffer);
3221 limit = make_number (IT_CHARPOS (*it) + TEXT_PROP_DISTANCE_LIMIT); 3226 limit = make_number (IT_CHARPOS (*it) + TEXT_PROP_DISTANCE_LIMIT);
3222 position = make_number (IT_CHARPOS (*it));
3223
3224 } 3227 }
3225 3228
3226 /* Get the interval containing IT's position. Value is a null 3229 /* Get the interval containing IT's position. Value is a null
3227 interval if there isn't such an interval. */ 3230 interval if there isn't such an interval. */
3231 position = make_number (charpos);
3228 iv = validate_interval_range (object, &position, &position, 0); 3232 iv = validate_interval_range (object, &position, &position, 0);
3229 if (!NULL_INTERVAL_P (iv)) 3233 if (!NULL_INTERVAL_P (iv))
3230 { 3234 {
@@ -3268,6 +3272,9 @@ compute_stop_pos (it)
3268 } 3272 }
3269 } 3273 }
3270 3274
3275 composition_compute_stop_pos (&it->cmp_it, charpos, bytepos,
3276 it->stop_charpos, it->string);
3277
3271 xassert (STRINGP (it->string) 3278 xassert (STRINGP (it->string)
3272 || (it->stop_charpos >= BEGV 3279 || (it->stop_charpos >= BEGV
3273 && it->stop_charpos >= IT_CHARPOS (*it))); 3280 && it->stop_charpos >= IT_CHARPOS (*it)));
@@ -3600,7 +3607,8 @@ face_before_or_after_it_pos (it, before_p)
3600 /* For composition, we must check the character after the 3607 /* For composition, we must check the character after the
3601 composition. */ 3608 composition. */
3602 pos = (it->what == IT_COMPOSITION 3609 pos = (it->what == IT_COMPOSITION
3603 ? string_pos (IT_STRING_CHARPOS (*it) + it->cmp_len, it->string) 3610 ? string_pos (IT_STRING_CHARPOS (*it)
3611 + it->cmp_it.nchars, it->string)
3604 : string_pos (IT_STRING_CHARPOS (*it) + 1, it->string)); 3612 : string_pos (IT_STRING_CHARPOS (*it) + 1, it->string));
3605 3613
3606 if (it->current.overlay_string_index >= 0) 3614 if (it->current.overlay_string_index >= 0)
@@ -3650,7 +3658,7 @@ face_before_or_after_it_pos (it, before_p)
3650 if (it->what == IT_COMPOSITION) 3658 if (it->what == IT_COMPOSITION)
3651 /* For composition, we must check the position after the 3659 /* For composition, we must check the position after the
3652 composition. */ 3660 composition. */
3653 pos.charpos += it->cmp_len, pos.bytepos += it->len; 3661 pos.charpos += it->cmp_it.nchars, pos.bytepos += it->len;
3654 else 3662 else
3655 INC_TEXT_POS (pos, it->multibyte_p); 3663 INC_TEXT_POS (pos, it->multibyte_p);
3656 } 3664 }
@@ -4624,97 +4632,6 @@ string_buffer_position (w, string, around_charpos)
4624 `composition' property 4632 `composition' property
4625 ***********************************************************************/ 4633 ***********************************************************************/
4626 4634
4627static enum prop_handled
4628handle_auto_composed_prop (it)
4629 struct it *it;
4630{
4631 enum prop_handled handled = HANDLED_NORMALLY;
4632
4633 if (FUNCTIONP (Vauto_composition_function))
4634 {
4635 Lisp_Object val = Qnil;
4636 EMACS_INT pos, limit = -1;
4637
4638 if (STRINGP (it->string))
4639 pos = IT_STRING_CHARPOS (*it);
4640 else
4641 pos = IT_CHARPOS (*it);
4642
4643 val = Fget_text_property (make_number (pos), Qauto_composed, it->string);
4644 if (! NILP (val))
4645 {
4646 Lisp_Object cmp_prop;
4647 EMACS_INT cmp_start, cmp_end;
4648
4649 if (get_property_and_range (pos, Qcomposition, &cmp_prop,
4650 &cmp_start, &cmp_end, it->string)
4651 && cmp_start == pos
4652 && COMPOSITION_METHOD (cmp_prop) == COMPOSITION_WITH_GLYPH_STRING)
4653 {
4654 Lisp_Object gstring = COMPOSITION_COMPONENTS (cmp_prop);
4655 Lisp_Object font_object = LGSTRING_FONT (gstring);
4656
4657 if (! EQ (font_object,
4658 font_at (-1, pos, FACE_FROM_ID (it->f, it->face_id),
4659 it->w, it->string)))
4660 /* We must re-compute the composition for the
4661 different font. */
4662 val = Qnil;
4663 }
4664
4665 if (! NILP (val))
4666 {
4667 Lisp_Object end;
4668
4669 /* As Fnext_single_char_property_change is very slow, we
4670 limit the search to the current line. */
4671 if (STRINGP (it->string))
4672 limit = SCHARS (it->string);
4673 else
4674 limit = find_next_newline_no_quit (pos, 1);
4675 end = Fnext_single_char_property_change (make_number (pos),
4676 Qauto_composed,
4677 it->string,
4678 make_number (limit));
4679
4680 if (XINT (end) < limit)
4681 /* The current point is auto-composed, but there exist
4682 characters not yet composed beyond the
4683 auto-composed region. There's a possiblity that
4684 the last characters in the region may be newly
4685 composed. */
4686 val = Qnil;
4687 }
4688 }
4689 if (NILP (val) && ! STRINGP (it->string))
4690 {
4691 if (limit < 0)
4692 limit = (STRINGP (it->string) ? SCHARS (it->string)
4693 : find_next_newline_no_quit (pos, 1));
4694 if (pos < limit)
4695 {
4696 int count = SPECPDL_INDEX ();
4697 Lisp_Object args[5];
4698
4699 if (FRAME_WINDOW_P (it->f))
4700 limit = font_range (pos, limit,
4701 FACE_FROM_ID (it->f, it->face_id),
4702 it->f, it->string);
4703 args[0] = Vauto_composition_function;
4704 specbind (Qauto_composition_function, Qnil);
4705 args[1] = make_number (pos);
4706 args[2] = make_number (limit);
4707 args[3] = it->window;
4708 args[4] = it->string;
4709 safe_call (5, args);
4710 unbind_to (count, Qnil);
4711 }
4712 }
4713 }
4714
4715 return handled;
4716}
4717
4718/* Set up iterator IT from `composition' property at its current 4635/* Set up iterator IT from `composition' property at its current
4719 position. Called from handle_stop. */ 4636 position. Called from handle_stop. */
4720 4637
@@ -4724,7 +4641,6 @@ handle_composition_prop (it)
4724{ 4641{
4725 Lisp_Object prop, string; 4642 Lisp_Object prop, string;
4726 EMACS_INT pos, pos_byte, start, end; 4643 EMACS_INT pos, pos_byte, start, end;
4727 enum prop_handled handled = HANDLED_NORMALLY;
4728 4644
4729 if (STRINGP (it->string)) 4645 if (STRINGP (it->string))
4730 { 4646 {
@@ -4751,8 +4667,6 @@ handle_composition_prop (it)
4751 && COMPOSITION_VALID_P (start, end, prop) 4667 && COMPOSITION_VALID_P (start, end, prop)
4752 && (STRINGP (it->string) || (PT <= start || PT >= end))) 4668 && (STRINGP (it->string) || (PT <= start || PT >= end)))
4753 { 4669 {
4754 int id;
4755
4756 if (start != pos) 4670 if (start != pos)
4757 { 4671 {
4758 if (STRINGP (it->string)) 4672 if (STRINGP (it->string))
@@ -4760,63 +4674,17 @@ handle_composition_prop (it)
4760 else 4674 else
4761 pos_byte = CHAR_TO_BYTE (start); 4675 pos_byte = CHAR_TO_BYTE (start);
4762 } 4676 }
4763 id = get_composition_id (start, pos_byte, end - start, prop, string); 4677 it->cmp_it.id = get_composition_id (start, pos_byte, end - start,
4678 prop, string);
4764 4679
4765 if (id >= 0) 4680 if (it->cmp_it.id >= 0)
4766 { 4681 {
4767 struct composition *cmp = composition_table[id]; 4682 it->cmp_it.nchars = COMPOSITION_LENGTH (prop);
4768 4683 it->cmp_it.nglyphs = -1;
4769 if (cmp->glyph_len == 0)
4770 {
4771 /* No glyph. */
4772 if (STRINGP (it->string))
4773 {
4774 IT_STRING_CHARPOS (*it) = end;
4775 IT_STRING_BYTEPOS (*it) = string_char_to_byte (it->string,
4776 end);
4777 }
4778 else
4779 {
4780 IT_CHARPOS (*it) = end;
4781 IT_BYTEPOS (*it) = CHAR_TO_BYTE (end);
4782 }
4783 return HANDLED_RECOMPUTE_PROPS;
4784 }
4785
4786 it->stop_charpos = end;
4787 push_it (it);
4788
4789 it->method = GET_FROM_COMPOSITION;
4790 it->cmp_id = id;
4791 it->cmp_len = COMPOSITION_LENGTH (prop);
4792 /* For a terminal, draw only the first (non-TAB) character
4793 of the components. */
4794 if (composition_table[id]->method == COMPOSITION_WITH_GLYPH_STRING)
4795 {
4796 /* FIXME: This doesn't do anything!?! */
4797 Lisp_Object lgstring = AREF (XHASH_TABLE (composition_hash_table)
4798 ->key_and_value,
4799 cmp->hash_index * 2);
4800 }
4801 else
4802 {
4803 int i;
4804
4805 for (i = 0; i < cmp->glyph_len; i++)
4806 if ((it->c = COMPOSITION_GLYPH (composition_table[id], i))
4807 != '\t')
4808 break;
4809 }
4810 if (it->c == '\t')
4811 it->c = ' ';
4812 it->len = (STRINGP (it->string)
4813 ? string_char_to_byte (it->string, end)
4814 : CHAR_TO_BYTE (end)) - pos_byte;
4815 handled = HANDLED_RETURN;
4816 } 4684 }
4817 } 4685 }
4818 4686
4819 return handled; 4687 return HANDLED_NORMALLY;
4820} 4688}
4821 4689
4822 4690
@@ -4872,7 +4740,6 @@ next_overlay_string (it)
4872 it->ellipsis_p = (it->stack[it->sp - 1].display_ellipsis_p != 0); 4740 it->ellipsis_p = (it->stack[it->sp - 1].display_ellipsis_p != 0);
4873 pop_it (it); 4741 pop_it (it);
4874 xassert (it->sp > 0 4742 xassert (it->sp > 0
4875 || it->method == GET_FROM_COMPOSITION
4876 || (NILP (it->string) 4743 || (NILP (it->string)
4877 && it->method == GET_FROM_BUFFER 4744 && it->method == GET_FROM_BUFFER
4878 && it->stop_charpos >= BEGV 4745 && it->stop_charpos >= BEGV
@@ -4904,6 +4771,8 @@ next_overlay_string (it)
4904 SET_TEXT_POS (it->current.string_pos, 0, 0); 4771 SET_TEXT_POS (it->current.string_pos, 0, 0);
4905 it->method = GET_FROM_STRING; 4772 it->method = GET_FROM_STRING;
4906 it->stop_charpos = 0; 4773 it->stop_charpos = 0;
4774 if (it->cmp_it.stop_pos >= 0)
4775 it->cmp_it.stop_pos = 0;
4907 } 4776 }
4908 4777
4909 CHECK_IT (it); 4778 CHECK_IT (it);
@@ -5218,6 +5087,7 @@ push_it (it)
5218 p = it->stack + it->sp; 5087 p = it->stack + it->sp;
5219 5088
5220 p->stop_charpos = it->stop_charpos; 5089 p->stop_charpos = it->stop_charpos;
5090 p->cmp_it = it->cmp_it;
5221 xassert (it->face_id >= 0); 5091 xassert (it->face_id >= 0);
5222 p->face_id = it->face_id; 5092 p->face_id = it->face_id;
5223 p->string = it->string; 5093 p->string = it->string;
@@ -5230,13 +5100,6 @@ push_it (it)
5230 p->u.image.image_id = it->image_id; 5100 p->u.image.image_id = it->image_id;
5231 p->u.image.slice = it->slice; 5101 p->u.image.slice = it->slice;
5232 break; 5102 break;
5233 case GET_FROM_COMPOSITION:
5234 p->u.comp.object = it->object;
5235 p->u.comp.c = it->c;
5236 p->u.comp.len = it->len;
5237 p->u.comp.cmp_id = it->cmp_id;
5238 p->u.comp.cmp_len = it->cmp_len;
5239 break;
5240 case GET_FROM_STRETCH: 5103 case GET_FROM_STRETCH:
5241 p->u.stretch.object = it->object; 5104 p->u.stretch.object = it->object;
5242 break; 5105 break;
@@ -5273,6 +5136,7 @@ pop_it (it)
5273 --it->sp; 5136 --it->sp;
5274 p = it->stack + it->sp; 5137 p = it->stack + it->sp;
5275 it->stop_charpos = p->stop_charpos; 5138 it->stop_charpos = p->stop_charpos;
5139 it->cmp_it = p->cmp_it;
5276 it->face_id = p->face_id; 5140 it->face_id = p->face_id;
5277 it->current = p->current; 5141 it->current = p->current;
5278 it->position = p->position; 5142 it->position = p->position;
@@ -5288,13 +5152,6 @@ pop_it (it)
5288 it->object = p->u.image.object; 5152 it->object = p->u.image.object;
5289 it->slice = p->u.image.slice; 5153 it->slice = p->u.image.slice;
5290 break; 5154 break;
5291 case GET_FROM_COMPOSITION:
5292 it->object = p->u.comp.object;
5293 it->c = p->u.comp.c;
5294 it->len = p->u.comp.len;
5295 it->cmp_id = p->u.comp.cmp_id;
5296 it->cmp_len = p->u.comp.cmp_len;
5297 break;
5298 case GET_FROM_STRETCH: 5155 case GET_FROM_STRETCH:
5299 it->object = p->u.comp.object; 5156 it->object = p->u.comp.object;
5300 break; 5157 break;
@@ -5754,7 +5611,6 @@ static int (* get_next_element[NUM_IT_METHODS]) P_ ((struct it *it)) =
5754{ 5611{
5755 next_element_from_buffer, 5612 next_element_from_buffer,
5756 next_element_from_display_vector, 5613 next_element_from_display_vector,
5757 next_element_from_composition,
5758 next_element_from_string, 5614 next_element_from_string,
5759 next_element_from_c_string, 5615 next_element_from_c_string,
5760 next_element_from_image, 5616 next_element_from_image,
@@ -5763,6 +5619,19 @@ static int (* get_next_element[NUM_IT_METHODS]) P_ ((struct it *it)) =
5763 5619
5764#define GET_NEXT_DISPLAY_ELEMENT(it) (*get_next_element[(it)->method]) (it) 5620#define GET_NEXT_DISPLAY_ELEMENT(it) (*get_next_element[(it)->method]) (it)
5765 5621
5622
5623/* Return 1 iff a character at CHARPOS (and BYTEPOS) is composed
5624 (possibly with the following characters). */
5625
5626#define CHAR_COMPOSED_P(IT,CHARPOS,BYTEPOS) \
5627 ((IT)->cmp_it.id >= 0 \
5628 || ((IT)->cmp_it.stop_pos == (CHARPOS) \
5629 && composition_reseat_it (&(IT)->cmp_it, CHARPOS, BYTEPOS, \
5630 (IT)->end_charpos, (IT)->w, \
5631 FACE_FROM_ID ((IT)->f, (IT)->face_id), \
5632 (IT)->string)))
5633
5634
5766/* Load IT's display element fields with information about the next 5635/* Load IT's display element fields with information about the next
5767 display element from the current position of IT. Value is zero if 5636 display element from the current position of IT. Value is zero if
5768 end of buffer (or C string) is reached. */ 5637 end of buffer (or C string) is reached. */
@@ -6037,6 +5906,7 @@ get_next_display_element (it)
6037 } 5906 }
6038 } 5907 }
6039 5908
5909#ifdef HAVE_WINDOW_SYSTEM
6040 /* Adjust face id for a multibyte character. There are no multibyte 5910 /* Adjust face id for a multibyte character. There are no multibyte
6041 character in unibyte text. */ 5911 character in unibyte text. */
6042 if ((it->what == IT_CHARACTER || it->what == IT_COMPOSITION) 5912 if ((it->what == IT_CHARACTER || it->what == IT_COMPOSITION)
@@ -6045,12 +5915,24 @@ get_next_display_element (it)
6045 && FRAME_WINDOW_P (it->f)) 5915 && FRAME_WINDOW_P (it->f))
6046 { 5916 {
6047 struct face *face = FACE_FROM_ID (it->f, it->face_id); 5917 struct face *face = FACE_FROM_ID (it->f, it->face_id);
6048 int pos = (it->s ? -1
6049 : STRINGP (it->string) ? IT_STRING_CHARPOS (*it)
6050 : IT_CHARPOS (*it));
6051 5918
6052 it->face_id = FACE_FOR_CHAR (it->f, face, it->c, pos, it->string); 5919 if (it->what == IT_COMPOSITION && it->cmp_it.ch >= 0)
5920 {
5921 /* Automatic composition with glyph-string. */
5922 Lisp_Object gstring = composition_gstring_from_id (it->cmp_it.id);
5923
5924 it->face_id = face_for_font (it->f, LGSTRING_FONT (gstring), face);
5925 }
5926 else
5927 {
5928 int pos = (it->s ? -1
5929 : STRINGP (it->string) ? IT_STRING_CHARPOS (*it)
5930 : IT_CHARPOS (*it));
5931
5932 it->face_id = FACE_FOR_CHAR (it->f, face, it->c, pos, it->string);
5933 }
6053 } 5934 }
5935#endif
6054 5936
6055 /* Is this character the last one of a run of characters with 5937 /* Is this character the last one of a run of characters with
6056 box? If yes, set IT->end_of_box_run_p to 1. */ 5938 box? If yes, set IT->end_of_box_run_p to 1. */
@@ -6105,6 +5987,20 @@ set_iterator_to_next (it, reseat_p)
6105 invisible lines that are so because of selective display. */ 5987 invisible lines that are so because of selective display. */
6106 if (ITERATOR_AT_END_OF_LINE_P (it) && reseat_p) 5988 if (ITERATOR_AT_END_OF_LINE_P (it) && reseat_p)
6107 reseat_at_next_visible_line_start (it, 0); 5989 reseat_at_next_visible_line_start (it, 0);
5990 else if (it->cmp_it.id >= 0)
5991 {
5992 IT_CHARPOS (*it) += it->cmp_it.nchars;
5993 IT_BYTEPOS (*it) += it->cmp_it.nbytes;
5994 if (it->cmp_it.to < it->cmp_it.nglyphs)
5995 it->cmp_it.from = it->cmp_it.to;
5996 else
5997 {
5998 it->cmp_it.id = -1;
5999 composition_compute_stop_pos (&it->cmp_it, IT_CHARPOS (*it),
6000 IT_BYTEPOS (*it), it->stop_charpos,
6001 Qnil);
6002 }
6003 }
6108 else 6004 else
6109 { 6005 {
6110 xassert (it->len != 0); 6006 xassert (it->len != 0);
@@ -6114,23 +6010,6 @@ set_iterator_to_next (it, reseat_p)
6114 } 6010 }
6115 break; 6011 break;
6116 6012
6117 case GET_FROM_COMPOSITION:
6118 xassert (it->cmp_id >= 0 && it->cmp_id < n_compositions);
6119 xassert (it->sp > 0);
6120 pop_it (it);
6121 if (it->method == GET_FROM_STRING)
6122 {
6123 IT_STRING_BYTEPOS (*it) += it->len;
6124 IT_STRING_CHARPOS (*it) += it->cmp_len;
6125 goto consider_string_end;
6126 }
6127 else if (it->method == GET_FROM_BUFFER)
6128 {
6129 IT_BYTEPOS (*it) += it->len;
6130 IT_CHARPOS (*it) += it->cmp_len;
6131 }
6132 break;
6133
6134 case GET_FROM_C_STRING: 6013 case GET_FROM_C_STRING:
6135 /* Current display element of IT is from a C string. */ 6014 /* Current display element of IT is from a C string. */
6136 IT_BYTEPOS (*it) += it->len; 6015 IT_BYTEPOS (*it) += it->len;
@@ -6186,8 +6065,26 @@ set_iterator_to_next (it, reseat_p)
6186 case GET_FROM_STRING: 6065 case GET_FROM_STRING:
6187 /* Current display element is a character from a Lisp string. */ 6066 /* Current display element is a character from a Lisp string. */
6188 xassert (it->s == NULL && STRINGP (it->string)); 6067 xassert (it->s == NULL && STRINGP (it->string));
6189 IT_STRING_BYTEPOS (*it) += it->len; 6068 if (it->cmp_it.id >= 0)
6190 IT_STRING_CHARPOS (*it) += 1; 6069 {
6070 IT_STRING_CHARPOS (*it) += it->cmp_it.nchars;
6071 IT_STRING_BYTEPOS (*it) += it->cmp_it.nbytes;
6072 if (it->cmp_it.to < it->cmp_it.nglyphs)
6073 it->cmp_it.from = it->cmp_it.to;
6074 else
6075 {
6076 it->cmp_it.id = -1;
6077 composition_compute_stop_pos (&it->cmp_it,
6078 IT_STRING_CHARPOS (*it),
6079 IT_STRING_BYTEPOS (*it),
6080 it->stop_charpos, it->string);
6081 }
6082 }
6083 else
6084 {
6085 IT_STRING_BYTEPOS (*it) += it->len;
6086 IT_STRING_CHARPOS (*it) += 1;
6087 }
6191 6088
6192 consider_string_end: 6089 consider_string_end:
6193 6090
@@ -6330,6 +6227,12 @@ next_element_from_string (it)
6330 it->what = IT_EOB; 6227 it->what = IT_EOB;
6331 return 0; 6228 return 0;
6332 } 6229 }
6230 else if (CHAR_COMPOSED_P (it, IT_STRING_CHARPOS (*it),
6231 IT_STRING_BYTEPOS (*it))
6232 && next_element_from_composition (it))
6233 {
6234 return 1;
6235 }
6333 else if (STRING_MULTIBYTE (it->string)) 6236 else if (STRING_MULTIBYTE (it->string))
6334 { 6237 {
6335 int remaining = SBYTES (it->string) - IT_STRING_BYTEPOS (*it); 6238 int remaining = SBYTES (it->string) - IT_STRING_BYTEPOS (*it);
@@ -6360,6 +6263,12 @@ next_element_from_string (it)
6360 it->c = ' ', it->len = 1; 6263 it->c = ' ', it->len = 1;
6361 CHARPOS (position) = BYTEPOS (position) = -1; 6264 CHARPOS (position) = BYTEPOS (position) = -1;
6362 } 6265 }
6266 else if (CHAR_COMPOSED_P (it, IT_STRING_CHARPOS (*it),
6267 IT_STRING_BYTEPOS (*it))
6268 && next_element_from_composition (it))
6269 {
6270 return 1;
6271 }
6363 else if (STRING_MULTIBYTE (it->string)) 6272 else if (STRING_MULTIBYTE (it->string))
6364 { 6273 {
6365 int maxlen = SBYTES (it->string) - IT_STRING_BYTEPOS (*it); 6274 int maxlen = SBYTES (it->string) - IT_STRING_BYTEPOS (*it);
@@ -6546,14 +6455,16 @@ next_element_from_buffer (it)
6546 && IT_CHARPOS (*it) >= it->redisplay_end_trigger_charpos) 6455 && IT_CHARPOS (*it) >= it->redisplay_end_trigger_charpos)
6547 run_redisplay_end_trigger_hook (it); 6456 run_redisplay_end_trigger_hook (it);
6548 6457
6458 if (CHAR_COMPOSED_P (it, IT_CHARPOS (*it), IT_BYTEPOS (*it))
6459 && next_element_from_composition (it))
6460 {
6461 return 1;
6462 }
6463
6549 /* Get the next character, maybe multibyte. */ 6464 /* Get the next character, maybe multibyte. */
6550 p = BYTE_POS_ADDR (IT_BYTEPOS (*it)); 6465 p = BYTE_POS_ADDR (IT_BYTEPOS (*it));
6551 if (it->multibyte_p && !ASCII_BYTE_P (*p)) 6466 if (it->multibyte_p && !ASCII_BYTE_P (*p))
6552 { 6467 it->c = STRING_CHAR_AND_LENGTH (p, 0, it->len);
6553 int maxlen = ((IT_BYTEPOS (*it) >= GPT_BYTE ? ZV_BYTE : GPT_BYTE)
6554 - IT_BYTEPOS (*it));
6555 it->c = string_char_and_length (p, maxlen, &it->len);
6556 }
6557 else 6468 else
6558 it->c = *p, it->len = 1; 6469 it->c = *p, it->len = 1;
6559 6470
@@ -6625,22 +6536,43 @@ run_redisplay_end_trigger_hook (it)
6625} 6536}
6626 6537
6627 6538
6628/* Deliver a composition display element. The iterator IT is already 6539/* Deliver a composition display element. Unlike the other
6629 filled with composition information (done in 6540 next_element_from_XXX, this function is not registered in the array
6630 handle_composition_prop). Value is always 1. */ 6541 get_next_element[]. It is called from next_element_from_buffer and
6542 next_element_from_string when necessary. */
6631 6543
6632static int 6544static int
6633next_element_from_composition (it) 6545next_element_from_composition (it)
6634 struct it *it; 6546 struct it *it;
6635{ 6547{
6636 it->what = IT_COMPOSITION; 6548 it->what = IT_COMPOSITION;
6637 it->position = (STRINGP (it->string) 6549 it->len = it->cmp_it.nbytes;
6638 ? it->current.string_pos
6639 : it->current.pos);
6640 if (STRINGP (it->string)) 6550 if (STRINGP (it->string))
6641 it->object = it->string; 6551 {
6552 if (it->c < 0)
6553 {
6554 IT_STRING_CHARPOS (*it) += it->cmp_it.nchars;
6555 IT_STRING_BYTEPOS (*it) += it->cmp_it.nbytes;
6556 return 0;
6557 }
6558 it->position = it->current.string_pos;
6559 it->object = it->string;
6560 it->c = composition_update_it (&it->cmp_it, IT_STRING_CHARPOS (*it),
6561 IT_STRING_BYTEPOS (*it), it->string);
6562 }
6642 else 6563 else
6643 it->object = it->w->buffer; 6564 {
6565 if (it->c < 0)
6566 {
6567 IT_CHARPOS (*it) += it->cmp_it.nchars;
6568 IT_BYTEPOS (*it) += it->cmp_it.nbytes;
6569 return 0;
6570 }
6571 it->position = it->current.pos;
6572 it->object = it->w->buffer;
6573 it->c = composition_update_it (&it->cmp_it, IT_CHARPOS (*it),
6574 IT_BYTEPOS (*it), Qnil);
6575 }
6644 return 1; 6576 return 1;
6645} 6577}
6646 6578
@@ -15674,7 +15606,7 @@ dump_glyph (row, glyph, area)
15674 else if (glyph->type == COMPOSITE_GLYPH) 15606 else if (glyph->type == COMPOSITE_GLYPH)
15675 { 15607 {
15676 fprintf (stderr, 15608 fprintf (stderr,
15677 " %5d %4c %6d %c %3d 0x%05x %c %4d %1.1d%1.1d\n", 15609 " %5d %4c %6d %c %3d 0x%05x",
15678 glyph - row->glyphs[TEXT_AREA], 15610 glyph - row->glyphs[TEXT_AREA],
15679 '+', 15611 '+',
15680 glyph->charpos, 15612 glyph->charpos,
@@ -15684,8 +15616,12 @@ dump_glyph (row, glyph, area)
15684 ? 'S' 15616 ? 'S'
15685 : '-')), 15617 : '-')),
15686 glyph->pixel_width, 15618 glyph->pixel_width,
15687 glyph->u.cmp_id, 15619 glyph->u.cmp.id);
15688 '.', 15620 if (glyph->u.cmp.automatic)
15621 fprintf (stderr,
15622 "[%d-%d]",
15623 glyph->u.cmp.from, glyph->u.cmp.to);
15624 fprintf (stderr, " . %4d %1.1d%1.1d\n"
15689 glyph->face_id, 15625 glyph->face_id,
15690 glyph->left_box_line_p, 15626 glyph->left_box_line_p,
15691 glyph->right_box_line_p); 15627 glyph->right_box_line_p);
@@ -19609,70 +19545,45 @@ fill_composite_glyph_string (s, base_face, overlaps)
19609 int overlaps; 19545 int overlaps;
19610{ 19546{
19611 int i; 19547 int i;
19548 /* For all glyphs of this composition, starting at the offset
19549 S->gidx, until we reach the end of the definition or encounter a
19550 glyph that requires the different face, add it to S. */
19551 struct face *face;
19612 19552
19613 xassert (s); 19553 xassert (s);
19614 19554
19615 s->for_overlaps = overlaps; 19555 s->for_overlaps = overlaps;
19616 19556 s->face = NULL;
19617 if (s->cmp->method == COMPOSITION_WITH_GLYPH_STRING) 19557 s->font = NULL;
19618 { 19558 for (i = s->cmp_from; i < s->cmp->glyph_len; i++)
19619 Lisp_Object gstring
19620 = AREF (XHASH_TABLE (composition_hash_table)->key_and_value,
19621 s->cmp->hash_index * 2);
19622
19623 s->face = base_face;
19624 s->font = base_face->font;
19625 for (i = 0, s->nchars = 0; i < s->cmp->glyph_len; i++, s->nchars++)
19626 {
19627 Lisp_Object g = LGSTRING_GLYPH (gstring, i);
19628 unsigned code;
19629 XChar2b * store_pos;
19630 if (NILP (g))
19631 break;
19632 code = LGLYPH_CODE (g);
19633 store_pos = s->char2b + i;
19634 STORE_XCHAR2B (store_pos, code >> 8, code & 0xFF);
19635 }
19636 s->width = s->cmp->pixel_width;
19637 }
19638 else
19639 { 19559 {
19640 /* For all glyphs of this composition, starting at the offset 19560 int c = COMPOSITION_GLYPH (s->cmp, i);
19641 S->gidx, until we reach the end of the definition or encounter a
19642 glyph that requires the different face, add it to S. */
19643 struct face *face;
19644 19561
19645 s->face = NULL; 19562 if (c != '\t')
19646 s->font = NULL;
19647 for (i = s->gidx; i < s->cmp->glyph_len; i++)
19648 { 19563 {
19649 int c = COMPOSITION_GLYPH (s->cmp, i); 19564 int face_id = FACE_FOR_CHAR (s->f, base_face->ascii_face, c,
19565 -1, Qnil);
19650 19566
19651 if (c != '\t') 19567 face = get_char_face_and_encoding (s->f, c, face_id,
19568 s->char2b + i, 1, 1);
19569 if (face)
19652 { 19570 {
19653 int face_id = FACE_FOR_CHAR (s->f, base_face->ascii_face, c, 19571 if (! s->face)
19654 -1, Qnil);
19655
19656 face = get_char_face_and_encoding (s->f, c, face_id,
19657 s->char2b + i, 1, 1);
19658 if (face)
19659 { 19572 {
19660 if (! s->face) 19573 s->face = face;
19661 { 19574 s->font = s->face->font;
19662 s->face = face;
19663 s->font = s->face->font;
19664 }
19665 else if (s->face != face)
19666 break;
19667 } 19575 }
19576 else if (s->face != face)
19577 break;
19668 } 19578 }
19669 ++s->nchars;
19670 } 19579 }
19671 19580 ++s->nchars;
19672 /* All glyph strings for the same composition has the same width,
19673 i.e. the width set for the first component of the composition. */
19674 s->width = s->first_glyph->pixel_width;
19675 } 19581 }
19582 s->cmp_to = i;
19583
19584 /* All glyph strings for the same composition has the same width,
19585 i.e. the width set for the first component of the composition. */
19586 s->width = s->first_glyph->pixel_width;
19676 19587
19677 /* If the specified font could not be loaded, use the frame's 19588 /* If the specified font could not be loaded, use the frame's
19678 default font, but record the fact that we couldn't load it in 19589 default font, but record the fact that we couldn't load it in
@@ -19690,7 +19601,43 @@ fill_composite_glyph_string (s, base_face, overlaps)
19690 /* This glyph string must always be drawn with 16-bit functions. */ 19601 /* This glyph string must always be drawn with 16-bit functions. */
19691 s->two_byte_p = 1; 19602 s->two_byte_p = 1;
19692 19603
19693 return s->gidx + s->nchars; 19604 return s->cmp_to;
19605}
19606
19607static int
19608fill_gstring_glyph_string (s, face_id, start, end, overlaps)
19609 struct glyph_string *s;
19610 int face_id;
19611 int start, end, overlaps;
19612{
19613 struct glyph *glyph, *last;
19614 Lisp_Object lgstring;
19615 int i;
19616
19617 s->for_overlaps = overlaps;
19618 glyph = s->row->glyphs[s->area] + start;
19619 last = s->row->glyphs[s->area] + end;
19620 s->cmp_id = glyph->u.cmp.id;
19621 s->cmp_from = glyph->u.cmp.from;
19622 s->cmp_to = glyph->u.cmp.to;
19623 s->face = FACE_FROM_ID (s->f, face_id);
19624 lgstring = composition_gstring_from_id (s->cmp_id);
19625 s->font = XFONT_OBJECT (LGSTRING_FONT (lgstring));
19626 glyph++;
19627 while (glyph < last
19628 && glyph->u.cmp.automatic
19629 && glyph->u.cmp.id == s->cmp_id)
19630 s->cmp_to = (glyph++)->u.cmp.to;
19631
19632 for (i = s->cmp_from; i < s->cmp_to; i++)
19633 {
19634 Lisp_Object lglyph = LGSTRING_GLYPH (lgstring, i);
19635 unsigned code = LGLYPH_CODE (lglyph);
19636
19637 STORE_XCHAR2B ((s->char2b + i), code >> 8, code & 0xFF);
19638 }
19639 s->width = composition_gstring_width (lgstring, s->cmp_from, s->cmp_to, NULL);
19640 return glyph - s->row->glyphs[s->area];
19694} 19641}
19695 19642
19696 19643
@@ -19837,7 +19784,6 @@ get_per_char_metric (f, font, char2b)
19837{ 19784{
19838 static struct font_metrics metrics; 19785 static struct font_metrics metrics;
19839 unsigned code = (XCHAR2B_BYTE1 (char2b) << 8) | XCHAR2B_BYTE2 (char2b); 19786 unsigned code = (XCHAR2B_BYTE1 (char2b) << 8) | XCHAR2B_BYTE2 (char2b);
19840 struct font *fontp;
19841 19787
19842 if (! font || code == FONT_INVALID_CODE) 19788 if (! font || code == FONT_INVALID_CODE)
19843 return NULL; 19789 return NULL;
@@ -19875,10 +19821,27 @@ x_get_glyph_overhangs (glyph, f, left, right)
19875 } 19821 }
19876 else if (glyph->type == COMPOSITE_GLYPH) 19822 else if (glyph->type == COMPOSITE_GLYPH)
19877 { 19823 {
19878 struct composition *cmp = composition_table[glyph->u.cmp_id]; 19824 if (! glyph->u.cmp.automatic)
19825 {
19826 struct composition *cmp = composition_table[glyph->u.cmp.id];
19827
19828 if (cmp->rbearing - cmp->pixel_width)
19829 *right = cmp->rbearing - cmp->pixel_width;
19830 if (cmp->lbearing < 0);
19831 *left = - cmp->lbearing;
19832 }
19833 else
19834 {
19835 Lisp_Object gstring = composition_gstring_from_id (glyph->u.cmp.id);
19836 struct font_metrics metrics;
19879 19837
19880 *right = cmp->rbearing - cmp->pixel_width; 19838 composition_gstring_width (gstring, glyph->u.cmp.from,
19881 *left = - cmp->lbearing; 19839 glyph->u.cmp.to, &metrics);
19840 if (metrics.rbearing > metrics.width)
19841 *right = metrics.rbearing;
19842 if (metrics.lbearing < 0)
19843 *left = - metrics.lbearing;
19844 }
19882 } 19845 }
19883} 19846}
19884 19847
@@ -20142,7 +20105,7 @@ compute_overhangs_and_x (s, x, backward_p)
20142 INIT_GLYPH_STRING (s, char2b, w, row, area, START, HL); \ 20105 INIT_GLYPH_STRING (s, char2b, w, row, area, START, HL); \
20143 append_glyph_string (&HEAD, &TAIL, s); \ 20106 append_glyph_string (&HEAD, &TAIL, s); \
20144 s->x = (X); \ 20107 s->x = (X); \
20145 START = fill_glyph_string (s, face_id, START, END, overlaps); \ 20108 START = fill_glyph_string (s, face_id, START, END, overlaps); \
20146 } \ 20109 } \
20147 while (0) 20110 while (0)
20148 20111
@@ -20160,7 +20123,7 @@ compute_overhangs_and_x (s, x, backward_p)
20160 do { \ 20123 do { \
20161 int face_id = (row)->glyphs[area][START].face_id; \ 20124 int face_id = (row)->glyphs[area][START].face_id; \
20162 struct face *base_face = FACE_FROM_ID (f, face_id); \ 20125 struct face *base_face = FACE_FROM_ID (f, face_id); \
20163 int cmp_id = (row)->glyphs[area][START].u.cmp_id; \ 20126 int cmp_id = (row)->glyphs[area][START].u.cmp.id; \
20164 struct composition *cmp = composition_table[cmp_id]; \ 20127 struct composition *cmp = composition_table[cmp_id]; \
20165 XChar2b *char2b; \ 20128 XChar2b *char2b; \
20166 struct glyph_string *first_s; \ 20129 struct glyph_string *first_s; \
@@ -20176,7 +20139,7 @@ compute_overhangs_and_x (s, x, backward_p)
20176 INIT_GLYPH_STRING (s, char2b, w, row, area, START, HL); \ 20139 INIT_GLYPH_STRING (s, char2b, w, row, area, START, HL); \
20177 append_glyph_string (&(HEAD), &(TAIL), s); \ 20140 append_glyph_string (&(HEAD), &(TAIL), s); \
20178 s->cmp = cmp; \ 20141 s->cmp = cmp; \
20179 s->gidx = n; \ 20142 s->cmp_from = n; \
20180 s->x = (X); \ 20143 s->x = (X); \
20181 if (n == 0) \ 20144 if (n == 0) \
20182 first_s = s; \ 20145 first_s = s; \
@@ -20188,6 +20151,28 @@ compute_overhangs_and_x (s, x, backward_p)
20188 } while (0) 20151 } while (0)
20189 20152
20190 20153
20154/* Add a glyph string for a glyph-string sequence to the list of strings
20155 between HEAD and TAIL. */
20156
20157#define BUILD_GSTRING_GLYPH_STRING(START, END, HEAD, TAIL, HL, X, LAST_X) \
20158 do { \
20159 int face_id; \
20160 XChar2b *char2b; \
20161 Lisp_Object gstring; \
20162 \
20163 face_id = (row)->glyphs[area][START].face_id; \
20164 gstring = (composition_gstring_from_id \
20165 ((row)->glyphs[area][START].u.cmp.id)); \
20166 s = (struct glyph_string *) alloca (sizeof *s); \
20167 char2b = (XChar2b *) alloca ((sizeof *char2b) \
20168 * LGSTRING_GLYPH_LEN (gstring)); \
20169 INIT_GLYPH_STRING (s, char2b, w, row, area, START, HL); \
20170 append_glyph_string (&(HEAD), &(TAIL), s); \
20171 s->x = (X); \
20172 START = fill_gstring_glyph_string (s, face_id, START, END, overlaps); \
20173 } while (0)
20174
20175
20191/* Build a list of glyph strings between HEAD and TAIL for the glyphs 20176/* Build a list of glyph strings between HEAD and TAIL for the glyphs
20192 of AREA of glyph row ROW on window W between indices START and END. 20177 of AREA of glyph row ROW on window W between indices START and END.
20193 HL overrides the face for drawing glyph strings, e.g. it is 20178 HL overrides the face for drawing glyph strings, e.g. it is
@@ -20198,47 +20183,50 @@ compute_overhangs_and_x (s, x, backward_p)
20198 to allocate glyph strings (because draw_glyphs can be called 20183 to allocate glyph strings (because draw_glyphs can be called
20199 asynchronously). */ 20184 asynchronously). */
20200 20185
20201#define BUILD_GLYPH_STRINGS(START, END, HEAD, TAIL, HL, X, LAST_X) \ 20186#define BUILD_GLYPH_STRINGS(START, END, HEAD, TAIL, HL, X, LAST_X) \
20202 do \ 20187 do \
20203 { \ 20188 { \
20204 HEAD = TAIL = NULL; \ 20189 HEAD = TAIL = NULL; \
20205 while (START < END) \ 20190 while (START < END) \
20206 { \ 20191 { \
20207 struct glyph *first_glyph = (row)->glyphs[area] + START; \ 20192 struct glyph *first_glyph = (row)->glyphs[area] + START; \
20208 switch (first_glyph->type) \ 20193 switch (first_glyph->type) \
20209 { \ 20194 { \
20210 case CHAR_GLYPH: \ 20195 case CHAR_GLYPH: \
20211 BUILD_CHAR_GLYPH_STRINGS (START, END, HEAD, TAIL, \ 20196 BUILD_CHAR_GLYPH_STRINGS (START, END, HEAD, TAIL, \
20212 HL, X, LAST_X); \ 20197 HL, X, LAST_X); \
20213 break; \ 20198 break; \
20214 \ 20199 \
20215 case COMPOSITE_GLYPH: \ 20200 case COMPOSITE_GLYPH: \
20216 BUILD_COMPOSITE_GLYPH_STRING (START, END, HEAD, TAIL, \ 20201 if (first_glyph->u.cmp.automatic) \
20217 HL, X, LAST_X); \ 20202 BUILD_GSTRING_GLYPH_STRING (START, END, HEAD, TAIL, \
20218 break; \ 20203 HL, X, LAST_X); \
20219 \ 20204 else \
20220 case STRETCH_GLYPH: \ 20205 BUILD_COMPOSITE_GLYPH_STRING (START, END, HEAD, TAIL, \
20221 BUILD_STRETCH_GLYPH_STRING (START, END, HEAD, TAIL, \ 20206 HL, X, LAST_X); \
20222 HL, X, LAST_X); \ 20207 break; \
20223 break; \ 20208 \
20224 \ 20209 case STRETCH_GLYPH: \
20225 case IMAGE_GLYPH: \ 20210 BUILD_STRETCH_GLYPH_STRING (START, END, HEAD, TAIL, \
20226 BUILD_IMAGE_GLYPH_STRING (START, END, HEAD, TAIL, \ 20211 HL, X, LAST_X); \
20227 HL, X, LAST_X); \ 20212 break; \
20228 break; \ 20213 \
20229 \ 20214 case IMAGE_GLYPH: \
20230 default: \ 20215 BUILD_IMAGE_GLYPH_STRING (START, END, HEAD, TAIL, \
20231 abort (); \ 20216 HL, X, LAST_X); \
20232 } \ 20217 break; \
20233 \ 20218 \
20234 if (s) \ 20219 default: \
20235 { \ 20220 abort (); \
20236 set_glyph_string_background_width (s, START, LAST_X); \ 20221 } \
20237 (X) += s->width; \ 20222 \
20238 } \ 20223 if (s) \
20239 } \ 20224 { \
20240 } \ 20225 set_glyph_string_background_width (s, START, LAST_X); \
20241 while (0) 20226 (X) += s->width; \
20227 } \
20228 } \
20229 } while (0)
20242 20230
20243 20231
20244/* Draw glyphs between START and END in AREA of ROW on window W, 20232/* Draw glyphs between START and END in AREA of ROW on window W,
@@ -20559,8 +20547,9 @@ append_glyph (it)
20559 IT_EXPAND_MATRIX_WIDTH (it, area); 20547 IT_EXPAND_MATRIX_WIDTH (it, area);
20560} 20548}
20561 20549
20562/* Store one glyph for the composition IT->cmp_id in IT->glyph_row. 20550/* Store one glyph for the composition IT->cmp_it.id in
20563 Called from x_produce_glyphs when IT->glyph_row is non-null. */ 20551 IT->glyph_row. Called from x_produce_glyphs when IT->glyph_row is
20552 non-null. */
20564 20553
20565static INLINE void 20554static INLINE void
20566append_composite_glyph (it) 20555append_composite_glyph (it)
@@ -20581,6 +20570,18 @@ append_composite_glyph (it)
20581 glyph->descent = it->descent; 20570 glyph->descent = it->descent;
20582 glyph->voffset = it->voffset; 20571 glyph->voffset = it->voffset;
20583 glyph->type = COMPOSITE_GLYPH; 20572 glyph->type = COMPOSITE_GLYPH;
20573 if (it->cmp_it.ch < 0)
20574 {
20575 glyph->u.cmp.automatic = 0;
20576 glyph->u.cmp.id = it->cmp_it.id;
20577 }
20578 else
20579 {
20580 glyph->u.cmp.automatic = 1;
20581 glyph->u.cmp.id = it->cmp_it.id;
20582 glyph->u.cmp.from = it->cmp_it.from;
20583 glyph->u.cmp.to = it->cmp_it.to;
20584 }
20584 glyph->avoid_cursor_p = it->avoid_cursor_p; 20585 glyph->avoid_cursor_p = it->avoid_cursor_p;
20585 glyph->multibyte_p = it->multibyte_p; 20586 glyph->multibyte_p = it->multibyte_p;
20586 glyph->left_box_line_p = it->start_of_box_run_p; 20587 glyph->left_box_line_p = it->start_of_box_run_p;
@@ -20590,7 +20591,6 @@ append_composite_glyph (it)
20590 glyph->padding_p = 0; 20591 glyph->padding_p = 0;
20591 glyph->glyph_not_available_p = 0; 20592 glyph->glyph_not_available_p = 0;
20592 glyph->face_id = it->face_id; 20593 glyph->face_id = it->face_id;
20593 glyph->u.cmp_id = it->cmp_id;
20594 glyph->slice = null_glyph_slice; 20594 glyph->slice = null_glyph_slice;
20595 glyph->font_type = FONT_TYPE_UNKNOWN; 20595 glyph->font_type = FONT_TYPE_UNKNOWN;
20596 ++it->glyph_row->used[area]; 20596 ++it->glyph_row->used[area];
@@ -21447,9 +21447,11 @@ x_produce_glyphs (it)
21447 } 21447 }
21448 it->multibyte_p = saved_multibyte_p; 21448 it->multibyte_p = saved_multibyte_p;
21449 } 21449 }
21450 else if (it->what == IT_COMPOSITION) 21450 else if (it->what == IT_COMPOSITION && it->cmp_it.ch < 0)
21451 { 21451 {
21452 /* Note: A composition is represented as one glyph in the 21452 /* A static compositoin.
21453
21454 Note: A composition is represented as one glyph in the
21453 glyph matrix. There are no padding glyphs. 21455 glyph matrix. There are no padding glyphs.
21454 21456
21455 Important is that pixel_width, ascent, and descent are the 21457 Important is that pixel_width, ascent, and descent are the
@@ -21457,18 +21459,12 @@ x_produce_glyphs (it)
21457 the overall glyphs composed). */ 21459 the overall glyphs composed). */
21458 struct face *face = FACE_FROM_ID (it->f, it->face_id); 21460 struct face *face = FACE_FROM_ID (it->f, it->face_id);
21459 int boff; /* baseline offset */ 21461 int boff; /* baseline offset */
21460 struct composition *cmp = composition_table[it->cmp_id]; 21462 struct composition *cmp = composition_table[it->cmp_it.id];
21461 int glyph_len = cmp->glyph_len; 21463 int glyph_len = cmp->glyph_len;
21462 struct font *font = face->font; 21464 struct font *font = face->font;
21463 21465
21464 it->nglyphs = 1; 21466 it->nglyphs = 1;
21465 21467
21466 if (cmp->method == COMPOSITION_WITH_GLYPH_STRING)
21467 {
21468 PREPARE_FACE_FOR_DISPLAY (it->f, face);
21469 font_prepare_composition (cmp, it->f);
21470 }
21471 else
21472 /* If we have not yet calculated pixel size data of glyphs of 21468 /* If we have not yet calculated pixel size data of glyphs of
21473 the composition for the current face font, calculate them 21469 the composition for the current face font, calculate them
21474 now. Theoretically, we have to check all fonts for the 21470 now. Theoretically, we have to check all fonts for the
@@ -21488,7 +21484,6 @@ x_produce_glyphs (it)
21488 int lbearing, rbearing; 21484 int lbearing, rbearing;
21489 int i, width, ascent, descent; 21485 int i, width, ascent, descent;
21490 int left_padded = 0, right_padded = 0; 21486 int left_padded = 0, right_padded = 0;
21491 int face_id;
21492 int c; 21487 int c;
21493 XChar2b char2b; 21488 XChar2b char2b;
21494 struct font_metrics *pcm; 21489 struct font_metrics *pcm;
@@ -21771,6 +21766,52 @@ x_produce_glyphs (it)
21771 if (it->glyph_row) 21766 if (it->glyph_row)
21772 append_composite_glyph (it); 21767 append_composite_glyph (it);
21773 } 21768 }
21769 else if (it->what == IT_COMPOSITION)
21770 {
21771 /* A dynamic (automatic) composition. */
21772 struct face *face = FACE_FROM_ID (it->f, it->face_id);
21773 Lisp_Object gstring;
21774 struct font_metrics metrics;
21775
21776 gstring = composition_gstring_from_id (it->cmp_it.id);
21777 it->pixel_width
21778 = composition_gstring_width (gstring, it->cmp_it.from, it->cmp_it.to,
21779 &metrics);
21780 if (it->glyph_row
21781 && (metrics.lbearing < 0 || metrics.rbearing > metrics.width))
21782 it->glyph_row->contains_overlapping_glyphs_p = 1;
21783 it->ascent = it->phys_ascent = metrics.ascent;
21784 it->descent = it->phys_descent = metrics.descent;
21785 if (face->box != FACE_NO_BOX)
21786 {
21787 int thick = face->box_line_width;
21788
21789 if (thick > 0)
21790 {
21791 it->ascent += thick;
21792 it->descent += thick;
21793 }
21794 else
21795 thick = - thick;
21796
21797 if (it->start_of_box_run_p)
21798 it->pixel_width += thick;
21799 if (it->end_of_box_run_p)
21800 it->pixel_width += thick;
21801 }
21802 /* If face has an overline, add the height of the overline
21803 (1 pixel) and a 1 pixel margin to the character height. */
21804 if (face->overline_p)
21805 it->ascent += overline_margin;
21806 take_vertical_position_into_account (it);
21807 if (it->ascent < 0)
21808 it->ascent = 0;
21809 if (it->descent < 0)
21810 it->descent = 0;
21811
21812 if (it->glyph_row)
21813 append_composite_glyph (it);
21814 }
21774 else if (it->what == IT_IMAGE) 21815 else if (it->what == IT_IMAGE)
21775 produce_image_glyph (it); 21816 produce_image_glyph (it);
21776 else if (it->what == IT_STRETCH) 21817 else if (it->what == IT_STRETCH)