comparison src/xdisp.c @ 91178:e9ab44fefef3

(handle_auto_composed_prop): Simplify the code. Never return HANDLED_RECOMPUTE_PROPS.
author Kenichi Handa <handa@m17n.org>
date Tue, 04 Dec 2007 06:03:29 +0000
parents 5e49a450f62d
children cdc63ae7ea34
comparison
equal deleted inserted replaced
91177:ca4dcecf8f88 91178:e9ab44fefef3
4552 enum prop_handled handled = HANDLED_NORMALLY; 4552 enum prop_handled handled = HANDLED_NORMALLY;
4553 4553
4554 if (FUNCTIONP (Vauto_composition_function)) 4554 if (FUNCTIONP (Vauto_composition_function))
4555 { 4555 {
4556 Lisp_Object val; 4556 Lisp_Object val;
4557 EMACS_INT pos, this_pos; 4557 EMACS_INT pos, pos_byte, this_pos, start, end;
4558 int c;
4558 4559
4559 if (STRINGP (it->string)) 4560 if (STRINGP (it->string))
4560 pos = IT_STRING_CHARPOS (*it); 4561 {
4562 const unsigned char *s;
4563
4564 pos = IT_STRING_CHARPOS (*it);
4565 pos_byte = IT_STRING_BYTEPOS (*it);
4566 s = SDATA (it->string) + pos_byte;
4567 if (STRING_MULTIBYTE (it->string))
4568 c = STRING_CHAR (s, 0);
4569 else
4570 c = *s;
4571 }
4561 else 4572 else
4562 pos = IT_CHARPOS (*it); 4573 {
4574 pos = IT_CHARPOS (*it);
4575 pos_byte = IT_BYTEPOS (*it);
4576 c = FETCH_CHAR (pos_byte);
4577 }
4563 this_pos = pos; 4578 this_pos = pos;
4564 4579
4565 val =Fget_char_property (make_number (pos), Qauto_composed, it->string); 4580 if (get_property_and_range (pos, Qauto_composed, &val, &start, &end,
4566 if (! NILP (val)) 4581 it->string))
4567 { 4582 {
4568 Lisp_Object limit = Qnil, next; 4583 Lisp_Object cmp_prop;
4569 4584 EMACS_INT cmp_start, cmp_end;
4570 /* As Fnext_single_char_property_change is very slow, we 4585
4571 limit the search to the current line. */ 4586 #ifdef USE_FONT_BACKEND
4572 if (STRINGP (it->string)) 4587 if (enable_font_backend
4573 limit = make_number (SCHARS (it->string)); 4588 && get_property_and_range (pos, Qcomposition, &cmp_prop,
4574 else 4589 &cmp_start, &cmp_end, it->string)
4575 limit = make_number (find_next_newline_no_quit (pos, 1)); 4590 && cmp_start == pos
4576 4591 && COMPOSITION_METHOD (cmp_prop) == COMPOSITION_WITH_GLYPH_STRING)
4577 next = (Fnext_single_property_change
4578 (make_number (pos), Qauto_composed, it->string, limit));
4579 if (XINT (next) < XINT (limit))
4580 { 4592 {
4581 /* The current point is auto-composed, but there exist 4593 Lisp_Object gstring = COMPOSITION_COMPONENTS (cmp_prop);
4582 characters not yet composed beyond the auto-composed 4594 Lisp_Object font_object = LGSTRING_FONT (gstring);
4583 region. There's a possiblity that the last 4595
4584 characters in the region may be newly composed. */ 4596 if (! EQ (font_object,
4585 int charpos = XINT (next) - 1, bytepos, c; 4597 font_at (c, pos, FACE_FROM_ID (it->f, it->face_id),
4586 4598 it->w, it->string)))
4599 /* We must re-compute the composition. */
4600 val = Qnil;
4601 }
4602 #endif
4603 if (! NILP (val))
4604 {
4605 EMACS_INT limit;
4606
4607 /* As Fnext_single_char_property_change is very slow, we
4608 limit the search to the current line. */
4587 if (STRINGP (it->string)) 4609 if (STRINGP (it->string))
4610 limit = SCHARS (it->string);
4611 else
4612 limit = find_next_newline_no_quit (pos, 1);
4613
4614 if (end < limit)
4588 { 4615 {
4589 bytepos = string_char_to_byte (it->string, charpos); 4616 /* The current point is auto-composed, but there
4590 c = SDATA (it->string)[bytepos]; 4617 exist characters not yet composed beyond the
4618 auto-composed region. There's a possiblity that
4619 the last characters in the region may be newly
4620 composed. */
4621 int charpos = end - 1, bytepos, c;
4622
4623 if (STRINGP (it->string))
4624 {
4625 bytepos = string_char_to_byte (it->string, charpos);
4626 c = SDATA (it->string)[bytepos];
4627 }
4628 else
4629 {
4630 bytepos = CHAR_TO_BYTE (charpos);
4631 c = FETCH_BYTE (bytepos);
4632 }
4633 if (c != '\n')
4634 /* If the last character is not newline, it may be
4635 composed with the following characters. */
4636 val = Qnil, pos = charpos + 1;
4591 } 4637 }
4592 else
4593 {
4594 bytepos = CHAR_TO_BYTE (charpos);
4595 c = FETCH_BYTE (bytepos);
4596 }
4597 if (c != '\n')
4598 /* If the last character is not newline, it may be
4599 composed with the following characters. */
4600 val = Qnil, pos = charpos + 1;
4601 } 4638 }
4602 } 4639 }
4603 if (NILP (val)) 4640 if (NILP (val))
4604 { 4641 {
4605 int count = SPECPDL_INDEX (); 4642 int count = SPECPDL_INDEX ();
4609 specbind (Qauto_composition_function, Qnil); 4646 specbind (Qauto_composition_function, Qnil);
4610 args[1] = make_number (pos); 4647 args[1] = make_number (pos);
4611 args[2] = it->string; 4648 args[2] = it->string;
4612 #ifdef USE_FONT_BACKEND 4649 #ifdef USE_FONT_BACKEND
4613 if (enable_font_backend) 4650 if (enable_font_backend)
4614 { 4651 args[3] = it->window;
4615 struct face *face = FACE_FROM_ID (it->f, it->face_id);
4616 int c;
4617
4618 if (STRINGP (it->string))
4619 {
4620 EMACS_INT pos_byte = IT_STRING_BYTEPOS (*it);
4621 const unsigned char *s = SDATA (it->string) + pos_byte;
4622
4623 if (STRING_MULTIBYTE (it->string))
4624 it->c = STRING_CHAR (s, 0);
4625 else
4626 it->c = *s;
4627 }
4628 else
4629 {
4630 EMACS_INT pos_byte = IT_BYTEPOS (*it);
4631
4632 it->c = FETCH_CHAR (pos_byte);
4633 }
4634 args[3] = it->window;
4635 }
4636 else 4652 else
4637 #endif /* USE_FONT_BACKEND */ 4653 #endif /* USE_FONT_BACKEND */
4638 args[3] = Qnil; 4654 args[3] = Qnil;
4639 safe_call (4, args); 4655 safe_call (4, args);
4640 unbind_to (count, Qnil); 4656 unbind_to (count, Qnil);
4641
4642 if (this_pos == pos)
4643 {
4644 val = Fget_char_property (args[1], Qauto_composed, it->string);
4645 /* Return HANDLED_RECOMPUTE_PROPS only if function composed
4646 something. This avoids an endless loop if they failed to
4647 fontify the text for which reason ever. */
4648 if (! NILP (val))
4649 handled = HANDLED_RECOMPUTE_PROPS;
4650 }
4651 else
4652 handled = HANDLED_RECOMPUTE_PROPS;
4653 } 4657 }
4654 } 4658 }
4655 4659
4656 return handled; 4660 return handled;
4657 } 4661 }